def scan():
    
    parser = argparse.ArgumentParser(description = "Read all holding registries from a TCP MODBUS Slave")
    parser.add_argument("ip", help="IP address of the slave")
    parser.add_argument("-p", "--port", dest="port", help="Modbus Port. Defaults to 502", type=int, metavar="PORT", default=502)
    parser.add_argument("-u", "--uid", dest="uid", help="Modbus Unit ID. Defaults to 1", type=int, metavar="UID", default=1)
    parser.add_argument("-sa", "--start-address", dest="start_address", help="Starting Address for the scanner. Defaults to 1", type=int, metavar="START", default=1)
    parser.add_argument("-ea", "--end-address", dest="end_address", help="Ending Address for the scanner. Defaults to 65535", type=int, metavar="END", default=65535)
    
    args = parser.parse_args()
    
    try:
        ip = args.ip
    except IndexError:
        print "ERROR: No target to scan\n\n"
        parser.print_help()
        exit()

    # ip address format verification
    if not validate_ipv4(ip):
        print "ERROR: IP address is invalid\n\n"
        parser.print_help()
        exit()

    print 'Connecting to %s...' % ip,
    # connect to modbus slave
    client = ModbusTcpClient(ip, args.port)
    client.connect()
    if client.socket == None:
        print "ERROR: Could not connect to %s." %ip
        exit()
    print ' Connected.'

    # TODO add ETA mechanism
    results = {}
    addr = 1
    registers_tested = args.end_address - args.start_address + 1
    if registers_tested == 1:
        hr = client.read_holding_registers(args.start_address, 1, unit=args.uid) # unit value is device id of the slave (UID)
        if hr.function_code == 3: # if we succeed reading stuff
            results[addr] = hr.registers[0]
        # if it fails, hr.function = 131 (0x83), cf modbus doc
    else:
    	for addr in range(args.start_address, args.end_address):
            hr = client.read_holding_registers(addr, 1, unit=args.uid) # unit value is device id of the slave (UID)
            if hr.function_code == 3: # if we succeed reading stuff
                results[addr] = hr.registers[0]
            # if it fails, hr.function = 131 (0x83), cf modbus doc

    client.close()
    print 'Register scanning is finished (%d registers were tried)' % (registers_tested)
    # sorting dict for printing
    ordered_results = collections.OrderedDict(sorted(results.items()))
    for addr, value in ordered_results.iteritems():
        print 'Addr {0} \t{1}'.format(addr,value)
Exemplo n.º 2
0
class ModbusModule():
    def __init__(self, io_module_name, ip):
        logger.debug('Creating new controller with name {} and address {}.'.format(io_module_name, ip))
        self.io_module_name = io_module_name
        self.ip_address = ip
        self.controller_type = CONTROLLER_TYPE.Modbus
        # build connection object
        self.client = ModbusClient(ip, port=config.DEFAULT_MODBUS_PORT)
        self.client.connect()

    def __del__(self):
        self.client.close()

    def __str__(self):
        return 'Controller "{}" at address {}'.format(self.io_module_name, self.ip_address)

    def get_bit(self, address):
        try:
            result = self.client.read_coils(address)
            bit_value = result.bits[0]
        except ConnectionException:
            logger.error('Could not connect to Modbus module "{}"!'
                         .format(self.io_module_name))
            bit_value = False
        return bit_value

    def set_bit(self, address, value):
        try:
            self.client.write_coil(address, value)
        except ConnectionException:
            logger.error('Could not connect to Modbus module "{}"!'
                         .format(self.io_module_name))
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
def wren_gw_modbus_read(config):
    ''' read a value from the peer.

    @param config the configuration in the key/value type.
    '''

    try:
        m = ModbusTcpClient(host=config['node'], port=config['port'])
        m.connect()
        unit = 0xff
        if config.has_key('unit_id'):
            unit = config['unit_id']
        # sed data
        value = None
        if config['table'] == 'InputRegister':
            result = m.read_input_registers(config['address'], 1, unit=unit)
            if result:
                value = result.registers[config['address']]
        if config['table'] == 'HoldingRegister':
            result = m.read_holding_registers(config['address'], 1, unit=unit)
            if result:
                value = result.registers[config['address']]
        # close it.
        m.close()
        return {"status":True, "value":str(value)};
    except Exception as e:
        return {"status":False, "value":str(e)};
Exemplo n.º 5
0
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)};
Exemplo n.º 6
0
def _run_single_client(client_id, host, port, units, results, N, delay, warmup, table):
    _log.info('Client %d connecting to %s (%s)', client_id, host, port)
    client = ModbusClient(host, port=port)
    client.connect()

    _log.info('Client %d connected to %s (%s)', client_id, host, port)

    measurements = []
    errors = []
    for i in xrange(N):
        if N >= 1000 and i % (N/10) == 0 and i > 0:
            _log.info('Client %d %.0f%% complete', client_id, 100.0*i/N)
        try:
            m = _make_random_request(client, units, table)
            if i >= warmup or N <= warmup:
                if i == warmup:
                    _log.info('Client %d warmup complete.', client_id)
                measurements.append(m)
        except jem_exceptions.JemException, e:
            errors.append(e)
            _log.warn('Client %d received error response: %s', client_id, e)
        except Exception, e:
            from pymodbus import exceptions as es
            _log.error("Caught other exception: %s" % str(e))
            _log.error("Is instance: %s", isinstance(e, es.ModbusException))
Exemplo n.º 7
0
class TestMbTcpClass0(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_read_holding_registers(self):
		rv = self.client.read_holding_registers(0, 16)
		self.assertEqual(rv.function_code, 0x03)
		self.assertEqual(rv.registers, self.read_values)
		
	def test_read_holding_registers_exception(self):
		rv = self.client.read_holding_registers(16, 1)
		self.assertEqual(rv.function_code, 0x83)
		self.assertEqual(rv.exception_code, 0x02)
	
	def test_write_holding_registers(self):
		rq = self.client.write_registers(0, self.write_values)
		self.assertEqual(rq.function_code, 0x10)
		rr = self.client.read_holding_registers(0, 16)
		self.assertEqual(rr.registers, self.write_values)
		rq = self.client.write_registers(0, self.read_values)
		self.assertEqual(rq.function_code, 0x10)
		
	def test_write_holding_registers_exception(self):
		rq = self.client.write_registers(16, [0x00])
		self.assertEqual(rq.function_code, 0x90)
		self.assertEqual(rq.exception_code, 0x02)
Exemplo n.º 8
0
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]
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
    def testTcpClientConnect(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())
Exemplo n.º 11
0
 def get_temp(self, addr):
     # connect to modbus slave
     try:
         client = ModbusClient(addr, port=502)
         client.connect()
         rr = client.read_holding_registers(0x00,1,unit=1)
         temp = rr.registers[0]
         return temp
     except:
         # if unable to connect, return None
         log_stuff("Unable to connect to " + self.addr)
         return None
Exemplo n.º 12
0
def create_sunspec_sync_client(host):
    """ A quick helper method to create a sunspec
    client.

    :param host: The host to connect to
    :returns: an initialized SunspecClient
    """
    modbus = ModbusTcpClient(host)
    modbus.connect()
    client = SunspecClient(modbus)
    client.initialize()
    return client
Exemplo n.º 13
0
def main(host, port, delay, unit, table_num):
    client = ModbusClient(host, port=port)
    client.connect()
    
    min_response_time = 100
    max_response_time = 0
    sum_response_time = 0
    N = 0

    register_widths = diris_registers.TABLES[table_num-1].copy()
    register_labels = DEMO_REGISTERS.copy()
    registers = dict((addr, register_widths[addr]) \
                        for addr in DEMO_REGISTERS.keys() \
                        if addr in register_widths)

    label_width = max([len(label) for label in DEMO_REGISTERS.values()]) + 1

    while True:
    
        start = time.time()
        try:
            response = modbus.read_registers(client,
                                             registers=registers,
                                             unit=unit)
        except exceptions.ModbusExceptionResponse, e:
            response=None
    
        response_time = time.time() - start

        os.system('clear')

        print "Request Times:"

        min_response_time = min(min_response_time, response_time)
        max_response_time = max(max_response_time, response_time)
        sum_response_time += response_time
        N += 1
    
        print "Min".rjust(label_width) + ": " + str(min_response_time)
        print "Max".rjust(label_width) + ": " + str(max_response_time)
        print "Avg".rjust(label_width) + ": " + str(sum_response_time/N)

        print "Response Values:"
        for addr in sorted(registers.keys()):
            if response is None:
                break
            print (u"{label:>" + str(label_width) + u"s}: {value:f}").format(
                    label=register_labels[addr],
                    value=response.read_register(addr))

        print
        time.sleep(delay)
Exemplo n.º 14
0
class TcpRtuChannel(BaseChannel):
    def __init__(self, network, channel_name, channel_protocol, channel_params, manager, channel_type):
        self.server = channel_params.get("server", "")
        self.port = channel_params.get("port", "")
        self.modbus_client = None
        BaseChannel.__init__(self, network, channel_name, channel_protocol, channel_params, manager, channel_type)

    def run(self):
        self.modbus_client = ModbusTcpClient(host=self.server, port=self.port)
        try:
            self.modbus_client.connect()
            logger.debug("连接服务器成功.")
        except Exception, e:
            logger.error("连接服务器失败,错误信息:%r." % e)
Exemplo n.º 15
0
def main():
    # connect to modbus slave
    client = ModbusClient(args.slave_addr, port=502)
    client.connect()

    try:
        while True:
            # get value of holding registers (first has the temperature value)
            rr = client.read_holding_registers(0x00,1,unit=1)
            temp = rr.registers[0]
            enable_light(temp)
            time.sleep(3)
    except KeyboardInterrupt:
        subprocess.call(['gpio', 'write', '0', '0'])
        subprocess.call(['gpio', 'write', '1', '0'])
        print "Exiting..."
Exemplo n.º 16
0
def scan():
    
    parser = argparse.ArgumentParser(description = "Write all holding registries on a TCP MODBUS Slave")
    parser.add_argument("ip", help="IP address of the slave")
    parser.add_argument("-p", "--port", dest="port", help="Modbus Port. Defaults to 502", type=int, metavar="PORT", default=502)
    parser.add_argument("-u", "--uid", dest="uid", help="Modbus Unit ID. Defaults to 1", type=int, metavar="UID", default=1)
    parser.add_argument("-sa", "--start-address", dest="start_address", help="Starting Address for the writer. Defaults to 1", type=int, metavar="START", default=1)
    parser.add_argument("-ea", "--end-address", dest="end_address", help="Ending Address for the writer. Defaults to 65535", type=int, metavar="END", default=65535)
    parser.add_argument("-v", "--value", dest="value", help="Value that will be written. Defaults to 7777", type=int, metavar="VALUE", default=7777)
    
    args = parser.parse_args()
    
    try:
        ip = args.ip
    except IndexError:
        print "ERROR: No target given\n\n"
        parser.print_help()
        exit()

    # ip address format verification
    if not validate_ipv4(ip):
        print "ERROR: IP address is invalid\n\n"
        parser.print_help()
        exit()

    print 'Connecting to %s...' % ip,
    # connect to modbus slave
    client = ModbusTcpClient(ip, args.port)
    client.connect()
    if client.socket == None:
        print "ERROR: Could not connect to %s." %ip
        exit()
    print ' Connected.'

    # TODO add ETA mechanism
    results = []
    addr = 1
    for addr in range(args.start_address, args.end_address):
        hr = client.write_registers(addr, args.value, unit=args.uid) # unit value is device id of the slave (UID)
        if hr.function_code == 16: # if we succeeded writing stuff. code = 0x10
            results.append(addr)
        # if it fails, hr.function = 144 (0x90), cf modbus doc

    client.close()
    print 'Register writing is finished (%d addresses were tried)' % (args.end_address-args.start_address+1)
    print 'Writing was successful on these %d addresses:' % len(results)
    print results
Exemplo n.º 17
0
def connect_modbus(modbus_ip, modbus_port):
    try:
        client = ModbusClient(modbus_ip, port=modbus_port)
    except:
        return None
    if client.connect():
        return client
    return None
Exemplo n.º 18
0
def get_modbus(properties):
    try:
        print "Performing an action which may throw an exception."
        client = ModbusClient(properties['ip'], port=502)
        client.connect()
        log.debug(properties['registers'])
        log.debug(properties['coils'])
        modbus_values = {}
        
        # Get holding registers values
        modbus_registers = {}
        for i in properties['registers']:
            register_start_nb = i.split('-')[0]
            register_end_nb = i.split('-')[1]
            log.debug('Register start number : %s' % register_start_nb)
            log.debug('Register end number : %s' % register_end_nb)
            register_count = int(register_end_nb) - int(register_start_nb)
            log.debug('Number of registers to read : %s' % register_count)
            rr = client.read_holding_registers(int(register_start_nb),register_count, unit=0x01)
            modbus_registers[register_start_nb] = rr.registers
            log.debug('Registers values : %s' % rr.registers)

        # Get coils values
        modbus_coils = {}
        for i in properties['coils']:
            coil_start_nb = i.split('-')[0]
            coil_end_nb = i.split('-')[1]
            log.debug('Coil start number : ' + register_start_nb)
            log.debug('Coil end number : ' + register_end_nb)
            coil_count = int(coil_end_nb) - int(coil_start_nb)
            log.debug('Number of coils to read : ' + str(coil_count))
            rr = client.read_coils(int(coil_start_nb),coil_count, unit=0x01)
            modbus_coils[coil_start_nb] = rr.bits
            log.debug('Coils values : ' + str(rr.bits))
            log.debug('Modbus coils values : ' + str(modbus_coils))

        client.close()
        modbus_values['registers'] = modbus_registers
        modbus_values['coils'] = modbus_coils
        log.debug(str(modbus_values))
        return modbus_values

    except Exception, error:
        log.debug('Error connecting to %s' % properties['ip'])
        log.debug(str(error))
Exemplo n.º 19
0
class TcpRtuChannel(BaseChannel):
    def __init__(self, channel_params, devices_file_name, protocol, mqtt_client, network_name):
        BaseChannel.__init__(self, channel_params, devices_file_name, protocol, mqtt_client, network_name)
        # 配置项
        self.server = channel_params.get("server", "")
        self.port = channel_params.get("port", 0)
        self.protocol.set_device_info(self.server, self.port)
        # 通信对象
        self.modbus_client = None

    @staticmethod
    def check_config(channel_params):
        if "server" not in channel_params or "port" not in channel_params:
            return False
        return BaseChannel.check_config(channel_params)

    def run(self):

        # 首先上报设备数据
        for device_id in self.devices_info_dict:
            device_info = self.devices_info_dict[device_id]
            device_msg = {
                "device_id": device_info["device_id"],
                "device_type": device_info["device_type"],
                "device_addr": device_info["device_addr"],
                "device_port": device_info["device_port"],
                "protocol": self.protocol.protocol_type,
                "data": ""
            }
            self.mqtt_client.publish_data(device_msg)

        # 创建连接
        self.modbus_client = ModbusTcpClient(host=self.server, port=self.port)
        try:
            self.modbus_client.connect()
            logger.debug("连接服务器成功.")
        except Exception, e:
            logger.error("连接服务器失败,错误信息:%r." % e)
            self.modbus_client = None
            return

        while True:
            # 该线程保持空转
            time.sleep(5)
Exemplo n.º 20
0
def modbus_poller(id, stop_event, config):
    log = logging.getLogger("worker-" + str(id))
    log.setLevel(logging.DEBUG)

    client = ModbusClient(host=config["address"], port=config["port"])
    client.connect()

    log.info("Worker started")

    t_max = -1

    while not stop_event.is_set():
        log.info("Poller turn")

        t0 = time()

        address = 0
        for i in poll_range(config["num_controls"], config["chunk_size"]):
            result = client.read_input_registers(address=address, count=i, unit=1)
            address += i
            if result is not None:
                if result.function_code >= 0x80 and result.function_code != 132:
                    log.warn("Server returned error!")
                    print result
                    stop_event.set()
                    break
                elif result.function_code == 132:
                    print "Server fault: " + str(result)
                    sleep(1)
                    break

        t = time() - t0
        log.info("Request took " + str(t) + " s")

        if t > t_max:
            t_max = t

        sleep(config["thread"]["interval"])

    log.info("Worker shutting down")
    log.info("Max worker process time: " + str(t_max))
    client.close()
Exemplo n.º 21
0
def main(argv):
    syntax = os.path.basename(__file__) + " -p <first port> -n <number of servers> -i <ip:first port of pump server>"
    tcp_port = 502
    inj_tcp = "localhost:502"
    no_server = 1
    try:
        opts = getopt.getopt(argv, "hp:n:i:", ["port=", "noserver=","injport="])[0]
    except getopt.GetoptError:
        print syntax
        sys.exit(1)
    if len(opts) < 1:
        print syntax
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print syntax
            sys.exit()
        elif opt in ("-i", "--injport"):
            inj_tcp = arg
        elif opt in ("-p", "--port"):
            tcp_port = int(arg)
        elif opt in ("-n", "--noserver"):
            no_server = int(arg)
    port = tcp_port
    context_list = []
    identity_list = []
    address_list = []
    splitted = inj_tcp.split(":")
    ip_pump = splitted[0]
    port_pump = int(splitted[1])
    p_prev_client = None
    for srv in range(no_server):
        p_client = ModbusClient(ip_pump, port=port_pump)
        ret = p_client.connect()
        if ret:
            log.info("connection ok on {0}:{1}".format(ip_pump,port_pump))
            p_client.close()
        else:
            p_client = p_prev_client
            log.info("Keep the previous pump on {0}:{1}".format(ip_pump,port_pump-1))
        port_pump += 1
        address_list.append(("127.0.0.1", port))
        port += 1
        context = context_factory()
        context_list.append(context)
        identity_list.append(identity_factory())
        time = 1 # 1 seconds delay
        loop = LoopingCall(f=updating_writer, a=(context,srv,p_client))
        p_prev_client = p_client
        loop.start(time, now=False) # initially delay by time
    StartMultipleTcpServers(context_list, identity_list, address_list)
Exemplo n.º 22
0
Arquivo: scan.py Projeto: ououcool/ep
def sample(): 
    points=init()
    print 'all points:',points
    map=mapping()
    print 'mapping:',map
    if not points:
        logger.error("there is no valid record in [%s]." %CONFIG_FILE)        
    thread.start_new_thread(mail_notify, (3600*12,))          
    while True: 
        try: 
            # -- connect to the server --
            client = ModbusClient(HOST,port=PORT,framer=ModbusFramer)
            client.connect() 
            print 'connection ok!'
            # -- current time--
            now=time.localtime()
            dt="%s-%s-%s %s:%s:%s" %now[:6]       
            # -- read all points --      
            recordlist=[]  # id,value,time          
            for p in points:
                record=read(client,p) 
                if record:
                    _id= record[0]
                    if map[_id]:  
                        mem=map[_id],record[1],dt  
                        recordlist.append(mem)
            print 'recordlist',recordlist
            # -- insert all recordlist --        
            if recordlist:
                service=UploadService(URL_PREFIX_POST,URL_PREFIX_GET)
                r1=service.insert(recordlist) 
                r2=service.update(recordlist) 
                r3=storage(DB_FILE,recordlist)
                #print r1,r2,r3
                logger.info("OK!")
        except Exception,e:
            logger.error('error:%s' %e)
        finally:
Exemplo n.º 23
0
 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()
Exemplo n.º 24
0
Arquivo: scan.py Projeto: ououcool/ep
def search():
    client = ModbusClient(HOST,port=PORT,framer=ModbusFramer)
    if not client.connect():
        logger.error("cannot connect to [%s:%d]." %(HOST,PORT))     
    n=0
    while n<247:
        rr=client.read_holding_registers(address=0x015e,count=2,unit=n)
        assert(rr.function_code < 0x80) 
        if rr:
            print n
        else:
            print 'fail',n
        n=n+1
    client.close()
            
#search()
Exemplo n.º 25
0
class ControlLink(object):
    def __init__(self, host, port=Defaults.Port):
        self.conn = ModbusTcpClient(host, port)
        if not self.conn.connect():
            raise RuntimeError('Could not connect to host %s port %d' % (host, port))

    def read(self, offset):
        # Adjust offset due to weirdness.
        offset -= 40000

        # Create request.
        assert offset is not None
        assert offset >= 0
        req = ReadInputRegistersRequest(offset, 1)
        assert req is not None

        # Execute and return response.
        res = self.conn.execute(req)
        assert res is not None

        # Extract single value from response.
        values = res.registers
        assert values is not None
        assert len(values) == 1
        return long(values[0])

    def write(self, offset, value):
        # Adjust offset due to weirdness.
        offset -= 40000

        # Create request.
        assert offset is not None
        assert offset >= 0
        assert value is not None
        req = WriteSingleRegisterRequest(offset, value)

        # Execute and return response.
        res = self.conn.execute(req)
        assert res is not None
        assert res.value is not None
        nvalue = res.value
        if nvalue != value:
            report('address %d, wrote %d, returned %d'
                   % (offset, value, nvalue))
        return nvalue
Exemplo n.º 26
0
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
Exemplo n.º 27
0
    def testBasicSyncTcpClient(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._recv(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))
Exemplo n.º 28
0
def read_register(slave_addr, slave_port, reg_addr):
    
   
   # Call modbustcp client to read current 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 None
   
   reply = client.read_holding_registers(address=reg_addr, unit=1)
   client.close()

   if reply == None:
      print "No reply while reading Modbus register"
      return None      
      
   if reply.function_code != 3:
      print "Reading Modbus register returned wrong function code"
      return None
    
   return reply.registers[0]
