Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DataSourceGraph.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading.Tasks;
5using System.Web;
20
22{
27 {
32 {
33 }
34
40 public Grade Supports(Uri GraphUri)
41 {
42 if (!Gateway.IsDomain(GraphUri.Host, true) ||
43 !string.IsNullOrEmpty(GraphUri.Query) ||
44 !string.IsNullOrEmpty(GraphUri.Fragment) ||
46 {
47 return Grade.NotAtAll;
48 }
49
50 string s = GraphUri.AbsolutePath;
51 string[] Parts = s.Split('/');
52 int c = Parts.Length;
53
54 if (c <= 1 || !string.IsNullOrEmpty(Parts[0]))
55 return Grade.NotAtAll;
56
57 if (string.IsNullOrEmpty(Parts[c - 1]))
58 c--;
59
60 if (c <= 2 || !Gateway.ConcentratorServer.TryGetDataSource(HttpUtility.UrlDecode(Parts[1]), out _))
61 return Grade.NotAtAll;
62
63 return Grade.Excellent;
64 }
65
74 public async Task<ISemanticCube> LoadGraph(Uri GraphUri, ScriptNode Node, bool NullIfNotFound,
75 RequestOrigin Caller)
76 {
77 if (!Gateway.IsDomain(GraphUri.Host, true) ||
78 !string.IsNullOrEmpty(GraphUri.Query) ||
79 !string.IsNullOrEmpty(GraphUri.Fragment) ||
81 {
82 return null;
83 }
84
85 string s = GraphUri.AbsolutePath;
86 string[] Parts = s.Split('/');
87 int c = Parts.Length;
88
89 if (c <= 1 || !string.IsNullOrEmpty(Parts[0]))
90 return null;
91
92 if (string.IsNullOrEmpty(Parts[c - 1]))
93 c--;
94
95 if (c <= 2)
96 return null;
97
98 string SourceID = HttpUtility.UrlDecode(Parts[1]);
99 if (!Gateway.ConcentratorServer.TryGetDataSource(SourceID, out IDataSource Source))
100 return null;
101
102 if (!await Source.CanViewAsync(Caller))
103 return null;
104
106 Language Language = await Translator.GetDefaultLanguageAsync(); // TODO: Check Accept-Language HTTP header.
107
108 switch (c)
109 {
110 case 2: // DOMAIN/Source
111 await AppendSourceInformation(Result, Source, Language, null);
112 break;
113
114 case 3: // /DOMAIN/Source/NodeID
115 string NodeID = HttpUtility.UrlDecode(Parts[2]);
116 INode NodeObj = await Source.GetNodeAsync(new ThingReference(NodeID, SourceID));
117 if (NodeObj is null)
118 return null;
119
120 await AppendNodeInformation(Result, NodeObj, Language, Caller);
121 break;
122
123 case 4: // /DOMAIN/Source/Partition/NodeID
124 string Partition = HttpUtility.UrlDecode(Parts[2]);
125 NodeID = HttpUtility.UrlDecode(Parts[3]);
126 NodeObj = await Source.GetNodeAsync(new ThingReference(NodeID, SourceID, Partition));
127 if (NodeObj is null)
128 return null;
129
130 await AppendNodeInformation(Result, NodeObj, Language, Caller);
131 break;
132
133 case 5: // /DOMAIN/Source/NodeID/Category/Action
134 NodeID = HttpUtility.UrlDecode(Parts[2]);
135 NodeObj = await Source.GetNodeAsync(new ThingReference(NodeID, SourceID));
136 if (NodeObj is null)
137 return null;
138
139 return await GetNodeActionGraph(Result, NodeObj, Language, HttpUtility.UrlDecode(Parts[3]),
140 HttpUtility.UrlDecode(Parts[4]), Caller);
141
142 case 6: // /DOMAIN/Source/Partition/NodeID/Category/Action
143 Partition = HttpUtility.UrlDecode(Parts[2]);
144 NodeID = HttpUtility.UrlDecode(Parts[3]);
145 NodeObj = await Source.GetNodeAsync(new ThingReference(NodeID, SourceID, Partition));
146 if (NodeObj is null)
147 return null;
148
149 return await GetNodeActionGraph(Result, NodeObj, Language, HttpUtility.UrlDecode(Parts[4]),
150 HttpUtility.UrlDecode(Parts[5]), Caller);
151
152 default:
153 return null;
154 }
155
156 return Result;
157 }
158
166 public static async Task AppendSourceInformation(InMemorySemanticCube Result,
168 {
169 if (Source is null)
170 return;
171
172 if (!(Caller is null) && !await Source.CanViewAsync(Caller))
173 return;
174
175 string SourcePath = "/" + HttpUtility.UrlEncode(Source.SourceID);
176 UriNode SourceGraphUriNode = new UriNode(new Uri(Gateway.GetUrl(SourcePath)));
177
178 Result.Add(new SemanticTriple(
179 SourceGraphUriNode,
182
183 Result.Add(new SemanticTriple(
184 SourceGraphUriNode,
186 new StringLiteral(Source.SourceID)));
187
188 Result.Add(new SemanticTriple(
189 SourceGraphUriNode,
191 new StringLiteral(await Source.GetNameAsync(Language))));
192
193 Result.Add(new SemanticTriple(
194 SourceGraphUriNode,
196 new DateTimeLiteral(Source.LastChanged)));
197
198 Result.Add(new SemanticTriple(
199 SourceGraphUriNode,
201 new BooleanLiteral(Source.HasChildren)));
202
203 if (Source.HasChildren)
204 {
205 foreach (IDataSource ChildSource in Source.ChildSources)
206 {
207 Result.Add(new SemanticTriple(
208 SourceGraphUriNode,
210 new UriNode(new Uri(Gateway.GetUrl("/" + HttpUtility.UrlEncode(ChildSource.SourceID))))));
211 }
212 }
213
214 IEnumerable<INode> RootNodes = Source.RootNodes;
215
216 if (!(RootNodes is null))
217 {
218 foreach (INode RootNode in RootNodes)
219 {
220 Result.Add(new SemanticTriple(
221 SourceGraphUriNode,
223 new UriNode(GetNodeUri(RootNode))));
224 }
225 }
226 }
227
233 public static Uri GetNodeUri(INode Node)
234 {
235 StringBuilder sb = new StringBuilder();
236 GetNodeUri(Node, sb);
237 return new Uri(Gateway.GetUrl(sb.ToString()));
238 }
239
245 private static void GetNodeUri(INode Node, StringBuilder sb)
246 {
247 sb.Append('/');
248 sb.Append(HttpUtility.UrlEncode(Node.SourceId));
249
250 if (!string.IsNullOrEmpty(Node.Partition))
251 {
252 sb.Append('/');
253 sb.Append(HttpUtility.UrlEncode(Node.Partition));
254 }
255
256 sb.Append('/');
257 sb.Append(HttpUtility.UrlEncode(Node.NodeId));
258 }
259
267 public static async Task AppendNodeInformation(InMemorySemanticCube Result,
268 INode Node, Language Language, RequestOrigin Caller)
269 {
270 if (Node is null)
271 return;
272
273 if (!await Node.CanViewAsync(Caller))
274 return;
275
276 UriNode NodeGraphUriNode = new UriNode(GetNodeUri(Node));
277
278 Result.Add(new SemanticTriple(
279 NodeGraphUriNode,
282
283 Result.Add(new SemanticTriple(
284 NodeGraphUriNode,
286 new StringLiteral(await Node.GetTypeNameAsync(Language))));
287
288 Result.Add(new SemanticTriple(
289 NodeGraphUriNode,
291 new StringLiteral(Node.SourceId)));
292
293 Result.Add(new SemanticTriple(
294 NodeGraphUriNode,
296 new StringLiteral(Node.NodeId)));
297
298 Result.Add(new SemanticTriple(
299 NodeGraphUriNode,
301 new StringLiteral(Node.LogId)));
302
303 Result.Add(new SemanticTriple(
304 NodeGraphUriNode,
306 new StringLiteral(Node.LocalId)));
307
308 Result.Add(new SemanticTriple(
309 NodeGraphUriNode,
311 new StringLiteral(Node.LocalId)));
312
313 if (!string.IsNullOrEmpty(Node.Partition))
314 {
315 Result.Add(new SemanticTriple(
316 NodeGraphUriNode,
318 new StringLiteral(Node.Partition)));
319 }
320
321 if (!(Node.Parent is null))
322 {
323 Result.Add(new SemanticTriple(
324 NodeGraphUriNode,
326 new UriNode(GetNodeUri(Node.Parent))));
327 }
328
329 Result.Add(new SemanticTriple(
330 NodeGraphUriNode,
332 new DateTimeLiteral(Node.LastChanged)));
333
334 Result.Add(new SemanticTriple(
335 NodeGraphUriNode,
337 new BooleanLiteral(Node.HasChildren)));
338
339 Result.Add(new SemanticTriple(
340 NodeGraphUriNode,
342 new BooleanLiteral(Node.HasCommands)));
343
344 Result.Add(new SemanticTriple(
345 NodeGraphUriNode,
347 new BooleanLiteral(Node.IsControllable)));
348
349 Result.Add(new SemanticTriple(
350 NodeGraphUriNode,
352 new BooleanLiteral(Node.IsReadable)));
353
354 Result.Add(new SemanticTriple(
355 NodeGraphUriNode,
357 new CustomLiteral(Node.State.ToString(), IoTConcentrator.NodeState.AbsoluteUri)));
358
359 IEnumerable<DisplayableParameters.Parameter> Parameters = await Node.GetDisplayableParametersAsync(Language, Caller);
360 int ItemIndex;
361
362 if (!(Parameters is null))
363 {
364 BlankNode DisplayableParameters = new BlankNode("n" + Guid.NewGuid().ToString());
365 ItemIndex = 0;
366
367 Result.Add(new SemanticTriple(
368 NodeGraphUriNode,
370 DisplayableParameters));
371
372 foreach (DisplayableParameters.Parameter P in Parameters)
373 {
374 BlankNode DisplayableParameter = new BlankNode("n" + Guid.NewGuid().ToString());
375
376 Result.Add(new SemanticTriple(
377 DisplayableParameters,
378 new UriNode(Rdf.ListItem(++ItemIndex)),
379 DisplayableParameter));
380
381 Result.Add(new SemanticTriple(
382 DisplayableParameter,
384 new StringLiteral(P.Name)));
385
386 Result.Add(new SemanticTriple(
387 DisplayableParameter,
389 new StringLiteral(P.Id)));
390
391 Result.Add(new SemanticTriple(
392 DisplayableParameter,
394 SemanticElements.Encapsulate(P.UntypedValue)));
395 }
396 }
397
398 IEnumerable<DisplayableParameters.Message> NodeMessages = await Node.GetMessagesAsync(Caller);
399 if (!(NodeMessages is null))
400 {
401 BlankNode Messages = new BlankNode("n" + Guid.NewGuid().ToString());
402 ItemIndex = 0;
403
404 Result.Add(new SemanticTriple(
405 NodeGraphUriNode,
407 Messages));
408
409 foreach (DisplayableParameters.Message M in NodeMessages)
410 {
411 BlankNode Message = new BlankNode("n" + Guid.NewGuid().ToString());
412
413 Result.Add(new SemanticTriple(
414 Messages,
415 new UriNode(Rdf.ListItem(++ItemIndex)),
416 Message));
417
418 Result.Add(new SemanticTriple(
419 Message,
421 new StringLiteral(M.Body)));
422
423 Result.Add(new SemanticTriple(
424 Message,
426 new DateTimeLiteral(M.Timestamp)));
427
428 if (!string.IsNullOrEmpty(M.EventId))
429 {
430 Result.Add(new SemanticTriple(
431 Message,
433 new StringLiteral(M.EventId)));
434 }
435
436 Result.Add(new SemanticTriple(
437 Message,
438 new UriNode(Rdf.Type),
439 new CustomLiteral(M.Type.ToString(), IoTConcentrator.MessageType.AbsoluteUri)));
440 }
441 }
442
443 if (Node.HasChildren)
444 {
445 foreach (INode ChildNode in await Node.ChildNodes)
446 {
447 Result.Add(new SemanticTriple(
448 NodeGraphUriNode,
450 new UriNode(GetNodeUri(ChildNode))));
451 }
452 }
453
454 if (Node.HasCommands)
455 {
456 BlankNode Commands = new BlankNode("n" + Guid.NewGuid().ToString());
457 ItemIndex = 0;
458
459 Result.Add(new SemanticTriple(
460 NodeGraphUriNode,
462 Commands));
463
464 IEnumerable<ICommand> NodeCommands = await Node.Commands;
465
466 if (!(Commands is null))
467 {
468 foreach (ICommand Command in NodeCommands)
469 {
470 if (!await Command.CanExecuteAsync(Caller))
471 continue;
472
473 UriNode CommandUriNode = new UriNode(GetCommandUri(Node, Command));
474
475 Result.Add(new SemanticTriple(
476 Commands,
477 new UriNode(Rdf.ListItem(++ItemIndex)),
478 CommandUriNode));
479
480 Result.Add(new SemanticTriple(
481 CommandUriNode,
484
485 Result.Add(new SemanticTriple(
486 CommandUriNode,
488 new StringLiteral(await Command.GetNameAsync(Language))));
489
490 Result.Add(new SemanticTriple(
491 CommandUriNode,
493 new StringLiteral(Command.CommandID)));
494
495 Result.Add(new SemanticTriple(
496 CommandUriNode,
498 new StringLiteral(Command.SortCategory)));
499
500 Result.Add(new SemanticTriple(
501 CommandUriNode,
503 new StringLiteral(Command.SortKey)));
504
505 Result.Add(new SemanticTriple(
506 CommandUriNode,
508 new CustomLiteral(Command.Type.ToString(), IoTConcentrator.CommandType.AbsoluteUri)));
509
510 AddOptionalStringLiteral(Result, CommandUriNode, IoTConcentrator.Success,
511 await Command.GetSuccessStringAsync(Language));
512
513 AddOptionalStringLiteral(Result, CommandUriNode, IoTConcentrator.Failure,
514 await Command.GetFailureStringAsync(Language));
515
516 AddOptionalStringLiteral(Result, CommandUriNode, IoTConcentrator.Confirmation,
517 await Command.GetConfirmationStringAsync(Language));
518 }
519 }
520 }
521
522 BlankNode Operations = new BlankNode("n" + Guid.NewGuid().ToString());
523 ItemIndex = 0;
524
525 Result.Add(new SemanticTriple(
526 NodeGraphUriNode,
528 Operations));
529
530 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Edit, GetOperationUri(Node, "edit", "parameters"),
531 await Language.GetStringAsync(typeof(DataSourceGraph), 1, "Editable parameters for the node."));
532
533 if (Node.IsReadable && Node is ISensor)
534 {
535 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "all"),
536 await Language.GetStringAsync(typeof(DataSourceGraph), 2, "Read all available sensor data from node."));
537
538 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "momentary"),
539 await Language.GetStringAsync(typeof(DataSourceGraph), 3, "Read momentary sensor data from node."));
540
541 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "identity"),
542 await Language.GetStringAsync(typeof(DataSourceGraph), 4, "Read identity sensor data from node."));
543
544 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "status"),
545 await Language.GetStringAsync(typeof(DataSourceGraph), 5, "Read status sensor data from node."));
546
547 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "computed"),
548 await Language.GetStringAsync(typeof(DataSourceGraph), 6, "Read computed sensor data from node."));
549
550 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "peak"),
551 await Language.GetStringAsync(typeof(DataSourceGraph), 7, "Read peak sensor data from node."));
552
553 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "historical"),
554 await Language.GetStringAsync(typeof(DataSourceGraph), 8, "Read historical sensor data from node."));
555
556 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Read, GetOperationUri(Node, "read", "nonHistorical"),
557 await Language.GetStringAsync(typeof(DataSourceGraph), 9, "Read all non-historical sensor data from node."));
558 }
559
560 if (Node.IsControllable && Node is IActuator Actuator)
561 {
562 foreach (ControlParameter P in await Actuator.GetControlParameters())
563 {
564 AddOperation(Result, Operations, ref ItemIndex, IoTConcentrator.Control, GetOperationUri(Node, "control", P.Name),
565 string.IsNullOrEmpty(P.Description) ? await Language.GetStringAsync(typeof(DataSourceGraph), 10, "Control parameter.") : P.Description);
566 }
567 }
568 }
569
570 private static void AddOptionalStringLiteral(InMemorySemanticCube Result,
571 ISemanticElement Subject, Uri PredicateUri, string Value)
572 {
573 if (!string.IsNullOrEmpty(Value))
574 {
575 Result.Add(new SemanticTriple(
576 Subject,
577 new UriNode(PredicateUri),
578 new StringLiteral(Value)));
579 }
580 }
581
582 private static void AddOperation(InMemorySemanticCube Result, BlankNode Operations, ref int ItemIndex, Uri Predicate, Uri Graph, string Label)
583 {
584 BlankNode Operation = new BlankNode("n" + Guid.NewGuid().ToString());
585
586 Result.Add(new SemanticTriple(
587 Operations,
588 new UriNode(Rdf.ListItem(++ItemIndex)),
589 Operation));
590
591 Result.Add(new SemanticTriple(
592 Operation,
593 new UriNode(Predicate),
594 new UriNode(Graph)));
595
596 Result.Add(new SemanticTriple(
597 Operation,
599 new StringLiteral(Label)));
600 }
601
608 public static Uri GetCommandUri(INode Node, ICommand Command)
609 {
610 StringBuilder sb = new StringBuilder();
611 GetCommandUri(Node, Command, sb);
612 return new Uri(Gateway.GetUrl(sb.ToString()));
613 }
614
621 private static void GetCommandUri(INode Node, ICommand Command, StringBuilder sb)
622 {
623 GetNodeUri(Node, sb);
624 sb.Append("/cmd/");
625 sb.Append(HttpUtility.UrlEncode(Command.CommandID));
626 }
627
634 private static Uri GetOperationUri(INode Node, string Category, string Action)
635 {
636 StringBuilder sb = new StringBuilder();
637 GetOperationUri(Node, Category, Action, sb);
638 return new Uri(Gateway.GetUrl(sb.ToString()));
639 }
640
648 private static void GetOperationUri(INode Node, string Category, string Action, StringBuilder sb)
649 {
650 GetNodeUri(Node, sb);
651 sb.Append('/');
652 sb.Append(Category);
653 sb.Append('/');
654 sb.Append(Action);
655 }
656
657 private static async Task<ISemanticCube> GetNodeActionGraph(InMemorySemanticCube Result,
658 INode Node, Language Language, string Category, string Action, RequestOrigin Caller)
659 {
660 UriNode NodeGraphUriNode = new UriNode(GetNodeUri(Node));
661
662 switch (Category)
663 {
664 case "read":
665 if (!(Node is ISensor Sensor))
666 return null;
667
668 FieldType FieldTypes = 0;
669
670 foreach (string Part in Action.Split(' '))
671 {
672 switch (Part.Trim().ToLower())
673 {
674 case "all":
675 FieldTypes |= FieldType.All;
676 break;
677
678 case "momentary":
679 FieldTypes |= FieldType.Momentary;
680 break;
681
682 case "identity":
683 FieldTypes |= FieldType.Identity;
684 break;
685
686 case "status":
687 FieldTypes |= FieldType.Status;
688 break;
689
690 case "computed":
691 FieldTypes |= FieldType.Computed;
692 break;
693
694 case "peak":
695 FieldTypes |= FieldType.Peak;
696 break;
697
698 case "historical":
699 FieldTypes |= FieldType.Historical;
700 break;
701
702 case "nonhistorical":
703 FieldTypes |= FieldType.AllExceptHistorical;
704 break;
705 }
706 }
707
708 if (FieldTypes == 0)
709 return null;
710
711 BlankNode Fields = new BlankNode("n" + Guid.NewGuid().ToString());
712 int FieldIndex = 0;
713
714 Result.Add(new SemanticTriple(
715 NodeGraphUriNode,
717 Fields));
718
719 BlankNode Errors = new BlankNode("n" + Guid.NewGuid().ToString());
720 int ErrorIndex = 0;
721
722 Result.Add(new SemanticTriple(
723 NodeGraphUriNode,
725 Errors));
726
727 IThingReference[] Nodes = new IThingReference[] { Node };
728 ApprovedReadoutParameters Approval = await Gateway.ConcentratorServer.SensorServer.CanReadAsync(FieldTypes, Nodes, null, Caller)
729 ?? throw new ForbiddenException("Not authorized to read sensor-data from node.");
730
731 TaskCompletionSource<bool> ReadoutCompleted = new TaskCompletionSource<bool>();
732 InternalReadoutRequest Request = await Gateway.ConcentratorServer.SensorServer.DoInternalReadout(Caller.From,
733 Approval.Nodes, Approval.FieldTypes, Approval.FieldNames, DateTime.MinValue, DateTime.MaxValue,
734 async (Sender, e) =>
735 {
736 foreach (Field F in e.Fields)
737 {
738 BlankNode FieldNode = new BlankNode("n" + Guid.NewGuid().ToString());
739
740 Result.Add(new SemanticTriple(
741 Fields,
742 new UriNode(Rdf.ListItem(++FieldIndex)),
743 FieldNode));
744
745 string LocalizedName;
746
747 if (F.StringIdSteps is null || F.StringIdSteps.Length == 0)
748 LocalizedName = null;
749 else
750 {
751 Namespace BaseModule;
752
753 if (string.IsNullOrEmpty(F.Module))
754 BaseModule = null;
755 else
756 BaseModule = await Language.GetNamespaceAsync(F.Module);
757
758 LocalizedName = await LocalizationStep.TryGetLocalization(Language, BaseModule, F.StringIdSteps);
759 }
760
761 if (string.IsNullOrEmpty(LocalizedName))
762 {
763 Result.Add(new SemanticTriple(
764 FieldNode,
766 new StringLiteral(F.Name)));
767 }
768 else if (LocalizedName == F.Name)
769 {
770 Result.Add(new SemanticTriple(
771 FieldNode,
772 new UriNode(RdfSchema.Label),
773 new StringLiteral(F.Name, Language.Code)));
774 }
775 else
776 {
777 Result.Add(new SemanticTriple(
778 FieldNode,
779 new UriNode(RdfSchema.Label),
780 new StringLiteral(F.Name)));
781
782 Result.Add(new SemanticTriple(
783 FieldNode,
784 new UriNode(RdfSchema.Label),
785 new StringLiteral(LocalizedName, Language.Code)));
786 }
787
788 Result.Add(new SemanticTriple(
789 FieldNode,
791 SemanticElements.Encapsulate(F.ObjectValue)));
792
793 Result.Add(new SemanticTriple(
794 FieldNode,
796 new DateTimeLiteral(F.Timestamp)));
797
798 if (F.QoS.HasFlag(FieldQoS.Missing))
799 {
800 Result.Add(new SemanticTriple(
801 FieldNode,
802 new UriNode(IoTSensorData.QoSUri),
803 new CustomLiteral(nameof(FieldQoS.Missing), IoTSensorData.QoS)));
804 }
805
806 if (F.QoS.HasFlag(FieldQoS.InProgress))
807 {
808 Result.Add(new SemanticTriple(
809 FieldNode,
810 new UriNode(IoTSensorData.QoSUri),
811 new CustomLiteral(nameof(FieldQoS.InProgress), IoTSensorData.QoS)));
812 }
813
814 if (F.QoS.HasFlag(FieldQoS.AutomaticEstimate))
815 {
816 Result.Add(new SemanticTriple(
817 FieldNode,
818 new UriNode(IoTSensorData.QoSUri),
819 new CustomLiteral(nameof(FieldQoS.AutomaticEstimate), IoTSensorData.QoS)));
820 }
821
822 if (F.QoS.HasFlag(FieldQoS.ManualEstimate))
823 {
824 Result.Add(new SemanticTriple(
825 FieldNode,
826 new UriNode(IoTSensorData.QoSUri),
827 new CustomLiteral(nameof(FieldQoS.ManualEstimate), IoTSensorData.QoS)));
828 }
829
830 if (F.QoS.HasFlag(FieldQoS.ManualReadout))
831 {
832 Result.Add(new SemanticTriple(
833 FieldNode,
834 new UriNode(IoTSensorData.QoSUri),
835 new CustomLiteral(nameof(FieldQoS.ManualReadout), IoTSensorData.QoS)));
836 }
837
838 if (F.QoS.HasFlag(FieldQoS.AutomaticReadout))
839 {
840 Result.Add(new SemanticTriple(
841 FieldNode,
842 new UriNode(IoTSensorData.QoSUri),
843 new CustomLiteral(nameof(FieldQoS.AutomaticReadout), IoTSensorData.QoS)));
844 }
845
846 if (F.QoS.HasFlag(FieldQoS.TimeOffset))
847 {
848 Result.Add(new SemanticTriple(
849 FieldNode,
850 new UriNode(IoTSensorData.QoSUri),
851 new CustomLiteral(nameof(FieldQoS.TimeOffset), IoTSensorData.QoS)));
852 }
853
854 if (F.QoS.HasFlag(FieldQoS.Warning))
855 {
856 Result.Add(new SemanticTriple(
857 FieldNode,
858 new UriNode(IoTSensorData.QoSUri),
859 new CustomLiteral(nameof(FieldQoS.Warning), IoTSensorData.QoS)));
860 }
861
862 if (F.QoS.HasFlag(FieldQoS.Error))
863 {
864 Result.Add(new SemanticTriple(
865 FieldNode,
866 new UriNode(IoTSensorData.QoSUri),
867 new CustomLiteral(nameof(FieldQoS.Error), IoTSensorData.QoS)));
868 }
869
870 if (F.QoS.HasFlag(FieldQoS.Signed))
871 {
872 Result.Add(new SemanticTriple(
873 FieldNode,
874 new UriNode(IoTSensorData.QoSUri),
875 new CustomLiteral(nameof(FieldQoS.Signed), IoTSensorData.QoS)));
876 }
877
878 if (F.QoS.HasFlag(FieldQoS.Invoiced))
879 {
880 Result.Add(new SemanticTriple(
881 FieldNode,
882 new UriNode(IoTSensorData.QoSUri),
883 new CustomLiteral(nameof(FieldQoS.Invoiced), IoTSensorData.QoS)));
884 }
885
886 if (F.QoS.HasFlag(FieldQoS.EndOfSeries))
887 {
888 Result.Add(new SemanticTriple(
889 FieldNode,
890 new UriNode(IoTSensorData.QoSUri),
891 new CustomLiteral(nameof(FieldQoS.EndOfSeries), IoTSensorData.QoS)));
892 }
893
894 if (F.QoS.HasFlag(FieldQoS.PowerFailure))
895 {
896 Result.Add(new SemanticTriple(
897 FieldNode,
898 new UriNode(IoTSensorData.QoSUri),
899 new CustomLiteral(nameof(FieldQoS.PowerFailure), IoTSensorData.QoS)));
900 }
901
902 if (F.QoS.HasFlag(FieldQoS.InvoiceConfirmed))
903 {
904 Result.Add(new SemanticTriple(
905 FieldNode,
906 new UriNode(IoTSensorData.QoSUri),
907 new CustomLiteral(nameof(FieldQoS.InvoiceConfirmed), IoTSensorData.QoS)));
908 }
909
910 Result.Add(new SemanticTriple(
911 FieldNode,
913 new BooleanLiteral(F.Writable)));
914
915 if (F.Type.HasFlag(FieldType.Momentary))
916 {
917 Result.Add(new SemanticTriple(
918 FieldNode,
919 new UriNode(Rdf.Type),
920 new CustomLiteral(nameof(FieldType.Momentary), IoTSensorData.FieldType)));
921 }
922
923 if (F.Type.HasFlag(FieldType.Identity))
924 {
925 Result.Add(new SemanticTriple(
926 FieldNode,
927 new UriNode(Rdf.Type),
928 new CustomLiteral(nameof(FieldType.Identity), IoTSensorData.FieldType)));
929 }
930
931 if (F.Type.HasFlag(FieldType.Status))
932 {
933 Result.Add(new SemanticTriple(
934 FieldNode,
935 new UriNode(Rdf.Type),
936 new CustomLiteral(nameof(FieldType.Status), IoTSensorData.FieldType)));
937 }
938
939 if (F.Type.HasFlag(FieldType.Computed))
940 {
941 Result.Add(new SemanticTriple(
942 FieldNode,
943 new UriNode(Rdf.Type),
944 new CustomLiteral(nameof(FieldType.Computed), IoTSensorData.FieldType)));
945 }
946
947 if (F.Type.HasFlag(FieldType.Peak))
948 {
949 Result.Add(new SemanticTriple(
950 FieldNode,
951 new UriNode(Rdf.Type),
952 new CustomLiteral(nameof(FieldType.Peak), IoTSensorData.FieldType)));
953 }
954
955 if (F.Type.HasFlag(FieldType.Historical))
956 {
957 Result.Add(new SemanticTriple(
958 FieldNode,
959 new UriNode(Rdf.Type),
960 new CustomLiteral(nameof(FieldType.Historical), IoTSensorData.FieldType)));
961 }
962 }
963
964 if (e.Done)
965 ReadoutCompleted.TrySetResult(true);
966 },
967 (Sender, e) =>
968 {
969 foreach (ThingError Error in e.Errors)
970 {
971 BlankNode ErrorNode = new BlankNode("n" + Guid.NewGuid().ToString());
972
973 Result.Add(new SemanticTriple(
974 Errors,
975 new UriNode(Rdf.ListItem(++ErrorIndex)),
976 ErrorNode));
977
978 Result.Add(new SemanticTriple(
979 ErrorNode,
981 new StringLiteral(Error.ErrorMessage)));
982
983 Result.Add(new SemanticTriple(
984 ErrorNode,
986 new DateTimeLiteral(Error.Timestamp)));
987
988 if (!string.IsNullOrEmpty((Error.NodeId)))
989 {
990 Result.Add(new SemanticTriple(
991 ErrorNode,
993 new StringLiteral(Error.NodeId)));
994 }
995
996 if (!string.IsNullOrEmpty((Error.SourceId)))
997 {
998 Result.Add(new SemanticTriple(
999 ErrorNode,
1001 new StringLiteral(Error.SourceId)));
1002 }
1003
1004 if (!string.IsNullOrEmpty((Error.Partition)))
1005 {
1006 Result.Add(new SemanticTriple(
1007 ErrorNode,
1009 new StringLiteral(Error.Partition)));
1010 }
1011 }
1012
1013 if (e.Done)
1014 ReadoutCompleted.TrySetResult(true);
1015
1016 return Task.CompletedTask;
1017 }, null);
1018
1019 Task Timeout = Task.Delay(60000);
1020 Task T = await Task.WhenAny(ReadoutCompleted.Task, Timeout);
1021
1022 if (!ReadoutCompleted.Task.IsCompleted)
1023 {
1024 BlankNode ErrorNode = new BlankNode("n" + Guid.NewGuid().ToString());
1025
1026 Result.Add(new SemanticTriple(
1027 Errors,
1028 new UriNode(Rdf.ListItem(++ErrorIndex)),
1029 ErrorNode));
1030
1031 Result.Add(new SemanticTriple(
1032 ErrorNode,
1033 new UriNode(RdfSchema.Label),
1034 new StringLiteral("Timeout.")));
1035
1036 Result.Add(new SemanticTriple(
1037 ErrorNode,
1039 new DateTimeLiteral(DateTime.UtcNow)));
1040 }
1041 break;
1042
1043 case "cmd": // TODO
1044 case "edit": // TODO
1045 case "control": // TODO
1046 default:
1047 return null;
1048 }
1049
1050 return Result;
1051 }
1052
1053 }
1054}
override void Add(ISemanticTriple Triple)
Adds a triple to the cube.
Represents a blank node
Definition: BlankNode.cs:7
static ISemanticElement Encapsulate(object Value)
Encapsulates an object as a semantic element.
static readonly Uri Updated
http://purl.org/dc/terms/updated
Definition: DublinCore.cs:33
static readonly Uri Type
http://purl.org/dc/terms/type
Definition: DublinCore.cs:23
RDF Schema Ontology
Definition: Rdf.cs:9
static Uri ListItem(int Index)
URI representing an item in a list.
static readonly Uri Type
URI representing rdf:type
Definition: Rdf.cs:18
static readonly Uri Label
http://www.w3.org/2000/01/rdf-schema#label
Definition: RdfSchema.cs:18
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:126
static bool IsDomain(string DomainOrHost, bool IncludeAlternativeDomains)
If a domain or host name represents the gateway.
Definition: Gateway.cs:4258
static string GetUrl(string LocalResource)
Gets a URL for a resource.
Definition: Gateway.cs:4167
static ConcentratorServer ConcentratorServer
XMPP Concentrator Server.
Definition: Gateway.cs:3211
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
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
Basic access point for runtime language localization.
Definition: Translator.cs:16
static async Task< Language > GetDefaultLanguageAsync()
Gets the default language.
Definition: Translator.cs:223
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
Abstract base class for control parameters.
string Description
Description for parameter.
Tokens available in request.
Definition: RequestOrigin.cs:9
string From
Address of caller.
static readonly Uri Partition
urn:nf:iot:concentrator:1.0:partition
static readonly Uri Confirmation
urn:nf:iot:concentrator:1.0:confirmation
static readonly Uri CommandType
urn:nf:iot:concentrator:1.0:commandType
static readonly Uri NodeState
urn:nf:iot:concentrator:1.0:nodeState
static readonly Uri ChildSource
urn:nf:iot:concentrator:1.0:childSource
static readonly Uri Success
urn:nf:iot:concentrator:1.0:success
static readonly Uri MessageType
urn:nf:iot:concentrator:1.0:messageType
static readonly Uri Control
urn:nf:iot:concentrator:1.0:control
static readonly Uri Failure
urn:nf:iot:concentrator:1.0:failure
static readonly Uri Body
urn:nf:iot:concentrator:1.0:body
static readonly Uri Command
urn:nf:iot:concentrator:1.0:Command
static readonly Uri LocalId
urn:nf:iot:concentrator:1.0:localId
static readonly Uri DisplayableParameters
urn:nf:iot:concentrator:1.0:dispParam
static readonly Uri IsControllable
urn:nf:iot:concentrator:1.0:isControllable
static readonly Uri ChildNode
urn:nf:iot:concentrator:1.0:childNode
static readonly Uri SourceId
urn:nf:iot:concentrator:1.0:sourceId
static readonly Uri Commands
urn:nf:iot:concentrator:1.0:commands
static readonly Uri Read
urn:nf:iot:concentrator:1.0:read
static readonly Uri Node
urn:nf:iot:concentrator:1.0:Node
static readonly Uri ParameterId
urn:nf:iot:concentrator:1.0:parameterId
static readonly Uri HasChildSource
urn:nf:iot:concentrator:1.0:hasChildSource
static readonly Uri RootNode
urn:nf:iot:concentrator:1.0:rootNode
static readonly Uri Messages
urn:nf:iot:concentrator:1.0:messages
static readonly Uri State
urn:nf:iot:concentrator:1.0:state
static readonly Uri ParentNode
urn:nf:iot:concentrator:1.0:parentNode
static readonly Uri Operations
urn:nf:iot:concentrator:1.0:operations
static readonly Uri DataSource
urn:nf:iot:concentrator:1.0:DataSource
static readonly Uri SortCategory
urn:nf:iot:concentrator:1.0:sortCategory
static readonly Uri Edit
urn:nf:iot:concentrator:1.0:edit
static readonly Uri TypeName
urn:nf:iot:concentrator:1.0:typeName
static readonly Uri CommandId
urn:nf:iot:concentrator:1.0:commandId
static readonly Uri EventId
urn:nf:iot:concentrator:1.0:eventId
static readonly Uri LogId
urn:nf:iot:concentrator:1.0:logId
static readonly Uri HasCommands
urn:nf:iot:concentrator:1.0:hasCommands
static readonly Uri IsReadable
urn:nf:iot:concentrator:1.0:isReadable
static readonly Uri SortKey
urn:nf:iot:concentrator:1.0:sortKey
static readonly Uri NodeId
urn:nf:iot:concentrator:1.0:nodeId
static readonly Uri Errors
urn:nf:iot:sd:1.0:errros
static readonly Uri Fields
urn:nf:iot:sd:1.0:fields
static readonly Uri Value
urn:nf:iot:concentrator:1.0:value
static readonly Uri Timestamp
urn:nf:iot:sd:1.0:timestamp
Makes harmonized data sources and nodes available as semantic information.
static async Task AppendNodeInformation(InMemorySemanticCube Result, INode Node, Language Language, RequestOrigin Caller)
Appends semantic information about a node to a graph.
async Task< ISemanticCube > LoadGraph(Uri GraphUri, ScriptNode Node, bool NullIfNotFound, RequestOrigin Caller)
Loads the graph
DataSourceGraph()
Makes harmonized data sources and nodes available as semantic information.
static Uri GetCommandUri(INode Node, ICommand Command)
Gets the Graph URI for a node command.
static async Task AppendSourceInformation(InMemorySemanticCube Result, IDataSource Source, Language Language, RequestOrigin Caller)
Appends semantic information about a data source to a graph.
static Uri GetNodeUri(INode Node)
Gets the Graph URI for a node.
Grade Supports(Uri GraphUri)
How well the source handles a given Graph URI.
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
Contains a reference to a thing
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 semantic nodes.
Interface for actuator nodes.
Definition: IActuator.cs:10
Interface for commands.
Definition: ICommand.cs:32
Interface for datasources that are published through the concentrator interface.
Definition: IDataSource.cs:14
IEnumerable< INode > RootNodes
Root node references. If no root nodes are available, null is returned.
Definition: IDataSource.cs:65
Task< string > GetNameAsync(Language Language)
Gets the name of data source.
Task< bool > CanViewAsync(RequestOrigin Caller)
If the data source is visible to the caller.
bool HasChildren
If the source has any child sources.
Definition: IDataSource.cs:34
DateTime LastChanged
When the source was last updated.
Definition: IDataSource.cs:42
IEnumerable< IDataSource > ChildSources
Child sources. If no child sources are available, null is returned.
Definition: IDataSource.cs:50
string SourceID
ID of data source.
Definition: IDataSource.cs:19
Interface for nodes that are published through the concentrator interface.
Definition: INode.cs:49
Task< IEnumerable< Parameter > > GetDisplayableParametersAsync(Language Language, RequestOrigin Caller)
Gets displayable parameters.
Task< string > GetTypeNameAsync(Language Language)
Gets the type name of the node.
bool IsControllable
If the node can be controlled.
Definition: INode.cs:100
bool IsReadable
If the node can be read.
Definition: INode.cs:92
bool HasCommands
If the node has registered commands or not.
Definition: INode.cs:108
DateTime LastChanged
When the node was last updated.
Definition: INode.cs:124
NodeState State
Current overall state of the node.
Definition: INode.cs:132
bool HasChildren
If the source has any child sources.
Definition: INode.cs:76
Task< IEnumerable< INode > > ChildNodes
Child nodes. If no child nodes are available, null is returned.
Definition: INode.cs:140
INode Parent
Parent Node, or null if a root node.
Definition: INode.cs:116
Task< IEnumerable< Message > > GetMessagesAsync(RequestOrigin Caller)
Gets messages logged on the node.
string LogId
If provided, an ID for the node, as it would appear or be used in system logs. Can be null,...
Definition: INode.cs:62
Task< IEnumerable< ICommand > > Commands
Available command objects. If no commands are available, null is returned.
Definition: INode.cs:241
string LocalId
If provided, an ID for the node, but unique locally between siblings. Can be null,...
Definition: INode.cs:54
Task< bool > CanViewAsync(RequestOrigin Caller)
If the node is visible to the caller.
Interface for sensor nodes.
Definition: ISensor.cs:9
Interface for thing references.
string Partition
Optional partition in which the Node ID is unique.
string SourceId
Optional ID of source containing node.
Grade
Grade enumeration
Definition: Grade.cs:7
FieldQoS
Field Quality of Service flags
Definition: FieldQoS.cs:10
FieldType
Field Type flags
Definition: FieldType.cs:10