Mercurial > code > home > repos > light-bridge
comparison light_bridge.py @ 2:c6fd04e07db0
refactor light.py
author | drewp@bigasterisk.com |
---|---|
date | Sun, 28 Jan 2024 15:44:10 -0800 |
parents | 42a494b8ee1a |
children | 7eeda7f4f9cd |
comparison
equal
deleted
inserted
replaced
1:42a494b8ee1a | 2:c6fd04e07db0 |
---|---|
1 """ | 1 """ |
2 replaces a lot of mqtt_to_rdf and rdf_to_mqtt | 2 replaces a lot of mqtt_to_rdf and rdf_to_mqtt |
3 """ | 3 """ |
4 import asyncio | |
5 from dataclasses import dataclass | |
6 from functools import partial | |
7 import json | 4 import json |
8 import logging | 5 import logging |
6 from functools import partial | |
9 import time | 7 import time |
10 | 8 |
11 import background_loop | 9 import background_loop |
12 from patchablegraph import PatchableGraph | 10 from patchablegraph import PatchableGraph |
13 from patchablegraph.handler import GraphEvents, StaticGraph | 11 from patchablegraph.handler import GraphEvents, StaticGraph |
14 from rdflib import Namespace | 12 from rdflib import Namespace |
13 from sse_starlette.sse import EventSourceResponse | |
15 from starlette.applications import Starlette | 14 from starlette.applications import Starlette |
16 from starlette.requests import Request | 15 from starlette.requests import Request |
17 from starlette.responses import JSONResponse | 16 from starlette.responses import JSONResponse |
18 from starlette.routing import Route | 17 from starlette.routing import Route |
19 from starlette_exporter import PrometheusMiddleware, handle_metrics | 18 from starlette_exporter import PrometheusMiddleware, handle_metrics |
20 from sse_starlette.sse import EventSourceResponse | 19 |
20 from light import Color, Light, Lights | |
21 | 21 |
22 EX = Namespace('http://example.com/') | 22 EX = Namespace('http://example.com/') |
23 | 23 |
24 logging.basicConfig(level=logging.INFO) | 24 logging.basicConfig(level=logging.INFO) |
25 log = logging.getLogger() | 25 log = logging.getLogger() |
26 | |
27 | |
28 class Color(str): | |
29 | |
30 def to_js(self): | |
31 return self | |
32 | |
33 | |
34 @dataclass | |
35 class Light: | |
36 name: str | |
37 address: str | |
38 online: bool | |
39 colorRequest: Color | |
40 colorMessage: dict | |
41 colorCurrent: Color | |
42 latencyMs: float | |
43 | |
44 def to_js(self): | |
45 return { | |
46 'light': { | |
47 'name': self.name, | |
48 'address': self.address, | |
49 'online': self.online, | |
50 'colorRequest': self.colorRequest.to_js(), | |
51 'colorMessage': self.colorMessage, | |
52 'colorCurrent': self.colorCurrent.to_js(), | |
53 'latencyMs': self.latencyMs, | |
54 } | |
55 } | |
56 | |
57 | |
58 class Lights: | |
59 _d: dict[str, Light] = {} | |
60 | |
61 def add(self, d: Light): | |
62 self._d[d.name] = d | |
63 | |
64 def byName(self, name: str) -> Light: | |
65 return self._d[name] | |
66 | |
67 async def changes(self): # yields None on any data change | |
68 while True: | |
69 yield None | |
70 await asyncio.sleep(1) | |
71 | |
72 def to_js(self): | |
73 return {'lights': [d.to_js() for d in sorted(self._d.values(), key=lambda r: r.name)]} | |
74 | 26 |
75 | 27 |
76 async def output(lights: Lights, request: Request) -> JSONResponse: | 28 async def output(lights: Lights, request: Request) -> JSONResponse: |
77 light = lights.byName(request.query_params['light']) | 29 light = lights.byName(request.query_params['light']) |
78 return JSONResponse(light.to_js()) | 30 return JSONResponse(light.to_js()) |
80 | 32 |
81 async def table(lights: Lights, req: Request) -> EventSourceResponse: | 33 async def table(lights: Lights, req: Request) -> EventSourceResponse: |
82 | 34 |
83 async def g(): | 35 async def g(): |
84 async for ping in lights.changes(): | 36 async for ping in lights.changes(): |
85 await asyncio.sleep(1) | |
86 yield json.dumps({'now': time.time()} | lights.to_js()) | 37 yield json.dumps({'now': time.time()} | lights.to_js()) |
87 | 38 |
88 return EventSourceResponse(g()) | 39 return EventSourceResponse(g()) |
89 | 40 |
90 | 41 |