Exemplo n.º 29
0
class ModbusDevice:
	# ModbusDevice
	# i - IP address
	# p - Modbus port
	# f - framer
	# t - timeout
	#def __init__(self, i, p, f, t):
	def __init__(self, i, p):
		self.ip = i
		self.port = p
		self.framer = ModbusFramer
		self.timeout = 1
		self.rKeys = []
		self.rValues = []
		self.rAddress = []
		self.rIndex = []
		self.errors = []
		self.errFlag = False	# False = no errors, True = we had errors
		# Create the client
		try:
			if(LOG_LEVEL >= LOG_DEBUG):
			  print "modbus client"
			self.client = ModbusClient(self.ip, self.port)
			#self.client = ModbusClient(self.ip, self.port, self.framer, self.timeout)
			#self.client = ModbusClient(self.ip, self.port, timeout=10)
			if(LOG_LEVEL >= LOG_DEBUG):
				print "modbus client connect"
			rc = self.client.connect()
			if(rc == False):
				self.errFlag = True
				self.errors.append(str())
				print "modbus connect returned ", rc
			else:
				if(LOG_LEVEL >= LOG_DEBUG):
					print "modbus connect finished"
		except Exception, e:
			print "modbus device initialization exception ", e
			self.errors.append(str(e))
			self.errFlag = True
Exemplo n.º 30
0
class MainWindow(QMainWindow):
    i = 0

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        # scroll area Widget contents - layout
        self.scrollLayout = QFormLayout()
        self.scrollLayout.setContentsMargins(0, 0, 0, 0)

        # scroll area Widget contents
        self.scrollWidget = QWidget()
        self.scrollWidget.setLayout(self.scrollLayout)

        # scroll area
        self.scrollArea = QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setWidget(self.scrollWidget)

        # main layout
        self.mainLayout = QVBoxLayout()
        self.mainLayout.setSpacing(0)

        # add all main to the main vLayout
        self.mainLayout.addWidget(self.scrollArea)

        # central Widget
        self.centralWidget = QWidget()
        self.centralWidget.setLayout(self.mainLayout)

        # set central Widget
        self.setCentralWidget(self.centralWidget)

        try:
            self._bus = ModbusTcpClient('wechsler.panda.frm2')
            self._bus.connect()
            self._sync()
            print("PLC conforms to spec %.4f" % self.ReadFloat(0))
        except Exception:
            print("Modbus failed, using demo mode!")
            self._bus = None

        self._sync()

        widgets = []
        widgets.append(WriteWord(self, 'last_liftpos', addr=58 / 2))
        widgets.append(ReadWord(self, 'analog1', addr=92 / 2))
        widgets.append(ReadWord(self, 'analog2', addr=96 / 2))
        widgets.append(AnalogInput(self, 'liftpos_analog', addr=146 / 2))
        widgets.append(DiscreteInput(self, 'lift_sw', addr=68 / 2))
        widgets.append(LIFT(self, 'lift', 104 / 2))

        widgets.append(WriteWord(self, 'last_magpos', addr=60 / 2))
        widgets.append(DiscreteInput(self, 'magazin_sw', addr=72 / 2))
        widgets.append(MAGAZIN(self, 'magazin', addr=110 / 2))

        widgets.append(DiscreteInput(self, 'magazin_occ_sw', addr=84 / 2))
        widgets.append(DiscreteInput(self, 'magazin_occ', addr=88 / 2))

        widgets.append(DiscreteInput(self, 'liftclamp_sw', addr=76 / 2))
        widgets.append(CLAMP(self, 'liftclamp', addr=116 / 2))

        widgets.append(DiscreteInput(self, 'magazinclamp_sw', addr=80 / 2))
        widgets.append(CLAMP(self, 'magazinclamp', addr=122 / 2))

        widgets.append(CLAMP(self, 'tableclamp', addr=128 / 2))

        widgets.append(CLAMP(self, 'inhibit_relay', addr=134 / 2))

        widgets.append(WriteWord(self, 'enable_word', addr=150 / 2))

        widgets.append(DiscreteInput(self, 'spare inputs', addr=100 / 2))
        widgets.append(DiscreteOutput(self, 'spare outputs', addr=140 / 2))

        widgets.append(ReadWord(self, 'cycle_counter', addr=152 / 2))

        for w in widgets:
            self.addWidget(w)

        self.widgets = widgets

        self.startTimer(225)  # in ms !

    def ReadWord(self, addr):
        return self._registers[int(addr)]

    def WriteWord(self, addr, value):
        if self._bus:
            self._bus.write_register(int(addr | 0x4000), int(value))
            self._sync()

    def ReadDWord(self, addr):
        return unpack(
            '<I',
            pack('<HH', self._registers[int(addr)],
                 self._registers[int(addr) + 1]))

    def WriteDWord(self, addr, value):
        if self._bus:
            low, high = unpack('<HH', pack('<I', int(value)))
            self._bus.write_registers(int(addr | 0x4000), [low, high])
            self._sync()

    def ReadFloat(self, addr):
        return unpack(
            '<f',
            pack('<HH', self._registers[int(addr) + 1],
                 self._registers[int(addr)]))

    def WriteFloat(self, addr, value):
        if self._bus:
            low, high = unpack('<HH', pack('<f', float(value)))
            self._bus.write_registers(int(addr | 0x4000), [high, low])
            self._sync()

    def _sync(self):
        if self._bus:
            self._registers = self._bus.read_holding_registers(0x4000,
                                                               77).registers[:]
        else:
            self._registers = [self.i + i for i in range(77)]
            self.i += 1

    def timerEvent(self, event):  # pylint: disable=R0915
        self._sync()
        for w in self.widgets:
            w._update()
        return

    def addWidget(self, which):
        which.setContentsMargins(10, 0, 0, 0)
        self.scrollLayout.addRow(which)
        l = QFrame()
        l.setLineWidth(1)
        # l.setMidLineWidth(4)
        l.setFrameShape(QFrame.HLine)
        l.setContentsMargins(10, 0, 10, 0)
        self.scrollLayout.addRow(l)
Exemplo n.º 31
0
def read_modbus_from_tcp_port(conf_file, modbus_registers):

    log.info("Read modbus config from yaml file")
    modbus_conf = read_modbus_conf(conf_file)
    slaveAddr = modbus_conf['slaveaddr'] # ip du slave Modbus
    tcpport = modbus_conf['tcpport'] # port std modbus TCP
    
    log.info("Read modbus registers list from yaml file")
    input_regs = read_modbus_registers(modbus_registers)

    log.info("Build registers list")
    regs_list = build_registers_list(input_regs)

    payload = {}

    #---------------------------------------------------------------------------#
    # instanciating the approriate modbus client
    #---------------------------------------------------------------------------#
    client = ModbusClient(slaveAddr, port=tcpport)
    #client = ModbusClient(method='ascii', port=port, timeout=1)
    #client = ModbusClient(method='rtu', port='/dev/ttyp0', timeout=1)

    log.info("Connecting to Modbus slave")
    connect_ok = client.connect()

    if connect_ok:
        #---------------------------------------------------------------------------#
        # reading all registers and building payload
        #---------------------------------------------------------------------------#
        log.info("Read all input registers in sequence")

        errCnt = 0
        regCnt = 0

        timestamp = str(time.time())

        for reg in regs_list:
            try:    
                rr = client.read_input_registers(reg, 1, unit=1)

                message = {
                    'register_name': input_regs[regCnt]['name'],
                    'register_alias': input_regs[regCnt]['alias'],
                    'register_address': input_regs[regCnt]['address'],
                    'register_value': rr.registers,
                    'timestamp': timestamp
                }

                payload.update({str(regCnt):message})

                regCnt += 1

            except:
                errCnt += 1
                tb = traceback.format_exc()
                log.debug("!pymodbus:\terrCnt: %s; last tb: %s" % (errCnt, tb))
                
            finally:
                # close the client
                client.close()
    else:
        payload = 'Failed to connect to Modbus slave over TCP'
        log.error(payload)

    return payload
Exemplo n.º 32
0
class SolarEdge:

    model = "SolarEdge"
    stopbits = 1
    parity = "N"
    baud = 115200
    wordorder = Endian.Big

    def __init__(
        self, host=False, port=False,
        device=False, stopbits=False, parity=False, baud=False,
        timeout=TIMEOUT, retries=RETRIES, unit=UNIT,
        parent=False
    ):
        if parent:
            self.client = parent.client
            self.mode = parent.mode
            self.timeout = parent.timeout
            self.retries = parent.retries

            if unit:
                self.unit = unit
            else:
                self.unit = parent.unit

            if self.mode is connectionType.RTU:
                self.device = parent.device
                self.stopbits = parent.stopbits
                self.parity = parent.parity
                self.baud = parent.baud
            elif self.mode is connectionType.TCP:
                self.host = parent.host
                self.port = parent.port
            else:
                raise NotImplementedError(self.mode)
        else:
            self.host = host
            self.port = port
            self.device = device

            if stopbits:
                self.stopbits = stopbits

            if (parity
                    and parity.upper() in ["N", "E", "O"]):
                self.parity = parity.upper()
            else:
                self.parity = False

            if baud:
                self.baud = baud

            self.timeout = timeout
            self.retries = retries
            self.unit = unit

            if device:
                self.mode = connectionType.RTU
                self.client = ModbusSerialClient(
                    method="rtu",
                    port=self.device,
                    stopbits=self.stopbits,
                    parity=self.parity,
                    baudrate=self.baud,
                    timeout=self.timeout)
            else:
                self.mode = connectionType.TCP
                self.client = ModbusTcpClient(
                    host=self.host,
                    port=self.port,
                    timeout=self.timeout
                )

    def __repr__(self):
        if self.mode == connectionType.RTU:
            return f"{self.model}({self.device}, {self.mode}: stopbits={self.stopbits}, parity={self.parity}, baud={self.baud}, timeout={self.timeout}, retries={self.retries}, unit={hex(self.unit)})"
        elif self.mode == connectionType.TCP:
            return f"{self.model}({self.host}:{self.port}, {self.mode}: timeout={self.timeout}, retries={self.retries}, unit={hex(self.unit)})"
        else:
            return f"<{self.__class__.__module__}.{self.__class__.__name__} object at {hex(id(self))}>"

    def _read_holding_registers(self, address, length):
        for i in range(self.retries):
            if not self.connected():
                self.connect()
                time.sleep(0.1)
                continue

            result = self.client.read_holding_registers(address, length, unit=self.unit)

            if not isinstance(result, ReadHoldingRegistersResponse):
                continue
            if len(result.registers) != length:
                continue

            return BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big, wordorder=self.wordorder)

        return None

    def _decode_value(self, data, length, dtype, vtype):
        try:
            if dtype == registerDataType.UINT16:
                decoded = data.decode_16bit_uint()
            elif (dtype == registerDataType.UINT32 or
                  dtype == registerDataType.ACC32):
                decoded = data.decode_32bit_uint()
            elif dtype == registerDataType.UINT64:
                decoded = data.decode_64bit_uint()
            elif dtype == registerDataType.INT16:
                decoded = data.decode_16bit_int()
            elif (dtype == registerDataType.FLOAT32 or
                  dtype == registerDataType.SEFLOAT):
                decoded = data.decode_32bit_float()
            elif dtype == registerDataType.STRING:
                decoded = data.decode_string(length * 2).decode(encoding="utf-8", errors="ignore").replace("\x00", "").rstrip()
            else:
                raise NotImplementedError(dtype)

            if decoded == SUNSPEC_NOTIMPLEMENTED[dtype.name]:
                return vtype(False)
            else:
                return vtype(decoded)
        except NotImplementedError:
            raise

    def _read(self, value):
        address, length, rtype, dtype, vtype, label, fmt, batch = value

        try:
            if rtype == registerType.INPUT:
                return self._decode_value(self._read_input_registers(address, length), length, dtype, vtype)
            elif rtype == registerType.HOLDING:
                return self._decode_value(self._read_holding_registers(address, length), length, dtype, vtype)
            else:
                raise NotImplementedError(rtype)
        except NotImplementedError:
            raise
        except AttributeError:
            return False

    def _read_all(self, values, rtype):
        addr_min = False
        addr_max = False

        for k, v in values.items():
            v_addr = v[0]
            v_length = v[1]

            if addr_min is False:
                addr_min = v_addr
            if addr_max is False:
                addr_max = v_addr + v_length

            if v_addr < addr_min:
                addr_min = v_addr
            if (v_addr + v_length) > addr_max:
                addr_max = v_addr + v_length

        results = {}
        offset = addr_min
        length = addr_max - addr_min

        try:
            if rtype == registerType.INPUT:
                data = self._read_input_registers(offset, length)
            elif rtype == registerType.HOLDING:
                data = self._read_holding_registers(offset, length)
            else:
                raise NotImplementedError(rtype)

            if not data:
                return results

            for k, v in values.items():
                address, length, rtype, dtype, vtype, label, fmt, batch = v

                if address > offset:
                    skip_bytes = address - offset
                    offset += skip_bytes
                    data.skip_bytes(skip_bytes * 2)

                results[k] = self._decode_value(data, length, dtype, vtype)
                offset += length
        except NotImplementedError:
            raise

        return results

    def connect(self):
        return self.client.connect()

    def disconnect(self):
        self.client.close()

    def connected(self):
        return self.client.is_socket_open()

    def read(self, key):
        if key not in self.registers:
            raise KeyError(key)

        return {key: self._read(self.registers[key])}

    def read_all(self, rtype=registerType.HOLDING):
        registers = {k: v for k, v in self.registers.items() if (v[2] == rtype)}
        results = {}

        for batch in range(1, len(registers)):
            register_batch = {k: v for k, v in registers.items() if (v[7] == batch)}

            if not register_batch:
                break

            results.update(self._read_all(register_batch, rtype))

        return results
Exemplo n.º 33
0
#!/usr/bin/python
#MTU Server
from config import *
from pymodbus.client.sync import ModbusTcpClient
import time

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.INFO)

field_client = ModbusTcpClient(FIELD_IP, FIELD_PORT)
field_client.connect()
isa_client = ModbusTcpClient(OPC1_IP, OPC1_PORT)
isa_client.connect()

# while 1:
#     now = time.time()
#     print (int(now)/60)%60
#     if (int(now)/60)%60 == 0:
#         print "starting connection"
#         break
print "Simulation will start when the time is 0, 25, 50 ,75"
to = 0
while 1:
    toot = int(time.time()) % 100
    if to == toot - 1:
        print toot
    to = toot
    # print to
    if to == 0 or to == 25 or to == 50 or to == 75:
