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)
Пример #2
0
class UEMD(object):
    def __init__(self, host: str, port: int = 502, timeout: int = 3):
        self.client = ModbusTcpClient(host=host, port=port, timeout=timeout)

    def is_connectable(self):

        ret = self.client.connect()
        self.client.close()
        return ret

    def show(self):
        print(self.client)

        r = self.client.read_holding_registers(0, count=2)
        print(r.registers)

    def get_data(self):
        # print(self.is_connectable())

        result = self.client.read_holding_registers(0, count=2)
        decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                     byteorder=Endian.Little,
                                                     wordorder=Endian.Little)

        return decoder.decode_32bit_float()

    def __del__(self):
        self.client.close()
Пример #3
0
class SmaModbus(Log):
    """
    Communicates via modbus to SMA PV invertes
    """
    _unit_id: int = -1

    def __init__(self, host: str, port: int = 502):
        super().__init__()
        self._client = ModbusTcpClient(host, port)

    def connect(self):
        self._client.connect()
        # Ask for unit ID
        reply = self._client.read_holding_registers(42109, 4, unit=1)
        self._unit_id = reply.registers[3]

    def close(self):
        self._client.close()

    def read(self, reg: Register) -> ValueWithUnit:
        value = u32(
            self._client.read_holding_registers(reg.id, 2, unit=self._unit_id))
        if value == 0xffffffff or value == 0x80000000:
            # Use 0 as a more sane "not available" value
            value = 0
        return ValueWithUnit(value, reg.unit)
Пример #4
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)
Пример #5
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)
Пример #6
0
 def run(self):
     client = Client(self.url, port=self.port)
     client.connect()
     registers = []
     count = self.count
     readCount = 0
     try:
         while count > 0:
             if count > 125:
                 rr = client.read_holding_registers(self.address +
                                                    readCount - 1,
                                                    125,
                                                    unit=self.unit)
                 count -= 125
                 readCount += 125
             else:
                 rr = client.read_holding_registers(self.address +
                                                    readCount - 1,
                                                    count,
                                                    unit=self.unit)
                 count = 0
                 readCount += count
             registers = registers + rr.registers
         client.close()
         return registers
     except:
         return []
 def run(self):
     VEBUS_FIRST_ADDRESS = 3
     VEBUS_LAST_ADDRESS = 59
     VEBUS_NUM_ADDRESSES = VEBUS_LAST_ADDRESS - VEBUS_FIRST_ADDRESS
     VEBUS_INPUT_POWER_PHASE_1 = 12 - 3  #(Register 12, aber wir fangen ja erst bei Reg.3 an...)
     VEBUS_STATE_OF_CHARGE = 30 - 3
     GRID_FIRST_ADDRESS = 2600  #Reg. 2600 - 2602 sind die drei Phasen am Übergabezähler
     GRID_NUM_ADDRESSES = 3
     UID_VEBUS = 246
     UID_GRID = 30
     wechselrichter = ModbusTcpClient(self.ip, self.port)
     wechselrichter.connect()
     while True:
         vebus = wechselrichter.read_holding_registers(VEBUS_FIRST_ADDRESS,
                                                       VEBUS_NUM_ADDRESSES,
                                                       unit=UID_VEBUS)
         grid = wechselrichter.read_holding_registers(GRID_FIRST_ADDRESS,
                                                      GRID_NUM_ADDRESSES,
                                                      unit=UID_GRID)
         vebus_register = vebus.registers
         grid_register = grid.registers
         self.soc = vebus_register[VEBUS_STATE_OF_CHARGE] / 10
         self.pac = self.correct_power_value(
             vebus_register[VEBUS_INPUT_POWER_PHASE_1]) * 10
         self.pgrid1 = self.correct_power_value(grid_register[0])
         self.pgrid2 = self.correct_power_value(grid_register[1])
         self.pgrid3 = self.correct_power_value(grid_register[2])
         self.checked = True
         time.sleep(self.interval)
class ModbusUtility():
    def __init__(self, ip):
        self.modcli = ModbusTcpClient(ip)

    @staticmethod
    def getReg(reg, index=0):
        # Registers are stored without decimal points. Their values represent
        # the number multiplied by 100 so we undo that to get the real value

        # We assume desired register is first element, pass in optional index to change
        return (float(reg[index]) / 100)

    @staticmethod
    def setReg(data):
        # Since register data is stored without decimals and multiplied by 100 that is
        # what we supply
        return (int(data * 100))

    def PrintAllRegisters(self):
        print("Printing registers...")
        for key in REG_DICT.keys():
            data = self.ReadRegister(key)

            print("Register [{}]: {}".format(key, data))

    def ReadRegister(self, name):
        t = REG_DICT[name]["type"]  # Current register type
        o = REG_DICT[name]["offset"]  # Current register offset
        s = REG_DICT[name]["size"]  # Current register size in bytes.

        # If the size is greater the 2 bytes unpack it like it is a float.
        # Really we should also check that this is a float but it doesn't matter since
        # our system only has 3 registers that are 4 bytes long and they are all floats
        if (s > 2):
            data = self.modcli.read_holding_registers(o, s, unit=1).registers
            reg = struct.unpack(
                ">f", data[0].to_bytes(2, "big") + data[2].to_bytes(2, "big"))
            return (reg[0])

        data = self.modcli.read_holding_registers(o, 1, unit=1)

        return (self.getReg(data.registers))

    def WriteRegister(self, name, num):
        o = REG_DICT[name]["offset"]  # Current register offset
        s = REG_DICT[name]["size"] / 2  # Current register size

        if (s > 1):
            data = struct.unpack("HH", struct.pack("=f", num))
            # Sending these backwards is a concious decision. Unpack always returns
            # them in 'backwards' order.
            self.modcli.write_registers(o, data[1])
            self.modcli.write_registers(o + 1, data[0])
        else:
            data = num
            self.modcli.write_registers(o, self.setReg(data))
Пример #9
0
def main(protocol):
    global messageCounter
    global hub_manager
    try:
        print("\nPython %s\n" % sys.version)
        print("IoT Hub Client for Python")

        hub_manager = HubManager(protocol)

        print("Starting the IoT Hub Python sample using protocol %s..." %
              hub_manager.client_protocol)
        while True:
            time.sleep(POLLINGfrequency)
            modbusclient = ModbusClient(POLLINGHost, port=502)
            try:
                modbusclient.connect()
                messageToSend = {}
                messageToSend['POLLINGHost'] = POLLINGHost
                messageToSend['dateTime'] = str(datetime.datetime.now())
                messageToSend[
                    'Las Vegas'] = modbusclient.read_holding_registers(
                        0, 1, unit=0x01).registers[0]
                messageToSend[
                    'Stockholm'] = modbusclient.read_holding_registers(
                        1, 1, unit=0x01).registers[0]
                messageToSend[
                    'Wadi Halfa'] = modbusclient.read_holding_registers(
                        2, 1, unit=0x01).registers[0]
                messageToSend[
                    'MSFT Stock'] = modbusclient.read_holding_registers(
                        3, 1, unit=0x01).registers[0]
                messageToSend[
                    'HPE Stock'] = modbusclient.read_holding_registers(
                        4, 1, unit=0x01).registers[0]
                IoTmessageToSend = IoTHubMessage(
                    bytearray(json.dumps(messageToSend), 'utf8'))
                hub_manager.forward_event_to_output("output1",
                                                    IoTmessageToSend,
                                                    messageCounter)
                messageCounter += 1
            except Exception:
                errorMessage = "{\"error\":\"" + str(sys.exc_info()[0]) + "\"}"
                IoTmessageToSend = IoTHubMessage(
                    bytearray(errorMessage, 'utf8'))
                hub_manager.forward_event_to_output("output1",
                                                    IoTmessageToSend,
                                                    messageCounter)
                messageCounter += 1
            modbusclient.close()

    except IoTHubError as iothub_error:
        print("Unexpected error %s from IoTHub" % iothub_error)
        return
    except KeyboardInterrupt:
        print("IoTHubModuleClient sample stopped")
Пример #10
0
def retrieve_file(Filename, starting, filesize):
    MAX_FILE_SIZE = 2047
    blocksize = 64
    #print (filesize)
    if ((starting + int(filesize) < MAX_FILE_SIZE) & (get_IP() != "")):
        write_screen("Reading file from PLC...")
        client = ModbusClient(get_IP(), DPORT)
        client.connect()
        f = open(Filename, "wb")

        while (starting < filesize):
            if ((filesize // 2) - starting >= blocksize):
                #print ("Leemos "+str(blocksize)+" words desde "+str(starting)+" para llegar a "+str(filesize//2))
                #leemos 64 enteros, 128 bytes
                response = client.read_holding_registers(starting,
                                                         blocksize,
                                                         unit=0x01)
                dot()
            else:
                #				print ("Leemos "+str(filesize//2-starting)+" words desde "+str(starting)+" para llegar a "+str(filesize//2))
                response = client.read_holding_registers(
                    starting, (filesize // 2) - starting + 2, unit=0x01)
                starting = filesize + 1

            bytes = []
            regs = []
            if response:
                for regnum in range(1, len(response.registers) + 1):
                    regs.append(response.registers[regnum - 1])
                    if ((starting > filesize) &
                        (regnum == len(response.registers))):
                        print(response.registers[regnum - 2])
                        bytes.append(response.registers[regnum - 1] % 256)
                    else:
                        bytes.append(response.registers[regnum - 1] // 256)
                        bytes.append(response.registers[regnum - 1] % 256)

            #Last word is only 1 byte long...
            #print (regnum)
            #bytes.append(response.registers[regnum]%256)

            else:
                print("Error: could not read any register from PLC")

            f.write(bytearray(bytes))
            starting += 64

        f.close()
        client.close()
        write_screen("\n" + str(filesize) + " bytes recovered from PLC")
    else:
        print("Error: File does NOT exist. Exiting")
Пример #11
0
class CSpot():
    # CSpot: class used to read a spot modbus register
    def __init__(self, config):

        self.host = config[
            'HOST']  #use the host ip address defined in etc/config (default is '10.1.10.50')

        timeout = int(config['CONN_TIMEOUT_S']
                      )  #define a connection timeout (not currently used)
        #self.modBusRegToRead = int(config['READ_MODBUS_REG'])
        self.config = config  # make the config accessabile

    def ReadRegister(self, nReadings, sampleInteveralMs, address):
        self.client = ModbusTcpClient(
            self.host)  # use ModbusTcpClient from pymodbus
        #Method to read nReadings of a single modbus regeister at a sample interval sampleInteveralMs
        #Uses a pause of sampleInterval rather than re-sampling

        #Make an array for the the NReadings of values read from the register
        allValues = np.ones(nReadings)
        allValues = allValues * np.NAN
        t = TicToc()
        t.tic()  #Start timer
        registerValue = np.NAN

        #bug fix - read a registor once, to set the correct registor address
        request = self.client.read_holding_registers(address, 1)
        registerValue = request.registers
        registerValue = np.NAN

        for k in range(0, nReadings):
            try:
                #address = int(self.config['READ_MODBUS_REG'])
                request = self.client.read_holding_registers(address, 1)
                registerValue = request.registers
            except:
                registerValue = np.NAN  # return Nan if the register can't be read
            #print(registerValue)
            #print(type(registerValue))
            #print(allValues)
            #exit(0)
            allValues[k] = registerValue[0]
            time.sleep(
                sampleInteveralMs / 1e3
            )  #pause before next reading. NB we are consitently sampling the same phase of the chopper
        #Return the array of nReadings of a single modbus register and the time taken to acquire.
        elapsedTime = t.tocvalue()
        time.sleep(1)  #Dwell to allow return of reponse
        self.client.close()

        return allValues, elapsedTime
Пример #12
0
class modbus:
    def __init__(self, IP):
        # Class Variablen
        self._IP = IP
        self._client = ''
        # Plenticore als Modbus Client einrichten
        self._client = ModbusTcpClient(self._IP, port=1502)
        # self._wr.client.connect()

    def ReadRegister(self, address, count=1, **kwargs):
        return self._client.read_holding_registers(address, count, **kwargs)

    def ReadUInt16(self, addr):
        data = self._client.read_holding_registers(addr, 1, unit=71)
        UInt16register = BinaryPayloadDecoder.fromRegisters(
            data.registers, byteorder=Endian.Big, wordorder=Endian.Little)
        result = UInt16register.decode_16bit_uint()
        return (result)

    def ReadInt16(self, addr):
        data = self._client.read_holding_registers(addr, 1, unit=71)
        Int16register = BinaryPayloadDecoder.fromRegisters(
            data.registers, byteorder=Endian.Big, wordorder=Endian.Little)
        result = Int16register.decode_16bit_int()
        return (result)

    def ReadUInt32(self, addr):
        data = self._client.read_holding_registers(addr, 2, unit=71)
        UInt32register = BinaryPayloadDecoder.fromRegisters(
            data.registers, byteorder=Endian.Big, wordorder=Endian.Little)
        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.Little)
        result = Int32register.decode_32bit_int()
        return (result)

    def ReadFloat32(self, addr):
        data = self._client.read_holding_registers(addr, 2, unit=71)
        Float32register = BinaryPayloadDecoder.fromRegisters(
            data.registers, byteorder=Endian.Big, wordorder=Endian.Little)
        result = Float32register.decode_32bit_float()
        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.Little)
        result = UInt64register.decode_64bit_uint()
        return (result)

    def ReadString(self, addr):
        data = self._client.read_holding_registers(addr, 8, unit=71)
        Stringregister = BinaryPayloadDecoder.fromRegisters(
            data.registers, byteorder=Endian.Big, wordorder=Endian.Little)
        result = Stringregister.decode_string(8)
        return (result)
Пример #13
0
def getPortNo(type, ipaddress):
    slaveid = 1
    file_path = '/var/www/html/openWB/ramdisk/solaredgeport_' + str(type)
    # ModBus is configured to listen on port 502 or 1502, actual port is autodetected and cache in ramdisk
    port = 0  # port not defined
    ramdiskInitialized = False  # assume ramdisk cache is not set
    if os.path.isfile(file_path):
        with open(file_path, 'r') as f:
            try:
                data = f.read()
                (ipaddr, port) = data.split(':')
                if (ipaddress == ipaddr):
                    ramdiskInitialized = True
                    return port
                else:
                    print('changed ip addr, old: %s, new: %s' %
                          (ipaddr, ipaddress))
                    os.remove(file_path)
            except:
                pass  # ramdisk file does not exist, proceed with autodetection

    port = 502  # try port 502 first

    client = ModbusTcpClient(ipaddress, port=port)
    try:
        resp = client.read_holding_registers(40000, 1, unit=slaveid)
        if resp.registers[0] == 21365:
            if not ramdiskInitialized:  # if we reach this line, we were able to read ModBus registers
                # ramdisk is not set, so persist port value now for next time
                with open(file_path, 'w') as f:
                    f.write(ipaddress + ':' + str(port))
                return port
        # we were unable to read registers from port 502 so try 1502 next
    except ConnectionException:
        port = 1502
        client.port = port
        try:
            resp = client.read_holding_registers(40000, 1, unit=slaveid)
            if resp.registers[0] == 21365:
                # now it worked, persist port number in ramdisk
                if not ramdiskInitialized:
                    with open(file_path, 'w') as f:
                        f.write(ipaddress + ':' + str(port))
                    return port
        except:
            # no connection, remove cache file if any
            if os.path.isfile(file_path):
                os.remove(file_path)
    return port
Пример #14
0
def loop_process():
    # Main Process
    err_count = 0
    registre_count = 10

    while True:
        sleep(1)
        try:
            client = ModbusTcpClient(modbus_server_ip, modbus_server_port)

            # read registers
            CAPT1 = client.read_holding_registers(0, 1, unit=UNIT).registers[0]
            CAPT2 = client.read_holding_registers(1, 1, unit=UNIT).registers[0]
            M_UP = client.read_holding_registers(2, 1, unit=UNIT).registers[0]
            M_DOWN = client.read_holding_registers(3, 1,
                                                   unit=UNIT).registers[0]
            C_UP = client.read_holding_registers(4, 1, unit=UNIT).registers[0]
            C_DOWN = client.read_holding_registers(5, 1,
                                                   unit=UNIT).registers[0]
            C_STOP = client.read_holding_registers(6, 1,
                                                   unit=UNIT).registers[0]
            LIGHT1 = client.read_holding_registers(7, 1,
                                                   unit=UNIT).registers[0]
            LIGHT2 = client.read_holding_registers(8, 1,
                                                   unit=UNIT).registers[0]

            # process
            LIGHT1 = CAPT1
            LIGHT2 = CAPT2
            # Moteur up =
            M_UP = (not M_DOWN) and (not CAPT1) and (not C_STOP) and (C_UP
                                                                      or M_UP)
            M_DOWN = (not M_UP) and (CAPT2) and (not C_STOP) and (C_DOWN
                                                                  or M_DOWN)

            # C_* are just buttons
            C_UP = 0
            C_DOWN = 0
            C_STOP = 0

            # CAPT1 & CAPT2 are updated by the PHP script itself

            # save registers
            client.write_register(0, CAPT1, unit=UNIT)
            client.write_register(1, CAPT2, unit=UNIT)
            client.write_register(2, M_UP, unit=UNIT)
            client.write_register(3, M_DOWN, unit=UNIT)
            client.write_register(4, C_UP, unit=UNIT)
            client.write_register(5, C_DOWN, unit=UNIT)
            client.write_register(6, C_STOP, unit=UNIT)
            client.write_register(7, LIGHT1, unit=UNIT)
            client.write_register(8, LIGHT2, unit=UNIT)
        except Exception as err:
            print '[error] %s' % err
            err_count += 1
            if err_count == 5:
                print '[error] 5 errors happened in the process ! exiting...'
                sys.exit(1)
Пример #15
0
class OpenPlcModbus:
    def __init__(self):
        self.plc = ModbusClient('localhost', port=502)

    def get_counter_value(self):
        request = self.plc.read_holding_registers(1024, 1)
        value = request.registers[0]
        return value

    def get_motor_status(self):
        request = self.plc.read_coils(0, 1)
        status = request.bits[0]
        return status

    def turn_on(self, action):
        if action:
            self.plc.write_coil(1, True)
        else:
            self.plc.write_coil(1, False)

    def turn_off(self, action):
        if action:
            self.plc.write_coil(2, True)
        else:
            self.plc.write_coil(2, False)

    def close(self):
        self.plc.close()
Пример #16
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)};
Пример #17
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]
Пример #18
0
    def read_registers(self, slave):
        # Carefully measured artificial pause to make sure everything is processed
        time.sleep(0.02)
        try:
            if type(slave.slave_id) is int:
                # logging.debug(f'++ Requesting data from {slave.slave_id}')
                response = self.serialModbus.read_holding_registers(
                    0, slave.reg_count, unit=slave.slave_id)
            else:
                # logging.debug(f'++ Requesting data from {slave.slave_id}')
                tcp_modbus = ModbusTcpClient(slave.slave_id)
                tcp_modbus.connect()
                response = tcp_modbus.read_holding_registers(
                    0, slave.reg_count)

            if issubclass(type(response), ModbusException):
                raise response

            # logging.debug(f'++ Got data from {slave.slave_id}')
            return response

        except (IndexError, struct.error, ModbusException,
                ConnectionException) as e:
            logging.exception(e, exc_info=False)
            slave.errors += 1
            return None
