Switchmate Switch Covers

Hi!
In my Home Assistant Config, I set up a Jerry Rigged way of using Switchmate with Home Assistant. It goes like this:
Alexa -> Home Assistant (as MQTT Switch) -> MQTT Pub -> In Home Android Device -> Tasker Task -> Switchmate App -> On /off.

But what would be great if I could get a shorter path for turning it on, such as:

Alexa -> Home Assistant (as Switchmate Component, since it is BLE, Connecting to it and sending a simple packet payload (on/off) should suffice, especially in Raspberry Pi case) -> Switchmate (on/off), then returns state to Home Assistant.

Just putting this request out so I can get a group together to make this happen because the “Zip” add-on for the Switchmate (which talking to devs, say it’s a BLE to Wifi Bridge) will be coming soon. I’m buying a bunch of these for home controlling for my grandfather.

Thanks!

Would be great to see this integration!

Hey, wondering if you were still using the tasker work around. If so, any tips on setting it up. I bought 4 switchmates assuming that they’d be compatible with one of my many hubs (I have pretty much everything but the wink 2…). Fooled again!

The easiest way (other than direct control with the Wink component and Wink 2 Hub, which i still really want), having an MQTT Client Tasker Plugin will allow messages to send to your device from home assistant. Since I have a wall mounted android tablet at my house, this wasn’t an issue. Every time I say on or off, it sends it the android device, and Tasker initiates the task. The fast and sorry way i do it is use the AutoInput addon and tell it to go through the steps of turning it on and off like you were right in front of it. Its sort of inconvenient but it works OK.

Just picked up some switchmates recently to play around with in my apartment. If anyone is running HASS on a raspberry pi 3 (or something else capable of BLE) there is a great python script that you can use here (https://github.com/dale3h/switchmate/tree/python3) to control the switches directly. You’ll have to run the script manually a few times to sniff the MAC and auth keys for the switchmate devices but after that it should be pretty simple to add a command_line switch as follows:

- platform: command_line
  switches:
    bedroom_light:
      friendly_name: 'Bedroom Lights'
      command_on: '/path/to/switchmate.py <switchmate MAC> <switchmate auth> switch on'
      command_off: '/path/to/switchmate.py <switchmate MAC> <switchmate auth> switch off'

Hey,

Did you get the script to work?I downloaded the script and tried to install the dependencies using these commands:

sudo apt-get install libglib2.0-dev
sudo pip3 install bluepy==1.0.5
sudo pip3 install docopt==0.6.2

I got no errors during the install, but I get the following error when I run the script.

Scanning…
Traceback (most recent call last):
File “./switchmate.py”, line 136, in
scan()
File “./switchmate.py”, line 114, in scan
devices = scanner.scan(10.0)
File “/usr/local/lib/python2.7/dist-packages/bluepy-1.1.1-py2.7.egg/bluepy/btle.py”, line 674, in scan
self.start()
File “/usr/local/lib/python2.7/dist-packages/bluepy-1.1.1-py2.7.egg/bluepy/btle.py”, line 611, in start
self._startHelper(iface=self.iface)
File “/usr/local/lib/python2.7/dist-packages/bluepy-1.1.1-py2.7.egg/bluepy/btle.py”, line 246, in _startHelper
universal_newlines=True)
File “/usr/lib/python2.7/subprocess.py”, line 710, in init
errread, errwrite)
File “/usr/lib/python2.7/subprocess.py”, line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

Is there an addition dependency or installation step I am missing.

Thanks in advance.

Did you use Python 3? It looks like it’s using Python 2.7 dependancies.

Yeah I did. I’ll try using Python 2.7 dependencies.

Thanks

I think the issue is that you installed the dependencies as python 3 via pip3 but ran the script using python 2… Running the script via “python3 switchmate.py” should fix it.

I tried to run it using the python3 dependencies and get this error:

