master
Raw Download raw file
 1import pywemo
 2
 3# Total number of wemo devices inside the broadcast domain
 4NUM_WEMO_DEVICES = 12
 5
 6# Context: dumb_switch is just a button that looks like a light switch.
 7#          It is always powered on but does not actually sit in the flow of the circuit.
 8#          We use this "button" switch to be the 2nd location of the three way switch.
 9#          If either side is pressed (toggled) the other side should match BinaryState.
10#          This allows for the dumb button switch to control the other side of the pair.
11#          real_switch is the actual switch that should be controlled (the other side of the pair)
12#
13# Prereqs: You need to know the MAC addresses of both sides of the three-way switch.
14#          See discove_all.py for help with doing this part.
15#          This seemed to be the simplist way to setup the switch without doing anything crazy
16#          like editing the name of the switch and searching for some spcific name 
17#          (I thought about doing this)
18
19
20class ThreeWaySwitch:
21    def __init__(self, regsub, name, dumb_switch_mac, real_switch_mac):
22        self.name = name
23        self.real_switch = None  # set during discovery
24        self.real_switch_mac = real_switch_mac
25        self.dumb_switch = None  # set during discovery
26        self.dumb_switch_mac = dumb_switch_mac
27        self.regsub = regsub  # pywemo RegistrySubscription() type
28
29    def discover(self):
30        while self.real_switch == None or self.dumb_switch == None:
31            print('Searching for "{}" devices ... '.format(self.name), end="")
32            devices = pywemo.discover_devices()
33            print("saw {}/{} devices.".format(len(devices), NUM_WEMO_DEVICES))
34            for d in devices:
35                if d.mac == self.real_switch_mac:
36                    self.real_switch = d
37                if d.mac == self.dumb_switch_mac:
38                    self.dumb_switch = d
39        print(
40            "  real_switch:  {:24}{:24}{:12}".format(
41                self.real_switch.name, self.real_switch.host, self.real_switch.mac
42            )
43        )
44        print(
45            "  dumb_switch:  {:24}{:24}{:12}".format(
46                self.dumb_switch.name, self.dumb_switch.host, self.dumb_switch.mac
47            )
48        )
49
50    def sync(self):
51        self.real_switch.set_state(0)
52        self.dumb_switch.set_state(0)
53
54    def register_callbacks(self):
55        self.regsub.register(self.real_switch)
56        self.regsub.register(self.dumb_switch)
57        self.regsub.on(self.real_switch, "BinaryState", self.toggle_callback)
58        self.regsub.on(self.dumb_switch, "BinaryState", self.toggle_callback)
59        print('"{}" devices callback registration complete\n'.format(self.name))
60
61    def toggle_callback(self, device, cb_type, value):
62        print("  {:16}{:24}{:24}{:12}".format(self.name, device.name, cb_type, value))
63        if device.mac == self.real_switch.mac:
64            self.dumb_switch.set_state(value)
65        if device.mac == self.dumb_switch.mac:
66            self.real_switch.set_state(value)
67
68
69if __name__ == "__main__":
70    regsub = pywemo.SubscriptionRegistry()
71
72    # three way switches: (Name, dummy switch MAC, real_switch switch MAC)
73    kitchen = ThreeWaySwitch(regsub, "Kitchen Dimmer", "24F5A25D64CC", "58EF68BB617A")
74    foyer = ThreeWaySwitch(regsub, "Foyer Dimmer", "94103E4E72A0", "58EF68BB756C")
75    all_3ways = [kitchen, foyer]
76
77    print("--- Starting discovery of {} three-way circuits ---".format(len(all_3ways)))
78    for tw in all_3ways:
79        tw.discover()
80        tw.sync()
81        tw.register_callbacks()
82
83    print("--- Starting callback handler loop ---")
84    regsub.start()