Пример #19
0
def get_values(address,port):

	client = ModbusTcpClient(str(address), int(port))
	succeed = client.connect()

	if succeed:
		result = client.read_holding_registers(address=0,count=15,unit=1)
		result2 = client.read_coils(address=0,count=15,unit=1)
		client.close()
		results = {}
		for r in range(0,15):
			register = result.registers[r]
			results["r"+str(r)] = str(register)+"%"
			
			coil = result2.bits[r]
			if coil:
				coil='ON'
			else:
				coil='OFF'

			results["c"+str(r)] = coil

		#print(results)

		return jsonify(results)
	else:
		return render_template('index.html', error="Modbus slave is disconnected")
Пример #20
0
def reader():
    c = ModbusTcpClient(host="localhost", port=502)

    if not c.is_socket_open() and not c.connect():
        print("unable to connect to host")

    if not c.is_socket_open():
        return None

    holdingRegisters = c.read_holding_registers(1, 4)

    if holdingRegisters.isError():
        print('Error reading registers')
        return None

    # Imagine we've "energy" value in position 1 with two words
    energy = (
        holdingRegisters.registers[0] << 16) | holdingRegisters.registers[1]

    # Imagine we've "power" value in position 3 with two words
    power = (
        holdingRegisters.registers[2] << 16) | holdingRegisters.registers[3]

    out = {"energy": energy, "power": power}

    print(out)

    return json.dumps(out)
Пример #21
0
class Koyo:
    def __init__(self, ip_address):
        self.ip_address = ip_address
        self._koyo = ModbusClient(ip_address)
        print("Connected:", self._koyo.connect())
        if self._koyo.connect():
            self._getversions()
            self._get_device_info()

    def _getversions(self):
        data = self._koyo.read_input_registers(17500, 6)
        self.os_version = '.'.join(map(str, data.registers[0:3]))
        self.boot_version = '.'.join(map(str, data.registers[3:6]))

    def _get_device_info(self):
        data = self._koyo.read_input_registers(17510, 19)
        self.device_version = data.registers[0]
        self.family = data.registers[1]

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

    def read_register(self, x):
        read = self._koyo.read_holding_registers(x, count=1, unit=1)
        return read.registers[0]
Пример #22
0
def run_sync_client():
    """ Main loop for Modbus communication """
    # Define client connection
    client = ModbusClient('localhost', port=5020, framer=ModbusFramer)
    client.connect()

    # Specify target device
    log.debug("Reading Coils")
    rr = client.read_holding_registers(0, 7, unit=UNIT)
    log.debug(rr.registers)
    log.debug(rr.registers[0])
    decoder = BinaryPayloadDecoder.fromRegisters(rr.registers,
                                                 byteorder=Endian.Big)

    decoded = OrderedDict([
        ('value', decoder.decode_32bit_float()),
        ('qualityId', decoder.decode_16bit_uint()),
        ('unitId', decoder.decode_16bit_float()),
        ('paramId', decoder.decode_16bit_uint()),
        ('sentinel', decoder.decode_32bit_float())
    ])

    for name, value in iteritems(decoded):
        log.debug(name)
        log.debug(value)

    # Close Client
    client.close()
Пример #23
0
def main(
    host,
    port,
    address,
    write=None,
    unit=1
):  # NOTE: the unit is like an identifier for the slave; it corresponds to the identifier for a store

    client = ModbusTcpClient(host, port=port)
    client.connect()

    if write != None:
        value = write
        logger.debug(f"Writing value {value} to address {address}")
        rq = client.write_register(address, value, unit=unit)
        assert (not rq.isError())  # test that we are not an error

    rr = client.read_holding_registers(address, 1, unit=unit)
    logger.info(f"Value at address {address} is {rr.registers[0]}")
    #assert(rr.registers[0] == 11)       # test the expected value

    # logger.debug("Write to multiple holding registers and read back")
    # rq = client.write_registers(1, [10]*8, unit=UNIT)
    # rr = client.read_holding_registers(1, 8, unit=UNIT)
    # assert(not rq.isError())     # test that we are not an error
    # assert(rr.registers == [10]*8)      # test the expected value

    client.close()
Пример #24
0
def read_holding_regs():
    form = ReusableForm(request.form)

    print form.errors
    if request.method == 'POST':
        ip = request.form['ip']
        port = request.form['port']
        address = request.form['address']
        value = request.form['value']
        unitId = request.form['unitId']
        print ip, " ", port, " ", address

        host = ip
        port = int(port)
        client = ModbusTcpClient(host, port)
        client.connect()

        rr = client.read_holding_registers(int(address),
                                           int(value),
                                           unit=int(unitId))
        assert (rr.function_code < 0x80)  # test that we are not an error
        print(rr)
        print(str(rr.registers))

        if form.validate():
            flash(str(rr.registers))
        else:
            flash("Error")

    return render_template('read-hold-regs.html', form=form)
Пример #25
0
def Get_Modbus_Value(Sensors,IP,Address,RegisterID,RegisterAddr,RegisterLength,RegisterType,RegisterPeriod,P):
   try:
       result=[]
       for i in range (0,len(Sensors)):
            mclient = ModbusTcpClient(IP[i])
            mclient.connect()
            for j in range(0,len(RegisterID[i])):
		if(datetime.now()>=P[i][j]):
		   P[i][j] = P[i][j] + timedelta(seconds=RegisterPeriod[i][j])
		   data = mclient.read_holding_registers(RegisterAddr[i][j],RegisterLength[i][j], unit=Address[i])
		   reg = data.registers
                   decoder = BinaryPayloadDecoder.fromRegisters(reg,byteorder=Endian.Big,wordorder=Endian.Little)

                   if(RegisterType[i][j] == 1):
                     reg = float('{0:.2f}'.format(decoder.decode_16bit_uint()))
                   elif (RegisterType[i][j]==2):
                     reg = float('{0:.2f}'.format(decoder.decode_32bit_uint()))
                   elif (RegisterType[i][j]==3):
                     reg = float('{0:.2f}'.format(decoder.decode_16bit_int()))
                   elif (RegisterType[i][j]==4):
                     reg = float('{0:.2f}'.format(decoder.decode_32bit_int()))
                   elif (RegisterType[i][j]==5):
                     reg = float('{0:.2f}'.format(decoder.decode_32bit_float()))
                   result.append(reg)

       return result,P

   except ReturnError:
      print("Could not read modbus values from sensors",Sensors)
Пример #26
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
        ]
Пример #27
0
def readMBholdingregisters(clientIP, register, number=1):
    from pymodbus.client.sync import ModbusTcpClient, ConnectionException

    client = ModbusTcpClient(clientIP)
    values = []
    try:
        rawresult = client.read_holding_registers(register, number)
    except ConnectionException:
        # print('we were unable to connect to the host')
        statuscode = 7
    else:
        # print(rawresult)
        try:
            resultregisters = rawresult.registers
        except AttributeError:
            statuscode = rawresult.exception_code
        else:
            statuscode = 0
            values = resultregisters
    client.close()
    result = {
        'message': messagefrommbstatuscode(statuscode),
        'statuscode': statuscode,
        'values': values
    }
    return result
Пример #28
0
 def read_holding_registers(self, command):
     parser = argument_parser()
     command = 'read_holding_register ' + command
     spec = parser.parse_args(command.split())
     response = _ModbusClient.read_holding_registers(
         self, spec.address, spec.count, unit=spec.unit_id)
     return response
Пример #29
0
def loop_process():
    # Main Process (template = flip-flop)
    err_count = 0
    registre_count = 10

    while True:
        sleep(1)
        try:
            client = ModbusTcpClient(modbus_server_ip, modbus_server_port)

            coils = client.read_coils(0, count=registre_count, unit=UNIT)
            coils = coils.bits[:registre_count]
            # flipping booleans from list coils
            coils = [not i for i in coils]
            client.write_coils(0, coils)

            registers = client.read_holding_registers(0,
                                                      count=registre_count,
                                                      unit=UNIT)
            registers = registers.registers[:registre_count]
            registers = [i + 1 for i in registers]
            client.write_registers(0, registers, unit=UNIT)

            updateGPIO(coils, registers)
        except Exception as err:
            print('[error] %s' % err)
            err_count += 1
            if err_count == 5:
                print('[error] 5 errors happened in the process ! exiting...')
                sys.exit(1)
Пример #30
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)
Пример #31
0
def getModbusData(modeAwake, classicHost, classicPort):
    
    global isConnected, modbusClient

    try:
        if not isConnected:
            log.debug("Opening the modbus Connection")
            if modbusClient is None:
                modbusClient = ModbusClient(host=classicHost, port=classicPort)
    
            #Test for succesful connect, if not, log error and mark modbusConnected = False
            modbusClient.connect()

            result = modbusClient.read_holding_registers(4163, 2,  unit=10)
            if result.isError():
                # close the client
                log.error("MODBUS isError H:{} P:{}".format(classicHost, classicPort))
                modbusClient.close()
                isConnected = False
                return {}

            isConnected = True

        theData = {}
        #Read in all the registers at one time
        theData[4100] = getRegisters(theClient=modbusClient,addr=4100,count=44)
        theData[4360] = getRegisters(theClient=modbusClient,addr=4360,count=22)
        theData[4163] = getRegisters(theClient=modbusClient,addr=4163,count=2)
        theData[4209] = getRegisters(theClient=modbusClient,addr=4209,count=4)
        theData[4243] = getRegisters(theClient=modbusClient,addr=4243,count=32)
        theData[16386]= getRegisters(theClient=modbusClient,addr=16386,count=4)
        
        #If we are snoozing, then give up the connection
        #log.debug("modeAwake:{}".format(modeAwake))
        if not modeAwake :
            log.debug("Closing the modbus Connection, we are in Snooze mode")
            modbusClient.close()
            isConnected = False

    except: # Catch all modbus excpetions
        e = sys.exc_info()[0]
        log.error("MODBUS Error H:{} P:{} e:{}".format(classicHost, classicPort, e))
        try:
            modbusClient.close()
            isConnected = False

        except:
            log.error("MODBUS Error on close H:{} P:{}".format(classicHost, classicPort))

        return {}

    log.debug("Got data from Classic at {}:{}".format(classicHost,classicPort))

    #Iterate over them and get the decoded data all into one dict
    decoded = {}
    for index in theData:
        decoded = {**dict(decoded), **dict(doDecode(index, getDataDecoder(theData[index])))}

    return decoded
Пример #32
0
class PLC:

    # Method: Constructor
    # Description: Initializes the PLC device
    # Arguments: self: Initialized PLC object
    #            a: String IP address of HMI
    #            p: Integer port number to communicate with the HMI
    #            i: Float Initial value of PLC device
    #            t: List of float Threshold value at which the device will fail
    #            v: Integer Variance value
    # Returns: PLC object of initialized PLC Device
    def __init__(self, a, p, s):
        print "Client IP: %s Port: %s" % (a, p)
        self.client = ModbusTcpClient(a, port=p)
        self.status_reg_num = s

    # Method: Connect
    # Description: Connects PLC device with HMI
    # Arguments: self: Initialized PLC object
    # Returns: Void
    def connect(self):
        connected = False
        while not connected:
            try:
                connected = self.client.connect()
            except Exception as e:
                print "Connection Error %s" % e
                time.sleep(30)

    # Method: Disconnect
    # Description: Disconnects PLC device from HMI
    # Arguments: self: Initialized PLC object
    # Returns: Void
    def disconnect(self):
        self.client.close()
        sys.exit(0)

    # Method: Read Register
    # Description: Modbus Read register request
    # Arguments: Reg: Modbus connection between PLC device and HMI Server
    #            ID: integer id number of device
    # Returns: Integer value of register requested
    def read_reg(self, reg_num):
        return int(
            self.client.read_holding_registers(int(reg_num)).registers[0])

    # Method: Write Register
    # Description: Modbus Write register request
    # Arguments: Reg: Modbus connection between PLC device and HMI Server
    #            ID: integer id number of device
    #            Value: integer value to write to register
    # Returns: void
    def write_reg(self, reg_num, value):
        print "Reg Num: %s Value: %s" % (reg_num, value)
        self.client.write_register(reg_num, value)

    def status(self):
        return False if hex(self.read_reg(
            self.status_reg_num)) == "0xffff" else True
Пример #33
0
class Plc:
    def __init__(self,ip = "", port = ""):
        self.ip = ip
        self.port = port
        self.device = None
        self.connected = False



    def connect(self,ui=None):
        try:
            self.device = ModbusTcpClient(self.ip, self.port)
            self.device.connect()
            tc_values = self.device.read_holding_registers(40, 10, unit=0)
            assert(tcValues.function_code < 0x80)
            self.connected = True
            if ui:
                ui.plc_connection_button.setStyleSheet("background-color: rgb(78, 154, 6)")
                ui.plc_connection_button.setText(f"CONNECTED TO \nPLC")
            return 0
        except Exception as error:
            if ui:
                ui.plc_connection_button.setStyleSheet("background-color: rgb(255, 85, 0)")
                ui.plc_connection_button.setText(f"NOT CONNECTED TO \nPLC...")
            self.connected = False
            #print("Connection to PLC error : ", error)
            return 1

    def measure(self,ui = None, simu_mode=False):
        '''
        Measure and return teperature values in a tuple
        '''
        if not simu_mode:
            try:
                if not self.connected:
                    self.connect()
                tc_values = self.device.read_holding_registers(40, 10, unit=0)
                assert(tc_values.function_code < 0x80)  # test that there is not an error
                return [temperature for temp in tc_values]

            except Exception as error:
                print("Couldn't get temperatures : ", error)
                return [i*2 for i in range(10)]
        else:
            print(f"simu_mode is {simu_mode}")
            return [i*2 for i in range(10)]
