コード例 #1
0
ファイル: Command.cs プロジェクト: CK-Yong/QboxNext
        /// <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());
        }
コード例 #2
0
        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));
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
ファイル: Mini.cs プロジェクト: StefH/QboxNext
        public static string WriteMeterType(DeviceMeterType deviceMeterType)
        {
            var result = new BaseParseResult();

            result.Write((byte)3);
            var meterType = (byte)deviceMeterType;

            result.Write(meterType);
            return(result.GetMessage());
        }
コード例 #5
0
ファイル: ConsoleRunner.cs プロジェクト: StefH/QboxNext
        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()));
        }
コード例 #6
0
ファイル: Command.cs プロジェクト: CK-Yong/QboxNext
 /// <summary>
 /// Encode bytes to strings appropriate for putting in the response message.
 /// </summary>
 public static string Encode(params byte[] inBytes)
 {
     return(BaseParseResult.HexStr(inBytes));
 }
コード例 #7
0
ファイル: MiniDataHandler.cs プロジェクト: CK-Yong/QboxNext
        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);
                }
            }
        }
コード例 #8
0
ファイル: ErrorParseResult.cs プロジェクト: CK-Yong/QboxNext
 public ErrorParseResult(BaseParseResult baseParseResult)
 {
     SequenceNr = baseParseResult.SequenceNr;
     ProtocolNr = baseParseResult.ProtocolNr;
 }