pi@raspberrypi:~/switchmate $ sudo python3 ./switchmate.py scan
Scanning…
Traceback (most recent call last):
File “./switchmate.py”, line 136, in
scan()
File “./switchmate.py”, line 114, in scan
devices = scanner.scan(10.0)
File “/usr/local/lib/python3.4/dist-packages/bluepy/btle.py”, line 631, in scan
self.start()
File “/usr/local/lib/python3.4/dist-packages/bluepy/btle.py”, line 569, in start
self._mgmtCmd(“le on”)
File “/usr/local/lib/python3.4/dist-packages/bluepy/btle.py”, line 240, in _mgmtCmd
“Failed to execute mgmt cmd ‘%s’” % (cmd))
bluepy.btle.BTLEException: Failed to execute mgmt cmd ‘le on’

Also tried using the python2 dependencies. Same error.

pi@raspberrypi:~/switchmate $ sudo python2 ./switchmate.py scan
Scanning…
Traceback (most recent call last):
File “./switchmate.py”, line 136, in
scan()
File “./switchmate.py”, line 114, in scan
devices = scanner.scan(10.0)
File “/usr/local/lib/python2.7/dist-packages/bluepy/btle.py”, line 674, in scan
self.start()
File “/usr/local/lib/python2.7/dist-packages/bluepy/btle.py”, line 612, in start
self._mgmtCmd(“le on”)
File “/usr/local/lib/python2.7/dist-packages/bluepy/btle.py”, line 276, in _mgmtCmd
“Failed to execute mgmt cmd ‘%s’” % (cmd))
bluepy.btle.BTLEException: Failed to execute mgmt cmd ‘le on’

Not sure if there would be a conflict with the 2 version of python.

I guess I should verify what the pre-requests are for using the script. I currently am using the Pi bluetooth with the flic buttons and they work fine. Would I need another bluetooth dongle to scan for the switchmate devices?

Thanks

To be honest I’m not sure what this problem is. I don’t believe I really used the “scan” feature of the script but instead used an android app as a ble scanner to get the MAC addresses. I’ll have to try scanning when I get a chance. Not sure if the Pi bt is limited in talking to a single device but I have 3 switchmates so I don’t think that’s it.

Yeah I’m not getting any issues as long as I run the “scan” mode as root. I’m also running hassbian so maybe that pre-configures the raspberry pi bluetooth in a certain way that works for this use case? Try running sudo hcitool lescan to see if you can properly scan bluetooth LE devices without the python module being involved. Not sure if this is helpful but here is the output of my hciconfig command:

hci0:	Type: BR/EDR  Bus: UART
	BD Address: <Bluetooth MAC>  ACL MTU: 1021:8  SCO MTU: 64:1
	UP RUNNING 
	RX bytes:23667 acl:247 sco:0 events:1587 errors:0
	TX bytes:14540 acl:241 sco:0 commands:887 errors:0

I get this error when I try that command:
pi@raspberrypi:~ $ sudo hcitool lescan
Set scan parameters failed: Input/output error

If I try to take the device down it says that the device is busy.

pi@raspberrypi:~ $ sudo hciconfig hci0 down
Can’t down device hci0: Device or resource busy (16)

I have a feeling that the flic service has the device locked so that might be the problem. I could get a ble dongle and try that. If I run sudo hciconfig I get the device info.

hci0: Type: BR/EDR Bus: UART
BD Address: B8:27:EB:29:BE:B2 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:3386677 acl:0 sco:0 events:42 errors:0
TX bytes:9775 acl:6 sco:0 commands:1376 errors:0

Thanks for the help.

Yes, the flic service is definitely the problem. I didn’t realize that it required a separate service to communicate with the buttons. According to their github (GitHub - 50ButtonsEach/fliclib-linux-hci: Flic SDK for Linux):

This library is built on top of the HCI_CHANNEL_USER capability of the Linux kernel. This gives the library an exclusive access to directly access the bluetooth controller, which means no Bluetooth stack (like Bluez) is needed on the host side. This way we can (hopefully) guarantee stability compared to other solutions but also optimize the protocol to only exchange the packets that are needed for the Flic buttons to communicate. The downside however is that you will not be able to use that dedicated bluetooth controller for other bluetooth connections, such as streaming audio.

