Skip to content

Commit d3bfb28

Browse files
committed
Changing DeviceInfo general behavior, should fix #3
1 parent c363dfc commit d3bfb28

File tree

3 files changed

+79
-25
lines changed

3 files changed

+79
-25
lines changed

examples/multiple_devices.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python3
2+
"""Example of an application managing multiple devices.
3+
4+
This is a typical use case for bridges, in which a single hass-mqtt-things
5+
application acts on behalf of more than one device.
6+
7+
This makes use of the optional DeviceInfo parameter on add_thing.
8+
"""
9+
10+
from ham import MqttManager, DeviceInfo
11+
from ham.switch import OptimisticSwitch
12+
from time import sleep
13+
import os
14+
15+
MQTT_USERNAME = os.environ["MQTT_USERNAME"]
16+
MQTT_PASSWORD = os.environ["MQTT_PASSWORD"]
17+
MQTT_HOST = os.environ["MQTT_HOST"]
18+
19+
20+
class BaseSwitch(OptimisticSwitch):
21+
def __init__(self, index):
22+
self.index = index
23+
self.name = "switch %d" % index
24+
self.short_id = "s%d" % index
25+
26+
def callback(self, state):
27+
print("The switch #%d has been set to %s" % (self.index, state))
28+
29+
30+
if __name__ == "__main__":
31+
manager = MqttManager(MQTT_HOST, username=MQTT_USERNAME, password=MQTT_PASSWORD)
32+
all_switches = [BaseSwitch(200 + i) for i in range(3)]
33+
manager.add_things(all_switches)
34+
35+
for device_id in range(3):
36+
switches = [BaseSwitch(100 + 10 * device_id + i) for i in range(3)]
37+
di = DeviceInfo(
38+
name="Device#%d" % device_id,
39+
hw_version="1.0.0alpha",
40+
sw_version="0.0.%dbeta" % device_id,
41+
identifiers=["device_testing_%02d" % device_id],
42+
connections=[("mac", "eb:%02d:de:c3:e5:f0" % device_id)],
43+
)
44+
manager.add_things(switches, origin=di)
45+
all_switches.extend(switches)
46+
47+
manager.start()
48+
49+
print("Entering an infinite loop, Ctrl+C multiple times to exit.")
50+
state = False
51+
while True:
52+
for s in all_switches:
53+
sleep(1)
54+
s.state = state
55+
state = not state

src/ham/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__version__ = "0.5.6"
22

3-
from .manager import MqttManager
3+
from .manager import MqttManager, DeviceInfo
44

5-
__all__ = ["MqttManager"]
5+
__all__ = ["MqttManager", "DeviceInfo"]

src/ham/manager.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DeviceInfo(TypedDict, total=False):
3030

3131

3232
class MqttManager(Thread):
33-
things: dict[Optional[DeviceInfo], list[Thing]]
33+
things: list[tuple[Optional[DeviceInfo], Thing]]
3434
client: mqtt.Client
3535
node_id: str
3636
base_topic: str
@@ -100,20 +100,20 @@ def __init__(self, host='localhost', port=1883, username=None,
100100
else:
101101
self.name = self.node_id
102102

103-
self.things = defaultdict(list)
103+
self.things = list()
104104
self.unique_identifier = unique_identifier or self.get_mac()
105105
self.device_info = self._gen_device_info()
106106

107107
logger.debug("Initialization parameters: node_id=%s, base_topic=%s, discovery_prefix=%s, name=%s",
108108
self.node_id, self.base_topic, self.discovery_prefix, self.name)
109109

110110
def add_thing(self, thing: Thing, origin: Optional[DeviceInfo] = None):
111-
self.things[origin].append(thing)
111+
self.things.append((origin, thing))
112112
thing.set_manager(self)
113113

114114
def add_things(self, things: list[Thing], origin: Optional[DeviceInfo] = None):
115-
self.things[origin].extend(things)
116115
for thing in things:
116+
self.things.append((origin, thing))
117117
thing.set_manager(self)
118118

119119
def run(self):
@@ -182,7 +182,7 @@ def on_connect(self, _, userdata, flags, rc):
182182

183183
logger.debug("Device information for this manager: %s", self.device_info)
184184

185-
for origin, things in self.things.items():
185+
for origin, thing in self.things:
186186
if origin is None:
187187
common_config = {
188188
"~": self.base_topic,
@@ -197,28 +197,27 @@ def on_connect(self, _, userdata, flags, rc):
197197
"via": self.device_info["identifiers"][0]
198198
}
199199

200-
for thing in things:
201-
logger.info("Publishing discovery message for: %r", thing)
202-
203-
# New dictionary with sensible defaults
204-
config = common_config.copy()
205-
config["unique_id"] = f"{ self.unique_identifier }_{ thing.short_id }"
200+
logger.info("Publishing discovery message for: %r", thing)
201+
202+
# New dictionary with sensible defaults
203+
config = common_config.copy()
204+
config["unique_id"] = f"{ self.unique_identifier }_{ thing.short_id }"
206205

207-
# Then call get_config, and allow the implementation to override
208-
# the previously set defaults (at their own risk)
209-
config.update(thing.get_config())
206+
# Then call get_config, and allow the implementation to override
207+
# the previously set defaults (at their own risk)
208+
config.update(thing.get_config())
210209

211-
config_topic = "%s/%s/%s/%s/config" % (
212-
self.discovery_prefix,
213-
thing.component,
214-
self.node_id,
215-
thing.short_id
216-
)
210+
config_topic = "%s/%s/%s/%s/config" % (
211+
self.discovery_prefix,
212+
thing.component,
213+
self.node_id,
214+
thing.short_id
215+
)
217216

218-
logger.debug("Sending the following config dict to %s:\n%s", config_topic, config)
217+
logger.debug("Sending the following config dict to %s:\n%s", config_topic, config)
219218

220-
self.client.publish(config_topic, json.dumps(config), retain=True)
221-
thing.set_callbacks()
219+
self.client.publish(config_topic, json.dumps(config), retain=True)
220+
thing.set_callbacks()
222221

223222
# Set up availability topic
224223
###########################

0 commit comments

Comments
 (0)