/// <summary> /// Default metersettings, used after state waiting from host or waiting for metertype from client /// </summary> /// <param name="meterType"></param> /// <param name="client"></param> /// <returns></returns> public static string DefaultMeterSettings(DeviceMeterType meterType, QboxClient client) { var cmd = new BaseParseResult(); switch (meterType) { case DeviceMeterType.Ferraris_Black_Toothed: // Set calibration to 10 minutes cmd.Write(RequestCalibrateMeter); cmd.Write((byte)10); break; case DeviceMeterType.LED_TypeI: case DeviceMeterType.LED_TypeII: cmd.Write((byte)DeviceSettingType.SensorChannel); cmd.Write((byte)0x03); if (client != QboxClient.None) { cmd.Write((byte)ClientActivityRequest.RequestToRestartClient); cmd.Write((byte)client); } else { cmd.Write(RequestRestart); } break; } return(cmd.GetMessage()); }
private void BuildResult(BaseParseResult result, DateTime serverTime, ResponseType inResponseType) { // sequence number of the message received result.Write((byte)result.SequenceNr); // time in seconds since 1-1-2007 int seconds = Convert.ToInt32(serverTime.Subtract(Epoch).TotalSeconds); result.Write(seconds); result.Write(_context.Mini.Offset); // SequenceNr is 0-255. bool canSendAutoStatusCommand = inResponseType == ResponseType.Normal && CanSendAutoStatusCommand((byte)result.SequenceNr); bool canSendAutoAnswerCommand = inResponseType == ResponseType.Normal; var responseBuilder = new QboxResponseBuilder(_context.Mini, ClientRepositories.Queue, canSendAutoStatusCommand, canSendAutoAnswerCommand); var commands = responseBuilder.Build(); if (commands != null && commands.Count > 0) { result.Write(commands[0]); QueueCommands(commands.Skip(1)); } }
private bool TryMapCounterPayload(BaseParseResult result, CounterPayload payload, out CounterData counterData) { counterData = null; if (payload.Value == ulong.MaxValue) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. The payload value equals maximum ulong", _context.Mini.SerialNumber); return(false); } if ((payload is R21CounterPayload) && !(payload as R21CounterPayload).IsValid) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. The payload is of type R21CounterPayload but not valid for counter '{InternalNr}'", _context.Mini.SerialNumber, payload.InternalNr); return(false); } if (ClientNotConnected()) { // No connection with client, payload is last measured value and not the real value. First real value will be spread out over missing values _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. There is no connection with client, data not saved", _context.Mini.SerialNumber); return(false); } if (!MapCounterId(payload, _context.Mini)) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. Mapping the counter {InternalNr} failed", _context.Mini.SerialNumber, payload.InternalNr); return(false); } // store the data in the payload into the corresponding counter var counter = FindCounter(payload); if (counter == null) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. Received value for unknown counter: {InternalNr}", _context.Mini.SerialNumber, payload.InternalNr); return(false); } if (!(result is MiniParseResult parseResult)) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. The _result is not of type MiniParseResult", _context.Mini.SerialNumber); return(false); } // Counter is valid, set the LastDataReceived _context.Mini.QboxStatus.LastDataReceived = _dateTimeService.UtcNow; // Counter is valid, define a valid CounterData object counterData = new CounterData { SerialNumber = _context.Mini.SerialNumber, MeasureTime = parseResult.Model.MeasurementTime.ToUniversalTime(), // .ToAmsterdam(), // Change to Dutch Timezone CounterId = payload.InternalNr, PulseValue = Convert.ToInt32(payload.Value) }; return(true); }
public static string WriteMeterType(DeviceMeterType deviceMeterType) { var result = new BaseParseResult(); result.Write((byte)3); var meterType = (byte)deviceMeterType; result.Write(meterType); return(result.GetMessage()); }
private string ParseString(string message) { message = message.WithoutStxEtxEnvelope().Trim(); IMessageParser parser = _parserFactory.GetParser(message); BaseParseResult result = parser.Parse(message); // todo: evaluate // It's not possible to determine if hex is a request or response value, check is now based on ErrorParseResult if (result is ErrorParseResult) { parser = _parserFactory.GetParser(typeof(MiniResponse)); result = parser.Parse(message); } return(JsonConvert.SerializeObject(result, Formatting.Indented, new Newtonsoft.Json.Converters.StringEnumConverter())); }
/// <summary> /// Encode bytes to strings appropriate for putting in the response message. /// </summary> public static string Encode(params byte[] inBytes) { return(BaseParseResult.HexStr(inBytes)); }
public string Handle() { using (new ExtendedLogger(_context.Mini.SerialNumber)) { Log.Trace("Enter"); try { Log.Info("sn: {0} | input: {1} | lastUrl: {2}", _context.Mini.SerialNumber, _context.Message, _context.Mini.QboxStatus.Url); LogQboxMessage(_context.Message, QboxMessageType.Request); // start parsing var parser = _parserFactory.GetParser(_context.Message); _result = parser.Parse(_context.Message); // end of parsing if ((_result as MiniParseResult) != null) { var parseResult = (_result as MiniParseResult); // handle the result _context.Mini.QboxStatus.FirmwareVersion = parseResult.ProtocolNr; _context.Mini.State = parseResult.Model.Status.Status; _context.Mini.QboxStatus.State = (byte)parseResult.Model.Status.Status; var operational = false; switch (_context.Mini.State) { case MiniState.HardReset: _context.Mini.QboxStatus.LastHardReset = DateTime.UtcNow; break; case MiniState.InvalidImage: _context.Mini.QboxStatus.LastImageInvalid = DateTime.UtcNow; break; case MiniState.Operational: operational = true; break; case MiniState.ValidImage: _context.Mini.QboxStatus.LastImageValid = DateTime.UtcNow; break; case MiniState.UnexpectedReset: _context.Mini.QboxStatus.LastPowerLoss = DateTime.UtcNow; break; } if (!operational) { _context.Mini.QboxStatus.LastNotOperational = DateTime.UtcNow; } if (parseResult.Model.Status.TimeIsReliable) { _context.Mini.QboxStatus.LastTimeIsReliable = DateTime.UtcNow; } else { _context.Mini.QboxStatus.LastTimeUnreliable = DateTime.UtcNow; } if (parseResult.Model.Status.ValidResponse) { _context.Mini.QboxStatus.LastValidResponse = DateTime.UtcNow; } else { _context.Mini.QboxStatus.LastInvalidResponse = DateTime.UtcNow; } foreach (var payload in parseResult.Model.Payloads) { payload.Visit(this); } BuildResult(ResponseType.Normal); } else { var errorParseResult = _result as ErrorParseResult; if (errorParseResult != null) { LogQboxMessage(errorParseResult.Error, QboxMessageType.Error); } // We could not handle the message normally, but if we don't answer at all, the Qbox will just retransmit the message. // So we just send back the basic message, without handling the queue and auto-answer. BuildResult(ResponseType.Basic); } _context.Mini.QboxStatus.LastSeen = DateTime.UtcNow; Log.Debug("sn: {0} | result: {1}", _context.Mini.SerialNumber, _result.GetMessage()); LogQboxMessage(_result.GetMessageWithEnvelope(), QboxMessageType.Response); return(_result.GetMessageWithEnvelope()); } catch (Exception e) { if (_context.Mini != null) { _context.Mini.QboxStatus.LastSeen = DateTime.UtcNow; _context.Mini.QboxStatus.LastError = DateTime.UtcNow; _context.Mini.QboxStatus.LastErrorMessage = e.Message; } LogQboxMessage(e.ToString(), QboxMessageType.Exception); Log.Error(e, String.Format("sn: {0} | Error: {1}", _context.Mini.SerialNumber, e.Message)); return(e.Message); } } }
public ErrorParseResult(BaseParseResult baseParseResult) { SequenceNr = baseParseResult.SequenceNr; ProtocolNr = baseParseResult.ProtocolNr; }