using MQTTnet; using MQTTnet.Client; using System.Collections.Immutable; using System.Runtime.CompilerServices; namespace TestApp { internal class EnergyManager { private MqttFactory _MqttFactory; private IMqttClient _MqttClient; private ImmutableDictionary _CurrentValues = ImmutableDictionary.Empty; private EnergyManager() { _MqttFactory= new MqttFactory(); _MqttClient = _MqttFactory.CreateMqttClient(); } public static async Task Create() { var ret = new EnergyManager(); await ret.Connect(); return ret; } private async Task Connect() { var clientOptions = new MqttClientOptionsBuilder() .WithTcpServer("localhost") .Build(); await _MqttClient.ConnectAsync(clientOptions); _MqttClient.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync; var subscribeOptions = _MqttFactory.CreateSubscribeOptionsBuilder() .WithTopicFilter( f => { f.WithTopic("gdr/local/values/smart-meter"); } ) .Build(); var response = await _MqttClient.SubscribeAsync(subscribeOptions); } private Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg) { switch (arg.ApplicationMessage.Topic) { case "gdr/local/values/smart-meter": ParseGDRs(arg.ApplicationMessage.Payload); break; } return Task.CompletedTask; } private void ParseGDRs(byte[] payload) { var gdrs = GDRs.Parser.ParseFrom(payload); if (!gdrs.GDRs_.TryGetValue("smart-meter", out GDR smartMeterGDR)) { return; } _CurrentValues = smartMeterGDR.Values.ToImmutableDictionary(); } private double GetValue(ulong obisCode, double factor) { if (!_CurrentValues.TryGetValue(obisCode, out ulong value)) { return double.NaN; } return factor * value; } /// in W public double ActivePowerPositive => GetValue(1099528667391UL, 0.001); /// in Wh public double ActiveEnergyPositive => GetValue(1099528929535UL, 0.001); /// in W public double ActivePowerNegative => GetValue(1099545444607UL, 0.001); /// in Wh public double ActiveEnergyNegative => GetValue(1099545706751UL, 0.001); /// in var public double ReactivePowerPositive => GetValue(1099562221823UL, 0.001); /// in varh public double ReactiveEnergyPositive => GetValue(1099562483967UL, 0.001); /// in var public double ReactivePowerNegative => GetValue(1099578999039UL, 0.001); /// in varh public double ReactiveEnergyNegative => GetValue(1099579261183UL, 0.001); /// in VA public double ApparentPowerPositive => GetValue(1099662885119UL, 0.001); /// in VAh public double ApparentEnergyPositive => GetValue(1099663147263UL, 0.001); /// in VA public double ApparentPowerNegative => GetValue(1099679662335UL, 0.001); /// in VAh public double ApparentEnergyNegative => GetValue(1099679924479UL, 0.001); /// in - public double PowerFactor => GetValue(1099729993983UL, 0.001); /// in Hz public double SupplyFrequency => GetValue(1099746771199UL, 0.001); /// in W public double ActivePowerPositiveL1 => GetValue(1099864211711UL, 0.001); /// in Wh public double ActiveEnergyPositiveL1 => GetValue(1099864473855UL, 0.001); /// in W public double ActivePowerNegativeL1 => GetValue(1099880988927UL, 0.001); /// in Wh public double ActiveEnergyNegativeL1 => GetValue(1099881251071UL, 0.001); /// in var public double ReactivePowerPositiveL1 => GetValue(1099897766143UL, 0.001); /// in varh public double ReactiveEnergyPositiveL1 => GetValue(1099898028287UL, 0.001); /// in var public double ReactivePowerNegativeL1 => GetValue(1099914543359UL, 0.001); /// in varh public double ReactiveEnergyNegativeL1 => GetValue(1099914805503UL, 0.001); /// in VA public double ApparentPowerPositiveL1 => GetValue(1099998429439UL, 0.001); /// in VAh public double ApparentEnergyPositiveL1 => GetValue(1099998691583UL, 0.001); /// in VA public double ApparentPowerNegativeL1 => GetValue(1100015206655UL, 0.001); /// in VAh public double ApparentEnergyNegativeL1 => GetValue(1100015468799UL, 0.001); /// in A public double CurrentL1 => GetValue(1100031983871UL, 0.001); /// in V public double VoltageL1 => GetValue(1100048761087UL, 0.001); /// in - public double PowerFactorL1 => GetValue(1100065538303UL, 0.001); /// in W public double ActivePowerPositiveL2 => GetValue(1100199756031UL, 0.001); /// in Wh public double ActiveEnergyPositiveL2 => GetValue(1100200018175UL, 0.001); /// in W public double ActivePowerNegativeL2 => GetValue(1100216533247UL, 0.001); /// in Wh public double ActiveEnergyNegativeL2 => GetValue(1100216795391UL, 0.001); /// in var public double ReactivePowerPositiveL2 => GetValue(1100233310463UL, 0.001); /// in varh public double ReactiveEnergyPositiveL2 => GetValue(1100233572607UL, 0.001); /// in var public double ReactivePowerNegativeL2 => GetValue(1100250087679UL, 0.001); /// in varh public double ReactiveEnergyNegativeL2 => GetValue(1100250349823UL, 0.001); /// in VA public double ApparentPowerPositiveL2 => GetValue(1100333973759UL, 0.001); /// in VAh public double ApparentEnergyPositiveL2 => GetValue(1100334235903UL, 0.001); /// in VA public double ApparentPowerNegativeL2 => GetValue(1100350750975UL, 0.001); /// in VAh public double ApparentEnergyNegativeL2 => GetValue(1100351013119UL, 0.001); /// in A public double CurrentL2 => GetValue(1100367528191UL, 0.001); /// in V public double VoltageL2 => GetValue(1100384305407UL, 0.001); /// in - public double PowerFactorL2 => GetValue(1100401082623UL, 0.001); /// in W public double ActivePowerPositiveL3 => GetValue(1100535300351UL, 0.001); /// in Wh public double ActiveEnergyPositiveL3 => GetValue(1100535562495UL, 0.001); /// in W public double ActivePowerNegativeL3 => GetValue(1100552077567UL, 0.001); /// in Wh public double ActiveEnergyNegativeL3 => GetValue(1100552339711UL, 0.001); /// in var public double ReactivePowerPositiveL3 => GetValue(1100568854783UL, 0.001); /// in varh public double ReactiveEnergyPositiveL3 => GetValue(1100569116927UL, 0.001); /// in var public double ReactivePowerNegativeL3 => GetValue(1100585631999UL, 0.001); /// in varh public double ReactiveEnergyNegativeL3 => GetValue(1100585894143UL, 0.001); /// in VA public double ApparentPowerPositiveL3 => GetValue(1100669518079UL, 0.001); /// in VAh public double ApparentEnergyPositiveL3 => GetValue(1100669780223UL, 0.001); /// in VA public double ApparentPowerNegativeL3 => GetValue(1100686295295UL, 0.001); /// in VAh public double ApparentEnergyNegativeL3 => GetValue(1100686557439UL, 0.001); /// in A public double CurrentL3 => GetValue(1100703072511UL, 0.001); /// in V public double VoltageL3 => GetValue(1100719849727UL, 0.001); /// in - public double PowerFactorL3 => GetValue(1100736626943UL, 0.001); } }