Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
XmlData.cs
1using System;
3using System.Text;
4using System.Xml;
5using System.Threading.Tasks;
6using Waher.Content;
15
17{
21 public class XmlData : MqttData
22 {
23 private string xml;
24 private XmlDocument value;
25 private bool first = true;
26
30 public XmlData()
31 : base()
32 {
33 }
34
41 public XmlData(MqttTopic Topic, string Xml, XmlDocument Value)
42 : base(Topic)
43 {
44 this.xml = Xml;
45 this.value = Value;
46 }
47
54 public override Task<DataProcessingResult> DataReported(MqttTopic Topic, MqttContent Content)
55 {
56 try
57 {
58 string s = Content.DataString;
59
60 if (this.first)
61 {
62 if (!XML.IsValidXml(s))
63 return Task.FromResult(DataProcessingResult.Incompatible);
64
65 this.first = false;
66 }
67
68 this.value = XML.ParseXml(s, true);
69 this.xml = s;
70 this.Timestamp = DateTime.UtcNow;
71 this.QoS = Content.Header.QualityOfService;
72 this.Retain = Content.Header.Retain;
73
74 return Task.FromResult(DataProcessingResult.ProcessedNewMomentaryValues);
75 }
76 catch (Exception)
77 {
78 return Task.FromResult(DataProcessingResult.Incompatible);
79 }
80 }
81
85 public override Task<string> GetTypeName(Language Language)
86 {
87 return Language.GetStringAsync(typeof(MqttTopicNode), 41, "XML");
88 }
89
97 public override Task StartReadout(ThingReference ThingReference, ISensorReadout Request, string Prefix, bool Last)
98 {
99 List<Field> Fields = new List<Field>();
100
101 if (!(this.value.DocumentElement is null))
102 this.AppendFields(ThingReference, Fields, Request, this.value.DocumentElement, Prefix);
103
104 Request.ReportFields(Last, Fields.ToArray());
105
106 return Task.CompletedTask;
107 }
108
109 private void AppendFields(ThingReference ThingReference, List<Field> Fields, ISensorReadout Request, XmlElement Value, string Prefix)
110 {
111 if (Array.IndexOf(SensorClient.NamespacesSensorData, Value.NamespaceURI) >= 0)
112 {
114 if (!(SensorData.Fields is null))
115 Fields.AddRange(SensorData.Fields);
116 }
117 else
118 {
119 foreach (XmlAttribute Attribute in Value.Attributes)
120 {
121 if (string.IsNullOrEmpty(Prefix))
122 this.Add(ThingReference, Fields, Attribute.Name, Attribute.Value, Request);
123 else
124 this.Add(ThingReference, Fields, this.Append(Prefix, Attribute.Name), Attribute.Value, Request);
125 }
126
127 Dictionary<string, int> Repetitions = null;
128 string s;
129
130 foreach (XmlNode N in Value)
131 {
132 if (N is XmlElement ChildElement)
133 {
134 s = ChildElement.LocalName;
135
136 if (Repetitions is null)
137 Repetitions = new Dictionary<string, int>();
138
139 if (Repetitions.TryGetValue(s, out int i))
140 Repetitions[s] = i - 1;
141 else
142 Repetitions[s] = 0;
143 }
144 }
145
146 foreach (XmlNode N in Value)
147 {
148 if (N is XmlElement ChildElement)
149 {
150 s = ChildElement.LocalName;
151
152 if (Repetitions.TryGetValue(s, out int i))
153 {
154 if (i < 0)
155 Repetitions[s] = i = 1;
156 else if (i > 0)
157 Repetitions[s] = ++i;
158
159 if (i != 0)
160 s += ", #" + i.ToString();
161 }
162
163 if (string.IsNullOrEmpty(Prefix))
164 this.AppendFields(ThingReference, Fields, Request, ChildElement, s);
165 else
166 this.AppendFields(ThingReference, Fields, Request, ChildElement, Prefix + ", " + s);
167 }
168 else if (N is XmlText XmlText)
169 {
170 if (string.IsNullOrEmpty(Prefix))
171 this.Add(ThingReference, Fields, "Value", XmlText.InnerText, Request);
172 else
173 this.Add(ThingReference, Fields, Prefix, XmlText.InnerText, Request);
174 }
175 }
176 }
177 }
178
179 private void Add(ThingReference ThingReference, List<Field> Fields, string Name, string Value, ISensorReadout Request)
180 {
181 if (int.TryParse(Value, out int i))
182 this.Add(Fields, new Int32Field(ThingReference, this.Timestamp, Name, i, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
183 else if (long.TryParse(Value, out long l))
184 this.Add(Fields, new Int64Field(ThingReference, this.Timestamp, Name, l, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
185 else if (CommonTypes.TryParse(Value, out bool b))
186 this.Add(Fields, new BooleanField(ThingReference, this.Timestamp, Name, b, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
187 else if (CommonTypes.TryParse(Value, out double d, out byte NrDec))
188 this.Add(Fields, new QuantityField(ThingReference, this.Timestamp, Name, d, NrDec, string.Empty, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
189 else if (CommonTypes.TryParse(Value, out decimal d2, out NrDec))
190 this.Add(Fields, new QuantityField(ThingReference, this.Timestamp, Name, (double)d2, NrDec, string.Empty, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
191 else if (System.TimeSpan.TryParse(Value, out TimeSpan TimeSpan))
192 this.Add(Fields, new TimeField(ThingReference, this.Timestamp, Name, TimeSpan, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
193 else if (System.DateTime.TryParse(Value, out DateTime DateTime))
194 {
195 if (DateTime.TimeOfDay == TimeSpan.Zero)
196 this.Add(Fields, new DateField(ThingReference, this.Timestamp, Name, DateTime, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
197 else
198 this.Add(Fields, new DateTimeField(ThingReference, this.Timestamp, Name, DateTime, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
199 }
200 else if (CommonTypes.TryParseRfc822(Value, out DateTimeOffset DateTimeOffset))
201 this.Add(Fields, new DateTimeField(ThingReference, this.Timestamp, Name, DateTimeOffset.DateTime, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
202 else if (Content.Duration.TryParse(Value, out Duration Duration))
203 this.Add(Fields, new DurationField(ThingReference, this.Timestamp, Name, Duration, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
204 else
205 this.Add(Fields, new StringField(ThingReference, this.Timestamp, Name, Value, FieldType.Momentary, FieldQoS.AutomaticReadout), Request);
206 }
207
211 public override bool IsControllable => true;
212
217 {
218 return new ControlParameter[]
219 {
220 new MultiLineTextControlParameter("Value", "Publish", "Value:", "XML value of topic.",
221 (n) => Task.FromResult<string>(this.xml),
222 (n, v) =>
223 {
224 XmlDocument Doc = XML.ParseXml(v, true);
225 this.value = Doc;
226 this.xml = v;
227 this.Topic.MqttClient.PUBLISH(this.Topic.FullTopic, this.QoS, this.Retain, Encoding.UTF8.GetBytes(v));
228 return Task.CompletedTask;
229 })
230 };
231 }
232
236 public override void SnifferOutput(ICommunicationLayer Output)
237 {
238 this.Information(Output, this.xml);
239 }
240
244 public override Grade DefaultSupport => Grade.Excellent;
245
253 {
254 IMqttData Result = new XmlData(Topic, default, default);
255 Result.DataReported(Topic, Content);
256 return Result;
257 }
258 }
259}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:15
static bool TryParseRfc822(string s, out DateTimeOffset Value)
Parses a date and time value encoded according to RFC 822, §5.
Definition: CommonTypes.cs:172
static bool TryParse(string s, out double Value)
Tries to decode a string encoded double.
Definition: CommonTypes.cs:48
Helps with common XML-related tasks.
Definition: XML.cs:21
static XmlDocument ParseXml(string Xml)
Parses an XML Document from its string representation.
Definition: XML.cs:713
static bool IsValidXml(string Xml)
Checks if a string is valid XML
Definition: XML.cs:1397
Information about content received from the MQTT server.
Definition: MqttContent.cs:9
string DataString
String representation of UTF-8 encoded binary data.
Definition: MqttContent.cs:56
MqttHeader Header
MQTT Header
Definition: MqttContent.cs:35
Implements an XMPP sensor client interface.
Definition: SensorClient.cs:21
static readonly string[] NamespacesSensorData
Supported sensor-data namespaces.
Definition: SensorClient.cs:40
static SensorData ParseFields(XmlElement Content)
Parses sensor data field definitions.
Contains personal sensor data.
Definition: SensorData.cs:15
IEnumerable< Field > Fields
Sensor data fields.
Definition: SensorData.cs:73
Contains information about a language.
Definition: Language.cs:17
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
Definition: Language.cs:209
Abstract base class for control parameters.
Abstract base class for MQTT data encapsulations.
Definition: MqttData.cs:18
void Information(ICommunicationLayer Output, string Info)
Outputs information to sniffer.
Definition: MqttData.cs:91
DateTime Timestamp
Timestamp of data reception.
Definition: MqttData.cs:39
string Append(string Prefix, string Name)
Appends a name to a topic name.
Definition: MqttData.cs:100
Represents an MQTT topic with XML data.
Definition: XmlData.cs:22
XmlData()
Represents an MQTT topic with XML data.
Definition: XmlData.cs:30
override void SnifferOutput(ICommunicationLayer Output)
Outputs the parsed data to the sniffer.
Definition: XmlData.cs:236
override ControlParameter[] GetControlParameters()
TODO
Definition: XmlData.cs:216
override IMqttData CreateNew(MqttTopic Topic, MqttContent Content)
Creates a new instance of the data.
Definition: XmlData.cs:252
override Grade DefaultSupport
Default support.
Definition: XmlData.cs:244
override Task StartReadout(ThingReference ThingReference, ISensorReadout Request, string Prefix, bool Last)
Starts a readout of the data.
Definition: XmlData.cs:97
override Task< string > GetTypeName(Language Language)
Type name representing data.
Definition: XmlData.cs:85
XmlData(MqttTopic Topic, string Xml, XmlDocument Value)
Represents an MQTT topic with XML data.
Definition: XmlData.cs:41
override Task< DataProcessingResult > DataReported(MqttTopic Topic, MqttContent Content)
Called when new data has been published.
Definition: XmlData.cs:54
MQTT Topic information.
Definition: MqttTopic.cs:19
A Metering node representing an MQTT topic
Represents a boolean value that can be either true or false.
Definition: BooleanField.cs:11
Represents a date value.
Definition: DateField.cs:11
Represents a date and optional time value.
Represents a duration value. Duration values adhere to the type specified by xsd:duration.
Represents a 32-bit integer value.
Definition: Int32Field.cs:10
Represents a 64-bit integer value.
Definition: Int64Field.cs:10
Represents a physical quantity value.
Represents a string value.
Definition: StringField.cs:10
Represents a time value. Time values adhere to the type specified by xsd:time.
Definition: TimeField.cs:14
Contains a reference to a thing
Interface for observable classes implementing communication protocols.
Interface for classes managing sensor data readouts.
Task ReportFields(bool Done, params Field[] Fields)
Report read fields to the client.
Interface for MQTT Data encapsulations
Definition: IMqttData.cs:38
Task< DataProcessingResult > DataReported(MqttTopic Topic, MqttContent Content)
Called when new data has been published.
Grade
Grade enumeration
Definition: Grade.cs:7
DataProcessingResult
Results from processing an incoming message.
Definition: IMqttData.cs:17
FieldQoS
Field Quality of Service flags
Definition: FieldQoS.cs:10
FieldType
Field Type flags
Definition: FieldType.cs:10
Represents a duration value, as defined by the xsd:duration data type: http://www....
Definition: Duration.cs:14
MqttQualityOfService QualityOfService
Quality of Service level.
Definition: MqttHeader.cs:16