TP-Link HS110

For issues with communication ports, protocols, etc.
Post Reply
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: TP-Link HS110

Post by badidea »

Dinosaur wrote:The US version has "longitude" and "latitude"
That is annoying.
Dinosaur wrote:The AU version has "next_action" which reports FAIL_IS_OBJECT
The data is ,"next_action":{"type":-1},
Yes, my parser cannot handle nested objects at the moment.
Dinosaur wrote:Have you completely updated the snc.bi ?
No, just some fixes. I had a 75.3 second connection timeout at start if the Wifi was gone (or device off).
Now I can set this timeout. The extra code required for this is however a bit lengthy (and ugly).
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

I have been looking into the response time differences between the US & AU versions.
Using this DataTxRx routine I have marked the times in it.

Code: Select all

Sub DataTxRx
  If Control.PrintFlag = 3 Then Print "DataTxRx"
	Times.TxRxTime = (Timer - Times.CalTime) * 1000
	IP   = NetDevice(Control.Device).DeviceIP
	Port = NetDevice(Control.Device).ServerPort
	Tx   = NetDevice(Control.Device).TxData
	'==========================================
    var client = NetworkClient(IP,Port)
    var connection = client.GetConnection()
    while connection->CanPut() <> 1
        sleep 10
    wend
    '12 mSec
    connection->PutData(StrPtr(Tx),Len(Tx))
    while connection->CanGet() <> 1
      sleep 10
    wend
    '184 mSec
    var nBytes    = connection->GetData(pBuffer)
    '2186 mSec
    var LastChar  =instr(*pBuffer,HeaderEnd)-1
    var Header    =left(*pBuffer,LastChar)
    var DataStart =LastChar+4
    dim as ubyte ptr FileBuffer=@pBuffer[DataStart]
    Rx = ""
    For Cnt = 1 to nBytes
        Rx += Chr(*(FileBuffer + Cnt))
    Next
	'==========================================
    NetDevice(Control.Device).RxData = Rx
    Times.Elapsed = ((Timer - Times.CalTime) * 1000) - Times.TxRxTime
    '2264 mSec The US version takes 110 msec for complete routine.
End Sub
The " connection->GetData(pBuffer)" is obviously the culprit, but I don't understand why.
The Plug actually switches within a couple of hundred mSec.
I am reluctant to believe that using a 240 vac 50 hz device here in the US is the cause, particularly as all the
commands operate correctly. I guess after the end of the year I will find out.
I am retuning to oz for good. (well except for 1 or 2 , 3 week stints)

Regards
EDIT:Changed the value to 1 from 0 in the Function statement in snc.bi.

Code: Select all

byval noWait as integer = 1
Have tested thoroughly and see no detrimental affect.
It does take the total time below 100 mSec.
I guess the delay was meant to catch errors from larger than expected data chunk.
I will leave snc.bi as is for other applications.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: TP-Link HS110

Post by D.J.Peters »

If you receive data over TCP often you don't know it's size (including any header stuff).

On hardware level some devices works faster with large data chunks of 32K blocks others with 8K !

With other words the device knows if any data but not it's size !
declare function CanGet() as integer

Other point are how the device should know was it the last chunk of data or not ?

You can give it a hint if you know the size you would accept.

For this reason you can use the optional argument maxSize.
declare function GetData(byref pData as any ptr, byval maxSize as integer=0) as integer

For example If you would accept 1K of data you can set maxSize=1024 and the default chunk size of 8K are ignored in this case.

Joshy
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: TP-Link HS110

Post by badidea »

D.J.Peters wrote:...
For example If you would accept 1K of data you can set maxSize=1024 and the default chunk size of 8K are ignored in this case.
...
This device sends a response typically in the range of ~10 to ~1000 bytes. If a lot of timers are set in the device, the 'get_sysinfo' reply can exceed a 1000 bytes, but not very likely.

Just tested: The maxSize parameter does speed up the GetData() call, but only is maxSize is smaller then the data reply size. So think that 'maxSize' should be called 'minSize'. This call:

Code: Select all

