TP-Link HS110

For issues with communication ports, protocols, etc.
Post Reply
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

badidea , the computer on which this will run is a Beaglebone Black.
I have made a cape to fit on it which has 8 inputs and 20 1 amp outputs (O/P)
So perhaps that is where the O/P came from.

The reason the Enter key does that is that the Quit command = 0 and pressing Enter basically means 0.

Whole heartedly agree on the comments, but I usually leave them untill I am happy with the way it works.
If you were to see some of my gui projects, you would think the comments were excessive.

I have been doing a bit more to overcome the "pipe" problems.
The macscan.sh script works if you want to use it seperately, but it takes to long for my liking.
So, came up with this sofar using a script.

Code: Select all

#!/bin/sh
arp-scan -l -I $(ls /sys/class/net | grep -o "wl[^\t]\+")
That is then filtered by this very rough code to see if it is quicker and it is.(Typically 1.5 Sec)

Code: Select all

Sub mac2ip
    With NetDevice(Control.Device)
        Dim as Integer Cnt0 = Instr(.RxData,"responded")
        Dim as Integer NbrOfIP = Val(Mid(.RxData,Cnt0 - 3,3))
        Print NbrOfIP;" responded"

        Dim as Integer Cnt1 = Instr(.RxData,"192.168.0.1")          'find router
        Dim as String ip1 = Mid(.RxData,Cnt1,11)                    'extract it
        .RxData = Mid(.RxData,Cnt1 + 11,Len(.RxData)- Cnt1 + 11)    'shorten the string
        Print "Stripped ip1 ", ip1                                     'show ip 1 found
        Dim as Integer Cnt2  = Instr(.RxData,":")                   'look for first mac
        Dim as String mac1 = Mid(.RxData,Cnt2-2,17)                 'strip first mac found
        Print "Stripped mac1 ";mac1                                   'show mac 1 found
        Print
        .RxData = Mid(.RxData,Cnt2 + 15,Len(.RxData)- Cnt2 + 15)    'shorten the string
        Print
        
        Cnt1 = Instr(.RxData,"192.168.0.")          'find router
        Cnt2 = Instr(.RxData,":")                   'look for first mac
        Dim as String ip2   = Mid(.RxData,Cnt1,Cnt2 -2 -Cnt1)        'extract it
        Dim as String mac2  = Mid(.RxData,Cnt2-2,17)                'strip first mac found
        .RxData = Mid(.RxData,Cnt2 + 15,Len(.RxData)- Cnt2 + 15)    'shorten the string
        Print "Stripped ip2 ", ip2                                     'show ip 2 found
        Print "Stripped mac2 ";mac2                                   'show mac 2 found
        Print
    End With
End Sub
I have to write it to loop for the number that responded. Then will look in the Addresses.txt to see if I have collected a new one
and if I have find the first blank line and fill it in.(That will take a few days at the moment)

If you have time , it may be worth checking the V Gain and I gain.
I brought my multimeter home today, but I dont have a known load, so will have to experiment and measure.
For sure the Voltage is wrong (126V) , but that could be because I have a AU device and not a US one.

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

Re: TP-Link HS110

Post by badidea »

I get: {"emeter":{"get_vgain_igain":{"vgain":13264,"igain":17006,"err_code":0}}}
Not sure what those numbers mean, but last time with the 100 W lightbulb, values looked ok.
https://en.wikipedia.org/wiki/Mains_electricity wrote:In North America, the most common combination is 120 V and a frequency of 60 Hz
So 126 V could be right I think. The mains voltage can deviate a lot. Depends on supply, load and location.

I did some tests, results:

Code: Select all

No load

U [V] : 240.578
I [A] : 0.022
P [W] : 0.000
Power factor : 0.000

Cncandescent light bulb (rated: 100 W, 230 V)

U [V] : 241.571
I [A] : 0.454
P [W] : 109.743
Power factor : 1.001

Computer monitor (ASUS 24-inch)

U [V] : 240.204
I [A] : 0.108
P [W] : 12.531
Power factor : 0.483

Water boiler (Philips rated 2000 - 2400 W)

U [V] : 237.661
I [A] : 9.683
P [W] : 2301.261
Power factor : 1.000