Пример #34
0
def readModbus(host, port, address, registers, roundingFactor):
    client = ModbusTcpClient(host, port)
    metrics = client.read_holding_registers(address, registers, unit=0x1)
    result = []
    for res in metrics.registers:
        result.append(round(res * roundingFactor, 2))
    client.close()

    return result
Пример #35
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
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..."
Пример #37
0
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()
Пример #38
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))
Пример #39
0
def single_client_test(host, cycles):
    ''' Performs a single threaded test of a synchronous
    client against the specified host

    :param host: The host to connect to
    :param cycles: The number of iterations to perform
    '''
    logger = log_to_stderr()
    logger.setLevel(logging.DEBUG)
    logger.debug("starting worker: %d" % os.getpid())

    try:
        count  = 0
        client = ModbusTcpClient(host)
        while count < cycles:
            result = client.read_holding_registers(10, 1).getRegister(0)
            count += 1
    except: logger.exception("failed to run test successfully")
    logger.debug("finished worker: %d" % os.getpid())
Пример #40
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]
Пример #41
0
def readMBholdingregisters(clientIP, register, number=1):
    from pymodbus.client.sync import ModbusTcpClient, ConnectionException

    client = ModbusTcpClient(clientIP)
    values = []
    try:
        rawresult = client.read_holding_registers(register, number)
    except ConnectionException:
        # print('we were unable to connect to the host')
        statuscode = 7
    else:
        # print(rawresult)
        try:
            resultregisters = rawresult.registers
        except AttributeError:
            statuscode = rawresult.exception_code
        else:
            statuscode = 0
            values = resultregisters
    client.close()
    result = {'message': messagefrommbstatuscode(statuscode), 'statuscode': statuscode, 'values':values}
    return result
class SchneiderOTBSwitch(ChimeraObject, Switch):
    __config__ = {"device": None,
                  "output": 6,  # Which output to switch on/off
                  "switch_timeout": None,  # Maximum number of seconds to wait for state change
                  }

    def __init__(self):
        super(SchneiderOTBSwitch, self).__init__()

    def __start__(self):
        self.client = ModbusTcpClient(self["device"])

    def _getOTBstate(self):
        return self.client.read_holding_registers(100).getRegister(0)

    def _setOTBstate(self, state):
        self.client.write_register(100, state)
        return True

    def switchOn(self):
        if not self.isSwitchedOn():
            if self._setOTBstate(self._getOTBstate() + (1 << self['output'])):
                self.switchedOn()
                return True
            else:
                return False

    def switchOff(self):
        if self.isSwitchedOn():
            if self._setOTBstate(self._getOTBstate() - (1 << self['output'])):
                self.switchedOff()
                return True
            else:
                return False

    def isSwitchedOn(self):
        return self._getOTBstate() & 1 << self['output'] != 0
Пример #43
0
rr = client.read_coils(1,1)
assert(rq.function_code < 0x80)     # test that we are not an error
assert(rr.bits[0] == True)          # test the expected value

rq = client.write_coils(1, [True]*8)
rr = client.read_coils(1,8)
assert(rq.function_code < 0x80)     # test that we are not an error
assert(rr.bits == [True]*8)         # test the expected value

rq = client.write_coils(1, [False]*8)
rr = client.read_discrete_inputs(1,8)
assert(rq.function_code < 0x80)     # test that we are not an error
assert(rr.bits == [True]*8)         # test the expected value

rq = client.write_register(1, 10)
rr = client.read_holding_registers(1,1)
assert(rq.function_code < 0x80)     # test that we are not an error
assert(rr.registers[0] == 10)       # test the expected value

rq = client.write_registers(1, [10]*8)
rr = client.read_input_registers(1,8)
assert(rq.function_code < 0x80)     # test that we are not an error
assert(rr.registers == [17]*8)      # test the expected value

