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