Exemplo n.º 34
0
class HMIWindow(Gtk.Window):

    def initModbus(self):

        self.modbusClient = ModbusClient(PLANT_IP, port=PLANT_PORT)

    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

        IPText = Gtk.Entry()
        IPText.set_text("%s:%s" % (PLANT_IP, PLANT_PORT))

        IPButton = Gtk.Button("APPLY")
        IPButton.connect("clicked", self.setIPPLC)

        grid.attach(IPText, 0, elementIndex, 1, 1)
        grid.attach(IPButton, 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.IPText = IPText
        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 setIPPLC(self, widget):
        try:
            address,port = self.IPText.get_text().split(":")
            self.modbusClient = ModbusClient(address, port)
        except:
            pass

    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
Exemplo n.º 35
0
class Danbach_AGV():
    def __init__(self,
                 lwheel_scale=1.0,
                 rwheel_scale=1.0,
                 ip='192.168.10.30',
                 port=502,
                 timeout=7e-3):
        self.client = MbClient(ip, port=port, timeout=timeout)
        self.lwheel_scale = lwheel_scale
        self.rwheel_scale = rwheel_scale

    @property
    def connected(self):
        return self.client.is_socket_open()

    def connect(self):
        self.client.connect()
        self.client.write_registers(0x1600, [2, 0x0800, 0, 0])

    def disconnect(self):
        self.client.close()

    def forward(self, distance, speed=DEFAULT_SPEED):
        if distance == 0 or speed == 0:
            return
        l0, r0 = self.__get_wheel_odo__()
        t0 = time.time() - CMD_PERIOD
        while True:
            l, r = self.__get_wheel_odo__()
            if l >= l0 + distance or r >= r0 + distance:
                break
            if time.time() - t0 > CMD_PERIOD:
                t0 = time.time()
                if (distance - l + l0 < GUARD_DIST) or (distance - r + r0 <
                                                        GUARD_DIST):
                    speed = min(speed, GUARD_SPEED)
                self.__set_wheel__(speed, speed)

        self.__set_wheel__(0, 0)

    def back(self, distance, speed=DEFAULT_SPEED):
        if distance == 0 or speed == 0:
            return
        l0, r0 = self.__get_wheel_odo__()
        t0 = time.time() - CMD_PERIOD
        while True:
            l, r = self.__get_wheel_odo__()
            if l < l0 - distance or r < r0 - distance:
                break

            if time.time() - t0 > CMD_PERIOD:
                t0 = time.time()
                if (distance - l0 + l < GUARD_DIST) or (distance - r0 + r <
                                                        GUARD_DIST):
                    speed = min(speed, GUARD_SPEED)
                self.__set_wheel__(-speed, -speed)

        self.__set_wheel__(0, 0)

    def pivot(self, radian, speed=DEFAULT_SPEED):
        if radian == 0 or speed == 0:
            return
        l0, r0 = self.__get_wheel_odo__()
        t0 = time.time() - CMD_PERIOD
        while True:
            l, r = self.__get_wheel_odo__()
            if abs(abs(l - l0 - r + r0)) / WHEEL_DIST >= abs(radian):
                break

            if time.time() - t0 > CMD_PERIOD:
                if abs(radian) - abs(
                        abs(l - l0 - r + r0)) / WHEEL_DIST < GUARD_RADIAN:
                    speed = min(speed, GUARD_SPEED)
                t0 = time.time()
                if radian > 0:
                    self.__set_wheel__(-speed // 2, speed // 2)
                else:
                    self.__set_wheel__(speed // 2, -speed // 2)
        self.__set_wheel__(0, 0)

    def steer(self, radian, direction=1, speed=DEFAULT_SPEED):
        if radian == 0 or speed == 0:
            return
        l0, r0 = self.__get_wheel_odo__()
        t0 = time.time() - CMD_PERIOD
        while True:
            l, r = self.__get_wheel_odo__()
            if abs((l - l0) - (r - r0)) / WHEEL_DIST >= abs(radian):
                print((l - l0 - r + r0) / WHEEL_DIST / pi)
                break

            if time.time() - t0 > CMD_PERIOD:
                if abs(radian) - abs((l - l0) -
                                     (r - r0)) / WHEEL_DIST < GUARD_RADIAN:
                    speed = GUARD_SPEED
                t0 = time.time()
                if radian > 0 and direction == 1:
                    self.__set_wheel__(0, speed)
                elif radian < 0 and direction == 1:
                    self.__set_wheel__(speed, 0)
                elif radian > 0 and direction == -1:
                    self.__set_wheel__(0, -speed)
                else:
                    self.__set_wheel__(-speed, 0)
        self.__set_wheel__(0, 0)

    def turn(self, radian, inner_radius, direction=1, speed=DEFAULT_SPEED):
        self.__set_wheel__(0, 0)

    def __get_wheel_odo__(self):
        while True:
            try:
                rq = self.client.read_holding_registers(0x41E, 4, unit=1)
                L_WHEEL = rq.registers[0] * 0x00010000 + rq.registers[1]
                R_WHEEL = rq.registers[2] * 0x00010000 + rq.registers[3]
            except:
                continue
            break
        # 2's complement on int_32
        L_WHEEL = L_WHEEL - 0x100000000 if (L_WHEEL & 0x80000000) else L_WHEEL
        R_WHEEL = R_WHEEL - 0x100000000 if (R_WHEEL & 0x80000000) else R_WHEEL

        return L_WHEEL * 1e-3 * self.lwheel_scale, R_WHEEL * 1e-3 * self.rwheel_scale

    def __get_wheel_odo_raw__(self):
        while True:
            try:
                rq = self.client.read_holding_registers(0x41E, 4, unit=1)
                L_WHEEL = rq.registers[0] * 0x00010000 + rq.registers[1]
                R_WHEEL = rq.registers[2] * 0x00010000 + rq.registers[3]
            except:
                continue
            break
        # 2's complement on int_32
        L_WHEEL = L_WHEEL - 0x100000000 if (L_WHEEL & 0x80000000) else L_WHEEL
        R_WHEEL = R_WHEEL - 0x100000000 if (R_WHEEL & 0x80000000) else R_WHEEL

        return L_WHEEL, R_WHEEL

    def __set_wheel__(self, lspeed, rspeed):
        if lspeed == 0 and rspeed == 0:
            rq = self.client.write_registers(0x1620, [0x0002, 0, 0, 0, 0],
                                             unit=0x01)

        lspeed = lspeed + 0x10000 if lspeed < 0 else lspeed
        rspeed = rspeed + 0x10000 if rspeed < 0 else rspeed
        rq = self.client.write_registers(0x1620,
                                         [0x0001, lspeed, rspeed, 0, 0],
                                         unit=0x01)

    def __set_wheel__(self, lspeed, rspeed):
        if lspeed == 0 and rspeed == 0:
            rq = self.client.write_registers(0x1620, [0x0002, 0, 0, 0, 0],
                                             unit=0x01)

        lspeed = lspeed + 0x10000 if lspeed < 0 else lspeed
        rspeed = rspeed + 0x10000 if rspeed < 0 else rspeed
        rq = self.client.write_registers(0x1620,
                                         [0x0001, lspeed, rspeed, 0, 0],
                                         unit=0x01)
Exemplo n.º 36
0
def main():

 hosts = [ fds.CHARGE_CONTROLLER_IP ]

 parser = ArgumentParser()

 parser.add_argument('--dummydata', '-d', action='store_true', default=False,
                    dest='use_dummy_data',
                    help='Use dummy data instead of connect to the modbus or mcu.')
 parser.add_argument('--address','-a', action='store', 
                    dest='charge_controller_ip',
                    help='Set the Modbus IP to connect to the Charge Controller')
 parser.add_argument('--cycles', '-c', action='store', default=1,
                    dest='cycles', type=int,
                    help='Set the number of cycles')
 parser.add_argument('--sampling', '-s', action='store', default=2,
                    dest='sampling_rate', type=int,
                    help='Set the delay in seconds between two readings')
 parser.add_argument('--daemon', '-g', action='store_true', default=False,
                    dest='im_a_daemon',
                    help='The script will be a daemon')
 parser.add_argument('--version', action='version', version='%(prog)s  ' + str(__version__))

 results = parser.parse_args() 
 print 'Parsed arguments ========='
 print "Use dummy data" , results.use_dummy_data
 print "CC IP " , results.charge_controller_ip
 print "Cycles " , results.cycles
 print "Sampling rate " , results.sampling_rate
 print "Im a f****n deamon " , results.im_a_daemon
 print '=========================='

 SAMPLING_RATE = results.sampling_rate
 MAX_CYCLES  = results.cycles
 DUMMY_DATA  = results.use_dummy_data
 IM_A_DAEMON = results.im_a_daemon

 if results.charge_controller_ip is not None:
  hosts = [results.charge_controller_ip]

# logging.basicConfig()
# log = logging.getLogger('./modbus.error')
# log.setLevel(logging.ERROR)

 client = None

 # connect to modbus hosts
 if not DUMMY_DATA:
  for host in hosts:
    print "Trying to connect to Modbus IP Host %s ..." % host
    client = ModbusClient(host, fds.MODBUS_PORT)
    client.connect()

 sqlite_file = './data/db_fds_offgridbox-'+ str(datetime.datetime.now().strftime('%Y%m%d-%H:%M:%S')) +'.sqlite'

 if os.path.isfile(fds.SQLITE_FILENAME):
  os.rename(fds.SQLITE_FILENAME, sqlite_file)
  print "File backup in : " + sqlite_file


 # Connecting to the database file
 conn = sqlite3.connect(fds.SQLITE_FILENAME)
 cur = conn.cursor()
 createDBtables( cur )

 i = 0
 counter = 0
 while i < MAX_CYCLES: # circa un giorno a 30 al minuto ... forse un po d i piu
  counter = counter + 1
  sys.stdout.write("Reading Modbus " + str(counter) + ' :: ' )
  chargeControllerData = getChargeControllerData(client)
  sys.stdout.write('.')
  relayBoxData         = getRelayBoxData(client)
  sys.stdout.write('.')
  relayStateData       = readRelayState(client)
  sys.stdout.write('. done! - Reading MCU ')
  mcuData              = getMCUdata(fds.MCU_READ_CMD)
  sys.stdout.write('. done! - Adding element to db ' )
  addDataToDB(conn, chargeControllerData , relayBoxData, relayStateData, mcuData )
  print('! ')
  time.sleep(SAMPLING_RATE)
  if not IM_A_DAEMON:
   i = i + 1
 
 cur.execute('SELECT * FROM charge_controller')
 # print(cur.fetchall())

 conn.commit()
 conn.close()
Exemplo n.º 37
0
class FdsChargeController():
	comunicationType = ""
	serialPort       = ""
	ipAddress        = ""
	modbusClient     = None
	isDebug          = False

	client = None

	def __init__(self,
		communicationType,
		port=DEFAULT_C23_RS485,
		ipAddress=DEFAULT_CHARGE_CONTROLLER_IP,
		isDebug=False):

		self.isDebug = isDebug

		if (communicationType == MODBUS_ETH):
			self.communicationType = communicationType
			self.ipAddress = ipAddress
			logging.debug("FdsChargeController: ETH enabled ")
		elif (communicationType == MODBUS_RTU):
			self.communicationType = communicationType
			self.serialPort = port
			logging.debug("FdsChargeController: RTU enabled ")
		else:
			raise ValueError("Unsupported Modbus Communication Type. Choose MODBUS_RTU or MODBUS_ETH.")


	def connect(self):
		if(self.communicationType == MODBUS_ETH):
			logging.debug("FdsChargeController: connect EHT called")

			if self.isDebug == False:
			    	print("Trying to connect to Modbus IP Host %s ..." % self.ipAddress)
			    	self.client = ModbusClient(self.ipAddress, MODBUS_PORT)
			    	self.client.connect()
		
		elif (self.communicationType == MODBUS_RTU):
                        logging.debug("FdsChargeController: connect RTU called")



	def getChargeControllerData(self):
		data = {'type':'chargecontroller'}

		if self.client != None:
			try:
				# read registers. Start at 0 for convenience
				rr = self.client.read_holding_registers(0,80, unit=CHARGE_CONTROLLER_UNIT)

				# for all indexes, subtract 1 from what's in the manual
				V_PU_hi = rr.registers[0]
				V_PU_lo = rr.registers[1]
				I_PU_hi = rr.registers[2]
				I_PU_lo = rr.registers[3]

				V_PU = float(V_PU_hi) + float(V_PU_lo)
				I_PU = float(I_PU_hi) + float(I_PU_lo)

				v_scale = V_PU * 2**(-15)
				i_scale = I_PU * 2**(-15)
				p_scale = V_PU * I_PU * 2**(-17)

				# battery sense voltage, filtered
				data["battsV"]       = rr.registers[24] * v_scale
				data["battsSensedV"] = rr.registers[26] * v_scale
				data["battsI"]       = rr.registers[28] * i_scale
				data["arrayV"]       = rr.registers[27] * v_scale
				data["arrayI"]       = rr.registers[29] * i_scale
				data["statenum"]     = rr.registers[50]
				data["hsTemp"]       = rr.registers[35]
				data["rtsTemp"]      = rr.registers[36]
				data["outPower"]     = rr.registers[58] * p_scale
				data["inPower"]      = rr.registers[59] * p_scale
				data["minVb_daily"]  = rr.registers[64] * v_scale
				data["maxVb_daily"]  = rr.registers[65] * v_scale
				data["minTb_daily"]  = rr.registers[71]
				data["maxTb_daily"]  = rr.registers[72]
				data["dipswitches"]  = bin(rr.registers[48])[::-1][:-2].zfill(8)
				#led_state            = rr.registers
			except ModbusIOException as e:
				logging.error('Charge Controller: modbusIOException')
				raise e
			except Exception as e:
				logging.error('Charge Controller: unpredicted exception')
				raise e
		else:
			data["battsV"]       = random.uniform(0, 60)
			data["battsSensedV"] = random.uniform(0, 60)
			data["battsI"]       = random.uniform(0, 60)
			data["arrayV"]       = random.uniform(0, 60)
			data["arrayI"]       = random.uniform(0, 60)
			data["statenum"]     = random.randint(1, 10)
			data["hsTemp"]       = random.uniform(0, 60)
			data["rtsTemp"]      = random.uniform(0, 60)
			data["outPower"]     = random.uniform(0, 60)
			data["inPower"]      = random.uniform(0, 60)
			data["minVb_daily"]  = random.uniform(0, 60)
			data["maxVb_daily"]  = random.uniform(0, 60)
			data["minTb_daily"]  = random.uniform(0, 60)
			data["maxTb_daily"]  = random.uniform(0, 60)
			data["dipswitches"]  = bin(0x02)[::-1][:-2].zfill(8)

		return data



	def getRelayBoxData(self):
		data = {'type':'relaybox'}

		if self.client != None:
			try:
				# read registers. Start at 0 for convenience
				rr = self.client.read_holding_registers(0,18, unit=RELAYBOX_UNIT)
				v_scale = float(78.421 * 2**(-15))

				data["adc_vb"]        = rr.registers[0] * v_scale
				data["adc_vch_1"]     = rr.registers[1] * v_scale
				data["adc_vch_2"]     = rr.registers[2] * v_scale
				data["adc_vch_3"]     = rr.registers[3] * v_scale
				data["adc_vch_4"]     = rr.registers[4] * v_scale
				data["t_mod"]         = rr.registers[5]
				data["global_faults"] = rr.registers[6]
				data["global_alarms"] = rr.registers[7]
				data["hourmeter_HI"]  = rr.registers[8]
				data["hourmeter_LO"]  = rr.registers[9]
				data["ch_faults_1"]   = rr.registers[10]
				data["ch_faults_2"]   = rr.registers[11]
				data["ch_faults_3"]   = rr.registers[12]
				data["ch_faults_4"]   = rr.registers[13]
				data["ch_alarms_1"]   = rr.registers[14]
				data["ch_alarms_2"]   = rr.registers[15]
				data["ch_alarms_3"]   = rr.registers[16]
				data["ch_alarms_4"]   = rr.registers[17]
			except ModbusIOException as e:
				logging.error('RelayBoxRead: modbusIOException')
				raise e
			except Exception as e:
				logging.error('RelayBoxRead: unpredicted exception')
				raise e

		else:
			data["adc_vb"]        = random.uniform(0, 60)
			data["adc_vch_1"]     = random.uniform(0, 60)
			data["adc_vch_2"]     = random.uniform(0, 60)
			data["adc_vch_3"]     = random.uniform(0, 60)
			data["adc_vch_4"]     = random.uniform(0, 60)
			data["t_mod"]         = random.uniform(0, 60)
			data["global_faults"] = random.randint(0, 60)
			data["global_alarms"] = random.randint(0, 60)
			data["hourmeter_HI"]  = random.uniform(0, 60)
			data["hourmeter_LO"]  = random.uniform(0, 60)
			data["ch_faults_1"]   = random.randint(0, 60)
			data["ch_faults_2"]   = random.randint(0, 60)
			data["ch_faults_3"]   = random.randint(0, 60)
			data["ch_faults_4"]   = random.randint(0, 60)
			data["ch_alarms_1"]   = random.randint(0, 60)
			data["ch_alarms_2"]   = random.randint(0, 60)
			data["ch_alarms_3"]   = random.randint(0, 60)
			data["ch_alarms_4"]   = random.randint(0, 60)
		return data



	def getRelayBoxState(self):
		data = {'type':'relayState'}
		if self.client != None:
			try:
				rr = self.client.read_coils(0, 8, unit=RELAYBOX_UNIT)
				data["relay_1"]   = rr.bits[0]
				data["relay_2"]   = rr.bits[1]
				data["relay_3"]   = rr.bits[2]
				data["relay_4"]   = rr.bits[3]
				data["relay_5"]   = rr.bits[4]
				data["relay_6"]   = rr.bits[5]
				data["relay_7"]   = rr.bits[6]
				data["relay_8"]   = rr.bits[7]
			except ModbusIOException as e:
				logging.error( 'RelayState: modbusIOException')
				raise e
			except Exception as e:
				logging.error('RelayState: unpredicted exception')
				raise
		else:
			data["relay_1"]   = 0x1
			data["relay_2"]   = 0x1
			data["relay_3"]   = 0x1
			data["relay_4"]   = 0x0
			data["relay_5"]   = 0x0
			data["relay_6"]   = 0x0
			data["relay_7"]   = 0x0
			data["relay_8"]   = 0x0
		return data
Exemplo n.º 38
0
class Modbus_Driver(object):
    def __init__(self, config_file, config_section='modbus', **kwargs):
        # Use a config section if the config file is being shared with other
        # parts of a project. **kwargs can contain a variable amount of
        if (isinstance(config_file,str)):

            with open(config_file) as f:
                modbusConfig = yaml.safe_load(f)
        else:
            modbusConfig = config_file

        modbus_section = config_section

        self.BYTE_ORDER_DICT = {}
        self.WORD_ORDER_DICT = {}
        self.input_register_dict = {}
        self.holding_register_dict = {}
        self.coil_register_dict = {}
        self.discrete_register_dict = {}

        self.input_registers = {}
        self.holding_registers = {}
        self.coil_registers = {}
        self.discrete_registers = {}
        self.MODBUS_TYPE = modbusConfig[modbus_section]['modbus_type']
        # Check to see if unit id is a list, if it is then set flag that it is a
        # list
        self.UNIT_ID = modbusConfig[modbus_section]['UNIT_ID']
        if isinstance(self.UNIT_ID, list):
            self.UNIT_ID_LIST = self.UNIT_ID
            #Set default UNIT_ID as first UNIT_ID in list
            self.UNIT_ID = int(self.UNIT_ID_LIST[0])
        else:
            # Make a unit id list from the non-list definition for compatibility
            # reasons of previous configs. This also eliminates the possibility
            # of error in calling get_data_all_devices() on a config with a non
            # list definition
            self.UNIT_ID_LIST = []
            self.UNIT_ID_LIST.append(self.UNIT_ID)
        # Start logging if enabled in config
        self.LOGGING_FLAG = modbusConfig[modbus_section]['enable_logging']
        if self.LOGGING_FLAG == False:
            #Start client logging for trouble shooting
            logging.basicConfig()
            log = logging.getLogger()
            log.setLevel(logging.ERROR)

        # Start appropriate client based on the type specified in the config
        if self.MODBUS_TYPE == 'serial':
            self.METHOD = modbusConfig[modbus_section]['method']
            self.SERIAL_PORT = modbusConfig[modbus_section]['serial_port']
            self.STOPBITS = modbusConfig[modbus_section]['stopbits']
            self.BYTESIZE = modbusConfig[modbus_section]['bytesize']
            self.PARITY = modbusConfig[modbus_section]['parity']
            self.BAUDRATE = modbusConfig[modbus_section]['baudrate']
        elif self.MODBUS_TYPE == 'tcp':
            self.IP_ADDRESS = modbusConfig[modbus_section]['ip']
            self.PORT = modbusConfig[modbus_section]['port']
        else:
            print("Invalid modbus type")
            exit

        # Set the byte order as big or little endian
        if modbusConfig[modbus_section]['byte_order'] == 'big':
            self.BYTE_ORDER = Endian.Big
            self.BYTE_ORDER_DICT[self.UNIT_ID] = Endian.Big
        elif modbusConfig[modbus_section]['byte_order'] == 'little':
            self.BYTE_ORDER = Endian.Little
            self.BYTE_ORDER_DICT[self.UNIT_ID] = Endian.Little
        else:
            print("invalid byte order") # change to except later
            exit()
        # Set the word order as big or little endian
        if modbusConfig[modbus_section]['word_order'] == 'big':
            self.WORD_ORDER = Endian.Big
            self.WORD_ORDER_DICT[self.UNIT_ID] = Endian.Big

        elif modbusConfig[modbus_section]['word_order'] == 'little':
            self.WORD_ORDER = Endian.Little
            self.WORD_ORDER_DICT[self.UNIT_ID] = Endian.Little
        else:
            print("invalid byte order") # change to except later
            exit()

        # Read in all registers specified in the YAML config
        self.coil_register_dict = modbusConfig[modbus_section]['coil_registers']
        self.discrete_register_dict = modbusConfig[modbus_section]['discrete_registers']
        self.holding_register_dict = modbusConfig[modbus_section]['holding_registers']
        self.input_register_dict = modbusConfig[modbus_section]['input_registers']

        self.coil_registers[self.UNIT_ID] = self.coil_register_dict
        self.discrete_registers[self.UNIT_ID] = self.discrete_register_dict
        self.holding_registers[self.UNIT_ID] = self.holding_register_dict
        self.input_registers[self.UNIT_ID] = self.input_register_dict
        #print(self.holding_registers)

        # Add single device that is either specified in config_section parameter
        # or a single device config file
        for current_device in self.UNIT_ID_LIST:
            self.coil_registers[current_device] = self.coil_register_dict
            self.discrete_registers[current_device] = self.discrete_register_dict
            self.holding_registers[current_device] = self.holding_register_dict
            self.input_registers[current_device] = self.input_register_dict
            # Set the byte order as big or little endian
            if modbusConfig[modbus_section]['byte_order'] == 'big':
                self.BYTE_ORDER_DICT[current_device] = Endian.Big
            elif modbusConfig[modbus_section]['byte_order'] == 'little':
                self.BYTE_ORDER_DICT[current_device] = Endian.Little
            else:
                print("invalid byte order") # change to except later
                exit()
            # Set the word order as big or little endian
            if modbusConfig[modbus_section]['word_order'] == 'big':
                self.WORD_ORDER_DICT[current_device] = Endian.Big
            elif modbusConfig[modbus_section]['word_order'] == 'little':
                self.WORD_ORDER_DICT[current_device] = Endian.Little
            else:
                print("invalid word order") # change to except later
                exit()

        # Apply register offset if specified
        self.OFFSET_REGISTERS = modbusConfig[modbus_section]['OFFSET_REGISTERS']
        for key in self.holding_register_dict:
            self.holding_register_dict[key][0] -= self.OFFSET_REGISTERS

        # Add devices that were specified with **kwargs
        for device_name, modbus_section in kwargs.items():
            # The Device ID is used as the key in a dictionary for all settings
            # that could potentially differ between devices. Since all of the
            # functions already have been updated to take in a UNIT_ID this
            # can be used to retrieve the appropriate setting for the device.

            # TODO Handle case where the config section has a list of the same
            # device.

            current_device = modbusConfig[modbus_section]['UNIT_ID']
            #print(type(current_device))
            # TODO make this a for loop for each ID
            #current_device = current_device[0]
            self.UNIT_ID_LIST.append(int(current_device))

            if modbusConfig[modbus_section]['byte_order'] == 'big':
                self.BYTE_ORDER_DICT[current_device] = Endian.Big
            elif modbusConfig[modbus_section]['byte_order'] == 'little':
                self.BYTE_ORDER_DICT[current_device] = Endian.Little
            # Set the word order as big or little endian
            if modbusConfig[modbus_section]['word_order'] == 'big':
                self.WORD_ORDER_DICT[current_device] = Endian.Big
            elif modbusConfig[modbus_section]['word_order'] == 'little':
                self.WORD_ORDER_DICT[current_device] = Endian.Little
            else:
                print("invalid word order") # change to except later
                exit()
            # Read in all registers specified in the YAML config
            self.coil_register_dict = modbusConfig[modbus_section]['coil_registers']
            self.discrete_register_dict = modbusConfig[modbus_section]['discrete_registers']
            self.holding_register_dict = modbusConfig[modbus_section]['holding_registers']
            self.input_register_dict = modbusConfig[modbus_section]['input_registers']

            self.coil_registers[current_device] = self.coil_register_dict
            self.discrete_registers[current_device] = self.discrete_register_dict
            self.holding_registers[current_device] = self.holding_register_dict
            self.input_registers[current_device] = self.input_register_dict
            #print(self.holding_register_dict)
            '''
            # Read in all registers specified in the YAML config
            self.coil_registers[current_device] = modbusConfig[modbus_section]['coil_registers']
            self.discrete_registers[current_device] = modbusConfig[modbus_section]['discrete_registers']
            self.holding_registers[current_device] = modbusConfig[modbus_section]['holding_registers']
            self.input_register_dict[current_device] = modbusConfig[modbus_section]['input_registers']
            '''

            # Apply register offset if specified
            # TODO fix this for one device as well as multiple
            """
            self.OFFSET_REGISTERS_DICT[current_device] = modbusConfig[modbus_section]['OFFSET_REGISTERS']
            for key in self.holding_register_dict:
                self.holding_register_dict[key][0] -= self.OFFSET_REGISTERS
            """
            #print(self.holding_registers)



    def initialize_modbus(self):
        """
        initalize correct client according to type specified in config:
            'tcp' or 'serial'
        """
        if self.MODBUS_TYPE == 'serial':
            self.client= ModbusSerialClient(
                    method      = self.METHOD,
                    port        = self.SERIAL_PORT,
                    stopbits    = self.STOPBITS,
                    bytesize    = self.BYTESIZE, 
                    parity      = self.PARITY,
                    baudrate    = self.BAUDRATE
                )
            connection = self.client.connect()

        if self.MODBUS_TYPE == 'tcp':
            self.client = ModbusTcpClient(self.IP_ADDRESS,port=self.PORT)
        '''
        rr = self.read_register_raw(0x601,1,247)
        decoder = BinaryPayloadDecoder.fromRegisters(
                rr.registers,
                byteorder=self.BYTE_ORDER,
                wordorder=self.WORD_ORDER)
        output = decoder.decode_16bit_int()
        print(output)
        '''
        #rr = self.read_register_raw(1001,2,7)
        '''decoder = BinaryPayloadDecoder.fromRegisters(
                rr.registers,
                byteorder=self.BYTE_ORDER,
                wordorder=self.WORD_ORDER)
        '''


    def reconnect(self):
        try:
            self.client.close()
        finally:
            self.initialize_modbus()

    def write_single_register(self,register,value, unit=None):
        """
        :param register: address of reigster to write
        :param value: Unsigned short
        :returns: Status of write
        """
        if (unit is None):
            unit = self.UNIT_ID
        response = self.client.write_register(register,value,unit)
        return response

    def write_data(self,register,value):
        response = self.client.write_register(register,value,unit= self.UNIT_ID)
        return response

    def write_register(self,register_name,value, unit=None):
        """
        :param register_name: register key from holding register dictionary
            generated by yaml config
        :param value: value to write to register
        :returns: -- Nothing
        """
        # TODO add the ability to discern which settings will be appropriate for
        # the device that is being written to
        if (unit is None):
            unit = self.UNIT_ID
        '''
        builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER,
            wordorder=self.WORD_ORDER_DICT[unit])
        '''
        builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER_DICT[unit],
            wordorder=self.WORD_ORDER_DICT[unit])
        # This will change depending on the device that is being connected
        # potentially so it has to be correleated to the device ID

        if (self.holding_register_dict[register_name][1] == '8int'):
            builder.add_8bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '8uint'):
            builder.add_8bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '16int'):
            builder.add_16bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '16uint'):
            builder.add_16bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '32int'):
            builder.add_32bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '32uint'):
            builder.add_32bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '32float'):
            builder.add_32bit_float(value)
        elif (self.holding_register_dict[register_name][1] == '64int'):
            builder.add_64bit_int(value)
        elif (self.holding_register_dict[register_name][1] == '64uint'):
            builder.add_64bit_uint(value)
        elif (self.holding_register_dict[register_name][1] == '64float'):
            builder.add_64bit_float(value)
        else:
            print("Bad type")
            exit()
        payload = builder.build()
        self.client.write_registers(self.holding_register_dict[register_name][0],
            payload, skip_encode=True, unit = self.UNIT_ID)

    def write_coil(self,register,value, unit=None):
        """
        :param register_name: register key from holding register dictionary
            generated by yaml config
        :param value: value to write to register
        :returns:
        """
        # TODO mention what type the value needs to be for value
        if (unit is None):
            unit = self.UNIT_ID

        response = self.client.write_coil(register,value,unit)
        return response

    def read_coil(self,register, unit=None):
        """
        :param register: coil register address to read
        :returns: value stored in coil register
        """
        # TODO mention what type the value needs to be for value
        if (unit is None):
            unit = self.UNIT_ID

        rr = self.client.read_coils(register, 1, unit=unit)
        return rr.bits[0]

    def read_discrete(self,register,unit=None):
        """
        :param register: discrete register address to read
        :returns: value stored in coil register
        """
        if (unit is None):
            unit = self.UNIT_ID

        rr = self.client.read_discrete_inputs(register, count=1,unit=unit)
        return rr.bits[0]

    def read_register_raw(self,register,length, unit=None):
        """
        :param register: base holding register address to read
        :param length: amount of registers to read to encompass all of the data necessary
            for the type
        :returns: A deferred response handle
        """
        if (unit is None):
            unit = self.UNIT_ID

        response = self.client.read_holding_registers(register,length,unit=unit)
        return response

    def read_input_raw(self,register,length, unit=None):
        """
        :param register: base input register address to read
        :param length: amount of registers to read to encompass all of the data necessary
            for the type
        :returns: A deferred response handle
        """
        if (unit is None):
            unit = self.UNIT_ID

        response = self.client.read_input_registers(register,length,unit=unit)
        return response

    def decode_register(self,register,type, unit=None):
        #print(unit)
        #print(type(unit))
        """
        :param register: holding register address to retrieve
        :param type: type to interpret the registers retrieved as
        :returns: data in the type specified

        Based on the type provided, this function retrieves the values contained
        in the register address specfied plus the amount necessary to encompass
        the the type. For example, if 32int is specified with an address of 200
        the registers accessed would be 200 and 201.

        The types accepted are listed in the table below along with their length
        |   Type          | Length (registers) |
        | ------------- |:------------------:|
        |        ignore |                  1 |
        |          8int |                  1 |
        |         8uint |                  1 |
        |         16int |                  1 |
        |        16uint |                  1 |
        |         32int |                  2 |
        |        32uint |                  2 |
        |       32float |                  2 |
        |         64int |                  4 |
        |        64uint |                  4 |
        |       64float |                  4 |
        """
        if (unit is None):
            unit = self.UNIT_ID
        #omitting string for now since it requires a specified length
        if type == '8int':
            rr = self.read_register_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_8bit_int()

        elif type == '8uint':
            rr = self.read_register_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_8bit_uint()
        elif type == '16int':
            rr = self.read_register_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_16bit_int()
        elif type == '16uint':
            rr = self.read_register_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_16bit_uint()
        elif type == '32int':
            rr = self.read_register_raw(register,2,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_32bit_int()
        elif type == '32uint':
            rr = self.read_register_raw(register,2,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_32bit_uint()
        elif type == '32float':
            rr = self.read_register_raw(register,2,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_32bit_float()
        elif type == '64int':
            rr = self.read_register_raw(register,4,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_64bit_int()
        elif type == '64uint':
            rr = self.read_register_raw(register,4,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_64bit_uint()
        elif type == 'ignore':
            rr = self.read_register_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.skip_bytes(8)
        elif type == '64float':
            rr = self.read_register_raw(register,4,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_64bit_float()
        else:
            print("Wrong type specified")
            exit()

        return output

    def decode_input_register(self,register,type, unit=None):
        """
        :param register: input register address to retrieve
        :param type: type to interpret the registers retrieved as
        :returns: data in the type specified

        Based on the type provided, this function retrieves the values contained
        in the register address specfied plus the amount necessary to encompass
        the the type. For example, if 32int is specified with an address of 200
        the registers accessed would be 200 and 201.

        The types accepted are listed in the table below along with their length
        |   Type          | Length (registers) |
        | ------------- |:------------------:|
        |        ignore |                  1 |
        |          8int |                  1 |
        |         8uint |                  1 |
        |         16int |                  1 |
        |        16uint |                  1 |
        |         32int |                  2 |
        |        32uint |                  2 |
        |       32float |                  2 |
        |         64int |                  4 |
        |        64uint |                  4 |
        |       64float |                  4 |
        """
        if (unit is None):
            unit = self.UNIT_ID
        #omitting string for now since it requires a specified length
        if type == '8int':
            rr = self.read_input_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_8bit_int()

        elif type == '8uint':
            rr = self.read_input_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit][unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_8bit_uint()
        elif type == '16int':
            rr = self.read_input_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_16bit_int()
        elif type == '16uint':
            rr = self.read_input_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_16bit_uint()
        elif type == '32int':
            rr = self.read_input_raw(register,2,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_32bit_int()
        elif type == '32uint':
            rr = self.read_input_raw(register,2,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_32bit_uint()
        elif type == '32float':
            rr = self.read_input_raw(register,2,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_32bit_float()
        elif type == '64int':
            rr = self.read_input_raw(register,4,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_64bit_int()
        elif type == '64uint':
            rr = self.read_input_raw(register,4,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_64bit_uint()
        elif type == 'ignore':
            rr = self.read_input_raw(register,1,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.skip_bytes(8)
        elif type == '64float':
            rr = self.read_input_raw(register,4,unit)
            decoder = BinaryPayloadDecoder.fromRegisters(
                    rr.registers,
                    byteorder=self.BYTE_ORDER_DICT[unit],
                    wordorder=self.WORD_ORDER_DICT[unit])
            output = decoder.decode_64bit_float()
        else:
            print("Wrong type specified")
            exit()

        return output

    def read_register(self,register_name):
        response = self.decode_register(self.holding_register_dict[register_name][0],
            self.holding_register_dict[register_name][1])
        return response

    def read_input_raw(self,register_name):
        response = self.decode_input_register(self.holding_register_dict[register_name][0],
            self.holding_register_dict[register_name][1])
        return response


    def get_data(self,unit=None):
        """
        :returns: Dictionary containing the value retrieved for each register
        contained in the YAML config file, register names cannot be repeated
        or the register will be overwritten
        """
        output = {}

        if unit is None:
            unit = self.UNIT_ID

        for key in self.coil_registers[unit]:
            output[key] = self.read_coil(self.coil_registers[unit][key][0],unit)

        for key in self.discrete_registers[unit]:
            output[key] = self.read_discrete(self.discrete_registers[unit][key][0],unit)

        for key in self.input_registers[unit]:
            output[key] = self.decode_input_register(self.input_registers[unit][key][0],self.input_registers[unit][key][1],unit)
            
        for key in self.holding_registers[unit]:
            if (len(self.holding_registers[unit][key]) == 3):
                # Check Read/Write Flag
                if (self.holding_registers[unit][key][2].find('R') != -1):
                    output[key] = self.decode_register(self.holding_registers[unit][key][0],self.holding_registers[unit][key][1],unit)
            else:
                # Register list does not contain a Read/Write Flag assume R
                output[key] = self.decode_register(self.holding_registers[unit][key][0],self.holding_registers[unit][key][1],unit)

        return output

    def get_data_all_devices(self):
        reg_data_dict = {}
        cnt = 1
        for dev_id in self.UNIT_ID_LIST:
            new_key = str(dev_id)
            if str(dev_id) in reg_data_dict:
                new_key = new_key + '_' + str(cnt)
                cnt += 1
            reg_data_dict[new_key] = self.get_data(dev_id)
        return reg_data_dict
    def kill_modbus(self):
        """
        Closes connection with Modbus Slave
        """
        self.client.close()
Exemplo n.º 39
0
class ModBus_API:

    def __init__(self, IP_ADDRESS='169.254.167.246'):
        self.MIN_SIGNED = -2147483648
        self.MAX_UNSIGNED = 4294967295
        self.COLOR_CONTROL_IP = IP_ADDRESS
        self.client = None

    def connect_to_ccgx(self):
        try:
            self.client = ModbusClient(self.COLOR_CONTROL_IP, port='502')
            if(self.client.connect()):
                print('Successfully connected to: {0}'.format(
                    self.COLOR_CONTROL_IP))
            else:
                print('Error while connecting to: {0}'.format(
                    self.COLOR_CONTROL_IP))
        except:
            print('Error connecting')

    def read_device_data(self, address, unit, count=1, d_type='int32'):
        received = self.client.read_input_registers(
            address=address, count=count, unit=unit)
        message = BinaryPayloadDecoder.fromRegisters(
            received.registers, Endian.Big)
        if d_type == 'int32':
            interpreted = message.decode_32bit_int()
        elif d_type == 'uint32':
            interpreted = message.decode_32bit_uint()
        elif d_type == 'iunt:64':
            interpreted = message.decode_64bit_uint()
        elif d_type == 'str32':
            interpreted = message.decode_string(32)
        elif d_type == 'int16':
            interpreted = message.decode_16bit_int()
        elif d_type == 'uint16':
            interpreted = message.decode_16bit_uint()
        else:  # if no data type is defined do raw interpretation of the delivered data
            interpreted = message.decode_16bit_uint()
        return interpreted

    def close(self):
        self.client.close()

    def battery_state_map(self, n):
        n = int(n)
        if n == 0:
            return 'idle'
        elif n == 1:
            return 'charging'
        elif n == 2:
            return 'discharging'

    def show_data(self):
	
        data ={
        'Battery voltage' : self.read_device_data(840, 100, d_type='uint16')/10.0,
        'Battery current' : self.read_device_data(841, 100, d_type='int16')/10.0,
        'Battery power' : self.read_device_data(842, 100, d_type='int16'),
        'Battery state of charge' : self.read_device_data(843, 100, d_type='uint16'),
        'Battery state' : self.battery_state_map(self.read_device_data(844, 100, d_type='int16')),
        'AC consumption' : self.read_device_data(817, 100, d_type='int16'),
        'vebus volt' : float(self.read_device_data(15, 246, d_type='uint16'))/10.0,
        'vebus current' : float(self.read_device_data(18, 246, d_type='int16'))/10.0,
	    'Battery Consumed AH': float(self.read_device_data(845, 100, d_type='uint16'))/-10.0
	#'Consumed Amp1': float(self.read_device_data(771, 234, d_type='uint16'))
#	'Consumed Amp2': float(self.read_device_data(265, 245, d_type='uint16'))
        }
        return data
class PythonDiagnosticProgramm():

    #Modbus general
    def modbusConnectionOpen(self, iPAddress=modbus_ip, port=modbus_port):
        self.client = ModbusClient(
            iPAddress,
            port)  # PLC Address and Port; '192.168.000.250' does not work!
        time.sleep(0.1)
        return self.client.connect()

    def modbusConnectionClose(self):
        self.client.close()

#Modbus read

    def modbusReadOut(self, startAddress=0, numberOfAddresses=2):
        floatSolutionArray = []
        # numberOfAddresses should be not too much
        time.sleep(0.1)  # Can be modified: 0.1 becomes instable
        # numberOfAddresses*2 because we read 32bit registers
        result = self.client.read_input_registers(startAddress,
                                                  numberOfAddresses * 2)
        decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                     endian=Endian.Little)
        decodedAsInt = {
            i: decoder.decode_32bit_int()
            for i in range(0, numberOfAddresses)
        }
        #convert the received values in floats
        for m in range(numberOfAddresses):
            floatSolutionArray.append(
                (self._intToFloatPLC(decodedAsInt.get(m))))
        return floatSolutionArray

    def modbusReadOutAxis(self, axis):
        # With 0 there are 31 values to 30
        return self.modbusReadOut(axis * 100, 31)

    def modbusReadOutAll(self):
        # it reads of every Axis the first 31 Registers
        floatSolutionArray = np.zeros((5, 31))
        for axis in range(0, len(floatSolutionArray)):
            floatSolutionArray[axis, :] = self.modbusReadOutAxis(axis)
        # To be sure that it is an Numpy Array
        return np.array(floatSolutionArray)

    def modbusReadOutVariableAxisData(self):
        # Relevant Addressends for the Variable Axis Data Database
        addressend = [9, 10, 11, 12, 20, 21, 30]
        sQLArray = np.zeros([5, 7])
        floatSolutionArray = self.modbusReadOutAll()
        for m in range(len(addressend)):
            sQLArray[:, m] = floatSolutionArray[:, (addressend[m])]
        return sQLArray

#Modbus write

    def modbusWrite(self, address, value):
        toChange = self._IEEE754reverse(value)
        toSend = self._changingTheOrder(toChange)
        builder = BinaryPayloadBuilder(endian=Endian.Little)
        # That is because of difficulies with the PLC
        builder.add_32bit_uint((toSend))
        payload = builder.build()
        #result  = client.write_registers(address, payload, skip_encode=True)
        result = self.client.write_registers(address,
                                             payload,
                                             skip_encode=True)

#SQL
#SQL General

    def sQLConnectionOpen(self, filePath):
        self.connection = sqlite3.connect(filePath)
        self.cursor = self.connection.cursor()

    def sQLConnectionClose(self):
        self.connection.commit()
        self.connection.close()

#SQL Editing Methods

    def sQLCommand(self, sql_command):
        self.cursor.execute(sql_command)
        self.connection.commit()

    def sQLReadingTable(self, tableName="VariableAxisData"):
        self.cursor.execute("SELECT * FROM %s" % tableName)
        stringList = self.cursor.fetchall()
        for i in range(len(stringList)):
            print stringList[i]

    def sQLCreateTableVariableAxisData(self):
        sql_command = """
        CREATE TABLE VariableAxisData ( 
    Axis Int,
    X9 float,
    X10 float,
    X11 float,
    X12 float,
    X20 float,
    X21 float,
    X30 float);"""
        self.cursor.execute(sql_command)

    def sQLOverwriteVariableAxisData(self):
        floatSolutionArray = self.modbusReadOutVariableAxisData()
        for axis in range(len(floatSolutionArray[:, 0])):
            sql_command = """
            DELETE FROM VariableAxisData WHERE Axis=%i;""" % (axis)
            self.cursor.execute(sql_command)
            # Insert the new Values
            sql_command = """
            INSERT INTO VariableAxisData VALUES (%i,%f,%f,%f,%f,%f,%f,%f);""" % (
                axis, floatSolutionArray[axis][0], floatSolutionArray[axis][1],
                floatSolutionArray[axis][2], floatSolutionArray[axis][3],
                floatSolutionArray[axis][4], floatSolutionArray[axis][5],
                floatSolutionArray[axis][6])
            self.cursor.execute(sql_command)
            # Confirm
        self.connection.commit()

# txt
# Private Methodes

    def _intToFloatPLC(self, decodedAsInt):
        # Separate the Bytes; Initial order: byte4 | byte3 | byte2 | byte1
        byte1 = (decodedAsInt) & (0xFF)
        byte2 = (decodedAsInt) >> 8 & (0xFF)
        byte3 = (decodedAsInt) >> 16 & (0xFF)
        byte4 = (decodedAsInt) >> 24 & (0xFF)
        # Combine the Bytes correct; Final order: byte3 | byte4 | byte1 | byte2
        result = (byte3 << (24))
        result = (byte4 << (16)) | result
        result = (byte1 << (8)) | result
        result = (byte2) | result
        # Transform the bitorder in a float
        # Refering to IEEE 754:
        # The 23 lowest significant bits
        mantissa = result & 0x7FFFFF
        # The next 8 bits
        exponent = (result >> (23)) & 0xFF
        # The formula according to IEEE 754:
        _floatSolution = (1 +
                          ((mantissa) /
                           (math.pow(2, 23)))) * math.pow(2, (exponent - 127))
        # The most significant bit defines the sign
        if ((byte3 & 0x80) == 0x80):  #byte3 is the new most significant byte
            _floatSolution = -_floatSolution
        # Underflow case: Exception of IEEE 754
        if (result == 0):
            _floatSolution = 0
        # round the result
        _floatSolution = round(_floatSolution, 4)
        # Print-Function for test issues
        # print "Address, Decoded: ", address, ", " ,floatSolution, bin(result)
        # print axis, m
        # Save the result, it will be overwritten in the next loop
        return _floatSolution

    def _changingTheOrder(self, decodedAsInt):
        # Separate the Bytes; Initial order: byte4 | byte3 | byte2 | byte1
        byte1 = (decodedAsInt) & (0xFF)
        byte2 = (decodedAsInt) >> 8 & (0xFF)
        byte3 = (decodedAsInt) >> 16 & (0xFF)
        byte4 = (decodedAsInt) >> 24 & (0xFF)
        # Combine the Bytes correct; Final order: byte3 | byte4 | byte1 | byte2
        result = (byte3 << (24))
        result = (byte4 << (16)) | result
        result = (byte1 << (8)) | result
        result = (byte2) | result
        return (result)

    def _IEEE754reverse(self, valueIntoVR):
        valueAsInt = np.asarray(abs(valueIntoVR),
                                dtype=np.float32).view(np.int32).item()
        if (valueIntoVR < 0):
            valueAsInt = valueAsInt | 0x80000000
        return (valueAsInt)
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()
def env_modbus2mongodb_next():
    try:
        t = time()

        DBclient = MongoClient('mongodb://192.168.1.10/',
                               username='******',
                               password='******',
                               authSource='admin',
                               serverSelectionTimeoutMS=1000)

        # try:  # 数据库连接测试
        #     # The ismaster command is cheap and does not require auth.
        #     DBclient.admin.command('ismaster')
        # except ConnectionFailure as e:  # Exception
        #     DBclient.close()
        #     log.error(e)
        #     # print("Server not available")
        #     return

        db = DBclient['sensor_management']
        # collection = db['environment']
        collection = db['data_test_1117']

        # data_all = []
        for bus in range(1, 12):
            client = ModbusClient(ads.conn[bus - 1][0],
                                  port=ads.conn[bus - 1][1],
                                  timeout=1,
                                  framer=ModbusFramer)

            is_connected = client.connect()
            if not is_connected:  # modbus连接失败
                data_db = {
                    'name': '{:0>2d}xxxx'.format(bus),
                    'err': 'Modbus Connect Failed',
                    'datetime': datetime.now()
                }
                result = collection.insert_one(data_db)
                client.close()
                sleep(1)
                continue

            for box in range(ads.busBox[bus - 1],
                             ads.busBox[bus]):  # 云盒编号(0开始)
                sleep(1)
                rr = client.read_holding_registers(ads.rgs,
                                                   ads.len_data,
                                                   unit=box + 1)
                if not hasattr(rr, 'registers'):  # 无返回数据
                    data_db = {
                        'name': '{:0>2d}{:0>2d}xx'.format(bus, box + 1),
                        'message': rr.message,
                        'err': 'No Data Return',
                        'datetime': datetime.now()
                    }
                    result = collection.insert_one(data_db)
                    continue
                data_modbus = rr.registers

                for i in range(ads.box_num[box][0]):  # 二合一编号(0开始)
                    pos_two = ads.two_start + ads.two_len * i
                    # print('two', data_modbus[pos_two + ads.pos_name], (box+1) * 256 + i+1)
                    if data_modbus[pos_two + ads.pos_name] == (
                            box + 1) * 256 + ads.two_start + i + 1:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.two_start + i + 1),
                            'two_in_one': {
                                ads.two_type[j]:
                                data_modbus[pos_two + ads.pos_data + j] *
                                ads.two_carry[j]
                                for j in range(2)
                            },
                            'datetime':
                            datetime.now()
                        }
                    else:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.two_start + i + 1),
                            'data':
                            data_modbus,
                            'err':
                            'Unexpected Data Received',
                            'datetime':
                            datetime.now()
                        }
                    result = collection.insert_one(data_db)
                    # data_all.append(data_db)

                for i in range(ads.box_num[box][1]):  # 六合一编号
                    pos_six = ads.six_start * ads.two_len + ads.six_len * i
                    # print('six', data_modbus[pos_six + ads.pos_name], (box+1) * 256 + ads.six_start+i + ads.six_bios+1)
                    if data_modbus[pos_six + ads.pos_name] == (
                            box +
                            1) * 256 + ads.six_start + i + ads.six_bios + 1:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.six_start + i + 1),
                            'six_in_one': {
                                ads.six_type[j]:
                                data_modbus[pos_six + ads.pos_data + j] *
                                ads.six_carry[j]
                                for j in range(6)
                            },
                            'datetime':
                            datetime.now()
                        }
                    else:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.six_start + i + 1),
                            'data':
                            data_modbus,
                            'err':
                            'Unexpected Data Received',
                            'datetime':
                            datetime.now()
                        }
                    result = collection.insert_one(data_db)
                    # data_all.append(data_db)
            client.close()
        # DBclient.close()
    except ConnectionFailure as e:
        log.error(e)
    except Exception as e:
        # log.exception(e)
        # client.close()
        # DBclient.close()
        log.error(e)
        # log.info('Time Consuming: ' + str(time() - t))
        return
    finally:
        DBclient.close()
        log.info('Time Consuming: ' + str(time() - t))
Exemplo n.º 43
0
class ClientEngine():
    def __init__(self, **kwargs):
        self.callback = kwargs.get('callback', None)
        self.svrIp = kwargs.get('svrIp', None)
        self.svrPort = kwargs.get('svrPort', None)
        self.mbFramer = kwargs.get('mbFramer', None)
        self.client = ModbusClient(self.svrIp,
                                   port=self.svrPort,
                                   framer=self.mbFramer,
                                   timeout=1)
        self.stopper = threading.Event()
        self.queue_req = queue.LifoQueue()

    def start(self):
        self.th = threading.Thread(target=self.worker)
        self.th.start()
        self.stopper.clear()
        self.queue_req.join()

    def parse_response(self, resp, response_callback):
        if hasattr(resp, 'function_code'):
            if resp.function_code in [0x01, 0x02, 0x03, 0x04]:
                response_callback(self, resp.registers)
            elif resp.function_code in [0x06, 0x10]:
                response_callback(self)

    def worker(self):
        while not self.stopper.is_set():
            try:
                if self.client.connect():
                    while not self.queue_req.empty():
                        request, args, callback = self.queue_req.get()
                        self.parse_response(request(**args), callback)
                        self.queue_req.task_done()
                        time.sleep(0.1)
                else:
                    self.callback.on_connection_lost(self)
            except:
                print sys.exc_info()

    def _get_request_from_queue(self):
        if not self.queue_req.empty():
            request, args, callback = self.queue_req.get()
            self.parse_response(request(**args), callback)

    def read_reg(self, offset, len, response_callback):
        req = (self.client.read_holding_registers, {
            'address': offset,
            'count': len,
            'unit': 0x01
        }, response_callback)
        self.queue_req.put(req)

    def write_reg(self, reg_no, val, response_callback):
        req = (self.client.write_register, {
            'address': reg_no,
            'value': val,
            'unit': 0x01
        }, response_callback)
        self.queue_req.put(req)

    def stop(self):
        self.client.close()
        self.stopper.set()
        self.th.join()
def env_modbus2mongodb():
    try:
        t = time()
        DBclient = MongoClient('mongodb://192.168.1.10/',
                               username='******',
                               password='******',
                               authSource='admin')
        db = DBclient['sensor_management']
        # collection = db['environment']
        collection = db['data_test_1117']

        # data_all = []
        for bus in range(1, 12):
            client = ModbusClient(ads.conn[bus - 1][0],
                                  port=ads.conn[bus - 1][1],
                                  timeout=1,
                                  framer=ModbusFramer)
            client.connect()

            for box in range(ads.busBox[bus - 1],
                             ads.busBox[bus]):  # 云盒编号(0开始)
                sleep(1)
                rr = client.read_holding_registers(ads.rgs,
                                                   ads.len_data,
                                                   unit=box + 1)
                if not hasattr(rr, 'registers'):
                    data_db = {
                        'name': '{:0>2d}{:0>2d}xx'.format(bus, box + 1),
                        'message': rr.message,
                        'err': 'No Data Return',
                        'datetime': datetime.now()
                    }
                    result = collection.insert_one(data_db)
                    continue
                data_modbus = rr.registers

                for i in range(ads.box_num[box][0]):  # 二合一编号(0开始)
                    pos_two = ads.two_start + ads.two_len * i
                    # print('two', data_modbus[pos_two + ads.pos_name], (box+1) * 256 + i+1)
                    if data_modbus[pos_two + ads.pos_name] == (
                            box + 1) * 256 + ads.two_start + i + 1:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.two_start + i + 1),
                            'two_in_one': {
                                ads.two_type[j]:
                                data_modbus[pos_two + ads.pos_data + j] *
                                ads.two_carry[j]
                                for j in range(2)
                            },
                            'datetime':
                            datetime.now()
                        }
                    else:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.two_start + i + 1),
                            'data':
                            data_modbus,
                            'err':
                            'Unexpected Data Received',
                            'datetime':
                            datetime.now()
                        }
                    result = collection.insert_one(data_db)
                    # data_all.append(data_db)

                for i in range(ads.box_num[box][1]):  # 六合一编号
                    pos_six = ads.six_start * ads.two_len + ads.six_len * i
                    # print('six', data_modbus[pos_six + ads.pos_name], (box+1) * 256 + ads.six_start+i + ads.six_bios+1)
                    if data_modbus[pos_six + ads.pos_name] == (
                            box +
                            1) * 256 + ads.six_start + i + ads.six_bios + 1:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.six_start + i + 1),
                            'six_in_one': {
                                ads.six_type[j]:
                                data_modbus[pos_six + ads.pos_data + j] *
                                ads.six_carry[j]
                                for j in range(6)
                            },
                            'datetime':
                            datetime.now()
                        }
                    else:
                        data_db = {
                            'name':
                            '{:0>2d}{:0>2d}{:0>2d}'.format(
                                bus, box + 1, ads.six_start + i + 1),
                            'data':
                            data_modbus,
                            'err':
                            'Unexpected Data Received',
                            'datetime':
                            datetime.now()
                        }
                    result = collection.insert_one(data_db)
                    # data_all.append(data_db)

                # await asyncio.sleep(1)
            client.close()
        DBclient.close()
        log.info('Time Consuming: ' + str(time() - t))
    except Exception as e:
        # log.exception(e)
        client.close()
        DBclient.close()
        log.error(e)
        log.info('Time Consuming: ' + str(time() - t))