Extractor fan (rated: 68 W, 900 m3/h)

U [V] : 240.772
I [A] : 0.543
P [W] : 72.602
Power factor : 0.555
The voltage clearly dropped with the water boiler. Which can be expected with that load.

My (cheap) multimeter reports 238.9 V (ac). But measured somewhat later.

My code is now multiple files. More difficult to post. Printing part:

Code: Select all

case E_CMD_GET_IV_NOW
	dim as single voltage = val(getJsonValue(RxData, "voltage_mv") ) * 1e-3
	print "U [V] : " & format(voltage, "0.000")
	dim as single current = val(getJsonValue(RxData, "current_ma")) * 1e-3
	print "I [A] : " & format(current, "0.000")
	dim as single power = val(getJsonValue(RxData, "power_mw")) * 1e-3
	print "P [W] : " & format(power, "0.000")
	dim as single cos_phi = power / (voltage * current)
	print "Power factor : " & format(cos_phi, "0.000")
Used this code https://freebasic.net/forum/viewtopic.p ... 34#p264883 for the getJsonValue().
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: TP-Link HS110

Post by badidea »

A power logger. Logs to file, in tab separated format.
LibreOffice Calc refuses to understand the time format.
But if that works, some nice plots can be made this way.
Todo: Direct visual graph display of data.
Current issue: Programs ends on connection loss.

Code: Select all

#include "string.bi"
#include "vbcompat.bi"
#include once "SNC/snc.bi"
'#include once "json_parse.bas"

const as string ServerIP = "HS110-1" '"192.168.0.1"
const as ushort ServerPort = 9999
const EXIT_OK = 0, EXIT_NOK = 1 'Not Ok
const as string KEY_ESC = chr(27)
const as string LOG_FILE = "power_log.txt"

'--------------------------------- json parse-----------------------------------

const DQ = chr(34) 'double quote
const SQ = "'" 'single quote

