public static List <IPlcAlarm> TranslateFromSslData(Memory <byte> memory, int size)
        {
            // We do not need the header
            var result = new List <IPlcAlarm>();
            var offset = 6;
            var span   = memory.Span;

            while (offset < size)
            {
                var item = new S7PlcAlarmItemDatagram
                {
                    Length        = span[offset++],
                    TransportSize = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(offset, 2))
                };
                offset        += 2;
                item.AlarmType = span[offset++] == 4 ? AlarmMessageType.AlarmS : AlarmMessageType.Unknown;
                item.MsgNumber = BinaryPrimitives.ReadUInt32BigEndian(span.Slice(offset, 4));
                offset        += 2; // 2 is correct, we use the offset twice
                item.Id        = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(offset, 2));
                offset        += 2;

                item.EventState     = span[offset++]; // 0x00 == going   0x01  == coming
                item.State          = span[offset++]; // isAck
                item.AckStateGoing  = span[offset++];
                item.AckStateComing = span[offset++]; // 0x00 == no ack  0x01  == ack

                if (size >= offset + 12)
                {
                    item.Coming = S7PlcAlarmDetails.ExtractDetails(ref span, ref offset);
                }
                if (size >= offset + 12)
                {
                    item.Going = S7PlcAlarmDetails.ExtractDetails(ref span, ref offset);
                }

                result.Add(item);
            }

            return(result);
        }
Exemple #2
0
        public static S7AlarmMessage TranslateFromMemory(Memory <byte> data, AlarmMessageType subfunction)
        {
            var span    = data.Span;
            var current = new S7AlarmMessage();
            var offset  = 0;

            current.Timestamp          = GetDt(span.Slice(offset)); offset += 8;
            current.FunctionIdentifier = span[offset++];
            current.NumberOfMessages   = span[offset++];

            var alarms = new List <S7PlcAlarmItemDatagram>();

            for (var i = 0; i < current.NumberOfMessages; i++)
            {
                var alarm = new S7PlcAlarmItemDatagram
                {
                    AlarmType = subfunction
                };

                //var varspec = span[offset];
                offset++;
                alarm.Length = span[offset++];

                if (alarm.Length > 0)
                {
                    var syntaxId = span[offset++];

                    switch (syntaxId)
                    {
                    case (byte)SyntaxIds.AlarmInd:
                    case (byte)SyntaxIds.AlarmAck:
                    {
                        //var numberOfAssociatedValues = span[offset];
                        offset++;
                        alarm.MsgNumber = BinaryPrimitives.ReadUInt32BigEndian(span.Slice(offset, 4));
                        offset         += 2; // 2 is correct, we use the offset twice
                        alarm.Id        = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(offset, 2));
                        offset         += 2;


                        switch (subfunction)
                        {
                        case AlarmMessageType.AlarmSQ:             // ALARM_SQ
                        case AlarmMessageType.AlarmS:              // ALARM_S
                        {
                            alarm.EventState     = span[offset++]; // 0x00 == going   0x01  == coming
                            alarm.State          = span[offset++]; // isAck
                            alarm.AckStateGoing  = span[offset++];
                            alarm.AckStateComing = span[offset++]; // 0x00 == no ack  0x01  == ack

                            var details = new S7PlcAlarmDetails {
                                Timestamp = current.Timestamp
                            };
                            S7PlcAlarmDetails.ExtractAssotiatedValue(ref span, ref offset, details);

                            if (alarm.EventState == 0x00)
                            {
                                alarm.Going = details;
                            }
                            else if (alarm.EventState == 0x01)
                            {
                                alarm.Coming = details;
                            }
                        }
                        break;

                        case AlarmMessageType.AlarmAck:             // ALARM ack
                        {
                            alarm.AckStateGoing  = span[offset++];
                            alarm.AckStateComing = span[offset++];                 // 0x00 == no ack  0x01  == ack
                        }
                        break;

                        default:
                        {
                            ThrowHelper.ThrowUnknownAlarmSubfunction(subfunction);
                            break;
                        }
                        }
                        break;
                    }

                    default:
                    {
                        ThrowHelper.ThrowUnknownAlarmSyntax(syntaxId);
                        break;
                    }
                    }
                }

                alarms.Add(alarm);
            }
            current.Alarms = alarms;
            return(current);
        }