Exemplo n.º 45
0
class KSEM:
    def __init__(self, ip):
        self.client = ModbusTcpClient(ip, port="502")
        self.client.connect()

    def ReadUInt32(self,addr):
        data=self.client.read_holding_registers(addr, 2, unit=71)
        UInt32register = BinaryPayloadDecoder.fromRegisters(data.registers, byteorder=Endian.Big, wordorder=Endian.Big)
        result = UInt32register.decode_32bit_uint()
        return(result)

    def ReadInt32(self,addr):
        data=self.client.read_holding_registers(addr, 2, unit=71)
        Int32register = BinaryPayloadDecoder.fromRegisters(data.registers, byteorder=Endian.Big, wordorder=Endian.Big)
        result = Int32register.decode_32bit_int()
        return(result)

    def ReadUInt64(self,addr):
        data=self.client.read_holding_registers(addr,4,unit=71)
        UInt64register = BinaryPayloadDecoder.fromRegisters(data.registers, byteorder=Endian.Big, wordorder=Endian.Big)
        result = UInt64register.decode_64bit_uint()
        return(result)

    def write(self, filename, value):
        # print(filename + ": " + str(value))
        f = open(filename, 'w')
        f.write(str(value))
        f.close
        
    def run(self):
        voltage1 = self.ReadUInt32(62) * 0.001
        self.write('/var/www/html/openWB/ramdisk/evuv1', voltage1)

        voltage2 = self.ReadUInt32(102) * 0.001
        self.write('/var/www/html/openWB/ramdisk/evuv2', voltage2)

        voltage3 = self.ReadUInt32(142) * 0.001
        self.write('/var/www/html/openWB/ramdisk/evuv3', voltage3)

        bezugkwh = self.ReadUInt64(512) * 0.1 * 0.001
        self.write('/var/www/html/openWB/ramdisk/bezugkwh', bezugkwh)

        bezugw1p = self.ReadUInt32(40) * 0.1
        bezugw1m = self.ReadUInt32(42) * 0.1
        bezugw1 = bezugw1p if bezugw1p >= bezugw1m else -bezugw1m
        self.write('/var/www/html/openWB/ramdisk/bezugw1', bezugw1)

        bezugw2p = self.ReadUInt32(80) * 0.1
        bezugw2m = self.ReadUInt32(82) * 0.1
        bezugw2 = bezugw2p if bezugw2p >= bezugw2m else -bezugw2m
        self.write('/var/www/html/openWB/ramdisk/bezugw2', bezugw2)

        bezugw3p = self.ReadUInt32(120) * 0.1
        bezugw3m = self.ReadUInt32(122) * 0.1
        bezugw3 = bezugw3p if bezugw3p >= bezugw3m else -bezugw3m
        self.write('/var/www/html/openWB/ramdisk/bezugw3', bezugw3)

        bezuga1 = self.ReadUInt32(60) * 0.001
        self.write('/var/www/html/openWB/ramdisk/bezuga1', bezuga1)

        bezuga2 = self.ReadUInt32(100) * 0.001
        self.write('/var/www/html/openWB/ramdisk/bezuga2', bezuga2)

        bezuga3 = self.ReadUInt32(140) * 0.001
        self.write('/var/www/html/openWB/ramdisk/bezuga3', bezuga3)

        wattbezugp = self.ReadUInt32(0) * 0.1
        wattbezugm = self.ReadUInt32(2) * 0.1
        wattbezug = wattbezugp if wattbezugp >= wattbezugm else -wattbezugm
        finalwattbezug = int(wattbezug)
        self.write('/var/www/html/openWB/ramdisk/wattbezug', finalwattbezug)

        einspeisungkwh = self.ReadUInt64(516) * 0.1 * 0.001
        self.write('/var/www/html/openWB/ramdisk/einspeisungkwh', einspeisungkwh)

        evuhz = self.ReadUInt32(26) * 0.001
        self.write('/var/www/html/openWB/ramdisk/evuhz', evuhz)

        evupf1 = self.ReadInt32(64) * 0.001
        self.write('/var/www/html/openWB/ramdisk/evupf1', evupf1)

        evupf2 = self.ReadInt32(104) * 0.001
        self.write('/var/www/html/openWB/ramdisk/evupf2', evupf2)

        evupf3 = self.ReadInt32(144) * 0.001
        self.write('/var/www/html/openWB/ramdisk/evupf3', evupf3)