function getJsonValue(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
	'skip spaces
	while 1
		if cursor >= jsonStrLen then return "FAIL_END_SPC1"
		if jsonStr[cursor] <> asc(" ")  then exit while
		cursor += 1
	wend
	'check for colon
	if jsonStr[cursor] = asc(":") then
		cursor += 1
	else
		return "FAIL_NO_COLON"
	end if
	'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

function jsonKeyValue(jsonStr as string, key as string) as string
	return key + " : " + getJsonValue(jsonStr, key)
end function

'--------------------------------- Functions -----------------------------------

function encrypt(byref cmd as string) as string
	if len(cmd) > 0 then
		dim as ubyte key = 171 'same as -85
		for i as integer = 0 to len(cmd) - 1
			dim as ubyte a = key xor cmd[i]
			key = a
			cmd[i] = a
		next
	end if
	return cmd
end function

function decrypt(byref cmd as string) as string
	if len(cmd) > 0 then
		dim as ubyte key = 171 'same as -85
		for i as integer = 0 to len(cmd) - 1
			dim as ubyte a = key xor cmd[i]
			key = cmd[i]
			cmd[i] = a
		next
	end if
	return cmd
end function

'Prepend 4-byte length to string (max len = 255)
function TxLenStr(cmdStr as string ) as string
	return chr(0, 0, 0, len(cmdStr)) & cmdStr
end function

'Text -> "Text"
function quote(str1 as string) as string
	const DQ = chr(34)
	return DQ + str1 + DQ
end function

enum E_CMD
	E_CMD_OFF 'Turn Device Relay Off
	E_CMD_ON 'Turn Device Relay On
	E_CMD_INFO 'Get Device Info
	E_CMD_GET_TIME 'Get device date/time
	E_CMD_GET_TZONE 'Get device time zone
	E_CMD_SET_TZONE 'Set device time zone & date/time
	E_CMD_SET_AP 'Connect to AP with given SSID and Password
	E_CMD_SET_ALIAS 'Set Device Alias
	E_CMD_GET_IV_GAIN 'Get EMeter VGain and IGain Settings
	E_CMD_GET_IV_NOW 'Get Realtime Current and Voltage Reading
end enum

function generateCmdStr(iCmd as E_CMD) as string
	dim as string cmdStr
	select case iCmd
		case E_CMD_OFF
			cmdStr = !"{\"system\":{\"set_relay_state\":{\"state\":0}}}"
		case E_CMD_ON
			cmdStr = !"{\"system\":{\"set_relay_state\":{\"state\":1}}}"
		case E_CMD_INFO
			cmdStr = !"{\"system\":{\"get_sysinfo\":null}}"
		case E_CMD_GET_TIME
			cmdStr = !"{\"time\":{\"get_time\":null}}"
		case E_CMD_GET_TZONE
			cmdStr = !"{\"time\":{\"get_timezone\":null}}"
		case E_CMD_SET_TZONE
			'~ Dim as String Year  = Right(Date,4)
			'~ Dim as String Month = Left(Date,2)
			'~ Dim as String Day   = Mid(Date,4,2)
			'~ Dim as String Hour  = Left(Time,2)
			'~ Dim as String Min   = Mid(Time,4,2)
			'~ Dim as String Sec   = Right(Time,2)
			'~ 'Dim as String TZ = "00" 'Unknown
			'~ '{"time":{"set_timezone":{"year":2016,"month":1,"mday":1,"hour":10,"min":10,"sec":10,"index":42}}}
			'~ cmdStr = !"{\"time\":{\"set_timezone\":{\"year\":YYYY,\"month\":MM,\"mday\":DD,\"hour\":0,\"min\":mm,\"sec\":ss,\"index\":0}}}"
			'~ Cnt = Instr(cmdStr, "YYYY")
			'~ Mid(cmdStr, Cnt, 4) = Year
			'~ Cnt = Instr(cmdStr, "MM")
			'~ Mid(cmdStr, Cnt, 2) = Month
			'~ Cnt = Instr(cmdStr, "DD")
			'~ Mid(cmdStr, Cnt, 2) = Day
			'~ Cnt = Instr(cmdStr, "hh")
			'~ Mid(cmdStr, Cnt, 2) = Hour
			'~ Cnt = Instr(cmdStr, "mm")
			'~ Mid(cmdStr, Cnt, 2) = Min
			'~ Cnt = Instr(cmdStr, "ss")
			'~ Mid(cmdStr, Cnt, 2) = Sec
			'~ 'Cnt = Instr(cmdStr, "TZ")
			'~ 'Mid(cmdStr, Cnt, 2) = TZ
		case E_CMD_SET_AP
			'~ dim as string ssid, password
			'~ input "AP ssid: "; ssid
			'~ input "password: "; password
			'~ const KEY_WPA2 = 3
			'~ cmdStr  = !"{\"netif\":{\"set_stainfo\":{\"ssid\":" & quote(ssid)
			'~ cmdStr &= !",\"password\":" & quote(password)
			'~ cmdStr &= !",\"key_type\":" & KEY_WPA2
			'~ cmdStr &= !"}}}"
		case E_CMD_SET_ALIAS
			cmdStr = !"{\"system\":{\"set_dev_alias\":{\"alias\":\"StupidPlug\"}}}"
		case E_CMD_GET_IV_GAIN
			cmdStr = !"{\"emeter\":{\"get_vgain_igain\":{}}}"
		case E_CMD_GET_IV_NOW
			cmdStr = !"{\"emeter\":{\"get_realtime\":{}}}"
		case else
			print "Invalid option" : end
	end select
	return cmdStr
end function

type powerData_type
	dim as single voltage
	dim as single current
	dim as single power
	dim as single cos_phi
end type

'extract data from json string
function getPowerData(RxData as string) as powerData_type
	dim as powerData_type tempData
	with tempData
		.voltage = val(getJsonValue(RxData, "voltage_mv") ) * 1e-3
		.current = val(getJsonValue(RxData, "current_ma")) * 1e-3
		.power = val(getJsonValue(RxData, "power_mw")) * 1e-3
		.cos_phi = .power / (.voltage * .current)
	end with
	return tempData
end function

'display values on screen
sub printPowerData(powerData as powerData_type)
	print "U [V]:", format(powerData.voltage, "0.000"),
	print "I [A]:", format(powerData.current, "0.000"),
	print "P [W]:", format(powerData.power, "0.000"),
	print "Power factor:", format(powerData.cos_phi, "0.000")
end sub

'write values to file in append mode
function writePowerData(fileName as string, powerData as powerData_type) as integer
	dim as integer fileNum = freefile()
	dim as string outputStr
	dim as integer writeHeader = iif(fileexists(fileName), 0, 1)
	if open(fileName, for append, as fileNum) = 0 then
		if writeHeader then
			print "New file created: " & fileName
			print #fileNum, !"Time [hh:mm:ss]\tU [V]\tI [A]\tP [W]\tPower factor"
		end if
		outputStr  = time & !"\t"
		outputStr &= format(powerData.voltage, "0.000") & !"\t"
		outputStr &= format(powerData.current, "0.000") & !"\t"
		outputStr &= format(powerData.power, "0.000") & !"\t"
		outputStr &= format(powerData.cos_phi, "0.000")
		print #fileNum, outputStr
		close(fileNum)
	else
		return -1 'NOK
	end if
	return 0 'OK
end function

'----------------------------------- Main --------------------------------------

dim as E_CMD iCmd 'enum type
dim as string RxData, TxData, cmdStr
dim as double tEnd, tLoopWait, logInterval = 5
dim as zstring ptr pBuffer
dim as integer nBytes, quit = 0

dim as networkClient client = NetworkClient(ServerIP, ServerPort)
dim as networkConnection ptr pConnection = client.GetConnection()

iCmd = E_CMD_GET_IV_NOW
cmdStr = generateCmdStr(iCmd)
TxData = TxLenStr(encrypt(cmdStr))

print "Program started. Logs to file every " &  logInterval & " seconds"
while quit = 0
	tLoopWait = timer + logInterval

	'print "wait for allow sending data"
	tEnd = timer + 3.0
	while pConnection->CanPut() <> 1
		sleep 1
		if timer > tEnd then print "CanPut() timeout" : end(EXIT_NOK)
	wend

	'print "send data"
	if pConnection->PutData(strptr(TxData), len(TxData)) <= 0 then
		print "PutData() fail, LastError: " & pConnection->GetLastError
		end(EXIT_NOK)
	end if

	'print "wait for incomming data"
	tEnd = timer + 3.0
	while pConnection->CanGet() <> 1
		sleep 1
		if timer > tEnd then print "CanGet() timeout" : end(EXIT_NOK)
	wend

	'print "receive data"
	nBytes = pConnection->GetData(pBuffer, 1024, 1)
	if nBytes <= 0 then
		print "GetData() fail, LastError: " & pConnection->GetLastError
		end(EXIT_NOK)
	end if

	if nBytes > 4 then
		RxData = mid(*cast(zstring ptr, pBuffer + 4), 1, nBytes - 4)
		'RxData = *cast(zstring ptr, pBuffer + 4)
		decrypt(RxData)

		'check for set error field
		if getJsonValue(RxData, "err_code") = "0" then
			if iCmd = E_CMD_GET_IV_NOW then
				dim as powerData_type powerData = getPowerData(RxData)
				if writePowerData(LOG_FILE, powerData) <> 0 then
					print "Error: writePowerData()"
				end if
				printPowerData(powerData)
			else
				print RxData
			end if
		else
			print "RxData Error"
			print RxData : end(EXIT_NOK)
		endif
	else
		print "TxData Error"
		print RxData : end(EXIT_NOK)
	end if

	while timer < tLoopWait
		if inkey = KEY_ESC then quit = 1 : exit while
		sleep 1
	wend
wend

'free the buffer (allocated by snc.bi)
deallocate pBuffer
end(EXIT_OK)
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

Looks good, will try it and report back.
I need confirmation from your HS110 as to the network name when it has been reset to Factory default.
Mine comes up as :"TP-LINK_Smart Plug_B83C"
This works , but will be no good if every HS110 has a different name.
Note the space in the name.

I am trying to add automatic Wifi detection to the program by this method so no program exit is needed.
Although I could look for any wifi with the word ":"TP-LINK_Smart Plug"

Code: Select all

    Dim as String s , Chrs
    Dim as Long PF = FreeFile
    Open pipe "nmcli dev wifi" For Input As #PF     'prints out all wifi's found
    Do Until Eof(PF)
        Line Input #PF, Chrs
        s += Chrs
    Loop
    Close #PF
    Print s
    If Instr(s,"TP-LINK_Smart Plug_B83C") > 0 Then  'if the Plug is found
        Print "Found it"
        s = ""                                      'need double quotes to hide space in name.
        Open pipe "nmcli dev wifi connect " + Chr(34) + "TP-LINK_Smart Plug_B83C" + Chr(34) + " password 0" For Input as #PF
        Do Until Eof(PF)
            Line Input #PF, Chrs                    'get reply in
            s += Chrs
        Loop
        Close #PF
        Print s        
        Print "Done"
    EndIf
    Sleep
End
Regards

EDIT:Tested your logger and works ok. But to do a decent load I need to get a converter from Australian Plug to US Socket.
I have only been using it with my AU Laptop power supply. Will see if I can get one here or else a wiring job.
EDIT: Get it on Friday + bought a US version of the HS110.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

Surprise when I bought the us version of the HS110.
The get_sysinfo command produces the output in a completely different order.
The Australian HS110

Code: Select all

.Cmnd            = get_sysinfo
.SubCmnd         = sw_ver=1.5.5 Build 181225 Rel.102720
.HwVer           = 2.0
.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      = 0
.OnTime          = 0
.ActiveMode      = none
.Feature         = TIM:ENE
.Updating        = 0
.IconHash        = 
.Rssi            = -33
.LedOff          = 0
.Longitude       = 0
.Latitude        = 0
.HwId            = A28C8BB92AFCB6CAFB83A8C00145F7E2
.FwId            = 00000000000000000000000000000000
.DeviceId        = 80061922201888E1FBE72378A55A2C581ADF3EAA
.OemId           = 6480C2101948463DC65D7009CAECDECC
.NextAction      = type=-1
.ErrCode         = 0
The US version of the HS110

Code: Select all

.Cmnd            = get_sysinfo
.SubCmnd         = err_code=0
.HwVer           = 1.1.1 Build 160725 Rel.164033
.Type            = 1.0
.Model           = IOT.SMARTPLUGSWITCH
.MAC             = HS110(US)
.DevName         = 68:FF:7B:B8:79:89
.Alias           = 800615E675E904C5E1ABA6AF646A0D611B7ACBB2
.RelayState      = 60FF6B258734EA6880E186F8C96DDC61
.OnTime          = 060BFEA28A8CD1E67146EB5B2B599CC8
.ActiveMode      = FFF22CFF774A0B89F7624BFC6F50D5DE
.Feature         = TP-LINK_Smart Plug_7989
.Updating        = Wi-Fi Smart Plug With Energy Monitoring
.IconHash        = 
.Rssi            = 0
.LedOff          = 0
.Longitude       = none
.Latitude        = TIM:ENE
.HwId            = 0
.FwId            = -33
.DeviceId        = 0
.OemId           = 0
.NextAction      = 0=
.ErrCode         = 
When you look at the software version and build you will see that the US version is much older.
Amazon's OLD stock ???

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

Re: TP-Link HS110

Post by badidea »

Dinosaur wrote:When you look at the software version and build you will see that the US version is much older.
Amazon's OLD stock ???
How does the RxData string look like? The parsing seems to go wrong.
Also, on Amazon I see several product reviews with burned devices. TP-link might have improved the hardware in later versions.
The official way to update the firmware is via the Kasa app, but it seems also possible in different ways when I search for 'tp link hs110 firmware update'. E.g.: https://web.archive.org/web/20170609052 ... q-949.html

Currently working on a data plotter:
Image
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

That display looks good, well done. And here I thought you lost interest. ;)

