Commit 8f8f536
Changed files (4)
discover_all.py
@@ -0,0 +1,12 @@
+# a useful function not really needed for the 3way daemon
+#find_and_show_all_wemo_devices()
+def find_and_show_all_wemo_devices():
+ devices = {}
+ while len(devices) < NUM_WEMO_DEVICES:
+ print("discovering devices ... ", end='')
+ devices = pywemo.discover_devices()
+ print("%d/%d" % (len(devices) , NUM_WEMO_DEVICES))
+
+ print ("--- %d Devices Found ---" % len(devices))
+ for d in devices:
+ print (" {:24}{:16}{:12}".format(d.name, d.host, d.mac))
Dockerfile
@@ -4,4 +4,4 @@ RUN apk add musl-dev gcc linux-headers && \
pip install pywemo && \
apk del musl-dev gcc linux-headers
ADD three-way-switches.py /three-way-switches.py
-CMD python3 /three-way-switches.py
+CMD python3 -u /three-way-switches.py
README.md
@@ -1,1 +1,15 @@
-sudo docker run --network host -it pywemo
+# Quickstart
+
+```
+sudo docker build . -t "wemo-three-way-switch"
+sudo docker run --network host -d "wemo-three-way-switch"
+```
+
+
+## Expected image sizes
+
+```
+REPOSITORY TAG IMAGE ID CREATED SIZE
+wemo-three-way-switch latest 59553fd2c4f4 12 seconds ago 90.6 MB
+python 3.7-alpine 93b16a3d4364 6 days ago 79.4 MB
+```
three-way-switches.py
@@ -1,75 +1,82 @@
import pywemo
+# Total number of wemo devices inside the broadcast domain
NUM_WEMO_DEVICES = 12
-# Context: dumbswitch is just a button that looks like a light switch
+# Context: dumb_switch is just a button that looks like a light switch.
+# It is always powered on but does not actually sit in the flow of the circuit.
+# We use this "button" switch to be the 2nd location of the three way switch.
+# If either side is pressed (toggled) the other side should match.
+# This allows for the dumb button switch to control the other side of the pair.
+# real_switch is the actual switch that should be controlled (the other side of the pair)
+#
+# Prereqs: You need to know the MAC addresses of both sides of the three-way switch.
+# See discove_all.py for help with doing this part.
+# This seemed to be the simplist way to setup the switch without doing anything crazy
+# like editing the name of the switch and searching for some spcific name (I thought about doing this)
class ThreeWaySwitch:
- def __init__(self, regsub, name, notswitch_mac, dimmer_mac):
+ def __init__(self, regsub, name, dumb_switch_mac, real_switch_mac):
self.name = name
- self.notswitch_mac = notswitch_mac
- self.dimmer_mac = dimmer_mac
- self.dimmer = None # set during discovery
- self.notswitch = None # set during discovery
- self.regsub = regsub
+ self.real_switch = None # set during discovery
+ self.real_switch_mac = real_switch_mac
+ self.dumb_switch = None # set during discovery
+ self.dumb_switch_mac = dumb_switch_mac
+ self.regsub = regsub # pywemo RegistrySubscription() type
def discover(self):
- while self.dimmer == None or self.notswitch == None:
+ while self.real_switch == None or self.dumb_switch == None:
print("Searching for \"%s\" devices ... " % self.name, end='')
devices = pywemo.discover_devices()
print("saw %d/%d devices." % (len(devices) , NUM_WEMO_DEVICES))
for d in devices:
- if d.mac == self.dimmer_mac:
- self.dimmer = d
- if d.mac == self.notswitch_mac:
- self.notswitch = d
- print ("dimmer: {:24}{:24}{:12}".format(self.dimmer.name, self.dimmer.host, self.dimmer.mac))
- print ("notswitch: {:24}{:24}{:12}".format(self.notswitch.name, self.notswitch.host, self.notswitch.mac))
+ if d.mac == self.real_switch_mac:
+ self.real_switch = d
+ if d.mac == self.dumb_switch_mac:
+ self.dumb_switch = d
+ print ("real_switch: {:24}{:24}{:12}".format(
+ self.real_switch.name,
+ self.real_switch.host,
+ self.real_switch.mac)
+ )
+ print ("dumb_switch: {:24}{:24}{:12}".format(
+ self.dumb_switch.name,
+ self.dumb_switch.host,
+ self.dumb_switch.mac)
+ )
def sync(self):
- self.dimmer.set_state(0)
- self.notswitch.set_state(0)
+ self.real_switch.set_state(0)
+ self.dumb_switch.set_state(0)
def register_callbacks(self):
- self.regsub.register(self.dimmer)
- self.regsub.register(self.notswitch)
- self.regsub.on(self.dimmer, "BinaryState", self.toggle_callback)
- self.regsub.on(self.notswitch, "BinaryState", self.toggle_callback)
+ self.regsub.register(self.real_switch)
+ self.regsub.register(self.dumb_switch)
+ self.regsub.on(self.real_switch, "BinaryState", self.toggle_callback)
+ self.regsub.on(self.dumb_switch, "BinaryState", self.toggle_callback)
print()
def toggle_callback(self, device, cb_type, value):
print (" {:16}{:24}{:24}{:12}".format(self.name, device.name, cb_type, value))
- if device.mac == self.dimmer.mac:
- self.notswitch.set_state(value)
- if device.mac == self.notswitch.mac:
- self.dimmer.set_state(value)
-
+ if device.mac == self.real_switch.mac:
+ self.dumb_switch.set_state(value)
+ if device.mac == self.dumb_switch.mac:
+ self.real_switch.set_state(value)
-# a useful function not really needed for the 3way daemon
-#find_and_show_all_wemo_devices()
-def find_and_show_all_wemo_devices():
- devices = {}
- while len(devices) < NUM_WEMO_DEVICES:
- print("discovering devices ... ", end='')
- devices = pywemo.discover_devices()
- print("%d/%d" % (len(devices) , NUM_WEMO_DEVICES))
- print ("--- %d Devices Found ---" % len(devices))
- for d in devices:
- print (" {:24}{:16}{:12}".format(d.name, d.host, d.mac))
-
-
-regsub = pywemo.SubscriptionRegistry()
-
-# three way switches: (Name, dummy switch MAC, dimmer switch MAC)
-kitchen = ThreeWaySwitch(regsub, "Kitchen Dimmer", "24F5A25D64CC", "58EF68BB617A")
-foyer = ThreeWaySwitch(regsub, "Foyer Dimmer", "94103E4E72A0", "58EF68BB756C")
-all_3ways = [kitchen, foyer]
-
-for t in all_3ways:
- t.discover()
- t.sync()
- t.register_callbacks()
-
-print ("--- Starting Callback Handler Loop ---")
-regsub.start()
+if __name__ == "__main__":
+ regsub = pywemo.SubscriptionRegistry()
+
+ # three way switches: (Name, dummy switch MAC, real_switch switch MAC)
+ kitchen = ThreeWaySwitch(regsub, "Kitchen Dimmer", "24F5A25D64CC", "58EF68BB617A")
+ foyer = ThreeWaySwitch(regsub, "Foyer Dimmer", "94103E4E72A0", "58EF68BB756C")
+ all_3ways = [kitchen, foyer]
+
+ print ("--- Starting discovery of %d three-way circuits ---" % len(all_3ways))
+ for tw in all_3ways:
+ tw.discover()
+ tw.sync()
+ tw.register_callbacks()
+
+ print ("--- Starting callback handler loop ---")
+ regsub.start()