arguments = {
    'read_address':    1,
    'read_count':      8,
    'write_address':   1,
    'write_registers': [20]*8,
}
rq = client.readwrite_registers(**arguments)
Пример #44
0
The following is an quick performance check of the synchronous
modbus client.
'''
#---------------------------------------------------------------------------# 
# import the necessary modules
#---------------------------------------------------------------------------# 
from pymodbus.client.sync import ModbusTcpClient
from time import time

#---------------------------------------------------------------------------# 
# initialize the test
#---------------------------------------------------------------------------# 
client = ModbusTcpClient('127.0.0.1')
count  = 0
start  = time()
iterations = 10000

#---------------------------------------------------------------------------# 
# perform the test
#---------------------------------------------------------------------------# 
while count < iterations:
    result = client.read_holding_registers(10, 1, 0).getRegister(0)
    count += 1

#---------------------------------------------------------------------------# 
# check our results
#---------------------------------------------------------------------------# 
stop = time()
print "%d requests/second" % ((1.0 * count) / (stop - start))

Пример #45
0
class Handler(object):
    def __init__(self,a,a2,canvas, samples_no=1):    
        self.btnLog = builder.get_object("btnLog")    
        self.txtCommentBuffer = builder.get_object("txtCommentBuffer")
        self.dlgComments = builder.get_object("dlgComments")
        self.samples_no = samples_no
        self.loop_no = 0
        self.volume = 0
        self.elapsed = 0
        self.lastTick = None
        self.thisTick = None        
        self.loop = None
        self.listP1 = []
        self.reg104_1 = None
        self.low1, self.high1 = a_low, a_high # danzi.tn@20160728 current as nanoampere nA - analogic values
        self.low2, self.high2 = a_low, a_high # danzi.tn@20160728 current as nanoampere nA - analogic values
        self.low_p1, self.high_p1 = p_low, p_high # danzi.tn@20160728 pressure range (P in bar/10)
        self.low_q1, self.high_q1 = q_low, q_high # danzi.tn@20160728 flow-rate range (Q in lit/min/10)
        self.low_p2, self.high_p2 = p_low, p_high # danzi.tn@20160728 pressure range (P in bar/10)
        self.low_q2, self.high_q2 = q_low, q_high # danzi.tn@20160728 flow-rate range (Q in lit/min/10)

        self.p1_fit = np.polyfit([self.low1, self.high1],[self.low_p1, self.high_p1],1)
        self.p1_func = np.poly1d(self.p1_fit)
        #   Conversion from current (mA) to flow-rate (lit/min)
        self.q1_fit = np.polyfit([self.low1, self.high1],[self.low_q1, self.high_q1],1)
        self.q1_func = np.poly1d(self.q1_fit)    
        
        self.p2_fit = np.polyfit([self.low2, self.high2],[self.low_p2, self.high_p2],1)
        self.p2_func = np.poly1d(self.p2_fit)
        #   Conversion from current (mA) to flow-rate (lit/min)
        self.q2_fit = np.polyfit([self.low2, self.high2],[self.low_q2, self.high_q2],1)
        self.q2_func = np.poly1d(self.q2_fit)    
        
        self.ret_m1 = False
        self.ret_m2 = False
        self.ret_p = False
        self.afigure = a
        self.afigure2 = a2
        self.afigure3 = a3
        self.canvas = canvas
        self._bufsize = x_size
        self.databuffer_p1 = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_p2 = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_q1 = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_q2 = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_q_max = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_q_out = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.x = range(x_size)
        self.line_p1, = self.afigure3.plot(self.x, self.databuffer_p1,"b-", label='P1(An./Eng.)')
        self.line_p2, = self.afigure.plot(self.x, self.databuffer_p2,"m-", label='Pmax')
        self.line_q2, = self.afigure.plot(self.x, self.databuffer_q2,"g-",  label='Pout')
        self.line_q1, = self.afigure3.plot(self.x, self.databuffer_q1,"r-",  label='Q1(An./Eng.)')
        self.line_qmax, = self.afigure2.plot(self.x, self.databuffer_q1,"y-",  label='Qmax')
        self.line_qout, = self.afigure2.plot(self.x, self.databuffer_q1,"k-",  label='Qout')

        h1, l1 = a.get_legend_handles_labels()
        h2, l2 = a2.get_legend_handles_labels()
        h3, l3 = a3.get_legend_handles_labels()
        self.afigure.legend(h1+h2+h3, l1+l2+l3, loc=2, ncol=3, fontsize=10)
        self.pmax = 0
        self.qmax = 0
        self.blogFile = False
        self.oneLogged = False
        self.pipeLength = 0.0
        self.pipeDiam  = 0.0
        self.pipeType  = "ND"
        self.mixType  = "ND"
        self.mixDensity  = 0.0
        self.staticHead = 0.0
        self.treeview2  = builder.get_object("treeview2")
        self.p_count = 0
        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Name", renderer, text=0)
        self.treeview2.append_column(column)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Description", renderer, text=1)
        self.treeview2.append_column(column)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Value", renderer, text=2)
        self.treeview2.append_column(column)

        self.adjustPMax = builder.get_object("adjustment1")
        self.adjustQMax = builder.get_object("adjustment2")
        self.txtMongoConnection = builder.get_object("txtMongoConnection")
        self.lstPumps = builder.get_object("lstPumps")
        self.lstMan1 = builder.get_object("lstMan1")
        self.lstMan2 = builder.get_object("lstMan2")
        self.lblDbMesg = builder.get_object("lblDbMesg")
        
        self.btnFolder = builder.get_object("btnFolder")
        self.txtOutFolder = builder.get_object("txtOutFolder")
        self.chkAnalogic =  builder.get_object("chkAnalogic")
        self.btnFolder.connect("clicked", self.on_btnFolder_clicked)
        self.time = datetime.datetime.utcnow()
        self.sMongoDbConnection = ""
        self.mongo_CLI = None
        self.mongodb = None
        self.outputFolder = None
        self.export_csv_path = None
        self.lblAnalyzed = builder.get_object("lblAnalyzed")
        self.parentWindow =  builder.get_object("windowMain")
        if smtConfig.has_option('Mongodb','Connectionstring'):
            self.txtMongoConnection.set_text(smtConfig.get('Mongodb', 'Connectionstring'))

    def on_btnFolder_clicked(self, widget):
        dialog = Gtk.FileChooserDialog("Please choose an output folder", self.parentWindow,
                                       buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,"Select", Gtk.ResponseType.OK))
        dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
        dialog.set_default_size(600, 400)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            print("Select clicked")
            print("Folder selected: " + dialog.get_filename())
            self.outputFolder =  dialog.get_filename()
            self.export_csv_path = os.path.join(self.outputFolder,"test_{0}.csv".format(datetime.datetime.utcnow().strftime("%Y%m%d%H%M%S")))
            self.txtOutFolder.set_text( dialog.get_filename())
            if not smtConfig.has_section('Output'):
                smtConfig.add_section('Output')
            smtConfig.set('Output', 'Folder', self.outputFolder)        
            with open(sCFGName, 'wb') as configfile:
                smtConfig.write(configfile)
        elif response == Gtk.ResponseType.CANCEL:
            print("Cancel clicked")

        dialog.destroy()
        
        
    def on_txtMongoConnection_changed(self,txtEdit):
       pass

    def on_btnDatabase_clicked(self,btn):
        self.sMongoDbConnection = self.txtMongoConnection.get_text()
       
        splitted = self.sMongoDbConnection.split("@")
        mongo_database = splitted[0]        
        splitted = splitted[1].split(":")
        mongo_host = splitted[0]
        mongo_port = splitted[1]
        self.mongo_CLI = MongoClient(mongo_host, int(mongo_port))
        self.mongodb = self.mongo_CLI[mongo_database]
        self.lstPumps.clear()
        self.lstMan2.clear()
        self.lstMan1.clear()
        projs =[]
        self.lblDbMesg.set_label("")
        try:
            projs = list(self.mongodb.projects.find({}))
        except pyErrors.ServerSelectionTimeoutError as timeouterr:
            self.lblDbMesg.set_label(str(timeouterr))
            logApp.debug("Database error = {0}".format(str(timeouterr)))
        if len(projs) > 0:
            if not smtConfig.has_section('Mongodb'):
                smtConfig.add_section('Mongodb')
            smtConfig.set('Mongodb', 'Connectionstring', self.sMongoDbConnection)        
            with open(sCFGName, 'wb') as configfile:
                smtConfig.write(configfile)
            gePumps = self.mongodb.groutingequipments.find({"type":"P"})
            geManifolds = self.mongodb.groutingequipments.find({"type":"M"})
            for p in gePumps:
                self.lstPumps.append([p["ipAddress"], int(p["TCPPort"]),"{0}.{1}({2}:{3})".format(p["type"],p["code"],p["ipAddress"],p["TCPPort"])])
            for p in geManifolds:
                self.lstMan2.append([p["ipAddress"], int(p["TCPPort"]),"{0}.{1}({2}:{3})".format(p["type"],p["code"],p["ipAddress"],p["TCPPort"])])
                self.lstMan1.append([p["ipAddress"], int(p["TCPPort"]),"{0}.{1}({2}:{3})".format(p["type"],p["code"],p["ipAddress"],p["TCPPort"])])
            btn.set_label("DB Connected")
            logApp.debug("Database Connected")
        else:
            btn.set_label("DB Connect")
            self.lblDbMesg.set_label("Database {0} is empty".format(mongo_database))
            logApp.debug("Database {0} is empty".format(mongo_database))
            

    def on_cmbPumps_changed(self,cmb):
        tree_iter = cmb.get_active_iter()
        if tree_iter != None:
            model = cmb.get_model()
            ip = model[tree_iter][0]
            port = model[tree_iter][1]
            builder.get_object("txtIPPump").set_text(ip)
            builder.get_object("txtPortPump").set_text(str(port))
        
    def on_cmbMan1_changed(self,cmb):
        tree_iter = cmb.get_active_iter()
        if tree_iter != None:
            model = cmb.get_model()
            ip = model[tree_iter][0]
            port = model[tree_iter][1]
            builder.get_object("txtIP1").set_text(ip)
            builder.get_object("txtPort1").set_text(str(port))
        
        
    def on_cmbMan2_changed(self,cmb):
        tree_iter = cmb.get_active_iter()
        if tree_iter != None:
            model = cmb.get_model()
            ip = model[tree_iter][0]
            port = model[tree_iter][1]
            builder.get_object("txtIP2").set_text(ip)
            builder.get_object("txtPort2").set_text(str(port))
            
            
    def logging_data(self, a):
        self.loop_no += 1        
        builder.get_object("levelbar1").set_value(len(self.listP1)%60+1)
        # print "1.1 {0}".format(t1)
        txtPout = a[11]
        txtQout = a[12]
        aIN1 = a[2]
        aIN2 = a[3]
        aIN1ENG = a[4]
        aIN2ENG = a[5]
        pDeltaPump = a[8]
        qDeltaPump = a[9]
        # print "1.2 {0}".format(t1)
        # QUI CAPITA Unhandled error in Deferred quando si perde la connessione- provare un try except e saltare il campione
        try:
            okC1 = self.client_1.connect()
            if okC1:
                rr1 = self.client_1.read_holding_registers(0,48)
            else:
                logApp.error("logging_data connection to manifold 1 failed")
                aIN1.set_text("CONNECTION ERROR")
                aIN2.set_text("CONNECTION ERROR")
                aIN1ENG.set_text("CONNECTION ERROR")
                aIN2ENG.set_text("CONNECTION ERROR")
                return False
        except:
                logApp.error("Unhandled error in Deferred - logging_data connection to manifold 1 failed")
                print "1.3 {0}".format(t1)
                aIN1.set_text("Unhandled ERROR")
                aIN2.set_text("Unhandled ERROR")
                aIN1ENG.set_text("Unhandled ERROR")
                aIN2ENG.set_text("Unhandled ERROR")
                return False
        
        # logApp.debug("logging_data 3 read_holding_registers 2 ok")
        # print "3 {0}".format(t1)
        self.client_1.close()
        if rr1.registers[test_reg_no] == test_value_1 or rr1.registers[test_reg_no] == test_value_2:
            # Manifold 1
            p_mA1 = rr1.registers[4-1]
            q_mA1 = rr1.registers[6-1]
            q_Sign = 0
            if  rr1.registers[test_reg_no] == test_value_2:
                q_Sign = rr1.registers[12-1]
            # save value into databuffer            
            for iprog in range(12):
                logApp.info("Manifold registers[{0}] = {1}".format(iprog+1, rr1.registers[iprog]))
            t1=datetime.datetime.utcnow()
            # logApp.debug("logging_data 1")
            dt_seconds = (t1-self.time).seconds

            
            # convert ANALOGIC to Digital
            p_Eng1 = self.p1_func(p_mA1)
            q_Eng1 = self.q1_func(q_mA1)
            if q_Sign:
                q_Eng1 = -1.*q_Eng1
            pEng1Display = p_Eng1/10.
            qEng1Display = q_Eng1/10.
            self.thisTick = datetime.datetime.utcnow()            
            dV = 0.0
            if self.lastTick:
                dT = self.thisTick - self.lastTick
                self.elapsed = dT.total_seconds()
                dV = qEng1Display / 60 * self.elapsed
                self.volume += dV
                #print "total_seconds = " , dT.total_seconds()
                #print "qEng1Display = " , qEng1Display
                #print "dV = " , dV
                #print "volume = ", self.volume
                builder.get_object("txtVolume").set_text("{0:.2f} lit".format(self.volume))

            self.lastTick = self.thisTick            
            
            
            
            # display del valore analogico se chkAnalogic è selezionato
            if self.chkAnalogic.get_active():
                self.databuffer_p1.append( p_mA1 )
                self.afigure3.set_ylim(a_low, a_high)
                self.afigure3.set_ylabel('Voltage (mV)')
            else:
                self.databuffer_p1.append( pEng1Display )
                self.afigure3.set_ylim(-10, 80)
                self.afigure3.set_ylabel('Eng Values')
            self.line_p1.set_ydata(self.databuffer_p1)  
            
            # display del valore analogico se chkAnalogic è selezionato
            if self.chkAnalogic.get_active():
                self.databuffer_q1.append( q_mA1 )
            else:
                self.databuffer_q1.append( qEng1Display )
            self.line_q1.set_ydata(self.databuffer_q1)
            
            self.listP1.append(p_Eng1/10.)
            aIN1.set_text(str(p_mA1))
            aIN2.set_text(str(q_mA1))
            aIN1ENG.set_text("{0} bar".format(pEng1Display ))
            aIN2ENG.set_text("{0} lit/min".format(qEng1Display))
            # INIETTORE
            #print "4 {0}".format(t1)
            if self.client_p:
                rr_p = self.client_p.read_holding_registers(500,100,unit=1)
                # print "5 {0}".format(t1)
                txtPout.set_text("{0} bar".format(rr_p.registers[16]))
                txtQout.set_text("{0} s/min {1:.2f} l/min".format(rr_p.registers[20], litCiclo*rr_p.registers[20] ))
                self.pmax = rr_p.registers[60]
                self.qmax = rr_p.registers[62]            
                self.adjustPMax.set_value(float(self.pmax) )
                self.adjustQMax.set_value(float(self.qmax))
                builder.get_object("txtPmax").set_text("{0} bar".format(rr_p.registers[60]))
                builder.get_object("txtQmax").set_text("{0} s/min {1:.2f} l/min".format(rr_p.registers[62], litCiclo*rr_p.registers[62]))
                self.pDeltaP = self.pmax - rr_p.registers[16]
                self.qDeltaP = self.qmax - rr_p.registers[20]
                self.databuffer_q_max.append(self.qmax*litCiclo)
                self.databuffer_q_out.append(rr_p.registers[20]*litCiclo)
                self.databuffer_q2.append(rr_p.registers[16] )
                self.databuffer_p2.append( self.pmax )          
                self.line_p2.set_ydata(self.databuffer_p2)
                self.line_q2.set_ydata(self.databuffer_q2)
                self.line_qout.set_ydata(self.databuffer_q_out)
                self.line_qmax.set_ydata(self.databuffer_q_max)
                
                pDeltaPump.set_text("{0} bar".format(self.pDeltaP ))
                qDeltaPump.set_text("{0} s/min {1:.2f} l/min".format(self.qDeltaP, self.qDeltaP*litCiclo ))            
                self.p_count += 1
                rr_p.registers[50] = self.p_count
                self.client_p.write_registers(500,rr_p.registers,unit=1)
            
            self.afigure.relim()
            self.afigure.autoscale_view(False, False, True)
            self.afigure2.relim()
            self.afigure2.autoscale_view(False, False, True)
            self.afigure3.relim()
            self.afigure3.autoscale_view(False, False, True)
            self.canvas.draw()            
            if self.blogFile:
                self.oneLogged = True
                # TODO btnLog set label
                # time now - before
                self.btnLog.set_label("{0}".format(datetime.timedelta(seconds =dt_seconds)))
                log.info("%d;%f;%d;%f;%f;%f" % (p_mA1, p_Eng1, q_mA1, q_Sign, q_Eng1,self.elapsed,self.volume))
            # print "6 {0}".format(t1)
            logApp.debug("logging_data terminated successfully")      
        else:
            logApp.error( "error on test data {0}-{1} vs {2}".format(test_value_1,test_value_2,rr1.registers[test_reg_no]))
            return False
        return True


    def onDeleteWindow(self, *args):
        Gtk.main_quit(*args)

    def testConnection1(self, button):
        lblTest1 = builder.get_object("lblTest1")
        manifold_host_1 = builder.get_object("txtIP1").get_text()
        manifold_port_1 = int(builder.get_object("txtPort1").get_text())
        self.client_1 = ModbusClient(manifold_host_1, port=manifold_port_1)
        self.ret_m1=self.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:
            logApp.debug("connection to manifold #1 ({0}:{1}) succedeed".format(manifold_host_1,manifold_port_1))
            rr1_103 = self.client_1.read_holding_registers(103,10)
            self.reg104_1 = tuple(rr1_103.registers )
            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)
	else:
            logApp.debug("connection to manifold #1 ({0}:{1}) failed".format(manifold_host_1,manifold_port_1))
	self.client_1.close()


    def on_btnConnectPump_clicked(self, button):
        lblTestPump = builder.get_object("lblTestPump")
        pump_host = builder.get_object("txtIPPump").get_text()
        pump_port = int(builder.get_object("txtPortPump").get_text())
        self.client_p = ModbusClient(pump_host, port=pump_port)
        self.ret_p=self.client_p.connect()
        lblTestPump.set_text(str(self.ret_p))
        if not smtConfig.has_section('Pump'):
            smtConfig.add_section('Pump')
        if self.ret_p:
            builder.get_object("btnShow").set_sensitive(True)
            logApp.debug("connection to Pump ({0}:{1}) succedeed".format(pump_host,pump_port))            
            self.checkPump(self.client_p)
            smtConfig.set('Pump', 'host', pump_host)
            smtConfig.set('Pump', 'port', pump_port)
            with open(sCFGName, 'wb') as configfile:
                smtConfig.write(configfile)
	else:
            builder.get_object("btnShow").set_sensitive(False)
            logApp.debug("connection to Pump ({0}:{1}) failed".format(pump_host,pump_port))
        self.client_p.close()


    def checkPump(self,client_p):
        self.p_count += 1
        rq = client_p.write_register(550,self.p_count,unit=1)
        if rq.function_code < 0x80:
            rr_p = client_p.read_holding_registers(500,100,unit=1)
            if len(rr_p.registers)==100 and rr_p.registers[0]==self.p_count:
                decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[2:7],endian=Endian.Little)
                # 502
                bits_502 = decoder.decode_bits()
                bits_502 += decoder.decode_bits()
                # 503
                bits_503 = decoder.decode_bits()
                bits_503 += decoder.decode_bits()
                # 504
                bits_504 = decoder.decode_bits()
                bits_504 += decoder.decode_bits()
                # 505
                bits_505 = decoder.decode_bits()
                bits_505 += decoder.decode_bits()
                # 506
                bits_506 = decoder.decode_bits()
                bits_506 += decoder.decode_bits()
                if bits_502[7]:
                    builder.get_object("switchPumpStatus").set_active(True)
                else:
                    builder.get_object("switchPumpStatus").set_active(False)

                if bits_502[4] == False and bits_502[10] == True:
                    builder.get_object("switchPumpStatus").set_sensitive(True)
                else:
                    builder.get_object("switchPumpStatus").set_sensitive(False)                
        self.setPumpFlowAndPressure()


    def on_btnOpenFile_clicked(self,button):
        #os.system()
        subprocess.call(["libreoffice",self.export_csv_path])


    def setPumpFlowAndPressure(self):
        if self.ret_p:
            rr_p = self.client_p.read_holding_registers(500,100,unit=1)
            self.p_count += 1
            rr_p.registers[50] = self.p_count
            rr_p.registers[60] = int(self.pmax)
            rr_p.registers[62] = int(self.qmax)
            rr_p = self.client_p.write_registers(500,rr_p.registers,unit=1)
        

    def on_btnOff_clicked(self,button):
        print("Closing application")

	logApp.debug("HDLF GUI CLOSING")
        Gtk.main_quit()

    def storeHDLF(self):
        self.pipeLength = float(builder.get_object("txtPipeLenght").get_text())
        self.pipeDiam  =  float(builder.get_object("txtPipeDiam").get_text())
        self.pipeType  = builder.get_object("txtPipeType").get_text()
        self.mixType  = builder.get_object("txtMixType").get_text()
        self.mixDensity  =  float(builder.get_object("txtMixDensity").get_text())
        self.staticHead = float(builder.get_object("txtStaticHead").get_text())
        if not smtConfig.has_section('HeadLossFactor'):
            smtConfig.add_section('HeadLossFactor')
        smtConfig.set('HeadLossFactor', 'pipeLength', self.pipeLength)
        smtConfig.set('HeadLossFactor', 'pipeDiam', self.pipeDiam)
        smtConfig.set('HeadLossFactor', 'pipeType', self.pipeType)
        smtConfig.set('HeadLossFactor', 'mixType', self.mixType)
        smtConfig.set('HeadLossFactor', 'mixDensity', self.mixDensity)
        smtConfig.set('HeadLossFactor', 'staticHead', self.staticHead)
        with open(sCFGName, 'wb') as configfile:
            smtConfig.write(configfile)
        

    def on_btnLog_toggled(self,button):
        if button.get_active():
            self.time = datetime.datetime.utcnow()
            self.blogFile = True
            self.volume = 0
            self.elapsed = 0
        else:
            self.blogFile = False
            builder.get_object("btnLog").set_label("Log Data")


    def on_switchPumpStatus_state_set(self, switch,gparam):
        self.ret_p=self.client_p.connect()
        rr = self.client_p.read_holding_registers(500,100,unit=1)
        # conversione in bit array da 552
        decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[52:53],endian=Endian.Little)
        bits_552 = decoder.decode_bits()
        bits_552 += decoder.decode_bits()

        decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[2:7],endian=Endian.Little)
        # 502
        bits_502 = decoder.decode_bits()
        bits_502 += decoder.decode_bits()
        # 503
        bits_503 = decoder.decode_bits()
        bits_503 += decoder.decode_bits()
        # 504
        bits_504 = decoder.decode_bits()
        bits_504 += decoder.decode_bits()
        # 505
        bits_505 = decoder.decode_bits()
        bits_505 += decoder.decode_bits()
        # 506
        bits_506 = decoder.decode_bits()
        bits_506 += decoder.decode_bits()
        bSendCommand = False
        if switch.get_active():
            # %MW552:X2 START INIET. DA REMOTO
            bSendCommand = not bits_502[7]
            bits_552[2] = True
            bits_552[3] = False
            bits_552[14] = True
        else:
            # %MW552:X2 STOP INIET. DA REMOTO
            bSendCommand = bits_502[7]
            bits_552[2] = False
            bits_552[3] = True
            bits_552[14] = False
        builder = BinaryPayloadBuilder(endian=Endian.Little)
        # builder.add_bits(bits_502)
        builder.add_bits(bits_552)
        reg_552 = builder.to_registers()
        rr.registers[52:53] = reg_552
        self.p_count += 1
        rr.registers[50] = self.p_count
        if bSendCommand:
            self.client_p.write_registers(500, rr.registers,unit=1)
        self.client_p.close()

    def on_btnShow_clicked(self,button):
        # show dlgRegistries
        self.lstDialog = builder.get_object("dlgRegistries")
        self.liststore = builder.get_object("liststore1")
        if not self.ret_p:
            self.ret_p = self.client_p.connect()
        if self.ret_p:
            self.liststore.clear()
            rr = self.client_p.read_holding_registers(500,100,unit=1)
            for idx in [0,2,4,6,12,13,14,15,16,20,50,52,60,62]:
                if idx in (2,4,6,52):
                    decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[idx:idx+1],endian=Endian.Little)
                    bits = decoder.decode_bits()
                    bits += decoder.decode_bits()
                    for ib, b in enumerate(bits):
                        if b:
                            sCode = "%MW5{0:02d}:X{1}".format(idx,ib)
                            self.liststore.append([sCode,reg_descr[sCode], str( b ) ])
                else:
                    sCode = "%MW5{0:02d}".format(idx)
                    self.liststore.append([sCode, reg_descr[sCode], str( rr.registers[idx]) ])    
        response = self.lstDialog.run()

        self.lstDialog.hide()

    def on_btnOk_clicked(self,button):
        self.lstDialog.close()

    def on_btnOKComments_clicked(self, button):
        self.dlgComments.close()

    def on_btnComments_clicked(self, button):
        # self.parentWindow
        response = self.dlgComments.run()        
        self.dlgComments.hide()

    def on_btnVolume_clicked(self, button):
        self.volume = 0
        self.elapsed = 0
    
    def on_chkAnalogic_toggled(self,chk):
        if chk.get_active():
            logApp.info( "on_chkAnalogic_toggled toggled Active" ) #
        else:
            logApp.info( "on_chkAnalogic_toggled toggled Inactive" )

    def on_spinPMax_value_changed(self,spin):
        self.pmax = int(spin.get_value())
        self.setPumpFlowAndPressure()
        
    def on_spinQMax_value_changed(self,spin):
        self.qmax = int(spin.get_value())
        self.setPumpFlowAndPressure()

    def on_switchMain_activate(self, switch,gparam):
        
        self.lblAnalyzed.set_label("...")
        if switch.get_active():
            self.listP1 = []
            self.export_csv_path = os.path.join(self.outputFolder,"test_{0}.csv".format(datetime.datetime.utcnow().strftime("%Y%m%d%H%M%S")))            
            file_handler = logging.handlers.RotatingFileHandler(self.export_csv_path, maxBytes=5000000,backupCount=5)
            file_handler.setLevel(logging.INFO)
            formatter = logging.Formatter('%(asctime)s;%(message)s')
            file_handler.setFormatter(formatter)
            if len(log.handlers) > 0:
                log.handlers[0] = file_handler
            else:    
                log.addHandler(file_handler)
            log.info("p_mA1;p_Eng1;q_mA1;q_Sign;q_Eng1;elapsed;volume")
            self.client_1 = ModbusClient(manifold_host_1, port=manifold_port_1)
            self.client_p = None
            if self.ret_p:
                self.client_p = ModbusClient(pump_host, port=pump_port)
                #self.client_1.connect()
                self.ret_p = self.client_p.connect()
                time.sleep(1.5)
                print "start connection with Pump"
            time_delay = 1./float(self.samples_no) # 1 seconds delay
            self.loop = LoopingCall(f=self.logging_data, a=(self.client_1,None, builder.get_object("txtAIN1"),builder.get_object("txtAIN2"),builder.get_object("txtAIN1ENG"),builder.get_object("txtAIN2ENG"),None,None,builder.get_object("txtAIN1ENG2"),builder.get_object("txtAIN2ENG2"),self.client_p,builder.get_object("txtPout"),builder.get_object("txtQout")))
            print "LoopingCall  created"
            self.loop.start(time_delay, now=False) # initially delay by time
            print "loop started"
            builder.get_object("txtFilePath").set_text("")
            builder.get_object("btnOpenFile").set_sensitive(False)
            builder.get_object("btnOff").set_sensitive(False)
            # self.ani = animation.FuncAnimation(self.figure, self.update_plot, interval = 1000)
        else:
            self.loop.stop()
            time.sleep(1)
            #self.client_1.close()
            if self.ret_p:
                self.client_p.close()
                print "stop connection with Pump"
            time.sleep(1)
            builder.get_object("txtFilePath").set_text(self.export_csv_path)
            builder.get_object("btnOpenFile").set_sensitive(True)
            builder.get_object("btnOff").set_sensitive(True)
Пример #46
0
class ModbusFB(FunctionalBlock):
    DP_01 = dict(name="reg_1", access="input", dptId="7.xxx", default=0)
    DP_02 = dict(name="reg_2", access="input", dptId="7.xxx", default=0)
    DP_03 = dict(name="reg_3", access="output", dptId="7.xxx", default=0)

    GO_01 = dict(dp="reg_1", flags="CRWU", priority="low")
    GO_02 = dict(dp="reg_2", flags="CRWU", priority="low")
    GO_03 = dict(dp="reg_3", flags="CWTU", priority="low")

    DESC = "Modbus FB"

    def init(self):
        self._client = ModbusTcpClient(host=settings.MODBUS_HOST, port=settings.MODBUS_PORT)

    def _read(self, register):
        """

        @param register: name of the variable to read
        @type register: int

        @return: register value
        @rtype: int
        """
        self._client.connect()
        try:
            result = self._client.read_holding_registers(register, 1, unit=settings.MODBUS_UNIT)
            value = result.registers[0]
            return value
        finally:
            self._client.close()

    def _write(self, register, value):
        """

        @param var: name of the variable to read
        @type var: str
        """
        self._client.connect()
        try:
            self._client.write_register(register, value, unit=settings.MODBUS_UNIT)
        finally:
            self._client.close()

    @notify.datapoint(dp="reg_1", condition="change")
    @notify.datapoint(dp="reg_2", condition="change")
    @notify.datapoint(dp="reg_3", condition="change")
    def RegisterStateChanged(self, event):
        """ Method called when any of the 'reg_x' Datapoint change
        """
        logger.debug("%s: event=%s" % (self.name, repr(event)))

        dpName = event['dp']
        newValue = event['newValue']
        oldValue = event['oldValue']
        logger.info("%s: '%s' value changed from %s to %s" % (self.name, dpName, oldValue, newValue))

        # Send new register value to modbus client
        self._write(config.KNX_TO_MODBUS[dpName], newValue)

    @schedule.every(seconds=settings.MODBUS_REFRESH_RATE)
    def modbusRefresh(self):
        """ Read modbus output registers
        """
        for register, dp in config.MODBUS_TO_KNX.items():
            value = self._read(register)
            self.dp[dp].value = value
Пример #47
0
        while (not connected):
                resp = client.connect()
                if (resp == False):
                	sys.exit(1);
                	#time.sleep(10)
                else:
                        connected = 1
                count = count + 1


def close():
        global client
        client.close()

#main, pymodbus cant read more then 123 addresses at a time
rq = client.read_holding_registers(4100,120)
for x in range(0,120):
        reg= 4100 + x + 1 
        val = rq.registers[x]
        print(str(reg)+" "+str(val))

rq = client.read_holding_registers(4220,120)
for x in range(0,120):
        reg= 4220 + x + 1
        val = rq.registers[x]
        print(str(reg)+" "+str(val))

rq = client.read_holding_registers(16384,6)
for x in range(0,6):
        reg= 16385 + x + 1
        val = rq.registers[x]
Пример #48
0
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

host='25.7.11.1'
port=502
sleep_time=0.2;#in sec

try:
	print'Открываем соединение...'
	client = ModbusClient(host, port); print'Подключились к хосту',host
	client.connect(); print'Установили соединение'
	start_address = 0x00; regs=2;
	for i in range(2):
		print "."*20,"we are going to read now"
		rq = client.read_holding_registers(start_address,regs,unit=1)
		print
		
		print "MY OUTPUT:",i, rq.registers
		rq.registers[1]=rq.registers[1]+1;
		sleep(sleep_time)
		print "."*20,"we are going to write now"
		client.write_register(1,rq.registers[1],unit=1)
		print
		sleep(sleep_time)
		
except:
    print'ошибка!'

else:
    print'Всё хорошо.'
Пример #49
0
#!/usr/bin/env python

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

client=ModbusClient('192.168.0.125',port=502,framer=ModbusFramer)
connexion=client.connect()
print connexion
cnt=4 #nombre de registre
rr=client.read_holding_registers(0,cnt,unit=0x01)
time.sleep(2)
print rr

#tab=[]
#for i in range(0,cnt):
#   tab.append(rr.getRegister(i))
#print tab
#act = tab[0]+0.01*tab[1]
#react = tab[2]+0.01*tab[3]
#print 'Active energy: %10.2f' %act
#print 'Reactive energy: %10.2f' %react
client.close()
Пример #50
0
# -*- coding: utf-8 -*-
#!/usr/bin/env python
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
# INIETTORE
pump_host = '10.243.37.106' # 10.243.37.xx
pump_port = 502 # 502
client = ModbusClient(pump_host, port=pump_port)
ret_p=client.connect()
assert(ret_p==True)
default_550 = 2
rq = client.write_register(550,default_550,unit=1)
assert(rq.function_code < 0x80)
rr_p = client.read_holding_registers(500,100,unit=1)
assert(len(rr_p.registers)==100)
for idx, r in enumerate(rr_p.registers):
    print "MW5{0:02d}={1}".format(idx,r)
print rr_p.registers[0]
assert(rr_p.registers[0]==default_550) # registro 500 contiene quanto settato in 550
print "Pump register 500 = {0}".format(rr_p.registers[0])
client.close()
# CAVALLETTO 1
manifold_host = '10.243.37.8' # 10.243.37.xx
manifold_port = 502  # 502
client = ModbusClient(manifold_host, port=manifold_port)
ret_m=client.connect()
assert(ret_m==True)
rr_m = client.read_holding_registers(0,48)
assert(len(rr_m.registers)==48)
assert(rr_m.registers[0]==0x5200)
print "Manifold 1 first register {0}".format(rr_m.registers[0])
sIPAddr = "%d.%d.%d.%d" %  tuple(rr_m.registers[32-1:36-1])
Пример #51
0
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
# test connettività
host = '127.0.0.1'
port = 5020
test_reg_no = 0 # test the expected value (Machine ID, defaukt is 0x5100)  
test_value = 0x5100 # 20736
starting_register = 40001
client = ModbusClient(host, port=port)
try:
    client.connect()
    log.info("Connessione Modbus TCP a {0}:{1} effettuata".format(host,port))
    # scegliere registro e assert da verificare
    rr = client.read_holding_registers(starting_register,10)      
    if isinstance(rr ,ExceptionResponse):
        log.error("Errore su read_holding_registers {0}: {1}".format(starting_register,rr))
    else:
        log.info("{1} Regsitri letti {0}".format(rr.registers,len(rr.registers)))
        if rr.registers[test_reg_no] == test_value:   
            log.info("OK - Su registro {0} il valore {1} == {2}".format(test_reg_no,rr.registers[test_reg_no],test_value))
        else:
            log.error("Errore su registro {0}, valore {1} != {2}".format(test_reg_no,rr.registers[test_reg_no],test_value))
    client.close()    
    log.info("Chiusa la connessione Modbus TCP a {0}:{1}".format(host,port))
except ConnectionException as cex:
    log.error("Errore connessione Modbus TCP {1}:{2}. {0}".format(cex,host,port))
exit(-99)

Пример #52
0
class modbus():
####################################################################################################
#
#
#
#
#
####################################################################################################  
    def __init__(self, smarthome, device='', timeout=None, port=502, cycle=5, pe_adress = 0, pe_length= 0, pa_adress= 0, pa_length= 0):
        ##Initialdaten aus Plugin.conf
        self._sh = smarthome
        self._items = {}
        self.timeout = float(timeout)
        self.device = str(device)
        self.port = int(port)
        self.cycle = int(cycle)
        #Inputs
        self.pe_adress = int(pe_adress)
        self.pe_lenght = int(pe_length)
        #Outputs
        self.pa_adress = int(pa_adress)
        self.pa_lenght = int(pa_length)
        ######################################
        self._db = {}##ausgangsbytes
        self._db['in'] = {}
        self._db['out'] = {}
        #1: 	bool						0...1
        #5: 	8-bit signed value			0...255
        #5.001: 8-bit unsigned value		0...100
        #6: 	8-bit signed value			-128...127
        #7: 	16-bit unsigned value		0...65535
        #8: 	16-bit signed value			-32768...32767
        #9: 	floating point 				-671088,64 - 670760,96
        self._db['dpt'] = {1:1, 5:8, 5.001:8, 6:8, 7:16, 8:16}##dpt und länge in bits
        self.init_read = 0
        self._lock = threading.Lock()
        self.connected = False
        logger.info('Initialising Modbus TCP PLUGIN###############################################')
        smarthome.connections.monitor(self)
        
        
    def run(self):##plugin starten
        self.alive = True
        self._sh.scheduler.add('Modbus', self.refresh, cycle=self.cycle)
        logger.info('MODBUS: Started!')

    def stop(self):##plugin stoppen
        self.alive = False
        self._socket.close()
        logger.info('MODBUS: Stopped!')

    def parse_logic(self, logic):##nicht benoetigt
        pass

    def connect(self): #Verbinden/socket oeffnen
        self._lock.acquire()
        target = None
        try:
            if self.device is not None:
                self._modbuspy = ModbusTcpClient(self.device, self.port)
                self._modbuspy.connect()
        except Exception as e:
            logger.error('MODBUS: Could not connect to {}: {}'.format(self.device, e))
            self._lock.release()
            return
        else:
            
            logger.info('MODBUS: Connected to {}'.format(self.device))
            self.connected = True
            
            self._lock.release()

    def disconnect(self): #Verbindung trennen/socket schließen
        if self.connected:
            try:
                if self_socket is not None:
                   client.close()
            except:
                pass
            
            logger.info('MODBUS: Disconnected!')
            self.connected = False
            self._target = None
####################################################################################################
#HAUPTFUNKTION(main)
#Funktion wird zyklisch von Smarthome aufgerufen:
#
#
#
####################################################################################################    
    def refresh(self):
        logger.debug('MODBUS cycle started########################################################')
        if self.connected:
            if self.init_read == 0:                                                                 #1 start Ausgangsregister lesen
                self.read('out')
                self.init_read = 1
                pprint(self._db)
            
            start = time.time()
            werte = self.read()
            self.write()
            cycletime = time.time() - start
            logger.debug("Modbus cycle takes {0} seconds".format(cycletime))
        else:
            self.connect()#neu
            pass
####################################################################################################
#Items beim start überprüfen, auf modbus_on = 1
#Items Namen (gads) und Bytes werden peb und pab zugeordnet
#Bits werden in Bytes einsortiert
#
#
####################################################################################################
    def parse_item(self, item):
        
        if 'modbus_on' in item.conf:
            byte = int(item.conf['modbus_byte'])

            if 'modbus_bit' in item.conf:
                bit = int(item.conf['modbus_bit'])
            else:
               bit = None  
                                                                                                    ##Daten zusammenstellen
            daten = []
            daten.append(bit)                                                                       #0
            if 'modbus_dpt' in item.conf:
                daten.append(item.conf['modbus_dpt'])                                               #1
                daten.append(item())                                                                #2
            else:                                                                                   #oder
                daten.append(1)                                                                     #1
                daten.append(bool(item()))                                                          #2
                
            daten.append(item)                                                                      #3
            
            #pprint(daten)                                                                          #datensatz pro item 
            ##Unterscheidung in in/outputs
            if self.pe_adress <= byte <= (self.pe_adress+self.pe_lenght):                           ##INPUTS
                if not byte in self._db['in'].keys():
                    self._db['in'][byte] = []
                self._db['in'][byte].append(daten)
            elif self.pa_adress <= byte <= (self.pa_adress+self.pa_lenght):                         ##OUTPUTS
                if byte not in self._db['out'].keys():
                    self._db['out'][byte] = []
                self._db['out'][byte].append(daten)
        return None
####################################################################################################        
##Item hat sich verändert, wird von Smarthome aufgerufen, bei item(name, caller...)
##self._DB updaten!
#
#
#
####################################################################################################  
    def update_item(self, item, caller=None, source=None, dest=None):
        if caller == 'modbus':
            pass
####################################################################################################
#AusgangsWORTe an Steuerung schreiben
#
#
#
#
####################################################################################################  
    def write(self):
        try: 
            lb = 00000000
            hb = 00000000
            #### byte besteht immer aus 16 bits
            for byte in self._db['out']:
                for bit in sorted(self._db['out'][byte]):  
                    if bit in self._db['out'][byte]:
                        bitpos =    bit[0]                                                          #startbit/bitposition des binärwertes
                        type =      bit[1]
                        value =     bit[2]
                        name =      bit[3]
                        bit[2] =    bit[3]()                                                        ##aktueller wert des items abrufen und value updaten!
                        builder = BinaryPayloadBuilder(endian=Endian.Little)

                        ##unterscheidung dateityp
                        if type == '5' or type == '5.001' or type == '6' :                          ##8bit uint / int
                            length = 8
                            if bitpos < 8:  #lb
                                lb = value
                            else:           #hb
                                hb = value
                                
                            if type == '5':
                                builder.add_8bit_uint(lb)
                                builder.add_8bit_uint(hb)
                                #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) 
                            elif type == '5.001':                            ##0-100 in 0-255 umwandeln!
                                #print(dpts.en5001(lb))
                                #print(dpts.en5001(hb))
                                
                                lb = self.de5001(lb)
                                hb = self.de5001(hb)
                                #print("lb geschrieben", lb )
                                #print("hb geschrieben", hb )
                                builder.add_8bit_uint(lb)
                                builder.add_8bit_uint(hb)
                                #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) 
                            elif type == '6':
                                if lb > 127:
                                    lb = 127
                                elif lb < -128:
                                    lb = -128
                                if hb > 127:
                                    hb = 127
                                elif hb < -128:
                                    hb = -128
                                builder.add_8bit_int(lb)
                                builder.add_8bit_int(hb)
                                #logger.debug('MODBUS: 8bit int {0} ; {1}'.format(lb.hb)) 
                        elif type == '7' or type == '8':                                            #16bit uint / int
                            length = 16
                            if type == '7':                                                         #0...65535
                                builder.add_16bit_uint(value)
                                #logger.debug('MODBUS: 16bit uint {0} '.format(value)) 
                            else:                                                                   #-32768...32767
                                builder.add_16bit_int(value)   
                                #logger.debug('MODBUS: 16bit int {0}'.format(value)) 
                            
                        elif type == '1':
                            length = 1
                                                                                                    #nur pro byte einmal die bits wandeln
                            if bitpos < 8:  #lb
                                lb  = lb | int(value) << bitpos
                                #logger.debug('MODBUS: 8bit int{0}'.format(lb)) 
                                
                            else:           #hb
                                hb  = hb | int(value) << bitpos
                                #logger.debug('MODBUS: 8bit int{0}'.format(hb)) 
                                
                            builder.add_8bit_uint(lb)
                            builder.add_8bit_uint(hb)
                            
                payload = builder.build()
                logger.debug('MODBUS: write to PLC: WORD {0} set to {1} '.format(byte,payload)) 
                self._modbuspy.write_registers(byte, payload, skip_encode=True)
                builder.reset()        
        except Exception as e:
            logger.error('MODBUS: Could not write an OutWord, because {}'.format(e))
            self._lock.release()
            return None
####################################################################################################
#Liest komplett angegebenen Speicherbereich aus Steuerung aus und gibt sie in dict zurück!
#read = anfangswert, end= länge 
#Eingangsbereich von Steuerung lesen
#
#
####################################################################################################  
    def read(self, iO='in'):
        #print('DATEN VOM BUS LESEN')
        i = 0
        if iO !='in':
            x = 'out'
        else:
            x = 'in'
        try:
            for byte in self._db[x]:
                rr = self._modbuspy.read_holding_registers(byte,2)
                pprint(rr)
                decodert2 = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Little)
                ##prüfen welcher dpt typ vorliegt und  dann das registerabfrage ergebnis aufdröseln:
                #->decode_16bit_uint()  -> 7 / 8
                #->decode_8bit_uint()   -> 5 | 5.001
                #->decode_8bit_int()    -> 6
                #->decode_bits()        -> 1
                for bit in self._db[x][byte]:                                                    ##eintraege in dict durchgehen
                    bitpos = bit[0]
                    type =  bit[1]
                    name =  bit[3]
                    
                    if type == '5' or type == '5.001' or type == '6':                                              ##8bit uint / int
                        length = 8
                        
                        if type == '6':
                            lb = decodert2.decode_8bit_int()
                            hb = decodert2.decode_8bit_int()
                            
                        elif type == '5' or type == '5.001':
                            lb = decodert2.decode_8bit_uint()
                            hb = decodert2.decode_8bit_uint()
                            
                        if bitpos < 8:#lb
                            value = hb
                            #logger.debug('MODBUS: byte{0} startpos{1} wert (5) {2}'.format(bit, bitpos,value)) 
                        else:#hb
                            value = lb
                            #logger.debug('MODBUS: byte{0} startpos{1} wert (5) {2}'.format(bit, bitpos,value)) 
                        
                        if type == '5.001':
                            #print('lb/hb Daten gelesen', value)
                            value = self.en5001(value)
                            #logger.debug('MODBUS: byte{0} startpos{1} wert (5.001) {2}'.format(bit, bitpos, value)) 
                    elif type == '7' or type == '8':                                                #16bit uint / int
                        length = 16
                        if type == '7':                                                             #0...65535
                            value = decodert2.decode_16bit_uint()
                            #logger.debug('MODBUS: 16bit uint{0}'.format(value)) 
                        else:                                                                       #-32768...32767
                            value  = decodert2.decode_16bit_int()    
                            #logger.debug('MODBUS: 16bit int{0}'.format(value)) 
                        
                    elif type == '1':
                        length = 1
                        hb = decodert2.decode_bits()
                        lb = decodert2.decode_bits()
                        bits = lb+hb
                     
                        value = bits[bitpos]
                        #logger.debug('MODBUS: Bits{0}'.format(bits))   
                        
                    bit[2] = value                                                                  #zurückspeichern   
                    
                    decodert2.reset() 
            ##Debug#################################################################################
                    bit[3](value, caller='modbus')
                i = i+1
                lb = decodert2.decode_bits()
                hb = decodert2.decode_bits()
                bits = hb+lb
                decodert2.reset() 
                logger.debug('MODBUS: read from PLC {0}-{1} {2}'.format(byte, bits, bytes))

        except Exception as e:
            logger.error('MODBUS: Could not read an InputWord, because {}'.format( e))
            self._lock.release()
            return None
        i = 0
        return None        
####################################################################################################
#wandelt str in binary ohne führendes 0b
#und invertiert auf wunsch das Ergebnis!
#
#
#
####################################################################################################  

    def toBinary2(self, n, invert = 1):##
        byte = '{:08b}'.format(n)
         
        i = int(16)-len(byte)
        ausgabe = ""
        for x in range(0,i):
            ausgabe = "0"+ausgabe
        ausgabe = ausgabe+byte
        if invert == 1:#invertieren
            ausgabe = ausgabe[::-1]
        return ausgabe
        
    def toBinary(self, n, invert = 0):##
        byte = '{:08b}'.format(n)
        if invert == 1:#invertieren
            byte = byte[::-1] 
        ausgabe = []
        if byte == '00000000':
            ausgabe.append('00000000')
            ausgabe.append('00000000')
        elif byte < '256' :
            ausgabe.append(byte[0:8])
            ausgabe.append('00000000')
        else:
            ausgabe.append(byte[0:8])
            ausgabe.append(byte[8:17])   
        return ausgabe 

    def de5001(self, value):                                                                        #8bit 0-100 auf 0-255 normieren
        if value > 255:
            value = 255
        elif value < 0:
            value = 0
        return int(round(value*2.55))
    def en5001(self, value):                                                                        #8bit auf 0-100 normieren
        if value > 255:
            value = 255
        elif value < 0:
            value = 0
        return (round((value/2.55), 2))
Пример #53
0
#---------------------------------------------------------------------------# 
# If you need to decode a collection of registers in a weird layout, the
# payload decoder can help you as well.
#
# Here we demonstrate decoding a random register 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]
#---------------------------------------------------------------------------# 
address = 0x00
count   = 8
result  = client.read_holding_registers(address, count,  unit=1)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Big)
decoded = {
    'string': decoder.decode_string(8),
    'float': decoder.decode_32bit_float(),
    '16uint': decoder.decode_16bit_uint(),
    '8int': decoder.decode_8bit_int(),
    'bits': decoder.decode_bits(),
}

print "-" * 60
print "Decoded Data"
print "-" * 60
for name, value in decoded.iteritems():
    print ("%s\t" % name), value
class clientthreads(threading.Thread):

    def __init__(self, vnic, ipaddr, port):
        threading.Thread.__init__(self)
        self.ipaddr = ipaddr  # ip address
        self.port = port  # port address
        self.vnic = vnic  # virtual nic
        self.mode = ""  # server or client
        self.state = ""  # up or down
        self.dest = ""  # destination address for client
        self.clientstop = threading.Event()
        self.server = ""
        self.client = ""
        self.framer = ""
        self.vnicm = ""
        self.runtime= 0
        self.delayr = random.uniform(0,5)
        self.delayw = random.uniform(0,60)
        self.firstdelay = 0
        self.pstart= ""


    def run(self):
        self.client = ModbusTcpClient(self.dest, self.port, source_address=(self.ipaddr, 0), retries=1, retry_on_empty=True)
        if(self.mode=="read"):
            self.clientintr()
        elif(self.mode=="write"):
            self.clientintw()
        else:
            print "wrong mode specified"

    def clientintr(self):  # instantiate server stuff
        while(not self.clientstop.is_set()):
            if(time.time() - self.pstart > self.runtime):
                print "stopping"
                break
            if(self.firstdelay < 1):
                print "Start RDelay is: " + str(self.delayr)
                time.sleep(self.delayr)
                self.firstdelay = 1
                print "Starting Reads"

            self.clientreads()
            print "\n\r-----read-----\n\r"
            print self.dest 
            print time.time() - self.pstart
            print "------------------\n\r"
    
    def clientintw(self):  # instantiate server stuff
        while(not self.clientstop.is_set()):
            if(time.time() - self.pstart > self.runtime):
                print "stopping"
                break
            if(self.firstdelay < 1):
                print "Start WDelay is: " + str(self.delayw)
                time.sleep(self.delayw)
                self.firstdelay = 1
                print "Starting Writes"

            self.clientwrites()
            print "\n\r-----write----\n\r"
            print self.dest 
            print time.time() - self.pstart
            print "------------------\n\r"


    def clientreads(self):
        self.client.read_coils(1, 10)
        self.client.read_discrete_inputs(1, 10)
        self.client.read_holding_registers(1, 10)
        self.client.read_input_registers(1, 10)
        time.sleep(5)

    def clientwrites(self):
        self.client.write_coil(1, True)
        self.client.write_register(1, 3)
        self.client.write_coils(1, [True]*10)
        self.client.write_registers(1, [3]*10)
        time.sleep(60)
    
    def alloc(self):  # Allocate ip address
        if (validateIP(self.ipaddr, self.vnicm)):
            cmdargs = [self.vnic, self.ipaddr]
            subprocess.call(["ifconfig"] + cmdargs)
        else:
            return 0

    def dealloc(self):  # De-allocate ip address
        cmdargs = [self.vnic]
        subprocess.call(["ifconfig"] + cmdargs + ["down"])

    def stop(self):
        self.clientstop.set()
        return
Пример #55
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
Пример #56
0
class Handler(object):
    def __init__(self,a,a2,canvas,loop=None):
        self.loop = loop
        self.ret_m1 = False
        self.afigure = a
        self.afigure2 = a2
        self.canvas = canvas
        self._bufsize = x_size
        self.databuffer_p1 = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_p2 = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_r = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.databuffer_q1 = collections.deque([0.0]*self._bufsize, self._bufsize)
        self.x = range(x_size)
        self.line_p1, = self.afigure.plot(self.x, self.databuffer_p1,"b-", label='Pg')
        self.line_p2, = self.afigure.plot(self.x, self.databuffer_p2,"-", color='#ffa100', label='Pe')
        self.line_r, = self.afigure.plot(self.x, self.databuffer_r,"r-", label='R')
        self.line_q1, = self.afigure2.plot(self.x, self.databuffer_q1,"m-",  label='Q')

        h1, l1 = a.get_legend_handles_labels()
        h2, l2 = a2.get_legend_handles_labels()
        self.afigure.legend(h1+h2, l1+l2, loc=2, ncol=2, fontsize=10)
        self.pmax = 0
        self.qmax = 0
        self.qVmax = 0
        self.pR = 0
        self.blogFile = False
        self.oneLogged = False
        self.pipeLength = 0.0
        self.pipeDiam  = 0.0
        self.pipeType  = "ND"
        self.mixType  = "ND"
        self.mixDensity  = 0.0
        self.staticHead = 0.0
        self.treeview2  = builder.get_object("treeview2")
        self.p_count = 0
        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Name", renderer, text=0)
        self.treeview2.append_column(column)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Description", renderer, text=1)
        self.treeview2.append_column(column)

        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Value", renderer, text=2)
        self.treeview2.append_column(column)

        self.adjustPMax = builder.get_object("adjustment1")
        self.adjustQMax = builder.get_object("adjustment2")
        self.chkPAna = builder.get_object("chkPAna")
        self.txtDHLF = builder.get_object("txtDHLF")
        self.btnAnalyze = builder.get_object("btnAnalyze")
        self.txtRefPressure = builder.get_object("txtR")
        self.btnAnalyze.set_sensitive(False)
        self.time = datetime.datetime.utcnow()
        self.lastPe = collections.deque(maxlen=designRTW*60)
        self.lastPg = collections.deque(maxlen=designRTW*60)
        self.lastQ = collections.deque(maxlen=designRTW*60)
        self.txtQ2 = builder.get_object("txtQ2")
        self.txtQ1 = builder.get_object("txtQ1")
        self.txtK = builder.get_object("txtK")
        self.txtPoutMax = builder.get_object("txtPoutMax")
        self.lblOK = builder.get_object("lblOK")
        self.hdlf_q2 = 0
        self.hdlf_q1 = 0
        self.hdlf_k = 0
        
        self.designQmin = 0.
        


    def logging_data(self, a):
        self.send_parity()
        t1=datetime.datetime.utcnow()
        dt_seconds = (t1-self.time).seconds
        builder.get_object("levelbar1").set_value(len(listP1)%60+1)
        client_1 = a[0]
        client_p = a[8]
        txtPout = a[9]
        txtQout = a[10]
        aIN1 = a[1]
        aIN2 = a[2]
        aIN1ENG = a[3]
        aIN2ENG = a[4]
        aIN12 = a[5]
        aIN22 = a[6]
        aIN1ENG2 = a[7]
        strR = self.txtRefPressure.get_text()
        if strR.isdigit():
            self.pR = int(strR)
        else:
            self.pR = 10
            self.txtRefPressure.set_text("10")


        strR = builder.get_object("txtPipeLenght").get_text()
        if strR.isdigit():
            self.pipeLength = int(strR)
        else:
            builder.get_object("txtPipeLenght").set_text(str(self.pipeLength))
        
        
        self.hdlf_q2 = float(builder.get_object("txtQ2").get_text())
        self.hdlf_q1 = float(builder.get_object("txtQ1").get_text())
        self.hdlf_k = float(builder.get_object("txtK").get_text())

        strR = builder.get_object("txtStaticHead").get_text()
        try:
            self.staticHead = float(strR)
        except ValueError:
            builder.get_object("txtStaticHead").set_text(str(self.staticHead))
        
        
        rr1 = client_1.read_holding_registers(0,48)
        if rr1.registers[test_reg_no] == test_value:
            p_mA1 = rr1.registers[4-1]# AIN1 pressione in mA in posizione 4
            p_Eng1 = int(pEngFunc(p_mA1))
            # AIN2 portata in mA in posizione 6
            q_mA1 = rr1.registers[6-1]
            q_Eng1 = int(qEngFunc(q_mA1))            
            rr1_103 = client_1.read_holding_registers(103,10)
            reg104_1 = tuple(rr1_103.registers )
            
            
            p_mA2 = 0 # rr2.registers[4-1]# AIN1 pressione in mA in posizione 4
            p_Eng2 = 0 # rr2.registers[5-1]
            # AIN2 portata in mA in posizione 6
            q_mA2 = 0 # rr2.registers[6-1]
            if p_mA1 <= 4000:
                p_mA1 = 0
                p_Eng1 = 0
            if q_mA1 <= 4000:
                q_mA1 = 0
                q_Eng1 = 0

      
            hdlf = (self.hdlf_q2, self.hdlf_q1,self.hdlf_k)
            self.pDHL = phdlf( q_Eng1/10. ,self.pipeLength, hdlf )
            p_Eng2 = p_Eng1 - 10.*self.pDHL + 10.*self.staticHead
            
            self.lastQ.append(q_Eng1/10.)
            self.lastPe.append(p_Eng2/10.)
            self.lastPg.append(p_Eng1/10.)            
            if len(self.lastPe) == self.lastPe.maxlen:
                p_mA2 = np.mean(self.lastPe)
                q_mA2 = np.mean(self.lastQ)
                pRate = p_mA2/self.pR
                if q_mA2 <= self.designQmin and p_mA2 >= self.pR:
                    self.lblOK.set_label("OK")
                else:
                    self.lblOK.set_label("P<R ({0:.2f})".format(pRate))            
                
            self.txtDHLF.set_text("{0:.2f}".format(-self.pDHL))
            self.databuffer_p1.append( p_Eng1/10. )
            self.line_p1.set_ydata(self.databuffer_p1)
            self.databuffer_p2.append( p_Eng2/10. )
            self.line_p2.set_ydata(self.databuffer_p2)
            self.databuffer_r.append( self.pR )
            self.line_r.set_ydata(self.databuffer_r)


            self.databuffer_q1.append( q_Eng1/10. )
            self.line_q1.set_ydata(self.databuffer_q1)

            self.afigure.relim()
            self.afigure.autoscale_view(False, False, True)
            self.afigure2.relim()
            self.afigure2.autoscale_view(False, False, True)
            self.canvas.draw()

            listP1.append(p_Eng1/10.)
            listP2.append(p_Eng2/10.)
            aIN1.set_text(str(p_mA1))
            aIN2.set_text(str(q_mA1))
            aIN1ENG.set_text("{0} bar".format(p_Eng1/10.))
            aIN2ENG.set_text("{0} lit/min".format(q_Eng1/10.))
            
            aIN12.set_text("{0:.2f} bar".format(p_mA2))
            aIN22.set_text("{0:.2f} lit/min".format(q_mA2))
            
            aIN1ENG2.set_text("{0} bar".format(p_Eng2/10.))
            # INIETTORE
            rr_p = client_p.read_holding_registers(500,100,unit=1)
            txtPout.set_text("{0} bar".format(rr_p.registers[16]))


            fPoutMax = self.pR + rr_p.registers[16] - p_Eng2/10.            
            self.txtPoutMax.set_text("{0}".format(int(fPoutMax)))
            txtQout.set_text("{0} c/min {1:.2f} l/min".format(rr_p.registers[20], litCiclo*rr_p.registers[20] ))
            self.pmax = rr_p.registers[60]
            if self.chkPAna.get_active():
                self.qmax = rr_p.registers[64]
                builder.get_object("txtQmax").set_text("{0} V".format(self.qmax))
            else:
                self.qmax = rr_p.registers[62]
                builder.get_object("txtQmax").set_text("{0} c/min {1:.2f} l/min".format(self.qmax, litCiclo*self.qmax))
            # self.qVmax = rr_p.registers[64]
            builder.get_object("txtPmax").set_text("{0} bar".format(rr_p.registers[60]))
            # print "P: {0}->{1} \tdP = {4} \t\tQ: {2}->{3} \tn={5} \tavg P1 {6:.2f}({7:.2f}) P2 {8:.2f}({9:.2f})".format(p_Eng1/10.,p_Eng2/10.,q_Eng1/10.,q_Eng2/10.,(p_Eng1-p_Eng2)/10., len(listP1), np.mean(listP1),np.std(listP1),np.mean(listP2),np.std(listP2) )
            if self.blogFile:
                self.oneLogged = True
                # TODO btnLog set label
                # time now - before
                builder.get_object("btnLog").set_label("{0}".format(datetime.timedelta(seconds =dt_seconds)))
                log.info("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%s;%s;%f;%f;%f;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f" % (self.pR, p_mA1, p_Eng1, q_mA1, q_Eng1,reg104_1[0] ,reg104_1[1] ,reg104_1[2] , reg104_1[3],reg104_1[6] ,reg104_1[7] ,reg104_1[8] , reg104_1[9],p_mA2, p_Eng2, q_mA2,  self.pipeLength, self.pipeDiam,self.pipeType,self.mixType,self.mixDensity,self.staticHead,self.pDHL, rr_p.registers[16],rr_p.registers[20],self.pmax,self.qmax, self.pmax-rr_p.registers[16], rr_p.registers[16]- p_Eng1/10. , hdlf[0], hdlf[1], hdlf[2],fPoutMax))
        else:
            print "error on test data {0} vs {1} or {0} vs {2}".format(test_value,rr1.registers[test_reg_no],rr2.registers[test_reg_no])


    def onDeleteWindow(self, *args):
        Gtk.main_quit(*args)

    def testConnection1(self, button):
        lblTest1 = builder.get_object("lblTest1")
        manifold_host_1 = builder.get_object("txtIP1").get_text()
        manifold_port_1 = int(builder.get_object("txtPort1").get_text())
        client_1 = ModbusClient(manifold_host_1, port=manifold_port_1)
        self.ret_m1=client_1.connect()
        lblTest1.set_text(str(self.ret_m1))
        if not smtConfig.has_section('Manifold_1'):
            smtConfig.add_section('Manifold_1')
        if self.ret_m1:
            builder.get_object("switchMain").set_sensitive(True)
            smtConfig.set('Manifold_1', 'host', manifold_host_1)
            smtConfig.set('Manifold_1', 'port', manifold_port_1)
            with open(sCFGName, 'wb') as configfile:
                smtConfig.write(configfile)
        client_1.close()


    def on_btnConnectPump_clicked(self, button):
        lblTestPump = builder.get_object("lblTestPump")
        pump_host = builder.get_object("txtIPPump").get_text()
        pump_port = int(builder.get_object("txtPortPump").get_text())
        self.client_p = ModbusClient(pump_host, port=pump_port)
        self.ret_p=self.client_p.connect()
        lblTestPump.set_text(str(self.ret_p))
        if not smtConfig.has_section('Pump'):
            smtConfig.add_section('Pump')
        if self.ret_p:
            self.checkPump(self.client_p)
            smtConfig.set('Pump', 'host', pump_host)
            smtConfig.set('Pump', 'port', pump_port)
            with open(sCFGName, 'wb') as configfile:
                smtConfig.write(configfile)
        self.client_p.close()


    def checkPump(self,client_p):
        rr = client_p.read_holding_registers(500,100,unit=1)
        # conversione in bit array da 552
        decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[52:53],endian=Endian.Little)
        bits_552 = decoder.decode_bits()
        bits_552 += decoder.decode_bits()
        bits_552[10] = True
        b_builder = BinaryPayloadBuilder(endian=Endian.Little)
        b_builder.add_bits(bits_552)
        reg_552 = b_builder.to_registers()
        rr.registers[52:53] = reg_552
        for it in range(10):
            self.p_count += 1
            rr.registers[50] = self.p_count
            rq = client_p.write_registers(500, rr.registers,unit=1)
            if rq.function_code < 0x80:
                rr_p = client_p.read_holding_registers(500,100,unit=1)
                if len(rr_p.registers)==100 and rr_p.registers[0]==self.p_count:
                    decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[2:7],endian=Endian.Little)
                    # 502
                    bits_502 = decoder.decode_bits()
                    bits_502 += decoder.decode_bits()
                    # 503
                    bits_503 = decoder.decode_bits()
                    bits_503 += decoder.decode_bits()
                    # 504
                    bits_504 = decoder.decode_bits()
                    bits_504 += decoder.decode_bits()
                    # 505
                    bits_505 = decoder.decode_bits()
                    bits_505 += decoder.decode_bits()
                    # 506
                    bits_506 = decoder.decode_bits()
                    bits_506 += decoder.decode_bits()
                    if bits_502[7]:
                        builder.get_object("switchPumpStatus").set_active(True)
                    else:
                        builder.get_object("switchPumpStatus").set_active(False)

                    if bits_502[4] == False and bits_502[10] == True:
                        builder.get_object("switchPumpStatus").set_sensitive(True)
                    else:
                        builder.get_object("switchPumpStatus").set_sensitive(False)
                else:
                    print "errore checkPump %d" % self.p_count
        bits_552[10] = False
        print str(bits_552)
        b_builder = BinaryPayloadBuilder(endian=Endian.Little)
        b_builder.add_bits(bits_552)
        reg_552_2 = b_builder.to_registers()
        rr.registers[52:53] = reg_552_2
        rq = client_p.write_registers(500, rr.registers,unit=1)
        if rq.function_code < 0x80:
            pass
        else:
            print "checkPump terminato con scrittura KO"

    def on_btnOpenFile_clicked(self,button):
        #os.system()
        subprocess.call(["libreoffice",export_csv_path])


    def on_btnGetPump_clicked(self,button):
        self.adjustPMax.set_value(float(self.pmax) )
        self.adjustQMax.set_value(float(self.qmax))


    def send_parity(self):
        self.p_count += 1
        rr_p = self.client_p.write_registers(550,self.p_count,unit=1)

    def on_btnSetPump_clicked(self,button):
        rr_p = self.client_p.read_holding_registers(500,100,unit=1)
        decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[52:53],endian=Endian.Little)
        bits_552 = decoder.decode_bits()
        bits_552 += decoder.decode_bits()
        self.pmax = self.adjustPMax.get_value()
        _qmax = self.adjustQMax.get_value()
        self.p_count += 1
        rr_p.registers[50] = self.p_count
        rr_p.registers[60] = int(self.pmax)
        if self.chkPAna.get_active():
            self.qmax = getFlowRateAsVolts(_qmax)
            v = getVoltsFromFlowRate(self.qmax)
            print "_qmax => {0} self.qmax => {1} c => {2}".format(_qmax, self.qmax, v)
            rr_p.registers[64] = self.qmax
            rr_p.registers[62] = int(_qmax/litCiclo)
            bits_552[12] = True
        else:
            self.qmax = _qmax
            rr_p.registers[62] = int(self.qmax)
            rr_p.registers[64] = cicli_volt[int(self.qmax)]
            bits_552[12] = False
        b_builder = BinaryPayloadBuilder(endian=Endian.Little)
        # builder.add_bits(bits_502)
        b_builder.add_bits(bits_552)
        reg_552 = b_builder.to_registers()
        rr_p.registers[52:53] = reg_552
        rr_p = self.client_p.write_registers(500,rr_p.registers,unit=1)


    def on_btnOff_clicked(self,button):
        print("Closing application")
        Gtk.main_quit()

    def on_btnLog_toggled(self,button):
        if button.get_active():
            self.time = datetime.datetime.utcnow()
                
            self.blogFile = True
        else:
            self.blogFile = False
            builder.get_object("btnLog").set_label("Log Data")


    def readDataSetupConfig(self):
        self.pipeLength = float(builder.get_object("txtPipeLenght").get_text())
        self.pipeDiam  =  float(builder.get_object("txtPipeDiam").get_text())
        self.pipeType  = builder.get_object("txtPipeType").get_text()
        self.mixType  = builder.get_object("txtMixType").get_text()
        self.mixDensity  =  float(builder.get_object("txtMixDensity").get_text())
        self.staticHead = float(builder.get_object("txtStaticHead").get_text())
        self.hdlf_q2 = float(builder.get_object("txtQ2").get_text())
        self.hdlf_q1 = float(builder.get_object("txtQ1").get_text())
        self.hdlf_k = float(builder.get_object("txtK").get_text())
        self.pR = int(builder.get_object("txtR").get_text())
        self.designQmin = int(builder.get_object("txtQmin").get_text())
        designRTW = int(builder.get_object("txtRefTime").get_text())
        
        if designRTW*60 != self.lastPe.maxlen:
            print "resize RTW from {0} to {1}".format(self.lastPe.maxlen, designRTW*60)
            self.lastPe = collections.deque(self.lastPe, maxlen=designRTW*60)
            self.lastPg = collections.deque(self.lastPg, maxlen=designRTW*60)
            self.lastQ = collections.deque(self.lastQ, maxlen=designRTW*60)

        if not smtConfig.has_section('HeadLossFactor'):
            smtConfig.add_section('HeadLossFactor')
        smtConfig.set('HeadLossFactor', 'pipeLength', self.pipeLength)
        smtConfig.set('HeadLossFactor', 'pipeDiam', self.pipeDiam)
        smtConfig.set('HeadLossFactor', 'pipeType', self.pipeType)
        smtConfig.set('HeadLossFactor', 'mixType', self.mixType)
        smtConfig.set('HeadLossFactor', 'mixDensity', self.mixDensity)
        smtConfig.set('HeadLossFactor', 'staticHead', self.staticHead)
        smtConfig.set('HeadLossFactor', 'Q2', self.hdlf_q2)
        smtConfig.set('HeadLossFactor', 'Q1', self.hdlf_q1)
        smtConfig.set('HeadLossFactor', 'K', self.hdlf_k)
        
        
        if not smtConfig.has_section('Design'):
            smtConfig.add_section('Design')
        smtConfig.set('Design', 'R', self.pR)
        smtConfig.set('Design', 'Qmin', self.designQmin)
        smtConfig.set('Design', 'RTW', designRTW)        
        
        with open(sCFGName, 'wb') as configfile:
            smtConfig.write(configfile)

    def on_switchPumpStatus_state_set(self, switch,gparam):
        self.ret_p=self.client_p.connect()
        rr = self.client_p.read_holding_registers(500,100,unit=1)
        # conversione in bit array da 552
        decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[52:53],endian=Endian.Little)
        bits_552 = decoder.decode_bits()
        bits_552 += decoder.decode_bits()

        decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[2:7],endian=Endian.Little)
        # 502
        bits_502 = decoder.decode_bits()
        bits_502 += decoder.decode_bits()
        # 503
        bits_503 = decoder.decode_bits()
        bits_503 += decoder.decode_bits()
        # 504
        bits_504 = decoder.decode_bits()
        bits_504 += decoder.decode_bits()
        # 505
        bits_505 = decoder.decode_bits()
        bits_505 += decoder.decode_bits()
        # 506
        bits_506 = decoder.decode_bits()
        bits_506 += decoder.decode_bits()
        bSendCommand = False
        if switch.get_active():
            # %MW552:X2 START INIET. DA REMOTO
            bSendCommand = not bits_502[7]
            bits_552[2] = True
            bits_552[3] = False
            bits_552[14] = True
        else:
            # %MW552:X2 STOP INIET. DA REMOTO
            bSendCommand = bits_502[7]
            bits_552[2] = False
            bits_552[3] = True
            bits_552[14] = False
        builder = BinaryPayloadBuilder(endian=Endian.Little)
        # builder.add_bits(bits_502)
        builder.add_bits(bits_552)
        reg_552 = builder.to_registers()
        rr.registers[52:53] = reg_552
        self.p_count += 1
        rr.registers[50] = self.p_count
        if bSendCommand:
            self.client_p.write_registers(500, rr.registers,unit=1)
            if bits_552[2]:
                bits_552[2] = False
                builder = BinaryPayloadBuilder(endian=Endian.Little)
                # builder.add_bits(bits_502)
                builder.add_bits(bits_552)
                reg_552 = builder.to_registers()
                self.client_p.write_register(552, reg_552[0])
                print "pulsante rilasciato"

        self.client_p.close()

    def on_btnShow_clicked(self,button):
        # show dlgRegistries
        self.lstDialog = builder.get_object("dlgRegistries")
        self.liststore = builder.get_object("liststore1")
        if self.ret_p:
            self.liststore.clear()
            rr = self.client_p.read_holding_registers(500,100,unit=1)
            for idx in [0,2,4,6,12,13,14,15,16,20,50,52,60,62,64]:
                if idx in (2,4,6,52):
                    decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[idx:idx+1],endian=Endian.Little)
                    bits = decoder.decode_bits()
                    bits += decoder.decode_bits()
                    for ib, b in enumerate(bits):
                        if b:
                            sCode = "%MW5{0:02d}:X{1}".format(idx,ib)
                            self.liststore.append([sCode,reg_descr[sCode], str( b ) ])
                else:
                    sCode = "%MW5{0:02d}".format(idx)
                    self.liststore.append([sCode, reg_descr[sCode], str( rr.registers[idx]) ])


        response = self.lstDialog.run()

        self.lstDialog.hide()

    def on_btnOk_clicked(self,button):
        self.lstDialog.close()



    def on_btnAnalyze_clicked(self,button):
        with open(export_csv_path, 'rb') as csvfile:
            template_vars = {}
            csv_reader = csv.DictReader(csvfile, delimiter=';')
            csv_list = list(csv_reader)
            data = [ np.asarray([row["q_Eng1"],row["dPManifold"],row["q_out"],row["dPPump"] , row["p_Eng1"],row["p_Eng2"]], dtype=np.float64)  for row in csv_list]
            x1 = [d[0]/10. for d in data]
            y1 = [d[1]/10. for d in data]
            x2 = [d[2]*litCiclo for d in data]
            y2 = [d[3] for d in data]
            p1 = [d[4]/10. for d in data]
            p2 = [d[5]/10. for d in data]
            dP = [d[4]/10. - d[5]/10. for d in data]
            # The solution minimizes the squared error
            fit1_1, res1_1, _, _, _ =  np.polyfit(x1, y1,1,full=True)
            fit1_2, res1_2, _, _, _ =  np.polyfit(x1, y1,2,full=True)
            fit2_1, res2_1, _, _, _ =  np.polyfit(x2, y2,1,full=True)
            fit2_2, res2_2, _, _, _ =  np.polyfit(x2, y2,2,full=True)
            p_func_fit1_1 = np.poly1d(fit1_1)
            p_func_fit1_2 = np.poly1d(fit1_2)
            p_func_fit2_1 = np.poly1d(fit2_1)
            p_func_fit2_2 = np.poly1d(fit2_2)
            xp = np.linspace(np.min(x1), np.max(x1), 100)
            fig = plt.figure(figsize=(16, 9), dpi=100)
            plt.plot(x1, y1, 'b.', label='Samples')
            plt.plot(xp, p_func_fit1_1(xp), 'r--', label="Linear (e={0:.3f})".format(res1_1[0]))
            plt.plot(xp, p_func_fit1_2(xp), 'g-', label="Curved (e={0:.3f})".format(res1_2[0]))
            plt.xlabel('Flow Rate (lit/min)')
            plt.ylabel('Pressure (bar)')
            #plt.legend()
            plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=3, mode="expand", borderaxespad=0.)
            plt.grid(True)
            tex1 = r'$%.3fx^{2}%+.3fx%+.3f$' % tuple(fit1_2)
            plt.text(int(np.min(x1)),np.max(y1)*0.9, tex1, fontsize=16, va='bottom', color="g")

            template_vars["fit1_1"] = tuple(fit1_1)
            template_vars["fit1_2"] = tuple(fit1_2)
            template_vars["res1_1"] = res1_1
            template_vars["res1_2"] = res1_2


            imagefname = "hflf_1_{0}.png".format(sDate)
            imagefpath = os.path.join(sCurrentWorkingdir,"out",imagefname)
            template_vars["hflf_1"] = imagefpath
            plt.savefig(imagefpath,format="png", bbox_inches='tight', pad_inches=0)
            plt.close(fig)

            xp = np.linspace(np.min(x2), np.max(x2), 100)
            fig = plt.figure(figsize=(16, 9), dpi=100)
            plt.plot(x2, y2, 'b.', label='Samples')
            plt.plot(xp, p_func_fit2_1(xp), 'r--', label='Linear model (e={0:.3f})'.format(res2_1[0]))
            plt.plot(xp, p_func_fit2_2(xp), 'g-', label='Curved model (e={0:.3f})'.format(res2_2[0]))
            plt.xlabel('Flow Rate (lit/min)')
            plt.ylabel('Pressure (bar)')
            plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=3, mode="expand", borderaxespad=0.)
            plt.grid(True)
            tex1 = r'$%.3fx^{2}%+.3fx%+.3f$' % tuple(fit2_2)
            plt.text(int(np.min(x2)),np.max(y2)*0.9, tex1, fontsize=16, va='bottom', color="g")


            imagefname = "hflf_2_{0}.png".format(sDate)
            imagefpath = os.path.join(sCurrentWorkingdir,"out",imagefname)
            template_vars["hflf_2"] = imagefpath
            plt.savefig(imagefpath,format="png", bbox_inches='tight', pad_inches=0)
            plt.close(fig)

            # andamento pressione portata nel tempo
            fig = plt.figure(figsize=(16, 9), dpi=100)
            t = np.arange(len(p1))
            a = fig.add_subplot(212)
            a.grid(True)

            for tick in a.xaxis.get_major_ticks():
                tick.label.set_fontsize(10)
            for tick in a.yaxis.get_major_ticks():
                tick.label.set_fontsize(10)

            a.set_xlabel('Time (seconds)')
            #a.set_ylim(np.min(dP)-2, np.max(dP)+2)
            a.set_ylim(np.min(p1)-2, np.max(p1)+2)
            a.set_xlim(0, len(t)+1)

            a.plot(t, p1, 'bo-', label='P1')
            a.plot(t, p2, 'ro-', label='P2')
            a.set_ylabel('Pressure (P bar)', fontsize=10)
            a.legend(loc=2, ncol=2, fontsize=10)
            a2 = fig.add_subplot(211)
            a2.grid(True)

            for tick in a2.xaxis.get_major_ticks():
                tick.label.set_fontsize(10)

            for tick in a2.yaxis.get_major_ticks():
                tick.label.set_fontsize(10)

            a2.set_xlabel('Time (seconds)')
            a2.set_ylabel('Flow rate (Q lit/min)', fontsize=10)
            a2.set_ylim(np.min(x1)-2, np.max(x1)+2)
            a2.set_xlim(0, len(t)+1)
            #a.plot(t, dP, 'r-', label='dP')
            a2.plot(t, x1, 'go-', label='Q')
            a2.legend(loc=2, ncol=2, fontsize=10)

            template_vars["t_items"] = list(t)
            template_vars["q_items"] = list(x1)
            template_vars["p1_items"] = list(p1)
            template_vars["p2_items"] = list(p2)
            template_vars["dp_items"] = list(dP)
            template_vars["pipeLength"] = self.pipeLength
            template_vars["pipeDiam"] = self.pipeDiam
            template_vars["pipeType"] = self.pipeType
            template_vars["mixType"] = self.mixType
            template_vars["mixDensity"] = self.mixDensity


            imagefname = "time_{0}.png".format(sDate)
            imagefpath = os.path.join(sCurrentWorkingdir,"out",imagefname)
            template_vars["time"] = imagefpath
            plt.savefig(imagefpath,format="png", bbox_inches='tight', pad_inches=0)
            plt.close(fig)
            template_vars["issue_date"] = datetime.datetime.utcnow().strftime("%Y.%m.%d %H:%M:%S")

            env = Environment(loader=FileSystemLoader('.'))
            templateFile = "hdlf_template.html"
            templateFilePath = os.path.join(sCurrentWorkingdir,"out",templateFile)
            template = env.get_template(templateFile)
            html_out = template.render(template_vars)

            pdffname = "hdlf_{0}.pdf".format(sDate)
            pdfpath = os.path.join(sCurrentWorkingdir,"out",pdffname)
            HTML(string=html_out).write_pdf(pdfpath, stylesheets=["typography.css","grid.css"])


    def on_switchMain_activate(self, switch,gparam):
        if switch.get_active():
            self.client_1 = ModbusClient(manifold_host_1, port=manifold_port_1)
            self.client_p = ModbusClient(pump_host, port=pump_port)
            self.client_1.connect()
            self.client_p.connect()
            self.readDataSetupConfig()
            time.sleep(2)
            print "start connection"
            time_delay = 1 # 1 seconds delay
            self.loop = LoopingCall(f=self.logging_data, a=(self.client_1, builder.get_object("txtAIN1"),builder.get_object("txtAIN2"),builder.get_object("txtAIN1ENG"),builder.get_object("txtAIN2ENG"),builder.get_object("txtAIN12"),builder.get_object("txtAIN22"),builder.get_object("txtAIN1ENG2"),self.client_p,builder.get_object("txtPout"),builder.get_object("txtQout")))
            self.loop.start(time_delay, now=False) # initially delay by time
            builder.get_object("btnOpenFile").set_sensitive(False)
            builder.get_object("btnOff").set_sensitive(False)
            self.btnAnalyze.set_sensitive(False)
            # self.ani = animation.FuncAnimation(self.figure, self.update_plot, interval = 1000)
        else:
            self.loop.stop()
            time.sleep(1)
            self.client_1.close()
            self.client_p.close()
            print "stop connection"
            time.sleep(2)
            builder.get_object("txtFilePath").set_text(export_csv_path)
            builder.get_object("btnOpenFile").set_sensitive(True)
            builder.get_object("btnOff").set_sensitive(True)
            if self.oneLogged:
                self.btnAnalyze.set_sensitive(True)
Пример #57
0
class InModbus(ApplicationSession):
    """
    Reads the AC-Values of the WAGO 750-494 I/O Clamps every second via Modbus
    and publishes them to the topic eshl/eshl.wago.v2.readout.meter.494
    """
    def __init__(self, config=None):
        ApplicationSession.__init__(self, config)
        self.pfcIp = '192.168.1.50'
        self.modbusTcpPort = 502
        self.numberOfClamps = 7
        self.client = ModbusClient(self.pfcIp, self.modbusTcpPort)
        self.clamps = []
        for i in range(0, self.numberOfClamps):
            self.clamps.append('Clamp' + str(i + 1))
        self.clampsV2 = []
        for i in range(0, self.numberOfClamps):
            if i < 9:
                self.clampsV2.append('Clamp0' + str(i + 1))
            if i >= 9:
                self.clampsV2.append('Clamp' + str(i + 1))


#==============================================================================
#   Generates a blank Dataset with the current system timestamp
#==============================================================================
    def blankDataSetGen(self):
        blankDataset = {'U1' : 'NaN',
                        'U2' : 'NaN',
                        'U3' : 'NaN',
                        'I1' : 'NaN',
                        'I2' : 'NaN',
                        'I3' : 'NaN',
                        'P1' : 'NaN',
                        'P2' : 'NaN',
                        'P3' : 'NaN',
                        'Q1' : 'NaN',
                        'Q2' : 'NaN',
                        'Q3' : 'NaN',
                        'S1' : 'NaN',
                        'S2' : 'NaN',
                        'S3' : 'NaN',
                        'CosPhi1' : 'NaN',
                        'CosPhi2' : 'NaN',
                        'CosPhi3' : 'NaN',
                        'PF1': 'NaN',
                        'PF2': 'NaN',
                        'PF3': 'NaN',
                        'Qua1': 'NaN',
                        'Qua2': 'NaN',
                        'Qua3': 'NaN',
                        'AEI1': 'NaN',
                        'AED1': 'NaN',
                        'REI1': 'NaN',
                        'REC1': 'NaN',
                        'AEI2': 'NaN',
                        'AED2': 'NaN',
                        'REI2': 'NaN',
                        'REC2': 'NaN',
                        'AEI3': 'NaN',
                        'AED3': 'NaN',
                        'REI3': 'NaN',
                        'REC3': 'NaN',
                        'DataValid' : '0',
                        'TimestampPFC' : 'NaN',
                        'TimestampSYS' : round(time.time() * 1000)
                        }
        return blankDataset

    def requestLoop(self):

        numberOfRegPerClamp = 74  # max number of holding registers is 125 as the total number of bytes incl. CRC is 256 according to the spec (via 03 command)
        meterreadings = {}
        meterreadingsV2 = {}
        print(time.time())

        try:
            if (self.client.connect() is False):
                print('not connected')
                self.client = self.client.connect()
                print('trying to connecto to ' + str(self.pfcIp))
            address = 0
#==============================================================================
#       Read current timestamp from PFC
#==============================================================================
            timestampSys = round(time.time() * 1000)
            result2 = self.client.read_holding_registers(timestampPFCRegister, 4)
            decoder = BinaryPayloadDecoder.fromRegisters(result2.registers, endian=Endian.Little)
            timestampPFC = decoder.decode_64bit_int()

#==============================================================================
#       Reads the values from modbus registers clamp by clamp
#       and buffers the results in  meterreadings{}
#		It is not possible to read all registers in one request because of the limitation of the Modbus-Message size to 255kb
# 		When the results of all clamps are buffered, they are published
#==============================================================================
            for x in range(0, len(self.clamps)):
                result = self.client.read_holding_registers(address, numberOfRegPerClamp)

                decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
                decoded = {
                    'I1': decoder.decode_32bit_float(),
                    'I2': decoder.decode_32bit_float(),
                    'I3': decoder.decode_32bit_float(),
                    'U1': decoder.decode_32bit_float(),
                    'U2': decoder.decode_32bit_float(),
                    'U3': decoder.decode_32bit_float(),
                    'P1': decoder.decode_32bit_float(),
                    'P2': decoder.decode_32bit_float(),
                    'P3': decoder.decode_32bit_float(),
                    'Q1': decoder.decode_32bit_float(),
                    'Q2': decoder.decode_32bit_float(),
                    'Q3': decoder.decode_32bit_float(),
                    'S1': decoder.decode_32bit_float(),
                    'S2': decoder.decode_32bit_float(),
                    'S3': decoder.decode_32bit_float(),
                    'CosPhi1': decoder.decode_32bit_float(),
                    'CosPhi2': decoder.decode_32bit_float(),
                    'CosPhi3': decoder.decode_32bit_float(),
                    'PF1': decoder.decode_32bit_float(),
                    'PF2': decoder.decode_32bit_float(),
                    'PF3': decoder.decode_32bit_float(),
                    'Qua1': decoder.decode_32bit_float(),
                    'Qua2': decoder.decode_32bit_float(),
                    'Qua3': decoder.decode_32bit_float(),
                    'AEI1': decoder.decode_32bit_float(),
                    'AED1': decoder.decode_32bit_float(),
                    'REI1': decoder.decode_32bit_float(),
                    'REC1': decoder.decode_32bit_float(),
                    'AEI2': decoder.decode_32bit_float(),
                    'AED2': decoder.decode_32bit_float(),
                    'REI2': decoder.decode_32bit_float(),
                    'REC2': decoder.decode_32bit_float(),
                    'AEI3': decoder.decode_32bit_float(),
                    'AED3': decoder.decode_32bit_float(),
                    'REI3': decoder.decode_32bit_float(),
                    'REC3': decoder.decode_32bit_float(),
                    'DataValid' : decoder.decode_32bit_float()}
#==============================================================================
#        standardize both TimestampPFC and TimestampSYS precision to be millisecond
#==============================================================================
                decoded['TimestampPFC'] = str(timestampPFC)[0:13]
                decoded['TimestampSYS'] = timestampSys

#==============================================================================
#                 PFC measures energy values in mWh --> convert to watt-seconds
#==============================================================================
                decoded['AEI1'] = float(decoded['AEI1']) * 3.6
                decoded['AED1'] = float(decoded['AED1']) * 3.6
                decoded['REI1'] = float(decoded['REI1']) * 3.6
                decoded['REC1'] = float(decoded['REC1']) * 3.6
                decoded['AEI2'] = float(decoded['AEI2']) * 3.6
                decoded['AED2'] = float(decoded['AED2']) * 3.6
                decoded['REI2'] = float(decoded['REI2']) * 3.6
                decoded['REC2'] = float(decoded['REC2']) * 3.6
                decoded['AEI3'] = float(decoded['AEI3']) * 3.6
                decoded['AED3'] = float(decoded['AED3']) * 3.6
                decoded['REI3'] = float(decoded['REI3']) * 3.6
                decoded['REC3'] = float(decoded['REC3']) * 3.6

                meterreadingsV2[self.clampsV2[x]] = decoded
                meterreadings[self.clamps[x]] = decoded
                address += numberOfRegPerClamp

            self.publish(u'eshl.wago.v1.readout.wiz.494', json.dumps(meterreadings, sort_keys=True))
            self.publish(u'eshl.wago.v2.readout.wiz.494', meterreadingsV2)

#==============================================================================
#      If there is no connection to the pfc-modbus slave or no connection to the pfc at all
#      the blankDataSet is published
#==============================================================================
        except ConnectionException as connErr:
            for x in range(0, len(self.clamps)):
                    meterreadings[self.clamps[x]] = self.blankDataSetGen()
            self.publish(u'eshl.wago.v1.readout.wiz.494', json.dumps(meterreadings, sort_keys=True))
            self.publish(u'eshl.wago.v2.readout.wiz.494', meterreadings)
            sys.__stdout__.write('ConnectionException in-wago-wiz-494' + '\n' + 'Timestamp: ' + str(timestampSys) + ', Errorcode --> ' + str(connErr))
            sys.__stdout__.flush()
        except Exception as err:
            sys.__stdout__.write('Exception in-wago-wiz-494' + '\n' + 'Timestamp: ' + str(timestampSys) + ', Errorcode --> ' + str(err))
            sys.__stdout__.flush()

    def onJoin(self, details):
        ApplicationSession.onJoin(self, details)
        print("session ready")

        self._loop = task.LoopingCall(self.requestLoop)
        self._loop.start(1.0)

    def onLeave(self, details):
        ApplicationSession.onLeave(self, details)
        print("leaving")

        if(hasattr(self, "_loop") and self._loop):
            self._loop.stop()
Пример #58
0
def run_binary_payload_ex():
    # ----------------------------------------------------------------------- #
    # We are going to use a simple client to send our requests
    # ----------------------------------------------------------------------- #
    client = ModbusClient('127.0.0.1', port=5440)
    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
    # - another 16 bit unsigned int 0x5678
    # - an 8 bit int 0x12
    # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
    # - an 32 bit uint 0x12345678
    # - an 32 bit signed int -0x1234
    # - an 64 bit signed int 0x12345678

    # The packing can also be applied to the word (wordorder) and bytes in each
    # word (byteorder)

    # The wordorder is applicable only for 32 and 64 bit values
    # Lets say we need to write a value 0x12345678 to a 32 bit register

    # The following combinations could be used to write the register

    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #
    # Word Order - Big                      Byte Order - Big
    # word1 =0x1234 word2 = 0x5678

    # Word Order - Big                      Byte Order - Little
    # word1 =0x3412 word2 = 0x7856

    # Word Order - Little                   Byte Order - Big
    # word1 = 0x5678 word2 = 0x1234

    # Word Order - Little                   Byte Order - Little
    # word1 =0x7856 word2 = 0x3412
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #

    # ----------------------------------------------------------------------- #
    builder = BinaryPayloadBuilder(byteorder=Endian.Little,
                                   wordorder=Endian.Big)
    builder.add_string('abcdefgh')
    builder.add_32bit_float(22.34)
    builder.add_16bit_uint(0x1234)
    builder.add_16bit_uint(0x5678)
    builder.add_8bit_int(0x12)
    builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
    builder.add_32bit_uint(0x12345678)
    builder.add_32bit_int(-0x1234)
    builder.add_64bit_int(0x1234567890ABCDEF)
    payload = builder.build()
    address = 0
    client.write_registers(address, payload, skip_encode=True, unit=1)
    # ----------------------------------------------------------------------- #
    # If you need to decode a collection of registers in a weird layout, the
    # payload decoder can help you as well.
    #
    # Here we demonstrate decoding a random register layout, unpacked it looks
    # like the following:
    #
    # - a 8 byte string 'abcdefgh'
    # - a 32 bit float 22.34
    # - a 16 bit unsigned int 0x1234
    # - another 16 bit unsigned int which we will ignore
    # - an 8 bit int 0x12
    # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
    # ----------------------------------------------------------------------- #
    address = 0x00
    count = len(payload)
    result = client.read_holding_registers(address, count,  unit=1)
    print("-" * 60)
    print("Registers")
    print("-" * 60)
    print(result.registers)
    print("\n")
    decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                 byteorder=Endian.Little,
                                                 wordorder=Endian.Big)
    decoded = {
        'string': decoder.decode_string(8),
        'float': decoder.decode_32bit_float(),
        '16uint': decoder.decode_16bit_uint(),
        'ignored': decoder.skip_bytes(2),
        '8int': decoder.decode_8bit_int(),
        'bits': decoder.decode_bits(),
        "32uints": decoder.decode_32bit_uint(),
        "32ints": decoder.decode_32bit_int(),
        "64ints": decoder.decode_64bit_int(),
    }
    
    print("-" * 60)
    print("Decoded Data")
    print("-" * 60)
    for name, value in iteritems(decoded):
        print("%s\t" % name, hex(value) if isinstance(value, int) else value)
    
    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
Пример #59
0
    topic = "/plc1"
    try:
        publish.single(topic, payload, hostname="broker_ip_address", port=1883, retain=False, qos=0)
    except Exception as err:
        print "Couldn't publish :" + str(err)
        pass


client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("mqtt_broker_ip_address")
client.loop_start()

while True:
    rr = client2.read_holding_registers(200, 1, unit=1)
    rr22 = client2.read_holding_registers(22, 1, unit=1)
    rr40 = client2.read_holding_registers(40, 1, unit=1)
    rr41 = client2.read_holding_registers(41, 1, unit=1)
    rr13 = client2.read_holding_registers(14, 1, unit=1)
    rr51 = client2.read_holding_registers(51, 1, unit=1)
    rr61 = client2.read_holding_registers(61, 1, unit=1)
    result = rr.registers
    result22 = rr22.registers
    result40 = rr40.registers
    result41 = rr41.registers
    result13 = rr13.registers
    result51 = rr51.registers
    result61 = rr61.registers
    valor = str(result)[1:-1]
    valor22 = str(result22)[1:-1]