Hello everyone,
After much reading (notably here and here), I finally managed to hack together a solution that works quite well to get TechLife Pro light bulbs (such as these ones or these ones) to play nice with Home Assistant, without physically opening up the light bulbs or otherwise modifying their hardware or software.
This tutorial is still a work in progress, so please bear with me and let me know if something is incorrect or isn’t working for you.
0. Prerequisites
For the purposes of this guide, I will assume that you are running HA inside Docker. I also assume that you are familiar with the command line and with general tech speak.
Make sure that your HA installation is up and running, and has a working MQTT broker (such as the excellent core_mosquitto
addon), both installed and running.
1. Create a working directory in the homeassistant
container
Run the following command from inside the main HA Docker container:
mkdir -p /config/custom_components/TechLife
2. Copy necessary files from the mosquitto_core
container to the homeassistant
container
Copy the following files from the mosquitto_core
container to homeassistant
container, into the directory that you created in step 1:
libcares.so.2
libcares.so.2.3.0
libcrypto.so.1.0.0
libmosquitto.so.1
libssl.so.1.0.0
mosquitto_pub
You can try executing the mosquitto_pub
binary from your working directory inside the homeassistant
container. However, it should give an error about missing libraries at this point; we’ll take care of this later on.
3. Create handler script and add it to HA
We’re going to create a script that handles and sends event to the light bulbs. Save this file in the directory from step 1.
TechLife.sh
:
#!/bin/bash
t="dev_sub_""$1"
t=$(echo $t | tr '[:upper:]' '[:lower:]')
cp /config/custom_components/TechLife/*.so* /usr/lib
if [ "$2" != "" ]; then
if [ "$2" = "on" ]; then
echo -en "\xfa\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x23\xfb" | /config/custom_components/TechLife/mosquitto_pub -t $t -s -h 10.0.1.11 -u "mqttusernamehere" -P "mqttpasswordhere"
elif [ "$2" = "off" ]; then
echo -en "\xfa\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\xfb" | /config/custom_components/TechLife/mosquitto_pub -t $t -s -h 10.0.1.11 -u "mqttusernamehere" -P "mqttpasswordhere"
elif [ "$2" = "dim" ]; then
echo -en "\xfa\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x23\xfb" | /config/custom_components/TechLife/mosquitto_pub -t $t -s -h 10.0.1.11 -u "mqttusernamehere" -P "mqttpasswordhere"
d=$(expr $3 \* 100)
prefix='28'
oneToSix='000000000000'
sevenToTen=$(printf %08X "$d" | grep -o .. | tac | tr "\n" "," | sed "s/,//g")
elevenToThirteen='0000f0'
oneToThirteen=$(echo $oneToSix$sevenToTen$elevenToThirteen)
oneToThirteenMod=$(echo $oneToThirteen | sed 's/../0x&^/g' | sed 's/.$//')
xor=$(python3 -c "print(hex($oneToThirteenMod)[2:].lower())")
suffix='29'
k=$(echo $prefix$oneToSix$sevenToTen$elevenToThirteen$xor$suffix | sed 's/../\\x&/g' | tr -d "\n")
echo -en $k | /config/custom_components/TechLife/mosquitto_pub -t $t -s -h 10.0.1.11 -u "mqttusernamehere" -P "mqttpasswordhere"
fi
else
echo "Usage: "
echo "$0 [MAC] on"
echo "$0 [MAC] off"
echo "$0 [MAC] dim [0-100]"
fi
Add the script to your configuration.yaml
in order to expose it to HA.
shell_command:
techlife: bash /config/custom_components/TechLife/TechLife.sh {{ mac }} {{ action }} {{ level }}
4. Connect the light bulb to your 2.4GHz Wifi network
There is no need to install the TechLife app to do this. The app is poorly designed and does not work most of the time. Instead, follow these simple steps.
-
Modify the following variables in the excellent Python script included below (taken from here)
-
ssid
: Your 2.4GHz Wifi network’s SSID -
password
: Your 2.4GHz Wifi network’s password -
bssid
: Your 2.4GHz Wifi network’s BSSID (MAC address) written as a byte array
-
-
Screw in the light bulb and turn it on
-
Connect to the Wifi network created by the light bulb
-
Execute the Python script
At this point, the bulb will reboot, connect to your Wifi network, and automatically start listening for MQTT commands.
Take note of the output that the script spits out; this is your light bulb’s MAC address, which you’ll need for the next steps.
TechLifePro_Setup.py
:
#!/usr/bin/env python
# 1. Modify the variables according to your setup: ssid, password, bssid, [email]
# 2. Connect the computer to AP-TechLife-xx-xx SSID
# 3. Run the script
import socket
# Variables to change
ssid = 'YOURSSID'
password = 'WIFIPASSWORD'
bssid = bytearray([0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa]) # Enter your WiFi router's WiFi interface MAC address in hex (eg. AA:AA:AA:AA:AA:AA)
email = '[email protected]' # not absolutely required
# The bulb's network details
TCP_IP = '192.168.66.1'
TCP_PORT = 8000
BUFFER_SIZE = 1024
# Initialize Payload
payload = bytearray(145)
payload[0x00] = 0xff
payload[0x69] = 0x01
# Add the SSID to the payload
ssid_start = 0x01
ssid_length = 0
for letter in ssid:
payload[(ssid_start + ssid_length)] = ord(letter)
ssid_length += 1
# Add the WiFi password to the payload
pass_start = 0x22
pass_length = 0
for letter in password:
payload[(pass_start + pass_length)] = ord(letter)
pass_length += 1
# Add the BSSID to the payload
bssid_start = 0x63
bssid_length = 0
for digit in bssid:
payload[(bssid_start + bssid_length)] = digit
bssid_length += 1
# Add the email to the payload
email_start = 0x6a
email_length = 0
for letter in email:
payload[(email_start + email_length)] = ord(letter)
email_length += 1
checksum = 0
j = 1
while j < 0x8f:
checksum = (payload[j] ^ checksum)
checksum = checksum & 0xff
j += 1
payload[0x8e] = 0xf0
payload[0x8f] = checksum & 0xff
payload[0x90] = 0xef
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(payload)
data = s.recv(BUFFER_SIZE)
s.close()
print ("received data:", data)
5. Configure the bulbs to talk to your MQTT server instead of the TechLife MQTT server
The TechLife Pro light bulbs are configured to listen to a specific MQTT topic on one of two specific external domains. We therefore need to instruct the light bulbs to listen to your server instead.
Using a Python 2.7 compiler (either on your computer, or using an online service such as this one), run the following script, replacing the values in the first two lines with the appropriate values in your case.
mqttServerIp = '10.0.1.11'
bulbMacAddress = 'aa:bb:cc:dd:ee:ff'
###############################################
def calcChecksum(stream):
checksum = 0
for i in range(1, 14):
checksum = checksum ^ stream[i]
stream[14] = checksum & 255
return bytearray(stream)
def changeIP (ipAddr, port):
Command = bytearray.fromhex("AF 00 00 00 00 00 00 f0 00 00 00 00 00 00 00 b0")
l = list(Command)
idx = 1
for ip in map(int,ipAddr.split('.')):
l[idx] = ip
idx = idx + 1
l[5] = port & 0xff
l[6] = port >> 8
return calcChecksum(l)
command = '\\x' + '\\x'.join(format(x, '02x') for x in changeIP(mqttServerIp,1883))
print 'echo -en "' + command + '" | mosquitto_pub -t "dev_sub_' + bulbMacAddress.lower() + '" -h "cloud.qh-tek.com" -s'
print 'echo -en "' + command + '" | mosquitto_pub -t "dev_sub_' + bulbMacAddress.lower() + '" -h "cloud.hq-tek.com" -s'
The result should be something like this:
echo -en "\xaf\x0a\x00\x01\x0b\x5b\x07\xf0\x00\x00\x00\x00\x00\x00\xac\xb0" | mosquitto_pub -t "dev_sub_aa:bb:cc:dd:ee:ff" -h "cloud.qh-tek.com" -s
echo -en "\xaf\x0a\x00\x01\x0b\x5b\x07\xf0\x00\x00\x00\x00\x00\x00\xac\xb0" | mosquitto_pub -t "dev_sub_aa:bb:cc:dd:ee:ff" -h "cloud.hq-tek.com" -s
Copy/paste these two lines on the command line and execute them; at least one of them should be successful. This tells the overseas MQTT server to instruct the bulb to use your local MQTT server from now on.
The bulb should flash once after a few seconds to confirm that it has received the command.
6. Configure HA
Create the following user in HA with the (terrible) username and password combination that is hardcoded into the light bulbs, which will enable the MQTT auth to go through seamlessly.
- Name:
TechLife MQTT
- Username:
testuser
- Password:
testpassword
Additionally, add the following to your configuration.yaml
.
Replace the MAC address with the one that was output by the script in step 4.
light:
- platform: template
lights:
bedroom:
friendly_name: "Light's friendly name"
turn_on:
service: shell_command.techlife
data:
action: "on"
mac: "aa:bb:cc:dd:ee:ff"
turn_off:
service: shell_command.techlife
data:
action: "off"
mac: "aa:bb:cc:dd:ee:ff"
set_level:
service: shell_command.techlife
data_template:
action: "dim"
level: "{{ (brightness / 255 * 100) | round }}"
mac: "aa:bb:cc:dd:ee:ff"
7. Restart HA
Restart HA and try out your newly created light entity! Everything should just work at this point.
Conclusion
If ever you want to add additional light bulbs, simply repeat steps 4 to 7.
As I mentioned earlier, this tutorial is a WIP, so let me know if you encounter any hiccups or if you have any questions. So far I have 4 TechLife Pro light bulbs, all working smoothly.
Enjoy!