A few weeks ago, we purchased a tp-link LB130 smart bulb to use with the Home Assistant software we had been trying on the Raspberry Pi. The support for the bulb in the Home Assistant software was limited and so Andrew started to decode the data using Wireshark between the bulb and the Android and IOS apps to try to find the commands sent to and from the Wi-Fi bulb so he would write his own Python class to control the bulb on our home network.
Below is a list of all the commands which Andrew found on the bulb to control the settings and also a python class to control the bulb. The software for this project can be found on my GitHub repository.
TP-Link A19-LB130 Wifi Bulb Python Library
The tplight.py python library contains a class LB130 and methods for controlling the TP-Link A19-LB130 Wifi bulb.
A demo file demo.py is included which shows how to use the class.
Create an instance of the LB130 class with the IP address for the bulb
light = LB130("10.0.0.130")
Methods
status()
Get the connection status from the bulb. Returns a JSON formatted string with all of the available parameters.
light_details()
Get the light details from the bulb including min and max voltage, wattage and colour rendering index. Returns a JSON formatted string with all of the available parameters.
on()
Set the bulbs state to on.
off()
Set the bulbs state to off.
reboot()
Reboot the bulb.
alias(name)
Get or set the alias name for the bulb.
time(date)
Get or set the date and time on the bulb. Takes and returns date as a DateTime object.
timezone(timezone)
Get or set the timezone for the bulb. A value between 0 and 109. See timezones.md or the list below for a list of available timezones.
transition_period(period)
Get or set the transition period for any changes made to the colour or brightness of the bulb. Value in milliseconds between 0 and 10000.
hue(hue)
Get or set the bulb's hue. Value between 0 and 360.
saturation(saturation)
Get or set the colour saturation for the bulb. Value between 0 and 100.
brightness(brightness)
Get or set the brightness. Value between 0 and 100.
temperature(temperature)
Get or set the colour temperature. Value between 0 and 7000.
TP-Link A19-LB130 Wifi Bulb Command Protocol
Commands are sent to the light bulb IP address, Port 9999 using a JSON formatted string. The string is encrypted by XORing each byte with the previous plain text byte.
tplight.py contains the encryption and decryption routines.
smartlife.iot.common.system
reboot
reboot the device
Command:
{"smartlife.iot.common.system":{"reboot":{"delay":1}}}
Returns:
{"smartlife.iot.common.system":{"reboot":{"err_code":0}}}
set_dev_alias
Set the name or alias for the device
Command:
{"smartlife.iot.common.system":{"set_dev_alias":{"alias":"Kitchen Light"}}}
Returns:
{"smartlife.iot.common.system":{"set_dev_alias":{"err_code":0}}}
system
get_info
Gets the system information for the light bulb.
Command:
{"system":{"get_sysinfo":""}}
Returns:
{"system":{"get_sysinfo":{"sw_ver":"1.5.5 Build 170623 Rel.090105","hw_ver":"1.0","model":"LB130(EU)","description":"Smart Wi-Fi LED Bulb with Color Changing","alias":"Aaaa","mic_type":"IOT.SMARTBULB","dev_state":"normal","mic_mac":"50C7BF5E9C8F","deviceId":"80123265DD825560B3CAA1C3B1B12956187286B1","oemId":"D5C424D3C480911C980ECDD56C27988F","hwId":"111E35908497A05512E259BB76801E10","is_factory":false,"disco_ver":"1.0","ctrl_protocols":{"name":"Linkie","version":"1.0"},"light_state":{"on_off":1,"mode":"normal","hue":30,"saturation":100,"color_temp":0,"brightness":7},"is_dimmable":1,"is_color":1,"is_variable_color_temp":1,"preferred_state":[{"index":0,"hue":0,"saturation":0,"color_temp":2700,"brightness":50},{"index":1,"hue":0,"saturation":75,"color_temp":0,"brightness":100},{"index":2,"hue":120,"saturation":75,"color_temp":0,"brightness":100},{"index":3,"hue":240,"saturation":75,"color_temp":0,"brightness":100}],"rssi":-57,"active_mode":"none","heapsize":316848,"err_code":0}}}
smartlife.iot.common.schedule
The scheduler allows you to set events which will run at a scheduled date and time.
get_rules
Get a list of the rules present on the device
Command:
{"smartlife.iot.common.schedule":{"get_rules":""}}
Returns:
{"smartlife.iot.common.schedule":{"get_rules":{"rule_list":[{"id":"CF652E0D1D57B0BC12D978822F4456CA","name":"name","enable":1,"wday":[1,0,1,0,1,0,0],"stime_opt":0,"smin":780,"sact":2,"s_light":{"on_off":1,"mode":"customize_preset","hue":129,"saturation":21,"color_temp":0,"brightness":17},"etime_opt":-1,"emin":0,"eact":-1,"repeat":1}],"enable":1,"err_code":0}}}
add_rule
Add a new rule to the scheduler.
Command:
{"smartlife.iot.common.schedule":{"add_rule":{"name":"name","repeat":1,"wday":[1,0,1,0,1,0,0],"stime_opt":0,"eact":-1,"smin":780,"s_light":{"saturation":21,"hue":129,"brightness":17,"color_temp":0,"mode":"customize_preset","on_off":1},"enable":1,"day":24,"year":2017,"month":8,"sact":2,"emin":-1,"etime_opt":-1},"set_overall_enable":{"enable":1}}}
Returns:
{"smartlife.iot.common.schedule":{"add_rule":{"id":"CF652E0D1D57B0BC12D978822F4456CA","err_code":0},"set_overall_enable":{"err_code":0}}}
delete_rule
Delete a rule from the scheduler
Command:
{"smartlife.iot.common.schedule":{"delete_rule":{"id":"CF652E0D1D57B0BC12D978822F4456CA"}}}
Returns
{"smartlife.iot.common.schedule":{"delete_rule":{"err_code":0}}}
get_next_action
smartlife.iot.common.timesetting
get_time
Gets the date and time from the device
Command:
{"smartlife.iot.common.timesetting":{"get_time":{}}}
Returns:
{"smartlife.iot.common.timesetting":{"get_time":{"year":2017,"month":8,"mday":24,"hour":20,"min":10,"sec":19,"err_code":0}}}
set_time
Sets the date and time for the device
Command:
{"smartlife.iot.common.timesetting":{"set_time":{"year":2017,"month":8,"mday":24,"hour":20,"min":10,"sec":19}}}
Returns:
{"smartlife.iot.common.timesetting":{"set_time":{"err_code":0}}}
get_timezone
Gets the timezone code for the device
Command:
{"smartlife.iot.common.timesetting":{"get_timezone":{}}}
Returns:
{"smartlife.iot.common.timesetting":{"get_timezone":{"index":39,"err_code":0}}}
set_timezone
Set the timezone code for the device
Command:
{"smartlife.iot.common.timesetting":{"set_timezone":{"index":39,"hour":18,"year":2017,"min":26,"month":8,"sec":42,"mday":25}}}
Returns:
{"smartlife.iot.common.timesetting":{"set_timezone":{"err_code":0}}}
smartlife.iot.common.emeter
get_daystat
Get the daily power usage in wh for the specified month
Command:
{"smartlife.iot.common.emeter":{"get_daystat":{"year":2017,"month":8}}}
Returns:
{"smartlife.iot.common.emeter":{"get_daystat":{"day_list":[{"year":2017,"month":8,"day":2,"energy_wh":0},{"year":2017,"month":8,"day":3,"energy_wh":0},{"year":2017,"month":8,"day":9,"energy_wh":2},{"year":2017,"month":8,"day":12,"energy_wh":3},{"year":2017,"month":8,"day":14,"energy_wh":0},{"year":2017,"month":8,"day":15,"energy_wh":3},{"year":2017,"month":8,"day":16,"energy_wh":3},{"year":2017,"month":8,"day":17,"energy_wh":4},{"year":2017,"month":8,"day":23,"energy_wh":0},{"year":2017,"month":8,"day":24,"energy_wh":14},{"year":2017,"month":8,"day":25,"energy_wh":0},{"year":2017,"month":8,"day":26,"energy_wh":0}],"err_code":0}}}
smartlife.iot.smartbulb.lightingservice
get_light_state
Get the status and values for the hue, saturation, brightness and colour temperature
Command:
{"smartlife.iot.smartbulb.lightingservice":{"get_light_state":""}}
Returns:
{"smartlife.iot.smartbulb.lightingservice":{"get_light_state":{"on_off":1,"mode":"normal","hue":30,"saturation":100,"color_temp":0,"brightness":7,"err_code":0}}}
transition_light_state
Set the status and values for the hue, saturation, brightness and colour temperature. The transition period for changing to the new state can be defined using the transition_period variable.
Command:
{"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"ignore_default":1,"transition_period":150,"mode":"normal","hue":120,"on_off":1,"saturation":65,"color_temp":0,"brightness":10}}}
Returns:
{"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"on_off":1,"mode":"normal","hue":120,"saturation":65,"color_temp":0,"brightness":10,"err_code":0}}}
get_light_details
Get the system details for the device such as min and max voltages, lamp beam angle and maximum lumens.
Command:
{"smartlife.iot.smartbulb.lightingservice":{"get_light_details":""}}
Returns:
{"smartlife.iot.smartbulb.lightingservice":{"get_light_details":{"lamp_beam_angle":150,"min_voltage":110,"max_voltage":120,"wattage":10,"incandescent_equivalent":60,"max_lumens":800,"color_rendering_index":80,"err_code":0}}}
get_default_behavior
Get the default behavior for the device when it powers on.
Command:
{"smartlife.iot.smartbulb.lightingservice":{"get_default_behavior":""}}
Returns:
{"smartlife.iot.smartbulb.lightingservice":{"get_default_behavior":{"soft_on":{"mode":"last_status"},"hard_on":{"mode":"last_status"},"err_code":0}}}
Wifi Setup
get_scaninfo
Scan for nearby Access Points
Command:
{"netif":{"get_scaninfo":{"refresh":1}}}
set_stainfo
Connect to an access point with a specified SSID, password and key type.
Command:
{"netif":{"set_stainfo":{"ssid":"WiFi","password":"123","key_type":3}}}
Time Zone Settings
The TP-Link LB130 uses a code between 1 and 103 for setting the timezone of the device. The codes below can be used with the set_timezone command on the protocols page.
- 0: UTC-12:00 - International Date Line West
- 1: UTC-11:00 - Coordinated Universal Time
- 2: UTC-10:00 - Hawaii
- 3: UTC-09:00 - Alaska
- 4: UTC-08:00 - Baji California
- 5: UTC-08:00 - Pacific Standard Time
- 6: UTC-08:00 - Pacific Daylight Time
- 7: UTC-07:00 - Arizona
- 8: UTC-07:00 - Chihuahua, La Paz, Mazatlan
- 9: UTC-07:00 - Mountain Standard Time
- 10: UTC-07:00 - Mountain Daylight Time
- 11: UTC-06:00 - Central America
- 12: UTC-06:00 - Central Standard Time
- 13: UTC-06:00 - Central Daylight Time
- 14: UTC-06:00 - Guadalajara, Mexico City
- 15: UTC-06:00 - Saskatchewan
- 16: UTC-05:00 - Bogota, Lima, Quito
- 17: UTC-05:00 - Eastern Standard Time
- 18: UTC-05:00 - Eastern Daylight Time
- 19: UTC-05:00 - Indiana (East)
- 20: UTC-04:30 - Caracas
- 21: UTC-04:00 - Asunicion
- 22: UTC-04:00 - Atlantic Standard Time
- 23: UTC-04:00 - Atlantic Daylight Time
- 24: UTC-04:00 - Cuiaba
- 25: UTC-04:00 - Georgetown
- 26: UTC-04:00 - Santiago
- 27: UTC-03:30 - Newfoundland
- 28: UTC-03:00 - Brasilia
- 29: UTC-03:00 - Buenos Aires
- 30: UTC-03:00 - Cayenne, Fortaleza
- 31: UTC-03:00 - Greenland
- 32: UTC-03:00 - Montevideo
- 33: UTC-03:00 - Salvador
- 34: UTC-02:00 - Coordindated Universal Time
- 35: UTC-01:00 - Azores
- 36: UTC-01:00 - Cabo Verde Is.
- 37: UTC - Casablanca
- 38: UTC - Coordindated Universal Time
- 39: UTC - Dublin, Edinburgh, Lisbon, London
- 40: UTC - Monrovia, Reykjavik
- 41: UTC+01:00 - Amsterdam, Berlin, Bern
- 42: UTC+01:00 - Belgrade, Bratislava
- 43: UTC+01:00 - Brussels, Copenhagen
- 44: UTC+01:00 - Sarajevo, Skopje, Warsaw
- 45: UTC+01:00 - West Central Africa
- 46: UTC+01:00 - Windkoek
- 47: UTC+02:00 - Amman
- 48: UTC+02:00 - Athens, Bucharest
- 49: UTC+02:00 - Beirut
- 50: UTC+02:00 - Cairo
- 51: UTC+02:00 - Damascus
- 52: UTC+02:00 - E. Europe
- 53: UTC+02:00 - Harare, Pretoria
- 54: UTC+02:00 - Helsinki, Kyiv, Riga, Sofia
- 55: UTC+02:00 - Istanbul
- 56: UTC+02:00 - Jerusalem
- 57: UTC+02:00 - Kalinigrad (RTZ 1)
- 58: UTC+02:00 - Tripoli
- 59: UTC+02:00 - Baghdad
- 60: UTC+03:00 - Kuwait, Riyadh
- 61: UTC+03:00 - Minsk
- 62: UTC+03:00 - Moscow, St. Petersburg
- 63: UTC+03:00 - Nairobi
- 64: UTC+03:30 - Tehran
- 65: UTC+04:00 - Abu Dhabi, Muscat
- 66: UTC+04:00 - Baku
- 67: UTC+04:00 - Izhevsk, Samara (RTZ 3)
- 68: UTC+04:00 - Port Louis
- 69: UTC+04:00 - Tbilisi
- 70: UTC+04:00 - Yerevan
- 71: UTC+04:30 - Kabal
- 72: UTC+05:00 - Ashgabat, Tashkent
- 73: UTC+05:00 - Ekaterinburg (RTZ 4)
- 74: UTC+05:00 - Islamabad, Karachi
- 75: UTC+05:30 - Chennai, Kolkata, Mumbai
- 76: UTC+05:30 - Sri Jayawardenepura
- 77: UTC+05:45 - Kathmandu
- 78: UTC+06:00 - Astana
- 79: UTC+06:00 - Dhaka
- 80: UTC+06:00 - Novosibirsk (RTZ 5)
- 81: UTC+06:30 - Yangon (Rangoon)
- 82: UTC+07:00 - Bankok, Hanoi, Jakarta
- 83: UTC+07:00 - Kransnoyarsk (RTZ 6)
- 84: UTC+08:00 - Beijing, Chongqing, Hong Kong
- 85: UTC+08:00 - Irkutsk (RTZ 7)
- 86: UTC+08:00 - Kuala Lumpur, Singapore
- 87: UTC+08:00 - Perth
- 88: UTC+08:00 - Taipei
- 89: UTC+08:00 - Ulaanbaatar
- 90: UTC+09:00 - Osaka, Sapporo, Tokyo
- 91: UTC+09:00 - Seoul
- 92: UTC+09:00 - Yakutsk (RTZ 8)
- 93: UTC+09:30 - Adelaide
- 94: UTC+09:30 - Darwin
- 95: UTC+10:00 - Brisbane
- 96: UTC+10:00 - Canberra, Melbourne, Sydney
- 97: UTC+10:00 - Guam, Port Moresby
- 98: UTC+10:00 - Hobart
- 99: UTC+10:00 - Magadan
- 100: UTC+10:00 - Vladivostok, Magadan (RTZ 9)
- 101: UTC+11:00 - Chokurdakh (RTZ 10)
- 102: UTC+11:00 - Solomon Is., New Caledonia
- 103: UTC+12:00 - Anadyr, Petropavlovsk
- 104: UTC+12:00 - Auckland, Wellington
- 105: UTC+12:00 - Corrdinated Universal Time
- 106: UTC+12:00 - Fiji
- 107: UTC+13:00 - Nuku’alofa
- 108: UTC+13:00 - Samoa
- 109: UTC+14:00 - Kiritimati Island
The software for this project can be found on my GitHub repository.
Kevin
What annoys me about this light is it communicates with AWS hosts. It's fairly chatty. I've blocked it at my firewall. f them.
Jeff
Thank You. I was using another library for the Wifi switches, which does not have support for the bulbs. I started to reverse engineer the commands and decided to search for "smartlife.iot.common.schedule" which brought up your page, with some of the work already done.
Brian
Jeff, I am sorry but I don't have any of the WiFi switches to test with the code.
J.W
Compliments for a job well done.
I had already converted the HS110 to FreeBasic with the aim that it was NOT to be connected to the Internet.It looked like I was going to have to connect to Initialize the KL130 with Kasa until I found your post. In the end the set_stainfo commands were identical, and I can now complete all the other commands.
Once again many thanks
Zayle
Hi I'm trying to set wifi to bulb using set_stainfo
It was working before but not working over the night with socket exception [SocketException (0x274d): No connection could be made because the target machine actively refused it 192.168.0.100:9999]
Dave
if anyone is noticing it failing to connect to the blub when it is off, its due to the returned json object changing shape depending if the bulb is off or on.
I was seeing it fail to get the 'hue' value when the blub was off, it was due to the hue, color temp, mode and saturation being in a nested key called 'dft_on_state' if the blub in off.
I did a quick and dirty fix in the __init__ and it fixed my issue:
col1 = 'system'
col2 = 'get_sysinfo'
col3 = 'light_state'
col4 = 'dft_on_state'
if self.__on_off == 1: # blub is on
self.__hue = int(data[col1][col2][col3]['hue'])
self.__saturation = int(data[col1][col2][col3]['saturation'])
self.__brightness = int(data[col1][col2][col3]['brightness'])
self.__color_temp = int(data[col1][col2][col3]['color_temp'])
else: # bulb is off
self.__hue = int(data[col1][col2][col3][col4]['hue'])
self.__saturation = int(data[col1][col2][col3][col4]['saturation'])
self.__brightness = int(data[col1][col2][col3][col4]['brightness'])
self.__color_temp = int(data[col1][col2][col3][col4]['color_temp'])