Broadlink S1C Kit sensors in HA using python and MQTT

Hi All,

I’ve been playing around with the Broadlink S1C sensors (Alarm Kit), I was looking for a way to integrate it into HA and I found the following thread on the python-broadlink github:

Thanks to the work of a user named “jazzina” I managed to “integrate” the broadlink S1C alarm sensors into HA.

It’s not 100% reliable but it’s working (sort of…), maybe someone will have the time to do more testing and make it better and more reliable.

In my setup, I have the S1C Kit which includes only 1 door magnet sensor and 1 motion PIR sensor

First, I used the broadlink e-Control app to add the device and sensors, then I wrote a simple python script which runs in the background, gets the sensors data and publish the data via MQTT.

If you want to try it yourself here are the steps you need to take:

Create a new directory on your Raspberry Pi with an Hassbian distribution:

mkdir /home/pi/s1c

Change directory:

cd /home/pi/s1c

jazzina code wasn’t added to the official python-broadlink library and I didn’t want to to make any breaking changes to my Hassbian so I just downloaded the library from here:

wget https://github.com/jazzina/python-broadlink/blob/master/broadlink/__init__.py -O /home/pi/s1c/broadlink.py

Create a new python script using nano:

nano s1c.py

Change the following code according to your needs and parameters and paste it in the s1c.py file.

s1c.py:

import broadlink
import time, os
devices = broadlink.S1C(host=("10.0.0.31",80), mac=bytearray.fromhex("B4430XXXXXXX")) # Change to your S1C IP Address and S1C Mac Address
devices.auth()
sens = devices.get_sensors_status()
old = sens
while 1:
	try:
		sens = devices.get_sensors_status()
		for i, se in enumerate(sens['sensors']):
			if se['status'] != old['sensors'][i]['status']:
				sName = se['name']
				sType = se['type']
				if sType == "Door Sensor" and str(se['status']) == "0" or sType == "Door Sensor" and str(se['status']) == "128": # Instead of sType you can test for sName in case you have multiple sensors
					print time.ctime() + ": Door closed: " + str(se['status'])
					os.system("mosquitto_pub -h 10.0.0.35 -p 1883 -t 'sensors/s1c/entrance_door' -u mosquitto -P password -m " + "Closed") # change the ip address, user name and password for your mosquitto server
				elif sType == "Door Sensor" and str(se['status']) == "16" or sType == "Door Sensor" and str(se['status']) == "144":
					print time.ctime()  +": Door opened: " + str(se['status'])
					os.system("mosquitto_pub -h 10.0.0.35 -p 1883 -t 'sensors/s1c/entrance_door' -u mosquitto -P password -m " + "Open")
				elif sType == "Door Sensor" and str(se['status']) == "48":
					print time.ctime()  +": Door Sensor tampered: " + str(se['status'])
					os.system("mosquitto_pub -h 10.0.0.35 -p 1883 -t 'sensors/s1c/entrance_door' -u mosquitto -P password -m " + "Tampered")
				elif sType == "Motion Sensor" and str(se['status']) == "0" or sType == "Motion Sensor" and str(se['status']) == "128":
					print time.ctime()  +": No Motion: " + str(se['status'])
					os.system("mosquitto_pub -h 10.0.0.35 -p 1883 -t 'sensors/s1c/motion_sensor' -u mosquitto -P password -m " + "No_motion")
				elif sType == "Motion Sensor" and str(se['status']) == "16":
					print time.ctime()  +": Motion Detected: " + str(se['status'])
					os.system("mosquitto_pub -h 10.0.0.35 -p 1883 -t 'sensors/s1c/motion_sensor' -u mosquitto -P password -m " + "Motion_Detected")
				elif sType == "Motion Sensor" and str(se['status']) == "32":
					print time.ctime()  +": Motion Sensor Tampered: " + str(se['status'])
					os.system("mosquitto_pub -h 10.0.0.35 -p 1883 -t 'sensors/s1c/motion_sensor' -u mosquitto -P password -m " + "Tampered")
				old = sens
	except:
		continue

sensors.yaml:

- platform: mqtt
  state_topic: "sensors/s1c/entrance_door"
  name: "entrance_door_sensor"

- platform: mqtt
  state_topic: "sensors/s1c/motion_sensor"
  name: "motion_sensor"

customize.yaml:

sensor.motion_sensor:
	friendly_name: Motion Sensor
	icon: mdi:walk

sensor.entrance_door_sensor:
	friendly_name: Door Sensor
	icon: mdi:glassdoor

Run the script (using python 2.7):

