Mercurial > code > home > repos > homeauto
changeset 799:e0e623c01a69
ts build is part of docker now; new web debug console
author | drewp@bigasterisk.com |
---|---|
date | Fri, 01 Jan 2021 14:17:12 -0800 |
parents | cdc76c84e3e2 |
children | b311e6ca7bbd |
files | service/mqtt_to_rdf/.devcontainer/devcontainer.json service/mqtt_to_rdf/Dockerfile service/mqtt_to_rdf/mqtt_to_rdf.py service/mqtt_to_rdf/package.json service/mqtt_to_rdf/package.json5 service/mqtt_to_rdf/pnpm-lock.yaml service/mqtt_to_rdf/rollup.config.js service/mqtt_to_rdf/src/index.ts service/mqtt_to_rdf/src/style.styl |
diffstat | 9 files changed, 320 insertions(+), 159 deletions(-) [+] |
line wrap: on
line diff
--- a/service/mqtt_to_rdf/.devcontainer/devcontainer.json Tue Dec 29 21:05:32 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -{ - "name": "dev", - "context": "..", - "dockerFile": "../Dockerfile", - - // Use 'settings' to set *default* container specific settings.json values on container create. - // You can edit these settings after create using File > Preferences > Settings > Remote. - "settings": { - "terminal.integrated.shell.linux": "/bin/bash", - "python.pythonPath": "/usr/bin/python3", - "python.linting.enabled": true - //"python.linting.pylintEnabled": true, - //"python.linting.pylintPath": "/usr/local/share/pip-global/bin/pylint" - }, - - // Use 'appPort' to create a container with published ports. If the port isn't working, be sure - // your server accepts connections from all interfaces (0.0.0.0 or '*'), not just localhost. - "appPort": [], - - // Add the IDs of extensions you want installed when the container is created in the array below. - "extensions": [ - "ms-python.python", - "gregorbiswanger.package-watcher", - "hoffs.vscode-versionlens", - "esbenp.prettier-vscode" - ] -}
--- a/service/mqtt_to_rdf/Dockerfile Tue Dec 29 21:05:32 2020 -0800 +++ b/service/mqtt_to_rdf/Dockerfile Fri Jan 01 14:17:12 2021 -0800 @@ -2,17 +2,33 @@ WORKDIR /opt -COPY requirements.txt ./ -RUN pip3 uninstall --yes enum34 +RUN apt-get update +RUN apt-get remove -y nodejs +RUN apt-get install -y wget xz-utils && \ + wget --output-document=node.tar.xz https://nodejs.org/dist/v14.15.3/node-v14.15.3-linux-x64.tar.xz && \ + tar xf node.tar.xz && \ + ln -s node*x64 nodejs -RUN pip3 install --index-url https://projects.bigasterisk.com/ --extra-index-url https://pypi.org/simple -r requirements.txt -RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip?v3' +ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/workspace/nodejs/bin +RUN /opt/nodejs/bin/node /opt/nodejs/bin/npm install -g pnpm \ + && ln -s /opt/nodejs/bin/node /usr/local/bin/node \ + && ln -s /opt/nodejs/bin/pnpm /usr/local/bin/pnpm + +RUN pip3 uninstall --yes enum34 RUN pip3 install -U attrs -COPY *.py *.html *.css *.js ./ -COPY conf/ ./conf -COPY build/bundle.js build/ +COPY requirements.txt ./ +RUN pip3 install --index-url https://projects.bigasterisk.com/ --extra-index-url https://pypi.org/simple -r requirements.txt +RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip?v3' + +COPY package.json5 pnpm-lock.yaml ./ +RUN pnpm install -EXPOSE 10018:10018 +COPY tsconfig.json rollup.config.js ./ +COPY src/ ./src +RUN pnpm build -CMD [ "python3", "./mqtt_to_rdf.py" ] +COPY *.py *.html ./ +COPY conf/ ./conf + +CMD [ "python3", "./mqtt_to_rdf.py", "-v" ]
--- a/service/mqtt_to_rdf/mqtt_to_rdf.py Tue Dec 29 21:05:32 2020 -0800 +++ b/service/mqtt_to_rdf/mqtt_to_rdf.py Fri Jan 01 14:17:12 2021 -0800 @@ -1,11 +1,14 @@ """ Subscribe to mqtt topics; generate RDF statements. """ +import time import json +from logging import debug from pathlib import Path from typing import Callable, cast import cyclone.web +import cyclone.sse import prometheus_client import rx import rx.operators @@ -21,7 +24,7 @@ from rdflib.term import Node from rx.core import Observable from standardservice.logsetup import log, verboseLogging -from twisted.internet import reactor +from twisted.internet import reactor, task from button_events import button_events @@ -30,6 +33,11 @@ collectors = {} +def appendLimit(lst, elem, n=10): + del lst[:len(lst) - n + 1] + lst.append(elem) + + def parseDurationLiteral(lit: Literal) -> float: if lit.endswith('s'): return float(lit.split('s')[0]) @@ -38,33 +46,43 @@ class MqttStatementSource: - def __init__(self, uri: URIRef, config: Graph, masterGraph: PatchableGraph, mqtt, internalMqtt): + def __init__(self, uri: URIRef, config: Graph, masterGraph: PatchableGraph, mqtt, internalMqtt, debugPageData): self.uri = uri self.config = config self.masterGraph = masterGraph + self.debugPageData = debugPageData self.mqtt = mqtt # deprecated self.internalMqtt = internalMqtt self.mqttTopic = self.topicFromConfig(self.config) log.debug(f'new mqttTopic {self.mqttTopic}') - statPath = '/subscribed_topic/' + self.mqttTopic.decode('ascii').replace('/', '|') - #scales.init(self, statPath) - #self._mqttStats = scales.collection(statPath + '/incoming', scales.IntStat('count'), scales.RecentFpsStat('fps')) - - rawBytes = self.subscribeMqtt(self.mqttTopic) - rawBytes = self.addFilters(rawBytes) - rawBytes = rx.operators.do_action(self.countIncomingMessage)(rawBytes) - parsed = self.getParser()(rawBytes) + self.debugSub = { + 'topic': self.mqttTopic.decode('ascii'), + 'recentMessages': [], + 'recentParsed': [], + 'recentConversions': [], + 'currentMetrics': [], + 'currentOutputGraph': { + 't': 1, + 'n3': "(n3)" + }, + } + self.debugPageData['subscribed'].append(self.debugSub) - g = self.config - for conv in g.items(g.value(self.uri, ROOM['conversions'])): - parsed = self.conversionStep(conv)(parsed) + rawBytes: Observable = self.subscribeMqtt(self.mqttTopic) + # rawBytes = rx.operators.do_action(self.countIncomingMessage)(rawBytes) + rawBytes.subscribe(on_next=self.countIncomingMessage) + # rawBytes = self.addFilters(rawBytes) + # parsed = self.getParser()(rawBytes) - outputQuadsSets = rx.combine_latest( - *[self.makeQuads(parsed, plan) for plan in g.objects(self.uri, ROOM['graphStatements'])]) + # g = self.config + # for conv in g.items(g.value(self.uri, ROOM['conversions'])): + # parsed = self.conversionStep(conv)(parsed) - outputQuadsSets.subscribe_(self.updateQuads) + # outputQuadsSets = rx.combine_latest( *[self.makeQuads(parsed, plan) for plan in g.objects(self.uri, ROOM['graphStatements'])]) + + # outputQuadsSets.subscribe_(self.updateQuads) def addFilters(self, rawBytes): jsonEq = self.config.value(self.uri, ROOM['filterPayloadJsonEquals']) @@ -87,9 +105,13 @@ mqtt = self.internalMqtt if topic.startswith(b'frontdoorlock') else self.mqtt return mqtt.subscribe(topic) - def countIncomingMessage(self, _): - pass #self._mqttStats.fps.mark() - #self._mqttStats.count += 1 + def countIncomingMessage(self, msg: bytes): + self.debugPageData['messagesSeen'] += 1 + + appendLimit(self.debugSub['recentMessages'], { + 't': round(time.time(), 3), + 'msg': msg.decode('ascii'), + }) def getParser(self): g = self.config @@ -199,6 +221,32 @@ self.write(generate_latest(REGISTRY)) +class DebugPageData(cyclone.sse.SSEHandler): + + def __init__(self, application, request): + cyclone.sse.SSEHandler.__init__(self, application, request) + self.lastSent = None + + def watch(self): + try: + dpd = self.settings.debugPageData + js = json.dumps(dpd, sort_keys=True) + if js != self.lastSent: + print('sending dpd update') + self.sendEvent(message=js) + self.lastSent = js + except Exception: + import traceback + traceback.print_exc() + + def bind(self): + self.loop = task.LoopingCall(self.watch) + self.loop.start(1, now=True) + + def unbind(self): + self.loop.stop() + + if __name__ == '__main__': arg = docopt(""" Usage: mqtt_to_rdf.py [options] @@ -218,14 +266,23 @@ masterGraph = PatchableGraph() + brokerHost = 'mosquitto-frontdoor.default.svc.cluster.local' + brokerPort = 10210 + + debugPageData = { + # schema in index.ts + 'server': f'{brokerHost}:{brokerPort}', + 'messagesSeen': 0, + 'subscribed': [], + } + mqtt = MqttClient(clientId='mqtt_to_rdf', brokerHost='mosquitto-ext.default.svc.cluster.local', brokerPort=1883) # deprecated - internalMqtt = MqttClient(clientId='mqtt_to_rdf', - brokerHost='mosquitto-frontdoor.default.svc.cluster.local', - brokerPort=10210) + internalMqtt = MqttClient(clientId='mqtt_to_rdf', brokerHost=brokerHost, brokerPort=brokerPort) srcs = [] - for src in config.subjects(RDF.type, ROOM['MqttStatementSource']): - srcs.append(MqttStatementSource(src, config, masterGraph, mqtt=mqtt, internalMqtt=internalMqtt)) + for src in sorted(config.subjects(RDF.type, ROOM['MqttStatementSource'])): + srcs.append( + MqttStatementSource(src, config, masterGraph, mqtt=mqtt, internalMqtt=internalMqtt, debugPageData=debugPageData)) log.info(f'set up {len(srcs)} sources') port = 10018 @@ -244,11 +301,13 @@ (r"/graph/mqtt/events", CycloneGraphEventsHandler, { 'masterGraph': masterGraph }), + (r'/debugPageData', DebugPageData), (r'/metrics', Metrics), ], mqtt=mqtt, internalMqtt=internalMqtt, masterGraph=masterGraph, + debugPageData=debugPageData, debug=arg['-v']), interface='::') log.warn('serving on %s', port)
--- a/service/mqtt_to_rdf/package.json Tue Dec 29 21:05:32 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -{ - "name": "mqtt_to_rdf", - "version": "0.0.1", - "scripts": { - "build": "rollup -c", - "build_forever": "rollup -cw", - "test": "jest", - "test_forever": "jest --watch" - }, - "dependencies": { - "@polymer/polymer": "^3.3.1", - "@types/jsonld": "^1.5.0", - "jsonld": "^2.0.1", - "streamed-graph": "file:/my/proj/streamed-graph", - "@types/n3": "^1.1.5", - "n3": "link:/my/dl/modified/N3.js", - "lit-element": "^2.2.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^11.0.1", - "@rollup/plugin-node-resolve": "^7.0.0", - "@rollup/plugin-replace": "^2.3.0", - "@types/jest": "^24.9.0", - "@types/rollup-plugin-postcss": "^2.0.0", - "add": "^2.0.6", - "jest": "^24.9.0", - "node-globals": "^0.1.5", - "rollup": "^1.29.0", - "rollup-plugin-node-builtins": "^2.1.2", - "rollup-plugin-postcss": "^2.0.3", - "rollup-plugin-terser": "^5.2.0", - "rollup-plugin-typescript2": "^0.25.3", - "stylus": "^0.54.7", - "ts-jest": "^24.3.0", - "tslib": "^1.10.0", - "typescript": "^3.7.5" - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/mqtt_to_rdf/package.json5 Fri Jan 01 14:17:12 2021 -0800 @@ -0,0 +1,38 @@ +{ + "name": "mqtt_to_rdf", + "version": "0.0.1", + "scripts": { + "build": "rollup -c", + "build_forever": "rollup -cw", + "test": "jest", + "test_forever": "jest --watch" + }, + "dependencies": { + "@polymer/polymer": "^3.3.1", + "@types/jsonld": "^1.5.0", + "jsonld": "^2.0.1", + // "streamed-graph": "file:/my/proj/streamed-graph", + // "@types/n3": "^1.1.5", + // "n3": "link:/my/dl/modified/N3.js", + "lit-element": "^2.2.1" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^11.0.1", + "@rollup/plugin-node-resolve": "^7.0.0", + "@rollup/plugin-replace": "^2.3.0", + "@types/jest": "^24.9.0", + "@types/rollup-plugin-postcss": "^2.0.0", + "add": "^2.0.6", + "jest": "^24.9.0", + "node-globals": "^0.1.5", + "rollup": "^1.29.0", + "rollup-plugin-node-builtins": "^2.1.2", + "rollup-plugin-postcss": "^2.0.3", + "rollup-plugin-terser": "^5.2.0", + "rollup-plugin-typescript2": "^0.25.3", + "stylus": "^0.54.7", + "ts-jest": "^24.3.0", + "tslib": "^1.10.0", + "typescript": "^3.7.5" + } +}
--- a/service/mqtt_to_rdf/pnpm-lock.yaml Tue Dec 29 21:05:32 2020 -0800 +++ b/service/mqtt_to_rdf/pnpm-lock.yaml Fri Jan 01 14:17:12 2021 -0800 @@ -1,11 +1,8 @@ dependencies: '@polymer/polymer': 3.3.1 '@types/jsonld': 1.5.0 - '@types/n3': 1.1.5 jsonld: 2.0.2 lit-element: 2.2.1 - n3: 'link:../../../../../../my/dl/modified/N3.js' - streamed-graph: 'link:../../../../../../my/proj/streamed-graph' devDependencies: '@rollup/plugin-commonjs': 11.0.2_rollup@1.31.0 '@rollup/plugin-node-resolve': 7.1.1_rollup@1.31.0 @@ -444,26 +441,14 @@ dev: false resolution: integrity: sha512-EG2N8JLQ1xDfO6Z/1QRdiUcYX3428CqVRqmY7LyK5or5J1RQ16dpKH6qQ4umVD0vBHU47xHlMeyMbQ6o+6tiYg== - /@types/n3/1.1.5: - dependencies: - '@types/node': 13.7.0 - '@types/rdf-js': 2.0.11 - dev: false - resolution: - integrity: sha512-FaW94FyqTIrPP3ZEiwX745xQhzeoTlNiFsXjxPWsKBd+yvBtIW3ykd9kGnGWI/jz2Rp2iFKto3Tc+IcBL6a6yA== /@types/node/13.7.0: + dev: true resolution: integrity: sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ== /@types/q/1.5.2: dev: true resolution: integrity: sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== - /@types/rdf-js/2.0.11: - dependencies: - '@types/node': 13.7.0 - dev: false - resolution: - integrity: sha512-GC5MZU2HbL5JnlrLAzoxSqLprqtKwocz0TNVugqM04t1ZeeNFpZRqqBQc9Jhev35hEwdH84siRLaCesxHHYlmA== /@types/resolve/0.0.8: dependencies: '@types/node': 13.7.0 @@ -2927,6 +2912,8 @@ engines: node: '>=4.0' optional: true + os: + - darwin requiresBuild: true resolution: integrity: sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== @@ -3902,6 +3889,9 @@ node: '>=6' peerDependencies: jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true resolution: integrity: sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== /jest-regex-util/24.9.0: @@ -4713,6 +4703,9 @@ engines: node: '>=6' npm: ' >=4' + os: + - darwin + - linux resolution: integrity: sha1-zgW68PKik01AH1X4hwuj9T74CcI= /node-int64/0.4.0: @@ -7092,20 +7085,17 @@ '@rollup/plugin-replace': ^2.3.0 '@types/jest': ^24.9.0 '@types/jsonld': ^1.5.0 - '@types/n3': ^1.1.5 '@types/rollup-plugin-postcss': ^2.0.0 add: ^2.0.6 jest: ^24.9.0 jsonld: ^2.0.1 lit-element: ^2.2.1 - n3: 'link:/my/dl/modified/N3.js' node-globals: ^0.1.5 rollup: ^1.29.0 rollup-plugin-node-builtins: ^2.1.2 rollup-plugin-postcss: ^2.0.3 rollup-plugin-terser: ^5.2.0 rollup-plugin-typescript2: ^0.25.3 - streamed-graph: 'file:/my/proj/streamed-graph' stylus: ^0.54.7 ts-jest: ^24.3.0 tslib: ^1.10.0
--- a/service/mqtt_to_rdf/rollup.config.js Tue Dec 29 21:05:32 2020 -0800 +++ b/service/mqtt_to_rdf/rollup.config.js Fri Jan 01 14:17:12 2021 -0800 @@ -3,6 +3,7 @@ import resolve from "@rollup/plugin-node-resolve"; import typescript from "rollup-plugin-typescript2"; import replace from "@rollup/plugin-replace"; +import postcss from "rollup-plugin-postcss"; const workaround_jsonld_module_system_picker = "process = {version: '1.0.0'}"; const workaround_some_browser_detector = "global = window"; @@ -39,6 +40,7 @@ }), typescript(), commonjs(workaround_jsonld_expand_issue), + postcss({ inject: false }), replace({ ...replacements, delimiters: ["", ""] }), ], };
--- a/service/mqtt_to_rdf/src/index.ts Tue Dec 29 21:05:32 2020 -0800 +++ b/service/mqtt_to_rdf/src/index.ts Fri Jan 01 14:17:12 2021 -0800 @@ -1,64 +1,168 @@ // for the web page export { DomBind } from "@polymer/polymer/lib/elements/dom-bind.js"; -export { StreamedGraph } from "streamed-graph"; +// export { StreamedGraph } from "streamed-graph"; -import { LitElement, property, html, customElement } from "lit-element"; +import { + LitElement, + property, + html, + customElement, + unsafeCSS, +} from "lit-element"; -import { Literal, N3Store } from "n3"; -import { NamedNode, DataFactory } from "n3"; -const { namedNode, literal } = DataFactory; +// import { Literal, N3Store } from "n3"; +// import { NamedNode, DataFactory } from "n3"; +// const { namedNode, literal } = DataFactory; + +// import { VersionedGraph } from "streamed-graph"; +import style from "./style.styl"; +// import { labelFromUri, graphLiteral, graphUriValue } from "./graph_access"; + +// const room = "http://projects.bigasterisk.com/room/"; -import { VersionedGraph } from "streamed-graph"; -// import style from "./style.styl"; -import { labelFromUri, graphLiteral, graphUriValue } from "./graph_access"; - -const room = "http://projects.bigasterisk.com/room/"; +// function asString(x: Literal | undefined): string { +// if (x && x.value) { +// return x.value; +// } +// return "(unknown)"; +// } -function asString(x: Literal | undefined): string { - if (x && x.value) { - return x.value; - } - return "(unknown)"; +interface Msg { + t: number; + msg: string; +} +interface GraphAtTime { + t: number; + n3: string; +} +interface Metric { + name: string; + labels: { [_: string]: string }; + value: string; +} +interface Subscribed { + topic: string; + recentMessages: Msg[]; + recentParsed: GraphAtTime[]; + recentConversions: GraphAtTime[]; + currentMetrics: Metric[]; + currentOutputGraph: GraphAtTime; +} +interface PageData { + server: string; + messagesSeen: number; + subscribed: Subscribed[]; } @customElement("mqtt-to-rdf-page") export class MqttToRdfPage extends LitElement { - // static get styles() { - // return [style]; - // } + static get styles() { + return unsafeCSS(style); + } - @property({ type: Object }) - graph!: VersionedGraph; + // @property({ type: Object }) + // graph!: VersionedGraph; connectedCallback() { super.connectedCallback(); - const sg = this.ownerDocument!.querySelector("streamed-graph"); - sg?.addEventListener("graph-changed", ((ev: CustomEvent) => { - this.graph = ev.detail!.value as VersionedGraph; - }) as EventListener); + const data = new EventSource("debugPageData"); + data.addEventListener("message", (ev: { data: string }) => { + this.pageData = JSON.parse(ev.data) as PageData; + console.log("data update"); + }); + // const sg = this.ownerDocument!.querySelector("streamed-graph"); + // sg?.addEventListener("graph-changed", ((ev: CustomEvent) => { + // this.graph = ev.detail!.value as VersionedGraph; + // }) as EventListener); } - static get observers() { - return ["onGraphChanged(graph)"]; - } + // static get observers() { + // return ["onGraphChanged(graph)"]; + // } + + @property({}) + pageData: PageData = { + server: "loading...", + messagesSeen: 0, + subscribed: [ + { + topic: "top1", + recentMessages: [ + { t: 123456, msg: "one" }, + { t: 234567, msg: "two" }, + ], + recentParsed: [{ t: 123, n3: ":a :b :c ." }], + recentConversions: [], + currentMetrics: [], + currentOutputGraph: { t: 1, n3: "(n3)" }, + }, + ], + }; render() { + const d = this.pageData; + const now = Date.now() / 1000; + const ago = (t: number) => html`${Math.round(now - t)}s ago`; + const recentMsg = (m: Msg) => html` <div>${ago(m.t)} msg=${m.msg}</div> `; + const topicItem = (t: Subscribed, index: number) => + html`<div class="topic" style="grid-column: 1; grid-row: ${index + 2}"> + ${t.topic} ${t.recentMessages.map(recentMsg)} + </div>`; - return html` - <pre> - mqtt_to_rdf - - connected to <mqtt server> + const parsedMessage = (g: GraphAtTime) => + html` <div class="graph">graph: ${g.n3}</div> `; + const parsedMessages = (t: Subscribed, index: number) => + html` + <div style="grid-column: 2; grid-row: ${index + 2}"> + topic=${t.topic} ${t.recentParsed.map(parsedMessage)} + </div> + `; - messages received <n from stats page> + const metric = (m: Metric) => + html`<div> + metrix ${m.name} ${JSON.stringify(m.labels)} = ${m.value} + </div>`; + const conversions = (t: Subscribed, index: number) => + html` + <div style="grid-column: 3; grid-row: ${index + 2}"> + topic=${t.topic} ${t.recentConversions.map(parsedMessage)} + </div> + `; + const outputMetrics = (t: Subscribed, index: number) => + html` + <div style="grid-column: 4; grid-row: ${index + 2}"> + topic=${t.topic} ${t.currentMetrics.map(metric)} + </div> + `; + const outputGraph = (t: Subscribed, index: number) => + html` + <div style="grid-column: 5; grid-row: ${index + 2}"> + topic=${t.topic} ${parsedMessage(t.currentOutputGraph)} + </div> + `; + return html` + <h1>mqtt_to_rdf</h1> - subscribed topics: - ari nightlight temp: 72.2 <graph> - ... + <section>connected to ${d.server}; messages received ${ + d.messagesSeen + }</section> + + <div class="grid"> + <div class="hd" style="grid-row: 1; grid-column: 1">subscribed topics</div> + ${d.subscribed.map(topicItem)} + <div class="hd" style="grid-row: 1; grid-column: 2">parsed message: rx stream of Graph</div> + ${d.subscribed.map(parsedMessages)} - </pre> + <div class="hd" style="grid-row: 1; grid-column: 3">conversions: rx stream (possible separate times from the previous) of Callable[[Graph], Graph]</div> + ${d.subscribed.map(conversions)} + + <div class="hd" style="grid-row: 1; grid-column: 4">output metrics: prom collection according to converted graph</div> + ${d.subscribed.map(outputMetrics)} + + <div class="hd" style="grid-row: 1; grid-column: 5">output graph: PatchableGraph</div> + ${d.subscribed.map(outputGraph)} + </section> `; } - }
--- a/service/mqtt_to_rdf/src/style.styl Tue Dec 29 21:05:32 2020 -0800 +++ b/service/mqtt_to_rdf/src/style.styl Fri Jan 01 14:17:12 2021 -0800 @@ -1,5 +1,22 @@ -:host - display: flex - flex-direction: column - padding: 2px 0 +:host { + display: flex; + flex-direction: column; + padding: 2px 0; +} + +.grid { + display: grid; + grid-auto-columns: minmax(10em, auto); + grid-auto-rows: minmax(10em, auto); + grid-template-rows: 3em; +} + +.grid * { + outline: 1px solid gray; + overflow: auto; + padding: 3px +} + +.hd + font-weight: bold \ No newline at end of file