def start(self): log.info('Initializing sensor "Victron Energy VE.Direct"') # Initialize the hardware driver. try: # MicroPython if platform_info.vendor in [ platform_info.MICROPYTHON.Vanilla, platform_info.MICROPYTHON.Pycom ]: raise NotImplementedError( 'VEDirect driver not implemented on MicroPython') # CPython elif platform_info.vendor == platform_info.MICROPYTHON.RaspberryPi: from vedirect import Vedirect self.driver = Vedirect(serialport=self.device, timeout=self.timeout) else: raise NotImplementedError( 'VEDirect driver not implemented on this platform') return True except Exception as ex: log.exc(ex, 'VEDirect hardware driver failed')
def __init__(self, serialport, timeout, debug=False, sim=False): self.sim = sim self.debug = debug if sim: self.ve = Mpptsim(debug) else: self.ve = Vedirect(serialport, timeout, debug)
parser.add_argument('--port', help='Serial port') parser.add_argument('--timeout', help='Serial port read timeout', type=int, default='60') parser.add_argument('--mqttbroker', help='MQTT broker address', type=str, default='photon.local') parser.add_argument('--mqttbrokerport', help='MQTT broker port', type=int, default='1883') parser.add_argument('--topicprefix', help='MQTT topic prefix', type=str, default='vedirect') args = parser.parse_args() ve = Vedirect(args.port, args.timeout) client = mqtt.Client() client.connect(args.mqttbroker, args.mqttbrokerport, 60) client.loop_start() def mqtt_send_callback(packet): for key, value in packet.items(): if key != 'SER#': # topic cannot contain MQTT wildcards client.publish(args.topicprefix + key, value) ve.read_data_callback(mqtt_send_callback)
#!/usr/bin/python3 # -*- coding: utf-8 -*- import argparse, os from vedirect import Vedirect def print_data_callback(packet): print(packet) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Process VE.Direct protocol') parser.add_argument('--port', help='Serial port') parser.add_argument('--timeout', help='Serial port read timeout', type=int, default='60') args = parser.parse_args() ve = Vedirect(args.port, args.timeout) print(ve.read_data_callback(print_data_callback))
# -*- coding: utf-8 -*- import argparse, os from vedirect import Mpptsim from vedirect import Vecommon from vedirect import Vedirect # ve = Mpptsim() ve = Vedirect('/dev/tty.usbserial-VE4ZKFJZ',60, False) print(ve.read_text_frame()) print ("========Below is command response ========") for i in [1,3,4]: f,v = ve.send_command(":"+str(i)) if f: print('{:d} : "'.format(i) + v + '",' ) print ("========Below is command 7========") for i in range(65535): f,v = ve.send_command(":7"+ Vecommon.int_to_little_endian(i)) if f: print('0x{:04X} : "'.format(i) + v + '",' ) # mppt_command_list = [ # 0x0100,0x0104,0x010A,0x010B,0x0140, # 0x0200,0x0201,0x0202,0x0205,0x0207, # 0xEDFF,0xEDFE,0xEDFD,0xEDFC,0xEDFB,0xEDF7,0xEDF6,0xEDF4,0xEDF2,0xEDF1,0xEDF0,0xEDEF,0xEDEC,0xEDEA,0xEDE8,0xEDE7,0xEDE6,0xEDE5,0xEDE4,0xEDE3,0xED2E,0xEDE0,0xEDCA, # 0xEDEC,0xEDDF,0xEDDD,0xEDDC,0xEDDB,0xEDDA,0xEDD7,0xEDD5,0xEDD4,0xEDD3,0xEDD2,0xEDD1,0xEDD0,0xEDCE,0xEDCD,0xEDCC,0x2211,0x2212, # 0xEDBC,0xEDBB,0xEDBD,0xEDB8,0xEDB3, # 0xEDAD,0xEDAC,0xEDAB,0xEDA9,0xEDA8,0xED9D,0xED9C,0xED91,0xED90, # 0xEDD9,0x0350,0x0351,0x0352,0x0353,0xEDBA,0xEDB9,0x100A, # 0xEDA0,0xEDA5,0xEDA7,0xED9B,0xED9A,0xED99,0xED96,0xED97,0xED90,0x2030,0x2031,
class VEDirectSensor(AbstractSensor): """ About ===== Victron Energy VE.Direct MPPT charge controller sensor component. Supported devices ================= - SmartSolar MPPT 100/20 - SmartSolar MPPT 75/15 - BlueSolar MPPT 75/15 - BMV 702 battery monitor Resources ========= - https://github.com/karioja/vedirect - https://www.victronenergy.com/solar-charge-controllers/smartsolar-mppt-75-10-75-15-100-15-100-20 - https://www.victronenergy.com/solar-charge-controllers/bluesolar-mppt-150-35 - https://www.victronenergy.com/battery-monitors/bmv-700 - https://www.victronenergy.com/live/victronconnect:mppt-solarchargers """ def __init__(self, settings=None): super().__init__(settings=settings) # Can be overwritten by ``.set_address()``. self.device = settings['device'] self.timeout = 5 self.driver = None def start(self): log.info('Initializing sensor "Victron Energy VE.Direct"') # Initialize the hardware driver. try: # MicroPython if platform_info.vendor in [ platform_info.MICROPYTHON.Vanilla, platform_info.MICROPYTHON.Pycom ]: raise NotImplementedError( 'VEDirect driver not implemented on MicroPython') # CPython elif platform_info.vendor == platform_info.MICROPYTHON.RaspberryPi: from vedirect import Vedirect self.driver = Vedirect(serialport=self.device, timeout=self.timeout) else: raise NotImplementedError( 'VEDirect driver not implemented on this platform') return True except Exception as ex: log.exc(ex, 'VEDirect hardware driver failed') def read(self): log.info('Reading sensor "Victron Energy VE.Direct"') # MicroPython if platform_info.vendor in [ platform_info.MICROPYTHON.Vanilla, platform_info.MICROPYTHON.Pycom ]: raise NotImplementedError( 'VEDirect driver not implemented on MicroPython') # CPython elif platform_info.vendor == platform_info.MICROPYTHON.RaspberryPi: data_raw = self.driver.read_data_single() data = {} for key, value in data_raw.items(): key = 'vedirect:{}'.format(key) data[key] = value return data
def get_data(self): ve = Vedirect(self.port, 60) return self.format_data(ve.read_data_single())
def print_data_callback(packet): print(packet) # print(":".join("{:02x}".format(ord(c)) for c in packet)) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Process VE.Direct protocol') parser.add_argument('--port', help='Serial port') parser.add_argument('--timeout', help='Serial port read timeout', type=int, default='60') args = parser.parse_args() ve = Vedirect(args.port, args.timeout) print("FINAL RESULT = ", ve.send_command('7F7ED00')) # print(ve.read_frame()) # raw_data = ve.read_data_single() # print_data_callback(raw_data) #print(ve.read_data_callback(print_data_callback)) # print(ve.send_command(':7F7ED00')) # print("Oct:",ve.send_command(':1')) # ss = Smartsolar(args.port, args.timeout) # print(ss.readText()) # ver = ss.pingDevice() # print("Ver: " + ver) # print(ss.getParam("BatteryFloatVoltage")) # print(ss.getParam("BatteryAbsorptionVoltage")) # print(ss.getParam("SystemTotal")) # print(ss.appVersion())
class Smartsolar: def __init__(self, serialport, timeout, debug=False, sim=False): self.sim = sim self.debug = debug if sim: self.ve = Mpptsim(debug) else: self.ve = Vedirect(serialport, timeout, debug) def read_text_frame(self): return self.text_translate(self.ve.read_text_frame()) def ping_device(self): flag, raw_result = self.ve.send_command("1") return self.resp_done_decode(raw_result) def get_app_version(self): flag, raw_result = self.ve.send_command("3") return self.resp_done_decode(raw_result) # Decode ping/get app command response. def resp_done_decode(self, raw_result): result = raw_result[2:6] version = result[3] + "." + result[0:2] return version def get_param(self, param): if not param in Veconst.REG_PARAMS.keys(): return ("Param not found!") cmd_str = ":7" + Vecommon.int_to_little_endian(param) flag, raw_result = self.ve.send_command(cmd_str) #rtn ":7F7ED009C09C5" if not flag: return (flag, raw_result) result = raw_result[len(cmd_str):len(raw_result) - 2] # 9C09 reg_param = Veconst.REG_PARAMS[param] if reg_param[Veconst.IDX_DATA_TYPE] == Veconst.TYPE_STRING: # string val = bytearray.fromhex(result).decode("utf-8").strip("\x00") else: val = Vecommon.little_endian_to_int(result) reg_param = Veconst.REG_PARAMS[param] if reg_param[Veconst.IDX_SCALE] > 0: val = val * reg_param[Veconst.IDX_SCALE] return (True, (val, reg_param[Veconst.IDX_UNIT], reg_param[Veconst.IDX_DESC])) def human_dump(self, d): for i in d: print(i[0], ":", i[1], i[2]) def text_translate(self, dict): tar_dict = [] for k in dict: if k in Veconst.VEDIRECT_MAPPING.keys(): v = dict[k] if Veconst.VEDIRECT_MAPPING[k]["process"] > 0: v = "{:.02f}".format( float(v) * Veconst.VEDIRECT_MAPPING[k]["process"]) elif Veconst.VEDIRECT_MAPPING[k]["process"] == -10: v = Veconst.PID_MAPPING[v] elif Veconst.VEDIRECT_MAPPING[k]["process"] == -11: v = Veconst.CS_MAPPING[v] elif Veconst.VEDIRECT_MAPPING[k]["process"] == -12: v = Veconst.MPPT_MAPPING[v] attr = [ Veconst.VEDIRECT_MAPPING[k]["name"], v, Veconst.VEDIRECT_MAPPING[k]["unit"], dict[k] ] else: attr = [k, dict[k], "", dict[k], dict[k]] tar_dict.append(attr) if self.debug: self.human_dump(tar_dict) return tar_dict