public static S7AlarmIndicationDatagram TranslateFromMemory(Memory <byte> data) { var current = new S7AlarmIndicationDatagram { UserData = S7UserDataDatagram.TranslateFromMemory(data), }; current.AlarmMessage = S7AlarmMessage.TranslateFromMemory(current.UserData.Data.Data, (AlarmMessageType)current.UserData.Parameter.SubFunction); return(current); }
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); }