@ksheumaker got some better script to work with from other guy that had interest, maybe helps you too.
import socket
import struct
import binascii
import json
import datetime
from struct import unpack
myIPadress = "192.168.?.?"
myMACadress = "" #May be search for this if ipadres doesn't react, later
output = {}
def APSint(codec,start):
return int(binascii.b2a_hex(codec[(start):(start+2)]),16)
def APSbool(codec,start):
return bool(binascii.b2a_hex(codec[(start):(start+2)]))
def APSuid(codec,start):
return str(binascii.b2a_hex(codec[(start):(start+12)]))[2:14]
def APSstr(codec,start,amount):
return str(codec[start:(start+amount)])[2:(amount+2)]
def APStimestamp(codec,start,amount):
timestr=str(binascii.b2a_hex(codec[start:(start+amount)]))[2:(amount+2)]
return timestr[0:4]+"-"+timestr[4:6]+"-"+timestr[6:8]+" "+timestr[8:10]+":"+timestr[10:12]+":"+timestr[12:14]
#initialize socket
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((myIPadress,8899))
#get ECUID
ECU_R = 'APS1100160001END'
ECU_Rsend = ECU_R.encode('utf-8')
soc.send(ECU_Rsend)
ECU_Rreceive = soc.recv(1024)
# print ("\nAsking for ECUID number: ")
# print(ECU_Rreceive)
# Decoded explanation
# APS 1100940001 = Open sentence and answer notation
# 216000026497 = ECU_R nummer
# 01 =text unkown
# 00 00 (a7 90)=42896[167,144] 00 00 00 00 00 00 00
# 8x status of UID ca=202 d0=208 d0 d0 d0 d0 d0 d0
# 0008=(aantal UID) maximaal (16)
# 0000=integer unkown
# 10012 = text unkown
# ECU_R_1.2.13009 = Version
# Etc/GMT-8 = ETC ipv UTC Timezone server op lokatie met -8 uur?
# 80 97 1b 01 5d 1e 00 00 00 00 00 00
# END\n
myECUID = APSstr(ECU_Rreceive,13,12) #216000026497
output["ECU_R_ID"] = myECUID
output["maxUID"] = APSint(ECU_Rreceive,46)
output["Version"] = APSstr(ECU_Rreceive,55,15)
output["TimeZone"] = APSstr(ECU_Rreceive,70,9)
#print(output)
#get data from UID
ECU_R = 'APS1100280002'+myECUID+"END" # 2 extra?
ECU_Rsend = ECU_R.encode('utf-8')
soc.send(ECU_Rsend)
ECU_Rreceive = soc.recv(2048)
#print("\nAsking for UID numbers and data: "+str(len(ECU_Rreceive)))
#print(ECU_Rreceive)
#print("\n")
#print(binascii.b2a_hex(ECU_Rreceive))
if (len(ECU_Rreceive)>16) :
#base data valid for all UID
output["timestamp"] = APStimestamp(ECU_Rreceive,19,14)
counter = 1
maxcounter = APSint(ECU_Rreceive,17) #number of inverters
offset=26
while counter <= maxcounter:
# Records will pass for each inverter on this ECU_R (UID)
# 1-3 APS
# 4-18 UID
# 19 number of inverters?
#------------------------
# 20-32 Inverter ID (UID)
# 33 0 or 1 Marks online status of inverter instance
# 34 unkown "0"
# 35 unkown "1" Could be country because of 31 (Netherlands)
# 36-37 Frequency multiplied by 10
# 38-39 Temperature Celsius Bit 7 of second byte is signbit (1=+, 0=-)?
# 40-41 Power A Channel A on Inverter
# 42-43 Voltage A Chanel A on Inverter
# 44-45 Power B Channel B on Inverter
# 46-47 Voltage B Chanel B on Inverter
# 48-51 END or channel C and D till END
#pick up data for this inverter
# output={}
output["UID"+str(counter)] = APSuid(ECU_Rreceive,offset)
#you can also use UID as index in dictonary
uid=output["UID"+str(counter)][7:12]
output["Online"+uid] = APSbool(ECU_Rreceive,offset+6)
output["Something"+uid] = APSstr(ECU_Rreceive,offset+7,2)
output["Frequentie"+uid] = APSint(ECU_Rreceive,offset+9)/10.0
output["Temperature"+uid] = APSint(ECU_Rreceive,offset+11)-100 # check later if sign is bit 7 64 and fahrenheit
step = 13
channel = 1
while (channel <= 2): #QS1 must have 4 times, so C and D but how to see the difference
output["Power"+uid+"-"+str(channel)] = APSint(ECU_Rreceive,offset+step)
output["Volt"+uid+"-"+str(channel)] = APSint(ECU_Rreceive,offset+step+2)
step += 4
channel += 1
# print(output)
#end while channel
offset += step #how big is UID block
counter += 1
#print(output)
#end while UID
#print(output)
else:
output["Error"] = "No inverters active"
print(json.dumps(output))
heads up on above, seems to mess up a bit in QS1 data, the bytes per UID are longer for QS1