class TestClientServer(unittest.TestCase): def setUp(self): # modbus server self.server = ModbusServer(port=5020, no_block=True) self.server.start() # modbus client self.client = ModbusClient(port=5020) self.client.open() def tearDown(self): self.client.close() def test_read_and_write(self): # word space self.assertEqual(self.client.read_holding_registers(0), [0], 'Default value is 0 when server start') self.assertEqual(self.client.read_input_registers(0), [0], 'Default value is 0 when server start') # single read/write self.assertEqual(self.client.write_single_register(0, 0xffff), True) self.assertEqual(self.client.read_input_registers(0), [0xffff]) # multi-write at max size words_l = [randint(0, 0xffff)] * 0x7b self.assertEqual(self.client.write_multiple_registers(0, words_l), True) self.assertEqual(self.client.read_holding_registers(0, len(words_l)), words_l) self.assertEqual(self.client.read_input_registers(0, len(words_l)), words_l) # write over sized words_l = [randint(0, 0xffff)] * 0x7c self.assertEqual(self.client.write_multiple_registers(0, words_l), None) # bit space self.assertEqual(self.client.read_coils(0), [False], 'Default value is False when server start') self.assertEqual(self.client.read_discrete_inputs(0), [False], 'Default value is False when server start') # single read/write self.assertEqual(self.client.write_single_coil(0, True), True) self.assertEqual(self.client.read_coils(0), [True]) self.assertEqual(self.client.read_discrete_inputs(0), [True]) # multi-write at min size bits_l = [getrandbits(1)] * 0x1 self.assertEqual(self.client.write_multiple_coils(0, bits_l), True) self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l) self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l) # multi-write at max size bits_l = [getrandbits(1)] * 0x7b0 self.assertEqual(self.client.write_multiple_coils(0, bits_l), True) self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l) self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l) # multi-write over sized bits_l = [getrandbits(1)] * 0x7b1 self.assertEqual(self.client.write_multiple_coils(0, bits_l), None)
def multiple_read_valid_invalid_combination(target_testrig, logger, fsm_targets, unit, io_channel): """ Requirement :WINGDECSAT-213 Test Case 3: Modbus: Log unsuccessful master read access Setup: WiCE 1-X Plus Test Rig GTU -1 is device under test (DUT) Systemtest server Given: GTU-1 is up and running. When: Setup connection with GTU1 on eth-pont-2 Send multiple read command to gtu1 with both valid and invalid input register address every 100 ms. Valid register address request will be send for more than 800ms after every invalid register address request. Read log message from gtu1. Then: Unknown Modbus address log shall be available """ #Given fsm = fsm_targets[unit.value] fnd_api = fsm.get_fnd_api() sleep(10) setup_modbus_gateway(logger, fsm, io_channel) sleep(2) ip_target = fsm_targets[unit.value].get_ip_eth_point(io_channel) logger.info("Target ip is {}".format(ip_target)) modbus_client = ModbusClient(host=ip_target, port=502, auto_open=True, auto_close=True) logger.info("modbus_client response {}".format(modbus_client)) #When #Then logger.info("Shooting continuous valid and invalid request") for i in range(0,6): modbus_client.read_input_registers(36720,1) sleep(0.1) for i in range(0,4): modbus_client.read_input_registers(1,1) sleep(0.1) response = get_command_to_run_journal(logger,fsm_targets,current_time,2) assert response <=10.00 sleep(5)
def VICTRON_modbus_power(): debug = debugVICTRON Modbus_Device_IP = "192.168.1.190" Modbus_Device_ID = "100" Modbus_Device_Port = 502 modbus_read_address = 842 debug = False value = 0.0 try: c = ModbusClient(host=Modbus_Device_IP, unit_id=Modbus_Device_ID, port=Modbus_Device_Port, debug=debug) c.open() collected = c.read_input_registers(modbus_read_address, 1) value = utils.get_2comp(collected[0], 16) #utils.get_list_2comp to convert a list c.close() if debug: print("Modbus IP=", Modbus_Device_IP, "Modbus ID=", Modbus_Device_ID, "Modbus address=", modbus_read_address, "Value=", value, "Collected=", collected) except: print("Could not read power from Victron modbus") return value
def read_valid_registers(target_ip, port, reg): result = False print(f'\n=====Polling remote server for {reg}:=====') for i in range(start_reg, end_reg): client = ModbusClient(host=target_ip, port=port, auto_open=True, auto_close=True, timeout=10) if reg == "hold": data = client.read_holding_registers(i, 1) if reg == "input": data = client.read_input_registers(i, 1) if reg == "discrete": data = client.read_discrete_inputs(i, 1) if reg == "coil": data = client.read_coils(i, 1) if data: result = True print(f'\nValid Registers {reg} detected at {i} with value {data}') client.close() print('/', end='') sleep(0.1) # return valid_list,data_list,permission_list if result != True: print(f'\n No Valid Registers detected in specified range')
def VICTRON_modbus(Modbus_Device_ID, Modbus_read_address, factor): debug = debugVICTRON Modbus_Device_IP = "192.168.1.190" Modbus_Device_Port = 502 value = 0.0 collected = [0] collected_array = [0] collected_array.pop() if debug: print("Victron Modbus collecting from ID", Modbus_Device_ID, "register", Modbus_read_address) try: c = ModbusClient(host=Modbus_Device_IP, unit_id=Modbus_Device_ID, port=Modbus_Device_Port, debug=debug) c.open() collected = c.read_input_registers(Modbus_read_address, 1) if debug: print("VICTRON collected from modbus=", collected) value = collected[0] value = value / factor if debug: print("Modbus IP=", Modbus_Device_IP, "Modbus ID=", Modbus_Device_ID, "Modbus address=", Modbus_read_address, "Value=", value) c.close() except: print("could not read from SMA Modbus IP=", Modbus_Device_IP, "Modbus ID=", Modbus_Device_ID, "Modbus address=", Modbus_read_address) return value
def read_all_tags(self): try: c = ModbusClient(host="192.168.2.11", port=502, debug=False) c.open() for name, tag in self.tag_db.items(): mb0 = tag['modbus_start'] -1 mb1 = tag['modbus_stop'] -1 size = 1+mb1-mb0 #print(name, mb0, mb1, size) #print(tag) if 0 <= mb0 < 100000: val = c.read_coils(mb0)[0] elif 100000 <= mb0 < 200000: val = c.read_discrete_inputs(mb0-100000)[0] elif 300000 <= mb0 < 400000: val = c.read_input_registers(mb0-300000, size) if size == 1: val = val[0] elif size == 2: val = utils.word_list_to_long(val, big_endian=False)[0] elif 400000 <= mb0 < 500000: val = c.read_holding_registers(mb0-400000, size ) if size == 1: val = val[0] elif size == 2: val = utils.word_list_to_long(val, big_endian=False)[0] if tag['dtype'] == 'float32': val = utils.decode_ieee(val) #print(name, val) self.settings[name] = val except Exception as err: print("Error in read_all_tags", err) c.close()
def Collect_Modbus(Collect_Array): #todo: add try try: c = ModbusClient(host=Modbus_Device_IP, unit_id=Modbus_Device_ID, port=Modbus_Device_Port, debug=False) c.open() for x in range(len(Collect_Array)): collected_array = [0] collected_array.pop() collected = c.read_input_registers(Collect_Array[x][0], Collect_Array[x][1]) collected_merged = struct.pack('>HH', collected[0], collected[1]) collected_array.append(struct.unpack('>i', collected_merged)[0]) #store_url format : (sensor, description, value, metric, timestamp) if collected_array[0] < 100000 and collected_array[0] > -100000: store_url("SMA", Collect_Array[x][3], collected_array, Collect_Array[x][2], datetime.now()) print("SMA", Collect_Array[x][3], collected_array[0], Collect_Array[x][2], datetime.now()) else: store_url("SMA", Collect_Array[x][3], 0, Collect_Array[x][2], datetime.now()) print("unrealistic value detected set value to 0") c.close() except: print("Could not read from modbus")
def routineLoop(): global ac, dados, off for i in ip: #Entra na lista de ip's for x in add[ip.index(i)]: #entra na lista de endereços ac = ModbusClient(host=i, auto_open=True, unit_id=x) readTemp = ac.read_input_registers( 0) #Leitura da temperatura lida pelo ac dados = ac.read_holding_registers(2, 26) if bool(readTemp ) == False: #Se o valor for falso pula para o próximo ac break if dados[0] == 0: off = 1 else: off = 0 resposta = connect( off, int(readTemp[0]), str(i), str(x), str(dados[1]), str(dados[3]), str(dados[2])) #Envia os dados para API e recebe a resposta resposta = json.loads(resposta) print('Recebido: ' + str(resposta)) decisao = decision(dados, resposta) d = datetime.now() print(decisao + " | " + str(d.hour) + ":" + str(d.minute) + ":" + str(d.second)) ac.close()
def make_summary(): SERVER_HOST = "192.168.43.239" SERVER_PORT = 502 SERVER_UNIT_ID = 2 c = ModbusClient() c.host(SERVER_HOST) c.port(SERVER_PORT) c.unit_id(SERVER_UNIT_ID) if not c.is_open(): if not c.open(): print("cannot connect ....") if c.is_open(): # read 54 registers at address 0, store result in regs list regs = c.read_input_registers(0,54) # if success change register value to float if regs: abc = [utils.decode_ieee(f) for f in utils.word_list_to_long(regs)] data = { "Power KWH" : "%0.3f"%abc[0], "Power KVAH" : "%0.3f"%abc[1], "Power KVArP" : "%0.3f"%abc[2], "Power KVArN" : "%0.3f"%abc[3], "Line Voltages V RY" : "%0.3f"%abc[4], "Line Voltages V YB" : "%0.3f"%abc[5], "Line Voltages V BR" : "%0.3f"%abc[6], "Line Current IR" : "%0.3f"%abc[7], "Line Current IY" : "%0.3f"%abc[8], "Line Current IB" : "%0.3f"%abc[9], "Active Power Consumed" : "%0.3f"%abc[10], "Reactive Power Consumed" : "%0.3f"%abc[11], "Apparent Power Consumed" : "%0.3f"%abc[12], "Phase Voltages VRN" : "%0.3f"%abc[13], "Phase Voltages VYN" : "%0.3f"%abc[14], "Phase Voltages VBN" : "%0.3f"%abc[15], "Power Factor" : "%0.3f"%abc[16], "Frequency" : "%0.3f"%abc[17], "Real Power on R" : "%0.3f"%abc[18], "Real Power on Y" : "%0.3f"%abc[19], "Real Power on B" : "%0.3f"%abc[20], "Reactive Power on R" : "%0.3f"%abc[21], "Reactive Power on Y" : "%0.3f"%abc[22], "Reactive Power on B" : "%0.3f"%abc[23], "Apparent Power on R" : "%0.3f"%abc[24], "Apparent Power on Y" : "%0.3f"%abc[25], "Apparent Power on B" : "%0.3f"%abc[26] } mydate = datetime.datetime.now() date=datetime.datetime.strftime(mydate,'%Y/%m/%d--%H:%M:%S') abc.insert(27,date) myfile = open('data.csv','a') with myfile: writer = csv.writer(myfile, delimiter=',', quoting=csv.QUOTE_ALL) writer.writerow(abc) return data
def tcp_function(Porta, Endereco, BaudRate, Registrador, Linhas): TCPIP_MODBUS = ModbusClient() TCPIP_MODBUS.host(Endereco) TCPIP_MODBUS.port(Porta) if not TCPIP_MODBUS.is_open(): if not TCPIP_MODBUS.open(): print('Cannot connect to the Modbus TCP/IP Server/Slave') if TCPIP_MODBUS.is_open(): TCPIP_DATA = TCPIP_MODBUS.read_input_registers(Registrador, Linhas) if TCPIP_DATA: print('TCP/IP successfully read') else: print('Read Errors in TCP/IP Server/Slave') return TCPIP_DATA
def importFromGrid(setPoint, SOCDischarge, SOCCharge): log.write('%02d, %02d, %02d, ' % (setPoint, SOCDischarge, SOCCharge)) #log.write(str(setPoint)+', '+str(SOCDischarge)+', '+str(SOCCharge)+', ') hub4 = ModbusClient() hub4.host(farmIP) hub4.port(hub4Port) hub4.unit_id(hub4Id) inverter = ModbusClient() inverter.host(farmIP) inverter.port(invPort) inverter.unit_id(invId) success = False if inverter.open(): r = inverter.read_input_registers(30, 1) soc = r[0] / 10.0 # convert to a percentage log.write('%.1f, inverter, ' % (soc)) print 'SOC=', (soc) else: log.write('failed to open inverter coms') #sort the chargeing if hub4.open(): success = True if soc < SOCCharge: #allow chargeing at max power set point log.write('charging, ') success = success & hub4.write_single_register(2700, setPoint) else: #battery sufficiently charged set charging power to 0 log.write('not charging, ') success = success & hub4.write_single_register(2700, 0) if soc > SOCDischarge: #allow battery to discharge log.write('discharging, ') success = success & hub4.write_single_register(2702, 100) else: #disallow discharge log.write('not discharging, ') success = success & hub4.write_single_register(2702, 0) hub4.close() log.write('hub4, ') else: log.write('hub4 failed to open hub4 comms') return success
def Collect_Modbus(Device_IP, Device_ID, Device_Port, Collect_Array): c = ModbusClient(host=Device_IP, unit_id=Device_ID, port=Device_Port, debug=False) c.open() collected_array = [0] collected_array.pop() for x in range(len(Collect_Array)): print(x) collected = c.read_input_registers(Collect_Array[x][0], Collect_Array[x][1]) collected_merged = struct.pack('>HH', collected[0], collected[1]) collected_array.append(struct.unpack('>I', collected_merged)[0]) print(collected_array) c.close() return collected_array
class Alicat(Adapter): """Alicat device (e.g. pressure controller) with a Modbus/TCP interface""" def __init__(self, ip_address): super(Alicat, self).__init__(ip_address) self.mb_client = ModbusClient(host=ip_address, timeout=5) def start(self): while True: self.mb_client.open() if self.mb_client.is_open(): break print 'Unable to connect to Alicat device at {}; retrying...'.format( self.ip_address) sleep(1) def stop(self): self.mb_client.close() def read_all(self): if self.a_ins: data = self.mb_client.read_input_registers( self.a_in_range[0], self.a_in_range[1] - self.a_in_range[0] + 1) if not data: raise ConnectionError i0 = self.a_in_range[ 0] # Starting index for looking up values from the data list for d in self.a_ins.values(): if d.length == 2: d.val = data[d.address - i0:d.address - i0 + 2] elif d.length == 1: d.val = data[d.address - i0] def write_all(self): # print 'Write outputs' if self.a_outs: data = [] for d in self.a_outs.values(): if d.length == 2: data += d.raw_array elif d.length == 1: data.append(d.raw_array) self.mb_client.write_multiple_registers(self.a_out_range[0], data)
def victron_modbus_power(): Modbus_Device_IP="192.168.1.190" Modbus_Device_ID="100" Modbus_Device_Port = 502 modbus_read_address = 842 debug=False value = 0.0 try: c= ModbusClient(host=Modbus_Device_IP,unit_id=Modbus_Device_ID,port=Modbus_Device_Port,debug=debug) c.open() collected = c.read_input_registers(modbus_read_address,1) value = utils.get_2comp(collected[0],16)/1000 #utils.get_list_2comp to convert a list c.close() if debug: print("Modbus IP=",Modbus_Device_IP,"Modbus ID=",Modbus_Device_ID,"Modbus address=",modbus_read_address,"Value=",value) #store_url("SMA",Collect_Array[x][3],0,Collect_Array[x][2],datetime.now()) #store_url(sensor, description, value, metric, timestamp) store_url("BAT","power",value,"W",datetime.now()) except: print("Could not read power from Victron modbus") return value
def monitor_register(target_ip, port, address, delay, reg): while True: client = ModbusClient(host=target_ip, port=port, auto_open=True, auto_close=True, timeout=1) if reg == "Holding": data = client.read_holding_registers(address, 1) if reg == "Input": data = client.read_input_registers(address, 1) if reg == "Discrete": data = client.read_discrete_inputs(address, 1) if reg == "Coil": data = client.read_coils(address, 1) if data: print(f'{reg} register at address {address} has value {data}') #print ('.', end='') client.close() sleep(delay)
def read_valid_registers(ip_addr,port,reg): valid_list=[] data_list=[] permission_list=[] client=ModbusClient(host=ip_addr,port=port,auto_open=True,auto_close=True,timeout=10) for i in tqdm(range(1,500)): if reg == "hold": data=client.read_holding_registers(i,1) if reg == "input": data=client.read_input_registers(i,1) if reg == "discrete": data=client.read_discrete_inputs(i,1) if reg == "coil": data=client.read_coils(i,1) if data: valid_list.append(i) data_list.append(data[0]) permission_list.append("Read") client.close() return valid_list,data_list,permission_list
def victron_modbus_bat_status(): Modbus_Device_IP="192.168.1.190" Modbus_Device_ID="225" Modbus_Device_Port = 502 modbus_read_address = 266 debug=False try: collected_array = [0] collected_array.pop() c= ModbusClient(host=Modbus_Device_IP,unit_id=Modbus_Device_ID,port=Modbus_Device_Port,debug=debug) c.open() collected = c.read_input_registers(modbus_read_address,1) collected[0] = collected[0]/10 if debug: print("Modbus IP=",Modbus_Device_IP,"Modbus ID=",Modbus_Device_ID,"Modbus address=",modbus_read_address,"Value=",collected[0]) c.close() #store_url("SMA",Collect_Array[x][3],0,Collect_Array[x][2],datetime.now()) #store_url(sensor, description, value, metric, timestamp) store_url("BAT","Battery level",collected[0],"Percent",datetime.now()) except: print("Could not read battery level from Victron modbus")
def SMA_modbus(Collect_Array): debug = debugSMA #define variables #Modbus_Device_IP = "192.168.1.170" Modbus_Device_IP = "192.168.0.237" Modbus_Device_ID = "3" Modbus_Device_Port = 502 generated = 0.0 collected = [0] collected_array = [0] collected_array.pop() if debug: print("SMA collecting from ID", Modbus_Device_ID, "register", Collect_Array[1]) try: c = ModbusClient(host=Modbus_Device_IP, unit_id=Modbus_Device_ID, port=Modbus_Device_Port, debug=debug) c.open() collected = c.read_input_registers(Collect_Array[0], Collect_Array[1]) c.close() if debug: print("SMA collected from modbus=", collected) collected_merged = struct.pack('>HH', collected[0], collected[1]) collected_array.append(struct.unpack('>i', collected_merged)[0]) if collected_array[0] < 100000 and collected_array[0] > -100000: if debug: print("SMA debug", collected, collected_array) generated = collected_array[0] else: generated = 0.0 if debug: print("unrealistic value detected set value to 0") except: print("Could not read from SMA Modus IP=", Modbus_Device_IP, "DeviceID=", Modbus_Device_ID, "Port=", Modbus_Device_Port, "Register=", Collect_Array) return generated
def run_gui(): global x, y, x1, y1 # Declaring Modbus PLC print("The IP address of the PLC is:", sys.argv[1]) #Declaring the modbus client try: client = ModbusClient(host=sys.argv[1], port=502) except ValueError: print("Error with host or port number") # Declaring the colors required int he graphics. This is in RGB format BLACK = (0, 0, 0) GREY = (169, 169, 169) BLUE = (0, 0, 255) GREEN = (0, 255, 0) RED = (255, 0, 0) # Drawing the robotic arm in pygame. The one time initilization is performed to use the Pygame instance pygame.init() size = [600, 600] screen = pygame.display.set_mode(size) pygame.display.set_caption("Robotic Arm-Rishabh Das-UAH") message = pygame.font.SysFont("monospace", 15) header = pygame.font.SysFont("monospace", 30) run = True # This is the main loop that gets the current position of the robotic arm and updates the graphics after # every 100 ms while run: # ----------------------------------------------------------------------------------------- # MODBUS Section of the loop. The reading of the registers are collected fromt he PLC memory # ----------------------------------------------------------------------------------------- # check the connectivity of the TCP client to the GUI to the PLC if not client.is_open(): if not client.open(): print("Unable to Connect to " + sys.argv[1] + ":502") # Reading the registers for current lengths and the thetas theta_list = client.read_input_registers(2, reg_nb=2) length_list = client.read_holding_registers(4, reg_nb=2) # Print the list of the thetas # print(theta_list) # print(length_list) # Get the length of the arms from the MODBUS memory of the PLC to local variables length_1 = length_list[0] length_2 = length_list[1] if length_1 != 0 and length_2 != 0: ratio = (length_1 / length_2) else: print("Warning! \nArm length set to 0") if length_1 != 0: #Dulplicate arm length value length_2 = length_1 elif length_2 != 0: #Dulplicate arm length value length_1 = length_2 else: #Default Values of the Robotic arm length length_1 = 10 length_2 = 10 ratio = (length_1 / length_2) # sys.exit(0) length_2 = 250 / (ratio + 1) length_1 = 250 - length_2 if length_1 > 0 and length_2 > 0: # Get the current Theta positions of the arms from the MODBUS memory of the PLC to local variables Theta_1 = theta_list[0] Theta_2 = theta_list[0] + theta_list[1] # Calculate the coordinates calculate_coordinates(length_1, length_2, Theta_1, Theta_2) # ----------------------------------------------------------------------------------------- # This section of the loop creates the GUI of the robotic arm using the pygame library # ----------------------------------------------------------------------------------------- screen.fill(BLACK) # Drawing the robotic arm in pygame pygame.draw.line(screen, GREEN, [275, 275], [275 + x1, 275 - y1], 5) pygame.draw.line(screen, GREEN, [275 + x1, 275 - y1], [275 + x, 275 - y], 5) pygame.draw.circle(screen, BLUE, [275, 275], 7) pygame.draw.circle(screen, BLUE, [275 + round(x1), 275 - round(y1)], 7) pygame.draw.circle(screen, BLUE, [275 + round(x), 275 - round(y)], 7) # Calculate the coordinates calculate_coordinates(length_list[0], length_list[1], Theta_1, Theta_2) disp_coor1 = message.render( "(" + str(int(x1)) + "," + str(int(y1)) + ")", 1, GREEN) disp_coor2 = message.render( "(" + str(int(x)) + "," + str(int(y)) + ")", 1, GREEN) calculate_coordinates(length_1, length_2, Theta_1, Theta_2) screen.blit(disp_coor1, (275 + round(x1), 275 - round(y1))) screen.blit(disp_coor2, (275 + round(x), 275 - round(y))) #Displaying Heading title = header.render("Robotic Arm", 1, GREEN) screen.blit(title, (10, 1)) #Displaying Theta values theta1_values = message.render( "Theta first joint:" + str(theta_list[0]), 1, GREEN) theta2_values = message.render( "Theta second joint:" + str(theta_list[1]), 1, GREEN) screen.blit(theta1_values, (400, 550)) screen.blit(theta2_values, (400, 570)) # Checking if the user clicked on the close button for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() run = False sys.exit(0) pygame.display.update() #Controls the refresh rate of the robotic arm time.sleep(0.05) else: print("Invalid length! The GUI cannot be rendered!") sys.exit(0)
print(reg_1) return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_1)] else: return None def write_float(self, address, floats_list): b32_1 = [utils.encode_ieee(f) for f in floats_list] b16_1 = utils.long_list_to_word(b32_1) return self.write_multiple_registers(address, b16_1) try: print("Connecting to SEL Meter...") sel = ModbusClient(host=hosts[0], port=ports[0], auto_open=True) if sel:print("Connected!") while sel.open(): try: ia = sel.read_input_registers(350,2) #print(ia) IA = int('0b'+bin(ia[0])[2:]+bin(ia[1])[2:].zfill(16),2)/100.0 print("IA is",IA,"Amps") ib = sel.read_input_registers(352,2) IB = int('0b'+bin(ib[0])[2:]+bin(ib[1])[2:].zfill(16),2)/100.0 print("IB is",IB,"Amps") ic = sel.read_input_registers(354,2) IC = int('0b'+bin(ic[0])[2:]+bin(ic[1])[2:].zfill(16),2)/100.0 print("IC is",IC,"Amps") w3 = sel.read_input_registers(370,2) W3 = int('0b'+bin(w3[0])[2:]+bin(w3[1])[2:].zfill(16),2)/100.0 print("W3 is",W3,"kW\n") ''' u3 = sel.read_input_registers(372,2) U3 = int('0b'+bin(u3[0])[2:]+bin(u3[1])[2:],2)/100.0
class Device(): def __init__(self, host, port, timeout, byteorder=BE): # big_endian : Byte order of the device memory structure # True >> big endian # False >> little endian if byteorder == BE: self.big_endian=True else: self.big_endian=False self.dev = ModbusClient() self.dev.host(host) self.dev.port(port) self.dev.timeout(timeout) self.dev.open() #self.dev.debug = True #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ READ METHODS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# #Method to read binary variable def read_bits(self, VarNameList, AddressList, functioncode=2): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # functioncode : functioncode for modbus reading operation # 1 >> for Discrete Output (Coils) # 2 >> for Discrete Input # Return : dictionary of variable name and its value self.values = [] if functioncode == 1: for address in AddressList: self.values.extend(self.dev.read_coils(address[0], len(address))) elif functioncode == 2: for address in AddressList: self.values.extend(self.dev.read_discrete_inputs(address[0], len(address))) self.Result = dict(zip(VarNameList, self.values)) return self.Result #Method to read INT16 or UINT16 variable def read_INT16(self, VarNameList, AddressList, MultiplierList, signed=False, roundto=3, functioncode=3): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # MultiplierList : list of multiplier # roundto : number of digits after decimal point # any positive integer number >> to limit the number of digits after decimal point # None >> to disable # signed : True >> for signed values # False >> for unsigned values # functioncode : functioncode for modbus reading operation # 3 >> for Holding Register # 4 >> for Input Register # Return : dictionary of variable name and its value self.values = [] if functioncode == 3: for address in AddressList: self.values.extend(self.dev.read_holding_registers(address[0],len(address))) elif functioncode == 4: for address in AddressList: self.values.extend(self.dev.read_input_registers(address[0],len(address))) if signed: self.values = UINT16toINT16(self.values) for i in range(0, len(self.values)): self.values[i] = round(self.values[i]*MultiplierList[i],roundto) self.Result = dict(zip(VarNameList, self.values)) return self.Result #Method to read INT32 or UINT32 variable def read_INT32(self, VarNameList, AddressList, MultiplierList, signed=False, roundto=3, functioncode=3): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # MultiplierList : list of multiplier # roundto : number of digits after decimal point # any positive integer number >> to limit the number of digits after decimal point # None >> to disable # signed : True >> for signed values # False >> for unsigned values # functioncode : functioncode for modbus reading operation # 3 >> for Holding Register # 4 >> for Input Register # Return : dictionary of variable name and its value self.values = [] if functioncode == 3: for address in AddressList: self.values.extend(self.dev.read_holding_registers(address[0],len(address))) elif functioncode == 4: for address in AddressList: self.values.extend(self.dev.read_input_registers(address[0],len(address))) self.values = UINT16toINT32(self.values, self.big_endian, signed) for i in range(0, len(self.values)): self.values[i] = round(self.values[i]*MultiplierList[i], roundto) self.Result = dict(zip(VarNameList, self.values)) return self.Result #Method to read INT64 or UINT64 variable def read_INT64(self, VarNameList, AddressList, MultiplierList, signed=False, roundto=3, functioncode=3): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # MultiplierList : list of multiplier # roundto : number of digits after decimal point # any positive integer number >> to limit the number of digits after decimal point # None >> to disable # signed : True >> for signed values # False >> for unsigned values # functioncode : functioncode for modbus reading operation # 3 >> for Holding Register # 4 >> for Input Register # Return : dictionary of variable name and its value self.values = [] if functioncode == 3: for address in AddressList: self.values.extend(self.dev.read_holding_registers(address[0],len(address))) elif functioncode == 4: for address in AddressList: self.values.extend(self.dev.read_input_registers(address[0],len(address))) self.values = UINT16toINT64(self.values, self.big_endian, signed) for i in range(0, len(self.values)): self.values[i] = round(self.values[i]*MultiplierList[i], roundto) self.Result = dict(zip(VarNameList, self.values)) return self.Result #Method to read FLOAT16 variable def read_FLOAT16(self, VarNameList, AddressList, MultiplierList, roundto=3, functioncode=3): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # MultiplierList : list of multiplier # roundto : number of digits after decimal point # any positive integer number >> to limit the number of digits after decimal point # None >> to disable # functioncode : functioncode for modbus reading operation # 3 >> for Holding Register # 4 >> for Input Register # Return : dictionary of variable name and its value self.values = [] if functioncode == 3: for address in AddressList: self.values.extend(self.dev.read_holding_registers(address[0],len(address))) elif functioncode == 4: for address in AddressList: self.values.extend(self.dev.read_input_registers(address[0],len(address))) self.values = UINT16toFLOAT16(self.values) for i in range(0, len(self.values)): self.values[i] = round(self.values[i]*MultiplierList[i], roundto) self.Result = dict(zip(VarNameList, self.values)) return self.Result #Method to read FLOAT32 variable def read_FLOAT32(self, VarNameList, AddressList, MultiplierList, roundto=3, functioncode=3): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # MultiplierList : list of multiplier # roundto : number of digits after decimal point # any positive integer number >> to limit the number of digits after decimal point # None >> to disable # functioncode : functioncode for modbus reading operation # 3 >> for Holding Register # 4 >> for Input Register # Return : dictionary of variable name and its value self.values = [] if functioncode == 3: for address in AddressList: self.values.extend(self.dev.read_holding_registers(address[0],len(address))) elif functioncode == 4: for address in AddressList: self.values.extend(self.dev.read_input_registers(address[0],len(address))) self.values = UINT16toFLOAT32(self.values, self.big_endian) for i in range(0, len(self.values)): self.values[i] = round(self.values[i]*MultiplierList[i], roundto) self.Result = dict(zip(VarNameList, self.values)) return self.Result #Method to read FLOAT64 variable def read_FLOAT64(self, VarNameList, AddressList, MultiplierList, roundto=3, functioncode=3): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # MultiplierList : list of multiplier # roundto : number of digits after decimal point # any positive integer number >> to limit the number of digits after decimal point # None >> to disable # functioncode : functioncode for modbus reading operation # 3 >> for Holding Register # 4 >> for Input Register # Return : dictionary of variable name and its value self.values = [] if functioncode == 3: for address in AddressList: self.values.extend(self.dev.read_holding_registers(address[0],len(address))) elif functioncode == 4: for address in AddressList: self.values.extend(self.dev.read_input_registers(address[0],len(address))) self.values = UINT16toFLOAT64(self.values, self.big_endian) for i in range(0, len(self.values)): self.values[i] = round(self.values[i]*MultiplierList[i], roundto) self.Result = dict(zip(VarNameList, self.values)) return self.Result #Method to read STRING variable def read_STRING(self, VarNameList, AddressList, functioncode=3): # Arguments: # VarNameList : list of variable name # AddressList : list of variable register address in decimal (relative address) # functioncode : functioncode for modbus reading operation # 3 >> for Holding Register # 4 >> for Input Register # Return : dictionary of variable name and its value self.values = [] if functioncode == 3: for address in AddressList: _uint16Val = self.dev.read_holding_registers(address[0],len(address)) self.values.append(UINT16toSTRING(_uint16Val, self.big_endian)) elif functioncode == 4: for address in AddressList: _uint16Val = self.dev.read_input_registers(address[0],len(address)) self.values.append(UINT16toSTRING(_uint16Val, self.big_endian)) self.Result = dict(zip(VarNameList, self.values)) return self.Result #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WRITE METHODS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Method to write binary value on discrete output register (Coil) def write_bit(self, registerAddress, value): # Arguments: # registerAddress : register address in decimal (relative address) # value : 0 or 1 self.dev.write_single_coil(registerAddress, value) # Method to write numeric value on holding register def write_num(self, registerAddress, value, valueType): # Arguments: # registerAddress : register START address in decimal (relative address) # value : numerical value # valueType : UINT16, UINT32, UINT64, INT16, INT32, INT64, FLOAT16, # FLOAT32, FLOAT64, STRING startAddress = registerAddress val = None if valueType == UINT16: val = [value] elif valueType == INT16: val = INT16toUINT16([value]) elif valueType == UINT32: val = INT32toUINT16(value, self.big_endian, signed=False) elif valueType == INT32: val = INT32toUINT16(value, self.big_endian, signed=True) elif valueType == UINT64: val = INT64toUINT16(value, self.big_endian, signed=False) elif valueType == INT64: val = INT64toUINT16(value, self.big_endian, signed=True) elif valueType == FLOAT16: val = FLOAT16toUINT16([value]) elif valueType == FLOAT32: val = FLOAT32toUINT16(value, self.big_endian) elif valueType == FLOAT64: val = FLOAT64toUINT16(value, self.big_endian) elif valueType == STRING: val = STRINGtoUINT16(value, self.big_endian) # write multiple registers self.dev.write_multiple_registers(startAddress, val) def close(self): self.dev.close()
while True: # open or reconnect TCP to server if not c.is_open(): if not c.open(): print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT)) # if open() is ok, read register (modbus function 0x03) if c.is_open(): print( "hourmeter, alarm_daily, load_fault_daily, array_fault_daily, Vb_min_daily, Vb_max_daily, Ahc_daily, Ahl_daily, Va_max_daily, Time in Absorption(HR)), Time in Equalize(HR), Time in Float(HR)" ) varhex = "0x8000" for i in range(0, 255): i = int(varhex, 16) regs = c.read_input_registers(i, 17) hourmeter = regs[0] + ((regs[1] & 0x00FF) << 32) print(hourmeter, end=",") alarm = (regs[3] << 16) + (regs[2] >> 16) if alarm == 0: print("No alarms", end=",") elif (alarm & 1): print("RTS OPEN", end=",") elif ((alarm & (1 << 1)) >> 1): print("RTS shorted", end=",") elif ((alarm & (1 << 2)) >> 2): print("RTS Disconnected", end=",") elif ((alarm & (1 << 3)) >> 3): print("Ths (heatsink temp sensor) Open", end=",") elif ((alarm & (1 << 4)) >> 4):
newDataset = dataset.iloc[0:Number_of_Measurements] print(newDataset.index) #print(newDataset.values) PV_KW_list = newDataset['KW'].tolist() #extracting list out of the values column del PV_KW_list[-1] #deleting last item cause it is NaN PV_KW_list = [ int(x) for x in PV_KW_list ] #converting into a list of integers #print(PV_KW_list) # used for debugging #print(str(len(PV_KW_list))) # open or reconnect TCP to server if not c.is_open(): if not c.open(): print("Unable to connect to "+SERVER_HOST+":"+str(SERVER_PORT)) # if open() is ok, write the registers with the PV generation values if c.is_open(): print("Database Client Connected to Server") #list_int = c.read_input_registers(0, (len(PV_KW_list)-1)) list_int = c.read_input_registers(0, len(PV_KW_list)) if list_int: print("Registers addresses #0 to #"+str(len(PV_KW_list))+": "+str(list_int)) for addr in range(len(PV_KW_list)): is_ok = c.write_single_register(addr, PV_KW_list[addr]) if is_ok: print("register #" + str(addr) + ": write [PV gen (KW)] to " + str(PV_KW_list[addr])) else: print("resgister #" + str(addr) + ": unable to write " + str(PV_KW_list[addr])) print("Finish writing "+ str(addr+1) +" resgisters with PV data measurements") # closing TCP connection after writing all registers c.close()
c = ModbusClient() # define modbus server host, port c.host(args.modbus_host) c.port(args.modbus_port) while True: # open or reconnect TCP to server if not c.is_open(): if not c.open(): logging.error("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT)) data = [] for key, value in inputRegisters.items(): if c.is_open(): row = c.read_input_registers(int(value)) row.insert(0, key) data.append(row) for key, value in holdingRegisters.items(): if c.is_open(): row = c.read_holding_registers(int(value)) row.insert(0, key) data.append(row) elements = [] for row in data: e = Element(row) elements.append(e)
# Reference: http://pythonhosted.org/pyModbusTCP/quickstart/index.html#utils-module-modbus-data-mangling from pyModbusTCP.client import ModbusClient from pyModbusTCP import utils c = ModbusClient(host="192.168.1.35", port=502, unit_id=30, auto_open=True) c.open() if not c.is_open(): raise Exception("could not connect") list_16_bits = c.read_input_registers(211, 2) list_32_bits = utils.word_list_to_long(list_16_bits) c.close()
class ClientGUI: def __init__(self): self.lock = RLock() self.calibgui = None self.client = ModbusClient() self.register_values_widgets = {} self.counter = 1 self.find_thread = None self.obj_data = None self.stop_signal = False self.__build_ui() def run_ui(self): self.root.mainloop() def __build_ui(self): # ui hierarchy: # #root # connectframe # connectlabel # connectbutton # snapshotbutton # calibbuton # mainframe # registerframe # reglabel # registergridframe # ... # outputframe # outputlabel # outputtext root = Tk() self.root = root root.wm_title("RemoteSurf Modbus Client") root.protocol("WM_DELETE_WINDOW", self.__delete_window) self.font = tkFont.Font(root = root, family = "Helvetica", size = 12) connectframe = Frame(root) connectbutton = Button(connectframe, text = "Connect", command = self.__connectbutton_click) connectlabel = Label(connectframe, text = "Not connected.") calibbutton = Button(connectframe, text = "Calibrate", command = self.__calibbutton_click) homebutton = Button(connectframe, text = "Home", command = self.__homebutton_click) findbutton = Button(connectframe, text = "Find", command = self.__findbutton_click) mainframe = Frame(root) registerframe = Frame(mainframe) reglabel = Label(registerframe, text = "Set registers") registergridframe = Frame(registerframe) # outputframe = Frame(mainframe) # outputlabel = Label(outputframe, text = "Output") # vscrollbar = Scrollbar(outputframe) # hscrollbar = Scrollbar(outputframe) # outputtext = ThreadSafeConsole(outputframe, root, vscrollbar, font = self.font, wrap = NONE) connectframe.pack(side = TOP, fill = X) connectlabel.pack(side = BOTTOM, anchor = W) homebutton.pack(side = RIGHT) findbutton.pack(side = RIGHT) calibbutton.pack(side = RIGHT) connectbutton.pack(side = RIGHT) mainframe.pack(side = BOTTOM, fill = BOTH, expand = YES) registerframe.pack(side = TOP, expand = YES, anchor = W) # outputframe.pack(side = BOTTOM, fill = BOTH, expand = YES) reglabel.pack(side = TOP, anchor = CENTER) registergridframe.pack(side = BOTTOM, anchor = W) # registerframe.config(bg = "cyan") # mainframe.config(bg = "pink") # registergridframe.config(bg = "red") registergridframe.columnconfigure(0, weight = 1) registergridframe.columnconfigure(1, weight = 1) registergridframe.columnconfigure(2, weight = 1) registergridframe.columnconfigure(3, weight = 1) self.x_pad = 10 registergrid_widgets = [] titles = ["Address", "Label", "Value", ""] col = 0 for title in titles: title_label = Label(registergridframe, text = title) title_label.grid(row = 0, column = col, padx = self.x_pad) registergrid_widgets.append(title_label) col += 1 registers_data = [(500, "x"), (501, "y"), (502, "z"), (503, "A"), (504, "B"), (505, "C"), ] for i in range(len(registers_data)): reg_data = registers_data[i] row = i + 1 self.__add_register(registergridframe, reg_data, row, registergrid_widgets) # hscrollbar.config(orient = HORIZONTAL, command = outputtext.xview) # hscrollbar.pack(side = BOTTOM, fill = X) # outputtext.config(state = DISABLED, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set) #must change to NORMAL before writing text programmatically # outputtext.pack(side = LEFT, fill = BOTH, expand = YES, padx = x_padding, pady = y_padding) # vscrollbar.config(command = outputtext.yview) # vscrollbar.pack(side = RIGHT, fill = Y) self.connectframe = connectframe self.connectlabel = connectlabel self.connectbutton = connectbutton self.mainframe = mainframe self.registerframe = registerframe self.reglabel = reglabel self.registergridframe = registergridframe self.calibbutton = calibbutton # self.outputframe = outputframe # self.outputlabel = outputlabel # self.vscrollbar = vscrollbar # self.hscrollbar = hscrollbar # self.outputtext = outputtext root.update() w, h = root.winfo_width(), root.winfo_height() root.minsize(w, h) x, y = MAINFRAME_POS root.geometry('%dx%d+%d+%d' % (w, h, x, y)) def __homebutton_click(self): values = { 500: 300, 501: 0, 502: 500, 503: 180, 504: 0, 505: 180, } self.set_values(values, go_to_value = False) def __add_register(self, master, data, row, widget_list): regaddresslabel = Label(master, text=str(data[0])) regaddresslabel.grid(row=row, column=0) reglabellabel = Label(master, text=data[1]) reglabellabel.grid(row=row, column=1) regvalueentry = AccessibleEntry(master, justify = RIGHT) regvalueentry.set("0") regvalueentry.grid(row=row, column=2, padx=self.x_pad) regsetbtn = Button(master, text="Set", command = self.__setbutton_click) regsetbtn.grid(row=row, column=3) widget_list.append(regaddresslabel) widget_list.append(reglabellabel) widget_list.append(regvalueentry) widget_list.append(regsetbtn) self.register_values_widgets[data[0]] = (0, regvalueentry) def __calibbutton_click(self): if not self.calibgui: self.calibgui = CalibGUI(self) def __findbutton_click(self): if self.find_thread is None: self.find_thread = Thread(target=self.__find_object) self.find_thread.start() def __find_object(self): import DataCache as DC from glob import glob from os.path import join import numpy as np from SFMSolver import SFMSolver, find_ext_params import Utils print "FINDING" np.set_printoptions(precision=3, suppress=True) files_dir = "out/2017_3_8__14_51_22/" files = glob(join(files_dir, "*.jpg")) masks = [] for f in files: m = f.replace(".jpg", "_mask.png") masks.append(m) sfm = SFMSolver(files, masks) if self.obj_data is None: imgs, kpts, points, data = sfm.calc_data_from_files_triang_simple() self.obj_data = imgs, kpts, points, data else: imgs, kpts, points, data = self.obj_data arr_calib = DC.getData("out/%s/arrangement_calib.p" % ARRANGEMENT_CALIB_DIR) ttc = arr_calib["ttc"] tor = arr_calib["tor"] if "cam_mtx" in arr_calib: print "camMtx, distcoeffs load" Utils.camMtx = arr_calib["cam_mtx"] Utils.dist_coeffs = arr_calib["dist_coeffs"] if self.stop_signal: self.stop_signal = False return for point in FIND_POINTS: values = { 500: point[0], 501: point[1], 502: point[2], 503: point[3], 504: point[4], 505: point[5], } print "set_values call" self.set_values(values, True) print "set_values return" time.sleep(0.5) CamGrabber.capture_if_no_chessboard = True CamGrabber.capture = True time.sleep(0.5) if self.stop_signal: self.stop_signal = False return find_dir = logger.outputdir files = glob("%s/*.jpg" % find_dir) print files # files_dir = "out/2017_4_5__15_57_20/" # files = glob(join(files_dir, "*.jpg")) files.sort() files = files[-len(FIND_POINTS):] results = [] for f in files: res = find_ext_params(f, imgs, kpts, points, data, tor, ttc) results.append(res) if self.stop_signal: self.stop_signal = False return for i in range(len(results)): print i, results[i] write_log((i, results[i])) result = max(results, key=lambda x: x[2]) write_log(result) values = { 500: int(result[0][0] * 10), 501: int(result[0][1] * 10), 502: int(result[0][2] * 10) + 200, 503: int(result[1][2]), 504: int(result[1][1]), 505: int(result[1][0]), } print "num inl: ", result[2] pprint(values) self.set_values(values, go_to_value=False) self.find_thread = None def __connectbutton_click(self): if self.client.is_open(): self.client.close() else: self.client.host(SERVER_HOST) self.client.port(SERVER_PORT) if self.client.open(): write_log("Connection established") self.refresh_values() self.read_robot_pos() else: write_log("ERROR: Connecting failed") self.__update_gui() def read_robot_pos(self): write_log("Reading robot position:") posdict = {} for i in range(1000, 1006): if self.client.is_open(): with self.lock: real_val_uint = self.client.read_input_registers(i)[0] real_val_holding_uint = self.client.read_holding_registers(i)[0] assert real_val_uint == real_val_holding_uint real_val_int = uintToInt16(real_val_uint) posdict[i] = real_val_int write_log("%d, %d" % (i, real_val_int)) else: write_log("ERROR: Read could not be completed, client not connected.") self.__update_gui() break write_log("Read done.") return posdict def refresh_values(self): for address in self.register_values_widgets: if self.client.is_open(): value, widget = self.register_values_widgets[address] with self.lock: real_val_uint = self.client.read_input_registers(address)[0] real_val_holding_uint = self.client.read_holding_registers(address)[0] assert real_val_uint == real_val_holding_uint real_val_int = uintToInt16(real_val_uint) widget.set(str(real_val_int)) self.register_values_widgets[address] = (real_val_int, widget) else: write_log("ERROR: Read could not be completed, client not connected.") self.__update_gui() break write_log("Refresh done.") return self.register_values_widgets def __update_gui(self): if self.client.is_open(): self.connectlabel.config(text = "Connected to: %s:%d" % (SERVER_HOST, SERVER_PORT)) self.connectbutton.config(text = "Disconnect") else: self.connectbutton.config(text = "Connect") self.connectlabel.config(text = "Not connected.") self.root.update() def __print_memory(self): self.refresh_values() write_log("Memory dump:") write_log("------------") for address in self.register_values_widgets: val, widget = self.register_values_widgets[address] write_log("%d, %d" % (address, val)) write_log("------------") def __setbutton_click(self, wait = False): if not self.client.is_open(): write_log("ERROR: Not connected to client") return # writing message counter retval = self.__write_register(COUNTER_REGISTER_OUT, self.counter) if not retval: self.__update_gui() return # writing registers for address in self.register_values_widgets: value, widget = self.register_values_widgets[address] widgetvalue_int = None try: widgetvalue_int = int(widget.get()) except ValueError: write_log("ERROR: Wrong input format in value entry for address: %d" % address) continue if value == widgetvalue_int: continue retval = self.__write_register(address, widgetvalue_int) if retval: self.register_values_widgets[address] = (widgetvalue_int, widget) else: self.__update_gui() self.refresh_values() # message counter wait if wait: global break_wait while not break_wait: with self.lock: counter = self.client.read_input_registers(COUNTER_REGISTER_IN)[0] if counter == self.counter: break time.sleep(0.1) break_wait = False # counter increment self.counter = (self.counter + 1) % 20 if PRINT_ALL_MEMORY_ON_WRITE: self.__print_memory() self.read_robot_pos() def __write_register(self, address, value): if not (-32768 <= value <= 32767): write_log("ERROR: -32768 <= value <= 32767 is false for address: %d" % address) return False widgetvalue_uint = intToUint16(value) if self.client.is_open(): with self.lock: retval = self.client.write_single_register(address, widgetvalue_uint) if retval: write_log("Register written. Address: %d, value: %d" % (address, value)) return True else: write_log("ERROR: Write failed. Address: %d, value: %d" % (address, value)) else: write_log("ERROR: client not connected.") return False def set_values(self, values, wait = True, go_to_value = True): """ :param values: dictionary of { address : value} both int :return: """ for address in values: if address not in self.register_values_widgets: continue val, widget = self.register_values_widgets[address] widget.set(str(values[address])) if go_to_value: self.__setbutton_click(wait) def __delete_window(self): CamGrabber.exit = True self.stop_signal = True self.client.close() self.root.quit()
class Modbus(): def __init__(self, smarthome, gateway_ip, gateway_port=502, gateway_id=1, update_cycle=60): logger.info("Modbus: init plugin") self._sh = smarthome self._gateway_id = int(gateway_id) self._update_cycle = int(update_cycle) self._keylist = {} #self._client = ModbusTcpClient(gateway_ip,port=gateway_port) self._client = ModbusClient(host=gateway_ip, port=gateway_port, auto_open=True, auto_close=True) self._client.unit_id(2) self._client.debug(True) if not self._client.is_open(): if not self._client.open(): logger.error("Modbus: connection to gateway can not be established") else: logger.info("Modbus: connection to gateway established") self._client.close() def run(self): self.alive = True self._sh.scheduler.add('MODBUS', self._update_values, prio=5, cycle=self._update_cycle) def stop(self): self.alive = False self._sh.scheduler.remove('MODBUS') def parse_item(self, item): if 'modbus_gateway_id' in item.conf: gateid = int(item.conf['modbus_gateway_id']) else: gateid = 1 if gateid != self._gateway_id: #logger.debug("Modbus: parse item error (gateway_id is not configured as plugin): {0}".format(item)) return None if 'modbus_cmd' not in item.conf: #logger.debug("Modbus: parse item error (modbus_cmd missing): {0}".format(item)) return None if 'modbus_scaling' not in item.conf: #logger.debug("Modbus: parse item error (modbus_scaling missing): {0}".format(item)) return None if 'modbus_register' in item.conf: logger.debug("Modbus: parse item: {0}".format(item)) register = item.conf['modbus_register'] if not register in self._keylist: self._keylist[register] = {'items': [item], 'logics': []} else: self._keylist[register]['items'].append(item) return None # return self.update_item #else: # return None def parse_logic(self, logic): pass def _update_values(self): for register in self._keylist: for item in self._keylist[register]['items']: if int(item.conf['modbus_cmd']) == 4: reg_list = self._client.read_input_registers(int(item.conf['modbus_register'])-30001, 1) logger.info("Modbus: Plain value: {}".format(str(reg_list[0]))) if reg_list is None: return None if len(reg_list) > 0: phys_value = reg_list[0] / (int(item.conf['modbus_scaling']))# * pow(10, int(item.conf['modbus_decimal'])) logger.info("Modbus: Physical value: {0}".format(phys_value)) item(phys_value, 'MODBUS', ' {0}'.format(phys_value)) elif int(item.conf['modbus_cmd']) == 6: sendvalue = int(item()*int(item.conf['modbus_scaling'])) reg_list = self._client.write_single_register(int(item.conf['modbus_register'])-40001, sendvalue) if not reg_list: logger.info("Modbus: Error writing register") def update_item(self, item, caller=None, source=None, dest=None): if caller != 'MODBUS': logger.info("update item: {0}".format(item.id())) if int(item.conf['modbus_cmd']) == 4: reg_list = self._client.read_input_registers(int(item.conf['modbus_register'])-30001, 1) logger.info("Modbus: Plain value: {}".format(str(reg_list[0]))) if reg_list is None: return None if len(reg_list) > 0: phys_value = reg_list[0] / (int(item.conf['modbus_scaling']))# * pow(10, int(item.conf['modbus_decimal'])) logger.info("Modbus: Physical value: {0}".format(phys_value)) item(phys_value, 'MODBUS', ' {0}'.format(phys_value))
from pyModbusTCP.client import ModbusClient c = ModbusClient(host="192.168.127.247", port=502, auto_open=True, auto_close=True) regs = c.read_input_registers(12, 4) if regs: print("Temps:\n1: " + str(regs[0] / 10) + "\n2: " + str(regs[1] / 10) + "\n3: " + str(regs[2] / 10) + "\n4: " + str(regs[3] / 10)) else: print("read error")
def main(): """ Nome: main Entradas: Sem parâmetros de entrada. Função: É a principal função do programa principal. Realiza o manejo de informações entre o inversor de frequência, e salva os dados no InfluxDB. Objetos: Client_ModBus (Objeto responsável pela comunicação ModBus TCP/IP). Client_MQTT (Objeto responsável pela comunicação com o Banco de Dados na rede externa, no CPD) Variáveis: Terminal de Potência | Especificação do Terminal | Tipo de Variável | Momento de medição | Unidade | Nome da Variável Grid | 3Phase | DeliveredEnergy | LastReset | kWh | Grid_3Phase_DeliveredEnergy_LastReset_kWh Grid | 3Phase | DaylyEnergy | Today | kWh | Grid_3Phase_DaylyEnergy_Today_kWh Grid | Phase1 | RMSVoltage | Instant | V | Grid_Phase1_RMSVoltage_Instant_V Grid | Phase2 | RMSVoltage | Instant | V | Grid_Phase2_RMSVoltage_Instant_V Grid | Phase3 | RMSVoltage | Instant | V | Grid_Phase3_RMSVoltage_Instant_V Grid | 3Phase | Delivered_Aparent_Power | Instant | VA | Grid_3Phase_Delivered_Aparent_Power_Instant_VA Grid | 3Phase | OutputActivePower | Instant | W | Grid_3Phase_OutputActivePower_Instant_W PV_Input | Total | InputCurrent | Instant | A | PV_Input_Total_InputCurrent_Instant_A Grid | Phase1 | RMSCurrent | Instant | A | Grid_Phase1_RMSCurrent_Instant_A Grid | Phase2 | RMSCurrent | Instant | A | Grid_Phase2_RMSCurrent_Instant_A Grid | Phase3 | RMSCurrent | Instant | A | Grid_Phase3_RMSCurrent_Instant_A Grid | 3Phase | OutputReactiveower | LastReset | VAr | Grid_3Phase_OutputReactivePower_LastReset_VAr Grid | 3Phase | DaylyReactiveEnergy | Today | kVArh | Grid_3Phase_DaylyReactiveEnergy_Today_kVArh PVDCInput | String1 | InputCurrent | Instant | A | PVDCInput_String1_InputCurrent_Instant_A PVDCInput | String2 | InputCurrent | Instant | A | PVDCInput_String2_InputCurrent_Instant_A PVDCInput | String3 | InputCurrent | Instant | A | PVDCInput_String3_InputCurrent_Instant_A PVDCInput | String4 | InputCurrent | Instant | A | PVDCInput_String4_InputCurrent_Instant_A PVDCInput | String5 | InputCurrent | Instant | A | PVDCInput_String5_InputCurrent_Instant_A PVDCInput | String6 | InputCurrent | Instant | A | PVDCInput_String6_InputCurrent_Instant_A PVDCInput | String7 | InputCurrent | Instant | A | PVDCInput_String7_InputCurrent_Instant_A PVDCInput | String8 | InputCurrent | Instant | A | PVDCInput_String8_InputCurrent_Instant_A PVDCInput | String9 | InputCurrent | Instant | A | PVDCInput_String9_InputCurrent_Instant_A PVDCInput | String10 | InputCurrent | Instant | A | PVDCInput_String10_InputCurrent_Instant_A PVDCInput | String11 | InputCurrent | Instant | A | PVDCInput_String11_InputCurrent_Instant_A PVDCInput | String12 | InputCurrent | Instant | A | PVDCInput_String12_InputCurrent_Instant_A PVDCInput | String13 | InputCurrent | Instant | A | PVDCInput_String13_InputCurrent_Instant_A PVDCInput | String14 | InputCurrent | Instant | A | PVDCInput_String14_InputCurrent_Instant_A PVDCInput | String15 | InputCurrent | Instant | A | PVDCInput_String15_InputCurrent_Instant_A PVDCInput | String16 | InputCurrent | Instant | A | PVDCInput_String16_InputCurrent_Instant_A PV_Input | Total | InputVoltage | Instant | Vdc | PV_Input_Total_InputVoltage_Instant_Vdc """ Inverter_Registers_Address = [ 6, 7, 12, 13, 24, 25, 26, 28, 29, 32, 21, 22, 23, 30, 38, 39, 40, 41, 42, 43, 44, 45, 33 ] # Endereço requisitado ao inversor Inverter_Registers_Length = [ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] # Dimensão do registrador Control_Flag = False Grid_3Phase_DaylyReactiveEnergy_Today_kVArh = 0 Ts = 60 Initial_Time = time.time() Client_MQTT = mqtt.Client("IngeTeam 100kW") Client_MQTT.on_connect = on_connect Client_MQTT.on_message = on_message Client_MQTT.connect("mqtt.eclipse.org", 1883, 60) while True: Client_MQTT.loop_start() Input_Registers = [] #Client_ModBus.debug(True) try: Client_ModBus = ModbusClient(host=HOST, port=502, auto_open=True, auto_close=True) Client_ModBus.open() for Address in range(len(Inverter_Registers_Address)): if Inverter_Registers_Length[Address] == 2 and not ( Control_Flag): Input_Registers.append( Client_ModBus.read_input_registers( Inverter_Registers_Address[Address], Inverter_Registers_Length[Address])) Control_Flag = True elif Inverter_Registers_Length[Address] == 2 and Control_Flag: Control_Flag = False else: Input_Registers.append( Client_ModBus.read_input_registers( Inverter_Registers_Address[Address], Inverter_Registers_Length[Address])) Grid_3Phase_DeliveredEnergy_LastReset_kWh = convert_input_register_value_to_real_value( convert_parameters_uint_32(Input_Registers[0][0], Input_Registers[0][1]), Scale_Factor=0.01) Grid_3Phase_DaylyEnergy_Today_kWh = convert_input_register_value_to_real_value( convert_parameters_uint_32(Input_Registers[1][0], Input_Registers[1][1]), Scale_Factor=0.01) Grid_Phase1_RMSVoltage_Instant_V = convert_input_register_value_to_real_value( Input_Registers[2][0], Scale_Factor=0.1) Grid_Phase2_RMSVoltage_Instant_V = convert_input_register_value_to_real_value( Input_Registers[3][0], Scale_Factor=0.1) Grid_Phase3_RMSVoltage_Instant_V = convert_input_register_value_to_real_value( Input_Registers[4][0], Scale_Factor=0.1) Grid_3Phase_Instant_Delivered_Aparent_Power_VA = convert_input_register_value_to_real_value( Input_Registers[5][0], Scale_Factor=10) Grid_3Phase_OutputActivePower_Instant_W = convert_input_register_value_to_real_value( Input_Registers[6][0], Scale_Factor=10) PV_Input_TotalCurrent_A = convert_input_register_value_to_real_value( Input_Registers[7][0], Scale_Factor=0.01) Grid_Phase1_RMSCurrent_Instant_A = convert_input_register_value_to_real_value( Input_Registers[8][0], Scale_Factor=0.01) Grid_Phase2_RMSCurrent_Instant_A = convert_input_register_value_to_real_value( Input_Registers[9][0], Scale_Factor=0.01) Grid_Phase3_RMSCurrent_Instant_A = convert_input_register_value_to_real_value( Input_Registers[10][0], Scale_Factor=0.01) Grid_3Phase_OutputReactivePower_LastReset_VAr = convert_input_register_value_to_real_value( Input_Registers[11][0], Scale_Factor=10) Grid_3Phase_DaylyReactiveEnergy_Today_kVArh = grid_3Phase_dayly_energy_today_kVArh( Grid_3Phase_DaylyReactiveEnergy_Today_kVArh, Grid_3Phase_OutputReactivePower_LastReset_VAr, Ts) PVDCInput_String1_InputCurrent_Instant_A, PVDCInput_String2_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[12][0]) PVDCInput_String3_InputCurrent_Instant_A, PVDCInput_String4_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[13][0]) PVDCInput_String5_InputCurrent_Instant_A, PVDCInput_String6_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[14][0]) PVDCInput_String7_InputCurrent_Instant_A, PVDCInput_String8_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[15][0]) PVDCInput_String9_InputCurrent_Instant_A, PVDCInput_String10_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[16][0]) PVDCInput_String11_InputCurrent_Instant_A, PVDCInput_String12_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[17][0]) PVDCInput_String13_InputCurrent_Instant_A, PVDCInput_String14_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[18][0]) PVDCInput_String15_InputCurrent_Instant_A, PVDCInput_String16_InputCurrent_Instant_A = convert_parameters_uint_16_to_8bits_8bits( Input_Registers[19][0]) PV_Input_Total_InputVoltage_Vdc = convert_input_register_value_to_real_value( Input_Registers[20][0], Scale_Factor=1) mqtt_publish(Client_MQTT, Topics[0], Grid_3Phase_DeliveredEnergy_LastReset_kWh) mqtt_publish(Client_MQTT, Topics[1], Grid_3Phase_DaylyEnergy_Today_kWh) mqtt_publish(Client_MQTT, Topics[2], Grid_Phase1_RMSVoltage_Instant_V) mqtt_publish(Client_MQTT, Topics[3], Grid_Phase2_RMSVoltage_Instant_V) mqtt_publish(Client_MQTT, Topics[4], Grid_Phase3_RMSVoltage_Instant_V) mqtt_publish(Client_MQTT, Topics[5], Grid_3Phase_Instant_Delivered_Aparent_Power_VA) mqtt_publish(Client_MQTT, Topics[6], Grid_3Phase_OutputActivePower_Instant_W) mqtt_publish(Client_MQTT, Topics[7], PV_Input_TotalCurrent_A) mqtt_publish(Client_MQTT, Topics[8], Grid_Phase1_RMSCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[9], Grid_Phase2_RMSCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[10], Grid_Phase3_RMSCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[11], Grid_3Phase_OutputReactivePower_LastReset_VAr) mqtt_publish(Client_MQTT, Topics[12], Grid_3Phase_DaylyReactiveEnergy_Today_kVArh) mqtt_publish(Client_MQTT, Topics[13], PVDCInput_String1_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[14], PVDCInput_String2_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[15], PVDCInput_String3_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[16], PVDCInput_String4_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[17], PVDCInput_String5_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[18], PVDCInput_String6_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[19], PVDCInput_String7_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[20], PVDCInput_String8_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[21], PVDCInput_String9_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[22], PVDCInput_String10_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[23], PVDCInput_String11_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[24], PVDCInput_String12_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[25], PVDCInput_String13_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[26], PVDCInput_String14_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[27], PVDCInput_String15_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[28], PVDCInput_String16_InputCurrent_Instant_A) mqtt_publish(Client_MQTT, Topics[29], PV_Input_Total_InputVoltage_Vdc) Client_ModBus.close() except: print("Except") for topic in range(len(Topics)): mqtt_publish(Client_MQTT, Topics[topic], 0) Grid_3Phase_DaylyReactiveEnergy_Today_kVArh = 0 Final_Time = time.time() CPU_Process_Time = Final_Time - Initial_Time print("Tempo de Processamento: %f" % (CPU_Process_Time)) if Ts - CPU_Process_Time > 0: time.sleep(Ts - CPU_Process_Time) Initial_Time = Initial_Time + Ts
del PV_KW_list[-1] #deleting last item cause it is NaN PV_KW_list = [ int(x) for x in PV_KW_list ] #converting into integers #print(PV_KW_list) # uncomment this line to see debug message # c.debug(True) # define modbus server host, port c.host(SERVER_HOST) c.port(SERVER_PORT) # open or reconnect TCP to server if not c.is_open(): if not c.open(): print("Unable to connect to "+SERVER_HOST+":"+str(SERVER_PORT)) # if open() is ok, write the registers with the PV generation values if c.is_open(): print("Connected to Server") for addr in range(len(PV_KW_list)): is_ok = c.read_input_registers(addr, 1) if is_ok: print("register #" + str(addr) + ": PV gen (KW) :" + str(is_ok)) else: print("resgister #" + str(addr) + ": Unable to read " + str(PV_KW_list[addr])) time.sleep(Sampling_Rate) # closing TCP connection after writing all registers print("Finish reading registers") c.close()
# TCP auto connect on modbus request, close after it #c = ModbusClient(host="127.0.0.1", auto_open=True, auto_close=True) c = ModbusClient() c.host("192.168.58.10") c.port(502) # managing TCP sessions with call to c.open()/c.close() c.open() # to debug the communication #c.debug(True) inputRegD = c.read_discrete_inputs(0, 16) coil = c.read_coils(0, 16) read_holding = c.read_holding_registers(0, 2) inputReg = c.read_input_registers(0, 2) while True: if inputRegD: #print(regs) #print(type(regs)) #print(type(coil)) x = inputRegD[5] print("Read Input: " + str(inputRegD)) print("Read Coils: " + str(coil)) print("Holding Register: " + str(read_holding)) print("Read Input Register: " + str(inputReg)) else: print("read error") time.sleep(5)
class Plugin(LoggerPlugin): """ Zeichnet die Messdaten einer Heliotherm-Wärmepumpe (mit RCG2) auf. Modbus-TCP muss aktiviert sein und die korrekte IP-Adresse eingetragen sein, damit dieses Gerät funktioniert. """ def __init__(self, *args, **kwargs): # Plugin setup super(Plugin, self).__init__(*args, **kwargs) self.loadConfig() self.setDeviceName(self._name) self.smallGUI = True self.activeGroups = self.loadPersistentVariable('activeGroups', [True]) self.__doc_activeGroups__ = """ Enthält eine Liste mit Funktionen, die die Wärmepumpe besitzt. Gültige Werte sind: True: Alle Standartmessdaten werden aufgezeichnet 'EVU': Alle EVU-Daten werden aufgezeichnet 'MKR1': Mischkreis 1 Daten werden aufgezeichnet 'MKR2': Mischkreis 2 Daten werden aufgezeichnet 'ext': Externe Daten werden aufgezeichnet '2teStufe': Zweite Stufe Daten werden aufgezeichnet """ self._availableGroups = ['EVU', 'MKR1', 'MKR2', 'ext', '2teStufe'] # Data-logger thread self._firstStart = True self._lastStoerung = False self._lastExtAnf = True self._lastMode = 0 self._heizkreis1Solltemperatur = 0 self._heizkreis2Solltemperatur = 0 # self._error = False self._modes = { 0: 'AUS', 1: 'Automatik', 2: 'Kühlen', 3: 'Sommer', 4: 'Dauerbetrieb', 5: 'Absenkung', 6: 'Urlaub', 7: 'Party', 8: 'Ausheizen', 9: 'EVU Sperre', 10: 'Hauptschalter aus' } self._base_address = "" self.setPerpetualTimer(self._helio_alle) self._base_address = self.host self._c = ModbusClient(host=self._base_address, port=self.port, auto_open=True, auto_close=True) self._c.timeout(10) self.start() def loadGUI(self): self.widget = QtWidgets.QWidget() packagedir = self.getDir(__file__) uic.loadUi(packagedir + "/Heliotherm/heliotherm.ui", self.widget) # self.setCallbacks() self.widget.pushButton.clicked.connect(self._openConnectionCallback) self.widget.samplerateSpinBox.valueChanged.connect( self._changeSamplerate) self.widget.comboBox.setCurrentText(self.host) # self._openConnectionCallback() return self.widget def _openConnectionCallback(self): if self.run: self.cancel() self.widget.pushButton.setText("Verbinden") self._base_address = "" else: address = self.widget.comboBox.currentText() self._base_address = address self._c = ModbusClient(host=self._base_address, port=self.port, auto_open=True, auto_close=True) self._c.timeout(10) self.start() self.widget.pushButton.setText("Beenden") def _helio_set(self, reg_addr, reg_value): for element in self._mappingWrite: if element[0] == reg_addr and element[5] == True: ans = self._c.write_single_register(reg_addr, reg_value) if ans == True: return True else: return False else: raise PermissionError raise KeyError def _Schreiben(self, reg_name, reg_value): """ Schreibe ein Register manuell. """ for element in self._mappingWrite: if element[1] == reg_name and element[5] == True: ans = self._c.write_single_register(element[0], reg_value) if ans == True: return "Wert wurde geändert" else: return "Wert konnte nicht geändert werden." else: return "Element darf nicht beschrieben werden." return "Element nicht gefunden" def Anschalten(self, modus=1): """ Schalte den Modus der Wärmepumpe um: 0= AUS, 1= Automatik, 2= Kühlen, 3= Sommer, 4= Dauerbetrieb, 5= Absenkung, 6=Urlaub, 7= Party, """ # 0= AUS # 1= Automatik # 2= Kühlen # 3= Sommer # 4= Dauerbetrieb # 5= Absenkung # 6=Urlaub # 7= Party if int(modus) in self._modes.keys() and int(modus) <= 7: return self._c.write_single_register(100, int(modus)) else: return 'Wähle einen Modus zwischen 0 und 7\n' + str(self._modes) def MKR1Schreiben(self, modus=1): """ Schalte den Modus des MKR1 um: 0= AUS, 1= Automatik, 2= Kühlen, 3= Sommer, 4= Dauerbetrieb, 5= Absenkung, 6=Urlaub, 7= Party, """ # 0= AUS # 1= Automatik # 2= Kühlen # 3= Sommer # 4= Dauerbetrieb # 5= Absenkung # 6=Urlaub # 7= Party if int(modus) in self._modes.keys() and int(modus) <= 7: return self._c.write_single_register(107, int(modus)) else: return 'Wähle einen Modus zwischen 0 und 7\n' + str(self._modes) def MKR2Schreiben(self, modus=1): """ Schalte den Modus des MKR2 um: 0= AUS, 1= Automatik, 2= Kühlen, 3= Sommer, 4= Dauerbetrieb, 5= Absenkung, 6=Urlaub, 7= Party, """ # 0= AUS # 1= Automatik # 2= Kühlen # 3= Sommer # 4= Dauerbetrieb # 5= Absenkung # 6=Urlaub # 7= Party if int(modus) in self._modes.keys() and int(modus) <= 7: return self._c.write_single_register(112, int(modus)) else: return 'Wähle einen Modus zwischen 0 und 7\n' + str(self._modes) def MKR1Automatik(self): """ Schalte MKR1 auf Automatik """ return self.MKR1Schreiben(modus=1) def MKR2Automatik(self): """ Schalte MKR2 auf Automatik """ return self.MKR2Schreiben(modus=1) def MKR1Aus(self): """ Schalte MKR1 aus """ return self.MKR1Schreiben(modus=0) def MKR2Aus(self): """ Schalte MKR2 aus """ return self.MKR1Schreiben(modus=0) def MKR1Kuehlen(self): """ Schalte MKR1 auf Kühlen """ return self.MKR1Schreiben(modus=2) def MKR2Kuehlen(self): """ Schalte MKR2 auf Kühlen """ return self.MKR1Schreiben(modus=2) def MKR1Absenkung(self): """ Schalte MKR1 auf Absenkung """ return self.MKR1Schreiben(modus=5) def MKR2Absenkung(self): """ Schalte MKR2 auf Absenkung """ return self.MKR1Schreiben(modus=5) def Ausschalten(self): """ Schalte die Wärmepumpe aus """ return self._c.write_single_register(100, 0) @property def Heizkreis1Solltemperatur(self): return self._heizkreis1Solltemperatur @Heizkreis1Solltemperatur.setter def Heizkreis1Solltemperatur(self, value): reg_addr = 108 try: value = float(value) except: pass if value > 0: self._helio_set(reg_addr, value) self._heizkreis1Solltemperatur = value @property def Heizkreis2Solltemperatur(self): return self._heizkreis2Solltemperatur @Heizkreis2Solltemperatur.setter def Heizkreis2Solltemperatur(self, value): reg_addr = 113 try: value = float(value) except: pass if value > 0: self._helio_set(reg_addr, value) self._heizkreis2Solltemperatur = value def _helio_alle(self, all=False): readStart = 10 readEnd = 75 resultRead = self._c.read_input_registers(readStart, readEnd - readStart + 1) writeStart = 100 writeEnd = 159 resultWrite = self._c.read_holding_registers(writeStart, writeEnd - writeStart + 1) if type(resultWrite) != list: writeStart = 100 writeEnd = 134 resultWrite = self._c.read_holding_registers( writeStart, writeEnd - writeStart + 1) ans = {} if type(resultWrite) == list: for idx, value in enumerate(self._mappingWrite): if idx >= len(resultWrite): break if len(self._mappingWrite[idx]) == 6: if self._mappingWrite[idx][4] in self.activeGroups or all: sname = self._mappingWrite[idx][1] divisor = self._mappingWrite[idx][2] unit = self._mappingWrite[idx][3] y = resultWrite[idx] if y >= 2**16 / 2: y = 2**16 - y y = y / divisor ans[sname] = [y, unit] if self._mappingWrite[idx][0] == 100: if not self._firstStart and y != self._lastMode: mode = self._modes[y] self.event( 'Betriebsart wurde verändert: {}'.format( mode), 'Betriebsart', self._name, 0, 'ModusChanged') self._lastMode = y elif self._mappingWrite[idx][0] == 108: self._heizkreis1Solltemperatur = y elif self._mappingWrite[idx][0] == 113: self._heizkreis2Solltemperatur = y elif self._mappingWrite[idx][0] == 127: if not self._firstStart and y != self._lastExtAnf: if y == 1: self.event( 'Externe Anforderung angeschaltet', 'Externe Anforderung', self._name, 0, 'ExtAnfAn') else: self.event( 'Externe Anforderung ausgeschaltet', 'Externe Anforderung', self._name, 0, 'ExtAnfAus') self._lastExtAnf = y else: pass # handle parameters else: logging.warning( 'Could not read writeable-registers, {}'.format(resultWrite)) if self.widget: self.widget.comboBox.setCurrentText('Fehler') if type(resultRead) == list: for idx, value in enumerate(self._mappingRead): if self._mappingRead[idx][4] in self.activeGroups or all: if len(self._mappingRead[idx] == 5): sname = self._mappingRead[idx][1] divisor = self._mappingRead[idx][2] unit = self._mappingRead[idx][3] y = resultRead[idx] if y >= 2**16 / 2: y = 2**16 - y y = y / divisor ans[sname] = [y, unit] if self._mappingRead[idx][0] == 26: if not self._firstStart and y != self._lastStoerung: if y != 0: self.event( 'Störung aufgetreten: {}!'.format(y), 'Stoerung', self._name, 2, 'StoerungAn') else: self.event('Störung wurde behoben!', 'Stoerung', self._name, 0, 'StoerungAus') self._lastStoerung = y else: pass # handle parameters self._firstStart = False else: logging.warning( 'Could not read read-registers, {}'.format(resultRead)) if self.widget: self.widget.comboBox.setCurrentText('Fehler') self.stream(sdict={self._name: ans}) def _changeSamplerate(self): self.samplerate = self.widget.samplerateSpinBox.value() def loadConfig(self): packagedir = self.getDir(__file__) with open(packagedir + "/config.json", encoding="UTF-8") as jsonfile: config = json.load(jsonfile, encoding="UTF-8") self._mappingWrite = config['mappingWrite'] self._mappingRead = config['mappingRead'] self.host = config['hostname'] self.port = config['port'] self._name = config['name'] self.samplerate = config['samplerate']