python /home/pi/s1c/s1c.py

  • Please notice that the s1c.py script should be running in the background all the time so it will be a good idea to run it on startup.

Run the s1c.py as a service:

Create a new file named broadlink-s1c.service:

nano broadlink-s1c.service

paste the following and save:

[Unit]
Description=Broadlink S1C
Wants=network.target
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python /home/pi/s1c/s1c.py

[Install]
WantedBy=multi-user.target

Enable the service:

sudo mv broadlink-s1c.service /etc/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable broadlink-s1c.service
sudo systemctl start broadlink-s1c.service
sudo systemctl status broadlink-s1c.service -l

That’s it for now, I haven’t tested this much just for an hour or so and i am not a programmer, if you have any any ideas how to imporve it or if you test it and find any issues or bugs please update this thread.

Screenshots:

Cheers,
Shai.

6 Likes

I think it’s not exactly the best idea to poll the s1c device so rapidly. Currently I implemented it pretty the same, just with some sleep timer, but I will take a look if there’s some broadcast from s1c when an event is happened and to try to take care of it.

I agree, It suffers from the same timeout issues like the A1 sensor, it works for me most of the times but the real issue is the timeouts.

Hello,

I atacched my error

pi@hassbian:~/s1c $ python /home/pi/s1c/s1c.py
Traceback (most recent call last):
File “/home/pi/s1c/s1c.py”, line 1, in
import broadlink
File “/home/pi/s1c/broadlink.py”, line 7

^
SyntaxError: invalid syntax

Make sure you are using python 2.7 and not python 3

Hello, I have reviewed and in the information of HA, it states that I have python 3, as I attached you, what do I have to do in this case ?.

thank you very much

Do you have it installed on a raspberry pi / hassbian ?

yes, is correct

Great,

First connect to the raspberry pi using SSH client
Type: python -V
It should show you the python version

What is the output of the command ?

Great,

You just need to follow these instructions:

Make sure that when you run the s1c.py file you do it as follows:

python s1c.py

and you need to make sure that the file broadlink.py you downloaded is also in the same folder

Hello!
Right, I’ve done all the steps and I just fail to start the script, that’s why I’ve asked for help.

I have uploaded the files to google drive:

https://drive.google.com/drive/folders/0B2-DXeKeq1abWjhsMnpfV3d1YVE?usp=sharing

Try to use them, maybe something went wrong when you copied and pasted the code, just don’t forget to change the IP and MAC Address for the S1C, And the IP, username and password to your mqtt broker.

Hello,

I attached my file

https://www.joaquinmoreno.com/nube/index.php/s/qOAPkffifVGiCDy

Thank you
best regards

You don’t need the colons in the mac address

It should be like this:

devices = broadlink.S1C(host=("192.168.0.182",80), mac=bytearray.fromhex("34EA34F0B949")) # Change to your S1C IP Address and S1C Mac Address

I removed the 2 points to the mac of s1c.py, on the other hand, I edited the broadlink.py, and it had nothing to do with the one that you have the google drive.

It seems that from the repository that you put you download erroneously, therefore I copied your broadlink.py.

Now I execute and it gives me the following error:

pi@hassbian:~/s1c $ python /home/pi/s1c/s1c.py
Traceback (most recent call last):
File “/home/pi/s1c/s1c.py”, line 7, in
sens = devices.get_sensors_status()
File “/home/pi/s1c/broadlink.py”, line 549, in get_sensors_status
_name = str(bytes(sens[4:26]).decode())
UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xc3 in position 10: ordinal not in range(128)

My status as you do, show the same code

I think the codes of the sensors are different than mine, later I will post the information how to capture your sensor codes

@pilitos Use this code to discover your sensor codes, then replace the codes on the other script to match to your’s:

name this file discover.py and put it in the same folder as the other scripts:

import broadlink
devices = broadlink.S1C(host=("10.0.0.20",80), mac=bytearray.fromhex("B44300000000")) # Change to your S1C MAC an IP
devices.auth()

print (devices)
sens = devices.get_sensors_status()
while 1:
	for i, se in enumerate(sens['sensors']):
		print ('Name:', se['name'], 'Status:', se['status'], 'Type:', se['type'])

Hello,

Thank you,

It gives me the following error, when running discover.py.

Am I doing it correctly?

pi@hassbian:~/s1c $ python discover.py
<broadlink.S1C instance at 0x76a9bdf0>
Traceback (most recent call last):
File “discover.py”, line 6, in
sens = devices.get_sensors_status()
File “/home/pi/s1c/broadlink.py”, line 549, in get_sensors_status
_name = str(bytes(sens[4:26]).decode())
UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xc3 in position 10: ordinal not in range(128)