Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
TransducerAccessMessage.cs
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using Waher.Content;
11
13{
18 {
19 private TransducerData data;
20 private ushort errorCode;
21
34 {
35 this.TransducerAccessService = TransducerAccessService;
36 }
37
42
46 public override string NetworkServiceIdName => this.TransducerAccessService.ToString();
47
57 public bool TryParseTransducerData(ThingReference Thing, Teds ChannelTeds, Unit PreferredUnit, out ushort ErrorCode, out TransducerData Data)
58 {
59 if (!(this.data is null))
60 {
61 ErrorCode = this.errorCode;
62 Data = this.data;
63 return true;
64 }
65
66 Data = null;
67
68 try
69 {
70 this.Position = 0;
71 if (this.MessageType == MessageType.Reply)
72 ErrorCode = this.NextUInt16(nameof(ErrorCode));
73 else
74 ErrorCode = 0;
75
76 ChannelAddress ChannelInfo = this.NextChannelId(true);
77 List<Field> Fields = new List<Field>();
78
79 switch (this.TransducerAccessService)
80 {
81 case TransducerAccessService.SyncReadTransducerSampleDataFromAChannelOfATIM:
82 string Value = this.NextString(nameof(Value));
83 DateTime Timestamp = this.NextTime(nameof(Timestamp)).ToDateTime();
84
85 if (CommonTypes.TryParse(Value, out double NumericValue, out byte NrDecimals))
86 {
87 string FieldName = "Value";
88 string Unit = string.Empty;
89
90 if (!(ChannelTeds is null))
91 {
92 FieldName = ChannelTeds.FieldName ?? FieldName;
93
94 if (!(PreferredUnit is null) &&
95 !(ChannelTeds.FieldUnit is null) &&
96 Script.Units.Unit.TryConvert(NumericValue, ChannelTeds.FieldUnit, NrDecimals, PreferredUnit, out double ConvertedValue, out byte NrDec2))
97 {
98 NumericValue = ConvertedValue;
99 Unit = PreferredUnit.ToString();
100 NrDecimals = NrDec2;
101 }
102 else
103 Unit = ChannelTeds.Unit;
104 }
105
106 Fields.Add(new QuantityField(Thing, Timestamp, FieldName,
107 NumericValue, NrDecimals, Unit, FieldType.Momentary,
108 FieldQoS.AutomaticReadout));
109 }
110 else
111 {
112 Fields.Add(new StringField(Thing, Timestamp, "Value", Value,
113 FieldType.Momentary, FieldQoS.AutomaticReadout));
114 }
115
116 // TODO: Historic value vs. Momentary value
117 break;
118
119 default:
120 return false;
121 }
122
123 Data = new TransducerData(ChannelInfo, Fields.ToArray());
124
125 if (!(ChannelTeds is null))
126 this.data = Data;
127
128 this.errorCode = ErrorCode;
129 return true;
130 }
131 catch (Exception)
132 {
133 ErrorCode = 0xffff;
134 return false;
135 }
136 }
137
146 out double TimeoutSeconds)
147 {
148 try
149 {
150 Channel = this.NextChannelId(true);
151 SamplingMode = this.NextUInt8<SamplingMode>(nameof(SamplingMode));
152 TimeoutSeconds = this.NextTimeDurationSeconds(nameof(TimeoutSeconds));
153
154 return true;
155 }
156 catch (Exception)
157 {
158 Channel = null;
159 SamplingMode = 0;
160 TimeoutSeconds = 0;
161
162 return false;
163 }
164 }
165
176 public static byte[] SerializeRequest(byte[] NcapId, byte[] TimId, ushort ChannelId,
177 SamplingMode SamplingMode, double TimeoutSeconds, StringBuilder SnifferOutput)
178 {
179 using (MemoryStream ms = new MemoryStream())
180 {
181 byte[] AppId = MeteringTopology.Root.ObjectId.ToByteArray();
182
183 ms.Write(AppId, 0, 16);
184 ms.Write(NcapId ?? EmptyUuid, 0, 16);
185 ms.Write(TimId ?? EmptyUuid, 0, 16);
186 ms.WriteByte((byte)(ChannelId >> 8));
187 ms.WriteByte((byte)ChannelId);
188 ms.WriteByte((byte)SamplingMode);
189
190 TimeoutSeconds *= 1e9 * 65536;
191 ulong l = (ulong)TimeoutSeconds;
192 byte[] Bin = BitConverter.GetBytes(l);
193 Array.Reverse(Bin);
194 ms.Write(Bin, 0, 8);
195
196 byte[] Result = Ieee1451Parser.SerializeMessage(
197 TransducerAccessService.SyncReadTransducerSampleDataFromAChannelOfATIM,
198 MessageType.Command, ms.ToArray(), SnifferOutput);
199
200 if (!(SnifferOutput is null))
201 {
202 SnifferOutput.Append("App ID: ");
203 SnifferOutput.AppendLine(Hashes.BinaryToString(AppId));
204 SnifferOutput.Append("NCAP ID: ");
205 SnifferOutput.AppendLine(Hashes.BinaryToString(NcapId ?? EmptyUuid));
206 SnifferOutput.Append("TIM ID: ");
207 SnifferOutput.AppendLine(Hashes.BinaryToString(TimId ?? EmptyUuid));
208 SnifferOutput.Append("Channel ID: ");
209 SnifferOutput.AppendLine(ChannelId.ToString());
210 SnifferOutput.Append("Sampling Mode: ");
211 SnifferOutput.AppendLine(SamplingMode.ToString());
212 SnifferOutput.Append("Timeout (s): ");
213 SnifferOutput.AppendLine(TimeoutSeconds.ToString());
214 }
215
216 return Result;
217 }
218 }
219
231 public static byte[] SerializeResponse(ushort ErrorCode, byte[] NcapId, byte[] TimId, ushort ChannelId,
232 string Value, DateTime Timestamp, StringBuilder SnifferOutput)
233 {
234 if (NcapId is null)
235 NcapId = new byte[16];
236 else if (NcapId.Length != 16)
237 throw new ArgumentException("Invalid NCAP UUID.", nameof(NcapId));
238
239 if (TimId is null)
240 TimId = new byte[16];
241 else if (TimId.Length != 16)
242 throw new ArgumentException("Invalid TIM UUID.", nameof(TimId));
243
244 using (MemoryStream ms = new MemoryStream())
245 {
246 byte[] AppId = MeteringTopology.Root.ObjectId.ToByteArray();
247
248 ms.WriteByte((byte)(ErrorCode >> 8));
249 ms.WriteByte((byte)ErrorCode);
250 ms.Write(AppId, 0, 16);
251 ms.Write(NcapId, 0, 16);
252 ms.Write(TimId, 0, 16);
253 ms.WriteByte((byte)(ChannelId >> 8));
254 ms.WriteByte((byte)ChannelId);
255
256 byte[] Bin = Encoding.UTF8.GetBytes(Value);
257 ms.Write(Bin, 0, Bin.Length);
258 ms.WriteByte(0);
259
260 Time Time = new Time(Timestamp);
261
262 ms.WriteByte((byte)(Time.Seconds >> 40));
263 ms.WriteByte((byte)(Time.Seconds >> 32));
264 ms.WriteByte((byte)(Time.Seconds >> 24));
265 ms.WriteByte((byte)(Time.Seconds >> 16));
266 ms.WriteByte((byte)(Time.Seconds >> 8));
267 ms.WriteByte((byte)Time.Seconds);
268 ms.WriteByte((byte)(Time.NanoSeconds >> 24));
269 ms.WriteByte((byte)(Time.NanoSeconds >> 16));
270 ms.WriteByte((byte)(Time.NanoSeconds >> 8));
271 ms.WriteByte((byte)Time.NanoSeconds);
272
273 byte[] Result = Ieee1451Parser.SerializeMessage(
274 TransducerAccessService.SyncReadTransducerSampleDataFromAChannelOfATIM,
275 MessageType.Reply, ms.ToArray(), SnifferOutput);
276
277 if (!(SnifferOutput is null))
278 {
279 SnifferOutput.Append("App ID: ");
280 SnifferOutput.AppendLine(Hashes.BinaryToString(AppId));
281 SnifferOutput.Append("NCAP ID: ");
282 SnifferOutput.AppendLine(Hashes.BinaryToString(NcapId));
283 SnifferOutput.Append("TIM ID: ");
284 SnifferOutput.AppendLine(Hashes.BinaryToString(TimId));
285 SnifferOutput.Append("Channel ID: ");
286 SnifferOutput.AppendLine(ChannelId.ToString());
287 SnifferOutput.Append("Value: ");
288 SnifferOutput.AppendLine(Value);
289 SnifferOutput.Append("Timestamp: ");
290 SnifferOutput.AppendLine(Timestamp.ToString());
291 }
292
293 return Result;
294 }
295 }
296 }
297}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static bool TryParse(string s, out double Value)
Tries to decode a string encoded double.
Definition: CommonTypes.cs:46
Represents a unit.
Definition: Unit.cs:15
override string ToString()
Definition: Unit.cs:517
static readonly Unit Empty
Empty unit.
Definition: Unit.cs:436
Contains methods for simple hash calculations.
Definition: Hashes.cs:59
static string BinaryToString(byte[] Data)
Converts an array of bytes to a string with their hexadecimal representations (in lower case).
Definition: Hashes.cs:65
string NextString(string Name)
Gets the next String.
Definition: Binary.cs:421
ICommunicationLayer ComLayer
Sniffable interface on which the message was received.
Definition: Binary.cs:75
Time NextTime(string Name)
Gets the next Time.
Definition: Binary.cs:464
double NextTimeDurationSeconds(string Name)
Gets the next time duration, expressed in seconds.
Definition: Binary.cs:480
ushort NextUInt16(string Name)
Gets the next ushort.
Definition: Binary.cs:206
ChannelAddress NextChannelId(bool AppId)
Parses a Channel ID from the message.
static readonly byte[] EmptyUuid
Empty UUID (16 zero bytes)
Definition: Message.cs:13
byte[] Tail
Bytes that are received after the body.
Definition: Message.cs:57
string Unit
Field unit of value, if found, otherwise the empty string.
Definition: Teds.cs:69
Unit FieldUnit
Field unit of value, if found, otherwise null.
Definition: Teds.cs:64
bool TryParseTransducerData(ThingReference Thing, Teds ChannelTeds, Unit PreferredUnit, out ushort ErrorCode, out TransducerData Data)
Tries to parse Transducer Data from the message.
TransducerAccessService TransducerAccessService
Transducer Access Service
TransducerAccessMessage(NetworkServiceType NetworkServiceType, TransducerAccessService TransducerAccessService, MessageType MessageType, byte[] Body, byte[] Tail, ICommunicationLayer ComLayer)
IEEE 1451.0 Transducer Access Message
static byte[] SerializeResponse(ushort ErrorCode, byte[] NcapId, byte[] TimId, ushort ChannelId, string Value, DateTime Timestamp, StringBuilder SnifferOutput)
Serializes a request for transducer data.
static byte[] SerializeRequest(byte[] NcapId, byte[] TimId, ushort ChannelId, SamplingMode SamplingMode, double TimeoutSeconds, StringBuilder SnifferOutput)
Serializes a request for transducer data.
bool TryParseRequest(out ChannelAddress Channel, out SamplingMode SamplingMode, out double TimeoutSeconds)
Tries to parse a Transfucer Access request from the message.
override string NetworkServiceIdName
Name of Message.NetworkServiceId
Static class for IEEE 1451-related parsing tasks.
static byte[] SerializeMessage(NetworkServiceType NetworkServiceType, byte NetworkServiceId, MessageType MessageType, byte[] Payload)
Creates a binary IEEE 1451.0 message.
Defines the Metering Topology data source. This data source contains a tree structure of persistent r...
Represents a physical quantity value.
Represents a string value.
Definition: StringField.cs:10
Contains a reference to a thing
Interface for observable classes implementing communication protocols.
MessageType
Network Service Message Type
Definition: MessageType.cs:7
TransducerAccessService
Transducer access service
NetworkServiceType
IEEE 1451.0 Network Service Type
FieldQoS
Field Quality of Service flags
Definition: FieldQoS.cs:10
FieldType
Field Type flags
Definition: FieldType.cs:10
Time representation in IEEE 1451.0
Definition: Time.cs:10
DateTime ToDateTime()
Converts the Time structure to a DateTime.
Definition: Time.cs:49