Exemplo n.º 46
0
    host = '192.168.30.150'
    port = '502'
    client1 = ModbusTcpClient(host, port)

    host2 = '192.168.30.177'
    client2 = ModbusTcpClient(host2, port)

    while True:

        check = ping_reboot()

        ##LS-001
        # host = '192.168.30.150'
        # port = '502'
        # client = ModbusTcpClient(host, port)
        client1.connect()
        reg_data = []
        print 'client connection-------------------- ', client1.connect()
        for i in range(0, a):

            if i in [1, 27, 28, 29, 30]:
                read_holding_register(client1, 'int32', i)

            elif i in [2, 3, 17, 26]:
                read_holding_register(client1, 'int64', i)

            elif i in [31]:
                read_holding_register(client1, 'uint32', i)

            else:
                read_holding_register(client1, 'float32', i)
Exemplo n.º 47
0
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
Exemplo n.º 48
0
#!/usr/bin/python3
from pymodbus.client.sync import ModbusTcpClient
import time
import sys

# Simulation eines PLCs (Siemens S7-1200) der die gewünschten Werte in einer Frequenz von 0,5Hz (2s) setzt
modbus_ip = '10.0.0.42'
register_values = [1, 1234, 56]

client = ModbusTcpClient(modbus_ip)
if not client.connect():
    print("Der Modbus Server läuft nicht.")
    sys.exit(1)

while True:
    client.write_registers(0, register_values)
    print("[PLC]: Setze die Werte {} auf Register 1 bis 3".format(
        register_values))
    time.sleep(2)
Exemplo n.º 49
0
#!/usr/bin/env python

from pymodbus.client.sync import ModbusTcpClient as ModbusClient
from pymodbus.transaction import ModbusRtuFramer

import pymodbus
import serial
from pymodbus.pdu import ModbusRequest

import logging

FORMAT = ('%(asctime)-15s %(threadName)-15s '
          '%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)

import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import json, time
import inspect

client1 = ModbusClient('192.168.1.10', port=502, framer=ModbusRtuFramer)
client1.connect()

# client1.read_holding_registers(A, B , unit=C)
#where A=Address of register(s), B=register number, unit=slave id

rr0 = client1.read_holding_registers(1, 1, unit=1)
print(rr0.registers)
Exemplo n.º 50
0
 def poll(self):
     types = {
         'b': 1,
         'B': 1,
         'h': 1,
         'H': 1,
         'i': 2,
         'I': 2,
         'q': 4,
         'Q': 4,
         'f': 2,
         'd': 4,
         's': 0,
         'c': 1
     }
     measures = {}
     client = ModbusTcpClient(host=self.host,
                              port=self.port,
                              retries=self.retries,
                              backoff=self.backoff,
                              timeout=self.timeout,
                              retry_on_empty=True,
                              retry_on_invalid=True)
     if not client.connect():
         logger.error("Cannot connect to bridge %s" % (self.host))
         return None
     ut = time.time()
     for row in self.mapping:
         (name, descr, unit, datatype, rw, scale, offset, register) = row
         register = int(register)
         scale = float(scale)
         offset = float(offset)
         length = types.get(datatype)
         string = re.match(r'^s(\d*)$', datatype)
         if string:
             length = int(string.group(1)) >> 1
         try:
             endian = Endian.Little
             if length >= 2:
                 endian = Endian.Big
             result = client.read_holding_registers(register - 1,
                                                    length,
                                                    unit=self.slaveid)
         except ConnectionException as e:
             logger.error(
                 "Error reading bridge %s slave %d register %d: %s" %
                 (self.host, self.slaveid, register, str(e)))
             client.close()
             return None
         if type(result) == ExceptionResponse:
             logger.error(
                 "Error reading bridge %s slave %d register %d: %s" %
                 (self.host, self.slaveid, register, result))
             client.close()
             return None
         if result.isError():
             logger.error("Error reading bridge %s slave %d register %d" %
                          (self.host, self.slaveid, register))
             client.close()
             return None
         if datatype in ['h', 'H', 'i', 'I'
                         ] and result.registers[0] == 0x8000:
             continue
         try:
             if string:
                 value = decoder.decode_string(255).decode()
                 measures[name] = value
                 logger.debug(
                     'Modbus bridge: %s slave %s register %s (%s) value: %s'
                     % (self.host, self.slaveid, register, name, value))
                 continue
             decoder = BinaryPayloadDecoder.fromRegisters(
                 result.registers, byteorder=Endian.Big, wordorder=endian)
             if datatype == 'b':
                 value = decoder.decode_8bit_int()
             if datatype == 'B':
                 value = decoder.decode_8bit_uint()
             if datatype == 'h':
                 value = decoder.decode_16bit_int()
             if datatype == 'H':
                 value = decoder.decode_16bit_uint()
             if datatype == 'i':
                 value = decoder.decode_32bit_int()
             if datatype == 'I':
                 value = decoder.decode_32bit_uint()
             if datatype == 'q':
                 value = decoder.decode_64bit_int()
             if datatype == 'Q':
                 value = decoder.decode_64bit_uint()
             if datatype == 'f':
                 value = decoder.decode_32bit_float()
             if datatype == 'd':
                 value = decoder.decode_64bit_float()
         except (AttributeError, ValueError, struct.error):
             logger.error("Error reading bridge %s slave %d register %d" %
                          (self.host, self.slaveid, register))
             client.close()
             return None
         if math.isnan(value):
             continue
         measures[name] = round(value * scale, 8) + offset
         logger.debug(
             'Modbus bridge: %s slave: %s register: %s (%s) value: %s %s' %
             (self.host, self.slaveid, register, name, measures[name],
              unit))
     client.close()
     data = {
         'ts': ut,
         'client_id': self.clientid,
         'device_id': self.deviceid,
         'measures': measures
     }
     print(data)
     return data
Exemplo n.º 51
0
parser.add_argument(
    '--op',
    required=True,
    choices=['r', 'w'],
    help='op type.')
parser.add_argument(
    '--val',
    type=int, help='Wrtite value.')

args = parser.parse_args()


try:
    results = None

    if client.connect() == False:
        print("[ERROR] failed to connect.")
        sys.exit(0)

    if args.op == 'w':
        if args.fun == 'hr':
            rq = client.write_register(args.adr, args.val, unit=args.id)
        elif args.fun == 'co':
            rq = client.write_coil(args.adr, args.val, unit=args.id)
        
        print "Write function return code : " + str(rq.function_code)
    else :
        if args.fun == 'hr':
            rr = client.read_holding_registers(args.adr, args.qty, unit=args.id)
            if rr != None: results = rr.registers
        elif args.fun == 'ri':
Exemplo n.º 52
0
from pymodbus.client.sync import ModbusTcpClient
import timeit

client = ModbusTcpClient('127.0.0.1', 5020)
client.connect()


def write(c):
    c.write_coil(1, False)
    c.read_coils(1, 1)


print timeit.timeit(lambda: write(client), number=100)

#result = client.read_coils(1,1)
#print result.bits[0]
client.close()
Exemplo n.º 53
0
class SDM:

    model = "SDM"
    stopbits = 1
    parity = "N"
    baud = 38400
    registers = {}

    def __init__(
        self, host=False, port=False,
        device=False, stopbits=False, parity=False, baud=False,
        timeout=TIMEOUT, retries=RETRIES, unit=UNIT,
        parent=False
    ):
        if parent:
            self.client = parent.client
            self.mode = parent.mode
            self.timeout = parent.timeout
            self.retries = parent.retries

            if unit:
                self.unit = unit
            else:
                self.unit = parent.unit

            if self.mode is connectionType.RTU:
                self.device = parent.device
                self.stopbits = parent.stopbits
                self.parity = parent.parity
                self.baud = parent.baud
            elif self.mode is connectionType.TCP:
                self.host = parent.host
                self.port = parent.port
            else:
                raise NotImplementedError(self.mode)
        else:
            self.host = host
            self.port = port
            self.device = device

            if stopbits:
                self.stopbits = stopbits

            if (parity
                    and parity.upper() in ["N", "E", "O"]):
                self.parity = parity.upper()
            else:
                self.parity = False

            if baud:
                self.baud = baud

            self.timeout = timeout
            self.retries = retries
            self.unit = unit

            if device:
                self.mode = connectionType.RTU
                self.client = ModbusSerialClient(
                    method="rtu",
                    port=self.device,
                    stopbits=self.stopbits,
                    parity=self.parity,
                    baudrate=self.baud,
                    timeout=self.timeout)
            else:
                self.mode = connectionType.TCP
                self.client = ModbusTcpClient(
                    host=self.host,
                    port=self.port,
                    timeout=self.timeout
                )

    def __repr__(self):
        if self.mode == connectionType.RTU:
            return f"{self.model}({self.device}, {self.mode}: stopbits={self.stopbits}, parity={self.parity}, baud={self.baud}, timeout={self.timeout}, retries={self.retries}, unit={hex(self.unit)})"
        elif self.mode == connectionType.TCP:
            return f"{self.model}({self.host}:{self.port}, {self.mode}: timeout={self.timeout}, retries={self.retries}, unit={hex(self.unit)})"
        else:
            return f"<{self.__class__.__module__}.{self.__class__.__name__} object at {hex(id(self))}>"

    def _read_input_registers(self, address, length):
        for i in range(self.retries):
            if not self.connected():
                self.connect()
                time.sleep(0.1)
                continue

            result = self.client.read_input_registers(address=address, count=length, unit=self.unit)

            if not isinstance(result, ReadInputRegistersResponse):
                continue
            if len(result.registers) != length:
                continue

            return BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big, wordorder=Endian.Big)

        return None

    def _read_holding_registers(self, address, length):
        for i in range(self.retries):
            if not self.connected():
                self.connect()
                time.sleep(0.1)
                continue

            result = self.client.read_holding_registers(address=address, count=length, unit=self.unit)

            if not isinstance(result, ReadHoldingRegistersResponse):
                continue
            if len(result.registers) != length:
                continue

            return BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Big, wordorder=Endian.Big)

        return None

    def _write_holding_register(self, address, value):
        return self.client.write_registers(address=address, values=value, unit=self.unit)

    def _encode_value(self, data, dtype):
        builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big)

        try:
            if dtype == registerDataType.FLOAT32:
                builder.add_32bit_float(data)
            else:
                raise NotImplementedError(dtype)
        except NotImplementedError:
            raise

        return builder.to_registers()

    def _decode_value(self, data, length, dtype, vtype):
        try:
            if dtype == registerDataType.FLOAT32:
                return vtype(data.decode_32bit_float())
            else:
                raise NotImplementedError(dtype)
        except NotImplementedError:
            raise

    def _read(self, value):
        address, length, rtype, dtype, vtype, label, fmt, batch = value

        try:
            if rtype == registerType.INPUT:
                return self._decode_value(self._read_input_registers(address, length), length, dtype, vtype)
            elif rtype == registerType.HOLDING:
                return self._decode_value(self._read_holding_registers(address, length), length, dtype, vtype)
            else:
                raise NotImplementedError(rtype)
        except NotImplementedError:
            raise

    def _read_all(self, values, rtype):
        addr_min = False
        addr_max = False

        for k, v in values.items():
            v_addr = v[0]
            v_length = v[1]

            if addr_min is False:
                addr_min = v_addr
            if addr_max is False:
                addr_max = v_addr + v_length

            if v_addr < addr_min:
                addr_min = v_addr
            if (v_addr + v_length) > addr_max:
                addr_max = v_addr + v_length

        results = {}
        offset = addr_min
        length = addr_max - addr_min

        try:
            if rtype == registerType.INPUT:
                data = self._read_input_registers(offset, length)
            elif rtype == registerType.HOLDING:
                data = self._read_holding_registers(offset, length)
            else:
                raise NotImplementedError(rtype)

            if not data:
                return results

            for k, v in values.items():
                address, length, rtype, dtype, vtype, label, fmt, batch = v

                if address > offset:
                    skip_bytes = address - offset
                    offset += skip_bytes
                    data.skip_bytes(skip_bytes * 2)

                results[k] = self._decode_value(data, length, dtype, vtype)
                offset += length
        except NotImplementedError:
            raise

        return results

    def _write(self, value, data):
        address, length, rtype, dtype, vtype, label, fmt, batch = value

        try:
            if rtype == registerType.HOLDING:
                return self._write_holding_register(address, self._encode_value(data, dtype))
            else:
                raise NotImplementedError(rtype)
        except NotImplementedError:
            raise

    def connect(self):
        return self.client.connect()

    def disconnect(self):
        self.client.close()

    def connected(self):
        return self.client.is_socket_open()

    def read(self, key):
        if key not in self.registers:
            raise KeyError(key)

        return self._read(self.registers[key])

    def write(self, key, data):
        if key not in self.registers:
            raise KeyError(key)

        return self._write(self.registers[key], data)

    def read_all(self, rtype=registerType.INPUT):
        registers = {k: v for k, v in self.registers.items() if (v[2] == rtype)}
        results = {}

        for batch in range(1, len(registers)):
            register_batch = {k: v for k, v in registers.items() if (v[7] == batch)}

            if not register_batch:
                break

            results.update(self._read_all(register_batch, rtype))

        return results
