/// <summary> /// Constructor. /// </summary> public QboxResponseBuilder(MiniPoco inMini, IQueue <string> ioCommandQueue, bool inCanSendAutoStatusCommands, bool inCanSendAutoAnswerCommand) { _mini = inMini; _commandQueue = ioCommandQueue; _canSendAutoStatusCommands = inCanSendAutoStatusCommands; _canSendAutoAnswerCommands = inCanSendAutoAnswerCommand; }
public static ClientMiniStatus GetClientMiniStatus(this MiniPoco mini, ClientQboxPoco client) { if (client == null) { return(null); } var clientKey = (QboxClient)client.ClientId; if (mini.QboxStatus.ClientStatuses.ContainsKey(clientKey.ToString())) { return(new ClientMiniStatus(mini.QboxStatus.ClientStatuses[clientKey.ToString()], mini.QboxStatus.FirmwareVersion)); } return(null); }
/// <summary> /// Constructs the data for the handling of a qbox data dump /// </summary> /// <param name="message">The actual message dumped by the Qbox. This is the decrypted message!</param> /// <param name="length">The length of the message</param> /// <param name="lastSeenAtUrl">The url used to dump the message</param> /// <param name="externalIp">The external ip from which the dump was initiated</param> /// <param name="mini">The mini the dump is made from</param> /// <param name="error">An optional error message to show if the retrieval or binding of the Mini, MiniPoco or decryption of the message was incorrect.</param> public QboxDataDumpContext(string message, int length, string lastSeenAtUrl, string externalIp, MiniPoco mini, string error = null) { Guard.IsNotNullOrEmpty(lastSeenAtUrl, "last seen url is missing"); Guard.IsNotNullOrEmpty(externalIp, "External Ip is missing"); Guard.IsNotNullOrEmpty(message, "message is missing"); Message = message; Length = length; Mini = mini; Error = error; if (Mini != null) { Mini.QboxStatus.IpAddress[externalIp] = DateTime.Now.ToUniversalTime(); Mini.QboxStatus.Url = lastSeenAtUrl; } }
/// <summary> /// Change the InternalId (CounterId) of the payload to the value that will be used to store and retrieve the measurements. /// </summary> /// <returns>false if the mapping could not be done (for example when the secondary meter type of a duo is not an S0 meter).</returns> public static bool MapCounterId(CounterPayload ioPayload, MiniPoco inMini) { Dictionary <int, int> mapping = null; var counterWithSourcePayload = ioPayload as CounterWithSourcePayload; if (counterWithSourcePayload == null || counterWithSourcePayload.PrimaryMeter) { // Firmware A34, Smart Meter and soladin measured on client reports counters instead of specific message: if (inMini.Clients.Any(d => (d.MeterType == DeviceMeterType.Smart_Meter_E) || (d.MeterType == DeviceMeterType.Smart_Meter_EG))) { mapping = SmartMeterIdMapping; } else if (inMini.Clients.Any(d => d.MeterType == DeviceMeterType.Soladin_600)) { mapping = SoladinIdMapping; } } if (counterWithSourcePayload != null && !counterWithSourcePayload.PrimaryMeter) { // At the moment we only support S0 as secondary meter type, so log an error when we find a different meter type. var clientsWithUnsupportedSecondaryMeterTypes = inMini.Clients.Where(c => c.SecondaryMeterType != DeviceMeterType.None && c.SecondaryMeterType != DeviceMeterType.SO_Pulse).ToList(); if (clientsWithUnsupportedSecondaryMeterTypes.Count > 0) { Log.Error("Qbox {0} has counter for unsupported secondary meter type {1}", inMini.SerialNumber, clientsWithUnsupportedSecondaryMeterTypes[0].SecondaryMeterType); return(false); } // S0 as secondary meter type does not need to be mapped. } if (mapping != null && mapping.ContainsKey(ioPayload.InternalNr)) { ioPayload.InternalNr = mapping[ioPayload.InternalNr]; } return(true); }
/// <summary> /// Is inMini a duo meter? /// </summary> private bool IsDuo(MiniPoco inMini) { return(inMini.Clients.Any()); }
/// <summary> /// Is inMini a Ferraris meter? /// </summary> private bool IsFerrarisMeter(MiniPoco inMini) { return(inMini.IsMeterTypePresent(DeviceMeterType.Ferraris_Black_Toothed)); }
/// <summary> /// Is inMini a LED meter? /// </summary> private bool IsLedMeter(MiniPoco inMini) { return(inMini.IsMeterTypePresent(DeviceMeterType.LED_TypeI) || inMini.IsMeterTypePresent(DeviceMeterType.LED_TypeII)); }
/// <summary> /// Returns a mini poco by serial number. First tries the Redis cache repository and if not found /// checks if it can find the box in Eco. /// Upon connection exception it will also fall back to ECO. /// </summary> /// <param name="sn">Serialnumber of the Mini</param> /// <returns>MiniPoco object holding the Mini data</returns> private MiniPoco Mini(string sn) { try { // SAM: previously the Qbox metadata was read from Redis. For now we take a huge shortcut and // only support smart meters EG with S0. // This code is tied to a similar construct in Qservice (SeriesRetriever.GetSeriesAtCounterLevel). var counterSensorMappingsSmartMeter = new CounterSensorMappingPoco { PeriodeBegin = new DateTime(2000, 1, 1), Formule = 1000 }; var mini = new MiniPoco() { SerialNumber = sn, DataStorePath = QboxNext.Core.Config.DataStorePath, Counters = new List <CounterPoco>() { new CounterPoco { CounterId = 181, CounterSensorMappings = new List <CounterSensorMappingPoco> { counterSensorMappingsSmartMeter } }, new CounterPoco { CounterId = 182, CounterSensorMappings = new List <CounterSensorMappingPoco> { counterSensorMappingsSmartMeter } }, new CounterPoco { CounterId = 281, CounterSensorMappings = new List <CounterSensorMappingPoco> { counterSensorMappingsSmartMeter } }, new CounterPoco { CounterId = 282, CounterSensorMappings = new List <CounterSensorMappingPoco> { counterSensorMappingsSmartMeter } }, new CounterPoco { CounterId = 2421, CounterSensorMappings = new List <CounterSensorMappingPoco> { counterSensorMappingsSmartMeter } }, new CounterPoco { CounterId = 1, // This is not correct, since the Eltako's have different formula's. Keep it simple for now. CounterSensorMappings = new List <CounterSensorMappingPoco> { counterSensorMappingsSmartMeter } } }, Clients = new List <ClientQboxPoco>() { new ClientQboxPoco { ClientId = 0, MeterType = DeviceMeterType.Smart_Meter_EG, // Main meter type for second Qbox of Duo. SecondaryMeterType = DeviceMeterType.SO_Pulse // Should be DeviceMeterType.SO_Pulse for Mono with Qbox Solar. } }, Precision = Precision.mWh, MeterType = DeviceMeterType.NO_Meter, // This should contain the actual meter type for Mono. SecondaryMeterType = DeviceMeterType.None, // This should be DeviceMeterType.SO_Pulse for Mono with Qbox Solar. AutoAnswer = true }; if (mini != null) { mini.PrepareCounters(); } return(mini); } catch (Exception e) { Log.Error(e, e.Message); } throw new ArgumentOutOfRangeException("sn"); }