mirror of
https://github.com/carcinogoy/Victron_MK3_Parser.git
synced 2025-05-15 14:40:14 -07:00
122 lines
3.7 KiB
Python
122 lines
3.7 KiB
Python
import binascii
|
|
import serial
|
|
import threading
|
|
import time
|
|
import paho.mqtt.client as mqtt
|
|
import json
|
|
from bitarray import bitarray
|
|
|
|
mqttBroker = "192.168.1.100"
|
|
deviceName = "Inverter"
|
|
usbDevice = "/dev/ttyUSB0"
|
|
|
|
client = mqtt.Client(deviceName)
|
|
client.connect(mqttBroker)
|
|
serial = serial.Serial(usbDevice, 2400, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=0)
|
|
|
|
Inverter_Stats_Object = {}
|
|
|
|
#put your mqtt,post,blahblah here
|
|
def handleString(dataName, data):
|
|
Inverter_Stats_Object[dataName] = data
|
|
|
|
|
|
def handle_acFrame(frameBytes):
|
|
# AC main voltage
|
|
data = int.from_bytes(frameBytes[5:7], 'little') * 0.01
|
|
handleString("AC_Main_Voltage", data)
|
|
|
|
# AC main current
|
|
data = int.from_bytes(frameBytes[7:9], 'little') * 0.01
|
|
handleString("AC_Main_Current", data)
|
|
|
|
# AC inverter voltage
|
|
data = int.from_bytes(frameBytes[9:11], 'little') * 0.01
|
|
handleString("AC_Inverter_Voltage", data)
|
|
|
|
# AC inverter current
|
|
data = int.from_bytes(frameBytes[11:13], 'little') * 0.01
|
|
handleString("AC_Inverter_Current", data)
|
|
|
|
def handle_dcFrame(frameBytes):
|
|
# DC voltage
|
|
data = int.from_bytes(frameBytes[5:7], 'little') * 0.01
|
|
handleString("DC_Voltage", data)
|
|
|
|
# DC charge current
|
|
data = int.from_bytes(frameBytes[7:10], 'little') * 0.01
|
|
handleString("DC_Current_Used", data)
|
|
|
|
# DC drain current
|
|
data = int.from_bytes(frameBytes[10:13], 'little') * 0.01
|
|
handleString("DC_Current_Provided", data)
|
|
|
|
def handle_ledFrame(frameBytes):
|
|
ba = bitarray(endian='little')
|
|
ba.frombytes(frameBytes[1:2])
|
|
handleString("LED_Mains", int(ba[0]))
|
|
handleString("LED_Absorption", int(ba[1]))
|
|
handleString("LED_Bulk", int(ba[2]))
|
|
handleString("LED_Float", int(ba[3]))
|
|
handleString("LED_Inverter", int(ba[4]))
|
|
handleString("LED_Overload", int(ba[5]))
|
|
handleString("LED_Low_Battery", int(ba[6]))
|
|
handleString("LED_Temp", int(ba[7]))
|
|
|
|
|
|
def read_from_port(ser):
|
|
while True:
|
|
try:
|
|
byteV = b'\x00'
|
|
length = 0
|
|
frameType = 0x00
|
|
# find start of a frame
|
|
while byteV.hex() != 'ff' and byteV.hex() != '20':
|
|
if ser.inWaiting():
|
|
length = byteV
|
|
byteV = ser.read(1)
|
|
else:
|
|
time.sleep(0.01)
|
|
if byteV.hex() == 'ff':
|
|
frameType = 'ff'
|
|
else:
|
|
frameType = '20'
|
|
byteL = []
|
|
while len(byteL) < int.from_bytes(length, 'little'):
|
|
while ser.inWaiting() == 0:
|
|
time.sleep(0.01)
|
|
b = ser.read(1)
|
|
byteL.append(b)
|
|
frameBytes = bytes.fromhex(''.join(x.hex() for x in byteL))
|
|
if frameType == '20':
|
|
if byteL[4].hex() == '08':
|
|
handle_acFrame(frameBytes)
|
|
if byteL[4].hex() == '0c':
|
|
handle_dcFrame(frameBytes)
|
|
else:
|
|
if byteL[0].hex() == '4c':
|
|
handle_ledFrame(frameBytes)
|
|
except:
|
|
pass
|
|
|
|
def write_cmd(ser):
|
|
while True:
|
|
#dc
|
|
serial.write(bytes.fromhex('03ff4600b8'))
|
|
time.sleep(1)
|
|
#ac
|
|
serial.write(bytes.fromhex('03ff4601b7'))
|
|
time.sleep(1)
|
|
#led
|
|
serial.write(bytes.fromhex('02ff4cb3'))
|
|
time.sleep(1)
|
|
try:
|
|
client.publish(deviceName + "/data", json.dumps(Inverter_Stats_Object))
|
|
except:
|
|
print("Error sending data to MQTT.")
|
|
|
|
|
|
thread = threading.Thread(target=read_from_port, args=(serial,))
|
|
thread.start()
|
|
thread2 = threading.Thread(target=write_cmd, args=(serial,))
|
|
thread2.start() |