Exemplo n.º 54
0
#!/usr/bin/python
import sys
import os
import time
import getopt
import socket
import ConfigParser
import struct
import binascii
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
ipaddress = str(sys.argv[1])
from pymodbus.client.sync import ModbusTcpClient
client = ModbusTcpClient(ipaddress, port=502)
connection = client.connect()

#grid power
resp = client.read_holding_registers(2600, 1, unit=30)
decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,
                                             byteorder=Endian.Big,
                                             wordorder=Endian.Big)
w1 = str(decoder.decode_16bit_int())
resp = client.read_holding_registers(2601, 1, unit=30)
decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,
                                             byteorder=Endian.Big,
                                             wordorder=Endian.Big)
w2 = str(decoder.decode_16bit_int())
resp = client.read_holding_registers(2602, 1, unit=30)
decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,
                                             byteorder=Endian.Big,
                                             wordorder=Endian.Big)
Exemplo n.º 55
0
class VisualizerApp(Ui_MainWindow):
    def __init__(self, main_window):
        self.setupUi(main_window)

        self.connect_slots()
        self.init_poll_table()
        self.update_poll_table_column_headers()

        self.configure_modbus_client()

        self.connected = False

    def connect_slots(self):
        self.singlePollPushButton.clicked.connect(self.single_poll)
        self.startRegisterSpinBox.valueChanged.connect(
            self.update_poll_table_column_headers)

    def init_poll_table(self):
        """
        Initialize the table with QTableWidgetItem objects that are empty strings.
        """
        num_rows = self.pollTable.rowCount()
        num_cols = self.pollTable.columnCount()

        for j in range(num_cols):
            for i in range(num_rows):
                self.pollTable.setItem(i, j, QTableWidgetItem(""))

    def update_poll_table_column_headers(self):
        self.clear_poll_table()  # Avoids confusion

        start = self.startRegisterSpinBox.value()
        num_cols = self.pollTable.columnCount()
        num_rows = self.pollTable.rowCount()

        for i in range(num_cols):
            self.pollTable.horizontalHeaderItem(i).setText(
                str(start + i * num_rows))

    def clear_poll_table(self):
        num_rows = self.pollTable.rowCount()
        num_cols = self.pollTable.columnCount()

        for j in range(num_cols):
            for i in range(num_rows):
                self.pollTable.item(i, j).setText("")

    def write_poll_table(self, data):
        self.clear_poll_table()
        num_rows = self.pollTable.rowCount()

        cur_col = 0
        for i, datum in enumerate(data):
            self.pollTable.item(i % 10, cur_col).setText(str(datum))
            #self.pollTable.setItem(i % 10, cur_col, QTableWidgetItem(str(datum)))
            if (i + 1) % num_rows == 0:
                cur_col += 1

    def configure_modbus_client(self):
        tcp_mode = self.tcpRadioButton.isChecked()
        rtu_mode = self.rtuRadioButton.isChecked()

        if rtu_mode:
            pass
        elif tcp_mode:
            host = self.tcpHostLineEdit.text()
            port = self.tcpPortLineEdit.text()
            self.client = ModbusTcpClient(host, port)

        self.connected = self.client.connect()

        if not self.connected:
            self.write_console("Could not connect.")

        else:
            self.write_console("Connection Successful.")

    def single_poll(self):
        data = self.poll_modbus_data()
        self.write_poll_table(data)

        if data:
            self.write_console("Poll Successful")

    def poll_modbus_data(self):
        self.configure_modbus_client()

        if not self.connected:
            return []

        start = self.startRegisterSpinBox.value()
        length = self.numberOfRegistersSpinBox.value()
        register_type = self.registerTypeComboBox.currentText()

        if register_type == "Coils":
            rr = self.client.read_coils(start, length)
            data = rr.bits[:length]

        elif register_type == "Discrete Inputs":
            rr = self.client.read_discrete_inputs(start, length)
            data = rr.bits[:length]

        elif register_type == "Input Registers":
            rr = self.client.read_input_registers(start, length)
            data = rr.registers

        elif register_type == "Holding Registers":
            rr = self.client.read_holding_registers(start, length)
            data = rr.registers

        else:
            self.write_console("Unknown Register Type.")
            data = []

        return data

    def write_console(self, msg):
        self.consoleLineEdit.setText(msg)

    def exit(self):
        QApplication.quit()
