def __init__(self, sh, *args, **kwargs): self.logger = logging.getLogger(__name__) self._helios_ip = self.get_parameter_value('helios_ip') self._client = ModbusTcpClient(self._helios_ip) self.alive = False self._is_connected = False self._update_cycle = self.get_parameter_value('update_cycle')
def test_tcp_client_send(self): """ Test the tcp client send method""" client = ModbusTcpClient() self.assertRaises(ConnectionException, lambda: client.send(None)) client.socket = MockSocket() self.assertEqual(0, client.send(None)) self.assertEqual(4, client.send('1234'))
def test_tcp_client_recv(self): """ Test the tcp client receive method""" client = ModbusTcpClient() self.assertRaises(ConnectionException, lambda: client.receive(1024)) client.socket = MockSocket() self.assertEqual('', client.receive(0)) self.assertEqual('\x00'*4, client.receive(4))
def __init__(self, ip_address, port): if ip_address is not None or port is not None: if MODBUS_BACKEND == PYMODBUS3: self._client = ModbusTcpClient(ip_address, port=port) if MODBUS_BACKEND == UMODBUS: self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._sock.settimeout(2) # seconds self._sock.connect((ip_address, port)) super(COMx, self).__init__(com=self, registration_number=0)
def __init__(self, sh): from bin.smarthome import VERSION if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5': self.logger = logging.getLogger(__name__) self._helios_ip = self.get_parameter_value('helios_ip') self._client = ModbusTcpClient(self._helios_ip) self.alive = False self._is_connected = False self._update_cycle = self.get_parameter_value('update_cycle')
def connect(self): """Connect to target MODBUS server. """ try: self.client = ModbusTcpClient(self.config['ip_add']) self.client.connect() self.connected = True except: print('MODBUS CLIENT:', self.process_name, '-- unable to connect to target server.')
def test_tcp_client_connect(self): """ Test the tcp client connection method""" with patch.object(socket, 'create_connection') as mock_method: mock_method.return_value = object() client = ModbusTcpClient() self.assertTrue(client.connect()) with patch.object(socket, 'create_connection') as mock_method: mock_method.side_effect = socket.error() client = ModbusTcpClient() self.assertFalse(client.connect())
def runModBus(IOVariables): client = ModbusTcpClient('192.168.1.9') Digital_Out_1 = ModbusDigitalOutputIOCard(2048, client, IOVariables) try: Digital_Out_1.WriteStatus() except ConnectionException: print('A connection error to the modbus occured at {}'.format( datetime.datetime.now() ) ) pass client.close()
def read_sensors(request): sensors = Sensor.objects.all() sensor_data = [] dictionary = {} for sensor in sensors: client = ModbusTcpClient(sensor.address.server, port=502, timeout=1) try: client.connect() if sensor.sensor_type == Sensor.SensorType.DIGITAL: reply = client.read_discrete_inputs(sensor.channel, 1, unit=1) sensor_reading = reply.bits[0] sensor_response = { 'sensor_name': sensor.name, 'sensor_reading': sensor_reading } if sensor.digital_sensor_alert and sensor.email and str( sensor_reading) != sensor.last_value: if sensor.digital_alert_value and sensor_reading: send_sensor_alert_email(sensor, str(sensor_reading)) #send_sensor_alert_email() elif not sensor.digital_alert_value and not sensor_reading: send_sensor_alert_email(sensor, str(sensor_reading)) #send_sensor_alert_email() else: reply = client.read_input_registers(sensor.channel, 1, unit=1) sensor_reading = round( reply.registers[0] * sensor.conversion_factor, 2) if sensor.high_alert_value and sensor.email: if sensor_reading > sensor.high_alert_value and float( sensor.last_value) <= sensor.high_alert_value: send_sensor_alert_email(sensor, str(sensor_reading)) #send_sensor_alert_email() if sensor.low_alert_value and sensor.email: if sensor_reading < sensor.low_alert_value and float( sensor.last_value) >= sensor.low_alert_value: send_sensor_alert_email(sensor, str(sensor_reading)) #send_sensor_alert_email() sensor.last_value = str(sensor_reading) sensor.save() client.close() except: sensor_reading = "Could Not Connect" sensor_response = { 'sensor_name': sensor.name, 'sensor_reading': sensor_reading } sensor_data.append(sensor_response) client.close() dictionary['sensor_data'] = sensor_data return render(request, 'sensors/sensor_data.html', dictionary)
def setRelayState(interlock: Interlock_model, state: {0, 1}) -> Interlock_model.State: client = ModbusTcpClient(interlock.card.server) client.connect() client.write_coil(interlock.channel, state, unit=1) sleep(0.3) reply = client.read_coils(interlock.channel, 1, unit=1) state = reply.bits[0] client.close() if state == ModbusInterlock.MODBUS_OFF: return Interlock_model.State.LOCKED elif state == ModbusInterlock.MODBUS_ON: return Interlock_model.State.UNLOCKED
def __init__(self, address, port=502, logger=None): if not logger: self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.ERROR) else: self.logger = logger self.address = address self.client = ModbusTcpClient(address, port)
def __init__(self): if (self.logger == None): self.createLogger('generalPLCgateway') if len(self.plc_host) > 1: plc_client = ModbusTcpClient(self.plc_host) try: if len(self.plc_host) > 1: result = plc_client.read_holding_registers(0, 5, unit=0X01) if len(result.registers) == 5: print("Gateway connected succesfully to PLC : " + str(result)) #self.update_conected_plc(self.plc_host) else: print("connection is terminated ") self.logger.error("connection is terminated ") except Exception as e: print("error sending data to PLC " + str(e)) self.logger.error("error sending data to PLC " + str(e))
class Modbus: def __init__(self, uri='localhost', port=502): self.host = socket.gethostbyname(uri) self.client = ModbusClient(self.host, port=port) self.client.connect() # // TODO implement a fallback # if not self.client: # raise RuntimeError('Error establishing connection with uri {}'.format(uri)) def _read(self, response, typ='Float32'): if typ == 'Float32': raw = struct.pack('>HH', response.get_register(1), response.get_register(0)) return struct.unpack('>f', raw)[0] def read(self, register, n, unit=1, typ='Float32'): response = self.client.read_holding_registers(register, n, unit=unit) return self._read(response, typ) def readN(self, registers, n, unit=1): # // TODO implement reading multiple registers pass
def test_tcp_client_recv(self): """ Test the tcp client receive method""" client = ModbusTcpClient() self.assertRaises(ConnectionException, lambda: client.receive(1024)) client.socket = MockSocket() self.assertEqual('', client.receive(0)) self.assertEqual('\x00' * 4, client.receive(4))
def runModBus(IOVariables): #---------------------------------------------------------------------------# # 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. #---------------------------------------------------------------------------# client = ModbusTcpClient('192.168.1.9') #rq = client.write_registers(2048, [0]) #rr = client.read_input_registers(000, 1) #print (rr.registers) #---------------------------------------------------------------------------# # configure io card #---------------------------------------------------------------------------# #Digital_In_1 = ModbusDigitalInputIOCard(0, client) #print('IOVariables in modbus.py: {IOVariables} '.format(IOVariables=IOVariables)) Digital_Out_1 = ModbusDigitalOutputIOCard(2048, client, IOVariables) #---------------------------------------------------------------------------# # Run io card #---------------------------------------------------------------------------# #Digital_In_1.ReadStatus() #---------------------------------------------------------------------------# # Run io card #---------------------------------------------------------------------------# try: Digital_Out_1.WriteStatus() except ConnectionException: print('A connection error to the modbus occured at {}'.format( datetime.datetime.now() ) ) pass #---------------------------------------------------------------------------# # close the client #---------------------------------------------------------------------------# client.close()
def __init__(self, address:str, port:int=502, unit:int=1, method:str="rtu", retries:int=3, pollingtime:float=1.0): super().__init__() self.coil=self.create("coil",MBPLC.COIL) self.input=self.create("input",MBPLC.INPUT) self.holding=self.create("holding",MBPLC.HOLDING) self.register=self.create("register",MBPLC.REGISTER) self.address=address self.unit=unit self.port=port self.method=method self.retries=retries self.pollingtime=pollingtime self.client = ModbusClient(address, port, method=method, retries=retries) self.thread=Thread(target=self.__Polling, args=())
def get_1wire_config(ip_address): try: client = ModbusTcpClient(ip_address) wire_config = [] for i in range(MAX_1WIRE): holding_regs = client.read_holding_registers( HR_TI_001_ID_H + i * 4, 4) cur_uuid = format_uuid(holding_regs.registers) holding_regs = client.read_holding_registers(HR_TI_001 + i, 1) wire_config.append( [i, cur_uuid, i, to_signed(holding_regs.registers[0]) / 10.0]) client.close() return wire_config except ConnectionException: print("{0} - unavailable".format(cuip))
from pymodbus3.client.sync import ModbusTcpClient inp = input( u"Press any key and enter to send a packet... (Just enter to quit)") client = ModbusTcpClient('100.100.100.2') while (inp): client.write_coil(1, True) result = client.read_coils(1, 1) print(result.bits[0]) client.close() inp = input( u"Press any key and enter to send a packet... (Just enter to quit)")
def test_sync_tcp_client_instantiation(self): client = ModbusTcpClient() self.assertNotEqual(client, None)
def test_basic_sync_tcp_client(self): """ Test the basic methods for the tcp sync client""" # receive/send client = ModbusTcpClient() client.socket = MockSocket() self.assertEqual(0, client.send(None)) self.assertEqual(1, client.send('\x00')) self.assertEqual('\x00', client.receive(1)) # connect/disconnect self.assertTrue(client.connect()) client.close() # already closed socket client.socket = False client.close() self.assertEqual("127.0.0.1:502", str(client))
class HeliosTCP(SmartPlugin): PLUGIN_VERSION = "1.0.2" MODBUS_SLAVE = 180 PORT = 502 START_REGISTER = 1 _items = {} def __init__(self, sh): from bin.smarthome import VERSION if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5': self.logger = logging.getLogger(__name__) self._helios_ip = self.get_parameter_value('helios_ip') self._client = ModbusTcpClient(self._helios_ip) self.alive = False self._is_connected = False self._update_cycle = self.get_parameter_value('update_cycle') def run(self): """ Run method for the plugin """ self.logger.debug("Run method called") self._is_connected = self._client.connect() if not self._is_connected: self.logger.error( "Helios TCP: Failed to connect to Modbus Server at {0}".format( self._helios_ip)) self.scheduler_add('Helios TCP', self._update_values, cycle=self._update_cycle) self.alive = True def stop(self): """ Stop method for the plugin """ self.logger.debug("Stop method called") self.scheduler_remove('Helios TCP') self._client.close() self.alive = False def parse_item(self, item): if 'helios_tcp' in item.conf: varname = item.conf['helios_tcp'] if varname in VARLIST.keys(): self._items[varname] = item return self.update_item else: self.logger.warning( "Helios TCP: Ignoring unknown variable '{0}'".format( varname)) def _update_values(self): for item in self._items: self._read_value(self._items[item]) @staticmethod def _string_to_registers(instr: str): l = bytearray(instr, 'ascii') return [k[0] * 256 + k[1] for k in zip(l[::2], l[1::2])] + [0] def _read_value(self, item): try: var = item.conf['helios_tcp'] except ValueError: return try: varprop = VARLIST[var] except KeyError: self.logger.error( "Helios TCP: Failed to find variable '{0}'".format(var)) return # At first we write the variable name to read into the input registers: payload = self._string_to_registers(varprop['var']) request = self._client.write_registers(self.START_REGISTER, payload, unit=self.MODBUS_SLAVE) if request is None: self.logger.warning( "Helios TCP: Failed to send read request for variable '{0}'". format(var)) return # Now we may read the holding registers: response = self._client.read_holding_registers(self.START_REGISTER, varprop['length'], unit=self.MODBUS_SLAVE) if response is None: self.logger.warning( "Helios TCP: Failed to send read response for variable '{0}'". format(var)) return # Now we may dedocde the result # Note that we immediatly strip the varname from the result. result = response.encode().decode('ascii')[8:] result = list(result) # Remove trailing zeros: while result[-1] == '\x00': result.pop() result = ''.join(result) # Finally we may cast the result and return the obtained value: try: item(varprop["type"](result), self.get_shortname()) except ValueError: self.logger.warning( "Helios TCP: Could not assign {0} to item {1}".format( varprop["type"](result), item.id())) return def update_item(self, item, caller=None, source=None, dest=None): """ Item has been updated This method is called, if the value of an item has been updated by SmartHomeNG. It should write the changed value out to the device (hardware/interface) that is managed by this plugin. :param item: item to be updated towards the plugin :param caller: if given it represents the callers name :param source: if given it represents the source :param dest: if given it represents the dest """ if self.alive and caller != self.get_shortname(): try: var = item.conf['helios_tcp'] except ValueError: return newval = item() try: varprop = VARLIST[var] except KeyError: self.logger.error( "Helios TCP: Failed to find variable '{0}'".format(var)) return if not varprop["write"]: return if type(newval) != varprop["type"]: self.logger.error( "Helios TCP: Type mismatch for variable '{0}'".format(var)) return if newval < varprop["min"] or newval > varprop["max"]: self.logger.error( "Helios TCP: Variable '{0}' out of bounds. The allowed range is [{1}, {2}]" .format(var, varprop["min"], varprop["max"])) return if varprop["type"] == bool: payload_string = "{0}={1}".format(varprop["var"], int(newval)) elif varprop["type"] == int: payload_string = "{0}={1}".format(varprop["var"], int(newval)) elif varprop["type"] == float: payload_string = "{0}={1:.1f}".format(varprop["var"], newval) else: self.logger.error( "Helios TCP: Type {0} of varible '{1}' not known".format( varprop["type"], var)) return payload = self._string_to_registers(payload_string) request = self._client.write_registers(self.START_REGISTER, payload, unit=self.MODBUS_SLAVE) if request is None: self.logger.warning( "Helios TCP: Failed to send write request for variable '{0}'" .format(var)) return
def plugin_poll(handle): """ Poll readings from the modbus device and returns it in a JSON document as a Python dict. Available for poll mode only. Args: handle: handle returned by the plugin initialisation call Returns: returns a reading in a JSON document, as a Python dict, if it is available None - If no reading is available Raises: """ try: global mbus_client if mbus_client is None: try: source_address = handle['address']['value'] source_port = int(handle['port']['value']) except Exception as ex: e_msg = 'Failed to parse Modbus TCP address and / or port configuration.' _LOGGER.error('%s %s', e_msg, str(ex)) raise ValueError(e_msg) try: mbus_client = ModbusTcpClient(host=source_address, port=source_port) mbus_client_connected = mbus_client.connect() if mbus_client_connected: _LOGGER.info('Modbus TCP Client is connected. %s:%d', source_address, source_port) else: raise RuntimeError("Modbus TCP Connection failed!") except: mbus_client = None _LOGGER.warn('Failed to connect! Modbus TCP host %s on port %d', source_address, source_port) return """ read_coils(self, address, count=1, **kwargs) read_discrete_inputs(self, address, count=1, **kwargs) read_holding_registers(self, address, count=1, **kwargs) read_input_registers(self, address, count=1, **kwargs) - address: The starting address to read from - count: The number of coils / discrete or registers to read - unit: The slave unit this request is targeting On TCP/IP, the MODBUS server is addressed using its IP address; therefore, the MODBUS Unit Identifier is useless. Remark : The value 0 is also accepted to communicate directly to a MODBUS TCP device. """ unit_id = UNIT modbus_map = json.loads(handle['map']['value']) readings = {} # Read coils coils_address_info = modbus_map['coils'] if len(coils_address_info) > 0: for k, address in coils_address_info.items(): coil_bit_values = mbus_client.read_coils(99 + int(address), 1, unit=unit_id) readings.update({k: coil_bit_values.bits[0]}) # Discrete input discrete_input_info = modbus_map['inputs'] if len(discrete_input_info) > 0: for k, address in discrete_input_info.items(): read_discrete_inputs = mbus_client.read_discrete_inputs(99 + int(address), 1, unit=unit_id) readings.update({k: read_discrete_inputs.bits[0]}) # Holding registers holding_registers_info = modbus_map['registers'] if len(holding_registers_info) > 0: for k, address in holding_registers_info.items(): register_values = mbus_client.read_holding_registers(99 + int(address), 1, unit=unit_id) readings.update({k: register_values.registers[0]}) # Read input registers input_registers_info = modbus_map['inputRegisters'] if len(input_registers_info) > 0: for k, address in input_registers_info.items(): read_input_reg = mbus_client.read_input_registers(99 + int(address), 1, unit=unit_id) readings.update({k: read_input_reg.registers[0] }) wrapper = { 'asset': handle['assetName']['value'], 'timestamp': utils.local_timestamp(), 'key': str(uuid.uuid4()), 'readings': readings } except Exception as ex: _LOGGER.error('Failed to read data from modbus device. Got error %s', str(ex)) raise ex else: return wrapper
}, 'module10': { 'ch1': 713, 'ch2': 715, 'ch3': 717, 'ch4': 719 }, 'module11': { 'ch1': 721, 'ch2': 723, 'ch3': 725, 'ch4': 727 } } client = ModbusTcpClient('192.168.100.12') # configure I/O modules (input = 0x100, output = 0x180) client.write_register( 6146, 0x180, unit=10 ) #<--- this is supposed to config module 2, point 0 as an output but it doesn't work... client.write_register(input_output_flags['module2']['ch1'], 0x180) client.write_register(input_output_flags['module2']['ch2'], 0x180) client.write_register(input_output_flags['module2']['ch3'], 0x180) client.write_register(input_output_flags['module3']['ch1'], 0x180) print("config set") # save configuration to flash (doesn't work... see Opto doc 1465, page 104) #client.write_register(0, 0x00000003, unit=30) #print("saved to flash")
while threads_switch: global read_discrete_inputs_data global discrete_inputs_data if discrete_inputs_data != read_discrete_inputs_data: msg = str(read_discrete_inputs_data) rc, mid = mqtt_client.publish("one2one/fpq", payload=msg, qos=1) # qos on_publish(msg, rc) print(read_discrete_inputs_data) discrete_inputs_data = read_discrete_inputs_data logging.basicConfig() log = logging.getLogger() log.setLevel(logging.CRITICAL) modbus_client = ModbusClient('192.168.1.133', port=503, retries=2, framer=ModbusFramer) modbus_client.connect() write_coils_data = [] read_discrete_inputs_data = [] discrete_inputs_data = [] threads_switch = 1 while True: time.sleep(1) ''' threads = [] t1 = threading.Thread(target=modbus_rr) threads.append(t1) t2 = threading.Thread(target=modbus_print) threads.append(t2)
import time from pymodbus3.client.sync import ModbusTcpClient client = ModbusTcpClient('127.0.0.1') while True: client.write_coil(0, True) time.sleep(1.0) client.write_coil(0, False) time.sleep(1.0)
def display_remote_io(ip_address): ''' display remote I/O information at the given IP address ''' try: client = ModbusTcpClient(ip_address) client.write_coil(HW_CY_006, False) ip_holding_regs = client.read_holding_registers(HR_CI_006_CV, 6) client.write_registers(HW_CI_006_PV, ip_holding_regs.registers) cur_ip = format_modbus_ip_address(ip_holding_regs.registers[0], ip_holding_regs.registers[1]) cur_gateway = format_modbus_ip_address(ip_holding_regs.registers[2], ip_holding_regs.registers[3]) cur_subnet = format_modbus_ip_address(ip_holding_regs.registers[4], ip_holding_regs.registers[5]) ip_holding_regs = client.read_holding_registers(HR_CI_009_CV, 4) cur_mac = format_mac(ip_holding_regs.registers) ip_holding_regs = client.read_holding_registers(HR_KI_003, 2) cur_version = format_version(ip_holding_regs.registers[0]) print("{0} - {1}, version:{2}.{3}.{4} ".format( ip_address, device_type_name(ip_holding_regs.registers[1]), cur_version[1], cur_version[2], cur_version[3]), end='') print("gateway:{0}, subnet:{1} mac:{2}".format(cur_gateway, cur_subnet, cur_mac)) client.close() except ConnectionException: print("{0} - unavailable".format(ip_address))
from time import sleep import os from datetime import datetime #---------------------------------------------------------------------------# # configure the client logging #---------------------------------------------------------------------------# import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.INFO) #---------------------------------------------------------------------------# # We are going to use a simple client to send our requests #---------------------------------------------------------------------------# client = ModbusClient('192.168.33.1', port=10502) client.connect() FILENAME = 'rtu_5_log.csv' try: os.remove(FILENAME) except OSError: pass print("*"*30) print("SCADA server, reading the values of switch states, current and voltage readings") print("*"*30+"\n\n") fd = open(FILENAME, 'w+') csvrow = "timestamp;switch19;switch24;switch25;switch36;voltageb5;current19;current24;current25;current36\n"
#working ------- 1 seferde 124 tane cektik from pymodbus3.client.sync import ModbusTcpClient import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.DEBUG) #defaults ip="188.59.150.237" start="0" count="3" unit_number="2" #get necessary values #modbus connection client = ModbusTcpClient(ip) connection = client.connect() #read register request = client.read_holding_registers(int(start),int(count),unit=int(unit_number)) result = request.registers print (result) #result is the array of register values, can be accesses as result[i] #ege
# # 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('192.168.1.4', port=502) #client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1) # client = ModbusClient(method='rtu', port='/dev/ttyp0', timeout=1) client.connect() #---------------------------------------------------------------------------# # 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).
STOPC = 29835 #This are complements of control keys, must be write together with the control key AUTO = 35701 AUTOC = 29834 MANUAL = 35702 MANUALC = 29833 AUTOM = 35704 AUTOMC = 29831 START = 35705 STARTC = 29830 RESETAL = 35734 print("Waiting for the unit to start") time.sleep(30) host = sys.argv[1] print("Connecting to DSE with IP ", host) client = ModbusClient(host) client.connect() time.sleep(0.1) def sync_client_read(registerNumber): try: result = client.read_holding_registers(registerNumber, 1) return result.registers except: print("Connection Error Handled") output = False return output def read_register(PageNumber, RegisterOffset, Scale):
from pymodbus3.client.sync import ModbusTcpClient # instead of this # 192.168.1.22:502 #PLC Mod Bus Regs 40001-40100 #40096-40100 monnth day hour ..... #Reg 2 Bytes --> not 4 bytes plc_client = ModbusTcpClient('192.168.1.22') # result =client.read_holding_registers(0,5,unit=0X01) # print (str(result)) try: for x in range(5,6): result = plc_client.write_registers( 9,[int(x) ],unit=0X01) result = plc_client.write_registers(40007,[int(x) ],unit=0X01) result = plc_client.write_registers(40010,[int(1)],unit=0X01) print (str(result)) except Exception as e: print("error sending data to plc " + str(e)) plc_client.close()
import time import RPi.GPIO as GPIO from pymodbus3.client.sync import ModbusTcpClient #set up GPIO using BCM numbering GPIO.setmode(GPIO.BCM) #setup GPIO using Board numbering #GPIO.setmode(GPIO.BOARD) GPIO.cleanup() GPIO.setup(22, GPIO.OUT) GPIO.setup(5, GPIO.IN) client = ModbusTcpClient('127.0.0.1') while True: uzaklik=GPIO.input(5) print(uzaklik) if(uzaklik == 1.0): # Uncomment if connected to led # GPIO.output(22, True) client.write_register(1, 1) if(uzaklik == 0.0): # Uncomment if connected to led # GPIO.output(22, False) client.write_register(1, 1) time.sleep(1.0)
class __CalculatedParams: params = ConfParams() user = ThingBoardUser() dt2 = 1 / 6000 TMS_DL = float(params.getParam("INITIAL_TMS_DL")) CFT = 0 TCC_MODE = params.getParam("TCC_MODE") TCC = float(params.getParam("INITIAL_TCC")) alpha0 = int(params.getParam("IIR_Alfa")) dict_Tcycle_A_2_by_sensor_id = {} dict_Tcharge_by_sensor_id = {} timer = None plc_client = None if len(params.getParam("PLC_HOST")) > 1: plc_client = ModbusTcpClient(params.getParam("PLC_HOST")) # after 30 seconds, "hello, world" will be printed # a time counter will be more than “TMS” or the time counter will be more than 5 sec def init_timer(self): # print("init_timer:"+str(self.TMS)) min_interval = min(5.0, float(self.TMS_DL)) self.timer = threading.Timer(min_interval, self.timerFunction) self.timer.start() def timerFunction(self): self.submit_CFT_and_TCC() # print("sent by Timer, TMS:"+str(self.TMS)) def set_param(self, sensor_id, param_name, value): if self.timer == None: self.init_timer() if (not param_name): return if (param_name == "Tcycle_A_2"): self.process_Tcycle_A_2(sensor_id, value) elif (param_name == "Tcharge"): self.process_Tcharge(sensor_id, value) elif (param_name == "TBagSpacing"): self.submit_parameter("TBS", 0.01 * value, 3) elif (param_name == "ChBHight"): self.submit_parameter("ABH", 0.1 * value, 4) elif (param_name == "Tbaglength"): self.submit_parameter("TBL", 0.01 * value, 5) def submit_parameter(self, out_param_name, value, plc_reg_address=None): ts = {"ts": int(round(time.time() * 1000))} # if start_new_data: data = [] new_obj_to_send = {"ts": ts["ts"], "values": {}} # Lior process out_param_name ,value # Change - Start attr_to_send = calculate_info(out_param_name, value) #print(value_storage) #print(attr_to_send) self.user.send_attributes("PLC", attr_to_send) # new_obj_to_send["values"][out_param_name] = value new_obj_to_send["values"][out_param_name] = add_color_digit(value, out_param_name) # Change - End data.append(new_obj_to_send) value = int(value * pow(2, 9)) try: try: if not self.plc_client == None: result = self.plc_client.write_registers(plc_reg_address, [value], unit=0X01) print(out_param_name + " Sent to PLC : " + str(value)) self.sendIsAlive() except Exception as e: print("error sending data to PLC : " + str(e)) self.user.send_telemetry("PLC", data, False, None, None) except Exception as e: print("error sending data to Things Board : " + str(e)) # self.generalLogger.error("error sending data serv " + str(e)) def process_Tcycle_A_2(self, sensor_id, value): self.dict_Tcycle_A_2_by_sensor_id[sensor_id] = value if (len(self.dict_Tcycle_A_2_by_sensor_id) == 3 and len(self.dict_Tcharge_by_sensor_id) == 3): self.submit_CFT_and_TCC() def process_Tcharge(self, sensor_id, value): self.dict_Tcharge_by_sensor_id[sensor_id] = value if (len(self.dict_Tcycle_A_2_by_sensor_id) == 3 and len(self.dict_Tcharge_by_sensor_id) == 3): self.submit_CFT_and_TCC() def sendIsAlive(self): data = {"ts": int(round(time.time() * 1000)), "values": {"is_alive": True}} jsonData = json.dumps(data) re = self.user.post(self.user.telemetry_url.format(self.user.access_token("MODBUS")), jsonData) def submit_CFT_and_TCC(self): if not self.timer == None: self.timer.cancel() if (len(self.dict_Tcycle_A_2_by_sensor_id) == 0 and len(self.dict_Tcharge_by_sensor_id) == 0): # print("no values to be sent by timer, init_timer") self.init_timer() return Nsyc = 0 ATsycle = 0 self.CFT = 0 for value in self.dict_Tcycle_A_2_by_sensor_id.values(): if (value > 2800 and value < 18000): ATsycle += value Nsyc += 1 if Nsyc: ATsycle = ATsycle / Nsyc self.TMS_DL = (float(((10000 - (float(self.alpha0))) * (float(self.TMS_DL)) + (float(self.alpha0)) * ( float(ATsycle))) / 10000)) # self.TMS = self.dt2*float(self.TMS_DL) Nsyc = 0 Tcharge_values_list = [] if self.TCC_MODE == '0': for value in self.dict_Tcharge_by_sensor_id.values(): if (value > 0 and value < self.TMS_DL): Tcharge_values_list.append(int(value)) else: Tcharge_values_list.append(0) if len(Tcharge_values_list) > 0: self.TCC = self.dt2 * max(Tcharge_values_list) elif self.TCC_MODE == '1': self.TCC = 0 for value in self.dict_Tcharge_by_sensor_id.values(): if (value > 0 and value < self.TMS_DL): self.TCC += value Nsyc += 1 if Nsyc: self.TCC = self.dt2 * self.TCC / Nsyc # Mode 2: (Median(TCharge(1), TCharge(2), TCharge(3))) # If 0<TCharge(n)<( TMS_DL), Add TCharge(n) to a buffer # TCC = dt2*(median of the buffer) if self.TCC_MODE == '2': for value in self.dict_Tcharge_by_sensor_id.values(): if (value > 0 and value < self.TMS_DL): Tcharge_values_list.append(int(value)) if len(Tcharge_values_list) > 0: self.TCC = self.dt2 * median(Tcharge_values_list) else: self.TCC = 0 elif self.TCC_MODE == '3': for value in self.dict_Tcharge_by_sensor_id.values(): if (value > 0 and value < self.TMS_DL): Tcharge_values_list.append(int(value)) else: Tcharge_values_list.append(0) if len(Tcharge_values_list) > 0: value1 = max(Tcharge_values_list) Tcharge_values_list.remove(value1) if len(Tcharge_values_list) > 0: value2 = max(Tcharge_values_list) self.TCC = self.dt2 * (value1 + value2) / 2 else: self.TCC = self.dt2 * value1 if ATsycle > 0: self.CFT = self.dt2 * ATsycle - self.TCC; ts = {"ts": int(round(time.time() * 1000))} # if start_new_data: data = [] new_obj_to_send = {"ts": ts["ts"], "values": {}} # Change - Start attr_to_send = calculate_info("CFT", self.CFT) #print(value_storage) #print(attr_to_send) self.user.send_attributes("PLC", attr_to_send) attr_to_send = calculate_info("TCC", self.TCC) #print(attr_to_send) self.user.send_attributes("PLC", attr_to_send) # new_obj_to_send["values"]["CFT"] = self.CFT new_obj_to_send["values"]["CFT"] = add_color_digit(self.CFT, "CFT") # new_obj_to_send["values"]["TCC"] = self.TCC new_obj_to_send["values"]["TCC"] = add_color_digit(self.TCC, "TCC") # Change - End data.append(new_obj_to_send) cftToSend = int(self.CFT * pow(2, 9)) tccToSend = int(self.TCC * pow(2, 9)) try: try: if not self.plc_client == None: result = self.plc_client.write_registers(1, [tccToSend], unit=0X01) print(" TCC data sent to PLC : " + str(tccToSend)) result = self.plc_client.write_registers(6, [cftToSend], unit=0X01) print(" CFT data sent to PLC : " + str(cftToSend)) result = self.plc_client.write_registers(9, [1], unit=0X01) self.sendIsAlive() except Exception as e: print("error sending data to PLC : " + str(e)) self.user.send_telemetry("PLC", data, False, None, None) except Exception as e: print("error sending data to Things Board : " + str(e)) # self.generalLogger.error("error sending data serv " + str(e)) self.dict_Tcycle_A_2_by_sensor_id = {} self.dict_Tcharge_by_sensor_id = {} # self.timer = threading.Timer(min(5,int(self.TMS)), self.timerFunction) self.init_timer()
def write_network_config(cuip, aip, agw, asn, amac): try: client = ModbusTcpClient(cuip) client.write_register(HW_CI_006_PV, aip >> 16) client.write_register(HW_CI_006_PV + 1, aip & 0xffff) client.write_register(HW_CI_007_PV, agw >> 16) client.write_register(HW_CI_007_PV + 1, agw & 0xffff) client.write_register(HW_CI_008_PV, asn >> 16) client.write_register(HW_CI_008_PV + 1, asn & 0xffff) client.write_register(HW_CI_009_PV, 0) client.write_register(HW_CI_009_PV + 1, amac >> 32) client.write_register(HW_CI_009_PV + 2, (amac & 0xFFFFFFFF) >> 16) client.write_register(HW_CI_009_PV + 3, (amac & 0xFFFFFFFF) & 0xffff) client.write_coil(HW_CY_006, True) client.close() except ConnectionException: print("{0} - unavailable".format(cuip))
DCCurrentRegisterOffset = 201 STOP = 35700 #This are control keys STOPC = 29835 #This are complements of control keys, must be write together with the control key AUTO = 35701 AUTOC = 29834 MANUAL = 35702 MANUALC = 29833 AUTOM = 35704 AUTOMC = 29831 START = 35705 STARTC = 29830 RESETAL = 35734 host = sys.argv[1] print("Connecting to DSE with IP ", host) client = ModbusClient(str(host), port = 502) client.connect() time.sleep(0.1) def sync_client_read(registerNumber): try: result = client.read_holding_registers(registerNumber,1) return result.registers except: print("Connection Error Handled") output = False return output def read_register(PageNumber, RegisterOffset, Scale): register = 256 * PageNumber + RegisterOffset read = sync_client_read(register)
from pymodbus3.client.sync import ModbusTcpClient #.client.sync import time as t from twisted.internet import reactor, protocol from pymodbus3.constants import Defaults import logging logging.basicConfig() a = 1 client = ModbusTcpClient('10.181.5.35', port=502) 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 #result = client.read_coils(0,1) """arguments = { 'read_address': 1, 'read_count': 8, 'write_address': 1, 'write_registers': [20]*8,""" while a < 4: rq = client.write_registers(0, [0] * 15) rq2 = client.write_registers( 1000, [241] * 100) #Startadresse, skrevet verdi, antall registre log = logging.getLogger() log.setLevel(logging.DEBUG) client.write_coil(0, True) client.write_coil(1, True) client.write_coil(2, False) client.write_coil(3, True)
def main(): registersPerPage = 256 RPMPageNumber = 4 RPMRegisterOffset = 6 DCCurrentPageNumber = 4 DCCurrentStartOffset = 204 DCCurrentEndOffset = 205 STOP = 35700; # 10001011(H8B,D139) 01110100(H74,116) # -29836 (35700) STOPC = 29835; # 01110100(H74,D116) 10001011(H8B,D139) # 29835 AUTO = 35701; # 10001011(H8B,D139) 01110101(H75,D117) # -29835 (35701) AUTOC = 29834; # 01110100(H74,D116) 10001010(H8A,D138) # 29834 MANUAL = 35702; # 10001011(H8B,D139) 01110110(H76,D118) # -29834 (35702) MANUALC = 29833; # 01110100(H74,D116) 10001001(H89,D137) # 29833 AUTOM = 35704; # 10001011(H8B,D139) 01111000(H78,D120) # -29832 (35704) AUTOMC = 29831; # 01110100(H74,D116) 10000111(H87,D135) # 29831 START = 35705; # 10001011(H8B,D139) 01111001(H79,D121) # -29831 (35705) STARTC = 29830; # 01110100(H74,D116) 10000110(H87,D134) # 29830 RESETAL = 35734; # 10001011(H8B,D139) 10010110(H96,D150) # -35734 (35734) #RESETALC = 29801; # #RESETA2 = 35734; # 10001011(H8B,D139) 10010110(H96,D150) # (35734) #RESETA2C = 29828; #RESETAT = -29801; # 10001011(H8B,D139) 10010110(H96,D150) # -35734 (35734) #RESETATC = 29800; MODE_STOP = 0; #Stop mode MODE_AUTO = 1; #Auto mode MODE_MANUAL = 2; #Manual mode MODE_TEST = 3; #Test on load mode MODE_AUTO_MRESTORE = 4; #Auto with manual restore mode/Prohibit Return MODE_USER_CONFIG = 5; #User configuration mode MODE_TEST_OFF_LOAD = 6; #Test off load mode host = sys.argv[1] print(host) client = ModbusClient(str(host), port=502) client.connect() time.sleep(0.1) rm = client.write_registers(4104, [MANUAL,MANUALC]) print("Change DSE to MANUAL mode, starting engine in 5 seconds...") x = 4 while x>=1: time.sleep(1) print(str(x)) x-=1 rq = client.write_registers(4104, [START,STARTC]) time.sleep(3) print("Starting engine, proceding to read RPM and DC current") time.sleep(1) x = 1 while x==1: time.sleep(0.01) register = registersPerPage * RPMPageNumber + RPMRegisterOffset global RPMRegister RPMRegister = sync_client_read(register) register = registersPerPage * DCCurrentPageNumber + DCCurrentEndOffset global DCRegister DCRegister = sync_client_read(register) DCRegister = float(DCRegister) x = 0 os.system('sudo python3 readings.py') while 1==1: time.sleep(0.01) register = registersPerPage * RPMPageNumber + RPMRegisterOffset RPMRegister = sync_client_read(register) register = registersPerPage * DCCurrentPageNumber + DCCurrentEndOffset DCregister = sync_client_read(register) DCRegister = float(DCRegister)
class MBPLC(PLC): """PLC con comunicación Modbus. Args: address (str): Dirección IP (o nombre) del controlador. port (int): Puerto de conexión. Típicamente el 502. unit (int): Número de esclavo. method (str): Método de conexión (RTU/ASCII) retries (int): Reintentos de lectura/escritura. client (ModbusClient): Cliente modbus. pollingtime (float): Segundos entre escaneos. Attributes: coil (Memory): Memoria de bobinas. input (Memory): Memoria de entradas digitales. holding (Memory): Memoria de registros de retención. register (Memory): Memoria de registros de entrada. client (ModbusClient): Cliente Modbus. thread (Thread): Hebra de escaneo. """ class COIL: """Tipo de memoria COIL.""" pass class INPUT: """Tipo de memoria INPUT.""" pass class HOLDING: """Tipo de memoria HOLDING.""" pass class REGISTER: """Tipo de memoria REGISTER.""" pass class Memory(PLC.Memory): ''' Representacióne un área de memoria. Args: plc (PLC): Controlador al que pertenece. memorytype (type): Tipo de memoria (COIL, INPUT, HOLDING, REGISTER). Attributes: minindex (int): Dirección más baja de la memoria leída. maxindex (int): Dirección más alta de la memoria leída. ''' class Tag(PLC.Memory.Tag): ''' Variable de controlador Modbus. Args: memory (Memory): Memoria a la que pertenece. key (str): Nombre. description (str): Descripción. address: Dirección (None si no esta asociada). Attributes: value: Valor. subscriptor (Subcriptor[]): Objetos suscritos a los cambios. ''' def __init__(self, memory:PLC.Memory, key:str, description:str="", address=None): if type(address)==str: address=int(address) super().__init__(memory,key,description,address) if memory.minindex is None or memory.minindex>address: memory.minindex=address if memory.maxindex is None or memory.maxindex<address: memory.maxindex=address def set(self, value): ''' Modifica el valor de una variable. Args: value: Nuevo valor de la variable. ''' plc=self.memory.plc if plc.connected: try: if self.memory.memorytype==MBPLC.COIL: if isinstance(value,str): if value.upper()=="TRUE" or value=="1": value=True elif value.upper()=="FALSE" or value=="0": value=False rw = plc.client.write_coil(self.address,value,unit=plc.unit) if self.memory.memorytype==MBPLC.HOLDING: if isinstance(value,str): value=int(value) rw = plc.client.write_register(self.address,value,unit=plc.unit) self.update(value) except Exception as e: self.memory.plc.connected=False printexception(e,"Error writing to PLC") def __init__(self, plc:PLC, memorytype:type): self.memorytype=memorytype self.minindex=None self.maxindex=None super().__init__(plc) def __init__(self, address:str, port:int=502, unit:int=1, method:str="rtu", retries:int=3, pollingtime:float=1.0): super().__init__() self.coil=self.create("coil",MBPLC.COIL) self.input=self.create("input",MBPLC.INPUT) self.holding=self.create("holding",MBPLC.HOLDING) self.register=self.create("register",MBPLC.REGISTER) self.address=address self.unit=unit self.port=port self.method=method self.retries=retries self.pollingtime=pollingtime self.client = ModbusClient(address, port, method=method, retries=retries) self.thread=Thread(target=self.__Polling, args=()) def create(self,memory_key, memorytype:type): ''' Crea una memoria en el controlador. Args: memory_key (str): Nombre o identificador de la memoria. memorytype (type): Tipo de memoria (COIL, INPUT, HOLDING, REGISTER). Returns (Memory): Memoria que se ha creado. ''' return self.set(memory_key, self.Memory(self, memorytype)) def connect(self): ''' Conexión con el controlador ''' self.thread.start() def disconnect(self): ''' Termina la conexión con el controlador. ''' self.connected=false self.client.close() def read(self): ''' Lectura de un área de memoria del controlador real. Si falla la lectura (tras el número de reintentos) se actualiza el estado de conexión a desconectado. ''' try: if not self.coil.minindex is None: rr = self.client.read_coils(self.coil.minindex, self.coil.maxindex-self.coil.minindex+1,unit=self.unit) for i in range(self.coil.minindex,self.coil.maxindex+1): if i in self.coil.tagbyaddress: self.coil.tagbyaddress[i].update(rr.bits[i-self.coil.minindex]) if not self.input.minindex is None: rr = self.client.read_discrete_inputs(self.input.minindex, self.input.maxindex-self.input.minindex+1,unit=self.unit) for i in range(self.input.minindex,self.input.maxindex+1): if i in self.input.tagbyaddress: self.input.tagbyaddress[i].update(rr.bits[i-self.input.minindex]) if not self.holding.minindex is None: rr = self.client.read_holding_registers(self.holding.minindex, self.holding.maxindex-self.holding.minindex+1,unit=self.unit) for i in range(self.holding.minindex,self.holding.maxindex+1): if i in self.holding.tagbyaddress: self.holding.tagbyaddress[i].update(rr.registers[i-self.holding.minindex]) if not self.register.minindex is None: rr = self.client.read_input_registers(self.register.minindex, self.register.maxindex-self.register.minindex+1,unit=self.unit) for i in range(self.register.minindex,self.register.maxindex+1): if i in self.register.tagbyaddress: self.register.tagbyaddress[i].update(rr.registers[i-self.register.minindex]) except Exception as e: self.coil.plc.disconnect() printexception(e,"Error reading from PLC") def __Polling(plc): ''' Lectura de todas las áreas de escaneo. Establece la conexión con los controladores, si no se ha hecho antes, o se ha perdido. ''' while True: if plc.connected: plc.read() time.sleep(plc.pollingtime) else: print("Connecting to MBPLC "+plc.address+":"+str(plc.port)+"("+str(plc.unit)+")") plc.connected=plc.client.connect()