class ModbusClientRS: def __init__(self): self.client = ModbusClient() def writeRegister(self, address, value): if self.client.is_open(): return self.client.write_single_register(address, value) return None def readRegister(self, address, value): if self.client.is_open(): self.client.read_holding_registers(address, value) def connect(self, host, port): # self.client.debug(True) self.client.host(SERVER_HOST) self.client.port(SERVER_PORT) if not self.client.is_open(): if not self.client.open(): print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT)) def is_open(self): return self.client.is_open() def disconnect(self): return self.client.close()
class Modbus: def __init__(self, host, port, unit): self.client = ModbusClient(host, port, unit, timeout=3) def __enter__(self): self.client.open() return self def __exit__(self, exc_type, exc_val, exc_tb): self.client.close() def toFloat(self, ushorts): bs = struct.pack('H', ushorts[0]) + struct.pack('H', ushorts[1]) return struct.unpack('f', bs) def openConnect(self): try: if not self.isOpen: self.client.open() except: self.closeConnect() def closeConnect(self): self.client.close() @property def isOpen(self): return self.client.is_open() def getValue(self, addr): return self.toFloat(self.client.read_holding_registers(addr, 2))[0] def getValues(self, tags): return [(tag, self.getValue(tag)) for tag in tags]
def test(): c = ModbusClient() # uncomment this line to see debug message # c.debug(True) # define modbus server host, port c.host(SERVER_HOST) c.port(SERVER_PORT) 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 c.write_single_register(504, intToUint16(-216)) # sleep 2s before next polling time.sleep(2)
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 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_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 execute_func(): sensor_no = ModbusClient(host="192.40.50.107", port=10010, unit_id=1, auto_open=True) sensor_no.open() regs = sensor_no.read_holding_registers(0, 100) if regs: print(regs) else: print("read error") n = 0 data_count = 0 for n in range(50): data_count = n * 2 regs[data_count], regs[data_count + 1] = regs[data_count + 1], regs[data_count] dec_array = regs data_bytes = np.array(dec_array, dtype=np.uint16) data_as_float = data_bytes.view(dtype=np.float32) time_data = datetime.datetime.now() print(time_data) start = 1 start_range = 50 value = [[num for num in range(start, start + start_range)], [num for num in range(start, start + start_range)], data_as_float] data = np.array(value).T.tolist() # print(data) products = data arr = [] for product in products: vals = {} vals["Sensor No"] = str(int(product[1])) vals["Temp"] = str(product[2]) vals["Time"] = str(time_data) arr.append(vals) myclient = pymongo.MongoClient("mongodb://localhost:27017/") mydb = myclient["Modbus_Database"] mycol = mydb["collection1"] record_data = arr mycol.insert_many(record_data) global documents documents = list(mycol.find({}, {'_id': 0})) print(documents) # myclient.drop_database('Modbus_Database') mycol.delete_many({}) time.sleep(60)
def onStart(): Domoticz.Log("Domoticz SMA Inverter Modbus plugin start") if 1 not in Devices: Domoticz.Device(Name="Solar Yield", Unit=1, TypeName="kWh", Used=0).Create() if 2 not in Devices: Domoticz.Device(Name="DC Power A", Unit=2, TypeName="Usage", Used=0).Create() if 3 not in Devices: Domoticz.Device(Name="DC Power B", Unit=3, TypeName="Usage", Used=0).Create() if 4 not in Devices: Domoticz.Device(Name="AC Power", Unit=4, TypeName="Usage", Used=0).Create() if 5 not in Devices: Domoticz.Device(Name="Temperature", Unit=5, TypeName="Temperature", Used=0).Create() global client client = ModbusClient(host=Parameters["Address"], port=Parameters["Port"], unit_id=Parameters["Mode1"]) client.open() Domoticz.Heartbeat(int(Parameters["Mode2"]))
class kulucka: def __init__(self): self.bekle = 1 self.host = "212.154.74.164" self.port = 502 self.timeout = 2000 self.c = None self.sonuc = {} def baglan(self): self.c = ModbusClient(host=self.host, unit_id=1, timeout=self.timeout, auto_open=True, auto_close=True, port=self.port) def main(self): self.c.open() regs = self.c.read_holding_registers(12288, 6) if regs: self.parse(regs) else: print("read error") self.c.close() def parse(self, regs): k = 1 for i in range(0, len(regs), 2): sicaklik = regs[i] / 10 nem = regs[i + 1] / 10 self.sonuc["kulucka" + str(k)] = {"sicaklik": sicaklik, "nem": nem} k += 1 print()
def __init__(self, address, port): c = ModbusClient() c.host(address) c.port(port) c.unit_id(1) c.open() data = c.read_holding_registers(130, 12) self.data=data c.close() if data: self.LowT1Start = format(data[0], 'x') self.LowT1Stop = format(data[1], 'x') self.LowT2Start = format(data[2], 'x') self.LowT2Stop = format(data[3], 'x') self.NormT1Start = format(data[4], 'x') self.NormT1Stop = format(data[5], 'x') self.NormT2Start = format(data[6], 'x') self.NormT2Stop = format(data[7], 'x') self.PeakT1Start = format(data[8], 'x') self.PeakT1Stop = format(data[9], 'x') self.PeakT2Start = format(data[10], 'x') self.PeakT2Stop = format(data[11], 'x') else: print("Read Volt And Amper ERROR")
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 callback(msg): global DATA_TO_HOLDING, DATA_FROM_HOLDING, DATA_FROM_COIL, DATA_TO_COIL global start_addr, test_signal_coil, test_signal_holding global addr_num vx = msg.linear.x * 1000 vy = msg.linear.y * 1000 vz = msg.linear.z * 1000 rx = msg.angular.x * 1000 ry = msg.angular.y * 1000 rz = msg.angular.z * 1000 DATA_TO_HOLDING = [vx, vy, vz, rx, ry, rz] c = ModbusClient(host=MODBUS_SPEC['SERVER_HOST'], port=MODBUS_SPEC['SERVER_PORT']) ## polling loop # keep TCP open if not c.is_open(): c.open() #print('DATA_TO_HOLDING = %s' % (DATA_TO_HOLDING)) if DATA_TO_HOLDING is not None and len(DATA_TO_HOLDING) is not 0: if c.write_multiple_registers(MDS_ADDR_W['addr_start_holding_W'], DATA_TO_HOLDING): print('write holding ok from addr %s with list %s' % (MDS_ADDR_W['addr_start_holding_W'], DATA_TO_HOLDING)) else: print('write holding error from addr %s with list %s' % (MDS_ADDR_W['addr_start_holding_W'], DATA_TO_HOLDING)) else: print('holding data missing with %s with desired len %s' % (DATA_TO_HOLDING, MDS_ADDR_W['addr_num_holding_W'])) time.sleep(0.1)
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 Read(self): self.Reset() self.Error = True try: # Initializing connection to Eaton power meter via TCP c = ModbusClient() c.host(ip) c.port(port) c.open() #All time-stamp values timeMark = datetime.datetime.now() self.Error = False self.ErrorType = '' self.year = timeMark.year self.month = timeMark.month self.day = timeMark.day self.hour = timeMark.hour self.minute = timeMark.minute self.second = timeMark.second #All meter values self.Vab = convert(c, vabaddr) self.Vbc = convert(c, vbcaddr) self.Vca = convert(c, vcaaddr) self.Van = convert(c, vanaddr) self.Vbn = convert(c, vbnaddr) self.Vcn = convert(c, vcnaddr) self.phVab = convert(c, phvabaddr) self.phVbc = convert(c, phvbcaddr) self.phVca = convert(c, phvcaaddr) self.Ia = convert(c, iaaddr) self.Ib = convert(c, ibaddr) self.Ic = convert(c, icaddr) self.In = convert(c, inaddr) self.phIa = convert(c, phiaaddr) self.phIb = convert(c, phibaddr) self.phIc = convert(c, phicaddr) self.WphA = convert(c, wphaaddr) self.WphB = convert(c, wphbaddr) self.WphC = convert(c, wphcaddr) self.VARphA = convert(c, varaaddr) self.VARphB = convert(c, varbaddr) self.VARphC = convert(c, varcaddr) self.VanTHD = convert(c, vanaddr) self.VbnTHD = convert(c, vbnaddr) self.VcnTHD = convert(c, vcnaddr) self.IaTHD = convert(c, iathdaddr) self.IbTHD = convert(c, ibthdaddr) self.IcTHD = convert(c, icthdaddr) c.close() except: try: c.close() except: pass self.Error = True self.ErrorType = 'Connection Error'
def modbus_func(self): sensor_no = ModbusClient(host="192.40.50.107", port=10010, unit_id=1, auto_open=True) sensor_no.open() regs = sensor_no.read_holding_registers(0, 100) if regs: print(regs) else: print("read error")
def readPDTemp(num): c = ModbusClient(host='192.168.0.4', port=502, unit_id=4, auto_open=True, auto_close=True) if c.is_open(): registerPD = None registerTemp = None else: c.open() registerPD = None registerTemp = None if num == 4: registerPD = c.read_holding_registers(reg_addr=450, reg_nb=1) registerTemp = c.read_holding_registers(reg_addr=418, reg_nb=3) elif num == 5: registerPD = c.read_holding_registers(reg_addr=451, reg_nb=1) registerTemp = c.read_holding_registers(reg_addr=421, reg_nb=3) elif num == 6: registerPD = c.read_holding_registers(reg_addr=452, reg_nb=1) registerTemp = c.read_holding_registers(reg_addr=424, reg_nb=3) else: print("system error!") param = num, round(time.time()), registerTemp[0] / 10, registerTemp[ 1] / 10, registerTemp[2] / 10, registerPD[0] if registerPD: if registerTemp: try: with conn.cursor() as cursor: cursor.execute(qry, param) conn.commit() except TypeError: print('connection error with Db. Check it.') pass else: print("reboot CAM-4 to get temperature") else: print("reboot CAM-4 to get PD") c.close() result = { 'i': param[0], 'time': param[1], 'Temp_R': param[2], 'Temp_S': param[3], 'Temp_T': param[4], 'PD': param[5] } return result
class ModbusClass: def __init__(self): # Make an instance of modbus object self._client = ModbusClient() #Connect to the LOGO def _connectToLogo(self, ip_address, port_num): try: self._client.host(ip_address) self._client.port(port_num) self._client.open() print('Connected') except AttributeError: print('Failed to connect to Logo') # Generic Function for reading from any LOGO def _readData(self, _list=[], *args): _data = [] for regNumber in _list: dataValue = self._client.read_holding_registers( regNumber) # Reading voltage on AI3 dataValue = dataValue[0] dataValue = int(dataValue) _data.append(dataValue) else: return _data # Perform two's compliment on any given number just incase the number is negative def twosCompliment(self, _list, *args): _result_list = [] for number in _list: # All values are expected to be below 8 Bits. If More than 8 Bits, number is negative if number > 256: number = number - 65536 _result_list.append(number) else: number = number _result_list.append(number) else: return _result_list # Convert the electrical signals into meaningful data def signalConditioning(self, _gain, _offset, _signals=[], *args): _result_list = [] for _signal in _signals: _conditioned_signal = (_signal * _gain + _offset) _conditioned_signal = round(_conditioned_signal, 2) _result_list.append(_conditioned_signal) else: return _result_list
def state_off(self, name_x): SERVER_HOST = name_x SERVER_PORT = 502 c = ModbusClient() c.host(SERVER_HOST) c.port(SERVER_PORT) c.open() is_ok = c.write_single_coil(32768, False) if is_ok: self.first_read_label_text = str('kapali') self.image_source = "sf0.png" else: self.first_read_label_text = str('failed')
def checkConnection(host): # A simple function to check if the Modbus connection is open #...using the pyModbus.ModbusClient.is_open() method. client = ModbusClient() client.host(host) client.open() if client.is_open(): status = True else: status = False client.close() return status
def connect_nexus_machine(self): c = ModbusClient() c.host("192.168.0.147") c.port(502) c.open() input_register = c.read_coils(0, 16) while True: if input_register: self.lineEditIP.setText(str(input_register)) else: print("read error") time.sleep(5)
def modbus_com(SERVER_HOST, SERVER_PORT, function_code, start_register, amount_of_registers): c = ModbusClient() c.host(SERVER_HOST) c.port(SERVER_PORT) cnt = 0 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(): if function_code == "3": # Read the amount_of_registers from start_register regs = c.read_holding_registers(int(start_register), int(amount_of_registers)) # if success display registers if regs: print("reg address" + str(start_register) + "to" + str( int(start_register) + int(amount_of_registers) - 1) + ":" + str(regs)) elif function_code == "16": #Future support pass cnt += 1 if cnt >= 2: print("クライアント通信終了") c.close() break # sleep 1s before next polling time.sleep(1)
def polling_thread(): global regs c = ModbusClient(host=SERVER_HOST, port=SERVER_PORT) # polling loop while True: # keep TCP open if not c.is_open(): c.open() # do modbus reading on socket reg_list = c.read_holding_registers(0, 10) # if read is ok, store result in regs (with thread lock synchronization) if reg_list: with regs_lock: regs = list(reg_list) # 1s before next polling time.sleep(1)
def modbus_request(self, progress_callback): c = ModbusClient(host="localhost", auto_open=False) connection_ok = c.open() if connection_ok: try: self.holding_registers = c.read_holding_registers(0, 3) print(self.holding_registers) regs = [ int(10 * self.tcurrinsp.value()), int(10 * self.tcurrexp.value()), int(10 * self.currpress.value()) ] c.write_multiple_registers(3, regs) print(regs) c.close() except: print("modbus exception") pass else: print("other") pass finally: #print("passed") pass else: print("could not open") pass
def state_on(self, name_x): SERVER_HOST = name_x SERVER_PORT = 502 c = ModbusClient() c.host(SERVER_HOST) c.port(SERVER_PORT) c.open() is_ok = c.write_single_coil(32768, True) bits = c.read_holding_registers(32768) if bits: self.first_read_label_text = str('Acik') self.image_source = "sf_yesil.png" else: self.first_read_label_text = str('cannotread')
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
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
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)
class Traffic: beschikbaar = 0 adress = 0 rood_aan = 0b000100 geel_aan = 0b001000 groen_aan = 0b010000 gedoofd = 0b000000 time1 = time.time() def __init__(self): self.stand = 3 self.c = ModbusClient(host="192.168.3.135", port=502, auto_open=True) def getStatus(self): return self.beschikbaar def setStand(self, modus): self.stand = modus def update_light(self): if self.stand == 3: self.c.write_single_register(self.adress, self.rood_aan) elif self.stand == 1: self.c.write_single_register(self.adress, self.geel_aan) elif self.stand == 0: self.c.write_single_register(self.adress, self.groen_aan) elif self.stand == 4: self.c.write_single_register(self.adress, self.gedoofd) def afsluiten(self): while 1: time2 = time.time() - self.time1 if time2 < 3: self.setStand("geel_knipperen") elif 6 > time2 > 3: self.setStand("geel") elif time2 > 6: self.setStand("rood") break def normaal(self): while 1: time2 = time.time() - self.time1 if time2 < 3: self.setStand(2) #rood elif 13 > time2 > 3: self.setStand(0) #groen elif time2 > 13: self.setStand(4) break def checkError(self): if (self.c.close()): beschikbaar = 0 elif (self.c.open()): beschikbaar = 1
def connect(host, port): """Connects to the defined HOST AND PORT. returns the client""" c = ModbusClient() c.host(host) c.port(port) if not c.is_open(): if not c.open(): raise Exception() return c
def getModbusData(host, port, start_register, end_register): # Returns a list containing the data from each Modbus register between #...and including the start and end register # Depending on the format of any particular value you want, its data may be distributed #...over multiple registers and will require further formatting to be human-readable. # This function only returns the data directly taken from the device's Modbus registers. # Setting up the client #---------------------------------------------------- client = ModbusClient() # Creates a Modbus client opject client.host(host) # Assigns the specified host (IP) address to the client client.port(port) # Assigns the specified port to the client start_register -= 2 # The Modbus registers listed in the Shark100 User's manual end_register -= 2 #...are all offset by 2 from their actual values, #...so we account for that here. num_of_registers = end_register - start_register + 1 # Since the registers are taken as integers, we can take the range between the start and end #...registers and add 1 to get the total number of registers to query. #---------------------------------------------------- # Reading the device's Modbus registers #---------------------------------------------------- client.open() # Opens the connection response = client.read_holding_registers(start_register, num_of_registers) # This function returns a list of values, one for each of the Modbus registers specified. # It works even if some of the registers queried have data stored in different formats, #...so be careful not to automatically treat all data the same. client.close() # Closes the connection #---------------------------------------------------- return response
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
class com(object): """This class implements the modbusTCP connection functions """ def __init__(self): ''' Constructor for this class. ''' self._port = 0 def __del__(self): ''' Destructor for this class. ''' if self._port !=0: self.close() def open (self,SERVER_HOST = "192.168.0.210",SERVER_PORT = 502,SERVER_UNIT = 201): """Open modbus connection to the ComBox Args: SERVER_HOST: network address of the ComBox. Default='192.168.0.210' SERVER_PORT: modbus TCP port. Default='502' SERVER_UNIT: modbus address of the ComBox. Default='201' Returns: Boolean value True or False """ self._port = ModbusClient(SERVER_HOST, SERVER_PORT, SERVER_UNIT) if not self._port.is_open(): if not self._port.open(): print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT)) return self._port.is_open() def close(self): """Closes the modbusTCP connection Returns: Boolean value True or False """ self._port.close() return not self._port.is_open() def is_connected(self): """This function checks if the connection to the Schneider Conext ComBox is established and if it responds to readout commands. It requests the firmware version of the ComBox and checks for an received bitstream. Returns: Boolean value True or False return """ bitstream = self._port.read_holding_registers(0x001E, 7) # 0x001E Firmware Version str20 r if bitstream: return True else: return False
def polling_thread(): global regs, poll_cycle c = ModbusClient(host=args.host, port=args.port, unit_id=args.unit_id) # polling loop while True: # keep TCP open if not c.is_open(): c.open() # do modbus reading on socket reg_list = c.read_holding_registers(20610,20) # if read is ok, store result in regs (with thread lock synchronization) with regs_lock: if reg_list: regs = list(reg_list) poll_cycle += 1 else: poll_cycle = 0 # 1s before next polling time.sleep(0.2)
class Pebl: def __init__(self, ip, system, port=502): self.c = ModbusClient(host=ip, port=502, auto_open=True) self.c.host(ip) self.c.port(port) self.c.open() self.system = system print("opened") def run(self): return_values = [] data_points = csv_json_alarms(self.system) for data_point in data_points: print(data_point) if data_point['type'] == 'COIL': value = self.c.read_coils(int(data_point['address'])) print(value) name = data_point['alarm'] return_values.append({'name': name, 'value': value}) f = open('data.json', 'w') f.write(json.dumps(return_values)) f.close() def run_manual(self): return_values = [] data_points = csv_json_alarms(self.system) for data_point in data_points: print(data_point) if data_point['type'] == 'COIL': value = self.c.read_coils(int(data_point['address'])) name = data_point['alarm'] if data_point['trigger'] == 'NC': if not value[0]: return_values.append({'name': name, 'value': 'OK'}) else: return_values.append({'name': name, 'value': 'ALARM'}) elif data_point['trigger'] == 'NO': if value[0]: return_values.append({'name': name, 'value': 'ALARM'}) else: return_values.append({'name': name, 'value': 'OK'}) return return_values
def reader(worker, job): c = ModbusClient(host="localhost", port=502) if not c.is_open() and not c.open(): print("unable to connect to host") if c.is_open(): holdingRegisters = c.read_holding_registers(1, 4) # Imagine we've "energy" value in position 1 with two words energy = (holdingRegisters[0] << 16) | holdingRegisters[1] # Imagine we've "power" value in position 3 with two words power = (holdingRegisters[2] << 16) | holdingRegisters[3] out = {"energy": energy, "power": power} return json.dumps(out) return None
host = input("\nPlease enter IP address [127.0.0.1]: ") port = input("Please enter port [502]: ") if not host: host = "172.16.143.146" if not port: port = 502 c = ModbusClient(timeout=5) c.host(host) c.port(port) for attempt in range(3): print("\nTrying to connect to " + host + ":" + str(port) + "... Attempt " + str(attempt+1)) if c.open(): print("\nSuccessful Connection") failedconnection = False time.sleep(0.5) choice = "" while choice != "q": choice = input("\nPress \n[r] to Read \n[w] to Write \n[q] to Quit: ") if choice == "r": print("\nChose Read") read_regs() elif choice == "w": print("\nChose Write") write_regs() else: if choice != "q": print("\nInvalid choice")
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 AmpSwitch(object): def __init__(self, host, port=502, switches=(), debug=False): """ """ self.host = host self.port = port self.debug = debug self.switches = switches self.dev = None self.connect() def __str__(self): return "AmpSwitch(host=%s, port=%s, dev=%s>" % (self.host, self.port, self.dev) def setDebug(self, state): self.debug = state self.connect() def close(self): if self.dev is not None: self.dev.close() self.dev = None def connect(self): """ (re-) establish a connection to the device. """ if self.dev is None: self.dev = ModbusClient() self.dev.debug(self.debug) self.dev.host(self.host) self.dev.port(self.port) if self.dev.is_open(): return True ret = self.dev.open() if not ret: raise RuntimeError("failed to connect to %s:%s" % (self.host, self.port)) return True def readCoils(self): """ Return the state of all our switches. """ self.connect() regs = self.dev.read_coils(0, 16) return regs def setCoils(self, on=(), off=()): """Turn on and off a given set of switches. Argunents --------- on, off : list-like, or a single integer. Notes: ------ The off set is executed first. . There is a command to change all switchees at once, but I have not made it work yet. """ self.connect() if isinstance(on, int): on = on, if isinstance(off, int): off = off, regs0 = self.readCoils() regs1 = regs0[:] for c in off: ret = self.dev.write_single_coil(c, False) regs1[c] = False for c in on: ret = self.dev.write_single_coil(c, True) regs1[c] = True # ret = self.dev.write_multiple_registers(0, regs1) ret = self.readCoils() return ret def chooseCoil(self, n): return self.setCoils(on=n, off=list(range(16)))
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))
class modBusWriteRead(): def __init__(self,client_host): self.client_host = client_host self.client_port = 502 self.err_list = [] self.connect() #buradan bağlantı yapılacak; def connect(self): self.modbus_c = ModbusClient() self.modbus_c.host(self.client_host) self.modbus_c.port(self.client_port) if not self.modbus_c.is_open(): if not self.modbus_c.open(): text="unable to connect to " + self.client_host + ":" + str(self.client_port) print(text) def write_data_reg(self,address,list): if self.modbus_c.open(): if len(list)>120: sent_list = self.hazirla_dizi_to_write(list) i = 0 hedef_reg_taban = address for list_to_sent in sent_list: hedef_reg = hedef_reg_taban + (i * 120) a = self.modbus_c.write_multiple_registers(hedef_reg, list_to_sent) if a == None or a == False: self.err_list.append(False) i += 1 else: a = self.modbus_c.write_multiple_registers(address, list) if a == None or a == False: self.err_list.append(False) if len(self.err_list) > 0: self.err_list = [] pass # dikkat # print("data göndermede hata oluştu, tekrar deneyin !") def hazirla_dizi_to_write(self,d_list): # eğer gönderilecek değer 120 den büyük ise aşağıdaki fonksiyon 120 lik diziler döndürüyor r_list = [] g_list = [] i = 0 for index in range(len(d_list)): g_list.append(d_list[index]) i += 1 if i > 119: i = 0 r_list.append(g_list) g_list = [] if (len(d_list) - 1) == index and i < 119: r_list.append(g_list) return r_list def read_data_reg(self,address,reg_count,read_float=False ): # burada 16 lık ya da float olarak okunabiliyor if self.modbus_c.is_open(): if read_float == False: plc_list_int = self.modbus_c.read_holding_registers(address, reg_count) return plc_list_int elif read_float == True: plc_list_f_16=self.modbus_c.read_holding_registers(address,reg_count) if plc_list_f_16 is not None: plc_list_float=self.long_to_float(plc_list_f_16) return plc_list_float def long_to_float(self,list_16): list_float=[] list_16.reverse() list_long=utils.word_list_to_long(list_16) for any_long in list_long: list_float.append(utils.decode_ieee(any_long)) list_float.reverse() return list_float
c = ModbusClient() # uncomment this line to see debug message #c.debug(True) # define modbus server host, port c.host(SERVER_HOST) c.port(SERVER_PORT) toggle = True 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, write coils (modbus function 0x01) if c.is_open(): # write 4 bits in modbus address 0 to 3 print("") print("write bits") print("----------") print("") for addr in range(4): is_ok = c.write_single_coil(addr, toggle) if is_ok: print("bit #" + str(addr) + ": write to " + str(toggle)) else: print("bit #" + str(addr) + ": unable to write " + str(toggle))
class ModbusTCPSensor(OMPluginBase): """ Get sensor values form modbus """ name = 'modbusTCPSensor' version = '1.0.7' interfaces = [('config', '1.0')] config_description = [{'name': 'modbus_server_ip', 'type': 'str', 'description': 'IP or hostname of the ModBus server.'}, {'name': 'modbus_port', 'type': 'int', 'description': 'Port of the ModBus server. Default: 502'}, {'name': 'debug', 'type': 'int', 'description': 'Turn on debugging (0 = off, 1 = on)'}, {'name': 'sample_rate', 'type': 'int', 'description': 'How frequent (every x seconds) to fetch the sensor data, Default: 60'}, {'name': 'sensors', 'type': 'section', 'description': 'OM sensor ID (e.g. 4), a sensor type and a Modbus Address', 'repeat': True, 'min': 0, 'content': [{'name': 'sensor_id', 'type': 'int'}, {'name': 'sensor_type', 'type': 'enum', 'choices': ['temperature', 'humidity', 'brightness']}, {'name': 'modbus_address', 'type': 'int'}, {'name': 'modbus_register_length', 'type': 'int'}]}] default_config = {'modbus_port': 502, 'sample_rate': 60} def __init__(self, webinterface, logger): super(ModbusTCPSensor, self).__init__(webinterface, logger) self.logger('Starting ModbusTCPSensor plugin...') self._config = self.read_config(ModbusTCPSensor.default_config) self._config_checker = PluginConfigChecker(ModbusTCPSensor.config_description) py_modbus_tcp_egg = '/opt/openmotics/python/plugins/modbusTCPSensor/pyModbusTCP-0.1.7-py2.7.egg' if py_modbus_tcp_egg not in sys.path: sys.path.insert(0, py_modbus_tcp_egg) self._client = None self._samples = [] self._save_times = {} self._read_config() self.logger("Started ModbusTCPSensor plugin") def _read_config(self): self._ip = self._config.get('modbus_server_ip') self._port = self._config.get('modbus_port', ModbusTCPSensor.default_config['modbus_port']) self._debug = self._config.get('debug', 0) == 1 self._sample_rate = self._config.get('sample_rate', ModbusTCPSensor.default_config['sample_rate']) self._sensors = [] for sensor in self._config.get('sensors', []): if 0 <= sensor['sensor_id'] < 32: self._sensors.append(sensor) self._enabled = len(self._sensors) > 0 try: from pyModbusTCP.client import ModbusClient self._client = ModbusClient(self._ip, self._port, auto_open=True, auto_close=True) self._client.open() self._enabled = self._enabled & True except Exception as ex: self.logger('Error connecting to Modbus server: {0}'.format(ex)) self.logger('ModbusTCPSensor is {0}'.format('enabled' if self._enabled else 'disabled')) def clamp_sensor(self, value, sensor_type): clamping = {'temperature': [-32, 95.5, 1], 'humidity': [0, 100, 1], 'brightness': [0, 100, 0]} return round(max(clamping[sensor_type][0], min(value, clamping[sensor_type][1])), clamping[sensor_type][2]) @background_task def run(self): while True: try: if not self._enabled or self._client is None: time.sleep(5) continue om_sensors = {} for sensor in self._sensors: registers = self._client.read_holding_registers(sensor['modbus_address'], sensor['modbus_register_length']) if registers is None: continue sensor_value = struct.unpack('>f', struct.pack('BBBB', registers[1] >> 8, registers[1] & 255, registers[0] >> 8, registers[0] & 255))[0] if not om_sensors.get(sensor['sensor_id']): om_sensors[sensor['sensor_id']] = {'temperature': None, 'humidity': None, 'brightness': None} sensor_value = self.clamp_sensor(sensor_value, sensor['sensor_type']) om_sensors[sensor['sensor_id']][sensor['sensor_type']] = sensor_value if self._debug == 1: self.logger('The sensors values are: {0}'.format(om_sensors)) for sensor_id, values in om_sensors.iteritems(): result = json.loads(self.webinterface.set_virtual_sensor(sensor_id, **values)) if result['success'] is False: self.logger('Error when updating virtual sensor {0}: {1}'.format(sensor_id, result['msg'])) time.sleep(self._sample_rate) except Exception as ex: self.logger('Could not process sensor values: {0}'.format(ex)) time.sleep(15) @om_expose def get_config_description(self): return json.dumps(ModbusTCPSensor.config_description) @om_expose def get_config(self): return json.dumps(self._config) @om_expose def set_config(self, config): config = json.loads(config) for key in config: if isinstance(config[key], basestring): config[key] = str(config[key]) self._config_checker.check_config(config) self.write_config(config) self._config = config self._read_config() return json.dumps({'success': True})
import time import sys from math import * from multiprocessing import * from mpu6050_process_1 import MPU6050_Process_1 from mpu6050_process_2 import MPU6050_Process_2 from pyModbusTCP.client import ModbusClient with Manager() as manager: # Open a modbus client try: c = ModbusClient(host="140.116.82.50", port=7654) except ValueError: print("Error with host or port params") c.open() is_ok = c.write_single_register(0, 1) if not is_ok: print("open error") c.open() def exit_handler(): is_ok = c.write_multiple_registers(0, [0, 0, 0, 0, 0]) c.close() # registing exit handler atexit.register(exit_handler) # data sampling period interval = 120 sleep_time = 1 / interval