Mercurial > code > home > repos > light-bridge
annotate light.py @ 15:61d4ccecfed8
rough refactor
author | drewp@bigasterisk.com |
---|---|
date | Sun, 28 Jan 2024 21:18:01 -0800 |
parents | e3dbd04dab96 |
children | 1d15dc4d673f |
rev | line source |
---|---|
2 | 1 import asyncio |
14
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
2 import json |
2 | 3 import logging |
13
1c865af058e7
start make* funcs and add links to light addresses
drewp@bigasterisk.com
parents:
12
diff
changeset
|
4 from dataclasses import dataclass |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
5 from typing import Callable |
2 | 6 |
5
7eeda7f4f9cd
spell it to_dict, for compat with DataClassJsonMixin
drewp@bigasterisk.com
parents:
4
diff
changeset
|
7 from color import Color |
14
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
8 from mqtt_io import MqttIo |
5
7eeda7f4f9cd
spell it to_dict, for compat with DataClassJsonMixin
drewp@bigasterisk.com
parents:
4
diff
changeset
|
9 |
2 | 10 log = logging.getLogger('light') |
11 | |
12 | |
13 @dataclass | |
14 class Light: | |
15 name: str | |
14
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
16 address: Transport |
9 | 17 |
18 requestingColor: Color = Color.fromHex('#000000') | |
19 requestingDeviceColor: DeviceColor = DeviceColor() | |
20 | |
21 emittingColor: Color = Color.fromHex('#000000') | |
22 online: bool | None = None | |
23 latencyMs: float | None = None | |
24 | |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
25 notifyChanged: Callable | None = None |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
26 |
9 | 27 def __post_init__(self): |
28 self.requestingDeviceColor = self.deviceColor(self.requestingColor) | |
2 | 29 |
5
7eeda7f4f9cd
spell it to_dict, for compat with DataClassJsonMixin
drewp@bigasterisk.com
parents:
4
diff
changeset
|
30 def to_dict(self): |
9 | 31 d = { |
32 'name': self.name, | |
13
1c865af058e7
start make* funcs and add links to light addresses
drewp@bigasterisk.com
parents:
12
diff
changeset
|
33 'address': self.address.linked(), |
9 | 34 'requestingColor': self.requestingColor.hex(), |
35 'requestingDeviceColor': self.requestingDeviceColor.summary(), | |
36 'emittingColor': self.emittingColor.hex(), | |
37 'online': self.online, | |
38 'latencyMs': self.latencyMs, | |
2 | 39 } |
40 | |
9 | 41 return {'light': d} |
42 | |
43 def deviceColor(self, c: Color) -> DeviceColor: | |
44 # do LUT here | |
45 return DeviceColor(r=c.r, g=c.g, b=c.b) | |
46 | |
47 async def setColor(self, c: Color): | |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
48 log.info(f'setColor from {self.requestingColor} to {c}') |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
49 if c == self.requestingColor: |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
50 return |
9 | 51 self.requestingColor = c |
52 self.requestingDeviceColor = self.deviceColor(self.requestingColor) | |
14
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
53 |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
54 if self.notifyChanged: |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
55 self.notifyChanged() |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
56 |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
57 # waits for the relevant round-trip |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
58 log.info(f'transport send {self.requestingDeviceColor}') |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
59 await self.address.send(self.requestingDeviceColor) |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
60 |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
61 self.emittingColor = self.requestingColor |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
62 if self.notifyChanged: |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
63 self.notifyChanged() |
9 | 64 |
2 | 65 |
14
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
66 def makeZbBar(mqtt: MqttIo, name: str, ieee: str) -> Light: |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
67 return Light(name=name, address=ZigbeeTransport(mqtt, name, ieee)) |
13
1c865af058e7
start make* funcs and add links to light addresses
drewp@bigasterisk.com
parents:
12
diff
changeset
|
68 |
1c865af058e7
start make* funcs and add links to light addresses
drewp@bigasterisk.com
parents:
12
diff
changeset
|
69 |
2 | 70 class Lights: |
71 _d: dict[str, Light] = {} | |
72 | |
14
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
73 def __init__(self, mqtt: MqttIo): |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
74 self.mqtt = mqtt |
e3dbd04dab96
add mqtt; talk to first light (no throttling)
drewp@bigasterisk.com
parents:
13
diff
changeset
|
75 self.add(makeZbBar(mqtt, 'do-bar', '0xa4c13844948d2da4')) |
6 | 76 |
2 | 77 def add(self, d: Light): |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
78 d.notifyChanged = self.notifyChanged |
2 | 79 self._d[d.name] = d |
80 | |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
81 self.notifyChanged() |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
82 |
2 | 83 def byName(self, name: str) -> Light: |
84 return self._d[name] | |
85 | |
12 | 86 def to_dict(self): |
87 return {'lights': [d.to_dict() for d in sorted(self._d.values(), key=lambda r: r.name)]} | |
88 | |
89 # the following is bad. Get a better events lib. | |
90 _changeSleepTask: asyncio.Task | None = None | |
91 | |
2 | 92 async def changes(self): # yields None on any data change |
93 while True: | |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
94 log.info('Lights has a change') |
2 | 95 yield None |
11
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
96 self._changeSleepTask = asyncio.create_task(self._sleep()) |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
97 try: |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
98 await self._changeSleepTask |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
99 except asyncio.CancelledError: |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
100 pass |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
101 self._changeSleepTask = None |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
102 |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
103 async def _sleep(self): |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
104 await asyncio.sleep(100) |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
105 |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
106 def notifyChanged(self): |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
107 log.info('Lights.notifyChanged()') |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
108 if self._changeSleepTask is not None: |
028ed39aa78f
more ts types; attempted multiplayer but the change events are managed wrong
drewp@bigasterisk.com
parents:
9
diff
changeset
|
109 self._changeSleepTask.cancel() |