Add communication with local MQTT
This commit is contained in:
166
TestApp/Interface.proto
Normal file
166
TestApp/Interface.proto
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
// GCRs is the message type wich is published to the mqtt Handler for GCR
|
||||||
|
// config_uuid - unique identification of config in time (i.e. changes on config change)
|
||||||
|
message GCRs {
|
||||||
|
map<string,GCR> GCRs = 1;
|
||||||
|
string config_uuid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GDRs is the message type wich is published to the mqtt Handler for GDR
|
||||||
|
// config_uuid - unique identification of config at time of measurement (same as associated GCR)
|
||||||
|
message GDRs {
|
||||||
|
map<string,GDR> GDRs = 1;
|
||||||
|
string config_uuid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//GCR = Generic Config Record
|
||||||
|
message GCR {
|
||||||
|
string id = 1;
|
||||||
|
string label = 2;
|
||||||
|
Class class = 3;
|
||||||
|
repeated string sources = 4;
|
||||||
|
repeated uint64 codes = 5;
|
||||||
|
DeviceType devicetype = 6;
|
||||||
|
map<string,string> meta = 7;
|
||||||
|
google.protobuf.Timestamp timestamp = 8;
|
||||||
|
map<string,FlexDefinition> flexDefinitions = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
//GDR = Generic Data Record
|
||||||
|
message GDR {
|
||||||
|
string id = 1;
|
||||||
|
Status status = 2;
|
||||||
|
google.protobuf.Timestamp timestamp = 3;
|
||||||
|
map<uint64,uint64> values = 4;
|
||||||
|
map<string,FlexValue> flexValues = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class Consumer = Consumes Energy, Power, ...
|
||||||
|
// Class Producer = Produces Energy, Power, ...
|
||||||
|
// Class Hybrid = Consumes or Produces Energy, Power, ...
|
||||||
|
enum Class {
|
||||||
|
CLASS_UNKNOWN = 0;
|
||||||
|
CLASS_CONSUMER = 1;
|
||||||
|
CLASS_PRODUCER = 2;
|
||||||
|
CLASS_HYBRID = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// devicetype - declares which Type of Device the datasource is
|
||||||
|
enum DeviceType {
|
||||||
|
DEVICE_TYPE_UNKNOWN = 0;
|
||||||
|
DEVICE_TYPE_PHOTOVOLTAIC_SYSTEM = 1;
|
||||||
|
DEVICE_TYPE_ELECTRIC_VEHICLE = 2;
|
||||||
|
DEVICE_TYPE_BATTERY = 3;
|
||||||
|
DEVICE_TYPE_OVEN = 4;
|
||||||
|
DEVICE_TYPE_FLOW_HEATER = 5;
|
||||||
|
DEVICE_TYPE_BOILER = 6;
|
||||||
|
DEVICE_TYPE_IMMERSION_HEATER = 7;
|
||||||
|
DEVICE_TYPE_STOVE = 8;
|
||||||
|
DEVICE_TYPE_COOLER = 9;
|
||||||
|
DEVICE_TYPE_VENTILATION = 10;
|
||||||
|
DEVICE_TYPE_DISHWASHER = 11;
|
||||||
|
DEVICE_TYPE_DRYER = 12;
|
||||||
|
DEVICE_TYPE_HEAT_PUMP = 13;
|
||||||
|
DEVICE_TYPE_WASHING_MACHINE = 14;
|
||||||
|
DEVICE_TYPE_INVERTER_ONEPHASE = 15;
|
||||||
|
DEVICE_TYPE_INVERTER_THREEPHASE = 16;
|
||||||
|
DEVICE_TYPE_CHP = 17;
|
||||||
|
DEVICE_TYPE_BUILDING_OFFICE = 18;
|
||||||
|
DEVICE_TYPE_BUILDING_COMMERCIAL = 19;
|
||||||
|
DEVICE_TYPE_BUILDING_FACTORY = 20;
|
||||||
|
DEVICE_TYPE_BUILDING_SINGLE_HOME = 21;
|
||||||
|
DEVICE_TYPE_BUILDING_HOTEL = 22;
|
||||||
|
DEVICE_TYPE_BUILDING_APARTMENTS = 23;
|
||||||
|
DEVICE_TYPE_BUILDING_PARKING = 24;
|
||||||
|
DEVICE_TYPE_BUILDING_RESIDENTIAL = 25;
|
||||||
|
DEVICE_TYPE_ROOM_BATH = 26;
|
||||||
|
DEVICE_TYPE_ROOM_GARAGE = 27;
|
||||||
|
DEVICE_TYPE_ROOM_BASEMENT = 28;
|
||||||
|
DEVICE_TYPE_ROOM_CHILD = 29;
|
||||||
|
DEVICE_TYPE_ROOM_KITCHEN = 30;
|
||||||
|
DEVICE_TYPE_ROOM_SAUNA = 31;
|
||||||
|
DEVICE_TYPE_ROOM_BED = 32;
|
||||||
|
DEVICE_TYPE_ROOM_LIVING = 33;
|
||||||
|
DEVICE_TYPE_ROOM_GENERIC = 34;
|
||||||
|
DEVICE_TYPE_CONTROLLABLE_LOAD = 35;
|
||||||
|
DEVICE_TYPE_LIGHTING = 36;
|
||||||
|
DEVICE_TYPE_OFFICES = 37;
|
||||||
|
DEVICE_TYPE_DOMESTIC_APPLIANCES = 38;
|
||||||
|
DEVICE_TYPE_HEATER_OF_HEAT_PUMP = 39;
|
||||||
|
DEVICE_TYPE_INDUSTRIAL_ENGINE = 40;
|
||||||
|
DEVICE_TYPE_AIR_CONDITIONING = 41;
|
||||||
|
DEVICE_TYPE_COMPRESSOR = 42;
|
||||||
|
DEVICE_TYPE_PC_DATA_CENTER = 43;
|
||||||
|
DEVICE_TYPE_FUSES_THREE = 44;
|
||||||
|
DEVICE_TYPE_FUSES_SIX = 45;
|
||||||
|
DEVICE_TYPE_FUSES_NINE = 46;
|
||||||
|
DEVICE_TYPE_FUSES_TWELVE = 47;
|
||||||
|
DEVICE_TYPE_COMPACTOR = 48;
|
||||||
|
DEVICE_TYPE_WHITE_GOODS = 49;
|
||||||
|
DEVICE_TYPE_COLD_STORAGE_ROOM = 50;
|
||||||
|
DEVICE_TYPE_GARDEN_SHED = 51;
|
||||||
|
DEVICE_TYPE_COOLING_COMBINATION = 52;
|
||||||
|
DEVICE_TYPE_FACILITIES = 53;
|
||||||
|
DEVICE_TYPE_FREEZER = 54;
|
||||||
|
DEVICE_TYPE_FRIDGE = 55;
|
||||||
|
DEVICE_TYPE_GRID_CONNECTION_POINT = 56;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status OK = Datasource updated Data, GDR Updated
|
||||||
|
// Status WARNING = Datasource updated Data but configuration is needed
|
||||||
|
// Status Error = Datasource did not updated Data (Maybe broken)
|
||||||
|
enum Status {
|
||||||
|
STATUS_UNKNOWN = 0;
|
||||||
|
STATUS_OK = 1;
|
||||||
|
STATUS_WARNING = 2;
|
||||||
|
STATUS_ERROR = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlexValue is a message type which handles flexible datapoints inside a GDR
|
||||||
|
message FlexValue {
|
||||||
|
int64 int_value = 1;
|
||||||
|
string string_value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlexDefinition describes the content of the flexible values
|
||||||
|
message FlexDefinition {
|
||||||
|
string label = 1;
|
||||||
|
FlexValueType type = 2;
|
||||||
|
Unit unit = 3;
|
||||||
|
sint32 decimalpower = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlexValueType declares which field should be used parsing the flexvalue
|
||||||
|
enum FlexValueType {
|
||||||
|
FLEX_VALUE_TYPE_INTEGER = 0;
|
||||||
|
FLEX_VALUE_TYPE_STRING = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unit declares the unit of the flexible value
|
||||||
|
enum Unit {
|
||||||
|
UNIT_UNKNOWN = 0;
|
||||||
|
// Electrical values
|
||||||
|
UNIT_AMPERE = 1;
|
||||||
|
UNIT_VOLT = 2;
|
||||||
|
UNIT_WATT = 3;
|
||||||
|
UNIT_HERTZ = 4;
|
||||||
|
UNIT_VOLT_AMPERE = 5;
|
||||||
|
UNIT_VOLT_AMPERE_REACTIVE = 6;
|
||||||
|
UNIT_WATT_HOUR = 7;
|
||||||
|
UNIT_KILO_WATT_HOUR = 8;
|
||||||
|
// Time Values
|
||||||
|
UNIT_SECOND = 9;
|
||||||
|
UNIT_MINUTE = 10;
|
||||||
|
UNIT_HOUR = 11;
|
||||||
|
UNIT_DAY = 12;
|
||||||
|
UNIT_WEEK = 13;
|
||||||
|
UNIT_MONTH = 14;
|
||||||
|
UNIT_YEAR = 15;
|
||||||
|
// Other values
|
||||||
|
UNIT_DEGREE_CELSIUS = 16;
|
||||||
|
UNIT_KELVIN = 17;
|
||||||
|
UNIT_DEGREE_FAHRENHEIT = 18;
|
||||||
|
}
|
||||||
@@ -1,12 +1,19 @@
|
|||||||
using NModbus;
|
using MQTTnet;
|
||||||
|
using MQTTnet.Client;
|
||||||
|
using NModbus;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
||||||
namespace TestApp
|
namespace TestApp
|
||||||
{
|
{
|
||||||
internal class Program
|
internal class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
private static IMqttClient _MqttClient;
|
||||||
|
private static Dictionary<UInt64, UInt64> _CurrentValues = new Dictionary<ulong, ulong>();
|
||||||
|
|
||||||
|
static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
|
await ConnectMQTT();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -32,10 +39,11 @@ namespace TestApp
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var currentWirkleistung = _CurrentValues.GetValueOrDefault(1099528667391UL) / 1000;
|
||||||
|
|
||||||
ushort input = master.ReadHoldingRegisters(1, 1000, 1)[0];
|
ushort input = master.ReadHoldingRegisters(1, 1000, 1)[0];
|
||||||
ushort output = (ushort)(input + 50);
|
ushort output = (ushort)(input + currentWirkleistung);
|
||||||
master.WriteMultipleRegisters(1, 1100, new ushort[] { output });
|
master.WriteMultipleRegisters(1, 1100, new ushort[] { output });
|
||||||
Console.WriteLine($"Register values updated to {input} + 50 = {output}");
|
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -46,5 +54,56 @@ namespace TestApp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task ConnectMQTT() {
|
||||||
|
var factory = new MqttFactory();
|
||||||
|
|
||||||
|
_MqttClient = factory.CreateMqttClient();
|
||||||
|
|
||||||
|
var clientOptions = new MqttClientOptionsBuilder()
|
||||||
|
.WithTcpServer("localhost")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Console.WriteLine("Connecting to local MQTT ...");
|
||||||
|
await _MqttClient.ConnectAsync(clientOptions);
|
||||||
|
Console.WriteLine("Connected to local MQTT!");
|
||||||
|
|
||||||
|
_MqttClient.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync;
|
||||||
|
|
||||||
|
var subscribeOptions = factory.CreateSubscribeOptionsBuilder()
|
||||||
|
.WithTopicFilter(
|
||||||
|
f => {
|
||||||
|
f.WithTopic("gdr/local/values/smart-meter");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Console.WriteLine("Subscribing to smart-meter values ...");
|
||||||
|
var response = await _MqttClient.SubscribeAsync(subscribeOptions);
|
||||||
|
Console.WriteLine("Subscribed to smart-meter values!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
|
||||||
|
{
|
||||||
|
switch (arg.ApplicationMessage.Topic) {
|
||||||
|
case "gdr/local/values/smart-meter":
|
||||||
|
ParseGDRs(arg.ApplicationMessage.Payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ParseGDRs(byte[] payload)
|
||||||
|
{
|
||||||
|
var gdrs = GDRs.Parser.ParseFrom(payload);
|
||||||
|
|
||||||
|
if (!gdrs.GDRs_.TryGetValue("smart-meter", out GDR smartMeterGDR)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var value in smartMeterGDR.Values) {
|
||||||
|
_CurrentValues[value.Key] = value.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Google.Protobuf" Version="3.21.12" />
|
||||||
|
<PackageReference Include="Grpc.Tools" Version="2.39.1">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="MQTTnet" Version="4.1.4.563" />
|
||||||
<PackageReference Include="NModbus" Version="3.0.72" />
|
<PackageReference Include="NModbus" Version="3.0.72" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Protobuf Include="Interface.proto" GrpcServices="Server" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user