def device_polling(): if DashingEnabled: Dashlog.append("Starting device poller") ui.display() else: log.info("Starting device poller") CONF_ORNO = False CONF_EM370 = True CONF_SOLIS_4G_3P = True CONF_JANITZA_B23 = True CONF_EMONCMS = True RtuclientState = False QuerryNb = 0 HostName = 'emoncms.powerdale.com' ModbusHost = "10.10.10.101" ModbusPort = 502 emon_host = "emoncms.powerdale.com" emon_url = "/input/post.json?node=" emon_privateKey = "4dbf608f20eab1ad1d1bf4512dc85d1c" emon_node = "B4E" # for cycle in range(0, 2000): # vchart.append(50 + 50 * math.sin(cycle / 16.0)) # hchart.append(99.9 * abs(math.sin(cycle / 26.0))) # bchart.append(50 + 50 * math.sin(cycle / 6.0)) # ui.display() OR_WE_514_Registers = testmap.generate_device_dict( './mapping_tools/or_we_514-v1-1_1.json') EEM_MA370_Registers = testmap.generate_device_dict( './mapping_tools/eem_ma370-v1-1_1.json') SOLIS_4G_Registers = testmap.generate_device_dict( './mapping_tools/solis_4g_3p-v1-1_1.json') JANITZA_B23_Registers = testmap.generate_device_dict( './mapping_tools/janitza_b23-v1-1_1.json') #print(OR_WE_514_Registers) #print(json.dumps(EEM_MA370_Registers, indent='\t')) #print(OR_WE_514_Registers) #print(EEM_MA370_Registers) print(SOLIS_4G_Registers) SolarInverter = copy.deepcopy(SOLIS_4G_Registers) Grid = copy.deepcopy(EEM_MA370_Registers) Evse = copy.deepcopy(JANITZA_B23_Registers) SOLIS_Config = { 'Solar': { "NAME": "Inverter", "PORT": "/dev/ttyUSB0", "ADDRESS": 1, "DATA": SolarInverter } } EEM_Config = { 'Grid': { "NAME": "Grid", "PORT": "", "ADDRESS": 1, "DATA": Grid } } B23_Config = { 'Evse': { "NAME": "Evse", "PORT": "/dev/ttyUSB1", "ADDRESS": 2, "DATA": Evse } } # Create modbus clients if CONF_EM370: try: TcpClient = ModbusTcpClient(host=ModbusHost, port=ModbusPort, auto_open=True, timeout=5) if DashingEnabled: Dashlog.append( f"Modbus TCP client connected: {TcpClient.connect()}") else: log.info(f"Modbus TCP client connected: {TcpClient.connect()}") except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if CONF_SOLIS_4G_3P: try: Rtuclient = ModbusRtuClient(method='rtu', port='/dev/ttyUSB0', stopbits=1, bytesize=8, parity='N', baudrate=9600, timeout=1) if DashingEnabled: Dashlog.append(f"Modbus RTU port open: {Rtuclient.connect()}") else: print(f"Modbus RTU port open: {Rtuclient.connect()}") except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if CONF_JANITZA_B23: try: Rtuclient2 = ModbusRtuClient(method='rtu', port='/dev/ttyUSB1', stopbits=1, bytesize=8, parity='N', baudrate=9600, timeout=1) if DashingEnabled: Dashlog.append(f"Modbus RTU port open: {Rtuclient2.connect()}") else: print(f"Modbus RTU port open: {Rtuclient2.connect()}") except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass try: while True: #os.system('cls' if os.name == 'nt' else 'clear') QuerryNb = QuerryNb + 1 if CONF_EM370 and TcpClient.is_socket_open(): if DashingEnabled: Dashlog.append("Read EEM_MA370") ui.display() else: log.info("Read EEM_MA370") for x, z in EEM_Config.items(): if DashingEnabled: Dashlog.append(f"Reading slave {z['NAME']}") MyDict = z['DATA'] #print (MyDict) for k, y in MyDict.items(): #Log.append(y['Name']) if (y['Name'] == 'Active power'): if DashingEnabled: Dashlog.append( f"Active power: {y['Value']:.01f}W") hchart.title = f"Active power: {y['Value']:.0f}W" hchart.append(100 * y['Value'] / 5000) ui.display() rr = None try: rr = TcpClient.read_holding_registers( y['Address'], y['Size']) except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) if (isinstance(rr, ReadHoldingRegistersResponse) and (len(rr.registers) == y['Size'])): decoder = BinaryPayloadDecoder.fromRegisters( rr.registers, byteorder=Endian.Big, wordorder=Endian.Little) decoded = OrderedDict([ ('string', decoder.decode_string), ('bits', decoder.decode_bits), ('8int', decoder.decode_8bit_int), ('8uint', decoder.decode_8bit_uint), ('16int', decoder.decode_16bit_int), ('16uint', decoder.decode_16bit_uint), ('32int', decoder.decode_32bit_int), ('32uint', decoder.decode_32bit_uint), ('16float', decoder.decode_16bit_float), ('16float2', decoder.decode_16bit_float), ('32float', decoder.decode_32bit_float), ('32float2', decoder.decode_32bit_float), ('64int', decoder.decode_64bit_int), ('64uint', decoder.decode_64bit_uint), ('ignore', decoder.skip_bytes), ('64float', decoder.decode_64bit_float), ('64float2', decoder.decode_64bit_float), ]) y['Value'] = round( decoded[y['Type']]() * y['Scale'], 3) #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units']) #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}") #print("HOME") Rtuclient.connect() if CONF_SOLIS_4G_3P and Rtuclient.is_socket_open(): if DashingEnabled: Dashlog.append("Read Solis-4G inverter") ui.display() else: log.info("Read Solis-4G inverter") for x, z in SOLIS_Config.items(): if DashingEnabled: Dashlog.append(f"Reading slave {z['NAME']}") DashMeas1.append("") DashMeas1.append(f"Reading slave {z['NAME']}") ui.display() else: log.info(f"Reading slave {z['NAME']}") MyDict = z['DATA'] #print (MyDict) for k, y in MyDict.items(): #print(z['ADDRESS'], y['Address'], y['Size']) rr = None try: rr = Rtuclient.read_input_registers( y['Address'], y['Size'], unit=z['ADDRESS']) except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if (isinstance(rr, ReadInputRegistersResponse) and (len(rr.registers) == y['Size'])): decoder = BinaryPayloadDecoder.fromRegisters( rr.registers, byteorder=Endian.Big, wordorder=Endian.Big) decoded = OrderedDict([ ('string', decoder.decode_string), ('bits', decoder.decode_bits), ('8int', decoder.decode_8bit_int), ('8uint', decoder.decode_8bit_uint), ('16int', decoder.decode_16bit_int), ('16uint', decoder.decode_16bit_uint), ('32int', decoder.decode_32bit_int), ('32uint', decoder.decode_32bit_uint), ('16float', decoder.decode_16bit_float), ('16float2', decoder.decode_16bit_float), ('32float', decoder.decode_32bit_float), ('32float2', decoder.decode_32bit_float), ('64int', decoder.decode_64bit_int), ('64uint', decoder.decode_64bit_uint), ('ignore', decoder.skip_bytes), ('64float', decoder.decode_64bit_float), ('64float2', decoder.decode_64bit_float), ]) y['Value'] = round( decoded[y['Type']]() * y['Scale'], 3) #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units']) if DashingEnabled: DashMeas1.append( f"{y['Name']} = {y['Value']:.02f} {y['Units']}" ) ui.display() #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}") # Rtuclient.close() Rtuclient2.connect() if CONF_JANITZA_B23 and Rtuclient2.is_socket_open(): if DashingEnabled: Dashlog.append("Read EVSE charger") ui.display() else: log.info("Read EVSE charger...") for x, z in B23_Config.items(): if DashingEnabled: Dashlog.append(f"Reading slave {z['NAME']}") DashMeas1.append("") DashMeas1.append(f"Reading slave {z['NAME']}") ui.display() else: log.info(f"Reading slave {z['NAME']}") MyDict = z['DATA'] print(MyDict) for k, y in MyDict.items(): #print(z['ADDRESS'], y['Address'], y['Size']) rr = None try: rr = Rtuclient2.read_holding_registers( y['Address'], y['Size'], unit=z['ADDRESS']) except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if (isinstance(rr, ReadHoldingRegistersResponse) and (len(rr.registers) == y['Size'])): decoder = BinaryPayloadDecoder.fromRegisters( rr.registers, byteorder=Endian.Big, wordorder=Endian.Big) decoded = OrderedDict([ ('string', decoder.decode_string), ('bits', decoder.decode_bits), ('8int', decoder.decode_8bit_int), ('8uint', decoder.decode_8bit_uint), ('16int', decoder.decode_16bit_int), ('16uint', decoder.decode_16bit_uint), ('32int', decoder.decode_32bit_int), ('32uint', decoder.decode_32bit_uint), ('16float', decoder.decode_16bit_float), ('16float2', decoder.decode_16bit_float), ('32float', decoder.decode_32bit_float), ('32float2', decoder.decode_32bit_float), ('64int', decoder.decode_64bit_int), ('64uint', decoder.decode_64bit_uint), ('ignore', decoder.skip_bytes), ('64float', decoder.decode_64bit_float), ('64float2', decoder.decode_64bit_float), ]) y['Value'] = round( decoded[y['Type']]() * y['Scale'], 3) if math.isnan(y['Value']): y['Value'] = 0 #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units']) if DashingEnabled: DashMeas1.append( f"{y['Name']} = {y['Value']:.02f} {y['Units']}" ) ui.display() #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}") # Rtuclient.close() #print("HOME") if DashingEnabled: bchart.append(QuerryNb) else: log.info(f"Poller querry : {QuerryNb}") #print ( "Querry %s" % QuerryNb) if (CONF_EMONCMS and CONF_SOLIS_4G_3P): SolarPower = 0 for x, z in SOLIS_Config.items(): if Rtuclient.is_socket_open(): reqdata = {} #print("Slave: " + z['NAME']) MyDict = z['DATA'] #print (z['DATA']) for k, y in MyDict.items(): #DashErrors.append(y['Name']) if (y['Name'] == 'Freq'): vchart.append(50 + QuerryNb) reqdata[f"{z['NAME']}{y['Name']}"] = y['Value'] #print('reqdata = {reqdata}') req = MyEmon.senddata(reqdata) reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}' try: r = requests.get(reqstr, timeout=10) r.raise_for_status() except requests.exceptions.HTTPError as errh: print("Http Error:", errh) except requests.exceptions.ConnectionError as errc: print("Error Connecting:", errc) except requests.exceptions.Timeout as errt: print("Timeout Error:", errt) except requests.exceptions.RequestException as err: print("OOps: Something Else", err) #print (r.status_code) #log.info( f"EmonCMS send status {r.status_code}" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) ui.display() else: log.info( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) #print (r.content) else: #log.info( "EmonCMS ORNO unable to send" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} nothing to push") ui.display() else: log.info( f"EmonCMS slave {z['NAME']} nothing to push") if (CONF_EMONCMS and CONF_JANITZA_B23): for x, z in B23_Config.items(): if Rtuclient2.is_socket_open(): reqdata = {} #print("Slave: " + z['NAME']) MyDict = z['DATA'] #print (z['DATA']) for k, y in MyDict.items(): #DashErrors.append(y['Name']) if (y['Name'] == 'Freq'): vchart.append(50 + QuerryNb) reqdata[f"{z['NAME']}{y['Name']}"] = y['Value'] #print('reqdata = {reqdata}') req = MyEmon.senddata(reqdata) reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}' try: r = requests.get(reqstr, timeout=10) r.raise_for_status() except requests.exceptions.HTTPError as errh: print("Http Error:", errh) except requests.exceptions.ConnectionError as errc: print("Error Connecting:", errc) except requests.exceptions.Timeout as errt: print("Timeout Error:", errt) except requests.exceptions.RequestException as err: print("OOps: Something Else", err) #print (r.status_code) #log.info( f"EmonCMS send status {r.status_code}" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) ui.display() else: log.info( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) #print (r.content) else: #log.info( "EmonCMS ORNO unable to send" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} nothing to push") ui.display() else: log.info( f"EmonCMS slave {z['NAME']} nothing to push") if (CONF_EMONCMS and CONF_EM370): for x, z in EEM_Config.items(): if TcpClient.is_socket_open(): reqdata = {} #print("Slave: " + z['NAME']) MyDict = z['DATA'] #print (z['DATA']) for k, y in MyDict.items(): #DashErrors.append(y['Name']) reqdata[f"{z['NAME']}{y['Name']}"] = y['Value'] #print('reqdata = {reqdata}') reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}' try: r = requests.get(reqstr, timeout=10) r.raise_for_status() except requests.exceptions.HTTPError as errh: print("Http Error:", errh) except requests.exceptions.ConnectionError as errc: print("Error Connecting:", errc) except requests.exceptions.Timeout as errt: print("Timeout Error:", errt) except requests.exceptions.RequestException as err: print("OOps: Something Else", err) #print (r.status_code) #log.info( f"EmonCMS send status {r.status_code}" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) ui.display() else: log.info( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) #print (r.content) else: #log.info( "EmonCMS ORNO unable to send" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} nothing to push") ui.display() else: log.info( f"EmonCMS slave {z['NAME']} nothing to push") time.sleep(5) except Exception as e: print("Exception %s" % str(e))
print("opening {} hit CTRL+C to exit".format(sys.argv[1])) serialClient = ModbusSerialClient(method="rtu", port=sys.argv[1], baudrate=9600, stopbits=1, bytesize=8, timeout=0.2) serialClient.connect() print("Trying to read register 1000 and search for EVSE on bus.") noResponse = 0 found = 0 try: for cycle in range(1, 255): try: if not serialClient.is_socket_open(): #print("...reconnecting...") serialClient.connect() rq = serialClient.read_holding_registers(1000, 1, unit=cycle) if hasattr(rq, 'registers'): print("Found address {} register 1000={}".format( cycle, rq.registers[0])) found += 1 else: print("{} no answer".format(cycle)) noResponse += 1 except ModbusIOException as e: print("{} no answer (IO exception)".format(cycle)) noResponse += 1
def testSerialClientIsSocketOpen(self, mock_serial): ''' Test the serial client is_socket_open method''' client = ModbusSerialClient() self.assertFalse(client.is_socket_open()) client.socket = mock_serial self.assertTrue(client.is_socket_open())