Exemplo n.º 56
0
async def main():
    if simulation==1:
        
        if ((GOVtotal+27)<(GOVsolicitado)): 
            timeStamp = datetime.now()
            print(timeStamp)
            minutoActual=timeStamp.minute
            if 'minutoPasado' in locals():
                print(minutoActual)
                print(minutoPasado)
                if (minutoActual-minutoPasado >= ventana):
                    print('almacenar')
                    minutoPasado=minutoActual
                else:
                    print('no almacenar')
            else:
                print('inicio almacenar')
                minutoPasado=minutoActual

            flujoTR = flujoPreset + randrange(-3,3)
            GOVcomponente = GOVcomponente + flujoTR*(tiempoMuestreo/60)
            GOVtotal = GOVcomponente
            GSV = GOVtotal * factor
            time.sleep(tiempoMuestreo)

            
            #Esto lo modifiqué con mis variables
            servidor_driver_ucl = {
                "timestamp": listToString(timeStamp),
                "data": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
                "config": {
                    "version": 0.1,
                    "tipo": "driver_ucl_rt",
                },
                "ucl":{
                    "config": {
                        "version": 0.1,
                        "tipo": "ucl",
                        "id_instrumentacion": "23",
                        "nombre": "UCL 01",
                        "producto1": "regular",
                        "producto2": "premium"
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_en_espera": False,
                        "estado_en_uso": True,
                    },
                    "data_orden":{
                        "id_orden_actual": "23",
                        "cantidad_programada": str(GOVsolicitado),
                        "cantidad_componente": str(GOVcomponente),
                        "cantidad_cargada": str(GOVtotal),
                        "cantidad_restante": str(GOVtotal-GOVsolicitado),
                        "cantidad_gsv": str(GSV),
                        "unidad": "l",
                        "producto": producto

                    }
                },

                "mdp":{
                    "config": {
                        "version": 0.1,
                        "tipo": "mdp",
                        "id_instrumentacion": "23",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_en_espera": False,
                        "estado_en_uso": True
                    },
                    "data": {
                        "flujo": formato_flujo(str(flujoTR.registers[0])),
                        "flujoPreset": str(flujoPreset.registers[0]),
                        "unidad": "l/min",
                    }
                },
                "rtd":{
                    "config": {
                        "version": 0.1,
                        "tipo": "rtd",
                        "id_instrumentacion": "26",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_sensando": True
                    },
                    "data": {
                        "temperatura": formato_temperatura(str((temperaturaTRrgl.registers[0]/100)+(temperaturaTRprm.registers[0]/100))),
                        "temperaturaAvg": str(temperaturaAvg.registers[0]),
                        "unidad": "c",
                    }
                },
                "baumanometro":{
                    "config": {
                        "version": 0.1,
                        "tipo": "baumanometro",
                        "id_instrumentacion": "36",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_sensando": True
                    },
                    "data": {
                        "presion": str(presionTR.registers[0]),
                        "presionPreset": str(presionPreset.registers[0]),
                        "unidad": "kPa",
                    }
                },
                "densimetro":{
                    "config": {
                        "version": 0.1,
                        "tipo": "densimetro",
                        "id_instrumentacion": "37",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_sensando": True
                    },
                    "data": {
                        "densidadTR": str(densidadTR.registers[0]),
                        "densidadComponent": str(densidadComponent.registers[0]),
                        "unidad": "Kg m^3",
                    }
                },
                "caudalimetro":{
                    "config": {
                        "version": 0.1,
                        "tipo": "caudalimetro",
                        "id_instrumentacion": "38",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_sensando": True
                    },
                    "data": {
                        "masaTR": str(masaTR.registers[0]),
                        "unidad": "s/u",
                    }
                },
                "bsw":{
                    "config": {
                        "version": 0.1,
                        "tipo": "bsw",
                        "id_instrumentacion": "39",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_sensando": True
                    },
                    "data": {
                        "BSWTR": str(BSWTR.registers[0]),
                        "unidad": "s/u",
                    }
                },
                "gravidad":{
                    "config": {
                        "version": 0.1,
                        "tipo": "gravidad",
                        "id_instrumentacion": "40",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_sensando": True
                    },
                    "data": {
                        "gravidadTR": str(gravidadTR.registers[0]),
                        "unidad": "s/u",
                    }
                },
                "kFactor":{
                    "config": {
                        "version": 0.1,
                        "tipo": "kFactor",
                        "id_instrumentacion": "26",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "online_status": {
                        "estado_sensando": True
                    },
                    "data": {
                        "kFactor": str(kFactor.registers[0]),
                        "unidad": "adimensional",
                    }
                },
                "vcf":{
                    "config": {
                        "version": 0.1,
                        "tipo": "vcf",
                        "id_instrumentacion": "12",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "data": {
                        "estado_abierta": False,
                    }
                },
                # "vcf_descarga": {
                #     "config": {
                #         "version": 0.1,
                #         "tipo": "vcf",
                #         "id_instrumentacion": "12",
                #     },
                #     "servidor": {
                #         "online": True,
                #     },
                #     "data": {
                #         "estado_abierta": True,
                #     }
                # },
                "valvula_de_tanques":[
                    {
                        "config": {
                            "version": 0.1,
                            "tipo": "vcf",
                            "id_instrumentacion": "12",
                            "producto": "regular"
                        },
                        "servidor": {
                            "online": True,
                        },
                        "data": {
                            "estado_abierta": True,
                        }
                    },
                    {
                        "config": {
                            "version": 0.1,
                            "tipo": "vcf",
                            "id": "12",
                            "producto": "premium"
                        },
                        "servidor": {
                            "online": True,
                        },
                        "data": {
                            "estado_abierta": True,
                        }
                    },
                    # {
                    #     "config": {
                    #         "version": 0.1,
                    #         "tipo": "vcf",
                    #         "id": "12",
                    #         "producto": "diesel"
                    #     },
                    #     "servidor": {
                    #         "online": True,
                    #     },
                    #     "data": {
                    #         "estado_abierta": True,
                    #     }
                    # }
                ],
                "permisivo_tierra":{
                    "config": {
                        "version": 0.1,
                        "tipo": "permisivo",
                        "id_instrumentacion": "12",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "data": {
                        "estado_activado": True,
                    }
                },
                "permisivo_sobrellenado":{
                    "config": {
                        "version": 0.1,
                        "tipo": "permisivo",
                        "id_instrumentacion": "12",
                    },
                    "servidor": {
                        "online": True,
                    },
                    "data": {
                        "estado_activado": True,
                    }
                }
            }

            json_txt = json.dumps( servidor_driver_ucl)

            print(json_txt)

            await conn.write_message(json_txt)

            await asyncio.sleep(0.5)
    else:
        try:
            conn = await websocket_connect(url)
            client=ModbusTcpClient('192.168.0.200')
            #client.connect()

            while 1:
                """
                if client.connect():
                    #Fecha y hora
                    timeStamp=client.read_holding_registers(0x0023,12,unit=1)
                    #5.2.1. Preset quantity in whole units
                    GOVsolicitado=client.read_holding_registers(4036,2,unit=1)
                    #5.2.10. Component delivered gross quantity in whole units
                    GOVcomponente=client.read_holding_registers(4372,2,unit=1)
                    #5.2.8. Meter delivered gross quantity in whole units
                    GOVtotal=client.read_holding_registers(4192,2,unit=1)
                    #5.2.11. Component delivered net quantity in whole units
                    GSV=client.read_holding_registers(4564,2,unit=1)
                    #5.2.7. Preset gross flow rate in whole units
                    flujoPreset=client.read_holding_registers(4180,2,unit=1)
                    #5.2.9. Meter gross flow rate in whole units
                    flujoTR=client.read_holding_registers(4312,2,unit=1)
                    #5.2.13. Component batch average pressure in tenths or hundredths
                    presionPreset=client.read_holding_registers(4948,2,unit=1)
                    #5.2.16. Component current pressure in hundredths
                    presionTR=client.read_holding_registers(4948,2,unit=1)
                    #5.2.17. Component current density in tenths
                    densidadTR=client.read_holding_registers(5716,2,unit=1)
                    #5.2.14. Component batch average density/relative density/gravity
                    densidadComponent=client.read_holding_registers(5140,2,unit=1)
                    #5.2.15. Component current temp in hundredths
                    temperaturaTRrgl=client.read_holding_registers(5332,2,unit=1)
                    temperaturaTRprm=client.read_holding_registers(5334,2,unit=1)
                    #5.2.4. Preset batch average temp in tenths or hundredths
                    temperaturaAvg=client.read_holding_registers(4108,2,unit=1)
                    #5.2.22. Component current mass delivered
                    masaTR=client.read_holding_registers(6868,2,unit=1)
                    #5.2.20. Component current BSW hund
                    BSWTR=client.read_holding_registers(6484,2,unit=1)
                    #5.2.22. Component current API gravity tenths
                    gravidadTR=client.read_holding_registers(6676,2,unit=1)
                    #Meter k-factor
                    kFactor=client.read_holding_registers(1770,2,unit=1)

                    if temperaturaTRprm.registers[0]!=0:
                        producto="premium"
                    else:
                        producto="regular"
                else:
                    timeStamp.registers[0]=[0,0]
                    GOVsolicitado.registers[0]=0
                    GOVcomponente.registers[0]=0
                    GOVtotal.registers[0]=0
                    GSV.registers[0]=0
                    flujoPreset.registers[0]=0
                    flujoTR.registers[0]=0
                    presionPreset.registers[0]=0
                    presionTR.registers[0]=0
                    densidadTR.registers[0]=0
                    densidadComponent.registers[0]=0
                    temperaturaTRrgl.registers[0]=0
                    temperaturaTRprm.registers[0]=0
                    temperaturaAvg.registers[0]=0
                    masaTR.registers[0]=0
                    BSWTR.registers[0]=0
                    gravidadTR.registers[0]=0
                    kFactor.registers[0]=0
                    producto="regular"	
                """


                client.connect()
                #Fecha y hora
                timeStamp=client.read_holding_registers(0x0023,12,unit=1)
                #5.2.1. Preset quantity in whole units
                GOVsolicitado=client.read_holding_registers(4036,2,unit=1)
                #5.2.10. Component delivered gross quantity in whole units
                GOVcomponente=client.read_holding_registers(4372,2,unit=1)
                #5.2.8. Meter delivered gross quantity in whole units
                GOVtotal=client.read_holding_registers(4192,2,unit=1)
                #5.2.11. Component delivered net quantity in whole units
                GSV=client.read_holding_registers(4564,2,unit=1)
                #5.2.7. Preset gross flow rate in whole units
                flujoPreset=client.read_holding_registers(4180,2,unit=1)
                #5.2.9. Meter gross flow rate in whole units
                flujoTR=client.read_holding_registers(4312,2,unit=1)
                #5.2.13. Component batch average pressure in tenths or hundredths
                presionPreset=client.read_holding_registers(4948,2,unit=1)
                #5.2.16. Component current pressure in hundredths
                presionTR=client.read_holding_registers(4948,2,unit=1)
                #5.2.17. Component current density in tenths
                densidadTR=client.read_holding_registers(5716,2,unit=1)
                #5.2.14. Component batch average density/relative density/gravity
                densidadComponent=client.read_holding_registers(5140,2,unit=1)
                #5.2.15. Component current temp in hundredths
                temperaturaTRrgl=client.read_holding_registers(5332,2,unit=1)
                temperaturaTRprm=client.read_holding_registers(5334,2,unit=1)
                #5.2.4. Preset batch average temp in tenths or hundredths
                temperaturaAvg=client.read_holding_registers(4108,2,unit=1)
                #5.2.22. Component current mass delivered
                masaTR=client.read_holding_registers(6868,2,unit=1)
                #5.2.20. Component current BSW hund
                BSWTR=client.read_holding_registers(6484,2,unit=1)
                #5.2.22. Component current API gravity tenths
                gravidadTR=client.read_holding_registers(6676,2,unit=1)
                #Meter k-factor
                kFactor=client.read_holding_registers(1770,2,unit=1)

                if temperaturaTRprm.registers[0]!=0:
                    producto="premium"
                else:
                    producto="regular"


                #Esto lo modifiqué con mis variables
                servidor_driver_ucl = {
                    "timestamp": listToString(timeStamp.registers),
                    "data": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
                    "config": {
                        "version": 0.1,
                        "tipo": "driver_ucl_rt",
                    },
                    "ucl":{
                        "config": {
                            "version": 0.1,
                            "tipo": "ucl",
                            "id_instrumentacion": "23",
                            "nombre": "UCL 01",
                            "producto1": "regular",
                            "producto2": "premium"
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_en_espera": False,
                            "estado_en_uso": True,
                        },
                        "data_orden":{
                            "id_orden_actual": "23",
                            "cantidad_programada": str(GOVsolicitado.registers[0]),
                            "cantidad_componente": str(GOVcomponente.registers[0]),
                            "cantidad_cargada": str(GOVtotal.registers[0]),
                            "cantidad_restante": str(GOVtotal.registers[0]-GOVsolicitado.registers[0]),
                            "cantidad_gsv": str(GSV.registers[0]),
                            "unidad": "l",
                            "producto": producto

                        }
                    },

                    "mdp":{
                        "config": {
                            "version": 0.1,
                            "tipo": "mdp",
                            "id_instrumentacion": "23",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_en_espera": False,
                            "estado_en_uso": True
                        },
                        "data": {
                            "flujo": formato_flujo(str(flujoTR.registers[0])),
                            "flujoPreset": str(flujoPreset.registers[0]),
                            "unidad": "l/min",
                        }
                    },
                    "rtd":{
                        "config": {
                            "version": 0.1,
                            "tipo": "rtd",
                            "id_instrumentacion": "26",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_sensando": True
                        },
                        "data": {
                            "temperatura": formato_temperatura(str((temperaturaTRrgl.registers[0]/100)+(temperaturaTRprm.registers[0]/100))),
                            "temperaturaAvg": str(temperaturaAvg.registers[0]),
                            "unidad": "c",
                        }
                    },
                    "baumanometro":{
                        "config": {
                            "version": 0.1,
                            "tipo": "baumanometro",
                            "id_instrumentacion": "36",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_sensando": True
                        },
                        "data": {
                            "presion": str(presionTR.registers[0]),
                            "presionPreset": str(presionPreset.registers[0]),
                            "unidad": "kPa",
                        }
                    },
                    "densimetro":{
                        "config": {
                            "version": 0.1,
                            "tipo": "densimetro",
                            "id_instrumentacion": "37",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_sensando": True
                        },
                        "data": {
                            "densidadTR": str(densidadTR.registers[0]),
                            "densidadComponent": str(densidadComponent.registers[0]),
                            "unidad": "Kg m^3",
                        }
                    },
                    "caudalimetro":{
                        "config": {
                            "version": 0.1,
                            "tipo": "caudalimetro",
                            "id_instrumentacion": "38",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_sensando": True
                        },
                        "data": {
                            "masaTR": str(masaTR.registers[0]),
                            "unidad": "s/u",
                        }
                    },
                    "bsw":{
                        "config": {
                            "version": 0.1,
                            "tipo": "bsw",
                            "id_instrumentacion": "39",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_sensando": True
                        },
                        "data": {
                            "BSWTR": str(BSWTR.registers[0]),
                            "unidad": "s/u",
                        }
                    },
                    "gravidad":{
                        "config": {
                            "version": 0.1,
                            "tipo": "gravidad",
                            "id_instrumentacion": "40",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_sensando": True
                        },
                        "data": {
                            "gravidadTR": str(gravidadTR.registers[0]),
                            "unidad": "s/u",
                        }
                    },
                    "kFactor":{
                        "config": {
                            "version": 0.1,
                            "tipo": "kFactor",
                            "id_instrumentacion": "26",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "online_status": {
                            "estado_sensando": True
                        },
                        "data": {
                            "kFactor": str(kFactor.registers[0]),
                            "unidad": "adimensional",
                        }
                    },
                    "vcf":{
                        "config": {
                            "version": 0.1,
                            "tipo": "vcf",
                            "id_instrumentacion": "12",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "data": {
                            "estado_abierta": False,
                        }
                    },
                    # "vcf_descarga": {
                    #     "config": {
                    #         "version": 0.1,
                    #         "tipo": "vcf",
                    #         "id_instrumentacion": "12",
                    #     },
                    #     "servidor": {
                    #         "online": True,
                    #     },
                    #     "data": {
                    #         "estado_abierta": True,
                    #     }
                    # },
                    "valvula_de_tanques":[
                        {
                            "config": {
                                "version": 0.1,
                                "tipo": "vcf",
                                "id_instrumentacion": "12",
                                "producto": "regular"
                            },
                            "servidor": {
                                "online": True,
                            },
                            "data": {
                                "estado_abierta": True,
                            }
                        },
                        {
                            "config": {
                                "version": 0.1,
                                "tipo": "vcf",
                                "id": "12",
                                "producto": "premium"
                            },
                            "servidor": {
                                "online": True,
                            },
                            "data": {
                                "estado_abierta": True,
                            }
                        },
                        # {
                        #     "config": {
                        #         "version": 0.1,
                        #         "tipo": "vcf",
                        #         "id": "12",
                        #         "producto": "diesel"
                        #     },
                        #     "servidor": {
                        #         "online": True,
                        #     },
                        #     "data": {
                        #         "estado_abierta": True,
                        #     }
                        # }
                    ],
                    "permisivo_tierra":{
                        "config": {
                            "version": 0.1,
                            "tipo": "permisivo",
                            "id_instrumentacion": "12",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "data": {
                            "estado_activado": True,
                        }
                    },
                    "permisivo_sobrellenado":{
                        "config": {
                            "version": 0.1,
                            "tipo": "permisivo",
                            "id_instrumentacion": "12",
                        },
                        "servidor": {
                            "online": True,
                        },
                        "data": {
                            "estado_activado": True,
                        }
                    }
                }

                json_txt = json.dumps( servidor_driver_ucl)

                await conn.write_message(json_txt)

                await asyncio.sleep(0.5)

            client.close()


            
            
        except ConnectionRefusedError:
            print('error: ConnectionRefusedError')
            sys.exit(1)
        except TimeoutError:
            print('error: TimeoutError')
            sys.exit(1)
        print('done')
        sys.exit(0)
Exemplo n.º 57
0
class TPLC:
    def __init__(self):
        super().__init__()

        IP = "192.168.137.62"
        PORT = 502

        self.Client = ModbusTcpClient(IP, port=PORT)
        self.Connected = self.Client.connect()
        print("TPLC connected: " + str(self.Connected))

        self.nRTD = 8
        self.RTD = [0.] * self.nRTD
        self.RTD_setting = [0.] * self.nRTD
        self.nAttribute = [0.] * self.nRTD
        # self.PT80 = 0.
        # self.FlowValve = 0.
        # self.BottomChillerSetpoint = 0.
        # self.BottomChillerTemp = 0.
        # self.BottomChillerState = 0
        # self.BottomChillerPowerReset = 0
        # self.TopChillerSetpoint = 0.
        # self.TopChillerTemp = 0.
        # self.TopChillerState = 0
        # self.CameraChillerSetpoint = 0.
        # self.CameraChillerTemp = 0.
        # self.CameraChillerState = 0
        # self.WaterChillerSetpoint = 0.
        # self.WaterChillerTemp = 0.
        # self.WaterChillerPressure = 0.
        # self.WaterChillerState = 0
        # self.InnerPower = 0.
        # self.OuterClosePower = 0.
        # self.OuterFarPower = 0.
        # self.FreonPower = 0.
        # self.ColdRegionSetpoint = 0.
        # self.HotRegionSetpoint = 0.
        # self.HotRegionP = 0.
        # self.HotRegionI = 0.
        # self.HotRegionD = 0.
        # self.ColdRegionP = 0.
        # self.ColdRegionI = 0.
        # self.ColdRegionD = 0.
        # self.HotRegionPIDState = 0
        # self.ClodRegionPIDState = 0
        # self.Camera0Temp = 0.
        # self.Camera0Humidity = 0.
        # self.Camera0AirTemp = 0.
        # self.Camera1Temp = 0.
        # self.Camera1Humidity = 0.
        # self.Camera1AirTemp = 0.
        # self.Camera2Temp = 0.
        # self.Camera2Humidity = 0.
        # self.Camera2AirTemp = 0.
        # self.Camera3Temp = 0.
        # self.Camera3Humidity = 0.
        # self.Camera3AirTemp = 0.
        # self.WaterFlow = 0.
        # self.WaterTemp = 0.
        # self.WaterConductivityBefore = 0.
        # self.WaterConductivityAfter = 0.
        # self.WaterPressure = 0.
        # self.WaterLevel = 0.
        # self.WaterPrimingPower = 0
        # self.WaterPrimingStatus = 0
        # self.BeetleStatus = 0
        self.LiveCounter = 0
        self.NewData_Display = False
        self.NewData_Database = False

    def __del__(self):
        self.Client.close()

    def ReadAll(self):
        if self.Connected:
            # Reading all the RTDs
            Raw = self.Client.read_holding_registers(38000,
                                                     count=self.nRTD * 2,
                                                     unit=0x01)
            # RTD_setting = self.Client.read_holding_registers(18002, count=1, unit=0x01)
            for i in range(0, self.nRTD):
                self.RTD[i] = round(
                    struct.unpack(
                        "<f",
                        struct.pack("<HH", Raw.getRegister((2 * i) + 1),
                                    Raw.getRegister(2 * i)))[0], 3)
                # print("Updating TPLC", i, "RTD",self.RTD[i])

            Attribute = [0.] * self.nRTD
            for i in range(0, self.nRTD):
                Attribute[i] = self.Client.read_holding_registers(18000 +
                                                                  i * 8,
                                                                  count=1,
                                                                  unit=0x01)
                self.nAttribute[i] = hex(Attribute[i].getRegister(0))
            # print("Attributes", self.nAttribute)

            # PT80 (Cold Vacuum Conduit Pressure)
            # Raw = self.Client.read_holding_registers(0xA0, count = 2, unit = 0x01)
            # self.PT80 = round(struct.unpack("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 7)
            #
            # Flow valve
            #            Raw = self.Client.read_holding_registers(0x, count = 2, unit = 0x01)
            #            self.FlowValve = round(struct.unpack("<f", struct.pack("<HH", Raw.getRegister(1),
            #            Raw.getRegister(0)))[0], 0)

            # Bottom chiller
            # Raw = self.Client.read_holding_registers(0xA8, count = 4, unit = 0x01)
            # self.BottomChillerSetpoint = round(struct.unpack("<f", struct.pack
            # ("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            # self.BottomChillerTemp = round(struct.unpack("<f", struct.pack
            # ("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            # Raw = self.Client.read_coils(0x10, count = 1, unit = 0x01)
            # self.BottomChillerState = Raw.bits[0]
            #            self.BottomChillerPowerReset = Raw.bits[0]

            # Top chiller
            # Raw = self.Client.read_holding_registers(0xB0, count = 4, unit = 0x01)
            # self.TopChillerSetpoint = round(struct.unpack
            # ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            # self.TopChillerTemp = round(struct.unpack
            # ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            # Raw = self.Client.read_coils(0x13, count = 1, unit = 0x01)
            # self.TopChillerState = Raw.bits[0]

            # Camera chiller
            # Raw = self.Client.read_holding_registers(0xBA, count = 4, unit = 0x01)
            # self.CameraChillerSetpoint = round(struct.unpack("<f", struct.pack
            # ("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            # self.CameraChillerTemp = round(struct.unpack("<f", struct.pack
            # ("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            # Raw = self.Client.read_coils(0x15, count = 1, unit = 0x01)
            # self.CameraChillerState = Raw.bits[0]

            # Water chiller
            #             Raw = self.Client.read_holding_registers(0xC4, count = 4, unit = 0x01)
            #             self.WaterChillerSetpoint = round(struct.unpack("<f", struct.pack
            #             ("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            #             self.WaterChillerTemp = round(struct.unpack("<f", struct.pack
            #             ("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #            self.WaterChillerPressure = round(struct.unpack("<f", struct.pack
            #            ("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #             Raw = self.Client.read_coils(0x17, count = 1, unit = 0x01)
            #             self.WaterChillerState = Raw.bits[0]

            # Heaters
            # Raw = self.Client.read_holding_registers(0xC8, count = 8, unit = 0x01)
            # self.InnerPower = round(struct.unpack
            # ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            # self.OuterClosePower = round(struct.unpack("<f", struct.pack
            # ("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 1)
            # self.OuterFarPower = round(struct.unpack("<f", struct.pack
            # ("<HH", Raw.getRegister(5), Raw.getRegister(4)))[0], 1)
            # self.FreonPower = round(struct.unpack("<f", struct.pack
            # ("<HH", Raw.getRegister(7), Raw.getRegister(6)))[0], 1)

            # Hot/cold region
            #             Raw = self.Client.read_holding_registers(0xD0, count = 4, unit = 0x01)
            #             self.ColdRegionSetpoint = round(struct.unpack
            #             ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            #             self.HotRegionSetpoint = round(struct.unpack
            #             ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 1)
            #          self.HotRegionP = round(struct.unpack
            #          ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #            self.HotRegionI = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #            self.HotRegionD = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #            self.ColdRegionP = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #            self.ColdRegionI = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #            self.ColdRegionD = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(3), Raw.getRegister(2)))[0], 2)
            #             Raw = self.Client.read_coils(0x19, count = 1, unit = 0x01)
            #             self.HotRegionPIDState = Raw.bits[0]
            #            self.ClodRegionPIDState = Raw.bits[0]

            # Cameras
            #            Raw = self.Client.read_holding_registers(0x, count = 24, unit = 0x01)
            #            self.Camera0Temp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.Camera0Humidity = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            #            self.Camera0AirTemp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.Camera1Temp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.Camera1Humidity = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            #            self.Camera1AirTemp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.Camera2Temp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.Camera2Humidity = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            #            self.Camera2AirTemp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.Camera3Temp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.Camera3Humidity = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 1)
            #            self.Camera3AirTemp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)

            # Water system
            #            Raw = self.Client.read_holding_registers(0x, count = 12, unit = 0x01)
            #            self.WaterFlow = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.WaterTemp = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.WaterConductivityBefore = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.WaterConductivityAfter = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.WaterPressure = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            self.WaterLevel = round(struct.unpack
            #            ("<f", struct.pack("<HH", Raw.getRegister(1), Raw.getRegister(0)))[0], 2)
            #            Raw = self.Client.read_coils(0x, count = 1, unit = 0x01)
            #            self.WaterPrimingPower = Raw.bits[0]
            #            self.WaterPrimingStatus = Raw.bits[1]
            #            self.BeetleStatus = Raw.bits[2]

            # PLC
            Raw = self.Client.read_holding_registers(0x3E9, count=1, unit=0x01)
            self.LiveCounter = Raw.getRegister(0)

            self.NewData_Display = True
            self.NewData_Database = True

            return 0
        else:
            return 1

    def SaveSetting(self):
        self.WriteBool(0x0, 0, 1)

        return 0  # There is no way to know if it worked... Cross your fingers!

    def SetFlowValve(self, value):

        return self.WriteFloat(0x0, value)

    def SetBottomChillerSetpoint(self, value):

        return self.WriteFloat(0x0, value)

    def SetBottomChillerState(self, State):
        if State == "Off":
            value = 0
        elif State == "On":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def SetBottomChillerPowerReset(self, State):
        if State == "Off":
            value = 0
        elif State == "On":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def SetTopChillerSetpoint(self, value):

        return self.WriteFloat(0x0, value)

    def SetTopChillerState(self, State):
        if State == "Off":
            value = 0
        elif State == "On":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def SetCameraChillerSetpoint(self, value):

        return self.WriteFloat(0x0, value)

    def SetCameraChillerState(self, State):
        if State == "Off":
            value = 0
        elif State == "On":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def SetWaterChillerSetpoint(self, value):

        return self.WriteFloat(0x0, value)

    def SetWaterChillerState(self, State):
        if State == "Off":
            value = 0
        elif State == "On":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def SetInnerPower(self, value):

        return self.WriteFloat(0x0, value)

    def SetOuterClosePower(self, value):

        return self.WriteFloat(0x0, value)

    def SetOuterFarPower(self, value):

        return self.WriteFloat(0x0, value)

    def SetFreonPower(self, value):

        return self.WriteFloat(0x0, value)

    def SetInnerPowerState(self, State):
        if State == "Off":
            self.WriteBool(0x0, 0, 1)
        elif State == "On":
            self.WriteBool(0x0, 0, 1)

        return 0  # There is no way to know if it worked... Cross your fingers!

    def SetOuterClosePowerState(self, State):
        if State == "Off":
            self.WriteBool(0x0, 0, 1)
        elif State == "On":
            self.WriteBool(0x0, 0, 1)

        return 0  # There is no way to know if it worked... Cross your fingers!

    def SetOuterFarPowerState(self, State):
        if State == "Off":
            self.WriteBool(0x0, 0, 1)
        elif State == "On":
            self.WriteBool(0x0, 0, 1)

        return 0  # There is no way to know if it worked... Cross your fingers!

    def SetFreonPowerState(self, State):
        if State == "Off":
            self.WriteBool(0x0, 0, 1)
        elif State == "On":
            self.WriteBool(0x0, 0, 1)

        return 0  # There is no way to know if it worked... Cross your fingers!

    def SetColdRegionSetpoint(self, value):

        return self.WriteFloat(0x0, value)

    def SetHotRegionSetpoint(self, value):

        return self.WriteFloat(0x0, value)

    def SetHotRegionP(self, value):

        return self.WriteFloat(0x0, value)

    def SetHotRegionI(self, value):

        return self.WriteFloat(0x0, value)

    def SetHotRegionD(self, value):

        return self.WriteFloat(0x0, value)

    def SetColdRegionP(self, value):

        return self.WriteFloat(0x0, value)

    def SetColdRegionI(self, value):

        return self.WriteFloat(0x0, value)

    def SetColdRegionD(self, value):

        return self.WriteFloat(0x0, value)

    def SetHotRegionPIDMode(self, Mode):
        if Mode == "Manual":
            value = 0
        elif Mode == "Auto":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def SetColdRegionPIDMode(self, Mode):
        if Mode == "Manual":
            value = 0
        elif Mode == "Auto":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def SetWaterPrimingPower(self, State):
        if State == "Off":
            value = 0
        elif State == "On":
            value = 1
        else:
            print("State is either on or off in string format.")
            value = None

        return self.WriteBool(0x0, 0, value)

    def WriteFloat(self, Address, value):
        if self.Connected:
            value = round(value, 3)
            Dummy = self.Client.write_register(Address,
                                               struct.unpack(
                                                   "<HH",
                                                   struct.pack("<f",
                                                               value))[1],
                                               unit=0x01)
            Dummy = self.Client.write_register(Address + 1,
                                               struct.unpack(
                                                   "<HH",
                                                   struct.pack("<f",
                                                               value))[0],
                                               unit=0x01)

            time.sleep(1)

            Raw = self.Client.read_holding_registers(Address,
                                                     count=2,
                                                     unit=0x01)
            rvalue = round(
                struct.unpack(
                    "<f",
                    struct.pack("<HH", Raw.getRegister(1),
                                Raw.getRegister(0)))[0], 3)

            if value == rvalue:
                return 0
            else:
                return 2
        else:
            return 1

    def WriteBool(self, Address, Bit, value):
        if self.Connected:
            Raw = self.Client.read_coils(Address, count=Bit, unit=0x01)
            Raw.bits[Bit] = value
            Dummy = self.Client.write_coil(Address, Raw, unit=0x01)

            time.sleep(1)

            Raw = self.Client.read_coils(Address, count=Bit, unit=0x01)
            rvalue = Raw.bits[Bit]

            if value == rvalue:
                return 0
            else:
                return 2
        else:
            return 1
Exemplo n.º 58
0
class SolaredgeModbusHub:
    """Thread safe wrapper class for pymodbus."""

    def __init__(
        self,
        hass,
        name,
        host,
        port,
        scan_interval,
        read_meter1=False,
        read_meter2=False,
        read_meter3=False,
    ):
        """Initialize the Modbus hub."""
        self._hass = hass
        self._client = ModbusTcpClient(host=host, port=port)
        self._lock = threading.Lock()
        self._name = name
        self.read_meter1 = read_meter1
        self.read_meter2 = read_meter2
        self.read_meter3 = read_meter3
        self._scan_interval = timedelta(seconds=scan_interval)
        self._unsub_interval_method = None
        self._sensors = []
        self.data = {}

    @callback
    def async_add_solaredge_sensor(self, update_callback):
        """Listen for data updates."""
        # This is the first sensor, set up interval.
        if not self._sensors:
            self.connect()
            self._unsub_interval_method = async_track_time_interval(
                self._hass, self.async_refresh_modbus_data, self._scan_interval
            )

        self._sensors.append(update_callback)

    @callback
    def async_remove_solaredge_sensor(self, update_callback):
        """Remove data update."""
        self._sensors.remove(update_callback)

        if not self._sensors:
            """stop the interval timer upon removal of last sensor"""
            self._unsub_interval_method()
            self._unsub_interval_method = None
            self.close()

    async def async_refresh_modbus_data(self, _now: Optional[int] = None) -> None:
        """Time to update."""
        if not self._sensors:
            return

        update_result = self.read_modbus_data()

        if update_result:
            for update_callback in self._sensors:
                update_callback()

    @property
    def name(self):
        """Return the name of this hub."""
        return self._name

    def close(self):
        """Disconnect client."""
        with self._lock:
            self._client.close()

    def connect(self):
        """Connect client."""
        with self._lock:
            self._client.connect()

    def read_holding_registers(self, unit, address, count):
        """Read holding registers."""
        with self._lock:
            kwargs = {"unit": unit} if unit else {}
            return self._client.read_holding_registers(address, count, **kwargs)

    def calculate_value(self, value, sf):
        return value * 10 ** sf

    def read_modbus_data_stub(self):
        return (
            self.read_modbus_data_inverter_stub()
            and self.read_modbus_data_meter1_stub()
            and self.read_modbus_data_meter2_stub()
            and self.read_modbus_data_meter3_stub()
        )

    def read_modbus_data(self):
        return (
            self.read_modbus_data_inverter()
            and self.read_modbus_data_meter1()
            and self.read_modbus_data_meter2()
            and self.read_modbus_data_meter3()
        )

    def read_modbus_data_inverter_stub(self):
        self.data["accurrent"] = 1
        self.data["accurrenta"] = 1
        self.data["accurrentb"] = 1
        self.data["accurrentc"] = 1
        self.data["acvoltageab"] = 1
        self.data["acvoltagebc"] = 1
        self.data["acvoltageca"] = 1
        self.data["acvoltagean"] = 1
        self.data["acvoltagebn"] = 1
        self.data["acvoltagecn"] = 1
        self.data["acpower"] = 1
        self.data["acfreq"] = 1
        self.data["acva"] = 1
        self.data["acvar"] = 1
        self.data["acpf"] = 1
        self.data["acenergy"] = 1
        self.data["dccurrent"] = 1
        self.data["dcvoltage"] = 1
        self.data["dcpower"] = 1
        self.data["tempsink"] = 1
        self.data["status"] = 1
        self.data["statusvendor"] = 1

        return True

    def read_modbus_data_meter1_stub(self):
        return self.read_modbus_data_meter_stub("m1_")

    def read_modbus_data_meter2_stub(self):
        return self.read_modbus_data_meter_stub("m2_")

    def read_modbus_data_meter3_stub(self):
        return self.read_modbus_data_meter_stub("m3_")

    def read_modbus_data_meter_stub(self, meter_prefix):
        self.data[meter_prefix + "accurrent"] = 2
        self.data[meter_prefix + "accurrenta"] = 2
        self.data[meter_prefix + "accurrentb"] = 2
        self.data[meter_prefix + "accurrentc"] = 2

        self.data[meter_prefix + "acvoltageln"] = 2
        self.data[meter_prefix + "acvoltagean"] = 2
        self.data[meter_prefix + "acvoltagebn"] = 2
        self.data[meter_prefix + "acvoltagecn"] = 2
        self.data[meter_prefix + "acvoltagell"] = 2
        self.data[meter_prefix + "acvoltageab"] = 2
        self.data[meter_prefix + "acvoltagebc"] = 2
        self.data[meter_prefix + "acvoltageca"] = 2

        self.data[meter_prefix + "acfreq"] = 2

        self.data[meter_prefix + "acpower"] = 2
        self.data[meter_prefix + "acpowera"] = 2
        self.data[meter_prefix + "acpowerb"] = 2
        self.data[meter_prefix + "acpowerc"] = 2

        self.data[meter_prefix + "acva"] = 2
        self.data[meter_prefix + "acvaa"] = 2
        self.data[meter_prefix + "acvab"] = 2
        self.data[meter_prefix + "acvac"] = 2

        self.data[meter_prefix + "acvar"] = 2
        self.data[meter_prefix + "acvara"] = 2
        self.data[meter_prefix + "acvarb"] = 2
        self.data[meter_prefix + "acvarc"] = 2

        self.data[meter_prefix + "acpf"] = 2
        self.data[meter_prefix + "acpfa"] = 2
        self.data[meter_prefix + "acpfb"] = 2
        self.data[meter_prefix + "acpfc"] = 2

        self.data[meter_prefix + "exported"] = 2
        self.data[meter_prefix + "exporteda"] = 2
        self.data[meter_prefix + "exportedb"] = 2
        self.data[meter_prefix + "exportedc"] = 2

        self.data[meter_prefix + "imported"] = 2
        self.data[meter_prefix + "importeda"] = 2
        self.data[meter_prefix + "importedb"] = 2
        self.data[meter_prefix + "importedc"] = 2

        self.data[meter_prefix + "exportedva"] = 2
        self.data[meter_prefix + "exportedvaa"] = 2
        self.data[meter_prefix + "exportedvab"] = 2
        self.data[meter_prefix + "exportedvac"] = 2

        self.data[meter_prefix + "importedva"] = 2
        self.data[meter_prefix + "importedvaa"] = 2
        self.data[meter_prefix + "importedvab"] = 2
        self.data[meter_prefix + "importedvac"] = 2

        self.data[meter_prefix + "importvarhq1"] = 2
        self.data[meter_prefix + "importvarhq1a"] = 2
        self.data[meter_prefix + "importvarhq1b"] = 2
        self.data[meter_prefix + "importvarhq1c"] = 2

        self.data[meter_prefix + "importvarhq2"] = 2
        self.data[meter_prefix + "importvarhq2a"] = 2
        self.data[meter_prefix + "importvarhq2b"] = 2
        self.data[meter_prefix + "importvarhq2c"] = 2

        self.data[meter_prefix + "importvarhq3"] = 2
        self.data[meter_prefix + "importvarhq3a"] = 2
        self.data[meter_prefix + "importvarhq3b"] = 2
        self.data[meter_prefix + "importvarhq3c"] = 2

        self.data[meter_prefix + "importvarhq4"] = 2
        self.data[meter_prefix + "importvarhq4a"] = 2
        self.data[meter_prefix + "importvarhq4b"] = 2
        self.data[meter_prefix + "importvarhq4c"] = 2

        return True

    def read_modbus_data_meter1(self):
        if not self.read_meter1:
            return True
        else:
            return self.read_modbus_data_meter("m1_", 40190)

    def read_modbus_data_meter2(self):
        if not self.read_meter2:
            return True
        else:
            return self.read_modbus_data_meter("m2_", 40364)

    def read_modbus_data_meter3(self):
        if not self.read_meter3:
            return True
        else:
            return self.read_modbus_data_meter("m3_", 40539)

    def read_modbus_data_meter(self, meter_prefix, start_address):
        """start reading meter  data """
        meter_data = self.read_holding_registers(
            unit=1, address=start_address, count=103
        )
        if not meter_data.isError():
            decoder = BinaryPayloadDecoder.fromRegisters(
                meter_data.registers, byteorder=Endian.Big
            )
            accurrent = decoder.decode_16bit_int()
            accurrenta = decoder.decode_16bit_int()
            accurrentb = decoder.decode_16bit_int()
            accurrentc = decoder.decode_16bit_int()
            accurrentsf = decoder.decode_16bit_int()

            accurrent = self.calculate_value(accurrent, accurrentsf)
            accurrenta = self.calculate_value(accurrenta, accurrentsf)
            accurrentb = self.calculate_value(accurrentb, accurrentsf)
            accurrentc = self.calculate_value(accurrentc, accurrentsf)

            self.data[meter_prefix + "accurrent"] = round(accurrent, abs(accurrentsf))
            self.data[meter_prefix + "accurrenta"] = round(accurrenta, abs(accurrentsf))
            self.data[meter_prefix + "accurrentb"] = round(accurrentb, abs(accurrentsf))
            self.data[meter_prefix + "accurrentc"] = round(accurrentc, abs(accurrentsf))

            acvoltageln = decoder.decode_16bit_int()
            acvoltagean = decoder.decode_16bit_int()
            acvoltagebn = decoder.decode_16bit_int()
            acvoltagecn = decoder.decode_16bit_int()
            acvoltagell = decoder.decode_16bit_int()
            acvoltageab = decoder.decode_16bit_int()
            acvoltagebc = decoder.decode_16bit_int()
            acvoltageca = decoder.decode_16bit_int()
            acvoltagesf = decoder.decode_16bit_int()

            acvoltageln = self.calculate_value(acvoltageln, acvoltagesf)
            acvoltagean = self.calculate_value(acvoltagean, acvoltagesf)
            acvoltagebn = self.calculate_value(acvoltagebn, acvoltagesf)
            acvoltagecn = self.calculate_value(acvoltagecn, acvoltagesf)
            acvoltagell = self.calculate_value(acvoltagell, acvoltagesf)
            acvoltageab = self.calculate_value(acvoltageab, acvoltagesf)
            acvoltagebc = self.calculate_value(acvoltagebc, acvoltagesf)
            acvoltageca = self.calculate_value(acvoltageca, acvoltagesf)

            self.data[meter_prefix + "acvoltageln"] = round(
                acvoltageln, abs(acvoltagesf)
            )
            self.data[meter_prefix + "acvoltagean"] = round(
                acvoltagean, abs(acvoltagesf)
            )
            self.data[meter_prefix + "acvoltagebn"] = round(
                acvoltagebn, abs(acvoltagesf)
            )
            self.data[meter_prefix + "acvoltagecn"] = round(
                acvoltagecn, abs(acvoltagesf)
            )
            self.data[meter_prefix + "acvoltagell"] = round(
                acvoltagell, abs(acvoltagesf)
            )
            self.data[meter_prefix + "acvoltageab"] = round(
                acvoltageab, abs(acvoltagesf)
            )
            self.data[meter_prefix + "acvoltagebc"] = round(
                acvoltagebc, abs(acvoltagesf)
            )
            self.data[meter_prefix + "acvoltageca"] = round(
                acvoltageca, abs(acvoltagesf)
            )

            acfreq = decoder.decode_16bit_int()
            acfreqsf = decoder.decode_16bit_int()

            acfreq = self.calculate_value(acfreq, acfreqsf)

            self.data[meter_prefix + "acfreq"] = round(acfreq, abs(acfreqsf))

            acpower = decoder.decode_16bit_int()
            acpowera = decoder.decode_16bit_int()
            acpowerb = decoder.decode_16bit_int()
            acpowerc = decoder.decode_16bit_int()
            acpowersf = decoder.decode_16bit_int()

            acpower = self.calculate_value(acpower, acpowersf)
            acpowera = self.calculate_value(acpowera, acpowersf)
            acpowerb = self.calculate_value(acpowerb, acpowersf)
            acpowerc = self.calculate_value(acpowerc, acpowersf)

            self.data[meter_prefix + "acpower"] = round(acpower, abs(acpowersf))
            self.data[meter_prefix + "acpowera"] = round(acpowera, abs(acpowersf))
            self.data[meter_prefix + "acpowerb"] = round(acpowerb, abs(acpowersf))
            self.data[meter_prefix + "acpowerc"] = round(acpowerc, abs(acpowersf))

            acva = decoder.decode_16bit_int()
            acvaa = decoder.decode_16bit_int()
            acvab = decoder.decode_16bit_int()
            acvac = decoder.decode_16bit_int()
            acvasf = decoder.decode_16bit_int()

            acva = self.calculate_value(acva, acvasf)
            acvaa = self.calculate_value(acvaa, acvasf)
            acvab = self.calculate_value(acvab, acvasf)
            acvac = self.calculate_value(acvac, acvasf)

            self.data[meter_prefix + "acva"] = round(acva, abs(acvasf))
            self.data[meter_prefix + "acvaa"] = round(acvaa, abs(acvasf))
            self.data[meter_prefix + "acvab"] = round(acvab, abs(acvasf))
            self.data[meter_prefix + "acvac"] = round(acvac, abs(acvasf))

            acvar = decoder.decode_16bit_int()
            acvara = decoder.decode_16bit_int()
            acvarb = decoder.decode_16bit_int()
            acvarc = decoder.decode_16bit_int()
            acvarsf = decoder.decode_16bit_int()

            acvar = self.calculate_value(acvar, acvarsf)
            acvara = self.calculate_value(acvara, acvarsf)
            acvarb = self.calculate_value(acvarb, acvarsf)
            acvarc = self.calculate_value(acvarc, acvarsf)

            self.data[meter_prefix + "acvar"] = round(acvar, abs(acvarsf))
            self.data[meter_prefix + "acvara"] = round(acvara, abs(acvarsf))
            self.data[meter_prefix + "acvarb"] = round(acvarb, abs(acvarsf))
            self.data[meter_prefix + "acvarc"] = round(acvarc, abs(acvarsf))

            acpf = decoder.decode_16bit_int()
            acpfa = decoder.decode_16bit_int()
            acpfb = decoder.decode_16bit_int()
            acpfc = decoder.decode_16bit_int()
            acpfsf = decoder.decode_16bit_int()

            acpf = self.calculate_value(acpf, acpfsf)
            acpfa = self.calculate_value(acpfa, acpfsf)
            acpfb = self.calculate_value(acpfb, acpfsf)
            acpfc = self.calculate_value(acpfc, acpfsf)

            self.data[meter_prefix + "acpf"] = round(acpf, abs(acpfsf))
            self.data[meter_prefix + "acpfa"] = round(acpfa, abs(acpfsf))
            self.data[meter_prefix + "acpfb"] = round(acpfb, abs(acpfsf))
            self.data[meter_prefix + "acpfc"] = round(acpfc, abs(acpfsf))

            exported = decoder.decode_32bit_uint()
            exporteda = decoder.decode_32bit_uint()
            exportedb = decoder.decode_32bit_uint()
            exportedc = decoder.decode_32bit_uint()
            imported = decoder.decode_32bit_uint()
            importeda = decoder.decode_32bit_uint()
            importedb = decoder.decode_32bit_uint()
            importedc = decoder.decode_32bit_uint()
            energywsf = decoder.decode_16bit_int()

            exported = self.calculate_value(exported, energywsf)
            exporteda = self.calculate_value(exporteda, energywsf)
            exportedb = self.calculate_value(exportedb, energywsf)
            exportedc = self.calculate_value(exportedc, energywsf)
            imported = self.calculate_value(imported, energywsf)
            importeda = self.calculate_value(importeda, energywsf)
            importedb = self.calculate_value(importedb, energywsf)
            importedc = self.calculate_value(importedc, energywsf)

            self.data[meter_prefix + "exported"] = round(exported * 0.001, 3)
            self.data[meter_prefix + "exporteda"] = round(exporteda * 0.001, 3)
            self.data[meter_prefix + "exportedb"] = round(exportedb * 0.001, 3)
            self.data[meter_prefix + "exportedc"] = round(exportedc * 0.001, 3)
            self.data[meter_prefix + "imported"] = round(imported * 0.001, 3)
            self.data[meter_prefix + "importeda"] = round(importeda * 0.001, 3)
            self.data[meter_prefix + "importedb"] = round(importedb * 0.001, 3)
            self.data[meter_prefix + "importedc"] = round(importedc * 0.001, 3)

            exportedva = decoder.decode_32bit_uint()
            exportedvaa = decoder.decode_32bit_uint()
            exportedvab = decoder.decode_32bit_uint()
            exportedvac = decoder.decode_32bit_uint()
            importedva = decoder.decode_32bit_uint()
            importedvaa = decoder.decode_32bit_uint()
            importedvab = decoder.decode_32bit_uint()
            importedvac = decoder.decode_32bit_uint()
            energyvasf = decoder.decode_16bit_int()

            exportedva = self.calculate_value(exportedva, energyvasf)
            exportedvaa = self.calculate_value(exportedvaa, energyvasf)
            exportedvab = self.calculate_value(exportedvab, energyvasf)
            exportedvac = self.calculate_value(exportedvac, energyvasf)
            importedva = self.calculate_value(importedva, energyvasf)
            importedvaa = self.calculate_value(importedvaa, energyvasf)
            importedvab = self.calculate_value(importedvab, energyvasf)
            importedvac = self.calculate_value(importedvac, energyvasf)

            self.data[meter_prefix + "exportedva"] = round(exportedva, abs(energyvasf))
            self.data[meter_prefix + "exportedvaa"] = round(
                exportedvaa, abs(energyvasf)
            )
            self.data[meter_prefix + "exportedvab"] = round(
                exportedvab, abs(energyvasf)
            )
            self.data[meter_prefix + "exportedvac"] = round(
                exportedvac, abs(energyvasf)
            )
            self.data[meter_prefix + "importedva"] = round(importedva, abs(energyvasf))
            self.data[meter_prefix + "importedvaa"] = round(
                importedvaa, abs(energyvasf)
            )
            self.data[meter_prefix + "importedvab"] = round(
                importedvab, abs(energyvasf)
            )
            self.data[meter_prefix + "importedvac"] = round(
                importedvac, abs(energyvasf)
            )

            importvarhq1 = decoder.decode_32bit_uint()
            importvarhq1a = decoder.decode_32bit_uint()
            importvarhq1b = decoder.decode_32bit_uint()
            importvarhq1c = decoder.decode_32bit_uint()
            importvarhq2 = decoder.decode_32bit_uint()
            importvarhq2a = decoder.decode_32bit_uint()
            importvarhq2b = decoder.decode_32bit_uint()
            importvarhq2c = decoder.decode_32bit_uint()
            importvarhq3 = decoder.decode_32bit_uint()
            importvarhq3a = decoder.decode_32bit_uint()
            importvarhq3b = decoder.decode_32bit_uint()
            importvarhq3c = decoder.decode_32bit_uint()
            importvarhq4 = decoder.decode_32bit_uint()
            importvarhq4a = decoder.decode_32bit_uint()
            importvarhq4b = decoder.decode_32bit_uint()
            importvarhq4c = decoder.decode_32bit_uint()
            energyvarsf = decoder.decode_16bit_int()

            importvarhq1 = self.calculate_value(importvarhq1, energyvarsf)
            importvarhq1a = self.calculate_value(importvarhq1a, energyvarsf)
            importvarhq1b = self.calculate_value(importvarhq1b, energyvarsf)
            importvarhq1c = self.calculate_value(importvarhq1c, energyvarsf)
            importvarhq2 = self.calculate_value(importvarhq2, energyvarsf)
            importvarhq2a = self.calculate_value(importvarhq2a, energyvarsf)
            importvarhq2b = self.calculate_value(importvarhq2b, energyvarsf)
            importvarhq2c = self.calculate_value(importvarhq2c, energyvarsf)
            importvarhq3 = self.calculate_value(importvarhq3, energyvarsf)
            importvarhq3a = self.calculate_value(importvarhq3a, energyvarsf)
            importvarhq3b = self.calculate_value(importvarhq3b, energyvarsf)
            importvarhq3c = self.calculate_value(importvarhq3c, energyvarsf)
            importvarhq4 = self.calculate_value(importvarhq4, energyvarsf)
            importvarhq4a = self.calculate_value(importvarhq4a, energyvarsf)
            importvarhq4b = self.calculate_value(importvarhq4b, energyvarsf)
            importvarhq4c = self.calculate_value(importvarhq4c, energyvarsf)

            self.data[meter_prefix + "importvarhq1"] = round(
                importvarhq1, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq1a"] = round(
                importvarhq1a, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq1b"] = round(
                importvarhq1b, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq1c"] = round(
                importvarhq1c, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq2"] = round(
                importvarhq2, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq2a"] = round(
                importvarhq2a, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq2b"] = round(
                importvarhq2b, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq2c"] = round(
                importvarhq2c, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq3"] = round(
                importvarhq3, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq3a"] = round(
                importvarhq3a, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq3b"] = round(
                importvarhq3b, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq3c"] = round(
                importvarhq3c, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq4"] = round(
                importvarhq4, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq4a"] = round(
                importvarhq4a, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq4b"] = round(
                importvarhq4b, abs(energyvarsf)
            )
            self.data[meter_prefix + "importvarhq4c"] = round(
                importvarhq4c, abs(energyvarsf)
            )

            return True
        else:
            return False

    def read_modbus_data_inverter(self):
        inverter_data = self.read_holding_registers(unit=1, address=40071, count=38)
        if not inverter_data.isError():
            decoder = BinaryPayloadDecoder.fromRegisters(
                inverter_data.registers, byteorder=Endian.Big
            )
            accurrent = decoder.decode_16bit_uint()
            accurrenta = decoder.decode_16bit_uint()
            accurrentb = decoder.decode_16bit_uint()
            accurrentc = decoder.decode_16bit_uint()
            accurrentsf = decoder.decode_16bit_int()

            accurrent = self.calculate_value(accurrent, accurrentsf)
            accurrenta = self.calculate_value(accurrenta, accurrentsf)
            accurrentb = self.calculate_value(accurrentb, accurrentsf)
            accurrentc = self.calculate_value(accurrentc, accurrentsf)

            self.data["accurrent"] = round(accurrent, abs(accurrentsf))
            self.data["accurrenta"] = round(accurrenta, abs(accurrentsf))
            self.data["accurrentb"] = round(accurrentb, abs(accurrentsf))
            self.data["accurrentc"] = round(accurrentc, abs(accurrentsf))

            acvoltageab = decoder.decode_16bit_uint()
            acvoltagebc = decoder.decode_16bit_uint()
            acvoltageca = decoder.decode_16bit_uint()
            acvoltagean = decoder.decode_16bit_uint()
            acvoltagebn = decoder.decode_16bit_uint()
            acvoltagecn = decoder.decode_16bit_uint()
            acvoltagesf = decoder.decode_16bit_int()

            acvoltageab = self.calculate_value(acvoltageab, acvoltagesf)
            acvoltagebc = self.calculate_value(acvoltagebc, acvoltagesf)
            acvoltageca = self.calculate_value(acvoltageca, acvoltagesf)
            acvoltagean = self.calculate_value(acvoltagean, acvoltagesf)
            acvoltagebn = self.calculate_value(acvoltagebn, acvoltagesf)
            acvoltagecn = self.calculate_value(acvoltagecn, acvoltagesf)

            self.data["acvoltageab"] = round(acvoltageab, abs(acvoltagesf))
            self.data["acvoltagebc"] = round(acvoltagebc, abs(acvoltagesf))
            self.data["acvoltageca"] = round(acvoltageca, abs(acvoltagesf))
            self.data["acvoltagean"] = round(acvoltagean, abs(acvoltagesf))
            self.data["acvoltagebn"] = round(acvoltagebn, abs(acvoltagesf))
            self.data["acvoltagecn"] = round(acvoltagecn, abs(acvoltagesf))

            acpower = decoder.decode_16bit_int()
            acpowersf = decoder.decode_16bit_int()
            acpower = self.calculate_value(acpower, acpowersf)

            self.data["acpower"] = round(acpower, abs(acpowersf))

            acfreq = decoder.decode_16bit_uint()
            acfreqsf = decoder.decode_16bit_int()
            acfreq = self.calculate_value(acfreq, acfreqsf)

            self.data["acfreq"] = round(acfreq, abs(acfreqsf))

            acva = decoder.decode_16bit_int()
            acvasf = decoder.decode_16bit_int()
            acva = self.calculate_value(acva, acvasf)

            self.data["acva"] = round(acva, abs(acvasf))

            acvar = decoder.decode_16bit_int()
            acvarsf = decoder.decode_16bit_int()
            acvar = self.calculate_value(acvar, acvarsf)

            self.data["acvar"] = round(acvar, abs(acvarsf))

            acpf = decoder.decode_16bit_int()
            acpfsf = decoder.decode_16bit_int()
            acpf = self.calculate_value(acpf, acpfsf)

            self.data["acpf"] = round(acpf, abs(acpfsf))

            acenergy = decoder.decode_32bit_uint()
            acenergysf = decoder.decode_16bit_uint()
            acenergy = self.calculate_value(acenergy, acenergysf)

            self.data["acenergy"] = round(acenergy * 0.001, 3)

            dccurrent = decoder.decode_16bit_uint()
            dccurrentsf = decoder.decode_16bit_int()
            dccurrent = self.calculate_value(dccurrent, dccurrentsf)

            self.data["dccurrent"] = round(dccurrent, abs(dccurrentsf))

            dcvoltage = decoder.decode_16bit_uint()
            dcvoltagesf = decoder.decode_16bit_int()
            dcvoltage = self.calculate_value(dcvoltage, dcvoltagesf)

            self.data["dcvoltage"] = round(dcvoltage, abs(dcvoltagesf))

            dcpower = decoder.decode_16bit_int()
            dcpowersf = decoder.decode_16bit_int()
            dcpower = self.calculate_value(dcpower, dcpowersf)

            self.data["dcpower"] = round(dcpower, abs(dcpowersf))

            # skip register
            decoder.skip_bytes(2)

            tempsink = decoder.decode_16bit_int()

            # skip 2 registers
            decoder.skip_bytes(4)

            tempsf = decoder.decode_16bit_int()
            tempsink = self.calculate_value(tempsink, tempsf)

            self.data["tempsink"] = round(tempsink, abs(tempsf))

            status = decoder.decode_16bit_int()
            self.data["status"] = status
            statusvendor = decoder.decode_16bit_int()
            self.data["statusvendor"] = statusvendor

            return True
        else:
            return False
Exemplo n.º 59
0
from pymodbus.client.sync import ModbusTcpClient as ModbusClient

# ---------------------------------------------------------------------------#
# 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("127.0.0.1")
client.connect()

# ---------------------------------------------------------------------------#
# If you need to build a complex message to send, you can use the payload
# builder to simplify the packing logic.
#
# Here we demonstrate packing a random payload layout, unpacked it looks
# like the following:
#
# - a 8 byte string 'abcdefgh'
# - a 32 bit float 22.34
# - a 16 bit unsigned int 0x1234
# - an 8 bit int 0x12
# - an 8 bit bitstring [0,1,0,1,1,0,1,0]
# ---------------------------------------------------------------------------#
builder = BinaryPayloadBuilder(endian=Endian.Little)
Exemplo n.º 60
0
class Drive:
    client = None
    queue = []

    def __init__(self, sensors):
        self.sensors = sensors
        self.connect_modbus()
        
    def connect_modbus(self):
        try:
            self.client = ModbusClient(HOST, port=PORT)
            print("Opening modbus connection...")
            self.client.connect()
            print("Connection opened")
        except ConnectionException:
            print("Impossible to connect")

    def close_modbus(self):
        print("Closing modbus connection...")
        self.client.close()
        print("Connection closed")

    def add_vehicle(self, vehicle):
        self.queue.append(vehicle)

    def read_registers(self, sc):
        if self.client.is_socket_open():
            t = time.time_ns()
            regs = self.client.read_input_registers(0,1)
            if isinstance(regs, ReadInputRegistersResponse) and regs:
                registers = regs.registers
                if (isinstance(registers, list) and len(registers) > 0):
                    inputs = self.pad_inputs(self.hex_to_binary(registers[0]))
                    inputs = self.parse_input_status(inputs)
                    if len(inputs):
                        for sensor in self.sensors:
                            if sensor.input < len(inputs):
                                updated = sensor.update_state(inputs[sensor.input], t)
                                if updated:
                                    self.send_message(sensor, t)
            try:
                sc.enter(0.5, 1, self.read_registers, (sc, ))
            except:
                print("stop")
        else:
            print("Connection to address '" + HOST + "' could not be made")

    def hex_to_binary(self, hex_code):
        bin_code = bin(hex_code)[2:]
        padding = (4 - len(bin_code) % 4) % 4
        return '0' * padding + bin_code

    def pad_inputs(self, inputs):
        return inputs.zfill(8)

    def parse_input_status(self, inputs):
        inputs = inputs[::-1]
        coils = []
        for i in range(len(inputs)):
            coils.append(inputs[i] == '1')
        return coils

    def send_message(self, sensor, timestamp):
        t = time.localtime(timestamp / 1000000000)
        print("[" + time.strftime("%m/%d/%Y %H:%M:%S", t) + "] : Detection on channel (" + str(sensor.input) + ") : " + sensor.get_readable_state())