comparison service/wifi/src/wifi-table.ts @ 1476:817da2dc80fc

kind of running with lit-element and polymer together. lots of data missing from table still Ignore-this: db24e7b633929b01430b0794c1a065dc darcs-hash:cdb1d499a42b869d6affa3ee226f408358a59cf4
author drewp <drewp@bigasterisk.com>
date Sun, 05 Jan 2020 23:18:27 -0800
parents 4bbc68603168
children
comparison
equal deleted inserted replaced
1475:2e598cbcabf4 1476:817da2dc80fc
1 import { html } from 'lit-html'; 1 import { html } from "lit-html";
2 import { NamedNode, DataFactory } from 'n3'; 2 import { NamedNode, DataFactory } from "n3";
3 const { literal, quad, namedNode } = DataFactory; 3 const { literal, quad, namedNode } = DataFactory;
4 import * as sgmod from 'streamed-graph'; 4 import * as sgmod from "streamed-graph";
5 import { Literal, Term, N3Store } from 'n3'; 5 import { Literal, Term, N3Store } from "n3";
6 6
7 interface DevGroup { 7 interface DevGroup {
8 connectedToAp: NamedNode, 8 connectedToAp: NamedNode;
9 wifiBand: NamedNode, 9 wifiBand: NamedNode;
10 devs: Array<Dev> 10 devs: Array<Dev>;
11 } 11 }
12 interface Dev { 12 interface Dev {
13 agoMin: number, 13 agoMin: number;
14 ipAddress: Literal, 14 ipAddress: Literal;
15 dhcpHostname: string, 15 dhcpHostname: string;
16 macAddress: Literal, 16 macAddress: Literal;
17 packetsPerSec: number, 17 packetsPerSec: number;
18 bytesPerSec: number 18 bytesPerSec: number;
19 } 19 }
20 20
21 console.log('got', sgmod); 21 console.log("got", sgmod);
22 22
23 const NS: any = { 23 const NS: any = {
24 room: 'http://projects.bigasterisk.com/room/' 24 room: "http://projects.bigasterisk.com/room/",
25 } 25 };
26 26
27 // from rdf-uri.html 27 // from rdf-uri.html
28 const BigastUri = { 28 const BigastUri = {
29 // not well defined for uri prefixes that are string prefixes of each other 29 // not well defined for uri prefixes that are string prefixes of each other
30 compactUri: function (uri: string) { 30 compactUri: function(uri: string) {
31 if (uri === undefined) { 31 if (uri === undefined) {
32 return uri; 32 return uri;
33 } 33 }
34 if (typeof (uri) == "object") { throw new Error("type"); } 34 if (typeof uri == "object") {
35 throw new Error("type");
36 }
35 if (uri == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type") { 37 if (uri == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type") {
36 return "a"; 38 return "a";
37 } 39 }
38 for (var short of Object.keys(NS as any)) { 40 for (var short of Object.keys(NS as any)) {
39 var prefix = NS[short]; 41 var prefix = NS[short];
40 if (uri.indexOf(prefix) == 0) { 42 if (uri.indexOf(prefix) == 0) {
41 return short + ':' + uri.substr(prefix.length); 43 return short + ":" + uri.substr(prefix.length);
42 } 44 }
43 } 45 }
44 return uri; 46 return uri;
45 }, 47 },
46 expandUri: function (s: string) { 48 expandUri: function(s: string) {
47 for (var short of Object.keys(NS)) { 49 for (var short of Object.keys(NS)) {
48 var prefix = NS[short]; 50 var prefix = NS[short];
49 if (s.indexOf(short + ":") == 0) { 51 if (s.indexOf(short + ":") == 0) {
50 return prefix + s.substr(short.length + 1); 52 return prefix + s.substr(short.length + 1);
51 } 53 }
53 return s; 55 return s;
54 }, 56 },
55 }; 57 };
56 58
57 // workaround for uris that don't have good labels in the graph 59 // workaround for uris that don't have good labels in the graph
58 function labelFromUri(uri: NamedNode, prefix: string, tailsToLabels: any, defaultLabel: string) { 60 function labelFromUri(
61 uri: NamedNode,
62 prefix: string,
63 tailsToLabels: any,
64 defaultLabel: string
65 ) {
59 let label = defaultLabel === undefined ? uri.value : defaultLabel; 66 let label = defaultLabel === undefined ? uri.value : defaultLabel;
60 Object.entries(tailsToLabels).forEach(([tail, useLabel]) => { 67 Object.entries(tailsToLabels).forEach(([tail, useLabel]) => {
61 if (uri.equals(namedNode(prefix + tail))) { 68 if (uri.equals(namedNode(prefix + tail))) {
62 label = useLabel as string; 69 label = useLabel as string;
63 } 70 }
64 }); 71 });
65 return label 72 return label;
66 } 73 }
67 74
68 // set out[suffix] = graph.get(subj, predPrefix+suffix) for all suffixes 75 // set out[suffix] = graph.get(subj, predPrefix+suffix) for all suffixes
69 function getProperties(store: N3Store, out: any, subject: Term, predPrefix: string, predSuffixes: Array<string>) { 76 function getProperties(
70 predSuffixes.forEach((term) => { 77 store: N3Store,
71 store.forEach((q) => { 78 out: any,
72 out[term] = q.object; 79 subject: Term,
73 }, subject, namedNode(predPrefix + term), null, null); 80 predPrefix: string,
81 predSuffixes: Array<string>
82 ) {
83 predSuffixes.forEach(term => {
84 store.forEach(
85 q => {
86 out[term] = q.object;
87 },
88 subject,
89 namedNode(predPrefix + term),
90 null,
91 null
92 );
74 93
75 return out; 94 return out;
76 }); 95 });
77 } 96 }
78 97
79 function graphView(store: N3Store, showGroups: boolean): void { 98 function graphView(store: N3Store, showGroups: boolean): void {
80 const grouped: Map<string, DevGroup> = new Map(); 99 const grouped: Map<string, DevGroup> = new Map();
81 store.forEach((q) => { 100 store.forEach(
82 const row: any = { uri: q.subject }; 101 q => {
83 102 const row: any = { uri: q.subject };
84 getProperties(store, row, row.uri, 'room:', 103
85 ['dhcpHostname', 'ipAddress', 'macAddress', 'connectedToAp', 'wifiBand', 'connected', 'bytesPerSec', 'packetsPerSec']); 104 getProperties(store, row, row.uri, "room:", [
86 if (row.dhcpHostname && row.dhcpHostname.value) { 105 "dhcpHostname",
87 row.dhcpHostname = row.dhcpHostname.value; 106 "ipAddress",
88 } 107 "macAddress",
89 if (!showGroups || row.connectedToAp) { 108 "connectedToAp",
90 const key = (showGroups ? `${row.connectedToAp.toNT()}-${row.wifiBand.toNT()}` : 'all'); 109 "wifiBand",
91 if (!grouped.has(key)) { 110 "connected",
92 grouped.set(key, { connectedToAp: row.connectedToAp, wifiBand: row.wifiBand, devs: [] }); 111 "bytesPerSec",
93 } 112 "packetsPerSec",
94 grouped.get(key)!.devs.push(row); 113 ]);
95 } else { 114 if (row.dhcpHostname && row.dhcpHostname.value) {
96 console.log('lost row', row); 115 row.dhcpHostname = row.dhcpHostname.value;
97 } 116 }
98 if (row.connected) { 117 if (!showGroups || row.connectedToAp) {
99 const t = new Date(row.connected.value); 118 const key = showGroups
100 const agoMs = (Date.now() as number) - (t as unknown as number); 119 ? `${row.connectedToAp.toNT()}-${row.wifiBand.toNT()}`
101 row.agoMin = agoMs / 1000 / 60; 120 : "all";
102 } 121 if (!grouped.has(key)) {
103 if (row.bytesPerSec) { row.bytesPerSec = row.bytesPerSec.valueOf() + ' B/s'; } 122 grouped.set(key, {
104 if (row.packetsPerSec) { row.packetsPerSec = row.packetsPerSec.valueOf() + ' p/s'; } 123 connectedToAp: row.connectedToAp,
105 }, null, namedNode('rdf:type'), namedNode('room:NetworkedDevice'), null); 124 wifiBand: row.wifiBand,
125 devs: [],
126 });
127 }
128 grouped.get(key)!.devs.push(row);
129 } else {
130 console.log("lost row", row);
131 }
132 if (row.connected) {
133 const t = new Date(row.connected.value);
134 const agoMs = (Date.now() as number) - ((t as unknown) as number);
135 row.agoMin = agoMs / 1000 / 60;
136 }
137 if (row.bytesPerSec) {
138 row.bytesPerSec = row.bytesPerSec.valueOf() + " B/s";
139 }
140 if (row.packetsPerSec) {
141 row.packetsPerSec = row.packetsPerSec.valueOf() + " p/s";
142 }
143 },
144 null,
145 namedNode("rdf:type"),
146 namedNode("room:NetworkedDevice"),
147 null
148 );
106 } 149 }
107 150
108 const renderDevice = (dev: Dev) => { 151 const renderDevice = (dev: Dev) => {
109 const glow = Math.max(0, 1 - dev.agoMin / 60); 152 const glow = Math.max(0, 1 - dev.agoMin / 60);
110 const agoReport = dev.agoMin < 360 ? ` (${Math.ceil(dev.agoMin * 10) / 10} minutes ago)` : ''; 153 const agoReport =
154 dev.agoMin < 360 ? ` (${Math.ceil(dev.agoMin * 10) / 10} minutes ago)` : "";
111 return html` 155 return html`
112 <div class="dev" style="background: rgba(185, 5, 138, ${glow});"> 156 <div class="dev" style="background: rgba(185, 5, 138, ${glow});">
113 <span class="mac">${dev.macAddress.value}</span> 157 <span class="mac">${dev.macAddress.value}</span>
114 <span class="ip"><a href="http://${dev.ipAddress.value}/">${dev.ipAddress.value}</a></span> 158 <span class="ip"
115 <span class="packets">${dev.packetsPerSec}</span> 159 ><a href="http://${dev.ipAddress.value}/"
116 <span class="bytes">${dev.bytesPerSec}</span> 160 >${dev.ipAddress.value}</a
117 <span class="hostname">${dev.dhcpHostname}</span> 161 ></span
118 <span class="ago">${agoReport}</span> 162 >
119 <span class="links"> 163 <span class="packets">${dev.packetsPerSec}</span>
120 <a href="https://bigasterisk.com/ntop/lua/host_details.lua?ifid=17&amp;host=${dev.ipAddress.value}&amp;page=flows">[flows]</a> 164 <span class="bytes">${dev.bytesPerSec}</span>
121 </span> 165 <span class="hostname">${dev.dhcpHostname}</span>
122 </div> 166 <span class="ago">${agoReport}</span>
123 `; 167 <span class="links">
168 <a
169 href="https://bigasterisk.com/ntop/lua/host_details.lua?ifid=17&amp;host=${dev
170 .ipAddress.value}&amp;page=flows"
171 >[flows]</a
172 >
173 </span>
174 </div>
175 `;
124 }; 176 };
125 177
126 const renderGroup = (key: string, group: DevGroup) => { 178 const renderGroup = (key: string, group: DevGroup) => {
127 let label; 179 let label;
128 if (key != 'all') { 180 if (key != "all") {
129 label = labelFromUri(group.connectedToAp, 181 label = labelFromUri(
130 'http://bigasterisk.com/mac/', 182 group.connectedToAp,
183 "http://bigasterisk.com/mac/",
131 { 184 {
132 'a0:40:a0:6f:96:d5': "Main router (d5)", 185 "a0:40:a0:6f:96:d5": "Main router (d5)",
133 '8c:3b:ad:c4:8d:ce': "Downstairs satellite (ce)", 186 "8c:3b:ad:c4:8d:ce": "Downstairs satellite (ce)",
134 'a0:40:a0:6f:aa:f8': "Upstairs satellite (f8)", 187 "a0:40:a0:6f:aa:f8": "Upstairs satellite (f8)",
135 }, 188 },
136 "unknown"); 189 "unknown"
137 190 );
138 label += labelFromUri(group.wifiBand, 191
139 'http://projects.bigasterisk.com/room/wifiBand/', 192 label += labelFromUri(
193 group.wifiBand,
194 "http://projects.bigasterisk.com/room/wifiBand/",
140 { 195 {
141 '5G': ' 5G', 196 "5G": " 5G",
142 '2.4G': ' 2.4G', 197 "2.4G": " 2.4G",
143 }, 198 },
144 "unknown"); 199 "unknown"
200 );
145 } 201 }
146 202
147 const devs = group.devs; 203 const devs = group.devs;
148 function padIp(ip: string) { return ip.replace(/(\d+)/g, (m) => ('00' + m).slice(-3)); } 204 function padIp(ip: string) {
149 devs.sort((a, b) => { return padIp(a.ipAddress.value) > padIp(b.ipAddress.value) ? 1 : -1; }); 205 return ip.replace(/(\d+)/g, m => ("00" + m).slice(-3));
206 }
207 devs.sort((a, b) => {
208 return padIp(a.ipAddress.value) > padIp(b.ipAddress.value) ? 1 : -1;
209 });
150 return html` 210 return html`
151 <tr> 211 <tr>
152 <th>${label}</th> 212 <th>${label}</th>
153 <td> 213 <td>
154 <div>Devices:</div> 214 <div>Devices:</div>
155 ${devs.map((d) => { return renderDevice(d); })} 215 ${devs.map(d => {
156 </td> 216 return renderDevice(d);
157 </tr> 217 })}
158 `; 218 </td>
219 </tr>
220 `;
159 /* 221 /*
160 let groups=['?']; 222 let groups=['?'];
161 const out = html` 223 const out = html`
162 <style> 224 <style>
163 225
187 ${groups.map((row) => { return renderGroup(row[0], row[1]); })} 249 ${groups.map((row) => { return renderGroup(row[0], row[1]); })}
188 </table> 250 </table>
189 </div> 251 </div>
190 `; 252 `;
191 return out;*/ 253 return out;*/
192 } 254 };
193 export { graphView } 255 export { graphView };