So my script isn’t finding the Switchmate when I run sudo python3 switchmate.py scan, though sudo hcitool lescan does find it, so my adapter is capable of detecting it.

I do also have csrmesh installed to turn a HomeBrite bulb on and off, but that’s command line as well so I don’t see it taking over the adapter or anything. Any ideas?

(Oh, one more potentially important point: mine is one of the new-model Switchmates, the slightly-slimmer one with the motion sensor on it. So if anyone has gotten one of those working with the Python script, it would be really good to know so I’m not spinning wheels. :))

Turns out the UUID changed between versions. So when I change the line to:

SWITCHMATE_SERVICE = 'abd0f555eb40e7b2ac49ddeb83d32ba2'

…it now comes up in a scan.

So, next steps: getting status, and getting an auth code. Unfortunately, neither are working:

pi@raspberrypi:~/switchmate $ sudo python3 switchmate.py status
Looking for switchmate status...
Traceback (most recent call last):
  File "switchmate.py", line 140, in <module>
    status(arguments['<mac_address>'])
  File "switchmate.py", line 106, in status
    scanner.process(20)
  File "/usr/local/lib/python3.4/dist-packages/bluepy/btle.py", line 621, in process
    self.delegate.handleDiscovery(dev, (dev.updateCount <= 1), isNewData)
  File "switchmate.py", line 94, in handleDiscovery
    print(dev.addr + ' ' + ("off", "on")[(int(data, 16) >> 8) & 1])
TypeError: int() can't convert non-string with explicit base
pi@raspberrypi:~/switchmate $ sudo python3 switchmate.py c0:12:df:cb:b3:23 auth
Traceback (most recent call last):
  File "switchmate.py", line 157, in <module>
    device.writeCharacteristic(AUTH_NOTIFY_HANDLE, NOTIFY_VALUE, True)
  File "/usr/local/lib/python3.4/dist-packages/bluepy/btle.py", line 459, in writeCharacteristic
    return self._getResp('wr')
  File "/usr/local/lib/python3.4/dist-packages/bluepy/btle.py", line 334, in _getResp
    resp = self._waitResp(wantType + ['ntfy', 'ind'], timeout)
  File "/usr/local/lib/python3.4/dist-packages/bluepy/btle.py", line 296, in _waitResp
    raise BTLEException(BTLEException.COMM_ERROR, "Error from Bluetooth stack (%s)" % errcode)
bluepy.btle.BTLEException: Error from Bluetooth stack (comerr)

So I’m stuck again. :stuck_out_tongue:

EDIT: Some slight progress: I don’t need sudo anymore to get the same errors. So once this gets worked out it will be easier to incorporate into HASS.

Based on what you mentioned about the UUID changing between versions, it might be possible that some of the other hard-coded values in the script have changed as well such as AUTH_NOTIFY_HANDLE, AD_TYPE_UUID, or AD_TYPE_SERVICE_DATA. For instance, trying to run int(data, 16) when data is None will display the first error that you posted.

Gotcha. I was hoping not because of the need for the app to work with multiple versions of the device, but yeah, that could be. Is there any way to sniff what those values might need to be based on pairing one to the iOS app? Seeing as I have the device I am happy to test things and collect data if it might help.

So looking at it, AD_TYPE_UUID is probably right because if it’s not that line of code that errors never executes. So it’s probably AD_TYPE_SERVICE_DATA that needs to be jiggered, yes?

Yeah that is for the scanning which I never really relied on the script for that part anyway, if you know the MAC address of the switches then you should be set there. You also have issues with auth which brings in to play 4 constants AUTH_NOTIFY_HANDLE, NOTIFY_VALUE, AUTH_HANDLE, AUTH_INIT_VALUE.

I didn’t write this script so I can’t really tell you how all of these values were obtained initially unfortunately. If you want to poke around at the values and try to make sense of it, this repo has some good tools that might work https://github.com/getsenic/gatt-python