TP-Link does state that different regions have different firmware ??
I nearly bought another AU unit from Amazon Australia, but the model was an EU, is that what you have ?
My current one is an HS110(AU).
Have updated the US version to no avail, although I am not 100% sure if that program used the update included.
It said that it had downloaded the update. (Not possible as the Router is not connected to the Internet)

Interestingly, I can communicate with the AU version al day without an error, then I have failure after failure with the US version.
BUT, if I use the python script (the original) then it will communicate without problems.
Today I will write a very basic Tx/Rx (back to the start) and test each one again.

I read the feedback on the burned units, and be aware that the Chinese over rate everything they produce.
There is no way I would switch 12.5 Amps with it. Perhaps switch the plug ON, then switch the load ON.
But certainly not switch the load with the flimsy relay inside.

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

Re: TP-Link HS110

Post by badidea »

Dinosaur wrote:I nearly bought another AU unit from Amazon Australia, but the model was an EU, is that what you have ?
On the back: Model: HS110(EU) Ver: 3.1
Also with a connector used in most of Europe (red & blue on this map: https://en.wikipedia.org/wiki/Schuko#/m ... _types.png)
Dinosaur wrote:I read the feedback on the burned units, and be aware that the Chinese over rate everything they produce.
There is no way I would switch 12.5 Amps with it. Perhaps switch the plug ON, then switch the load ON.
Yes, I see that people use this thing for everything: Electric car charging, Air conditioning units, etc.
This is what is inside: https://www.edn.com/design/consumer/445 ... automation (HS100)
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

badidea, that's a good find.
I was already thinking about changing some of them for my own purpose and put a SSR in there.
I have a lot of experience with them.

The Australian HS110(EU) does have the correct socket, but the only other question is then,
Is this the start of your Rxdata when you call for sysinfo? This is US version

Code: Select all

{"system":{"get_sysinfo":{"err_code":0,
With the AU version the err_code is the last transmitted field.

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

Re: TP-Link HS110

Post by badidea »

Dinosaur wrote:badidea, that's a good find.
Note that this is the HS100, without the energy measurement (I think).
Dinosaur wrote:I was already thinking about changing some of them for my own purpose and put a SSR in there.
I have a lot of experience with them.
The Omron relay should be fine as long as one does not start switching on highly capacitive loads or switching off highly inductive loads.
Dinosaur wrote:Is this the start of your Rxdata when you call for sysinfo?

Code: Select all

{"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":76,"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}}}
If you try my getJsonValue() posted abvove, then the order data should not matter.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All
If you try my getJsonValue() posted abvove, then the order data should not matter.
Yep, that works well, thanks.
A couple of items don't appear to fill in.

Code: Select all

{"system":{"get_sysinfo":{"sw_ver":"1.5.5 Build 181225 Rel.102720","hw_ver":"2.0","type":"IOT.SMARTPLUGSWITCH","model":"HS110(AU)","mac":"B0:BE:76:C1:B8:3C","dev_name":"Smart Wi-Fi Plug With Energy Monitoring","alias":"HS110-1g","relay_state":0,"on_time":0,"active_mode":"none","feature":"TIM:ENE","updating":0,"icon_hash":"","rssi":-31,"led_off":0,"longitude_i":0,"latitude_i":0,"hwId":"A28C8BB92AFCB6CAFB83A8C00145F7E2","fwId":"00000000000000000000000000000000","deviceId":"80061922201888E1FBE72378A55A2C581ADF3EAA","oemId":"6480C2101948463DC65D7009CAECDECC","next_action":{"type":-1},"err_code":0}}}�   
PrintValues
AssignValue
.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         = FAIL_NO_KEY
.Alias           = HS110-1g
.RelayState      = 0
.OnTime          = 0
.ActiveMode      = none
.Feature         = TIM:ENE
.Updating        = 0
.IconHash        = 
.Rssi            = -31
.LedOff          = 0
.Longitude       = FAIL_NO_KEY
.Latitude        = FAIL_NO_KEY
.NextAction      = FAIL_IS_OBJECT
.ErrCode         = 0
The code

Code: Select all

        .HwVer           = getJsonValue(NetDevice(Control.Device).RxData, "hw_ver")
        .SwVer           = getJsonValue(NetDevice(Control.Device).RxData, "sw_ver")
        .DeviceId        = getJsonValue(NetDevice(Control.Device).RxData, "deviceId")
        .OemId           = getJsonValue(NetDevice(Control.Device).RxData, "oemId")
        .HwId            = getJsonValue(NetDevice(Control.Device).RxData, "hwId")
        .FwId            = getJsonValue(NetDevice(Control.Device).RxData, "fwId")

        .Types           = getJsonValue(NetDevice(Control.Device).RxData, "type")
        .Model           = getJsonValue(NetDevice(Control.Device).RxData, "model")
        .MAC             = getJsonValue(NetDevice(Control.Device).RxData, "mac")
        .DevName         = getJsonValue(NetDevice(Control.Device).RxData, "device_name")
        .Aliaas          = getJsonValue(NetDevice(Control.Device).RxData, "alias")
        .RelayState      = getJsonValue(NetDevice(Control.Device).RxData, "relay_state")
        .OnTime          = getJsonValue(NetDevice(Control.Device).RxData, "on_time")
        .ActiveMode      = getJsonValue(NetDevice(Control.Device).RxData, "active_mode")
        .Feature         = getJsonValue(NetDevice(Control.Device).RxData, "feature")
        .Updating        = getJsonValue(NetDevice(Control.Device).RxData, "updating")
        .IconHash        = getJsonValue(NetDevice(Control.Device).RxData, "icon_hash")
        .Rssi            = getJsonValue(NetDevice(Control.Device).RxData, "rssi")
        .LedOff          = getJsonValue(NetDevice(Control.Device).RxData, "led_off")
        .Longitude       = getJsonValue(NetDevice(Control.Device).RxData, "longitude")
        .Latitude        = getJsonValue(NetDevice(Control.Device).RxData, "latitude")
        .NextAction      = getJsonValue(NetDevice(Control.Device).RxData, "next_action")
        .ErrCode         = getJsonValue(NetDevice(Control.Device).RxData, "err_code")
Found the issue with the unreliable comms.
I had broken up the TxRxData routine into steps, mainly because of concern for slow comms.
Leaving the connection open whilst "Pipe" was the biggest cause.

But, the times at the moment are like 35 mSec for a complete Tx, Rx.
Each time I change Device number, I have to create a new connection etc. anyway, so
now I have a small lean TxRxData routine that only opens a connection when I have something to send, then it completes it and closes.

I have automated the looking for and registering of new devices, but at this stage only by using a command.
Not automatically when the program starts.
When I have completed that I will post the code.

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

Re: TP-Link HS110

Post by badidea »

Dinosaur wrote:A couple of items don't appear to fill in
I should make the routine case-insensitive I see.
No some other issue. In your code:
device_name --> dev_name
longitude --> longitude_i
latitude --> latitude_i

Those are the exact variable names here as well.
Dinosaur wrote:Each time I change Device number, I have to create a new connection etc.
Why don't you keep all the connections open?

I the mean time, I have been tweaking SNC further for shorter timeout on connection setup.
See: https://freebasic.net/forum/viewtopic.p ... 60#p265119
Last edited by badidea on Oct 13, 2019 21:12, edited 1 time in total.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

I thought I checked case carefully, but 1 for sure is not a case problem.It is a stupid mis reading error.
From .RxData

Code: Select all

,"dev_name":"Smart Wi-Fi Plug With Energy Monitoring",
I am checking for

Code: Select all

getJsonValue(NetDevice(Control.Device).RxData, "device_name")
device_name should be dev_name.
Why don't you keep all the connections open?
I had never even contemplated that. Will test that though.

You may recall my AU device is 240vac and 50 Hz and I have it running on 120vac & 60 Hz.
The US model takes 50 mSec to do Command 6.
The AU model takes 2110 mSec.???

I will update the software in them, but have to make sure the link you provided updates all regions.

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

Re: TP-Link HS110

Post by badidea »

Dinosaur wrote:device_name should be dev_name.
Yes, post above updated.

Also note that you still have the 4-byte garbage in your RxData "� "
Dinosaur wrote:The AU model takes 2110 mSec.???
Sounds like the SNC issue again. Check with the python code.
Dinosaur wrote:I will update the software in them, but have to make sure the link you provided updates all regions.
It is an old link. TP-link removed it from their website, so don't trust it too much.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: TP-Link HS110

Post by Dinosaur »

Hi All

The US version has "longitude" and "latitude"
The AU version has "next_action" which reports FAIL_IS_OBJECT
The data is ,"next_action":{"type":-1},

Have you completely updated the snc.bi ?

Regards
Post Reply