Closed konsumer closed 7 years ago
Also, possibly unrelated, this code doesn't make the lights flash (it doesn't do anything):
const Hs100Api = require('hs100-api')
const client = new Hs100Api.Client()
const plug1 = client.getPlug({host: '10.0.0.200'})
const plug2 = client.getPlug({host: '10.0.0.81'})
let toggle = true
setInterval(() => {
toggle = !toggle
plug1.setPowerState(toggle)
plug2.setPowerState(!toggle)
}, 3000)
I also tried this:
const Hs100Api = require('hs100-api')
const client = new Hs100Api.Client()
client.startDiscovery()
.on('plug-online', plug => {
console.log('on', plug.name)
})
.on('plug-offline', plug => {
console.log('off', plug.name)
})
.on('plug-new', plug => {
console.log('new', plug.name)
})
And I got this, after running it for a few minutes:
new Front Lamp
on Front Lamp
on Front Lamp
on Front Lamp
on Front Lamp
on Front Lamp
Front Lamp
seems to be the only one it detects.
Happy to do anything else that helps troubleshoot.
If it's helpful, the Firmware Version
in Kasa app is 1.0.9
. Maybe I need to do some wiresharking to reverse it?
I must be doing something wrong with my wiresharking. I filter eth.src == xx:xx:xx:xx:xx:xx
(where xx:xx:xx:xx:xx:xx
is MAC in Kasa app) and trigger power in app and it doesn't show anything. Any suggestions would be awesome.
Ok, so I setup a wifi AP on a raspberry pi, and captured just traffic for the mac address of the bulb with tcpdump. I analyzed it with this code:
const pcapp = require('pcap-parser')
const decrypt = require('hs100-api/lib/utils').decrypt
const parser = pcapp.parse('front-lamp.pcap')
parser.on('packet', packet => {
console.log(decrypt(packet.data).toString())
})
I am getting lots of gibberish mixed with JSON snippets, like this:
�.�;�x�l!EE,.,.@F��a̴nH(��!G)Y����~r�;�e�
{�x�l!�.�;EE(t
@@F�(�nôa��(����G)Vh@�Kr�
@@F����nôa��(����G)VhH��ji�"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"on_off":0,"transition_period":0}}}
�.�;�x�l!EE(*-/@F��̴nH(��!G)V����N@�a�
�̴nH(��!G)V���F�@ ��+
�.�;�x�l!EE��31@F�N�a̴nH(��!G)V���F�H ���j"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"on_off":0,"dft_on_state":{"mode":"normal","hue":0,"saturation":0,"color_temp":2700,"brightness":90},"err_code":0}}}
{�x�l!�.�;EE(t@@F�.�nôa��(���F�G)��@�L(�
{�x�l!�.�;EE(t@@F�-�nôa��(���F�G)��A�L)�
�.�;�x�l!EE(*02@F��a̴nH(��!G)�P��F�@�5�
�.�;�x�l!EE(*13@F��a̴nH(��!G)�P��A�@ ��l
�.�;�x�l!EE(*64@F��a̴nH(��!G)�P��A�A�7�
{�x�l!�.�;EE(��|@@F
�8�nôa��(���A�G)��@E',y'
{�x�l!�.�;EE<��'@@FG��nôa��(��*�����rr���
�^�
�.�;�x�l!EE,.75@F��a̴nH(��9J�e�*��r��S]�
{�x�l!�.�;EE(��(@@FG)Ĵnôa��(��*��J��@�ԕ�
{�x�l!�.�;EE�
�)@@FF�V�nôa��(��*��J��H��^i�"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"on_off":1,"transition_period":0}}}
�.�;�x�l!EE(*46@F��a̴nH(��9J�d�*��@��
�.�;�x�l!EE(*57@F��a̴nH(��9J�d�5F@ 3>#
�.�;�x�l!EE��:8@F�@�a̴nH(��9J�d�5FH >9�y"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"on_off":1,"mode":"normal","hue":0,"saturation":0,"color_temp":2700,"brightness":90,"err_code":0}}}
{�x�l!�.�;EE(��*@@FG'ʴnôa��(��5J<2@�Վ�
{�x�l!�.�;EE(��+@@FG$ɴnôa��(��5J<2A�Չ�
�.�;�x�l!EE(*;9@F��a̴nH(��9J<��5F@��
�.�;�x�l!EE(*8:@F��a̴nH(��9J<��5G@ 2iu
�.�;�x�l!EE(*9;@F��a̴nH(��9J<��5GA��
{�x�l!�.�;EE(��:@@F
Z��nôa��(��5J=3@E�V�
Should I be analyzing it differently?
I don't have any TPLink lightbulbs to test. If you can figure out the API I might be able to add support, but hard for me to do anything without a lightbulb of my own.
I hear that. It'd be cool if your lib could auto-detect API version and use the right decrypt function. I will keep playing with it and see if I can reverse it's API. Do you have any suggestions for getting started?
I'm happy to send you pcaps of anything, or anything else that might help.
This wireshark dissector actually worked out all the lower-level protocol stuff, and I can now get nice JSON output for all the data sent to/from the Kasa app. I'll have a look this weekend, and see if I can reverse the protocol a bit.
Konsumer, I am also interested in the LB120 bulb. I have one of these as well as HS200 switches and an HS100 plug. I am pretty much convinced that the ports are the same; however, the commands vary. I ran an experiment with one of each device type. All five of my devices were discover; however, only the HS100 and HS200 turned on. I borrowed heavily from what you did above for this (thanks).
const Hs100Api = require('hs100-api') const client = new Hs100Api.Client()
// Define the three test devices. Use the HS200 and HS100 as controls and the LB120 as the device under test. const LB120 = client.getPlug({host: '192.168.1.131'}) // Bedroom Light const HS200 = client.getPlug({host: '192.168.1.133'}) // Den Fan const HS100 = client.getPlug({host: '192.168.1.135'}) // Den Fan
// Verify that I discover the all my TP Link Devices client.startDiscovery().on('plug-new', p => console.log(p.name))
HS200.setPowerState(true) // Worked HS100.setPowerState(true) // Worked LB120.setPowerState(true) // Did not work
Dave G
@DaveGut I ended up making this which is specialized to the lightbulb (but should work fine with other JSON protocols, once they are worked out) and includes an improved wireshark dissector. Here are some instructions for using it. I'd be happy to add support for more devices/commands if you want to send me a pcap or just JSON dumps that are being sent.
Thanks. I will look at it! First look is a lot of good work.
Konsumer, I have been experimenting. One experiment was getting a system status using the sysinfo query. I finally fully parsed the basic command with the below being the result. Essentially, I am able to query most of the status attributes and display them individually. If you are interested, I can post the code and give you a link (I know this is way below your level of expertise; but, I am learning, Not bad for a 68 yo)
Cool! Yeah, I'd love to see the code.
Below is the code. I will someday get into github (just starting out). Sorry for the inconvenience. START HERE // Testing of the getSysInfo command for the LB1xx light bulb
/* Notes This script uses the upreviously developed, unmodified HS100 API. It was completed as an exercise to fully understand how the system is controlled.
Issue: The program sometimes fails when the light is OFF. Works when ON and right after turning off. /*
const Hs100Api = require('hs100-api') const client = new Hs100Api.Client()
// Define the bulb, using the HS100 API const BRLight = client.getPlug({host: '192.168.0.131'})
// Get the System Information and parsing into Attributes var j = Promise.resolve(BRLight.getSysInfo()) j.then(function(data){ var sysinfo = (data); sw_ver = sysinfo.sw_ver; hw_ver = sysinfo.hw_ver; model = sysinfo.model; description = sysinfo.description; //Description of bulb alias = sysinfo.alias; // local name for bulb mic_type = sysinfo.mic_type dev_state = sysinfo.dev_state mic_mac = sysinfo.mic_mac //MAC of bulb devId = sysinfo.devId oemId = sysinfo.oemId hwId = sysinfo.hwId disco_ver = sysinfo.disco_ver prot_name = sysinfo.ctrl_protocols.name prot_version = sysinfo.ctrl_protocols.version on_off = sysinfo.light_state.on_off mode = sysinfo.light_state.mode brightness = sysinfo.light_state.brightness color_temp = sysinfo.light_state.color_temp hue = sysinfo.light_state.hue saturation = sysinfo.light_state.saturation
// Display the full set of attributes collected onto the console console.log(" LB1XX Bulb Information ") console.log(" Alias: " + alias) console.log(" Model: " + model) console.log(" Description: " + description) console.log(" Device Type: " + mic_type) console.log(" Device State: " + dev_state) console.log("Device MAC Adress: " + mic_mac) console.log(" SW Version: " + sw_ver) console.log(" HW Version: " + hw_ver) console.log(" ") console.log(" Currrent Bulb State ") console.log(" Light On/off: " + on_off) console.log(" Bulb Mode: " + mode) console.log(" Bulb Brightness: " + brightness) console.log("Color_Temperature: " + color_temp) console.log(" Color Hue: "+ hue) console.log(" Color Saturation: " + saturation) console.log(" ") console.log(" LB1XX Bulb Other Information ") // A repository for additional attributes as I decide to capture them console.log(" Device ID: " + devId) console.log(" OEM ID: " + oemId) console.log(" HW ID: " + hwId) console.log(" Disco Version: " + disco_ver) console.log("Control Protocol: " + prot_name +" Ver "+ prot_version) })
Cool, I put it up here for readability. You can fork it and edit/save, if you wanna make changes. Looks good.
I reimplemented it using my library, ES6 template strings & object destructuring for readability. I noticed a few of my info object-keys are different than yours for some reason, specifically:
deviceId: devId
light_state: {on_off, dft_on_state: {mode, brightness, color_temp, hue, saturation}}
When I run it, I get the same sort of output you get:
LB1XX Bulb Information
Alias: Front Lamp
Model: LB120(US)
Description: Smart Wi-Fi LED Bulb with Tunable White Light
Device Type: IOT.SMARTBULB
Device State: normal
Device MAC Adress: --REMOVED---
SW Version: 1.0.9 Build 160524 Rel.100333
HW Version: 1.0
Currrent Bulb State
Light On/off: 0
Bulb Mode: normal
Bulb Brightness: 100
Color_Temperature: 2700
Color Hue: 0
Color Saturation: 0
LB1XX Bulb Other Information
Device ID: --REMOVED---
OEM ID: --REMOVED---
HW ID: --REMOVED---
Disco Version: 1.0
Control Protocol: Linkie Ver 1.0
And talking to you reminded me to implement an info()
function, so thanks!
I have modified the HS100.API (new name LB1nn) and created the device handler for SmartThings. It works. Can send as zip file if you wish.
Konsumer. I have now found and tested 17 commands on the API. Including energy monitor functions. I know there are others. My data is now at: https://github.com/DaveGut/TP-Link-Bulbs
@DaveGut what happened to that repo?
I have reloaded the program for any interested in the API aspects. The SmartThings integration is depreciated; however, i believe it still works. My new SmartThings integration is at https://github.com/DaveGut/TP-Link-to-SmartThings-Integration
Why: a. single Node.js file eliminating calls to the api files (and error potentials) b. more informative user interface with indications when command fail, or bulbs disconnect. c. has hooks to the bridge integration (SmartThing-PC-Bridge) which provided mechanism to reboot the bridge from SmartThings.
FYI - I am working on a ST Service Manager and associated Device Handlers that will discover the PC Bridge and then the TP-Link devices and install them automatically (after the user installs the service manager and related device handlers). I should also follow the bulbs so that static ports will not the necessary. Probably a couple of weeks until I am happy. Then back to the API with things I have learned.
If anyone in this thread is interested: I created a TPLink device simulator so I could have automated testing of my code. It also allowed me to improve bulb support for hs100-api as I can test bulbs even though I don't own any.
I have 2 LB120(US) lightbulbs that work correctly in the Kasa app. When I run this demo code, it only finds 1 of them: