Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ReadSensorData.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
6using Waher.Script;
12using Waher.Security;
13using Waher.Things;
15
17{
22 {
31 : base(new ScriptNode[] { Sensor }, new ArgumentType[] { ArgumentType.Scalar }, Start, Length, Expression)
32 {
33 }
34
44 : base(new ScriptNode[] { Sensor, FieldTypes }, new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar },
46 {
47 }
48
58 public ReadSensorData(ScriptNode Sensor, ScriptNode FieldTypes, ScriptNode Fields, int Start, int Length, Expression Expression)
59 : base(new ScriptNode[] { Sensor, FieldTypes, Fields },
60 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Normal },
62 {
63 }
64
75 public ReadSensorData(ScriptNode Sensor, ScriptNode FieldTypes, ScriptNode Fields, ScriptNode From,
77 : base(new ScriptNode[] { Sensor, FieldTypes, Fields, From },
78 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Normal, ArgumentType.Scalar },
80 {
81 }
82
94 public ReadSensorData(ScriptNode Sensor, ScriptNode FieldTypes, ScriptNode Fields, ScriptNode From, ScriptNode To,
96 : base(new ScriptNode[] { Sensor, FieldTypes, Fields, From, To },
97 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Normal, ArgumentType.Scalar, ArgumentType.Scalar },
99 {
100 }
101
105 public override string FunctionName => nameof(ReadSensorData);
106
110 public override string[] DefaultArgumentNames => new string[] { "Sensor", "FieldTypes", "Fields", "From", "To" };
111
116 public override bool IsAsynchronous => true;
117
125 {
126 return this.EvaluateAsync(Arguments, Variables).Result;
127 }
128
135 public override async Task<IElement> EvaluateAsync(IElement[] Arguments, Variables Variables)
136 {
137 int i = 0;
138 int c = Arguments.Length;
139
140 if (!(Arguments[i++].AssociatedObjectValue is ISensor Sensor))
141 throw new ScriptRuntimeException("Expected sensor in first argument.", this);
142
143 FieldType FieldTypes;
144 string[] FieldNames;
145 DateTime From, To;
146 object Obj;
147
148 if (i < c)
149 {
150 Obj = Arguments[i++].AssociatedObjectValue;
151
152 if (Obj is FieldType Types || Enum.TryParse(Obj?.ToString() ?? string.Empty, out Types))
153 FieldTypes = Types;
154 else
155 throw new ScriptRuntimeException("Expected a FieldTypes enumeration as second argument.", this);
156 }
157 else
158 FieldTypes = FieldType.Momentary;
159
160 if (i < c)
161 {
162 Obj = Arguments[i++].AssociatedObjectValue;
163
164 if (Obj is string[] Names)
165 FieldNames = Names;
166 else if (Obj is object[] Objects)
167 {
168 int j, d = Objects.Length;
169
170 FieldNames = new string[d];
171
172 for (j = 0; j < d; j++)
173 {
174 if (Objects[j] is string s)
175 FieldNames[j] = s;
176 else
177 throw new ScriptRuntimeException("Expected a string array or null as third argument.", this);
178 }
179 }
180 else if (Obj is null)
181 FieldNames = null;
182 else
183 throw new ScriptRuntimeException("Expected a string array or null as third argument.", this);
184 }
185 else
186 FieldNames = null;
187
188 if (i < c)
189 {
190 Obj = Arguments[i++].AssociatedObjectValue;
191
192 if (Obj is DateTime TP)
193 From = TP;
194 else if (Obj is null)
195 From = DateTime.MinValue;
196 else
197 throw new ScriptRuntimeException("Expected a Date & Time or null as fourth argument.", this);
198 }
199 else
200 From = DateTime.MinValue;
201
202 if (i < c)
203 {
204 Obj = Arguments[i++].AssociatedObjectValue;
205
206 if (Obj is DateTime TP)
207 To = TP;
208 else if (Obj is null)
209 To = DateTime.MaxValue;
210 else
211 throw new ScriptRuntimeException("Expected a Date & Time as fifth argument.", this);
212 }
213 else
214 To = DateTime.MaxValue;
215
216 TaskCompletionSource<bool> ReadoutCompleted = new TaskCompletionSource<bool>();
217 Dictionary<string, List<Field>> Fields = new Dictionary<string, List<Field>>();
218 List<ThingError> Errors = new List<ThingError>();
219 bool Error = false;
220
222 IThingReference[] Nodes = new IThingReference[] { Sensor };
223
224 if (!(Sensor is ExternalNode ExternalNode) ||
225 string.Compare(Gateway.XmppClient.BareJID, ExternalNode.Jid.Value, true) == 0)
226 {
227 ApprovedReadoutParameters Approval = await Gateway.ConcentratorServer.SensorServer.CanReadAsync(FieldTypes, Nodes, FieldNames, Origin)
228 ?? throw new ScriptRuntimeException("Not authorized to read sensor-data from node.", this);
229
230 Nodes = Approval.Nodes;
231 FieldTypes = Approval.FieldTypes;
232 FieldNames = Approval.FieldNames;
233 }
234
235 string Actor = Origin is IUser User ? User.UserName : nameof(ReadSensorData);
236
237 InternalReadoutRequest Request = await Gateway.ConcentratorServer.SensorServer.DoInternalReadout(
238 Actor, Nodes, FieldTypes, FieldNames, From, To, (Sender, e) =>
239 {
240 foreach (Field F in e.Fields)
241 {
242 if (Fields.TryGetValue(F.Name, out List<Field> List))
243 List.Add(F);
244 else
245 Fields[F.Name] = new List<Field>() { F };
246 }
247
248 if (e.Done)
249 ReadoutCompleted.TrySetResult(true);
250
251 return Task.CompletedTask;
252 },
253 (Sender, e) =>
254 {
255 Errors.AddRange(e.Errors);
256 Error = true;
257
258 if (e.Done)
259 ReadoutCompleted.TrySetResult(true);
260
261 return Task.CompletedTask;
262 }, null);
263
264 Task Timeout = Task.Delay(60000);
265 Task T = await Task.WhenAny(ReadoutCompleted.Task, Timeout);
266
267 if (!ReadoutCompleted.Task.IsCompleted)
268 {
269 Errors.Add(new ThingError(Sensor, "Timeout."));
270 Error = true;
271 }
272
273 Dictionary<string, IElement> Fields2 = new Dictionary<string, IElement>();
274
275 foreach (KeyValuePair<string, List<Field>> P in Fields)
276 {
277 if (P.Value.Count == 1)
278 Fields2[P.Key] = new ObjectValue(P.Value[0]);
279 else
280 Fields2[P.Key] = new ObjectVector(P.Value.ToArray());
281 }
282
283 return new ObjectValue(new Dictionary<string, IElement>()
284 {
285 { "Error", Error ? BooleanValue.True : BooleanValue.False },
286 { "Ok", Error ? BooleanValue.False : BooleanValue.True },
287 { "Fields", new ObjectValue(Fields2) },
288 { "Errors", new ObjectVector(Errors.ToArray()) }
289 });
290 }
291
295 public static string DefaultSource
296 {
297 get
298 {
299 if (Types.TryGetModuleParameter("DefaultSource", out object Obj) && Obj is string Source)
300 return Source;
301 else
302 return string.Empty;
303 }
304 }
305
312 public static bool TryGetDataSource(string SourceId, out IDataSource Source)
313 {
314 if (!Types.TryGetModuleParameter("Sources", out object Obj) || !(Obj is IDataSource[] Sources))
315 {
316 Source = null;
317 return false;
318 }
319
320 if (Sources != sources)
321 {
322 Dictionary<string, IDataSource> SourceById = new Dictionary<string, IDataSource>();
323 Add(SourceById, Sources);
324 sourceById = SourceById;
325 sources = Sources;
326 }
327
328 return sourceById.TryGetValue(SourceId, out Source);
329 }
330
331 private static void Add(Dictionary<string, IDataSource> SourceById, IEnumerable<IDataSource> Sources)
332 {
333 foreach (IDataSource Source in Sources)
334 {
335 SourceById[Source.SourceID] = Source;
336
337 if (Source.HasChildren)
338 Add(SourceById, Source.ChildSources);
339 }
340 }
341
342 private static IDataSource[] sources = null;
343 private static Dictionary<string, IDataSource> sourceById = null;
344 }
345}
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:126
static XmppClient XmppClient
XMPP Client connection of gateway.
Definition: Gateway.cs:3187
static ConcentratorServer ConcentratorServer
XMPP Concentrator Server.
Definition: Gateway.cs:3211
CaseInsensitiveString Jid
JID of remote entity.
Gets a node object on the gateway.
Definition: GetNode.cs:18
static Task< RequestOrigin > GetOriginOfRequest(Variables Variables)
Gets the origin of a request.
Definition: GetNode.cs:200
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
Evaluates the function.
ReadSensorData(ScriptNode Sensor, ScriptNode FieldTypes, int Start, int Length, Expression Expression)
Reads sensor data from a sensor node.
override IElement Evaluate(IElement[] Arguments, Variables Variables)
Evaluates the function.
ReadSensorData(ScriptNode Sensor, ScriptNode FieldTypes, ScriptNode Fields, ScriptNode From, ScriptNode To, int Start, int Length, Expression Expression)
Reads sensor data from a sensor node.
ReadSensorData(ScriptNode Sensor, ScriptNode FieldTypes, ScriptNode Fields, ScriptNode From, int Start, int Length, Expression Expression)
Reads sensor data from a sensor node.
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
override string[] DefaultArgumentNames
Default Argument names
static bool TryGetDataSource(string SourceId, out IDataSource Source)
Tries to get a data source, from its data source ID.
ReadSensorData(ScriptNode Sensor, ScriptNode FieldTypes, ScriptNode Fields, int Start, int Length, Expression Expression)
Reads sensor data from a sensor node.
ReadSensorData(ScriptNode Sensor, int Start, int Length, Expression Expression)
Reads sensor data from a sensor node.
Contains information about what sensor data readout parameters have been approved.
Manages a chat sensor data readout request.
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:14
static bool TryGetModuleParameter(string Name, out object Value)
Tries to get a module parameter value.
Definition: Types.cs:583
Class managing a script expression.
Definition: Expression.cs:39
Base class for multivariate funcions.
ScriptNode[] Arguments
Function arguments.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
Expression Expression
Expression of which the node is a part.
Definition: ScriptNode.cs:177
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
Collection of variables.
Definition: Variables.cs:25
Tokens available in request.
Definition: RequestOrigin.cs:9
Base class for all sensor data fields.
Definition: Field.cs:20
Contains information about an error on a thing
Definition: ThingError.cs:10
Basic interface for all types of elements.
Definition: IElement.cs:20
Basic interface for a user.
Definition: IUser.cs:7
Interface for datasources that are published through the concentrator interface.
Definition: IDataSource.cs:14
bool HasChildren
If the source has any child sources.
Definition: IDataSource.cs:34
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 sensor nodes.
Definition: ISensor.cs:9
Interface for thing references.
ArgumentType
Type of parameter used in a function definition or a lambda definition.
Definition: IFunction.cs:9
FieldType
Field Type flags
Definition: FieldType.cs:10