class SerialRtuChannel(BaseChannel): def __init__(self, network, channel_name, channel_protocol, channel_params, channel_manager, channel_type): self.port = channel_params.get("port", "") self.stopbits = channel_params.get("stopbits", serial.STOPBITS_ONE) self.parity = channel_params.get("parity", serial.PARITY_NONE) self.bytesize = channel_params.get("bytesize", serial.EIGHTBITS) self.baudrate = channel_params.get("baudrate", 9600) self.timeout = channel_params.get("timeout", 2) self.modbus_client = None BaseChannel.__init__(self, network, channel_name, channel_protocol, channel_params, channel_manager, channel_type) def run(self): self.modbus_client = ModbusSerialClient(method='rtu', port=self.port, baudrate=self.baudrate, stopbits=self.stopbits, parity=self.parity, bytesize=self.bytesize, timeout=self.timeout) try: self.modbus_client.connect() logger.debug("连接串口成功.") except Exception, e: logger.error("连接串口失败,错误信息:%r." % e) self.modbus_client = None
def pa #---------------------------------------------------------------------------# #---------------------------------------------------------------------------# # configure the client logging #---------------------------------------------------------------------------# import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.INFO) for port in ['/dev/ttyxuart3']: client = ModbusClient(method='rtu', port=port, baudrate=9600, timeout=1, retries=1) client.connect() try: for addr in [3,10]: # for addr in xrange(10,15): print ('Meter Modbus Address: %d' % addr) # regs = client.read_holding_registers(768,120,unit=addr); print regs.registers if regs else None # regs = client.read_holding_registers(128,4,unit=addr); print regs.registers if regs else None regs = client.read_holding_registers(142,8,unit=addr); print regs.registers if regs else None for addr in xrange(5,9): print ('Inverter Modbus Address: %d' % addr) regs = client.read_holding_registers(33,10,unit=addr); print regs.registers if regs else None except AttributeError, e: print 'Device not responding' finally:
def main(host, port, mqtt_username, mqtt_password, instance, name, serial_port): modbus = ModbusClient(method='rtu', port=serial_port, baudrate=9600, timeout=1) if not modbus.connect(): logger.error("Cannot connect to modbus") return client = mqtt.Client() client.loop_start() client.connect(host, port, 60) if mqtt_username is not None: client.username_pw_set(mqtt_username, mqtt_password) try: while True: now = int(time()) r = modbus.read_holding_registers(0, 16, unit=1) bat_volt = r.registers[8] * 96.667 * 2**(-15) bat_curr = r.registers[11] * 316.67 * 2**(-15) bat_temp = r.registers[15] client.publish('{}/{}/power'.format(instance, name), "{} {:0.2f}".format(now, bat_volt * bat_curr), 0) client.publish('{}/{}/voltage'.format(instance, name), "{} {:0.2f}".format(now, bat_volt), 0) client.publish('{}/{}/current'.format(instance, name), "{} {:0.2f}".format(now, bat_curr), 0) client.publish('{}/{}/temperature'.format(instance, name), "{} {}".format(now, bat_temp), 0) sleep(5) except KeyboardInterrupt: pass client.disconnect() client.loop_stop() modbus.close()
def main(args): global PUMP_TIME global SENSOR_TIME try: PUMP_TIME = int(args[1]) SENSOR_TIME = int(args[2]) print('using custom args. pump time: %d sensor time: %d' % (PUMP_TIME, SENSOR_TIME)) except: PUMP_TIME = 3 SENSOR_TIME = 5 print('using default args. pump time: %d sensor time: %d' % (PUMP_TIME, SENSOR_TIME)) startMeasurement() # Connect to sensor and record data try: client = ModbusClient(method = "rtu", port="/dev/ttyS0",stopbits = 1, bytesize = 8, parity = 'N', baudrate= 9600) # Connect to the serial modbus server connection = client.connect() if connection: recordData(client) # Closes the underlying socket connection client.close() except Exception as error: print('CO2 measurement failed: ' + repr(error)) finally: endMeasurement()
def run(self): global tCtrl _sample=select(tCtrl.samples,'id',self.id) _protocol=select(tCtrl.protocols,'id',_sample.properties['protocol_id']) _transport=select(tCtrl.transports,'id',_sample.properties['transport_id']) _rule=select(tCtrl.rules,'id',_sample.properties['rule_id']) _method=_protocol.properties['method'] _port=_transport.properties['port'] _para=_transport.properties['para'] _timeout=int(_transport.properties['timeout'])/1000.0 client = ModbusClient(method=_method, port=_port,baudrate= \ Baudrate(_para),bytesize=Bytesize(_para),parity=Parity(_para),\ stopbits=Stopbits(_para),timeout=_timeout) _index=int(_rule.properties['index']) _count=int(_rule.properties['count']) _unit_begin=Begin(_rule.properties['range']) _unit_end=End(_rule.properties['range']) client.connect() self.interval = int(_protocol.properties['period']) while not self.thread_stop: for i in range(_unit_begin,_unit_end): start_ = datetime.utcnow() response=client.read_holding_registers(address=_index, \ count=_count,unit=i) tCtrl.samples[self.index].data[i]=response.registers print response.registers #getRegister(1)/10.0 end_ = datetime.utcnow() print '[cost time] %s' %(end_-start_) time.sleep(self.interval)
def __init__(self, remote, timeout=0.01): if len(remote.split("."))==3: #we probably have a TCP request print "TCP connection to: ", remote self.client=ModbusTcpClient(remote, 502) self.__modbus_timeout=timeout else: if os.name!="posix" and timeout<0.03: print "RS485 timeout too low, using 0.03 seconds" self.__modbus_timeout=0.03 else: self.__modbus_timeout=timeout print "RS485 connection to: ", remote self.client=ModbusSerialClient(method="rtu", port=remote, stopbits=1,bytesize=8, parity="N",baudrate=38400, timeout=self.__modbus_timeout) #print self.client.connect() #motor tresholds, use default values unless a calibration file is loaded self.neutral=125*np.ones(5, dtype='int8') self.min_fwd=1*np.ones(5, dtype='int8') self.min_bwd=-1*np.ones(5, dtype='int8') self.motor_max=80#seems constant across all AUVs #flag for motors mounted the wrong way self.motor_spin=1*np.ones(5, dtype='int8') #flag if the motors are calibrated self.calib=False #flag to exit watchdog thread self.exit=False self.alarms_byte=0 self.__status=[0 for _ in range(16)] self.alarms_list=[[False]*12, ['Water ingress main compartment', 'Water ingress left battery', 'Water ingress right battery', 'Overheating', 'Low power', 'Over consumption', 'Maximum depth', 'Start error', 'SPI error', 'I2C error' ]] self.rwlock=threading.Lock() self.statuslock=threading.Lock() self.__motors_values=[0,0,0,0,0] self.modbus_write(1, 0xC000)#wtf ?! print "rock'n roll baby" #launch watchdog thread and exit __init__ threading.Thread(target=self.__keep_alive).start()
class PyModbusClient(BaseModbusClient): def __init__(self, *args, **kwargs): super(PyModbusClient, self).__init__(*args, **kwargs) if self.method == "tcp": from pymodbus.client.sync import ModbusTcpClient self.client = ModbusTcpClient(self.host, self.port) else: from pymodbus.client.sync import ModbusSerialClient argnames = ("stopbits", "bytesize", "parity", "baudrate", "timeout") kwargs = dict((k, getattr(self, k)) for k in argnames) kwargs.update({ "port": self.host, }) self.client = ModbusSerialClient(self.method, **kwargs) def read_coils(self, address, count): resp = self.client.read_coils(address, count, unit=self.unit) if resp is None: raise NoDeviceResponse() return resp.bits[:count] def write_coil(self, address, value): resp = self.client.write_coil(address, int(value), unit=self.unit) if resp is None: raise NoDeviceResponse() return resp.value
def testSerialClientSend(self): ''' Test the serial client send method''' client = ModbusSerialClient() self.assertRaises(ConnectionException, lambda: client._send(None)) client.socket = mockSocket() self.assertEqual(0, client._send(None)) self.assertEqual(4, client._send('1234'))
def testSerialClientRecv(self): ''' Test the serial client receive method''' client = ModbusSerialClient() self.assertRaises(ConnectionException, lambda: client._recv(1024)) client.socket = mockSocket() self.assertEqual('', client._recv(0)) self.assertEqual('\x00'*4, client._recv(4))
def testSerialClientSend(self, mock_serial): ''' Test the serial client send method''' mock_serial.in_waiting = None mock_serial.write = lambda x: len(x) client = ModbusSerialClient() self.assertRaises(ConnectionException, lambda: client._send(None)) # client.connect() client.socket = mock_serial self.assertEqual(0, client._send(None)) self.assertEqual(4, client._send('1234'))
def testSerialClientConnect(self): ''' Test the serial client connection method''' with patch.object(serial, 'Serial') as mock_method: mock_method.return_value = object() client = ModbusSerialClient() self.assertTrue(client.connect()) with patch.object(serial, 'Serial') as mock_method: mock_method.side_effect = serial.SerialException() client = ModbusSerialClient() self.assertFalse(client.connect())
def __init__(self): ModbusClient.__init__(self,method='rtu') self.port=0 self.baudrate=9600 self.bytesize=8 self.parity="E" self.stopbits=1 self.timeout=1 self.connect() self.unit=1 #slave address self.nms={"pv":0x3,"sv":0x2,}
def CONNECT_TO_METER(): try: client = None METER_PORT = find_tty_usb(ID_VENDOR, ID_PRODUCT) #reading to which port rs485(client) is connected client = ModbusClient(retries = RETRIES, method=COM_METHOD, port=METER_PORT, baudrate=BAUD_RATE, stopbits=STOP_BITS, parity=PARITY, bytesize=BYTE_SIZE, timeout=TIME_OUT) client.connect() return client except Exception as e: lgr.error('Error while connecting client: ', exc_info = True) print "Error while connecting client: \n"+e.__str__()
def serialinit(): try: client = ModbusClient(method='ascii', port='/dev/ttyMP2', parity='E', timeout=1 ) val = client.connect() if val: print "Connection open to client." return client else: print "Error in Client Connection!" return None except: return None
class SerialRtuChannel(BaseChannel): def __init__(self, channel_params, devices_file_name, protocol, mqtt_client, network_name): BaseChannel.__init__(self, channel_params, devices_file_name, protocol, mqtt_client, network_name) # 配置项 self.port = channel_params.get("port", "") self.baund = channel_params.get("baund", 9600) self.stopbits = channel_params.get("stopbits", serial.STOPBITS_ONE) self.parity = channel_params.get("parity", serial.PARITY_NONE) self.bytesize = channel_params.get("bytesize", serial.EIGHTBITS) self.timeout = channel_params.get("timeout", 2) self.protocol.set_device_info(self.port, self.baund) # modbus通信对象 self.modbus_client = ModbusSerialClient(method='rtu', port=self.port, baudrate=self.baund, stopbits=self.stopbits, parity=self.parity, bytesize=self.bytesize, timeout=self.timeout) @staticmethod def check_config(channel_params): if "port" not in channel_params or "baund" not in channel_params: return False return BaseChannel.check_config(channel_params) def run(self): # 首先上报设备数据 for device_id in self.devices_info_dict: device_info = self.devices_info_dict[device_id] device_msg = { "device_id": device_info["device_id"], "device_type": device_info["device_type"], "device_addr": device_info["device_addr"], "device_port": device_info["device_port"], "protocol": self.protocol.protocol_type, "data": "" } self.mqtt_client.publish_data(device_msg) try: self.modbus_client.connect() logger.debug("连接串口成功.") except Exception, e: logger.error("连接串口失败,错误信息:%r." % e) self.modbus_client = None return while True: # 该线程保持空转 time.sleep(5)
def main(): if len(sys.argv) != 4: print( """Usage: ./orno_modbus.py serial_port device_address target_device_address Example: ./orno_modbus.py /dev/ttyUSB0 1 11 If you have only one device you can set the device_address to 0 to change its address. """) sys.exit(0) port = sys.argv[1] address = int(sys.argv[2]) target_address = int(sys.argv[3]) client = ModbusClient(method="rtu", port=port, baudrate=9600) client.connect() request = SendOrnoPassword('00000000', unit=address) client.execute(request) response = client.write_registers(15, [target_address], unit=address) if response: if address: print "Success. Changed address from %d to %d." % (address, target_address) else: print "Success. Changed address to %d." % (target_address) else: print "Address change failed" client.close()
def CONNECT_TO_METER(): try: client = None METER_PORT = find_tty_usb(ID_VENDOR, ID_PRODUCT) #reading to which port rs485(client) is connected client = ModbusClient(retries = RETRIES, method=COM_METHOD, port=METER_PORT, baudrate=BAUD_RATE, stopbits=STOP_BITS, parity=PARITY, bytesize=BYTE_SIZE, timeout=TIME_OUT) client.connect() return client except Exception as e: print "Could not connect to client: \n" + e.__str__() log_file=open(DATA_BASE_PATH+"RealtimeLOG.txt","a") log_file.write(str(time.time())+" Could not connect to client: \n"+e.__str__()+"\n") log_file.close()
def __init__(self, *args, **kwargs): super(PyModbusClient, self).__init__(*args, **kwargs) if self.method == "tcp": from pymodbus.client.sync import ModbusTcpClient self.client = ModbusTcpClient(self.host, self.port) else: from pymodbus.client.sync import ModbusSerialClient argnames = ("stopbits", "bytesize", "parity", "baudrate", "timeout") kwargs = dict((k, getattr(self, k)) for k in argnames) kwargs.update({ "port": self.host, }) self.client = ModbusSerialClient(self.method, **kwargs)
def setUp(self): """ Initializes the test environment """ super(Runner, self).setUp() # "../tools/nullmodem/linux/run", self.initialize(["../tools/reference/diagslave", "-m", "ascii", "/dev/pts/14"]) self.client = ModbusClient(method='ascii', timeout=0.2, port='/dev/pts/13') self.client.connect()
def connectToDevice(self, device): """Connection to the client - the method takes the IP address (as a string, e.g. '192.168.1.11') as an argument.""" self.client = ModbusSerialClient(method='rtu',port=device,stopbits=1, bytesize=8, baudrate=115200, timeout=0.2) if not self.client.connect(): print "Unable to connect to %s" % device return False return True
def main(): mbAddress = 252 baud = 19200 comPort = '/dev/ttyUSB0' mb = ModbusClient(method='rtu', port=comPort, baudrate=baud, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_NONE, bytesize=serial.EIGHTBITS, timeout=3) connection = mb.connect() if connection == False: print "Connection failed\n" quit() else: print "Connection successful\n" TestCommunication(mb, mbAddress)
def __init__(self, unit, modbus_config): self.client = ModbusSerialClient(**modbus_config) self.unit = unit self.valid_commands = { 'read_holding_registers': self.read_holding_registers, 'write_registers': self.write_holding_registers, 'read_input_registers': self.read_input_registers, 'read_coils': self.read_coils, 'write_coils': self.write_coils, 'get_datetime': self.get_datetime, 'set_datetime': self.set_datetime, 'get_loginterval': self.get_loginterval, 'set_loginterval': self.set_loginterval, 'read_event': self.read_event, 'write_event': self.write_event, 'enable_event': self.enable_event, 'disable_event': self.disable_event, 'read_events': self.read_events, 'disable_event': self.disable_event, 'enable_event': self.enable_event, 'disable_relay': self.disable_relay, 'enable_relay': self.enable_relay, 'temperatura': self.get_temperature, 'humedad': self.get_humidity, 'luz': self.get_light, }
def connect(self, vendor="", product="", meter_port=None): """Connects to a specific port (if specified). Else, if the device details of USB-Modbus device are given, finds the port on which they are attached. This may be needed as the serial port on RPi was observed to. Parameters ---------- vendor: string product: string Returns -------- client : ModbusSerialClient """ if meter_port is None: self.vendor = vendor self.product = product self.meter_port = find_tty_usb(vendor, product) else: self.meter_port = meter_port self.logger.info('Connecting to port: %s' % self.meter_port) self.client = ModbusClient( retries=self.retries, method=self.com_method, baudrate=self.baudrate, stopbits=self.stopbits, parity=self.parity, bytesize=self.bytesize, timeout=self.timeout, port=self.meter_port) self.logger.info('Connected to port: %s' % self.meter_port) return self.client
class SynchronousRtuClient(Runner, unittest.TestCase): """ These are the integration tests for the synchronous serial rtu client. """ def setUp(self): """ Initializes the test environment """ super(Runner, self).setUp() self.initialize(["../tools/reference/diagslave", "-m", "rtu", "/dev/pts/14"]) self.client = ModbusClient(method='rtu', timeout=0.2, port='/dev/pts/13') self.client.connect() def tearDown(self): """ Cleans up the test environment """ self.client.close() super(Runner, self).tearDown()
def __init__(self, serial_socket): self.logger = logging.getLogger(__name__) self.client = ModbusClient(method='rtu', port=serial_socket, timeout=1) modbus_client_filter = ModbusClientFilter() logging.getLogger("pymodbus.client.sync").addFilter( modbus_client_filter)
class SynchronousAsciiClient(Runner, unittest.TestCase): ''' These are the integration tests for the synchronous serial ascii client. ''' def setUp(self): ''' Initializes the test environment ''' super(Runner, self).setUp() # "../tools/nullmodem/linux/run", self.initialize(["../tools/reference/diagslave", "-m", "ascii", "/dev/pts/14"]) self.client = ModbusClient(method='ascii', timeout=0.2, port='/dev/pts/13') self.client.connect() def tearDown(self): ''' Cleans up the test environment ''' self.client.close() super(Runner, self).tearDown()
def run_motor_gui(tkroot): client = ModbusClient(method="rtu", port="/dev/ttyUSB1", stopbits=1, \ bytesize=8, parity='E', baudrate=9600, timeout=0.1) # connect to the serial modbus server connection = client.connect() print("Connection = " + str(connection)) # Create and set up the GUI object root = Toplevel(tkroot) root.title("WIFIS Motor Controller") root.geometry("250x375") #root.protocol("WM_DELETE_WINDOW", on_closing) app = MainApplication(root,client) return client
def __init__(self): self.__parseConfig() # Configure logging on the client logging.basicConfig() self.log = logging.getLogger() # Change to DEBUG for full information during runtime self.log.setLevel(logging.INFO) # Setup and Open the connection self.client = ModbusClient(**self.comSettings)
def CONNECT_TO_METER(self): try: clt = None METER_PORT = self.find_tty_usb(self.ID_VENDOR, self.ID_PRODUCT) #reading to which port rs485(client) is connected clt = ModbusClient(retries=self.RETRIES, method=self.COM_METHOD, port=METER_PORT, baudrate=self.BAUD_RATE, stopbits=self.STOP_BITS, parity=self.PARITY, bytesize=self.BYTE_SIZE, timeout=self.TIME_OUT) self.iftrue = clt.connect() if self.iftrue: print "Connection successful. " + str(clt) return clt except Exception as e: #lgr.error('Error while connecting client: ', exc_info = True) print "Error while connecting client: \n" + e.__str__()
class Epever3210a(object): # CONSTANTS # VARIABLES _logger = None _console_handler = None _file_handler = None _csv_file_dir = '/var/dl/' _slave_address = 1 _serial_port = '/dev/ttyUSB0' _baudrate = 115200 _dl_bytes_decoder = DlBytesDecoder() _modbus_client = None _modbus_items = [] # SETTERS AND GETTERS @property def logger(self): return self._logger @logger.setter def logger(self, v): self._logger = v # FUNCTIONS DEFINITION def __init__(self): """ Initialize """ try: self.init_arg_parse() #*** Logger self._logger = DlLogger().new_logger(__name__) except OSError as l_e: self._logger.warning("init-> OSError, probably rollingfileAppender:{}".format(l_e)) if e.errno != errno.ENOENT: raise l_e except Exception as l_e: self._logger.error('Error in init: {}'.format(l_e)) raise l_e #exit(1) # SCRIPT ARGUMENTS def init_arg_parse(self): """ Parsing arguments """ self._parser = argparse.ArgumentParser(description='Actions with Epever3210a through USB dongle') self._add_arguments() args = self._parser.parse_args() self._args = args def _add_arguments(self): """ Add arguments to parser (called by init_arg_parse()) """ self._parser.add_argument('-v', '--verbose', help='increase output verbosity', action="store_true") self._parser.add_argument('-d', '--display_results', help='Display results as logger.info', action="store_true") self._parser.add_argument('-s', '--store_csv', help='stores output to CSV', action="store_true") self._parser.add_argument('-t', '--test', help='Runs test method', action="store_true") def execute_corresponding_args( self ): """ Parsing arguments and calling corresponding functions """ try: if self._args.verbose: self._logger.setLevel(logging.DEBUG) else: self._logger.setLevel(logging.INFO) self._modbus_client = ModbusSerialClient(method="rtu", port=self._serial_port, timeout=3, stopbits=1, bytesize=8, baudrate=self._baudrate) self._modbus_client.connect() if self._args.test: self.test() self.read_items() if self._args.display_results: self.display_items() if self._args.store_csv: self.store_to_csv() except Exception as l_e: self._logger.error('Error in execute_corresponding_args: {}'.format(l_e)) self._modbus_client.close() raise l_e def extend_items(self, a_dl_modbus_item): """ Adds given item to self._modbus_items """ self._modbus_items.append(a_dl_modbus_item) def read_items(self): """ Reads all items """ self.extend_items(DlModbusItem(0x3100, 'PV Array voltage', 'PVV', 1, 'V', 0)) self.extend_items(DlModbusItem(0x3101, 'PV array current', 'PVA', 1, 'A', 0)) self.extend_items(DlModbusItem(0x3102, 'PV array input power', 'PVP', 2, 'W', 0)) self.extend_items(DlModbusItem(0x310C, 'Load voltage', 'LV', 1, 'V', 0)) self.extend_items(DlModbusItem(0x310D, 'Load current', 'LA', 1, 'A', 0)) self.extend_items(DlModbusItem(0x310E, 'Load Power', 'LP', 2, 'W', 0)) self.extend_items(DlModbusItem(0x3110, 'Battery temperature', 'BTemp', 1, 'C', 0)) self.extend_items(DlModbusItem(0x3111, 'Device temperature', 'DTemp', 1, 'C', 0)) self.extend_items(DlModbusItem(0x311A, 'Battery remaining capacity', 'BattRemCap', 1, '%', 0)) self.extend_items(DlModbusItem(0x311D, 'Battery rated voltage', 'BattRatV', 1, 'V', 0)) self.extend_items(DlModbusItem(0x3200, 'Battery status', 'BattSt', 1, 'Enum', 0)) self.extend_items(DlModbusItem(0x3201, 'Charging equipment status', 'ChSt', 1, 'Enum', 0)) self.extend_items(DlModbusItem(0x3302, 'Max voltage today', 'BattVMaxDay', 1, 'V', 0)) self.extend_items(DlModbusItem(0x3303, 'Min voltage today', 'BattVMinDay', 1, 'V', 0)) self.extend_items(DlModbusItem(0x3304, 'Consumed energy today', 'LoadPDay', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x3306, 'Consumed energy month', 'LoadPMonth', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x3308, 'Consumed energy year', 'LoadPYear', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x330A, 'Total consumed energy', 'LoadPTot', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x330C, 'Generated energy today', 'GenPDay', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x330E, 'Generated energy month', 'GenPMonth', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x3310, 'Generated energy year', 'GenPYear', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x3312, 'Total Generated energy', 'GenPTot', 2, 'kWh', 0)) self.extend_items(DlModbusItem(0x331A, 'Battery voltage', 'BattV', 1, 'V', 0)) self.extend_items(DlModbusItem(0x331B, 'Battery current', 'BattA', 2, 'A', 0)) self.read_modbus_items() def read_modbus_items(self): """ """ for l_item in self._modbus_items: self._logger.debug('--> reading register:{} registers_count:{} slave:{}'.format(l_item._address, l_item._registers_count, self._slave_address)) try: l_registers_array = self._modbus_client.read_input_registers(l_item._address, l_item._registers_count, unit=self._slave_address) #self._logger.debug('-- register result:{}'.format(l_registers_array)) if l_item._registers_count == 1: l_val = float(l_registers_array.registers[0] / 100.0) elif l_item._registers_count == 2: l_low = float(l_registers_array.registers[0] / 100.0) l_high = float(l_registers_array.registers[1] / 100.0) l_val = l_low + (l_high * 100) # for readability #self._logger.debug('-- registers result:L/H({}/{})={}'.format(l_low, l_high, l_val)) l_item._item = l_val except Exception as l_e: self._logger.warning('Unable to get a valid answer from register "{}" index:{}/hex({}), registers_count:{}'.format(l_item._description, l_item._address, hex(l_item._address), l_item._registers_count)) def display_items(self): """ Displays information with logger on self._modbus_items """ for l_item in self._modbus_items: self._logger.info(l_item.out()) def get_mac(self): from uuid import getnode as get_mac mac = get_mac() l_res = '-'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2)) l_res = l_res.lower() self._logger.warning('mac:{}-'.format(l_res)) return l_res def csv_file_path(self): """ returns a complete file path for csv exporting creates directory if not exists """ l_res = os.path.join(self._csv_file_dir, str(datetime.utcnow().year), '{:02d}'.format(datetime.utcnow().month)) if not os.path.exists(l_res): os.makedirs(l_res) l_fname = datetime.utcnow().strftime('%Y%m%d') + '_' + self.get_mac() + '_' + self.__class__.__name__ + '.csv' l_res = os.path.join(l_res, l_fname) return l_res def _header_rows(self): l_res = [] l_res.append(['#Device', self.__class__.__name__]) l_res.append(['#Mac', self.get_mac()]) return l_res def store_to_csv(self): try: l_f_name = self.csv_file_path() l_file_exists = os.path.isfile(l_f_name) self._logger.info("store_to_csv->Writting into file {} exists:{}".format(l_f_name, l_file_exists)) with open(l_f_name, mode='a+') as l_csv_file: l_csv_writter = csv.writer(l_csv_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) if not l_file_exists: #Header comments for l_header_row in self._header_rows(): self._logger.info("store_values_into_csv->writting header:{}".format(l_header_row)) l_csv_writter.writerow(l_header_row) self._logger.info("store_to_csv->Writting METADATA row: %s" % (';'.join(str(l) for l in l_header_row))) #Headers l_fields_abbr_row = [] l_fields_abbr_row.append('Timestamp') for l_dl_modbus_item in self._modbus_items: l_fields_abbr_row.append(l_dl_modbus_item._abbreviation) l_csv_writter.writerow(l_fields_abbr_row) self._logger.info("store_to_csv->Writting Headers row: %s" % (';'.join(str(l) for l in l_fields_abbr_row))) # Metadata and registers l_values_dict = [] l_values_dict.append(datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')) for l_dl_modbus_item in self._modbus_items: l_values_dict.append(l_dl_modbus_item._item) #Registers no metadata self._logger.info("store_to_csv->Writting row: %s" % ('|'.join(str(l) for l in l_values_dict))) l_csv_writter.writerow(l_values_dict) except Exception as l_e: self._logger.error('store_values_into_csv->Error: %s' % l_e) raise l_e # TEST def test(self): """ Test function """ try: self._logger.info("################# BEGIN #################") l_od = OrderedDict() l_registers_array = self._modbus_client.read_input_registers(0x3100, 4, unit=1) l_od['solar_voltage,V'] = float(l_registers_array.registers[0] / 100.0) l_od['solar_current,A'] = float(l_registers_array.registers[1] / 100.0) l_od['input_power_l,W'] = float(l_registers_array.registers[2] / 100.0) l_od['input_power_h,W'] = float(l_registers_array.registers[3] / 100.0) l_registers_array = self._modbus_client.read_input_registers(0x310C, 4, unit=1) l_od['load_voltage,V'] = float(l_registers_array.registers[0] / 100.0) l_od['load_current,A'] = float(l_registers_array.registers[1] / 100.0) l_od['load_power_l,W'] = float(l_registers_array.registers[2] / 100.0) l_od['load_power_h,W'] = float(l_registers_array.registers[3] / 100.0) l_registers_array = self._modbus_client.read_input_registers(0x3302, 8, unit=1) l_od['max_battery_voltage_today,V'] = float(l_registers_array.registers[0] / 100.0) l_od['min_battery_voltage_today,A'] = float(l_registers_array.registers[1] / 100.0) l_od['tot_energy_today L,kWh'] = float(l_registers_array.registers[2] / 100.0) l_od['tot_energy_today H,kWh'] = float(l_registers_array.registers[3] / 100.0) l_od['tot_energy_month L,kWh'] = float(l_registers_array.registers[4] / 100.0) l_od['tot_energy_month H,kWh'] = float(l_registers_array.registers[5] / 100.0) l_registers_array = self._modbus_client.read_input_registers(0x330A, 6, unit=1) l_od['total_consumed_energy L,kWh'] = float(l_registers_array.registers[0] / 100.0) l_od['total_consumed_energy H,kWh'] = float(l_registers_array.registers[1] / 100.0) l_od['generated_energy_today L,kWh'] = float(l_registers_array.registers[2] / 100.0) l_od['generated_energy_today H,kWh'] = float(l_registers_array.registers[3] / 100.0) l_od['generated_energy_this_month L,kWh'] = float(l_registers_array.registers[4] / 100.0) l_od['generated_energy_this_month H,kWh'] = float(l_registers_array.registers[5] / 100.0) # l_registers_array = self._modbus_client.read_input_registers(0x9013, 3, unit=1) #P.15 of doc # l_od['real_time_clock,YMDHMS'] = float(l_registers_array.registers[0] / 100.0) for l_key, l_val in l_od.items(): l_tmp_array = l_key.split(',') l_label = l_tmp_array[0] l_unit = l_tmp_array[1] self._logger.info('{}: {} {}'.format(l_label, l_val, l_unit)) self._logger.info("################# END #################") except Exception as l_e: self._logger.exception("Exception occured: {}".format(l_e)) print('Error: {}'.format(l_e)) self._logger.error('Error: {}'.format(l_e)) sys.exit(1)
class SDM630ModbusV2(object): ## # Create a new class to fetch data from the Modbus interface of Solax inverters def __init__(self, port, baudrate, parity, stopbits, timeout): self.port = port self.client = ModbusSerialClient(method="rtu", port=self.port, baudrate=baudrate, parity=parity, stopbits=stopbits, timeout=timeout) def fetch(self, completionCallback): base = 0x0000 result = self.client.read_input_registers(base, 60) if isinstance(result, ModbusException): print("Exception from SDM630V2: {}".format(result)) return self.vals = {} self.vals['name'] = self.port.replace("/dev/tty", "") self.vals['Phase 1 line to neutral volts'] = float32( result, base, 0x0000) self.vals['Phase 2 line to neutral volts'] = float32( result, base, 0x0002) self.vals['Phase 3 line to neutral volts'] = float32( result, base, 0x0004) self.vals['Phase 1 current'] = float32(result, base, 0x0006) self.vals['Phase 2 current'] = float32(result, base, 0x0008) self.vals['Phase 3 current'] = float32(result, base, 0x000A) self.vals['Phase 1 power'] = float32(result, base, 0x000C) self.vals['Phase 2 power'] = float32(result, base, 0x000E) self.vals['Phase 3 power'] = float32(result, base, 0x0010) self.vals['Phase 1 volt amps'] = float32(result, base, 0x0012) self.vals['Phase 2 volt amps'] = float32(result, base, 0x0014) self.vals['Phase 3 volt amps'] = float32(result, base, 0x0016) self.vals['Phase 1 volt amps reactive'] = float32(result, base, 0x0018) self.vals['Phase 2 volt amps reactive'] = float32(result, base, 0x001A) self.vals['Phase 3 volt amps reactive'] = float32(result, base, 0x001C) self.vals['Phase 1 power factor'] = float32(result, base, 0x001E) self.vals['Phase 2 power factor'] = float32(result, base, 0x0020) self.vals['Phase 3 power factor'] = float32(result, base, 0x0022) self.vals['Phase 1 phase angle'] = float32(result, base, 0x0024) self.vals['Phase 2 phase angle'] = float32(result, base, 0x0026) self.vals['Phase 3 phase angle'] = float32(result, base, 0x0028) self.vals['Average line to neutral volts'] = float32( result, base, 0x002A) self.vals['Average line current'] = float32(result, base, 0x002E) self.vals['Sum of line currents'] = float32(result, base, 0x0030) self.vals['Total system power'] = float32(result, base, 0x0034) self.vals['Total system volt amps'] = float32(result, base, 0x0038) base = 0x003C result = self.client.read_input_registers(base, 48) if isinstance(result, ModbusException): print("Exception from SDM630V2: {}".format(result)) return self.vals['Total system VAr'] = float32(result, base, 0x003C) self.vals['Total system power factor'] = float32(result, base, 0x003E) self.vals['Total system phase angle'] = float32(result, base, 0x0042) self.vals['Frequency of supply voltages'] = float32( result, base, 0x0046) self.vals['Total import kWh'] = float32(result, base, 0x0048) self.vals['Total export kWh'] = float32(result, base, 0x004A) self.vals['Total import kVArh '] = float32(result, base, 0x004C) self.vals['Total export kVArh '] = float32(result, base, 0x004E) self.vals['Total VAh'] = float32(result, base, 0x0050) self.vals['Ah'] = float32(result, base, 0x0052) self.vals['Total system power demand'] = float32(result, base, 0x0054) self.vals['Maximum total system power demand'] = float32( result, base, 0x0056) self.vals['Total system VA demand'] = float32(result, base, 0x0064) self.vals['Maximum total system VA demand'] = float32( result, base, 0x0066) self.vals['Neutral current demand'] = float32(result, base, 0x0068) self.vals['Maximum neutral current demand'] = float32( result, base, 0x006A) base = 0x00C8 result = self.client.read_input_registers(base, 8) if isinstance(result, ModbusException): print("Exception from SDM630V2: {}".format(result)) return self.vals['Line 1 to Line 2 volts'] = float32(result, base, 0x00C8) self.vals['Line 2 to Line 3 volts'] = float32(result, base, 0x00CA) self.vals['Line 3 to Line 1 volts'] = float32(result, base, 0x00CC) self.vals['Average line to line volts'] = float32(result, base, 0x00CE) base = 0x00E0 result = self.client.read_input_registers(base, 46) if isinstance(result, ModbusException): print("Exception from SDM630V2: {}".format(result)) return self.vals['Neutral current'] = float32(result, base, 0x00E0) self.vals['Phase 1 L-N volts THD'] = float32(result, base, 0x00EA) self.vals['Phase 2 L-N volts THD'] = float32(result, base, 0x00EC) self.vals['Phase 3 L-N volts THD'] = float32(result, base, 0x00EE) self.vals['Phase 1 current THD'] = float32(result, base, 0x00F0) self.vals['Phase 2 current THD'] = float32(result, base, 0x00F2) self.vals['Phase 3 current THD'] = float32(result, base, 0x00F4) self.vals['Average line to neutral volts THD'] = float32( result, base, 0x00F8) self.vals['Average line current THD'] = float32(result, base, 0x00FA) self.vals['Phase 1 current demand'] = float32(result, base, 0x0102) self.vals['Phase 2 current demand'] = float32(result, base, 0x0104) self.vals['Phase 3 current demand'] = float32(result, base, 0x0106) self.vals['Maximum phase 1 current demand'] = float32( result, base, 0x0108) self.vals['Maximum phase 2 current demand'] = float32( result, base, 0x010A) self.vals['Maximum phase 3 current demand'] = float32( result, base, 0x010C) base = 0x014E result = self.client.read_input_registers(base, 48) if isinstance(result, ModbusException): print("Exception from SDM630V2: {}".format(result)) return self.vals['Line 1 to line 2 volts THD'] = float32(result, base, 0x014E) self.vals['Line 2 to line 3 volts THD'] = float32(result, base, 0x0150) self.vals['Line 3 to line 1 volts THD'] = float32(result, base, 0x0152) self.vals['Average line to line volts THD'] = float32( result, base, 0x0154) self.vals['Total kWh'] = float32(result, base, 0x0156) self.vals['Total kvarh'] = float32(result, base, 0x0158) self.vals['Phase 1 import kWh'] = float32(result, base, 0x015a) self.vals['Phase 2 import kWh'] = float32(result, base, 0x015c) self.vals['Phase 3 import kWh'] = float32(result, base, 0x015e) self.vals['Phase 1 export kWh'] = float32(result, base, 0x0160) self.vals['Phase 2 export kWh'] = float32(result, base, 0x0162) self.vals['Phase 3 export kWh'] = float32(result, base, 0x0164) self.vals['Phase 1 total kWh'] = float32(result, base, 0x0166) self.vals['Phase 2 total kWh'] = float32(result, base, 0x0168) self.vals['Phase 3 total kWh'] = float32(result, base, 0x016a) self.vals['Phase 1 import kvarh'] = float32(result, base, 0x016c) self.vals['Phase 2 import kvarh'] = float32(result, base, 0x016e) self.vals['Phase 3 import kvarh'] = float32(result, base, 0x0170) self.vals['Phase 1 export kvarh'] = float32(result, base, 0x0172) self.vals['Phase 2 export kvarh'] = float32(result, base, 0x0174) self.vals['Phase 3 export kvarh'] = float32(result, base, 0x0176) self.vals['Phase 1 total kvarh'] = float32(result, base, 0x0178) self.vals['Phase 2 total kvarh'] = float32(result, base, 0x017a) self.vals['Phase 3 total kvarh'] = float32(result, base, 0x017c) completionCallback(self.vals)
#from pymodbus.pdu import ModbusRequest from pymodbus.client.sync import ModbusSerialClient as ModbusClient #from pymodbus.transaction import ModbusRtuFramer #import sys #import paho.mqtt.client as mqtt #import msvcrt #import getch #import RPi.GPIO as GPIO import sys import select mbclient = ModbusClient(method="rtu", timeout=1, port='/dev/ttyUSB0', stopbits=1, bytesize=8, parity='N', baudrate=9600) connection = mbclient.connect() print(connection) time.sleep(3) #ALL SENSOR DATA ARE IN INPUT REGISTERS temp_adc_addr = 3000 voltage_adc_addr = 3001 current_adc_addr = 3002 ldr_addr = 3003 #CHIP TEMPERATURE IN HOLDING REGISTER
#!/usr/bin/python from pymodbus.client.sync import ModbusSerialClient client = ModbusSerialClient(method="rtu", port="/dev/virtualcom1", baudrate=9600, stopbits=1, bytesize=8, timeout=1) rq = client.read_holding_registers(1000, 7, unit=1) print(rq.registers)
class modbusRTUThread(QThread): # Parametros de la comunicacion serie slaveID = 2 port = '/dev/ttyUSB0' baud = 115200 bytesize = 8 parity = 'E' stopbits = 1 timeout = 1 NinReg = 29 NoutReg = 27 timeInterval = 1500 # en milisegundos stConnec = False # Datos de entrada y salida inData = Signal(object) outData = [0]*27 def __init__(self): # Se inicializa el thread QThread.__init__(self) # Se inicializa la comunicacion modbus RTU self.modbus = ModbusClient(method='rtu', port= self.port, baudrate= self.baud, bytesize= self.bytesize, parity= self.parity, stopbits= self.stopbits, timeout = self.timeout) self.modbus.connect() time.sleep(2) # Se inicializa el timer self.Refresh = QtCore.QTimer(self) self.Refresh.timeout.connect(self.getData) self.Refresh.start(self.timeInterval) def __del__(self): self.wait() def run(self): # Se inicia el timer para que inicie/continue la ejecución del thread pass def stop(self): # Se detiene el timer para detener la ejecución del thread self.Refresh.stop() def getData(self): try: # Se leen los registros del esclavo #print(datetime.datetime.now()) regsIn = self.modbus.read_holding_registers(0, self.NinReg, unit=self.slaveID) # Se desempaqueta la informacion recibida Registers = [] for k in range(0, self.NinReg): Registers.append(regsIn.getRegister(k)) self.inData.emit(Registers) # Se escriben los registros en el esclavo regsOut = self.modbus.write_registers(100, self.outData, unit=self.slaveID) #print(datetime.datetime.now()) except: # En caso de falla de comunicacion se informa y se igualan # todos los registros a -1 print("Falla en comunicacion") Registers = [0]* self.NinReg self.inData.emit(Registers)
def connect(self): # if self.master and not self.master.socket: # self.master = None if self.master is None: self.commError = False try: # as in the following the port is None, no port is opened on creation of the (py)serial object if self.type == 1: # Serial ASCII from pymodbus.client.sync import ModbusSerialClient self.master = ModbusSerialClient(method='ascii', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=True, timeout=self.timeout) elif self.type == 2: # Serial Binary from pymodbus.client.sync import ModbusSerialClient # @Reimport self.master = ModbusSerialClient(method='binary', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=True, timeout=self.timeout) elif self.type == 3: # TCP from pymodbus.client.sync import ModbusTcpClient try: self.master = ModbusTcpClient( host=self.host, port=self.port, retry_on_empty=True, retries=1, timeout=0.9, #self.timeout ) self.readRetries = 0 except: self.master = ModbusTcpClient( host=self.host, port=self.port, ) elif self.type == 4: # UDP from pymodbus.client.sync import ModbusUdpClient try: self.master = ModbusUdpClient( host=self.host, port=self.port, retry_on_empty=True, retries=3, timeout=0.7, #self.timeout ) except: # older versions of pymodbus don't support the retries, timeout nor the retry_on_empty arguments self.master = ModbusUdpClient( host=self.host, port=self.port, ) else: # Serial RTU from pymodbus.client.sync import ModbusSerialClient # @Reimport self.master = ModbusSerialClient( method='rtu', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=False, strict= False, # settings this to False disables the inter char timeout restriction timeout=self.timeout) # self.master.inter_char_timeout = 0.05 self.readRetries = 1 self.master.connect() self.updateActiveRegisters() time.sleep(.5) # avoid possible hickups on startup if self.isConnected() != None: self.sendmessage( QApplication.translate("Message", "Connected via MODBUS", None)) except Exception as ex: _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " connect() {0}").format( str(ex)), exc_tb.tb_lineno)
class modbusport(object): """ this class handles the communications with all the modbus devices""" def __init__(self, sendmessage, adderror, addserial, aw): self.sendmessage = sendmessage # function to create an Artisan message to the user in the message line self.adderror = adderror # signal an error to the user self.addserial = addserial # add to serial log self.aw = aw # retries self.readRetries = 1 #default initial settings. They are changed by settingsload() at initiation of program acording to the device chosen self.comport = "COM5" #NOTE: this string should not be translated. self.baudrate = 115200 self.bytesize = 8 self.parity = 'N' self.stopbits = 1 self.timeout = 1.0 self.PID_slave_ID = 0 self.PID_SV_register = 0 self.PID_p_register = 0 self.PID_i_register = 0 self.PID_d_register = 0 self.PID_ON_action = "" self.PID_OFF_action = "" self.channels = 8 self.inputSlaves = [0] * self.channels self.inputRegisters = [0] * self.channels self.inputFloats = [False] * self.channels self.inputBCDs = [False] * self.channels self.inputCodes = [3] * self.channels self.inputDivs = [0] * self.channels # 0: none, 1: 1/10, 2:1/100 self.inputModes = ["C"] * self.channels self.optimizer = True # if set, values of consecutive register addresses are requested in single requests # MODBUS functions associated to dicts associating MODBUS slave ids to registers in use # for optimized read of full register segments with single request # this dict is re-computed on each connect() by a call to updateActiveRegisters() # NOTE: for registers of type float (32bit = 2x16bit) also the succeeding register is registered here self.activeRegisters = {} # the readings cache that is filled by requesting sequences of values in blocks self.readingsCache = {} self.SVmultiplier = 0 self.PIDmultiplier = 0 self.byteorderLittle = False self.wordorderLittle = True self.master = None self.COMsemaphore = QSemaphore(1) self.host = '127.0.0.1' # the TCP/UDP host self.port = 502 # the TCP/UDP port self.type = 0 # type = # 0: Serial RTU # 1: Serial ASCII # 2: Serial Binary # 3: TCP # 4: UDP self.lastReadResult = 0 # this is set by eventaction following some custom button/slider Modbus actions with "read" command self.commError = False # True after a communication error was detected and not yet cleared by receiving proper data # this garantees a minimum of 30 miliseconds between readings and 80ms between writes (according to the Modbus spec) on serial connections # this sleep delays between requests seems to be beneficial on slow RTU serial connections like those of the FZ-94 def sleepBetween(self, write=False): if write: # if self.type in [3,4]: # TCP or UDP # time.sleep(0.040) pass # handled in MODBUS lib # else: time.sleep(0.035) else: if self.type in [ 3, 4 ]: # delay between writes only on serial connections pass else: time.sleep(0.035) def address2register(self, addr, code=3): if code == 3 or code == 6: return addr - 40001 else: return addr - 30001 def isConnected(self): return not (self.master is None) and self.master.socket def disconnect(self): try: self.master.close() except Exception: pass self.master = None def updateActiveRegisters(self): self.activeRegisters = {} for c in range(self.channels): slave = self.inputSlaves[c] if slave != 0: register = self.inputRegisters[c] code = self.inputCodes[c] registers = [register] if self.inputFloats[c] or self.inputBCDs[c]: registers.append(register + 1) if not (code in self.activeRegisters): self.activeRegisters[code] = {} if slave in self.activeRegisters[code]: self.activeRegisters[code][slave].extend(registers) else: self.activeRegisters[code][slave] = registers def clearReadingsCache(self): self.readingsCache = {} def cacheReadings(self, code, slave, register, results): if not (code in self.readingsCache): self.readingsCache[code] = {} if not slave in self.readingsCache[code]: self.readingsCache[code][slave] = {} for i, v in enumerate(results): self.readingsCache[code][slave][register + i] = v # {4: {1: [19], 0: [23]}, 3: {0: [12393, 12390, 8451, 8451]}} def readActiveRegisters(self): if not self.optimizer: return try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() self.clearReadingsCache() for code in self.activeRegisters: for slave in self.activeRegisters[code]: registers = sorted(self.activeRegisters[code][slave]) # split in successive sequences gaps = [[s, e] for s, e in zip(registers, registers[1:]) if s + 1 < e] edges = iter(registers[:1] + sum(gaps, []) + registers[-1:]) sequences = list( zip(edges, edges) ) # list of pairs of the form (start-register,end-register) for seq in sequences: retry = self.readRetries register = seq[0] count = seq[1] - seq[0] + 1 res = None self.sleepBetween( ) # we start with a sleep, as it could be that just a send command happend before the semaphore was catched while True: try: # we cache only MODBUS function 3 and 4 (not 1 and 2!) if code == 3: res = self.master.read_holding_registers( register, count, unit=slave) elif code == 4: res = self.master.read_input_registers( register, count, unit=slave) except Exception: res = None if res is None or res.isError( ): # requires pymodbus v1.5.1 if retry > 0: retry = retry - 1 time.sleep(0.020) else: raise Exception("Exception response") else: break if res is not None: if self.commError: # we clear the previous error and send a message self.commError = False self.adderror( QApplication.translate( "Error Message", "Modbus Communication Resumed", None)) self.cacheReadings(code, slave, register, res.registers) #note: logged chars should be unicode not binary if self.aw.seriallogflag: ser_str = "MODBUS readSingleRegister : {},{},{},{},{},{} || Slave = {} || Register = {} || Code = {} || Rx = {}".format( self.comport, self.baudrate, self.bytesize, self.parity, self.stopbits, self.timeout, slave, register, code, res) self.addserial(ser_str) except Exception: # as ex: # self.disconnect() # import traceback # traceback.print_exc(file=sys.stdout) # _, _, exc_tb = sys.exc_info() # self.adderror((QApplication.translate("Error Message","Modbus Error:",None) + " readSingleRegister() {0}").format(str(ex)),exc_tb.tb_lineno) self.adderror( QApplication.translate("Error Message", "Modbus Communication Error", None)) self.commError = True finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) def connect(self): # if self.master and not self.master.socket: # self.master = None if self.master is None: self.commError = False try: # as in the following the port is None, no port is opened on creation of the (py)serial object if self.type == 1: # Serial ASCII from pymodbus.client.sync import ModbusSerialClient self.master = ModbusSerialClient(method='ascii', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=True, timeout=self.timeout) elif self.type == 2: # Serial Binary from pymodbus.client.sync import ModbusSerialClient # @Reimport self.master = ModbusSerialClient(method='binary', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=True, timeout=self.timeout) elif self.type == 3: # TCP from pymodbus.client.sync import ModbusTcpClient try: self.master = ModbusTcpClient( host=self.host, port=self.port, retry_on_empty=True, retries=1, timeout=0.9, #self.timeout ) self.readRetries = 0 except: self.master = ModbusTcpClient( host=self.host, port=self.port, ) elif self.type == 4: # UDP from pymodbus.client.sync import ModbusUdpClient try: self.master = ModbusUdpClient( host=self.host, port=self.port, retry_on_empty=True, retries=3, timeout=0.7, #self.timeout ) except: # older versions of pymodbus don't support the retries, timeout nor the retry_on_empty arguments self.master = ModbusUdpClient( host=self.host, port=self.port, ) else: # Serial RTU from pymodbus.client.sync import ModbusSerialClient # @Reimport self.master = ModbusSerialClient( method='rtu', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=False, strict= False, # settings this to False disables the inter char timeout restriction timeout=self.timeout) # self.master.inter_char_timeout = 0.05 self.readRetries = 1 self.master.connect() self.updateActiveRegisters() time.sleep(.5) # avoid possible hickups on startup if self.isConnected() != None: self.sendmessage( QApplication.translate("Message", "Connected via MODBUS", None)) except Exception as ex: _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " connect() {0}").format( str(ex)), exc_tb.tb_lineno) # function 15 (Write Multiple Coils) def writeCoils(self, slave, register, values): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() self.master.write_coils(int(register), list(values), unit=int(slave)) time.sleep(.3) # avoid possible hickups on startup except Exception as ex: # self.disconnect() # import traceback # traceback.print_exc(file=sys.stdout) _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " writeCoils() {0}").format(str(ex)), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) # function 5 (Write Single Coil) def writeCoil(self, slave, register, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() self.master.write_coil(int(register), value, unit=int(slave)) time.sleep(.3) # avoid possible hickups on startup except Exception as ex: # self.disconnect() _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " writeCoil() {0}").format(str(ex)), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) # write value to register on slave (function 6 for int or function 16 for float) # value can be one of string (containing an int or float), an int or a float def writeRegister(self, slave, register, value): if stringp(value): if "." in value: self.writeWord(slave, register, value) else: self.writeSingleRegister(slave, register, value) elif isinstance(value, int): self.writeSingleRegister(slave, register, value) elif isinstance(value, float): self.writeWord(slave, register, value) # function 6 (Write Single Holding Register) def writeSingleRegister(self, slave, register, value): # _logger.debug("writeSingleRegister(%d,%d,%d)" % (slave,register,value)) try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() self.master.write_register(int(register), int(value), unit=int(slave)) time.sleep(.03) # avoid possible hickups on startup except Exception as ex: # _logger.debug("writeSingleRegister exception: %s" % str(ex)) # import traceback # traceback.print_exc(file=sys.stdout) # self.disconnect() _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " writeSingleRegister() {0}").format(str(ex)), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) # function 22 (Mask Write Register) # bits to be modified are "masked" with a 0 in the and_mask (not and_mask) # new bit values to be written are taken from the or_mask def maskWriteRegister(self, slave, register, and_mask, or_mask): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() self.master.mask_write_register(int(register), int(and_mask), int(or_mask), unit=int(slave)) time.sleep(.03) except Exception as ex: # import traceback # traceback.print_exc(file=sys.stdout) # self.disconnect() _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " writeMask() {0}").format(str(ex)), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) # a local variant of function 22 (Mask Write Register) # the masks are evaluated locally on the given integer value and the result is send via # using function 6 def localMaskWriteRegister(self, slave, register, and_mask, or_mask, value): new_val = (int(round(value)) & and_mask) | (or_mask & (and_mask ^ 0xFFFF)) self.writeSingleRegister(slave, register, int(new_val)) # function 16 (Write Multiple Holding Registers) # values is a list of integers or one integer def writeRegisters(self, slave, register, values): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() self.master.write_registers(int(register), values, unit=int(slave)) time.sleep(.03) except Exception as ex: # self.disconnect() _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " writeRegisters() {0}").format(str(ex)), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) # function 16 (Write Multiple Holding Registers) # value=int or float # writes a single precision 32bit float (2-registers) def writeWord(self, slave, register, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() builder = getBinaryPayloadBuilder(self.byteorderLittle, self.wordorderLittle) builder.add_32bit_float(float(value)) payload = builder.build() # .tolist() self.master.write_registers(int(register), payload, unit=int(slave), skip_encode=True) time.sleep(.03) except Exception as ex: # self.disconnect() _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " writeWord() {0}").format(str(ex)), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) # translates given int value int a 16bit BCD and writes it into one register def writeBCD(self, slave, register, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() builder = getBinaryPayloadBuilder(self.byteorderLittle, self.wordorderLittle) r = convert_to_bcd(int(value)) builder.add_16bit_uint(r) payload = builder.build() # .tolist() self.master.write_registers(int(register), payload, unit=int(slave), skip_encode=True) time.sleep(.03) except Exception as ex: # self.disconnect() _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " writeWord() {0}").format(str(ex)), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) # function 3 (Read Multiple Holding Registers) and 4 (Read Input Registers) def readFloat(self, slave, register, code=3): r = None try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if code in self.readingsCache and slave in self.readingsCache[code] and register in self.readingsCache[code][slave] \ and register+1 in self.readingsCache[code][slave]: # cache hit res = [ self.readingsCache[code][slave][register], self.readingsCache[code][slave][register + 1] ] decoder = getBinaryPayloadDecoderFromRegisters( res, self.byteorderLittle, self.wordorderLittle) r = decoder.decode_32bit_float() return r else: retry = self.readRetries while True: if code == 3: res = self.master.read_holding_registers( int(register), 2, unit=int(slave)) else: res = self.master.read_input_registers(int(register), 2, unit=int(slave)) if res is None or res.isError( ): # requires pymodbus v1.5.1 if retry > 0: retry = retry - 1 #time.sleep(0.020) else: raise Exception("Exception response") else: break decoder = getBinaryPayloadDecoderFromRegisters( res.registers, self.byteorderLittle, self.wordorderLittle) r = decoder.decode_32bit_float() if self.commError: # we clear the previous error and send a message self.commError = False self.adderror( QApplication.translate("Error Message", "Modbus Communication Resumed", None)) return r except Exception: # as ex: # import traceback # traceback.print_exc(file=sys.stdout) # self.disconnect() # _, _, exc_tb = sys.exc_info() # self.adderror((QApplication.translate("Error Message","Modbus Error:",None) + " readFloat() {0}").format(str(ex)),exc_tb.tb_lineno) self.adderror( QApplication.translate("Error Message", "Modbus Communication Error", None)) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) #note: logged chars should be unicode not binary if self.aw.seriallogflag: ser_str = "MODBUS readFloat :{},{},{},{},{},{} || Slave = {} || Register = {} || Code = {} || Rx = {}".format( self.comport, self.baudrate, self.bytesize, self.parity, self.stopbits, self.timeout, slave, register, code, r) self.addserial(ser_str) # function 3 (Read Multiple Holding Registers) and 4 (Read Input Registers) def readBCD(self, slave, register, code=3): r = None try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if code in self.readingsCache and slave in self.readingsCache[code] and register in self.readingsCache[code][slave] \ and register+1 in self.readingsCache[code][slave]: # cache hit res = [ self.readingsCache[code][slave][register], self.readingsCache[code][slave][register + 1] ] decoder = getBinaryPayloadDecoderFromRegisters( [res], self.byteorderLittle, self.wordorderLittle) r = decoder.decode_32bit_uint() return convert_from_bcd(r) else: retry = self.readRetries while True: if code == 3: res = self.master.read_holding_registers( int(register), 2, unit=int(slave)) else: res = self.master.read_input_registers(int(register), 2, unit=int(slave)) if res is None or res.isError( ): # requires pymodbus v1.5.1 if retry > 0: retry = retry - 1 #time.sleep(0.020) else: raise Exception("Exception response") else: break decoder = getBinaryPayloadDecoderFromRegisters( res.registers, self.byteorderLittle, self.wordorderLittle) r = decoder.decode_32bit_uint() if self.commError: # we clear the previous error and send a message self.commError = False self.adderror( QApplication.translate("Error Message", "Modbus Communication Resumed", None)) time.sleep( 0.020 ) # we add a small sleep between requests to help out the slow Loring electronic return convert_from_bcd(r) except Exception: # as ex: # import traceback # traceback.print_exc(file=sys.stdout) # self.disconnect() # _, _, exc_tb = sys.exc_info() # self.adderror((QApplication.translate("Error Message","Modbus Error:",None) + " readBCD() {0}").format(str(ex)),exc_tb.tb_lineno) self.adderror( QApplication.translate("Error Message", "Modbus Communication Error", None)) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) #note: logged chars should be unicode not binary if self.aw.seriallogflag: ser_str = "MODBUS readBCD : {},{},{},{},{},{} || Slave = {} || Register = {} || Code = {} || Rx = {}".format( self.comport, self.baudrate, self.bytesize, self.parity, self.stopbits, self.timeout, slave, register, code, r) self.addserial(ser_str) # as readSingleRegister, but does not retry nor raise and error and returns a None instead # also does not reserve the port via a semaphore! def peekSingleRegister(self, slave, register, code=3): try: if code == 1: res = self.master.read_coils(int(register), 1, unit=int(slave)) elif code == 2: res = self.master.read_discrete_inputs(int(register), 1, unit=int(slave)) elif code == 4: res = self.master.read_input_registers(int(register), 1, unit=int(slave)) else: # code==3 res = self.master.read_holding_registers(int(register), 1, unit=int(slave)) except Exception: res = None if res is not None and not res.isError(): # requires pymodbus v1.5.1 if code in [1, 2]: if res is not None and res.bits[0]: return 1 else: return 0 else: decoder = getBinaryPayloadDecoderFromRegisters( res.registers, self.byteorderLittle, self.wordorderLittle) r = decoder.decode_16bit_uint() return r else: return None # function 1 (Read Coil) # function 2 (Read Discrete Input) # function 3 (Read Multiple Holding Registers) and # function 4 (Read Input Registers) def readSingleRegister(self, slave, register, code=3): # import logging # logging.basicConfig() # log = logging.getLogger() # log.setLevel(logging.DEBUG) r = None try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if code in self.readingsCache and slave in self.readingsCache[ code] and register in self.readingsCache[code][slave]: # cache hit res = self.readingsCache[code][slave][register] decoder = getBinaryPayloadDecoderFromRegisters( [res], self.byteorderLittle, self.wordorderLittle) r = decoder.decode_16bit_uint() return r else: retry = self.readRetries while True: try: if code == 1: res = self.master.read_coils(int(register), 1, unit=int(slave)) elif code == 2: res = self.master.read_discrete_inputs( int(register), 1, unit=int(slave)) elif code == 4: res = self.master.read_input_registers( int(register), 1, unit=int(slave)) else: # code==3 res = self.master.read_holding_registers( int(register), 1, unit=int(slave)) except Exception: res = None if res is None or res.isError( ): # requires pymodbus v1.5.1 if retry > 0: retry = retry - 1 time.sleep(0.020) else: raise Exception("Exception response") else: break if code in [1, 2]: if res is not None and res.bits[0]: r = 1 else: r = 0 if self.commError: # we clear the previous error and send a message self.commError = False self.adderror( QApplication.translate( "Error Message", "Modbus Communication Resumed", None)) return r else: decoder = getBinaryPayloadDecoderFromRegisters( res.registers, self.byteorderLittle, self.wordorderLittle) r = decoder.decode_16bit_uint() if self.commError: # we clear the previous error and send a message self.commError = False self.adderror( QApplication.translate( "Error Message", "Modbus Communication Resumed", None)) return r except Exception: # as ex: # self.disconnect() # import traceback # traceback.print_exc(file=sys.stdout) # _, _, exc_tb = sys.exc_info() # self.adderror((QApplication.translate("Error Message","Modbus Error:",None) + " readSingleRegister() {0}").format(str(ex)),exc_tb.tb_lineno) self.adderror( QApplication.translate("Error Message", "Modbus Communication Error", None)) self.commError = True finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) #note: logged chars should be unicode not binary if self.aw.seriallogflag: ser_str = "MODBUS readSingleRegister : {},{},{},{},{},{} || Slave = {} || Register = {} || Code = {} || Rx = {}".format( self.comport, self.baudrate, self.bytesize, self.parity, self.stopbits, self.timeout, slave, register, code, r) self.addserial(ser_str) def setTarget(self, sv): if self.PID_slave_ID: multiplier = 1. if self.SVmultiplier == 1: multiplier = 10. elif self.SVmultiplier == 2: multiplier = 100. self.writeSingleRegister(self.PID_slave_ID, self.PID_SV_register, int(round(sv * multiplier))) def setPID(self, p, i, d): if self.PID_slave_ID and not (self.PID_p_register == self.PID_i_register == self.PID_d_register == 0): multiplier = 1. if self.PIDmultiplier == 1: multiplier = 10. elif self.PIDmultiplier == 2: multiplier = 100. self.writeSingleRegister(self.PID_slave_ID, self.PID_p_register, p * multiplier) self.writeSingleRegister(self.PID_slave_ID, self.PID_i_register, i * multiplier) self.writeSingleRegister(self.PID_slave_ID, self.PID_d_register, d * multiplier)
if len(sys.argv) >= 2: address = int(sys.argv[1]) start_address = int(sys.argv[2]) else: address = 0x03 start_address = 500 client_settings = A(ip='192.168.55.4', port=8000, id=0x01, start_address=start_address) # rtu master from pymodbus.client.sync import ModbusSerialClient as ModbusClient client = ModbusClient(method="rtu", port="/dev/ttyUSB1",baudrate=9600,timeout=2) client.connect() rr = client.read_holding_registers(0x0062, 4, unit=address) print [hex(i) for i in rr.registers] d = rr.registers regs_rr = [ [0x1100, 4], # f1, f2 [0x1120, 6], # t1, t2, delta_t [0x1140, 4], # p1, p2 [0x1160, 4], # m1, m2 [0x1180, 2], # q1 [0x130e, 16], # e1, m1, m2, delta_m, t1, t2, p1, p2 [0x132c, 2], # v3 ]
class EPsolarTracerClient: ''' EPsolar Tracer client ''' def __init__(self, unit=1, serialclient=None, **kwargs): ''' Initialize a serial client instance ''' self.unit = unit if serialclient is None: port = kwargs.get('port', 'COM1') baudrate = kwargs.get('baudrate', 115200) self.client = ModbusClient( method="rtu", port=port, stopbits=1, bytesize=8, parity='N', baudrate=baudrate, timeout = 1.0 ) else: self.client = serialclient def connect(self): ''' Connect to the serial :returns: True if connection succeeded, False otherwise ''' cc = self.client.connect() if cc is False: print("Unable to open port. Quitting") quit() return cc def close(self): ''' Closes the underlying connection ''' return self.client.close() def read_device_info(self): #request = ReadDeviceInformationRequest(unit = self.unit) request = ReadDeviceInformationRequest(unit=self.unit) response = self.client.execute(request) return response def read_input(self, name): register = registerByName(name) if register.is_coil(): response = self.client.read_coils(register.address, register.size, unit=self.unit) elif register.is_discrete_input(): response = self.client.read_discrete_inputs(register.address, register.size, unit=self.unit) elif register.is_input_register(): response = self.client.read_input_registers(register.address, register.size, unit=self.unit) else: response = self.client.read_holding_registers(register.address, register.size, unit=self.unit) return register.decode(response) def write_output(self, name, value): register = registerByName(name) values = register.encode(value) response = False if register.is_coil(): self.client.write_coil(register.address, values, unit=self.unit) response = True elif register.is_discrete_input(): log.error("Cannot write discrete input " + repr(name)) pass elif register.is_input_register(): log.error("Cannot write input register " + repr(name)) pass else: self.client.write_registers(register.address, values, unit=self.unit) response = True return response def __enter__(self): self.connect() print("Context mngr connect") return self def __exit__(self,type,value,traceback): self.close() print("Context mngr close")
def device_polling(): if DashingEnabled: Dashlog.append("Starting device poller") ui.display() else: log.info("Starting device poller") CONF_ORNO = False CONF_EM370 = True CONF_SOLIS_4G_3P = True CONF_JANITZA_B23 = True CONF_EMONCMS = True RtuclientState = False QuerryNb = 0 HostName = 'emoncms.powerdale.com' ModbusHost = "10.10.10.101" ModbusPort = 502 emon_host = "emoncms.powerdale.com" emon_url = "/input/post.json?node=" emon_privateKey = "4dbf608f20eab1ad1d1bf4512dc85d1c" emon_node = "B4E" # for cycle in range(0, 2000): # vchart.append(50 + 50 * math.sin(cycle / 16.0)) # hchart.append(99.9 * abs(math.sin(cycle / 26.0))) # bchart.append(50 + 50 * math.sin(cycle / 6.0)) # ui.display() OR_WE_514_Registers = testmap.generate_device_dict( './mapping_tools/or_we_514-v1-1_1.json') EEM_MA370_Registers = testmap.generate_device_dict( './mapping_tools/eem_ma370-v1-1_1.json') SOLIS_4G_Registers = testmap.generate_device_dict( './mapping_tools/solis_4g_3p-v1-1_1.json') JANITZA_B23_Registers = testmap.generate_device_dict( './mapping_tools/janitza_b23-v1-1_1.json') #print(OR_WE_514_Registers) #print(json.dumps(EEM_MA370_Registers, indent='\t')) #print(OR_WE_514_Registers) #print(EEM_MA370_Registers) print(SOLIS_4G_Registers) SolarInverter = copy.deepcopy(SOLIS_4G_Registers) Grid = copy.deepcopy(EEM_MA370_Registers) Evse = copy.deepcopy(JANITZA_B23_Registers) SOLIS_Config = { 'Solar': { "NAME": "Inverter", "PORT": "/dev/ttyUSB0", "ADDRESS": 1, "DATA": SolarInverter } } EEM_Config = { 'Grid': { "NAME": "Grid", "PORT": "", "ADDRESS": 1, "DATA": Grid } } B23_Config = { 'Evse': { "NAME": "Evse", "PORT": "/dev/ttyUSB1", "ADDRESS": 2, "DATA": Evse } } # Create modbus clients if CONF_EM370: try: TcpClient = ModbusTcpClient(host=ModbusHost, port=ModbusPort, auto_open=True, timeout=5) if DashingEnabled: Dashlog.append( f"Modbus TCP client connected: {TcpClient.connect()}") else: log.info(f"Modbus TCP client connected: {TcpClient.connect()}") except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if CONF_SOLIS_4G_3P: try: Rtuclient = ModbusRtuClient(method='rtu', port='/dev/ttyUSB0', stopbits=1, bytesize=8, parity='N', baudrate=9600, timeout=1) if DashingEnabled: Dashlog.append(f"Modbus RTU port open: {Rtuclient.connect()}") else: print(f"Modbus RTU port open: {Rtuclient.connect()}") except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if CONF_JANITZA_B23: try: Rtuclient2 = ModbusRtuClient(method='rtu', port='/dev/ttyUSB1', stopbits=1, bytesize=8, parity='N', baudrate=9600, timeout=1) if DashingEnabled: Dashlog.append(f"Modbus RTU port open: {Rtuclient2.connect()}") else: print(f"Modbus RTU port open: {Rtuclient2.connect()}") except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass try: while True: #os.system('cls' if os.name == 'nt' else 'clear') QuerryNb = QuerryNb + 1 if CONF_EM370 and TcpClient.is_socket_open(): if DashingEnabled: Dashlog.append("Read EEM_MA370") ui.display() else: log.info("Read EEM_MA370") for x, z in EEM_Config.items(): if DashingEnabled: Dashlog.append(f"Reading slave {z['NAME']}") MyDict = z['DATA'] #print (MyDict) for k, y in MyDict.items(): #Log.append(y['Name']) if (y['Name'] == 'Active power'): if DashingEnabled: Dashlog.append( f"Active power: {y['Value']:.01f}W") hchart.title = f"Active power: {y['Value']:.0f}W" hchart.append(100 * y['Value'] / 5000) ui.display() rr = None try: rr = TcpClient.read_holding_registers( y['Address'], y['Size']) except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) if (isinstance(rr, ReadHoldingRegistersResponse) and (len(rr.registers) == y['Size'])): decoder = BinaryPayloadDecoder.fromRegisters( rr.registers, byteorder=Endian.Big, wordorder=Endian.Little) decoded = OrderedDict([ ('string', decoder.decode_string), ('bits', decoder.decode_bits), ('8int', decoder.decode_8bit_int), ('8uint', decoder.decode_8bit_uint), ('16int', decoder.decode_16bit_int), ('16uint', decoder.decode_16bit_uint), ('32int', decoder.decode_32bit_int), ('32uint', decoder.decode_32bit_uint), ('16float', decoder.decode_16bit_float), ('16float2', decoder.decode_16bit_float), ('32float', decoder.decode_32bit_float), ('32float2', decoder.decode_32bit_float), ('64int', decoder.decode_64bit_int), ('64uint', decoder.decode_64bit_uint), ('ignore', decoder.skip_bytes), ('64float', decoder.decode_64bit_float), ('64float2', decoder.decode_64bit_float), ]) y['Value'] = round( decoded[y['Type']]() * y['Scale'], 3) #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units']) #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}") #print("HOME") Rtuclient.connect() if CONF_SOLIS_4G_3P and Rtuclient.is_socket_open(): if DashingEnabled: Dashlog.append("Read Solis-4G inverter") ui.display() else: log.info("Read Solis-4G inverter") for x, z in SOLIS_Config.items(): if DashingEnabled: Dashlog.append(f"Reading slave {z['NAME']}") DashMeas1.append("") DashMeas1.append(f"Reading slave {z['NAME']}") ui.display() else: log.info(f"Reading slave {z['NAME']}") MyDict = z['DATA'] #print (MyDict) for k, y in MyDict.items(): #print(z['ADDRESS'], y['Address'], y['Size']) rr = None try: rr = Rtuclient.read_input_registers( y['Address'], y['Size'], unit=z['ADDRESS']) except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if (isinstance(rr, ReadInputRegistersResponse) and (len(rr.registers) == y['Size'])): decoder = BinaryPayloadDecoder.fromRegisters( rr.registers, byteorder=Endian.Big, wordorder=Endian.Big) decoded = OrderedDict([ ('string', decoder.decode_string), ('bits', decoder.decode_bits), ('8int', decoder.decode_8bit_int), ('8uint', decoder.decode_8bit_uint), ('16int', decoder.decode_16bit_int), ('16uint', decoder.decode_16bit_uint), ('32int', decoder.decode_32bit_int), ('32uint', decoder.decode_32bit_uint), ('16float', decoder.decode_16bit_float), ('16float2', decoder.decode_16bit_float), ('32float', decoder.decode_32bit_float), ('32float2', decoder.decode_32bit_float), ('64int', decoder.decode_64bit_int), ('64uint', decoder.decode_64bit_uint), ('ignore', decoder.skip_bytes), ('64float', decoder.decode_64bit_float), ('64float2', decoder.decode_64bit_float), ]) y['Value'] = round( decoded[y['Type']]() * y['Scale'], 3) #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units']) if DashingEnabled: DashMeas1.append( f"{y['Name']} = {y['Value']:.02f} {y['Units']}" ) ui.display() #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}") # Rtuclient.close() Rtuclient2.connect() if CONF_JANITZA_B23 and Rtuclient2.is_socket_open(): if DashingEnabled: Dashlog.append("Read EVSE charger") ui.display() else: log.info("Read EVSE charger...") for x, z in B23_Config.items(): if DashingEnabled: Dashlog.append(f"Reading slave {z['NAME']}") DashMeas1.append("") DashMeas1.append(f"Reading slave {z['NAME']}") ui.display() else: log.info(f"Reading slave {z['NAME']}") MyDict = z['DATA'] print(MyDict) for k, y in MyDict.items(): #print(z['ADDRESS'], y['Address'], y['Size']) rr = None try: rr = Rtuclient2.read_holding_registers( y['Address'], y['Size'], unit=z['ADDRESS']) except Exception as e: if DashingEnabled: DashErrors.append("Exception %s" % str(e)) ui.display() else: log.info("Exception %s" % str(e)) pass if (isinstance(rr, ReadHoldingRegistersResponse) and (len(rr.registers) == y['Size'])): decoder = BinaryPayloadDecoder.fromRegisters( rr.registers, byteorder=Endian.Big, wordorder=Endian.Big) decoded = OrderedDict([ ('string', decoder.decode_string), ('bits', decoder.decode_bits), ('8int', decoder.decode_8bit_int), ('8uint', decoder.decode_8bit_uint), ('16int', decoder.decode_16bit_int), ('16uint', decoder.decode_16bit_uint), ('32int', decoder.decode_32bit_int), ('32uint', decoder.decode_32bit_uint), ('16float', decoder.decode_16bit_float), ('16float2', decoder.decode_16bit_float), ('32float', decoder.decode_32bit_float), ('32float2', decoder.decode_32bit_float), ('64int', decoder.decode_64bit_int), ('64uint', decoder.decode_64bit_uint), ('ignore', decoder.skip_bytes), ('64float', decoder.decode_64bit_float), ('64float2', decoder.decode_64bit_float), ]) y['Value'] = round( decoded[y['Type']]() * y['Scale'], 3) if math.isnan(y['Value']): y['Value'] = 0 #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units']) if DashingEnabled: DashMeas1.append( f"{y['Name']} = {y['Value']:.02f} {y['Units']}" ) ui.display() #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}") # Rtuclient.close() #print("HOME") if DashingEnabled: bchart.append(QuerryNb) else: log.info(f"Poller querry : {QuerryNb}") #print ( "Querry %s" % QuerryNb) if (CONF_EMONCMS and CONF_SOLIS_4G_3P): SolarPower = 0 for x, z in SOLIS_Config.items(): if Rtuclient.is_socket_open(): reqdata = {} #print("Slave: " + z['NAME']) MyDict = z['DATA'] #print (z['DATA']) for k, y in MyDict.items(): #DashErrors.append(y['Name']) if (y['Name'] == 'Freq'): vchart.append(50 + QuerryNb) reqdata[f"{z['NAME']}{y['Name']}"] = y['Value'] #print('reqdata = {reqdata}') req = MyEmon.senddata(reqdata) reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}' try: r = requests.get(reqstr, timeout=10) r.raise_for_status() except requests.exceptions.HTTPError as errh: print("Http Error:", errh) except requests.exceptions.ConnectionError as errc: print("Error Connecting:", errc) except requests.exceptions.Timeout as errt: print("Timeout Error:", errt) except requests.exceptions.RequestException as err: print("OOps: Something Else", err) #print (r.status_code) #log.info( f"EmonCMS send status {r.status_code}" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) ui.display() else: log.info( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) #print (r.content) else: #log.info( "EmonCMS ORNO unable to send" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} nothing to push") ui.display() else: log.info( f"EmonCMS slave {z['NAME']} nothing to push") if (CONF_EMONCMS and CONF_JANITZA_B23): for x, z in B23_Config.items(): if Rtuclient2.is_socket_open(): reqdata = {} #print("Slave: " + z['NAME']) MyDict = z['DATA'] #print (z['DATA']) for k, y in MyDict.items(): #DashErrors.append(y['Name']) if (y['Name'] == 'Freq'): vchart.append(50 + QuerryNb) reqdata[f"{z['NAME']}{y['Name']}"] = y['Value'] #print('reqdata = {reqdata}') req = MyEmon.senddata(reqdata) reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}' try: r = requests.get(reqstr, timeout=10) r.raise_for_status() except requests.exceptions.HTTPError as errh: print("Http Error:", errh) except requests.exceptions.ConnectionError as errc: print("Error Connecting:", errc) except requests.exceptions.Timeout as errt: print("Timeout Error:", errt) except requests.exceptions.RequestException as err: print("OOps: Something Else", err) #print (r.status_code) #log.info( f"EmonCMS send status {r.status_code}" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) ui.display() else: log.info( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) #print (r.content) else: #log.info( "EmonCMS ORNO unable to send" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} nothing to push") ui.display() else: log.info( f"EmonCMS slave {z['NAME']} nothing to push") if (CONF_EMONCMS and CONF_EM370): for x, z in EEM_Config.items(): if TcpClient.is_socket_open(): reqdata = {} #print("Slave: " + z['NAME']) MyDict = z['DATA'] #print (z['DATA']) for k, y in MyDict.items(): #DashErrors.append(y['Name']) reqdata[f"{z['NAME']}{y['Name']}"] = y['Value'] #print('reqdata = {reqdata}') reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}' try: r = requests.get(reqstr, timeout=10) r.raise_for_status() except requests.exceptions.HTTPError as errh: print("Http Error:", errh) except requests.exceptions.ConnectionError as errc: print("Error Connecting:", errc) except requests.exceptions.Timeout as errt: print("Timeout Error:", errt) except requests.exceptions.RequestException as err: print("OOps: Something Else", err) #print (r.status_code) #log.info( f"EmonCMS send status {r.status_code}" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) ui.display() else: log.info( f"EmonCMS slave {z['NAME']} push status {r.status_code}" ) #print (r.content) else: #log.info( "EmonCMS ORNO unable to send" ) if DashingEnabled: Dashlog.append( f"EmonCMS slave {z['NAME']} nothing to push") ui.display() else: log.info( f"EmonCMS slave {z['NAME']} nothing to push") time.sleep(5) except Exception as e: print("Exception %s" % str(e))
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys from pymodbus.client.sync import ModbusSerialClient as ModbusClient from pymongo import MongoClient from datetime import datetime modbus = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=9600, stopbits=1, parity='N', bytesize=8, timeout=1) modbus.connect() read_registers = modbus.read_input_registers(0,33) registers = read_registers.registers #Status Inverter (Stat) 0=waiting 1=normaal 2=fault status = registers[0] if status != 1: sys.exit() pv_volts = float(registers[3])/10 #1V pv_amps = float(registers[4])/10 #1A pv_watts = float(registers[6])/10 #1W ac_watts = float(registers[12])/10 #1W ac_herz = float(registers[13])/100 #1Hz ac_volts = float(registers[14])/10 #1V ac_amps = float(registers[15])/10 #1A total_today = float(registers[27])/10 #1kWh total = float(registers[29])/10 #1kWh #Total runtime (Htot-low byte) 0.5S runtime_low = float(registers[30]) #Total runtime (Htot-high-byte) 0.5S runtime_high = float(registers[31]) temperature = float(registers[32])/10 #1C
try: f = open('/dev/ttyUSB0') seradd = "/dev/ttyUSB0" f.close() except: seradd = "/dev/serial0" sdmid = 105 Values = {} actorstat = 0 evsefailure = 0 buchseconfigured = 1 loglevel = 1 from pymodbus.client.sync import ModbusSerialClient client = ModbusSerialClient(method="rtu", port=seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1) def logDebug(level, msg): if (int(level) >= int(loglevel)): file = open('/var/www/html/openWB/ramdisk/isss.log', 'a') if (int(level) == 0): file.write(time.ctime() + ': ' + str(msg) + '\n') if (int(level) == 1): file.write(time.ctime() + ': ' + str(msg) + '\n') if (int(level) == 2): file.write(time.ctime() + ': ' + str('\x1b[6;30;42m' + msg + '\x1b[0m') + '\n') file.close()
def __init__(self,port='/dev/ttyUSB0',baudrate=115200): self.port = port self.baudrate = baudrate self.m = ModbusSerialClient('rtu',port=self.port,baudrate=self.baudrate, parity='E')
class Robotiq140(object): def __init__(self, device='/dev/ttyUSB0', timeout=2): self.client = None for _ in range(20): if not self.connectToDevice(device): print('正在重新连接到robotiq140...') time.sleep(0.2) if not self.client.connect(): raise Exception('gripper connect error') if self.is_reset(): self.reset() self.activate(timeout) def connectToDevice(self, device='/dev/ttyUSB0'): """ 连接到modbus """ self.client = ModbusSerialClient( method='rtu', port=device, stopbits=1, bytesize=8, baudrate=115200, timeout=0.2) if not self.client.connect(): print("Unable to connect to %s" % device) return False return True def disconnectFromDevice(self): """Close connection""" self.client.close() def _send_command(self, data): """ Send a command to the Gripper - the method takes a list of uint8 as an argument. The meaning of each variable depends on the Gripper model (see support.robotiq.com for more details) """ # make sure data has an even number of elements if(len(data) % 2 == 1): data.append(0) # Initiate message as an empty list message = [] # Fill message by combining two bytes in one register for i in range(int(len(data)/2)): message.append((data[2*i] << 8) + data[2*i+1]) # To do!: Implement try/except self.client.write_registers(0x03E8, message, unit=0x0009) def _get_status(self, numBytes=6): """Sends a request to read, wait for the response and returns the Gripper status. The method gets the number of bytes to read as an argument""" numRegs = int(ceil(numBytes/2.0)) # To do!: Implement try/except # Get status from the device response = self.client.read_holding_registers(0x07D0, numRegs, unit=0x0009) # Instantiate output as an empty list output = [] # Fill the output with the bytes in the appropriate order for i in range(0, numRegs): output.append((response.getRegister(i) & 0xFF00) >> 8) output.append(response.getRegister(i) & 0x00FF) # Output the result return output def getStatus(self): """Request the status from the gripper and return it in the Robotiq2FGripper_robot_input msg type.""" # Acquire status from the Gripper status = self._get_status(6) # Message to output message = {} # 夹爪是否正常工作 message['gACT'] = (status[0] >> 0) & 0x01 # 夹爪是否正在移动,移动时不能接收下一个指令 message['gGTO'] = (status[0] >> 3) & 0x01 message['gSTA'] = (status[0] >> 4) & 0x03 # 是否检查到物体,0x00正在运动中没有物体,0x01物体在外面,0x02物体在里面,0x03运动到指定位置没有物体 message['gOBJ'] = (status[0] >> 6) & 0x03 # 错误信息 message['gFLT'] = status[2] # 需要达到的位置,0x00全开,0xFF全闭 message['gPR'] = status[3] # 当前位置 message['gPO'] = status[4] # 10×电流=gCu(mA) message['gCU'] = status[5] return message def sendCommand(self, command): """ 把字典转化为可以直接发送的数组,并发送 """ # 限制数值上下限 for n in 'rACT rGTO rATR'.split(): command[n] = int(np.clip(command.get(n, 0), 0, 1)) for n in 'rPR rSP rFR'.split(): command[n] = int(np.clip(command.get(n, 0), 0, 255)) # 转换为要发送的数组 message = [] message.append(command['rACT'] + (command['rGTO'] << 3) + (command['rATR'] << 4)) message.append(0) message.append(0) for n in 'rPR rSP rFR'.split(): message.append(command[n]) return self._send_command(message) def is_ready(self, status=None): status = status or self.getStatus() return status['gSTA'] == 3 and status['gACT'] == 1 def is_reset(self, status=None): status = status or self.getStatus() return status['gSTA'] == 0 or status['gACT'] == 0 def is_moving(self, status=None): status = status or self.getStatus() return status['gGTO'] == 1 and status['gOBJ'] == 0 def is_stopped(self, status=None): status = status or self.getStatus() return status['gOBJ'] != 0 def object_detected(self, status=None): status = status or self.getStatus() return status['gOBJ'] == 1 or status['gOBJ'] == 2 def get_fault_status(self, status=None): status = status or self.getStatus() return status['gFLT'] def get_pos(self, status=None): status = status or self.getStatus() po = status['gPO'] # TODO:这里的变换还要调一下 return np.clip(0.14/(13.-230.)*(po-230.), 0, 0.14) def get_req_pos(self, status=None): status = status or self.getStatus() pr = status['gPR'] # TODO:这里的变换还要调一下 return np.clip(0.14/(13.-230.)*(pr-230.), 0, 0.14) def is_closed(self, status=None): status = status or self.getStatus() return status['gPO'] >= 230 def is_opened(self, status=None): status = status or self.getStatus() return status['gPO'] <= 13 def get_current(self, status=None): status = status or self.getStatus() return status['gCU'] * 0.1 def wait_until_stopped(self, timeout=None): start_time = time.time() while not self.is_reset() and (not timeout or (time.time() - start_time) < timeout): if self.is_stopped(): return True time.sleep(0.1) return False def wait_until_moving(self, timeout=None): start_time = time.time() while not self.is_reset() and (not timeout or (time.time() - start_time) < timeout): if not self.is_stopped(): return True time.sleep(0.1) return False def reset(self): cmd = {n: 0 for n in 'rACT rGTO rATR rPR rSP rFR'.split()} self.sendCommand(cmd) def activate(self, timeout=None): cmd = dict(rACT=1, rGTO=1, rATR=0, rPR=0, rSP=255, rFR=150) self.sendCommand(cmd) start_time = time.time() while not timeout or (time.time() - start_time) < timeout: if self.is_ready(): return True time.sleep(0.1) return False def auto_release(self): cmd = {n: 0 for n in 'rACT rGTO rATR rPR rSP rFR'.split()} cmd['rACT'] = 1 cmd['rATR'] = 1 self.sendCommand(cmd) def goto(self, pos, vel=0.1, force=50, block=False, timeout=None): cmd = {n: 0 for n in 'rACT rGTO rATR rPR rSP rFR'.split()} cmd['rACT'] = 1 cmd['rGTO'] = 1 # cmd['rPR'] = int(np.clip((13.-230.)/0.14 * pos + 230., 0, 255)) cmd['rPR'] = int(np.clip((0.-230.)/0.143 * pos + 230., 0, 255)) cmd['rSP'] = int(np.clip(255./(0.1-0.013) * (vel-0.013), 0, 255)) cmd['rFR'] = int(np.clip(255./(100.-30.) * (force-30.), 0, 255)) self.sendCommand(cmd) time.sleep(0.1) if block: if not self.wait_until_moving(timeout): return False return self.wait_until_stopped(timeout) return True def stop(self, block=False, timeout=-1): cmd = {n: 0 for n in 'rACT rGTO rATR rPR rSP rFR'.split()} cmd['rACT'] = 1 cmd['rGTO'] = 0 self.sendCommand(cmd) time.sleep(0.1) if block: return self.wait_until_stopped(timeout) return True def open(self, vel=0.05, force=100, block=False, timeout=-1): if self.is_opened(): return True return self.goto(1.0, vel, force, block=block, timeout=timeout) def close(self, vel=0.05, force=100, block=False, timeout=-1): if self.is_closed(): return True return self.goto(-1.0, vel, force, block=block, timeout=timeout)
def testSyncSerialRTUClientTimeouts(self): client = ModbusSerialClient(method="rtu", baudrate=9600) assert client.silent_interval == round((3.5 * 11 / 9600), 6) client = ModbusSerialClient(method="rtu", baudrate=38400) assert client.silent_interval == round((1.75 / 1000), 6)
#logger.error("started program!") #sleep for 15 seconds before loop begins to allow other tasks to end. print("start! waiting 15 secs...") time.sleep(15) print("15 secs have passed...") while (1 == 1): result_error_count = 0 result_error_count_if = 0 result_error_count_batt = 0 db = MySQLdb.connect(host="localhost", user="******", passwd="yy", db="solardata") client = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=115200) client.connect() print("modbus connected!") try: #the ModbusClient takes about 3 seconds to query the controller. #add extra 7 seconds to make it poll every 10 seconds. #time.sleep(7) #result = client.read_input_registers(0x3100,6,unit=1) try: print("reading data from modbus...") result = client.read_input_registers(0x3100, 20, unit=1) print("data received! = " + str(result)) except Exception as e: print("error reading modbus")
from pymodbus.transaction import ModbusRtuFramer import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) #count= the number of registers to read #unit= the slave unit this request is targeting #address= the starting address to read from PORT= "COM8" client= ModbusClient(method = "rtu", port=PORT, stopbits = 1, bytesize = 8, parity = 'N', baudrate=19200, timeout = 10) #Connect to the serial modbus server connection = client.connect() print( connection) #Starting add, num of reg to read, slave unit. # result= client.read_holding_registers(0x00, 5 ,unit= 0x01) # print(result) #Starting add, num of reg to read, slave unit. #result= client.read_holding_registers(18,11,unit= 1) #print(result) # print(result)
def testSerialClientRepr(self): client = ModbusSerialClient() rep = "<{} at {} socket={}, method={}, timeout={}>".format( client.__class__.__name__, hex(id(client)), client.socket, client.method, client.timeout) self.assertEqual(repr(client), rep)
import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) #---------------------------------------------------------------------------# # choose the client you want #---------------------------------------------------------------------------# # make sure to start an implementation to hit against. For this # you can use an existing device, the reference implementation in the tools # directory, or start a pymodbus server. # # It should be noted that you can supply an ipv4 or an ipv6 host address for # both the UDP and TCP clients. #---------------------------------------------------------------------------# client = ModbusClient(method='rtu', port="/dev/ttyp0") # client = ModbusClient('127.0.0.1', port=5020) client.connect() #---------------------------------------------------------------------------# # import the extended messages to perform #---------------------------------------------------------------------------# from pymodbus.diag_message import * from pymodbus.file_message import * from pymodbus.other_message import * from pymodbus.mei_message import * #---------------------------------------------------------------------------# # extra requests #---------------------------------------------------------------------------# # If you are performing a request that is not available in the client
def testBasicSyncSerialClient(self): ''' Test the basic methods for the serial sync client''' # receive/send client = ModbusSerialClient() client.socket = mockSocket() self.assertEqual(0, client._send(None)) self.assertEqual(1, client._send('\x00')) self.assertEqual('\x00', client._recv(1)) # connect/disconnect self.assertTrue(client.connect()) client.close() # already closed socket client.socket = False client.close() self.assertEqual('ascii baud[19200]', str(client))
import RPi.GPIO as gpio gpio.setwarnings(False) gpio.setmode(gpio.BOARD) gpio.setup(36,gpio.OUT) gpio.output(36,0) ############################################################################################# server = "data.sparkfun.com" # base URL of your feed publicKey = "9b1g78xoMjs8787z3OwZ" #"GEGLXdO3dnHDKar5x2xW" privateKey = "xv9R17XkDntnYnYr259q" #"Nnlxo7DK7Vij456RVJVD" fields = ["aux_temp","bat_temp","comp_curr","hp","lp","milk_temp"] # Your feed's data fields # from pymodbus.client.sync import ModbusSerialClient as ModbusClient client=ModbusClient(method='rtu',port='/dev/ttyUSB0',baudrate=9600,timeout=1,parity='N') client.connect() db = MySQLdb.connect(host="localhost", user="******",passwd="root", db="temp_database") cur = db.cursor() response=client.read_holding_registers(0004,6,unit=1) #(starting addr, no of registers to be read, slave addr) responseFault=client.read_holding_registers(0022,14,unit=1) with open('/var/www/html/AutomationProject/file2.json')as f: data = json.loads(f.read()) print data['serial'] serialNum = data['serial'] ######################### Read MOD-BUS registers ############################
class pancakeuniformityFixture( hardware_station_common.test_station.test_fixture.TestFixture): """ class for auo unif Fixture this is for doing all the specific things necessary to interface with instruments """ def __init__(self, station_config, operator_interface): hardware_station_common.test_station.test_fixture.TestFixture.__init__( self, station_config, operator_interface) self._serial_port = None self._verbose = station_config.IS_VERBOSE self._start_delimiter = ':' self._end_delimiter = '\r\n' self._error_msg = 'This command is illegal,please check it again' self._read_error = False self._particle_counter_client = None # type: ModbusSerialClient def is_ready(self): if self._serial_port is not None: resp = self._read_response(2) btn_dic = { 2: r'BUTTON_LEFT:\d', 1: r'BUTTON_RIGHT:\d', 0: r'BUTTON:\d' } if resp: for key, item in btn_dic.items(): items = filter(lambda r: re.match(item, r, re.I), resp) if items: return key def initialize(self): self._operator_interface.print_to_console( "Initializing auo uniformity Fixture\n") self._serial_port = serial.Serial(self._station_config.FIXTURE_COMPORT, 115200, parity='N', stopbits=1, timeout=1, xonxoff=0, rtscts=0) if self._station_config.FIXTURE_PARTICLE_COUNTER: parity = 'N' Defaults.Retries = 5 Defaults.RetryOnEmpty = True self._particle_counter_client = ModbusSerialClient( method='rtu', baudrate=9600, bytesize=8, parity=parity, stopbits=1, port=self._station_config.FIXTURE_PARTICLE_COMPORT, timeout=2000) if not self._particle_counter_client.connect(): raise pancakeuniformityFixtureError( 'Unable to open particle counter port: %s' % self._station_config.FIXTURE_PARTICLE_COMPORT) if not self._serial_port: raise pancakeuniformityFixtureError( 'Unable to open fixture port: %s' % self._station_config.FIXTURE_COMPORT) else: self._operator_interface.print_to_console( "Fixture %s Initialized.\n" % self._station_config.FIXTURE_COMPORT) return True def _parsing_response(self, response): value = [] for item in response[1:len(response) - 1]: value.append((item.split(self._start_delimiter))[1].split( self._end_delimiter)[0]) return value def _write_serial(self, input_bytes): self._serial_port.flush() if self._verbose: print("flushed") print('writing: ' + input_bytes) bytes_written = self._serial_port.write(input_bytes) return bytes_written def _read_response(self, timeout=5): response = [] line_in = "" tim = time.time() while (not re.search("@_@", line_in, re.IGNORECASE) and (time.time() - tim < timeout)): line_in = self._serial_port.readline() if line_in != "": response.append(line_in) if self._verbose and len(response) > 1: pprint.pprint(response) return response ###################### # Fixture info ###################### def help(self): self._write_serial(self._station_config.COMMAND_HELP) response = self._read_response() if self._verbose: print(response) return response def reset(self): self._write_serial(self._station_config.COMMAND_RESET) response = self._read_response() if self._verbose: print(response[1]) value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] return value def id(self): self._write_serial(self._station_config.COMMAND_ID) response = self._read_response() if self._verbose: print(response[1]) value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] return value def version(self): self._write_serial(self._station_config.COMMAND_VERSION) response = self._read_response() if self._verbose: print(response[1]) value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] return value def close(self): self._operator_interface.print_to_console("Closing auo unif Fixture\n") if hasattr(self, '_serial_port') \ and self._serial_port is not None \ and self._station_config.FIXTURE_COMPORT: self.elminator_off() self._serial_port.close() self._serial_port = None if hasattr(self, '_particle_counter_client') and \ self._particle_counter_client is not None \ and self._station_config.FIXTURE_PARTICLE_COUNTER: self._particle_counter_client.close() self._particle_counter_client = None if self._verbose: print("====== Fixture Close =========") return True ###################### # Fixture control ###################### def elminator_on(self): self._write_serial(self._station_config.COMMAND_ELIMINATOR_ON) #time.sleep(CARRIER_LOAD_TIME) response = self._read_response() if self._verbose: print(response[1]) if "0" in response[1]: value = 0 elif self._error_msg not in response[1]: value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] else: value = None self._read_error = "True" raise pancakeuniformityFixtureError("Fail to Read %s" % response[0]) return value def elminator_off(self): self._write_serial(self._station_config.COMMAND_ELIMINATOR_OFF) #time.sleep(CARRIER_LOAD_TIME) response = self._read_response() if self._verbose: print(response[1]) if "0" in response[1]: value = 0 elif self._error_msg not in response[1]: value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] else: value = None self._read_error = "True" raise pancakeuniformityFixtureError("Fail to Read %s" % response[0]) return value def load(self): self._write_serial(self._station_config.COMMAND_LOAD) #time.sleep(CARRIER_LOAD_TIME) response = self._read_response() if self._verbose: print(response[1]) if "0" in response[1]: value = 0 elif self._error_msg not in response[1]: value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] else: value = None self._read_error = "True" raise pancakeuniformityFixtureError("Fail to Read %s" % response[0]) return value def unload(self): self._write_serial(self._station_config.COMMAND_UNLOAD) #time.sleep(CARRIER_UNLOAD_TIME) response = self._read_response() if self._verbose: print(response[1]) if "0" in response[1]: ## temporary fix for FW1.0.20161114 value = 0 elif self._error_msg not in response[1]: value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] else: value = None self._read_error = "True" raise pancakeuniformityFixtureError("Fail to Read %s" % response[0]) return value def scan_serial(self): self._write_serial(self._station_config.COMMAND_BARCODE) #time.sleep(BARCODE_TIME) response = self._read_response() if self._verbose: print(response[1]) if self._error_msg not in response[1]: value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] else: value = None self._read_error = "True" raise pancakeuniformityFixtureError("Fail to Read %s" % response[0]) return value ###################### # Fixture button system control ###################### def button_enable(self): self._write_serial(self._station_config.COMMAND_BUTTON_ENABLE) response = self._read_response() if self._verbose: print(response[1]) if self._error_msg not in response[1]: value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] else: value = None self._read_error = "True" raise pancakeuniformityFixtureError("Fail to Read %s" % response[0]) return value def button_disable(self): self._write_serial(self._station_config.COMMAND_BUTTON_DISABLE) response = self._read_response() if self._verbose: print(response[1]) if self._error_msg not in response[1]: value = (response[1].split(self._start_delimiter))[1].split( self._end_delimiter)[0] else: value = None self._read_error = "True" raise pancakeuniformityFixtureError("Fail to Read %s" % response[0]) return value ###################### # Particle Counter Control ###################### def particle_counter_on(self): if self._particle_counter_client is not None: wrs = self._particle_counter_client.\ write_register(self._station_config.FIXTRUE_PARTICLE_ADDR_START, 1, unit=self._station_config.FIXTURE_PARTICLE_ADDR) if wrs is None or wrs.isError(): raise pancakeuniformityFixtureError( 'Failed to start particle counter .') def particle_counter_off(self): if self._particle_counter_client is not None: self._particle_counter_client.write_register( self._station_config.FIXTRUE_PARTICLE_ADDR_START, 0, unit=self._station_config.FIXTURE_PARTICLE_ADDR ) # type: WriteSingleRegisterResponse def particle_counter_read_val(self): if self._particle_counter_client is not None: val = None retries = 1 while retries <= 10: rs = self._particle_counter_client.read_holding_registers( self._station_config.FIXTRUE_PARTICLE_ADDR_READ, 2, unit=self._station_config.FIXTURE_PARTICLE_ADDR ) # type: ReadHoldingRegistersResponse if rs is None or rs.isError(): if self._station_config.IS_VERBOSE: print( "Retries to read data from particle counter {}/10. " .format(retries)) retries += 1 time.sleep(0.5) else: # val = rs.registers[0] * 65535 + rs.registers[1] # modified by elton. for apc-r210/310 val = ctypes.c_int32(rs.registers[0] + (rs.registers[1] << 16)).value if hasattr(self._station_config, 'PARTICLE_COUNTER_APC' ) and self._station_config.PARTICLE_COUNTER_APC: val = (ctypes.c_int32((rs.registers[0] << 16) + rs.registers[1])).value break if val is None: raise pancakeuniformityFixtureError( 'Failed to read data from particle counter.') return val def particle_counter_state(self): if self._particle_counter_client is not None: retries = 1 val = None while retries <= 10 and val is None: rs = self._particle_counter_client.read_holding_registers( self._station_config.FIXTRUE_PARTICLE_ADDR_STATUS, 2, unit=self._station_config.FIXTURE_PARTICLE_ADDR ) # type: ReadHoldingRegistersResponse if rs is None or rs.isError(): if self._station_config.IS_VERBOSE: pprint.pprint( "Retries to read data from particle counter {0}/10. " .format(retries)) continue val = rs.registers[0] if val is None: raise pancakeuniformityFixtureError( 'Failed to read data from particle counter.') return val
def testBasicSyncSerialClient(self, mock_serial): ''' Test the basic methods for the serial sync client''' # receive/send mock_serial.in_waiting = 0 mock_serial.write = lambda x: len(x) mock_serial.read = lambda size: b'\x00' * size client = ModbusSerialClient() client.socket = mock_serial client.state = 0 self.assertEqual(0, client._send(None)) client.state = 0 self.assertEqual(1, client._send(b'\x00')) self.assertEqual(b'\x00', client._recv(1)) # connect/disconnect self.assertTrue(client.connect()) client.close() # already closed socket client.socket = False client.close() self.assertEqual('ModbusSerialClient(ascii baud[19200])', str(client))
from pymodbus.payload import BinaryPayloadBuilder import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) #count= the number of registers to read #unit= the slave unit this request is targeting #address= the starting address to read from client = ModbusClient(method="rtu", port="/dev/ttyUSB0", stopbits=1, bytesize=8, parity='N', baudrate=115200, timeout=0.5) #Connect to the serial modbus server connection = client.connect() print(connection) #builder = BinaryPayloadBuilder(byteorder=Endian.Big,wordorder=Endian.Little) #builder.add_32bit_uint(0x11223344) #builder.add_32bit_uint(0x55667788) #payload = builder.to_registers() #payload = builder.build()
def onCommand(self, Unit, Command, Level, Hue): Domoticz.Log("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level)) # ON/OFF payload value payload = Level # Set payload from slider/scroll # Set payload if a button has been pressed if (str(Command) == "On"): payload = self.Domoticz_Setting_Payload_ON if (str(Command) == "Off"): payload = self.Domoticz_Setting_Payload_OFF ######################################## # SET HARDWARE - pymodbus: RTU / ASCII ######################################## if (self.Domoticz_Setting_Communication_Mode == "rtu" or self.Domoticz_Setting_Communication_Mode == "ascii"): Domoticz.Debug("MODBUS DEBUG - INTERFACE: Port=" + self.Domoticz_Setting_Serial_Port + ", BaudRate=" + self.Domoticz_Setting_Baudrate + ", StopBits=" + str(self.StopBits) + ", ByteSize=" + str(self.ByteSize) + " Parity=" + self.Parity) Domoticz.Debug("MODBUS DEBUG - SETTINGS: Method=" + self.Domoticz_Setting_Communication_Mode + ", Device ID=" + self.Domoticz_Setting_Device_ID + ", Register=" + self.Domoticz_Setting_Register_Number + ", Function=" + self.Domoticz_Setting_Modbus_Function + ", Payload=" + payload) try: client = ModbusSerialClient( method=self.Domoticz_Setting_Communication_Mode, port=self.Domoticz_Setting_Serial_Port, stopbits=self.StopBits, bytesize=self.ByteSize, parity=self.Parity, baudrate=int(self.Domoticz_Setting_Baudrate), timeout=2, retries=2) except: Domoticz.Error("Error opening Serial interface on " + self.Domoticz_Setting_Serial_Port) Devices[1].Update(1, "0") # Set value to 0 (error) ######################################## # SET HARDWARE - pymodbus: RTU over TCP ######################################## if (self.Domoticz_Setting_Communication_Mode == "rtutcp"): Domoticz.Debug("MODBUS DEBUG - INTERFACE: IP=" + self.Domoticz_Setting_TCP_IP + ", Port=" + self.Domoticz_Setting_TCP_PORT) Domoticz.Debug("MODBUS DEBUG - SETTINGS: Method=" + self.Domoticz_Setting_Communication_Mode + ", Device ID=" + self.Domoticz_Setting_Device_ID + ", Register=" + self.Domoticz_Setting_Register_Number + ", Function=" + self.Domoticz_Setting_Modbus_Function + ", Payload=" + payload) try: client = ModbusTcpClient(host=self.Domoticz_Setting_TCP_IP, port=int( self.Domoticz_Setting_TCP_PORT), framer=ModbusRtuFramer, auto_open=True, auto_close=True, timeout=2) except: Domoticz.Error( "Error opening RTU over TCP interface on address: " + self.Domoticz_Setting_TCP_IPPORT) Devices[1].Update(1, "0") # Set value to 0 (error) ######################################## # SET HARDWARE - pymodbusTCP: TCP/IP ######################################## if (self.Domoticz_Setting_Communication_Mode == "tcpip"): Domoticz.Debug("MODBUS DEBUG - INTERFACE: IP=" + self.Domoticz_Setting_TCP_IP + ", Port=" + self.Domoticz_Setting_TCP_PORT) Domoticz.Debug("MODBUS DEBUG - SETTINGS: Method=" + self.Domoticz_Setting_Communication_Mode + ", Device ID=" + self.Domoticz_Setting_Device_ID + ", Register=" + self.Domoticz_Setting_Register_Number + ", Function" + self.Domoticz_Setting_Modbus_Function + ", Payload=" + payload) try: client = ModbusClient(host=self.Domoticz_Setting_TCP_IP, port=int(self.Domoticz_Setting_TCP_PORT), unit_id=int( self.Domoticz_Setting_Device_ID), auto_open=True, auto_close=True, timeout=2) except: Domoticz.Error("Error opening TCP/IP interface on address: " + self.Domoticz_Setting_TCP_IPPORT) Devices[1].Update(1, "0") # Set value to 0 (error) ######################################## # WRITE PAYLOAD - pymodbus: RTU / ASCII / RTU over TCP ######################################## if (self.Domoticz_Setting_Communication_Mode == "rtu" or self.Domoticz_Setting_Communication_Mode == "ascii" or self.Domoticz_Setting_Communication_Mode == "rtutcp"): try: # Function to execute if (self.Domoticz_Setting_Modbus_Function == "5"): result = client.write_coil( int(self.Domoticz_Setting_Device_ID), int(payload, 16), unit=int(self.Domoticz_Setting_Device_ID)) if (self.Domoticz_Setting_Modbus_Function == "6"): result = client.write_register( int(self.Domoticz_Setting_Device_ID), int(payload, 16), unit=int(self.Domoticz_Setting_Device_ID)) if (self.Domoticz_Setting_Modbus_Function == "15"): result = client.write_coils( int(self.Domoticz_Setting_Device_ID), int(payload, 16), unit=int(self.Domoticz_Setting_Device_ID)) if (self.Domoticz_Setting_Modbus_Function == "16"): result = client.write_registers( int(self.Domoticz_Setting_Device_ID), int(payload, 16), unit=int(self.Domoticz_Setting_Device_ID)) client.close() Domoticz.Debug("MODBUS DEBUG - RESULT: " + str(result)) if (str(Command) == "On"): Devices[1].Update(1, "1") # Update device to ON if (str(Command) == "Off"): Devices[1].Update(0, "0") # Update device to OFF except: Domoticz.Error( "Modbus error communicating! (RTU/ASCII/RTU over TCP), check your settings!" ) Devices[1].Update(1, "0") # Set value to 0 (error) ######################################## # SET PAYLOAD - pymodbusTCP: TCP/IP ######################################## if (self.Domoticz_Setting_Communication_Mode == "tcpip"): try: # Function to execute if (self.Domoticz_Setting_Modbus_Function == "5"): result = client.write_single_coil( int(self.Domoticz_Setting_Device_ID), int(payload)) if (self.Domoticz_Setting_Modbus_Function == "6"): result = client.write_single_register( int(self.Domoticz_Setting_Device_ID), int(payload)) if (self.Domoticz_Setting_Modbus_Function == "15"): result = client.write_multiple_coils( int(self.Domoticz_Setting_Device_ID), [payload ]) # TODO split up multiple bytes to proper array. if (self.Domoticz_Setting_Modbus_Function == "16"): result = client.write_multiple_registers( int(self.Domoticz_Setting_Device_ID), [payload ]) # TODO split up multiple bytes to proper array. client.close() Domoticz.Debug("MODBUS DEBUG - RESULT: " + str(result)) if (str(Command) == "On"): Devices[1].Update(1, "1") # Update device to ON if (str(Command) == "Off"): Devices[1].Update(0, "0") # Update device to OFF except: Domoticz.Error( "Modbus error communicating! (TCP/IP), check your settings!" ) Devices[1].Update(1, "0") # Set value to 0 (error)
writer.writerow(['UTC', date, device, int(typeValue), value]) def startLocation(): with open('config.csv') as csvfile: readCSV = csv.reader(csvfile, delimiter=',') for row in readCSV: location = row[0] break return location print('\n \n Starting execution') location = 'Waiting to read configuration' print(location) print("I'm located at " + startLocation()) client = ModbusClient(method='rtu', port='/dev/ttyUSB0', timeout=1, stopbits = 1, bytesize = 8, parity='N', baudrate= 9600) client.connect() pp = pprint.PrettyPrinter(indent=4) startime = time() values = [] print("\n") now = datetime.datetime.utcnow() dateName = now.strftime("%Y-%m-%d-%H-%M-%S") print("Reading values at " , dateName) with open('config.csv') as csvfile: readCSV = csv.reader(csvfile, delimiter=',') rownum = 0 header = 0 ip = [] usr = [] pwd = []
#!/usr/bin/python import sys # import os # import time # import getopt # import socket # import ConfigParser import struct # import binascii from pymodbus.client.sync import ModbusSerialClient seradd = str(sys.argv[1]) sdmid = int(sys.argv[2]) client = ModbusSerialClient(method = "rtu", port=seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1) # rq = client.read_holding_registers(0,8,unit=5) # print(rq.registers) resp = client.read_input_registers(0x06,2, unit=sdmid) print(struct.unpack('>f',struct.pack('>HH',*resp.registers))) resp = client.read_input_registers(0x08,2, unit=sdmid) print(struct.unpack('>f',struct.pack('>HH',*resp.registers))) resp = client.read_input_registers(0x0A,2, unit=sdmid) print(struct.unpack('>f',struct.pack('>HH',*resp.registers))) resp = client.read_input_registers(0x0C,2, unit=sdmid) print(struct.unpack('>f',struct.pack('>HH',*resp.registers))) resp = client.read_input_registers(0x0E,2, unit=sdmid) print(struct.unpack('>f',struct.pack('>HH',*resp.registers))) resp = client.read_input_registers(0x10,2, unit=sdmid) print(struct.unpack('>f',struct.pack('>HH',*resp.registers))) resp = client.read_input_registers(0x0156,2, unit=sdmid)
#!/usr/bin/python import sys import os import time import getopt import socket import ConfigParser import struct import binascii seradd = str(sys.argv[1]) from pymodbus.client.sync import ModbusSerialClient client = ModbusSerialClient(method="rtu", port=seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1) #rq = client.read_holding_registers(0,8,unit=5) #print(rq.registers) sdmid = int(sys.argv[2]) sdm2id = int(sys.argv[3]) resp = client.read_input_registers(0x00, 2, unit=sdmid) print(struct.unpack('>f', struct.pack('>HH', *resp.registers))) resp = client.read_input_registers(0x06, 2, unit=sdmid) print(struct.unpack('>f', struct.pack('>HH', *resp.registers))) resp = client.read_input_registers(0x0C, 2, unit=sdmid) print(struct.unpack('>f', struct.pack('>HH', *resp.registers))) resp = client.read_input_registers(0x1E, 2, unit=sdmid) print(struct.unpack('>f', struct.pack('>HH', *resp.registers))) resp = client.read_input_registers(0x0156, 2, unit=sdmid)
class TE485Modbus(object): def connect(self): self.mb = ModbusSerialClient( method='rtu', port='/dev/extcomm/0/0', stopbits=1, bytesize=8, parity=serial.PARITY_NONE, baudrate=19200, timeout=0.1, ) def set_sensitivity(self, sensitivity): ''' Set the sensitivity of the load cell 0x00 ......... 2 mV/V 0x01 ......... 5 mV/V 0x02 ....... 10 mV/V The greater the the sensitivity of the load cell means the amplifier/adc has to be less sensitive and thus a same change will cause smaller cange on the adc output. ''' # Set sensitivity self.mb.write_register(address=0, value=0xFF, unit=0x31) self.mb.write_register(address=16, value=sensitivity, unit=0x31) def calibrate(self, raw_zero, raw_full, full_cal_value): # Set upper limit value. self.mb.write_register(address=0, value=0xFF, unit=0x31) self.mb.write_register(address=20, value=full_cal_value, unit=0x31) # Calibrate zero self.mb.write_register(address=0, value=0xFF, unit=0x31) self.mb.write_register(address=18, value=raw_zero, unit=0x31) # Calibrate full. self.mb.write_register(address=0, value=0xFF, unit=0x31) self.mb.write_register(address=19, value=raw_full, unit=0x31) sleep(1) def read(self): r = self.mb.read_input_registers(0, count=3, unit=0x31) status, cal, raw = r.registers cal = ctypes.c_short(cal).value raw = ctypes.c_short(raw).value return status, cal, raw
def connect(self): self.client = ModbusSerialClient('rtu', port=self.port.port, baudrate=self.port.baudrate, timeout=self.port.timeout) self.client.connect()
def connect(): try: client = None client = ModbusClient(retries = 0, method='rtu', port='/dev/ttyUSB1', baudrate=38400, stopbits=1, parity='N', bytesize=8, timeout=1) client.connect() return client except Exception as e: print "Error while connecting client: \n"+e.__str__()