2using System.Collections.Generic;
4using System.Threading.Tasks;
24 private bool firstMessage =
true;
58 this.firstMessage =
false;
60 this.Timestamp = DateTime.UtcNow;
90 await ProcessRequest(This,
Message);
104 await LogErrorAsync(This,
string.Empty, ex.Message);
113 bool ContainsMomentary =
false;
120 await RemoveErrorAsync(This,
"TransducerResponseError");
127 ContainsMomentary =
true;
130 await SubTopic.
Node.
LogErrorAsync(
"TranducerError",
"Transducer error: " + ErrorCode.ToString(
"X4"));
134 await LogErrorAsync(This,
"TransducerResponseError",
"Unable to parse Transducer response.");
143 await RemoveErrorAsync(This,
"TedsResponseError");
150 await SubTopic.
Node.
LogErrorAsync(
"TedsError",
"TEDS error: " + ErrorCode.ToString(
"X4"));
154 await LogErrorAsync(This,
"TedsResponseError",
"Unable to parse TEDS response.");
162 await RemoveErrorAsync(This,
"DiscoveryResponseError");
175 if (Created = SubTopic is
null)
178 if (SubTopic.
Node is MqttNcapTopicNode TopicNode)
179 await TopicNode.NameReceived(NcapEntity.Name);
184 await SubTopic.
Node.
LogErrorAsync(
"DiscoveryError",
"Discovery error: " + ErrorCode.ToString(
"X4"));
190 StringBuilder ToSniffer = BrokerNode.HasSniffers ?
new StringBuilder() : null;
193 if (!(ToSniffer is
null))
194 await BrokerNode.
Information(ToSniffer.ToString());
204 int i, c = Math.Min(TimEntities.Names.Length, TimEntities.Identities.Length);
206 for (i = 0; i < c; i++)
211 NcapId = TimEntities.Channel.NcapId,
212 TimId = TimEntities.Identities[i],
218 if (Created = SubTopic is
null)
221 if (SubTopic.
Node is MqttNcapTopicNode TopicNode)
222 await TopicNode.NameReceived(TimEntities.Names[i]);
227 await SubTopic.
Node.
LogErrorAsync(
"DiscoveryError",
"Discovery error: " + ErrorCode.ToString(
"X4"));
233 StringBuilder ToSniffer = BrokerNode.HasSniffers ?
new StringBuilder() : null;
236 if (!(ToSniffer is
null))
237 await BrokerNode.
Information(ToSniffer.ToString());
248 int i, c = Math.Min(Channels.Names.Length, Channels.Channels.Length);
250 for (i = 0; i < c; i++)
255 NcapId = Channels.Channel.NcapId,
256 TimId = Channels.Channel.TimId,
257 ChannelId = Channels.Channels[i],
262 if (SubTopic.
Node is MqttNcapTopicNode TopicNode)
263 await TopicNode.NameReceived(Channels.Names[i]);
268 await SubTopic.
Node.
LogErrorAsync(
"DiscoveryError",
"Discovery error: " + ErrorCode.ToString(
"X4"));
275 await LogErrorAsync(This,
"DiscoveryResponseError",
"Unable to parse Discovery response.");
282 if (!(SubTopic?.Node is MqttNcapTopicNode NcapTopicNode))
285 if (!NcapTopicNode.ResponseReceived(
Topic,
Message) && ContainsMomentary)
305 await RemoveErrorAsync(This,
"TransducerRequestError");
307 StringBuilder sb =
new StringBuilder();
313 if (!MessageSwitch.IsZero(Address.TimId))
318 if (Address.ChannelId != 0)
321 sb.Append(Address.ChannelId.ToString());
334 await LogErrorAsync(This,
"TransducerRequestError",
"Unable to parse Transducer request.");
365 out
double TimeoutSeconds))
367 await RemoveErrorAsync(This,
"TedsRequestError");
369 StringBuilder sb =
new StringBuilder();
375 if (!MessageSwitch.IsZero(Address.TimId))
380 if (Address.ChannelId != 0)
383 sb.Append(Address.ChannelId.ToString());
389 if (!(SubTopic?.Node is
ITedsNode TedsNode))
396 await LogErrorAsync(This,
"TedsRequestError",
"Unable to parse TEDS request.");
404 await RemoveErrorAsync(This,
"DiscoveryRequestError");
406 StringBuilder sb =
new StringBuilder();
409 if (!MessageSwitch.IsZero(Data.Channel.TimId))
414 if (!MessageSwitch.IsZero(Data.Channel.TimId))
419 if (Data.Channel.ChannelId != 0)
422 sb.Append(Data.Channel.ChannelId.ToString());
431 bool Broadcast = SubTopic.LocalTopic ==
"D0" &&
432 await Node.GetParent() is RootTopic;
434 LinkedList<INode> ToProcess =
new LinkedList<INode>();
435 IEnumerable<INode> ChildNodes;
439 ChildNodes = await Node.ChildNodes;
440 if (!(ChildNodes is
null))
442 foreach (
INode ChildNode
in ChildNodes)
443 ToProcess.AddLast(ChildNode);
447 ToProcess.AddLast(Node);
449 while (!(ToProcess.First is
null))
451 INode ChildNode = ToProcess.First.Value;
452 ToProcess.RemoveFirst();
454 bool CheckChildren = Broadcast;
459 CheckChildren = ChildNode is DiscoverableTopicNode;
464 if (!(ChildNodes is
null))
466 foreach (
INode ChildNode2
in ChildNodes)
467 ToProcess.AddLast(ChildNode2);
475 await LogErrorAsync(This,
"DiscoveryRequestError",
"Unable to parse TEDS request.");
481 private static Task LogErrorAsync(
MqttData This,
string EventId,
string Message)
486 private static Task RemoveErrorAsync(
MqttData This,
string EventId)
505 List<Field> Data =
new List<Field>()
511 if (!(this.value is
null) && this.value.Length <= 256)
514 Convert.ToBase64String(
this.value),
FieldType.Momentary,
FieldQoS.AutomaticReadout));
519 return Task.CompletedTask;
Information about content received from the MQTT server.
ICommunicationLayer CommunicationLayer
Communication layer on which the message was received.
MqttHeader Header
MQTT Header
Contains methods for simple hash calculations.
static string BinaryToString(byte[] Data)
Converts an array of bytes to a string with their hexadecimal representations (in lower case).
Task LogInformationToSniffer()
Logs accumulated sniffer output to associated sniffable interface.
string GetTopic(string BaseTopic)
Gets the topic name of the corresponding node.
byte[] ApplicationId
Application ID
Discovery data about a collection of channels.
Discovery data about a collection of entities.
Discovery data about a single entity.
IEEE 1451.0 Discovery Message
static byte[] SerializeRequest(StringBuilder SnifferOutput)
Serializes an NCAP Discovery request.
DiscoveryService DiscoveryService
Discovery Service
bool TryParseMessage(out ushort ErrorCode, out DiscoveryData Data)
Tries to parse a Discovery message.
MessageType MessageType
Message Type
IEEE 1451.0 TEDS Access Message
bool TryParseRequest(out ChannelAddress Channel, out TedsAccessCode TedsAccessCode, out uint TedsOffset, out double TimeoutSeconds)
Tries to parse a TEDS request from the message.
Task<(ushort ErrorCode, Teds Teds)> TryParseTeds()
Tries to parse a TEDS from the message.
ChannelAddress ChannelInfo
Address information.
IEEE 1451.0 Transducer Access Message
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
bool TryParseRequest(out ChannelAddress Channel, out SamplingMode SamplingMode, out double TimeoutSeconds)
Tries to parse a Transfucer Access request from the message.
Abstract base class for IEEE 1451.1.6 NCAPs.
override Grade DefaultSupport
Default support.
Ncap()
Abstract base class for IEEE 1451.1.6 NCAPs.
override Task StartReadout(ThingReference ThingReference, ISensorReadout Request, string Prefix, bool Last)
Starts a readout of the data.
Ncap(MqttTopic Topic, byte[] Value)
Abstract base class for IEEE 1451.1.6 NCAPs.
async Task< DataProcessingResult > DataReported(MqttTopic Topic, MqttContent Content, byte[] Data)
Called when new data has been published.
static async Task< DataProcessingResult > MessageReceived(MqttData This, MqttTopic Topic, Message Message)
Processes an IEEE 1451.0 message.
Static class for IEEE 1451-related parsing tasks.
static Task< Message > TryParseMessage(byte[] Data)
Tries to parse an IEEE 1451.0-encoded data.
Base class for all metering nodes.
Abstract base class for MQTT data encapsulations.
MqttTopic Topic
Topic used
DateTime Timestamp
Timestamp of data reception.
string Append(string Prefix, string Name)
Appends a name to a topic name.
MQTT Broker connection object.
Task Publish(string Topic, MqttQualityOfService QoS, bool Retain, byte[] Data)
Publishes binary data to a topic.
MqttBrokerNode Node
Reference to broker node.
async Task< MqttTopic > GetTopic(string TopicString, bool CreateNew, bool IgnoreGuids)
Gets the Node responsible for managing a Topic
MqttBroker Broker
MQTT Broker
string FullTopic
Full topic name
IMqttTopicNode Node
Reference to the MQTT Topic Node
Node representing a connection to an MQTT broker.
async Task Information(string Comment)
Called to inform the viewer of something.
Represents a 32-bit integer value.
Represents a string value.
Contains a reference to a thing
Interface for nodes that are published through the concentrator interface.
Task< IEnumerable< INode > > ChildNodes
Child nodes. If no child nodes are available, null is returned.
Interface for classes managing sensor data readouts.
Task ReportFields(bool Done, params Field[] Fields)
Report read fields to the client.
Interface for nodes that can be discovered on an IEEE 1451.0 network.
Interface for nodes that can return TEDS.
Interface for nodes that can return transducer information.
Task< bool > RemoveErrorAsync()
Removes error messages with an empty event ID from the node.
Task LogErrorAsync(string Body)
Logs an error message on the node.
MqttQualityOfService
MQTT Quality of Service level.
TedsAccessCode
TEDS Access Code
SamplingMode
Sampling Mode
DiscoveryService
Discovery Service
MessageType
Network Service Message Type
TransducerAccessService
Transducer access service
DataProcessingResult
Results from processing an incoming message.
FieldQoS
Field Quality of Service flags
FieldType
Field Type flags