Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
NodeReadActionGraph.cs
1using System;
3using System.Threading.Tasks;
14
16{
21 {
22 private readonly INode node;
23 private readonly string action;
24
30 public NodeReadActionGraph(INode Node, string Action)
31 {
32 this.node = Node;
33 this.action = Action;
34 }
35
43 {
44 UriNode NodeGraphUriNode = new UriNode(DataSourceGraph.GetNodeUri(this.node));
45
46 if (!(this.node is ISensor Sensor))
47 return;
48
49 FieldType FieldTypes = 0;
50
51 foreach (string Part in this.action.Split(' '))
52 {
53 switch (Part.Trim().ToLower())
54 {
55 case "all":
56 FieldTypes |= FieldType.All;
57 break;
58
59 case "momentary":
60 FieldTypes |= FieldType.Momentary;
61 break;
62
63 case "identity":
64 FieldTypes |= FieldType.Identity;
65 break;
66
67 case "status":
68 FieldTypes |= FieldType.Status;
69 break;
70
71 case "computed":
72 FieldTypes |= FieldType.Computed;
73 break;
74
75 case "peak":
76 FieldTypes |= FieldType.Peak;
77 break;
78
79 case "historical":
80 FieldTypes |= FieldType.Historical;
81 break;
82
83 case "nonhistorical":
84 FieldTypes |= FieldType.AllExceptHistorical;
85 break;
86 }
87 }
88
89 if (FieldTypes == 0)
90 return;
91
92 BlankNode Timestamps = new BlankNode("n" + Guid.NewGuid().ToString());
93 int TimestampIndex = 0;
94
95 Result.Add(NodeGraphUriNode, IoTSensorData.timestamps, Timestamps);
96 Result.Add(Timestamps, Rdf.type, Rdf.Seq);
97
98 BlankNode Errors = new BlankNode("n" + Guid.NewGuid().ToString());
99 int ErrorIndex = 0;
100
101 Result.Add(NodeGraphUriNode, IoTSensorData.errors, Errors);
102 Result.Add(Errors, Rdf.type, Rdf.Seq);
103
104 Dictionary<DateTime, TimestampRec> TimestampNodes = new Dictionary<DateTime, TimestampRec>();
105 IThingReference[] Nodes = new IThingReference[] { this.node };
106 ApprovedReadoutParameters Approval = await Gateway.ConcentratorServer.SensorServer.CanReadAsync(FieldTypes, Nodes, null, Caller)
107 ?? throw new ForbiddenException("Not authorized to read sensor-data from node.");
108 DateTime Timestamp = DateTime.MinValue;
109 TimestampRec TimestampRec = null;
110
111 TaskCompletionSource<bool> ReadoutCompleted = new TaskCompletionSource<bool>();
112 InternalReadoutRequest Request = await Gateway.ConcentratorServer.SensorServer.DoInternalReadout(Caller.From,
113 Approval.Nodes, Approval.FieldTypes, Approval.FieldNames, DateTime.MinValue, DateTime.MaxValue,
114 async (Sender, e) =>
115 {
116 foreach (Field F in e.Fields)
117 {
118 if (TimestampRec is null || F.Timestamp != Timestamp)
119 {
120 Timestamp = F.Timestamp;
121 if (!TimestampNodes.TryGetValue(Timestamp, out TimestampRec))
122 {
123 TimestampNodes[Timestamp] = TimestampRec = new TimestampRec()
124 {
125 Node = new BlankNode("n" + Guid.NewGuid().ToString()),
126 Fields = new BlankNode("n" + Guid.NewGuid().ToString()),
127 FieldIndex = 0
128 };
129
130 Result.Add(Timestamps, Rdf.ListItem(++TimestampIndex), TimestampRec.Node);
131 Result.Add(TimestampRec.Node, IoTSensorData.timestamp, Timestamp);
132 Result.Add(TimestampRec.Node, IoTSensorData.fields, TimestampRec.Fields);
133 Result.Add(TimestampRec.Fields, Rdf.type, Rdf.Seq);
134 }
135 }
136
137 BlankNode FieldNode = new BlankNode("n" + Guid.NewGuid().ToString());
138
139 Result.Add(TimestampRec.Fields, Rdf.ListItem(++TimestampRec.FieldIndex), FieldNode);
140
141 string LocalizedName;
142
143 if (F.StringIdSteps is null || F.StringIdSteps.Length == 0)
144 LocalizedName = null;
145 else
146 {
147 Namespace BaseModule;
148
149 if (string.IsNullOrEmpty(F.Module))
150 BaseModule = null;
151 else
152 BaseModule = await Language.GetNamespaceAsync(F.Module);
153
154 LocalizedName = await LocalizationStep.TryGetLocalization(Language, BaseModule, F.StringIdSteps);
155 }
156
157 if (string.IsNullOrEmpty(LocalizedName))
158 Result.Add(FieldNode, RdfSchema.label, F.Name);
159 else if (LocalizedName == F.Name)
160 Result.Add(FieldNode, RdfSchema.label, F.Name, Language.Code);
161 else
162 {
163 Result.Add(FieldNode, RdfSchema.label, F.Name);
164 Result.Add(FieldNode, RdfSchema.label, LocalizedName, Language.Code);
165 }
166
167 Result.Add(FieldNode, IoTSensorData.value, F.ObjectValue);
168
169 if (F.QoS.HasFlag(FieldQoS.Missing))
170 {
171 Result.Add(FieldNode, IoTSensorData.qos,
172 nameof(FieldQoS.Missing), IoTSensorData.qos);
173 }
174
175 if (F.QoS.HasFlag(FieldQoS.InProgress))
176 {
177 Result.Add(FieldNode, IoTSensorData.qos,
178 nameof(FieldQoS.InProgress), IoTSensorData.qos);
179 }
180
181 if (F.QoS.HasFlag(FieldQoS.AutomaticEstimate))
182 {
183 Result.Add(FieldNode, IoTSensorData.qos,
184 nameof(FieldQoS.AutomaticEstimate), IoTSensorData.qos);
185 }
186
187 if (F.QoS.HasFlag(FieldQoS.ManualEstimate))
188 {
189 Result.Add(FieldNode, IoTSensorData.qos,
190 nameof(FieldQoS.ManualEstimate), IoTSensorData.qos);
191 }
192
193 if (F.QoS.HasFlag(FieldQoS.ManualReadout))
194 {
195 Result.Add(FieldNode, IoTSensorData.qos,
196 nameof(FieldQoS.ManualReadout), IoTSensorData.qos);
197 }
198
199 if (F.QoS.HasFlag(FieldQoS.AutomaticReadout))
200 {
201 Result.Add(FieldNode, IoTSensorData.qos,
202 nameof(FieldQoS.AutomaticReadout), IoTSensorData.qos);
203 }
204
205 if (F.QoS.HasFlag(FieldQoS.TimeOffset))
206 {
207 Result.Add(FieldNode, IoTSensorData.qos,
208 nameof(FieldQoS.TimeOffset), IoTSensorData.qos);
209 }
210
211 if (F.QoS.HasFlag(FieldQoS.Warning))
212 {
213 Result.Add(FieldNode, IoTSensorData.qos,
214 nameof(FieldQoS.Warning), IoTSensorData.qos);
215 }
216
217 if (F.QoS.HasFlag(FieldQoS.Error))
218 {
219 Result.Add(FieldNode, IoTSensorData.qos,
220 nameof(FieldQoS.Error), IoTSensorData.qos);
221 }
222
223 if (F.QoS.HasFlag(FieldQoS.Signed))
224 {
225 Result.Add(FieldNode, IoTSensorData.qos,
226 nameof(FieldQoS.Signed), IoTSensorData.qos);
227 }
228
229 if (F.QoS.HasFlag(FieldQoS.Invoiced))
230 {
231 Result.Add(FieldNode, IoTSensorData.qos,
232 nameof(FieldQoS.Invoiced), IoTSensorData.qos);
233 }
234
235 if (F.QoS.HasFlag(FieldQoS.EndOfSeries))
236 {
237 Result.Add(FieldNode, IoTSensorData.qos,
238 nameof(FieldQoS.EndOfSeries), IoTSensorData.qos);
239 }
240
241 if (F.QoS.HasFlag(FieldQoS.PowerFailure))
242 {
243 Result.Add(FieldNode, IoTSensorData.qos,
244 nameof(FieldQoS.PowerFailure), IoTSensorData.qos);
245 }
246
247 if (F.QoS.HasFlag(FieldQoS.InvoiceConfirmed))
248 {
249 Result.Add(FieldNode, IoTSensorData.qos,
250 nameof(FieldQoS.InvoiceConfirmed), IoTSensorData.qos);
251 }
252
253 Result.Add(FieldNode, IoTConcentrator.isControllable, F.Writable);
254
255 if (F.Type.HasFlag(FieldType.Momentary))
256 {
257 Result.Add(FieldNode, Rdf.type,
258 nameof(FieldType.Momentary), IoTSensorData.fieldType);
259 }
260
261 if (F.Type.HasFlag(FieldType.Identity))
262 {
263 Result.Add(FieldNode, Rdf.type,
264 nameof(FieldType.Identity), IoTSensorData.fieldType);
265 }
266
267 if (F.Type.HasFlag(FieldType.Status))
268 {
269 Result.Add(FieldNode, Rdf.type,
270 nameof(FieldType.Status), IoTSensorData.fieldType);
271 }
272
273 if (F.Type.HasFlag(FieldType.Computed))
274 {
275 Result.Add(FieldNode, Rdf.type,
276 nameof(FieldType.Computed), IoTSensorData.fieldType);
277 }
278
279 if (F.Type.HasFlag(FieldType.Peak))
280 {
281 Result.Add(FieldNode, Rdf.type,
282 nameof(FieldType.Peak), IoTSensorData.fieldType);
283 }
284
285 if (F.Type.HasFlag(FieldType.Historical))
286 {
287 Result.Add(FieldNode, Rdf.type,
288 nameof(FieldType.Historical), IoTSensorData.fieldType);
289 }
290 }
291
292 if (e.Done)
293 ReadoutCompleted.TrySetResult(true);
294 },
295 (Sender, e) =>
296 {
297 foreach (ThingError Error in e.Errors)
298 {
299 BlankNode ErrorNode = new BlankNode("n" + Guid.NewGuid().ToString());
300
301 Result.Add(Errors, Rdf.ListItem(++ErrorIndex), ErrorNode);
302 Result.Add(ErrorNode, RdfSchema.label, Error.ErrorMessage);
303 Result.Add(ErrorNode, IoTSensorData.timestamp, Error.Timestamp);
304
305 if (!string.IsNullOrEmpty(Error.NodeId))
306 Result.Add(ErrorNode, IoTConcentrator.nodeId, Error.NodeId);
307
308 if (!string.IsNullOrEmpty(Error.SourceId))
309 Result.Add(ErrorNode, IoTConcentrator.sourceId, Error.SourceId);
310
311 if (!string.IsNullOrEmpty(Error.Partition))
312 Result.Add(ErrorNode, IoTConcentrator.partition, Error.Partition);
313 }
314
315 if (e.Done)
316 ReadoutCompleted.TrySetResult(true);
317
318 return Task.CompletedTask;
319 }, null);
320
321 Task Timeout = Task.Delay(60000);
322 Task T = await Task.WhenAny(ReadoutCompleted.Task, Timeout);
323
324 if (!ReadoutCompleted.Task.IsCompleted)
325 {
326 BlankNode ErrorNode = new BlankNode("n" + Guid.NewGuid().ToString());
327
328 Result.Add(Errors, Rdf.ListItem(++ErrorIndex), ErrorNode);
329 Result.Add(ErrorNode, RdfSchema.label, "Timeout.");
330 Result.Add(ErrorNode, IoTSensorData.timestamp, DateTime.UtcNow);
331 }
332 }
333
334 private class TimestampRec
335 {
336 public BlankNode Node;
337 public BlankNode Fields;
338 public int FieldIndex;
339 }
340
341 }
342}
Represents a blank node
Definition: BlankNode.cs:7
static readonly Uri Seq
URI representing rdf:Seq, an ordered container.
Definition: Rdf.cs:91
static readonly Uri type
URI representing rdf:type
Definition: Rdf.cs:51
static Uri ListItem(int Index)
URI representing an item in a list.
static readonly Uri label
http://www.w3.org/2000/01/rdf-schema#label
Definition: RdfSchema.cs:51
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:147
static ConcentratorServer ConcentratorServer
XMPP Concentrator Server.
Definition: Gateway.cs:4053
The server understood the request, but is refusing to fulfill it. Authorization will not help and the...
Contains information about what sensor data readout parameters have been approved.
Manages a chat sensor data readout request.
Contains information about a language.
Definition: Language.cs:17
string Code
Language code.
Definition: Language.cs:49
Tokens available in request.
Definition: RequestOrigin.cs:9
static readonly Uri isControllable
urn:nf:iot:concentrator:1.0:isControllable
static readonly Uri sourceId
urn:nf:iot:concentrator:1.0:sourceId
static readonly Uri partition
urn:nf:iot:concentrator:1.0:partition
static readonly Uri nodeId
urn:nf:iot:concentrator:1.0:nodeId
static readonly Uri timestamp
urn:nf:iot:sd:1.0:timestamp
static readonly Uri timestamps
urn:nf:iot:sd:1.0:timestamps
static readonly Uri value
urn:nf:iot:concentrator:1.0:value
static readonly Uri errors
urn:nf:iot:sd:1.0:errros
Makes harmonized data sources and nodes available as semantic information.
static Uri GetNodeUri(INode Node)
Gets the Graph URI for a node.
NodeReadActionGraph(INode Node, string Action)
Dynamic graph of a node node action.
async Task GenerateGraph(InMemorySemanticCube Result, Language Language, RequestOrigin Caller)
Generates the semantic graph.
Base class for all sensor data fields.
Definition: Field.cs:20
Contains information about an error on a thing
Definition: ThingError.cs:10
DateTime Timestamp
Timestamp of error.
Definition: ThingError.cs:65
string ErrorMessage
Error message.
Definition: ThingError.cs:70
string NodeId
ID of node.
string Partition
Optional partition in which the Node ID is unique.
string SourceId
Optional ID of source containing node.
Interface for nodes that are published through the concentrator interface.
Definition: INode.cs:49
Interface for sensor nodes.
Definition: ISensor.cs:9
Interface for thing references.
Interface for dynamic graphs.
FieldQoS
Field Quality of Service flags
Definition: FieldQoS.cs:10
FieldType
Field Type flags
Definition: FieldType.cs:10