dim as integer nBytes = pConnection->GetData(pBuffer, 1) 'expect at least 1 byte
Returns (after a 'putData('get_sysinfo'):

Code: Select all

Received bytes = 610
{"system":{"get_sysinfo":{"sw_ver":"1.5.4 Build 180815 Rel.121440","hw_ver":"2.0","type":"IOT.SMARTPLUGSWITCH","model":"HS110(EU)","mac":"68:FF:7B:80:40:DE","dev_name":"Smart Wi-Fi Plug With Energy Monitoring","alias":"StupidPlug","relay_state":1,"on_time":1053,"active_mode":"none","feature":"TIM:ENE","updating":0,"icon_hash":"","rssi":33,"led_off":0,"longitude_i":0,"latitude_i":0,"hwId":"044A516EE63C875F9458DA25C2CCC5A0","fwId":"00000000000000000000000000000000","deviceId":"80061065B3D2BD6C2803CB3B3C8DB09C1B62B107","oemId":"1998A14DAA86E4E001FD7CAF42868B5E","next_action":{"type":-1},"err_code":0}}}
Within 200 ms (from connection setup to end (buffer deallocation).

This call:

Code: Select all

dim as integer nBytes = pConnection->GetData(pBuffer, 1024) 'expect at least 1024 bytes
Gives the same result, but takes 2.15 second.
Leaving maxSize out (or setting it to 0) also results in ~2 seconds.

So my noWait parameter addition is not needed, but I think that 'maxSize' should be called 'minSize'. Post in SNC topic adjusted accordingly.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

Yet, the US version will go as low as 30 mSec to do a Tx/Rx which is still way faster then the AU version where the
minimum I achieved with it is 80 mSec.
I did change the sleep times.

Code: Select all

    while connection->CanPut() <> 1
        sleep 1
    wend
    connection->PutData(StrPtr(Tx),Len(Tx))
    while connection->CanGet() <> 1
      sleep 10
    wend
The CanPut only takes about 2 mSec so having a 10 mSec sleep is pointless,
whereas the PutData takes much longer.

Anyway, I am glad we have identified the cause of the long delay.
The times I am getting now are not a problem.

Regards
EDIT: Before I start on the GUI, the next step is the Multi-colour Light bulb.
https://www.amazon.com/gp/product/B07FZ ... UTF8&psc=1
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: TP-Link HS110

Post by badidea »

Dinosaur wrote:EDIT: Before I start on the GUI, the next step is the Multi-colour Light bulb.
https://www.amazon.com/gp/product/B07FZ ... UTF8&psc=1
Does it use the same protocol? And do you know the commands to send?

I changed the getJsonValue() function to allow partial keywords.
E.g. 'longitude' instead of 'longitude_i'
But also 'sw' is allowed instead of 'sw_ver'
I called this version getJsonValuePartial() and the previous getJsonValueStrict()
But with this version you can get unexpected results quickly: If you look for 'uild', you get '2.0'.

Code: Select all

function getJsonValuePartial(jsonStr as string, key_ as string) as string
	dim as string key = key_
	dim as integer keyPos = instr(jsonStr, key)
	if keyPos = 0 then return "FAIL_NO_KEY" 'key not found
	dim as integer jsonStrLen = len(jsonStr)
	dim as integer cursor = keyPos + len(key) - 1
	dim as integer startPos, endPos '0 is first char
	'look for colon
	while 1
		if cursor >= jsonStrLen then return "FAIL_NO_COLON"
		if jsonStr[cursor] = asc(":") then exit while
		cursor += 1
	wend
	cursor += 1
	'skip spaces again
	while 1
		if cursor >= jsonStrLen then return "FAIL_END_SPC2"
		if jsonStr[cursor] <> asc(" ")  then exit while
		cursor += 1
	wend
	'check if char: [, {, ", number
	select case jsonStr[cursor]
		case asc("[")
			return "FAIL_IS_ARRAY"
		case asc("{")
			return "FAIL_IS_OBJECT"
		case asc(DQ)
			cursor += 1 'skip '"'
			startPos = cursor
			while 1
				if cursor >= jsonStrLen then return "FAIL_END_DQ"
				if jsonStr[cursor] = asc(DQ) then exit while
				cursor += 1
			wend
			endPos = cursor
		case asc("0") to asc("9"), asc("+"), asc("-")
			startPos = cursor 'include this last one in return value
			cursor += 1
			while 1
				if cursor >= jsonStrLen then return "FAIL_END_NUM"
				if jsonStr[cursor] < asc("0") or jsonStr[cursor] > asc("9") then exit while
				cursor += 1
			wend
			endPos = cursor
		case else
			return "FAIL_NO_SELECT"
	end select
	return mid(jsonStr, startPos + 1, endPos - startPos)
end function
Don't expect much progress from me until the end of October because I will not be near a computer till then.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All
Does it use the same protocol? And do you know the commands to send?
No and No, but what are the chances that the On & off are the same ?
Australian expression "Suck it and see"

Will test and see the getJsonValue() functions and let you know.
Don't expect much progress from me until the end of October because I will not be near a computer till then.
Jail time ?? :)
I will also be away from this project, I have a control panel to assemble for a machine upgrade in Australia, AND invent a way to talk to Smart Light Bulbs.

Regards
andykmv
Posts: 58
Joined: Feb 12, 2015 9:50

Re: TP-Link HS110

Post by andykmv »

hi guys

i have been interesed in home automation for a while and recently setup an rpi with openhab to play with some ifttt, esp wifi and sonoff devices, so i have been keenly following this thread as the project developed
Dinosaur wrote:....
I am reluctant to believe that using a 240 vac 50 hz device here in the US is the cause, particularly as all the commands operate correctly. I guess after the end of the year I will find out.....
just bought a tplink hs110 here in aus from officeworks about an hour ago - hoping i can join in since i have the aus version in aus so i can help test that scenario. where do i start ?

ps also running fbc on windows8.1pro atm, "FreeBASIC Compiler - Version 1.05.0 (01-31-2016), built for win64 (64bit)" or 32 bit same version.
And about time i setup 1.06, & 1.07.1 compiler so i'll add the latest winfbe.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

Andy you are welcome, the more the merrier.
I bought mine at Bunnings in Hervey Bay and would be interested in the differences.
If you run the

Code: Select all

.cmdStr = !"{\"system\":{\"get_sysinfo\":null}}"
command and post the result
that would show if there are significant differences.
Mine shows this.

Code: Select all

{"system":{"get_sysinfo":null}}
Elapsed = 155
Command Print  6
.HwVer           = 2.0
.SwVer           = 1.5.5 Build 181225 Rel.102720
.DeviceId        = 80061922201888E1FBE72378A55A2C581ADF3EAA
.OemId           = 6480C2101948463DC65D7009CAECDECC
.HwId            = A28C8BB92AFCB6CAFB83A8C00145F7E2
.FwId            = 00000000000000000000000000000000
.Type            = IOT.SMARTPLUGSWITCH
.Model           = HS110(AU)
.MAC             = B0:BE:76:C1:B8:3C
.DevName         = Smart Wi-Fi Plug With Energy Monitoring
.Alias           = TP-LINK_Smart Plug_B83C
.RelayState      = 1
.OnTime          = 40909
.ActiveMode      = none
.Feature         = TIM:ENE
.Updating        = 0
.IconHash        = 
.Rssi            = -36
.LedOff          = 0
.Longitude       = FAIL_NO_KEY
.Latitude        = FAIL_NO_KEY
.NextAction      = FAIL_IS_OBJECT
.ErrCode         = 0
As you can see it took 155 mSec. Ignore the FAIL's.
I am sure you will be able to get started from all the snippets in this thread, however there are some Linux commands which
you will need to convert for windows.
Open pipe "nmcli dev wifi" For Input As #PF
and
arp-scan -l -I $(ls /sys/class/net | grep -o "wl[^\t]\+")
I am happy to send you what I have done sofar and you can experiment with that.
Will send you a PM.

Regards
andykmv
Posts: 58
Joined: Feb 12, 2015 9:50

Re: TP-Link HS110

Post by andykmv »

thanks!
downloaded and attempted compile with 1.05.0 wi-64 - my script:
set cp="r:\data_papps\freebasic\lib"
set sp="R:\Data\Test\hs110"
set bp="R:\Data\Test\hs110"
R:\data_papps\FreeBASIC\fbc -target win64 -v %sp%\tplink.bas fblogo.rc -x %bp%\tplink.exe

and got this:

Code: Select all

FreeBASIC Compiler - Version 1.05.0 (01-31-2016), built for win64 (64bit)
Copyright (C) 2004-2016 The FreeBASIC development team.
standalone
target:       win64, x86-64, 64bit
compiling:    R:\Data\Test\hs110\tplink.bas -o R:\Data\Test\hs110\tplink.c (main module)
R:\Data\Test\hs110\Declares.bi(17) error 4: Duplicated definition in 'Declare Sub ReadFile()'
R:\Data\Test\hs110\tplink.bas(216) error 1: Argument count mismatch in 'ReadFile'
R:\Data\Test\hs110\tplink.bas(283) error 4: Duplicated definition, Min in 'Dim as String Min   = Mid(Time,4,2)'
R:\Data\Test\hs110\tplink.bas(284) error 41: Variable not declared, Min in 'If Val(Min) = 0 Then Min = " 0"'
R:\Data\Test\hs110\tplink.bas(284) error 3: Expected End-of-Line, found 'Min' in 'If Val(Min) = 0 Then Min = " 0"'
R:\Data\Test\hs110\tplink.bas(297) error 9: Expected expression, found 'Min' in 'Mid(.cmdStr,Control.Cnt,2) = Min'
R:\Data\Test\hs110\tplink.bas(570) error 20: Type mismatch in 'Sub ReadFile()'
R:\Data\Test\hs110\tplink.bas(570) warning 28(0): Return method mismatch
R:\Data\Test\hs110\tplink.bas(600) warning 13(0): Function result was not explicitly set
what version of fbc are you using ?
my snc is probably outofdate and i still have to mod commands 20 22
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

Andy I have no idea what you are doing with those commands.
set cp="r:\data_papps\freebasic\lib"
set sp="R:\Data\Test\hs110"
set bp="R:\Data\Test\hs110"
R:\data_papps\FreeBASIC\fbc -target win64 -v %sp%\tplink.bas fblogo.rc -x %bp%\tplink.exe
It is as simple as extracting all the files from the zip file into 1 folder.
Change to that folder and from the command line ; fbc -v -w All TPLink.bas
That's it , regardless of the fbc version.
The snc and all files needed are included in the zip.

The only thing that can go wrong is that it can't find the fbc compiler and you have to set the paths to it.

Regards
EDIT: I can't believe there are so many differences between Win & Linux.
I compiled it on Win 7 and got the same errors.
Change ReadFile to ReadFiles everywhere.(Obviously a name clash)
Change Min to Mins everywhere (Again a name clash)
Then it will compile,
Then I changed in the Command Prompt to the TPLink folder
AND GUESS WHAT, It wont run on Win 7, no error message, no printing NOTHING.
I am so happy I don't use Windows any more, sorry I can't help you any further.
andykmv
Posts: 58
Joined: Feb 12, 2015 9:50

Re: TP-Link HS110

Post by andykmv »

ok changed the readfile to readfiles, min to mins and also removed the resource file fblogo.rc from the fbc compile options.
result: compiled successfully.

thanks for the tips on the readfile and min names as it would have taken a while to find that. had a similar issue in a program of mine a year or so ago which got solved with a preprocessor command iirc.

ran the resulting tplink.exe on win 8.1 pro and got the menu printed out ok. whoo hoo!

have to mod the commands 20/22 next!
andykmv
Posts: 58
Joined: Feb 12, 2015 9:50

Re: TP-Link HS110

Post by andykmv »

windows 8.1 pro comand: netsh wlan show networks

Interface name : Wi-Fi
There are 3 networks currently visible.

SSID 1 : TP-LINK_Smart Plug_1A11
Network type : Infrastructure
Authentication : Open
Encryption : None

SSID 2 : andy
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP

SSID 3 : linksys
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

Andy looks like you are making progress.
A couple of notes:
1: Change the Alias command by adding more spaces to the command to avoid over writing the Quotes and curly brackets.

Code: Select all

            .cmdStr = !"{\"system\":{\"set_dev_alias\":{\"alias\":\"FreePlug         \"}}}"
            Control.Cnt = Instr(.cmdStr,"FreePlug")
            Mid(.cmdStr,Control.Cnt,Len(.DeviceAlias )) = .DeviceAlias
2: You don't have to use commands 20 & 21 if you are using the Kasa app.
Simply edit the file manually with the detail.
3: Any commands in the GetCmnd where the command ends with double quotes like this :""}}"
Change it to :null}}" I found some commands get stripped of the second " and the command fails.

Post any changes that were absolutely needed to get it to run on Windoze and I will put in some compile checks to include them.

Regards
andykmv
Posts: 58
Joined: Feb 12, 2015 9:50

Re: TP-Link HS110

Post by andykmv »

ok, trying the "suck it and see" method. :^)
thanks for the additional tips - i have started re-reading the thread
next step is get kasa working - having an issue with kasa at the moment
- for some reason can't select country but have only spent a few min on it - or was that mins ? :^)
once i get that nutted i'll see what the python script reports.

maybe some preprocessor commands such as #IFDEF __FB_WIN32__ or #IFDEF __FB_WIN64__ or #IFDEF __FB_WIN32__ or __FB_LINUX__ (depending on compile target using -target ) could be added to encapsulate windows or linux specific commands for compiling ( i can play with the windows side if i can work out a process similar to the nmcli equivalent query command for example) - do you have a sample in the thread of the data the nmcli command produces ? (raw)
Post Reply