Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
TopologyQuery.cs
1using System;
2using System.Text;
3using System.Text.RegularExpressions;
4using System.Threading.Tasks;
5using SkiaSharp;
8using Waher.Script;
13
15{
22 {
29 : base(@"^topologyquery\s*.*$")
30 {
31 }
32
36 public override string Name => "TopologyQuery";
37
46 public override async Task Execute(ChatState State, string[] Arguments, string OrgMessage, Match Details,
47 ResponseCallbackHandler ResponseCallback)
48 {
49 string Script = OrgMessage.Substring(13).Trim();
50 object Result;
51 SKColor Color;
52
53 if (string.IsNullOrEmpty(Script))
54 {
55 Result = null;
56 Color = SKColors.Empty;
57 }
58 else
59 {
60 Expression Exp = new Expression(Script);
61 Result = await Exp.EvaluateAsync(State.Session);
62 Result = Simplify(Result, out Color);
63 }
64
65 StringBuilder sb = new StringBuilder();
66 string Title = Gateway.HasDomain ? Gateway.Domain.Value : Gateway.XmppClient.BareJID;
67
68 sb.AppendLine("```dot");
69 sb.AppendLine("digraph G {");
70 sb.AppendLine("rankdir=LR");
71
72 EmbedResult(sb, Title, Result, Color);
73
74 sb.Append('"');
75 sb.Append(IoTGateway.Setup.XmppConfiguration.Instance.Host);
76 sb.Append("\" -> \"");
77 sb.Append(Title);
78 sb.AppendLine("\" [dir=back];");
79 sb.AppendLine("}");
80 sb.AppendLine("```");
81
82 await ResponseCallback(sb.ToString(), string.Empty);
83 }
84
85 public static object Simplify(object Result, out SKColor Color)
86 {
87 int i, j, c;
88
89 Color = SKColors.Empty;
90
91 while (true)
92 {
93 if (Result is IToMatrix ToMatrix)
94 Result = ToMatrix.ToMatrix();
95
96 if (Result is IMatrix M2)
97 {
98 if (M2 is ObjectMatrix OM2 && OM2.HasColumnNames)
99 return Result;
100
101 if (M2.Columns == 1)
102 Result = M2.GetColumn(0);
103 else if (M2.Rows == 1)
104 Result = M2.GetRow(0);
105 else
106 return Result;
107 }
108 else if (Result is Array V2)
109 {
110 if ((c = V2.Length) == 1)
111 Result = V2.GetValue(0);
112 else
113 {
114 for (i = 0; i < c; i++)
115 {
116 if (V2.GetValue(i) is SKColor Color2)
117 {
118 Color = Color2;
119
120 j = 0;
121 object[] Elements2 = new object[c - 1];
122
123 foreach (object Element in V2)
124 {
125 if (j < i)
126 Elements2[j] = Element;
127 else if (j > i)
128 Elements2[j - 1] = Element;
129
130 j++;
131 }
132
133 Result = Elements2;
134 break;
135 }
136 }
137
138 if (i == c)
139 return Result;
140 }
141 }
142 else if (Result is SKColor Color2)
143 {
144 Color = Color2;
145 return null;
146 }
147 else
148 return Result;
149 }
150 }
151
152 public static void EmbedResult(StringBuilder sb, string Title, object Result, SKColor Color)
153 {
154 bool First = true;
155 int i, j, c, d;
156 string s;
157
158 sb.Append('"');
159 sb.Append(XML.Encode(Title));
160 sb.Append("\" [");
161
162 if (Color != SKColors.Empty)
163 {
164 sb.Append("style=filled, fillcolor=\"#");
165 sb.Append(Color.Red.ToString("X2"));
166 sb.Append(Color.Green.ToString("X2"));
167 sb.Append(Color.Blue.ToString("X2"));
168
169 if (Color.Alpha != 255)
170 sb.Append(Color.Alpha.ToString("X2"));
171
172 sb.Append('"');
173 First = false;
174 }
175
176 if (Result is IToMatrix ToMatrix)
177 Result = ToMatrix.ToMatrix();
178
179 if (Result is IMatrix || Result is Array || Result is ISet)
180 {
181 if (!First)
182 sb.Append(", ");
183 else
184 First = false;
185
186 sb.Append("shape=plaintext, margin=0");
187 }
188
189 if (!First)
190 sb.Append(", ");
191
192 sb.Append("label=<");
193
194 if (Result is IMatrix M)
195 {
196 c = M.Rows;
197 d = M.Columns;
198
199 sb.Append("<table border=\"1\" cellborder=\"0\" cellspacing=\"1\">");
200 sb.Append("<tr><td align=\"center\" colspan=\"");
201 sb.Append(d.ToString());
202 sb.Append("\"><b>");
203 sb.Append(Title);
204 sb.Append("</b></td></tr>");
205
206 string[] Alignment = new string[d];
207
208 for (i = 0; i < c; i++)
209 {
210 for (j = 0; j < d; j++)
211 {
212 IElement E = M.GetElement(j, i);
213 object Obj = E.AssociatedObjectValue;
214
215 if (!(Obj is null))
216 {
217 if (Obj is double || Obj is float || Obj is int || Obj is long)
218 s = "right";
219 else if (Obj is bool)
220 s = "center";
221 else if (Obj is string || Obj is Enum)
222 s = "left";
223 else
224 s = string.Empty;
225
226 if (Alignment[j] is null)
227 Alignment[j] = s;
228 else if (Alignment[j] != s)
229 Alignment[j] = string.Empty;
230 }
231 }
232 }
233
234 if (Result is ObjectMatrix OM && OM.HasColumnNames)
235 {
236 sb.Append("<tr>");
237
238 j = 0;
239 foreach (string Name in OM.ColumnNames)
240 {
241 sb.Append("<td align=\"");
242 sb.Append(string.IsNullOrEmpty(s = Alignment[j++]) ? "center" : s);
243 sb.Append("\"><b>");
244 sb.Append(string.IsNullOrEmpty(Name) ? " " : XML.Encode(Name));
245 sb.Append("</b></td>");
246 }
247
248 sb.Append("</tr>");
249 }
250
251 for (i = 0; i < c; i++)
252 {
253 sb.Append("<tr>");
254
255 for (j = 0; j < d; j++)
256 {
257 IElement E = M.GetElement(j, i);
258 object Obj = E.AssociatedObjectValue;
259
260 s = Alignment[j];
261 sb.Append("<td");
262
263 if (!string.IsNullOrEmpty(s))
264 {
265 sb.Append(" align=\"");
266 sb.Append(s);
267 sb.Append('"');
268 }
269
270 sb.Append('>');
271 sb.Append(Obj?.ToString() ?? string.Empty);
272 sb.Append("</td>");
273 }
274
275 sb.Append("</tr>");
276 }
277
278 sb.Append("</table>");
279 }
280 else if (Result is Array V)
281 {
282 d = V.Length;
283
284 sb.Append("<table border=\"1\" cellborder=\"1\" cellspacing=\"1\">");
285 sb.Append("<tr><td align=\"center\" colspan=\"");
286 sb.Append(d.ToString());
287 sb.Append("\"><b>");
288 sb.Append(Title);
289 sb.Append("</b></td></tr><tr>");
290
291 foreach (object Obj in V)
292 {
293 sb.Append("<td>");
294 sb.Append(Obj?.ToString() ?? string.Empty);
295 sb.Append("</td>");
296 }
297
298 sb.Append("</tr></table>");
299 }
300 else if (Result is ISet S)
301 {
302 StringBuilder sb2 = new StringBuilder();
303 d = 0;
304
305 foreach (IElement E in S.ChildElements)
306 {
307 object Obj = E.AssociatedObjectValue;
308
309 sb2.Append("<td>");
310 sb2.Append(Obj?.ToString() ?? string.Empty);
311 sb2.Append("</td>");
312
313 d++;
314 }
315
316 sb.Append("<table border=\"1\" cellborder=\"1\" cellspacing=\"1\">");
317 sb.Append("<tr><td align=\"center\" colspan=\"");
318 sb.Append(d.ToString());
319 sb.Append("\"><b>");
320 sb.Append(Title);
321 sb.Append("</b></td></tr><tr>");
322 sb.Append(sb2.ToString());
323 sb.Append("</tr></table>");
324 }
325 else
326 {
327 sb.Append(XML.Encode(Title));
328
329 if (!(Result is null))
330 {
331 sb.Append("<br/><FONT POINT-SIZE=\"5\"><br/></FONT><FONT POINT-SIZE=\"20\"><b>");
332 sb.Append(Result?.ToString() ?? " ");
333 sb.Append("</b></FONT>");
334 }
335 }
336
337 sb.AppendLine(">];");
338 }
339
343 public override HelpItem[] GetHelp()
344 {
345 return new HelpItem[]
346 {
347 new HelpItem("TopologyQuery[ SCRIPT]", "Executes script (if provided), and returns the result in the form of a GraphViz graph of the current broker connected to its parent broker. Consolidating responses from multiple brokers generates a topology graph of all brokers, where each node contains the result of executing the script.")
348 };
349 }
350 }
351}
Helps with common XML-related tasks.
Definition: XML.cs:21
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:29
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:147
static XmppClient XmppClient
XMPP Client connection of gateway.
Definition: Gateway.cs:4038
Base class for all types of elements.
Definition: Element.cs:14
Class managing a script expression.
Definition: Expression.cs:41
async Task< object > EvaluateAsync(Variables Variables)
Evaluates the expression, using the variables provided in the Variables collection....
Definition: Expression.cs:4461
bool HasColumnNames
If the matrix has column names defined.
ToMatrix(ScriptNode Operand, bool NullCheck, int Start, int Length, Expression Expression)
To-Matrix operator.
Definition: ToMatrix.cs:22
readonly Variables Session
Session variables
Definition: ChatState.cs:49
An administrative command whose syntax is validated with a regular expression.
Definition: CommandRegEx.cs:12
Contains an item of information about a command.
Definition: HelpItem.cs:9
Executes script (if provided), and returns the result in the form of a GraphViz graph of the current ...
override async Task Execute(ChatState State, string[] Arguments, string OrgMessage, Match Details, ResponseCallbackHandler ResponseCallback)
Executes the command.
TopologyQuery()
Executes script (if provided), and returns the result in the form of a GraphViz graph of the current ...
override HelpItem[] GetHelp()
Markdown description of syntax.
Basic interface for all types of elements.
Definition: IElement.cs:21
object AssociatedObjectValue
Associated object value.
Definition: IElement.cs:34
ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
Definition: IElement.cs:50
Basic interface for matrices.
Definition: IMatrix.cs:7
Basic interface for all types of sets.
Definition: ISet.cs:10
Interface for objects that can be converted into matrices.
Definition: IToMatrix.cs:9
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.
delegate Task< string > ResponseCallbackHandler(string Markdown, string MessageId)
Delegate for response callback handler methods.