Пример #1
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)
Пример #2
0
class SMAModbus:
    def __init__(self, url, unit_id):
        logging.info('Connecting to Modbus server: {}'.format(url))
        self._client = ModbusTcpClient('192.168.1.88')
        self._client.connect()
        logging.info('Connected')
        self._unit_id = unit_id

    def readModbus(self):
        if not self._client.is_socket_open():
            self._client.connect()
        data = {}
        for tag, cfg in modbus_fields.items():
            result = self._client.read_holding_registers(cfg['address'],
                                                         2,
                                                         unit=self._unit_id)
            if result.isError():
                logging.error(
                    'Reading registers for {} gave an error'.format(tag))
                continue
            w1 = struct.pack('H', result.registers[0]
                             )  # Assuming register values are unsigned short's
            w2 = struct.pack('H', result.registers[1]
                             )  # Assuming register values are unsigned short's
            if cfg['datatype'] == 'S32':
                v = struct.unpack('i', w2 + w1)
            elif cfg['datatype'] == 'U32':
                v = struct.unpack('I', w2 + w1)
            else:
                raise NotImplementedError(
                    'Datatype {} is not implemented'.format(cfg['datatype']))
            v = v[0] / cfg['scale']
            if v < cfg['min'] or v > cfg['max']:
                logging.error(
                    'Value out of range for {}: {} < {} < {} [{}]'.format(
                        tag, cfg['min'], v, cfg['max'], cfg['unit']))
                logging.error('Raw data: {}.{}'.format(result.registers[0],
                                                       result.registers[1]))
                #skip output
                continue
            v = (result.registers[0] * 2**16 +
                 result.registers[1]) / cfg['scale']
            # check for negative or larger than 100y of output
            if v < 0 or v > 100 * 3000 * 1000:
                v = 0.
            data[tag] = v
        return data
Пример #3
0
class ClientDevice(device.Device):
    def __init__(self, device_type, slave_id=None, name=None, pathlist=None, baudrate=None, parity=None, ipaddr=None, ipport=None, timeout=None, trace=False):

        device.Device.__init__(self, addr=None)

        self.type = device_type
        self.name = name
        self.pathlist = pathlist
        self.slave_id = slave_id
        self.modbus_device = None
        self.retry_count = 2
        self.base_addr_list = [40000, 0, 50000]

        try:
            if device_type == RTU:
                self.modbus_device = ModbusSerialClient(method=RTU)
            elif device_type == TCP:
                self.modbus_device = ModbusTcpClient(host=ipaddr, port=ipport)
            self.modbus_device.trace(trace)
        except Exception as e:
            if self.modbus_device is not None:
                self.modbus_device.close()
            raise SunSpecClientError('Modbus error: %s' % str(e))

    def close(self):
        if self.modbus_device is not None:
            self.modbus_device.close()

    def is_connected(self):
        return (self.modbus_device is not None) and (self.modbus_device.is_socket_open())

    def connect(self):
        if self.is_connected():
            connected = self.modbus_device.connect()
            if not connected:
                raise SunSpecClientError('Modbus connection error')

    def read(self, addr, count):
        try:
            if self.modbus_device is not None:
                response = self.modbus_device.read_holding_registers(address=addr, count=count, unit=self.slave_id)
                if response.isError():
                    return str(response)
                    # raise SunSpecClientError(str(response))
                return SunSpecDecoder.fromRegisters(response.registers)._payload
            else:
                raise SunSpecClientError('No modbus device set for SunSpec device')
        except Exception as e:
            raise SunSpecClientError('Modbus read error: %s' % str(e))

    def write(self, addr, data):
        try:
            if self.modbus_device is not None:
                return self.modbus_device.write_registers(addr, data)
            else:
                raise SunSpecClientError('No modbus device set for SunSpec device')
        except Exception as e:
            raise SunSpecClientError('Modbus write error: %s' % str(e))

    def read_points(self):
        for model in self.models_list:
            model.read_points()

    def scan(self, progress=None, delay=None):
        error = ''

        if delay is not None:
            time.sleep(delay)

        if self.base_addr is None:
            for addr in self.base_addr_list:
                # print('trying base address %s' % (addr))
                try:
                    data = self.read(addr, 3)
                    # print("Data: %s" % str(data))
                    if data[:4] == b'SunS':
                        self.base_addr = addr
                        # print('device base address = %d' % self.base_addr)
                        break
                    else:
                        error = 'Device responded - not SunSpec register map'
                except SunSpecClientError as e:
                    if not error:
                        error = str(e)

                if delay is not None:
                    time.sleep(delay)

        if self.base_addr is not None:
            # print('base address = %s' % (self.base_addr))
            model_id = util.data_to_u16(data[4:6])
            addr = self.base_addr + 2

            while model_id != suns.SUNS_END_MODEL_ID:
                # read model and model len separately due to some devices not supplying
                # count for the end model id
                data = self.read(addr + 1, 1)
                if data and len(data) == 2:
                    if progress is not None:
                        cont = progress('Scanning model %s' % (model_id))
                        if not cont:
                            raise SunSpecClientError('Device scan terminated')
                    model_len = util.data_to_u16(data)
                    # print('model_id = %s  model_len = %s' % (model_id, model_len))

                    # move address past model id and length
                    model = ClientModel(self, model_id, addr + 2, model_len)
                    # print('loading model %s at %d' % (model_id, addr + 2))
                    try:
                        model.load()
                    except Exception as e:
                        model.load_error = str(e)
                    self.add_model(model)

                    addr += model_len + 2
                    data = self.read(addr, 1)
                    if data and len(data) == 2:
                        model_id = util.data_to_u16(data)
                    else:
                        break
                else:
                    break

                if delay is not None:
                    time.sleep(delay)

        else:
            if not error:
                error = 'Unknown error'
            raise SunSpecClientError(error)
Пример #4
0
class device():
    def __init__(self,
                 device='ION7650',
                 code=[],
                 reg=[],
                 cnt=[],
                 indexes=[],
                 ip='127.0.0.1',
                 port=502,
                 timeout=1,
                 hata='hata',
                 address=255):
        self.device = device  #device'in tipi icin kullanilmakta. ION7650 vs.
        #self.whole = {}         #?
        self.ip = ip  #device ip bilgisi tasir
        self.port = port  #okuma yapilacak port 502 default
        self.timeout = timeout  #timeout suresi
        self.hata = hata  #hata tipi ya da cumlesi
        self.code = code  #details config file'dan INPUT ya da HOLDING gibi okuma ayrimlari icin
        self.reg = reg  # register verisini tutar
        self.cnt = cnt  # register okuma adedi
        self.indexes = indexes  # one shot read index addresses
        self.address = address  # modbus address
        self.con_stat = False  #connection status
        self.DevDict = {}
        #self.regs = []
        self.reg_type = "UINT16"
        self.delay = 3600
        self.old_data = []
        self.data = []
        self.TempData = [
        ]  #okunan ancak indexlenmemis ilk veriyi tutmak icin. Ozellikle float verilerde.
        self.conn = 5

    def Connect(self):
        self.conn = ModbusTcpClient(host=self.ip,
                                    port=self.port,
                                    timeout=self.timeout)
        try:
            self.con_stat = self.conn.connect()
        except CError:
            print(self.hata)
            self.con_stat = False

    def read_input_U16(self, x):  #for the single reads
        if self.conn.is_socket_open(self):
            try:
                self.rr = self.conn.read_input_registers(self.reg[x],
                                                         self.cnt[x],
                                                         unit=self.address)
            except CError:
                print "no connection try again"  #CSVWrite("connection_logs.csv", Error=CError.message)
            else:
                if hasattr(self.rr, 'registers'):
                    self.data.append(self.rr.registers[0])

                else:
                    print "possible close_wait situation"
        else:
            print "No active connection"

    def read_input_S16(self, x):  # for the single reads
        if self.conn.is_socket_open():
            try:
                self.rr = self.conn.read_input_registers(self.reg[x],
                                                         self.cnt[x],
                                                         unit=self.address)
            except CError:
                print "no connection try again"  #CSVWrite("connection_logs.csv", Error=CError.message)
            else:
                if hasattr(self.rr, 'registers'):
                    if self.rr.registers[0] > 32768:
                        self.data.append(
                            ctypes.c_int(
                                (self.rr.registers[0] ^ 0XFFFF) * -1).value)
                    else:
                        self.data.append(self.rr.registers[0])
                else:
                    print "possible close_wait situation"
        else:
            print "No active connection"

    def read_holding_floats(
            self, reg, cnt,
            index):  # for the multi reads x degeri read() fonksiyonundaki
        if self.conn.is_socket_open():
            try:
                self.TempData = []
                self.rr = self.conn.read_holding_registers(reg,
                                                           cnt * 2,
                                                           unit=self.address)
                if hasattr(self.rr, 'registers'):
                    self.decoder = BinaryPayloadDecoder.fromRegisters(
                        self.rr.registers, Endian.Big, wordorder=Endian.Big)
                    for a in range(0, cnt):
                        self.TempData.append(
                            round(self.decoder.decode_32bit_float(), 2))
                    self.data.append([self.TempData[i] for i in index])
                else:
                    self.TempData = []
                    self.rr = self.conn.read_holding_registers(
                        reg, cnt * 2, unit=self.address)
                    if hasattr(self.rr, 'registers'):
                        self.decoder = BinaryPayloadDecoder.fromRegisters(
                            self.rr.registers,
                            Endian.Big,
                            wordorder=Endian.Big)
                        for a in range(0, cnt):
                            self.TempData.append(
                                round(self.decoder.decode_32bit_float(), 2))
                        self.data.append([
                            self.TempData[i] for i in index
                        ])  #a list comprehantion.we may use even an if clause.
            except CError:
                print "no connection try again"  #CSVWrite("connection_logs.csv", Er

                #error=CError.message)
            else:
                pass
        else:
            print "No active connection"

    #def JustConnect(self):
    #    self.conn, self.con_stat = Connection(self.ip, self.port, self.timeout, self.hata)

    def read(self):
        self.data.clear()  #cihazdan okunan toplam veri her okumada sifirlanir.
        for x in range(0, len(self.code)):
            time.sleep(self.delay)
            if self.code[x] == "INPUT":
                # Read input unsigned registers
                if self.reg_type[x] == "UINT16":
                    #self.read_input_U16(x)
                    pass
                # Read input registers signed values
                elif self.reg_type[x] == "INT16":
                    pass
                    # multi float reading aproach from payload        Text
                    pass
            elif self.code[x] == "HOLDING":

                if self.reg_type[x] == "UINT16":
                    #self.read_input_U16(x)
                    pass
                # Read input registers signed values
                elif self.reg_type[x] == "INT16":
                    pass
                # multi float reading aproach from payload
                elif self.reg_type[x] == "FLOATS":
                    self.read_holding_floats(x)


#_________________________________Dictionary Version

    def ReadDict(self):
        if self.conn.is_socket_open():
            self.data = [
            ]  #cihazdan okunan toplam veri her okumada sifirlanir.
            for x in self.DevDict.keys():
                if x == 'HOLDING':
                    for y in self.DevDict[x].keys():
                        if y == 'UINT16':
                            pass
                        elif y == "INT16":
                            pass
                        elif y == "FLOAT":
                            for z in xrange(0,
                                            len(self.DevDict[x][y]['count'])):
                                self.read_holding_floats(
                                    self.DevDict[x][y]['start_reg'][z],
                                    self.DevDict[x][y]['count'][z],
                                    self.DevDict[x][y]['indexes'][z])
                else:
                    pass
        else:
            print "No active connection"

    def JustClose(self):
        self.conn.close()

    def socket(self):
        return self.conn.is_socket_open()
Пример #5
0
class SolarEdge:

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

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

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

        else:
            self.host = host
            self.port = port
            self.device = device

            if stopbits:
                self.stopbits = stopbits

            if parity:
                self.parity = parity

            if baud:
                self.baud = baud

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

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

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

    def _read_holding_registers(self, address, length):
        for i in range(self.retries):
            result = self.client.read_holding_registers(address=address, count=length, unit=self.unit)

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

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

        return None

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

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

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

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

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

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

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

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

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

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

            if not data:
                return results

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

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

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

        return results

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

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

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

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

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

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

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

            if not register_batch:
                break

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

        return results
Пример #6
0
from pymodbus.client.sync import ModbusTcpClient
import time

#P2 Adam HL Relay
#client = ModbusTcpClient('10.202.55.173', 502)

#Cognex Scanner P2 L3 BF
#client = ModbusTcpClient('10.202.193.182', 502)

#Cognex Insight
client = ModbusTcpClient('10.202.180.24', 502)

client.connect()
if client.is_socket_open():
    print('cllent is open')

#Cognex Holding Regs (Works)
#result = client.read_holding_registers(21566,1)

#result = client.read_input_registers(20542,1)

#result = client.read_input_registers(20546,1)

#Cognex Holding Regs (Works)
#result = client.read_holding_registers(20546,1)

#Cognex Holding Regs (Works)
#result = client.read_holding_registers(2000,100)

#Cognex Holding Regs (Works)
result = client.read_holding_registers(4000, 4)
Пример #7
0
class SDM:

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

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

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

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

            if stopbits:
                self.stopbits = stopbits

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

            if baud:
                self.baud = baud

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

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

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

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

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

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

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

        return None

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

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

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

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

        return None

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

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

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

        return builder.to_registers()

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

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

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

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

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

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

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

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

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

            if not data:
                return results

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

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

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

        return results

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

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

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

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

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

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

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

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

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

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

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

            if not register_batch:
                break

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

        return results
Пример #8
0
class Danbach_AGV():
    def __init__(self,
                 lwheel_scale=1.0,
                 rwheel_scale=1.0,
                 ip='192.168.10.30',
                 port=502,
                 timeout=7e-3):
        self.client = MbClient(ip, port=port, timeout=timeout)
        self.lwheel_scale = lwheel_scale
        self.rwheel_scale = rwheel_scale

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

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

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

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

        self.__set_wheel__(0, 0)

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

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

        self.__set_wheel__(0, 0)

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

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

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

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

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

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

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

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

        return L_WHEEL, R_WHEEL

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

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

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

        lspeed = lspeed + 0x10000 if lspeed < 0 else lspeed
        rspeed = rspeed + 0x10000 if rspeed < 0 else rspeed
        rq = self.client.write_registers(0x1620,
                                         [0x0001, lspeed, rspeed, 0, 0],
                                         unit=0x01)
Пример #9
0
def device_polling():

    if DashingEnabled:
        Dashlog.append("Starting device poller")
        ui.display()
    else:
        log.info("Starting device poller")

    CONF_ORNO = False
    CONF_EM370 = True
    CONF_SOLIS_4G_3P = True
    CONF_JANITZA_B23 = True
    CONF_EMONCMS = True
    RtuclientState = False

    QuerryNb = 0

    HostName = 'emoncms.powerdale.com'
    ModbusHost = "10.10.10.101"
    ModbusPort = 502

    emon_host = "emoncms.powerdale.com"
    emon_url = "/input/post.json?node="
    emon_privateKey = "4dbf608f20eab1ad1d1bf4512dc85d1c"
    emon_node = "B4E"

    # for cycle in range(0, 2000):
    #     vchart.append(50 + 50 * math.sin(cycle / 16.0))
    #     hchart.append(99.9 * abs(math.sin(cycle / 26.0)))
    #     bchart.append(50 + 50 * math.sin(cycle / 6.0))
    #     ui.display()

    OR_WE_514_Registers = testmap.generate_device_dict(
        './mapping_tools/or_we_514-v1-1_1.json')
    EEM_MA370_Registers = testmap.generate_device_dict(
        './mapping_tools/eem_ma370-v1-1_1.json')
    SOLIS_4G_Registers = testmap.generate_device_dict(
        './mapping_tools/solis_4g_3p-v1-1_1.json')
    JANITZA_B23_Registers = testmap.generate_device_dict(
        './mapping_tools/janitza_b23-v1-1_1.json')
    #print(OR_WE_514_Registers)
    #print(json.dumps(EEM_MA370_Registers, indent='\t'))
    #print(OR_WE_514_Registers)
    #print(EEM_MA370_Registers)
    print(SOLIS_4G_Registers)

    SolarInverter = copy.deepcopy(SOLIS_4G_Registers)
    Grid = copy.deepcopy(EEM_MA370_Registers)
    Evse = copy.deepcopy(JANITZA_B23_Registers)

    SOLIS_Config = {
        'Solar': {
            "NAME": "Inverter",
            "PORT": "/dev/ttyUSB0",
            "ADDRESS": 1,
            "DATA": SolarInverter
        }
    }

    EEM_Config = {
        'Grid': {
            "NAME": "Grid",
            "PORT": "",
            "ADDRESS": 1,
            "DATA": Grid
        }
    }

    B23_Config = {
        'Evse': {
            "NAME": "Evse",
            "PORT": "/dev/ttyUSB1",
            "ADDRESS": 2,
            "DATA": Evse
        }
    }
    # Create modbus clients
    if CONF_EM370:
        try:
            TcpClient = ModbusTcpClient(host=ModbusHost,
                                        port=ModbusPort,
                                        auto_open=True,
                                        timeout=5)
            if DashingEnabled:
                Dashlog.append(
                    f"Modbus TCP client connected: {TcpClient.connect()}")
            else:
                log.info(f"Modbus TCP client connected: {TcpClient.connect()}")
        except Exception as e:
            if DashingEnabled:
                DashErrors.append("Exception %s" % str(e))
                ui.display()
            else:
                log.info("Exception %s" % str(e))
                pass

    if CONF_SOLIS_4G_3P:
        try:
            Rtuclient = ModbusRtuClient(method='rtu',
                                        port='/dev/ttyUSB0',
                                        stopbits=1,
                                        bytesize=8,
                                        parity='N',
                                        baudrate=9600,
                                        timeout=1)
            if DashingEnabled:
                Dashlog.append(f"Modbus RTU port open: {Rtuclient.connect()}")
            else:
                print(f"Modbus RTU port open: {Rtuclient.connect()}")
        except Exception as e:
            if DashingEnabled:
                DashErrors.append("Exception %s" % str(e))
                ui.display()
            else:
                log.info("Exception %s" % str(e))
                pass

    if CONF_JANITZA_B23:
        try:
            Rtuclient2 = ModbusRtuClient(method='rtu',
                                         port='/dev/ttyUSB1',
                                         stopbits=1,
                                         bytesize=8,
                                         parity='N',
                                         baudrate=9600,
                                         timeout=1)
            if DashingEnabled:
                Dashlog.append(f"Modbus RTU port open: {Rtuclient2.connect()}")
            else:
                print(f"Modbus RTU port open: {Rtuclient2.connect()}")
        except Exception as e:
            if DashingEnabled:
                DashErrors.append("Exception %s" % str(e))
                ui.display()
            else:
                log.info("Exception %s" % str(e))
                pass

    try:
        while True:
            #os.system('cls' if os.name == 'nt' else 'clear')
            QuerryNb = QuerryNb + 1

            if CONF_EM370 and TcpClient.is_socket_open():

                if DashingEnabled:
                    Dashlog.append("Read EEM_MA370")
                    ui.display()
                else:
                    log.info("Read EEM_MA370")

                for x, z in EEM_Config.items():
                    if DashingEnabled:
                        Dashlog.append(f"Reading slave {z['NAME']}")
                    MyDict = z['DATA']
                    #print (MyDict)
                    for k, y in MyDict.items():
                        #Log.append(y['Name'])
                        if (y['Name'] == 'Active power'):
                            if DashingEnabled:
                                Dashlog.append(
                                    f"Active power: {y['Value']:.01f}W")
                                hchart.title = f"Active power: {y['Value']:.0f}W"
                                hchart.append(100 * y['Value'] / 5000)
                                ui.display()
                        rr = None
                        try:
                            rr = TcpClient.read_holding_registers(
                                y['Address'], y['Size'])
                        except Exception as e:
                            if DashingEnabled:
                                DashErrors.append("Exception %s" % str(e))
                                ui.display()
                            else:
                                log.info("Exception %s" % str(e))
                        if (isinstance(rr, ReadHoldingRegistersResponse)
                                and (len(rr.registers) == y['Size'])):
                            decoder = BinaryPayloadDecoder.fromRegisters(
                                rr.registers,
                                byteorder=Endian.Big,
                                wordorder=Endian.Little)
                            decoded = OrderedDict([
                                ('string', decoder.decode_string),
                                ('bits', decoder.decode_bits),
                                ('8int', decoder.decode_8bit_int),
                                ('8uint', decoder.decode_8bit_uint),
                                ('16int', decoder.decode_16bit_int),
                                ('16uint', decoder.decode_16bit_uint),
                                ('32int', decoder.decode_32bit_int),
                                ('32uint', decoder.decode_32bit_uint),
                                ('16float', decoder.decode_16bit_float),
                                ('16float2', decoder.decode_16bit_float),
                                ('32float', decoder.decode_32bit_float),
                                ('32float2', decoder.decode_32bit_float),
                                ('64int', decoder.decode_64bit_int),
                                ('64uint', decoder.decode_64bit_uint),
                                ('ignore', decoder.skip_bytes),
                                ('64float', decoder.decode_64bit_float),
                                ('64float2', decoder.decode_64bit_float),
                            ])
                            y['Value'] = round(
                                decoded[y['Type']]() * y['Scale'], 3)
                            #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units'])
                            #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}")
            #print("HOME")

            Rtuclient.connect()
            if CONF_SOLIS_4G_3P and Rtuclient.is_socket_open():
                if DashingEnabled:
                    Dashlog.append("Read Solis-4G inverter")
                    ui.display()
                else:
                    log.info("Read Solis-4G inverter")

                for x, z in SOLIS_Config.items():
                    if DashingEnabled:
                        Dashlog.append(f"Reading slave {z['NAME']}")
                        DashMeas1.append("")
                        DashMeas1.append(f"Reading slave {z['NAME']}")
                        ui.display()
                    else:
                        log.info(f"Reading slave {z['NAME']}")

                    MyDict = z['DATA']
                    #print (MyDict)
                    for k, y in MyDict.items():
                        #print(z['ADDRESS'],  y['Address'], y['Size'])
                        rr = None
                        try:
                            rr = Rtuclient.read_input_registers(
                                y['Address'], y['Size'], unit=z['ADDRESS'])
                        except Exception as e:
                            if DashingEnabled:
                                DashErrors.append("Exception %s" % str(e))
                                ui.display()
                            else:
                                log.info("Exception %s" % str(e))
                                pass
                        if (isinstance(rr, ReadInputRegistersResponse)
                                and (len(rr.registers) == y['Size'])):
                            decoder = BinaryPayloadDecoder.fromRegisters(
                                rr.registers,
                                byteorder=Endian.Big,
                                wordorder=Endian.Big)
                            decoded = OrderedDict([
                                ('string', decoder.decode_string),
                                ('bits', decoder.decode_bits),
                                ('8int', decoder.decode_8bit_int),
                                ('8uint', decoder.decode_8bit_uint),
                                ('16int', decoder.decode_16bit_int),
                                ('16uint', decoder.decode_16bit_uint),
                                ('32int', decoder.decode_32bit_int),
                                ('32uint', decoder.decode_32bit_uint),
                                ('16float', decoder.decode_16bit_float),
                                ('16float2', decoder.decode_16bit_float),
                                ('32float', decoder.decode_32bit_float),
                                ('32float2', decoder.decode_32bit_float),
                                ('64int', decoder.decode_64bit_int),
                                ('64uint', decoder.decode_64bit_uint),
                                ('ignore', decoder.skip_bytes),
                                ('64float', decoder.decode_64bit_float),
                                ('64float2', decoder.decode_64bit_float),
                            ])
                            y['Value'] = round(
                                decoded[y['Type']]() * y['Scale'], 3)
                            #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units'])
                            if DashingEnabled:
                                DashMeas1.append(
                                    f"{y['Name']} = {y['Value']:.02f} {y['Units']}"
                                )
                                ui.display()
                            #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}")
#                Rtuclient.close()

            Rtuclient2.connect()
            if CONF_JANITZA_B23 and Rtuclient2.is_socket_open():
                if DashingEnabled:
                    Dashlog.append("Read EVSE charger")
                    ui.display()
                else:
                    log.info("Read EVSE charger...")

                for x, z in B23_Config.items():
                    if DashingEnabled:
                        Dashlog.append(f"Reading slave {z['NAME']}")
                        DashMeas1.append("")
                        DashMeas1.append(f"Reading slave {z['NAME']}")
                        ui.display()
                    else:
                        log.info(f"Reading slave {z['NAME']}")

                    MyDict = z['DATA']
                    print(MyDict)
                    for k, y in MyDict.items():
                        #print(z['ADDRESS'],  y['Address'], y['Size'])
                        rr = None
                        try:
                            rr = Rtuclient2.read_holding_registers(
                                y['Address'], y['Size'], unit=z['ADDRESS'])
                        except Exception as e:
                            if DashingEnabled:
                                DashErrors.append("Exception %s" % str(e))
                                ui.display()
                            else:
                                log.info("Exception %s" % str(e))
                                pass

                        if (isinstance(rr, ReadHoldingRegistersResponse)
                                and (len(rr.registers) == y['Size'])):
                            decoder = BinaryPayloadDecoder.fromRegisters(
                                rr.registers,
                                byteorder=Endian.Big,
                                wordorder=Endian.Big)
                            decoded = OrderedDict([
                                ('string', decoder.decode_string),
                                ('bits', decoder.decode_bits),
                                ('8int', decoder.decode_8bit_int),
                                ('8uint', decoder.decode_8bit_uint),
                                ('16int', decoder.decode_16bit_int),
                                ('16uint', decoder.decode_16bit_uint),
                                ('32int', decoder.decode_32bit_int),
                                ('32uint', decoder.decode_32bit_uint),
                                ('16float', decoder.decode_16bit_float),
                                ('16float2', decoder.decode_16bit_float),
                                ('32float', decoder.decode_32bit_float),
                                ('32float2', decoder.decode_32bit_float),
                                ('64int', decoder.decode_64bit_int),
                                ('64uint', decoder.decode_64bit_uint),
                                ('ignore', decoder.skip_bytes),
                                ('64float', decoder.decode_64bit_float),
                                ('64float2', decoder.decode_64bit_float),
                            ])
                            y['Value'] = round(
                                decoded[y['Type']]() * y['Scale'], 3)
                            if math.isnan(y['Value']):
                                y['Value'] = 0
                            #print ( "Register: " + y['Name'] + " = " + str(y['Value']) + " " + y['Units'])
                            if DashingEnabled:
                                DashMeas1.append(
                                    f"{y['Name']} = {y['Value']:.02f} {y['Units']}"
                                )
                                ui.display()
                            #print ( f"Register: {y['Name']} = {y['Value']:.02f} {y['Units']}")


#                Rtuclient.close()

#print("HOME")
            if DashingEnabled:
                bchart.append(QuerryNb)
            else:
                log.info(f"Poller querry : {QuerryNb}")
            #print ( "Querry %s" % QuerryNb)

            if (CONF_EMONCMS and CONF_SOLIS_4G_3P):
                SolarPower = 0
                for x, z in SOLIS_Config.items():
                    if Rtuclient.is_socket_open():
                        reqdata = {}
                        #print("Slave: " + z['NAME'])
                        MyDict = z['DATA']
                        #print (z['DATA'])
                        for k, y in MyDict.items():
                            #DashErrors.append(y['Name'])
                            if (y['Name'] == 'Freq'):
                                vchart.append(50 + QuerryNb)
                            reqdata[f"{z['NAME']}{y['Name']}"] = y['Value']
                        #print('reqdata = {reqdata}')
                        req = MyEmon.senddata(reqdata)
                        reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}'

                        try:
                            r = requests.get(reqstr, timeout=10)
                            r.raise_for_status()
                        except requests.exceptions.HTTPError as errh:
                            print("Http Error:", errh)
                        except requests.exceptions.ConnectionError as errc:
                            print("Error Connecting:", errc)
                        except requests.exceptions.Timeout as errt:
                            print("Timeout Error:", errt)
                        except requests.exceptions.RequestException as err:
                            print("OOps: Something Else", err)

                        #print (r.status_code)
                        #log.info( f"EmonCMS send status {r.status_code}" )
                        if DashingEnabled:
                            Dashlog.append(
                                f"EmonCMS slave {z['NAME']} push status {r.status_code}"
                            )
                            ui.display()
                        else:
                            log.info(
                                f"EmonCMS slave {z['NAME']} push status {r.status_code}"
                            )
                        #print (r.content)

                    else:
                        #log.info( "EmonCMS ORNO unable to send" )
                        if DashingEnabled:
                            Dashlog.append(
                                f"EmonCMS slave {z['NAME']} nothing to push")
                            ui.display()
                        else:
                            log.info(
                                f"EmonCMS slave {z['NAME']} nothing to push")

            if (CONF_EMONCMS and CONF_JANITZA_B23):
                for x, z in B23_Config.items():
                    if Rtuclient2.is_socket_open():
                        reqdata = {}
                        #print("Slave: " + z['NAME'])
                        MyDict = z['DATA']
                        #print (z['DATA'])
                        for k, y in MyDict.items():
                            #DashErrors.append(y['Name'])
                            if (y['Name'] == 'Freq'):
                                vchart.append(50 + QuerryNb)
                            reqdata[f"{z['NAME']}{y['Name']}"] = y['Value']
                        #print('reqdata = {reqdata}')
                        req = MyEmon.senddata(reqdata)
                        reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}'

                        try:
                            r = requests.get(reqstr, timeout=10)
                            r.raise_for_status()
                        except requests.exceptions.HTTPError as errh:
                            print("Http Error:", errh)
                        except requests.exceptions.ConnectionError as errc:
                            print("Error Connecting:", errc)
                        except requests.exceptions.Timeout as errt:
                            print("Timeout Error:", errt)
                        except requests.exceptions.RequestException as err:
                            print("OOps: Something Else", err)

                        #print (r.status_code)
                        #log.info( f"EmonCMS send status {r.status_code}" )
                        if DashingEnabled:
                            Dashlog.append(
                                f"EmonCMS slave {z['NAME']} push status {r.status_code}"
                            )
                            ui.display()
                        else:
                            log.info(
                                f"EmonCMS slave {z['NAME']} push status {r.status_code}"
                            )
                        #print (r.content)

                    else:
                        #log.info( "EmonCMS ORNO unable to send" )
                        if DashingEnabled:
                            Dashlog.append(
                                f"EmonCMS slave {z['NAME']} nothing to push")
                            ui.display()
                        else:
                            log.info(
                                f"EmonCMS slave {z['NAME']} nothing to push")

            if (CONF_EMONCMS and CONF_EM370):
                for x, z in EEM_Config.items():
                    if TcpClient.is_socket_open():
                        reqdata = {}
                        #print("Slave: " + z['NAME'])
                        MyDict = z['DATA']
                        #print (z['DATA'])
                        for k, y in MyDict.items():
                            #DashErrors.append(y['Name'])
                            reqdata[f"{z['NAME']}{y['Name']}"] = y['Value']
                        #print('reqdata = {reqdata}')
                        reqstr = f'http://{emon_host}{emon_url}{emon_node}&json={json.dumps(reqdata)}&apikey={emon_privateKey}'

                        try:
                            r = requests.get(reqstr, timeout=10)
                            r.raise_for_status()
                        except requests.exceptions.HTTPError as errh:
                            print("Http Error:", errh)
                        except requests.exceptions.ConnectionError as errc:
                            print("Error Connecting:", errc)
                        except requests.exceptions.Timeout as errt:
                            print("Timeout Error:", errt)
                        except requests.exceptions.RequestException as err:
                            print("OOps: Something Else", err)

                        #print (r.status_code)
                        #log.info( f"EmonCMS send status {r.status_code}" )
                        if DashingEnabled:
                            Dashlog.append(
                                f"EmonCMS slave {z['NAME']} push status {r.status_code}"
                            )
                            ui.display()
                        else:
                            log.info(
                                f"EmonCMS slave {z['NAME']} push status {r.status_code}"
                            )
                        #print (r.content)
                    else:
                        #log.info( "EmonCMS ORNO unable to send" )
                        if DashingEnabled:
                            Dashlog.append(
                                f"EmonCMS slave {z['NAME']} nothing to push")
                            ui.display()
                        else:
                            log.info(
                                f"EmonCMS slave {z['NAME']} nothing to push")
            time.sleep(5)
    except Exception as e:
        print("Exception %s" % str(e))
Пример #10
0
class Drive:
    client = None
    queue = []

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

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

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

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

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

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

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

    def send_message(self, sensor, timestamp):
        t = time.localtime(timestamp / 1000000000)
        print("[" + time.strftime("%m/%d/%Y %H:%M:%S", t) + "] : Detection on channel (" + str(sensor.input) + ") : " + sensor.get_readable_state())
Пример #11
0
 def testTcpClientIsSocketOpen(self):
     ''' Test the tcp client is_socket_open method'''
     client = ModbusTcpClient()
     self.assertFalse(client.is_socket_open())
Пример #12
0
class ModbusTCPPlcConnector:
    """
    Instantiates the connection to a PLC via modbus/TCP.
    """
    def __init__(self, plc_ip_address, timeout=0):
        """
        :param plc_ip_address: The IP address of the PLC.
        """
        self.modbus_client = ModbusTcpClient(plc_ip_address, timeout=timeout)
        self.modbus_client.connect()

        # Map of motor controls to modbus/TCP bits.
        self.motor_controls = {
            "control-motor-up": int(ModbusTCPRegisters.ControlMotorUp),
            "control-motor-down": int(ModbusTCPRegisters.ControlMotorDown),
            "control-motor-left": int(ModbusTCPRegisters.ControlMotorLeft),
            "control-motor-right": int(ModbusTCPRegisters.ControlMotorRight)
        }
        # The proper names for the motor controls.
        self.motor_names = ["motorUp", "motorDown", "motorLeft", "motorRight"]

        # The proper names for the sensors.
        self.sensor_names = [
            "topSensor", "bottomSensor", "leftSensor", "rightSensor"
        ]

    def is_connected(self):
        """
        Is the client connected?
        :return: True is modbus client is connected
        """
        return self.modbus_client.is_socket_open()

    def get_values(self):
        """
        This function queries the state of the sensors and motor controls.
        :return: A dictionary of the state of the motor controls and the state of the sensors.
        """

        # Should the HMI not be connected to the PLC return all values as false so that while being in the disconnected
        # state, all sensors and motors are shown as off
        sensors = dict(
            zip(self.sensor_names, ["true"] * len(self.sensor_names)))
        motors = dict(zip(self.motor_names, ["true"] * len(self.motor_names)))

        if self.is_connected():

            try:
                # Read the four bits of motor state from the PLC over modbus/TCP.
                motor_values = self.modbus_client.read_coils(
                    int(ModbusTCPRegisters.PLCInputs), 4).bits[:4]

                # Read the four bits of sensors state from the PLC over modbus/TCP.
                sensor_values = self.modbus_client.read_discrete_inputs(
                    int(ModbusTCPRegisters.PLCInputs)).bits[:4]

                # Separate the limit switches of the punching arm from the light switches
                limit_switches = sensor_values[:2]

                # Separate the light switches from the limit switches of the punching arm.
                light_sensors = sensor_values[2:4]

                # The values of the motor manual values must be inverted to fit our logic.
                # The values are converted to strings.
                corrected_motor_values = [
                    str(not value).lower() for value in motor_values
                ]

                # The values are converted to strings.
                light_sensor_values = [
                    str(value).lower() for value in light_sensors
                ]

                # The values are converted to strings.
                limit_switch_values = [
                    str(value).lower() for value in limit_switches
                ]

                # Join the sensor values again.
                joined_sensor_values = limit_switch_values + light_sensor_values

                # Join the proper sensor names as keys with the corresponding sensor values into a dictionary.
                sensors = dict(zip(self.sensor_names, joined_sensor_values))

                # Join the proper motor manual names as keys with the corresponding motor manual values into a dictionary.
                motors = dict(zip(self.motor_names, corrected_motor_values))
            except:
                pass

        # Return the dictionary that contains the current motor manual values as well as sensor values.
        return {**sensors, **motors}

    def set_order(self, count):
        """
        Set an positive numeric value as amount of times the process is to be executed.
        :param count: Positive integer.
        :return: The PLC connectors response, so it can be use if of interest.
        """
        if self.is_connected():
            try:
                self.modbus_client.write_register(
                    int(ModbusTCPRegisters.Orders), count)
            except:
                pass

    def set_application_state(self, state):
        """
        Set the current application state.
        :param state:
        :return: The PLC connectors response, so it can be use if of interest.
        """
        state_value = application.Disconnected().modbus_value
        if self.is_connected():
            try:
                state_value = self.modbus_client.write_register(
                    int(ModbusTCPRegisters.HmiApplicationState),
                    state.modbus_value)
            except:
                pass
        return state_value

    def set_motor(self, motor, motor_state):
        """
        Turn a motor of the process manually on or off.
        :param motor: Which motor is to be set.
        :param motor_state: On or Off.
        :return: The PLC connectors response, so it can be use if of interest.
        """
        register = self.motor_controls[motor]
        state_value = application.Disconnected().modbus_value
        if self.is_connected():
            try:
                state_value = self.modbus_client.write_register(
                    register, int(motor_state))
            except:
                pass
        return state_value

    def set_reset(self):
        """
        Initiate the reset signal to get the PLC out of the emergency stop state.
        :return: The PLC connectors response, so it can be use if of interest.
        """
        state_value = application.Disconnected().modbus_value
        if self.is_connected():
            try:
                state_value = self.modbus_client.write_register(
                    int(ModbusTCPRegisters.Reset), 1)
            except:
                pass
        return state_value

    def get_orders(self):
        """
        Retrieve the amount of currently placed orders.
        :return: The order count.
        """
        state_value = application.Disconnected().modbus_value
        if self.is_connected():
            try:
                state_value = self.modbus_client.read_holding_registers(
                    int(ModbusTCPRegisters.Orders), 1).registers[0]
            except:
                pass
        return state_value

    def get_process_state(self):
        """
        Query the process state.
        :return: A dictionary containing the current process state.
        """
        state_value = process.PendingState().modbus_value
        if self.is_connected():
            try:
                state_value = \
                    self.modbus_client.read_holding_registers(int(ModbusTCPRegisters.ProcessState), 2).registers[0]
            except:
                pass
        return state_value

    def get_application_state(self):
        """
        Query the application state.
        :return: A dictionary containing the current application state.
        """
        state_value = application.Disconnected().modbus_value
        if self.is_connected():
            try:
                state_value = \
                    self.modbus_client.read_holding_registers(int(ModbusTCPRegisters.PlcApplicationState), 1).registers[
                        0]
            except:
                pass
        return state_value
Пример #13
0
class ModbusDevice(TerrawareDevice):
    def __init__(self, host, port, settings, diagnostic_mode, local_sim,
                 spec_file_name):
        settings_items = settings.split(';')
        self._host = host
        self._unit = 1  # aka modbus slave number
        for setting in settings_items:
            if setting.startswith('unit='):
                self._unit = int(setting.split('=')[1])
        self.last_update_time = None
        self._diagnostic_mode = diagnostic_mode
        framer = ModbusRtuFramer if ('rtu-over-tcp'
                                     in settings_items) else ModbusSocketFramer
        self._modbus_client = ModbusTcpClient(host, port=port, framer=framer)
        self._read_holding = ('holding' in settings_items)
        self._seq_infos = []
        self._local_sim = local_sim

        # load seqeuence info
        with open(spec_file_name) as csvfile:
            lines = csv.DictReader(csvfile)
            for line in lines:
                self._seq_infos.append(line)

        print('created modbus device (%s:%d, unit: %d)' %
              (host, port, self._unit))

    def reconnect(self):
        self._modbus_client.close()
        gevent.sleep(0.5)
        self._modbus_client.connect()

    def poll(self):
        if (not self._local_sim) and (
                not self._modbus_client.is_socket_open()):
            self._modbus_client.connect()
        values = {}
        for seq_info in self._seq_infos:
            address = int(seq_info['address'], 0)
            value = self.read_register(address, seq_info['type'], self._unit)
            if value is not None:
                value *= float(seq_info['scale_factor'])
                values[seq_info['name']] = value
                if self._diagnostic_mode:
                    print('    %s/%s: %.2f' %
                          (self.server_path, seq_info['name'], value))
#                if int(seq_info['send_to_server']):
#                    self._controller.sequence.create(seq_rel_path, 'numeric', decimal_places=2)
#                    seq_values[full_seq_name] = value
        if values:
            self.last_update_time = time.time()
        print('received %d of %d value(s) from %s' %
              (len(values), len(self._seq_infos), self.server_path))
        if len(values) != len(self._seq_infos):
            print('received fewer values than expected; reconnecting')
            self.reconnect()
            values = {
            }  # when this happens, we seem to get corrupt data; don't want to store that
        return values

    def read_register(self, address, register_type, unit):
        if self._local_sim:
            return random.randint(1, 100)
        if register_type.endswith('32'):
            count = 2
        else:
            count = 1
        if self._read_holding:
            result = self._modbus_client.read_holding_registers(address,
                                                                count,
                                                                unit=unit)
        else:
            result = self._modbus_client.read_input_registers(address,
                                                              count,
                                                              unit=unit)
        if not hasattr(result, 'registers'):
            return None
        if register_type == 'uint16' and len(result.registers) >= 1:
            return result.registers[0]
        elif register_type == 'sint16' and len(result.registers) >= 1:
            v = result.registers[0]
            if v > 0x7fff:  # rough sign manipulation; should check/fix
                v = v - 0x10000
            return v
        elif register_type == 'uint32' and len(result.registers) >= 2:
            return result.registers[0] * 0x10000 + result.registers[1]
        elif register_type == 'sint32' and len(result.registers) >= 2:
            v = result.registers[0] * 0x10000 + result.registers[1]
            if v > 0x7fffffff:  # rough sign manipulation; should check/fix
                v = v - 0x100000000
            return v
        else:
            return None
Пример #14
0
class spidar_v1(object):
    """
    class for handling modbus connections to Spidar V1 systems

    parameters
    ----------
        ip : string
            ip address or domain name of spidar
        port : int
            port for modbus access (default 502)
        unit : int
            slave number on bus (default 1)
    """
    def __init__(self, ip='', port=502, unit=1, connect=False):
        self.ip = ip
        self.port = port
        self.unit = unit
        self.init_registers()
        self.e = ''

        if connect is True:
            self.connect()

    def init_registers(self):
        self.hr = spidar_registers()

    def connect(self):
        """
        initialize self.ip, self.port, self.unit
        """
        from pymodbus.client.sync import ModbusTcpClient as ModbusClient

        self.client = ModbusClient(host=self.ip, port=self.port, unit=self.unit)
        logger.info("Connecting to {0}".format(self.ip))
        try:
            self.client.connect()
            if self.client.is_socket_open() is True:
                logger.info("Connected to Spidar OK")
            else:
                self.client.connect()
                if self.client.is_socket_open is not True:
                    logger.error('Could Not Connect to {0}'.format(self.ip))
                    raise ValueError('Could Not Connect to {0}'.format(self.ip))
        except Exception as e:
            self.e = e
            logger.error("Connection failed")
            logger.debug(self.e)

    def disconnect(self):
        logger.info("Disconnecting from {0}".format(self.ip))
        try:
            self.client.close()
            logger.info("Closed connection")
        except Exception as e:
            logger.error("Error closing connection")
            logger.debug(e)

    def return_rt_data_readings(self):
        """ refresh all registers """
        start_reg = 0
        length = 105

        self.read_result = self.read_single_register([start_reg, length], singles=True)

        self.hr.met_data['pressure']['value'] = self.read_result[1] * self.hr.met_data['pressure']['scaling']

        self.hr.met_data['temperature']['value'] = self.read_result[2] * self.hr.met_data['temperature']['scaling']
        if self.hr.met_data['temperature']['scaling'] > 100:
            self.hr.met_data['temperature']['value'] -= 656

        self.hr.met_data['humidity']['value'] = self.read_result[3] * self.hr.met_data['humidity']['scaling']
        self.hr.met_data['precipitation']['value'] = self.read_result[4] * self.hr.met_data['precipitation']['scaling']

        n = 5

        for gate in range(1, 10 + 1):
            self.hr.wind_data_gate[gate]['height']['value'] = self.read_result[n]
            self.hr.wind_data_gate[gate]['speed']['min']['value'] = self.read_result[n+1] * self.hr.wind_data_gate[gate]['speed']['min']['scaling']
            self.hr.wind_data_gate[gate]['speed']['max']['value'] = self.read_result[n+2] * self.hr.wind_data_gate[gate]['speed']['max']['scaling']
            self.hr.wind_data_gate[gate]['speed']['avg']['value'] = self.read_result[n+3] * self.hr.wind_data_gate[gate]['speed']['avg']['scaling']
            self.hr.wind_data_gate[gate]['speed']['sd']['value'] = self.read_result[n+4] * self.hr.wind_data_gate[gate]['speed']['sd']['scaling']
            self.hr.wind_data_gate[gate]['dir']['min']['value'] = self.read_result[n+5] * self.hr.wind_data_gate[gate]['dir']['min']['scaling']
            self.hr.wind_data_gate[gate]['dir']['max']['value'] = self.read_result[n+6] * self.hr.wind_data_gate[gate]['dir']['max']['scaling']
            self.hr.wind_data_gate[gate]['dir']['avg']['value'] = self.read_result[n+7] * self.hr.wind_data_gate[gate]['dir']['avg']['scaling']
            self.hr.wind_data_gate[gate]['dir']['sd']['value'] = self.read_result[n+8] * self.hr.wind_data_gate[gate]['dir']['sd']['scaling']
            self.hr.wind_data_gate[gate]['quality']['value'] = self.read_result[n+9]

            n += 10


    def read_single_register(self, register, singles=False):
        """
        wrapper for pymodbus, returns single value
        """

        try:
            rr = self.client.read_holding_registers(register[0], register[1], unit=1)
            self.rr = rr

            if register[1] > 2 and singles is True:
                flo = rr.registers

            else:
                flo = rr.registers[0]

            return flo

        except Exception as e:
            self.e = e
            self.rr = rr
            return 9999
Пример #15
0
class ipackaccess(object):
    """
    class for handling modbus connections to iPackACCESS

    parameters
    ----------
        ip : string
            ip address or domain name of iPack
        port : int
            port for modbus access (default 502)
        unit : int
            slave number on bus (default 1)
        logger_model : int
            finished good number of connected Symphonie (default 8206)
    """
    def __init__(self,
                 ip='',
                 port=502,
                 logger_model=8206,
                 unit=1,
                 connect=True):
        self.ip = ip
        self.logger_model = logger_model
        self.port = port
        self.unit = unit
        self.init_registers()
        self.e = ''
        if connect is True:
            self.connect()

    def init_registers(self):
        """
        set registers for all available data manually
        each is a list
         0 = register address
         1 = number of registers
        """
        self.hr = ipackaccess_registers()

    def connect(self):
        """
        initialize self.ip, self.port, self.unit
        """
        from pymodbus.client.sync import ModbusTcpClient as ModbusClient

        self.client = ModbusClient(host=self.ip,
                                   port=self.port,
                                   unit=self.unit)

        logger.info("Connecting to {0}".format(self.ip))

        try:
            self.client.connect()
            if self.client.is_socket_open() is True:
                logger.info("Connected OK")
            else:
                self.client.connect()
                if self.client.is_socket_open is not True:
                    logger.error('Could Not Connect to {0}'.format(self.ip))
                    raise ValueError('Could Not Connect to {0}'.format(
                        self.ip))
        except Exception as e:
            self.e = e
            logger.error("Connection failed")
            logger.debug(self.e)

    def disconnect(self):
        logger.info("Disconnecting from {0}".format(self.ip))
        try:
            self.client.close()
            logger.info("Closed connection")
        except Exception as e:
            logger.error("Error closing connection")
            logger.debug(e)

    def poll(self,
             interval=4,
             reconnect=True,
             stat=True,
             rt=True,
             serial=False,
             diag=False,
             config=False,
             db='',
             save_to_db=False,
             echo=False):
        """
        regularly poll registers

        parameters : (default value)
              interval : seconds to wait between polls (4)
             reconnect : automatically reconnect on failure (True)
                  stat : poll statistical registers (True)
                    rt : poll real time registers (True)
                serial : poll serial registers (False)
                  diag : poll diagnostic registers (False)
                config : poll config registers (False)
                    db : sqlite3 db to save to ('')
            save_to_db : save to db? (False)
                  echo : print some data to console (False)

        returns register values as individual and packages arrays
        """
        from time import time, sleep
        i = 0
        # set up database connection if save_to_db is True
        while True:
            poll_time = time()
            i += 1
            if self.e != '':
                if reconnect is True:
                    self.connect()
                else:
                    return "Disconnected from {0}, reconnect disabled".format(
                        self.ip)
                self.e = ''

            if stat is True:
                self.return_stat_readings()
            if rt is True:
                self.return_rt_data_readings()
            if serial is True:
                self.return_rt_serial_readings()
            if diag is True:
                self.return_diag_readings()
            if config is True:
                self.return_config()

            if save_to_db is True:
                # do the db things
                pass

            if echo is True:
                if rt is True:
                    print("{0}\t{1}\t{2}\t{3}".format(i, self.date_time,
                                                      self.rt_ch1,
                                                      self.rt_ch13))
                else:
                    print("Poll # {0}".format(i))

            while time() < poll_time + interval:
                sleep(0.01)

    def return_diag_readings(self):
        """ data from diagnostic registers

        returns
        -------
        dict
            see ipackaccess.registers for more info

        """
        for i in self.hr.diag:
            try:
                self.hr.diag[i]['value'] = self.read_single_register(
                    self.hr.diag[i]['reg'])
            except KeyError:
                pass

        self.hr.diag['datetime'] = {
            'value':
            f"{str(self.hr.diag['year']['value'])}-{str(self.hr.diag['month']['value']).zfill(2)}-{str(self.hr.diag['day']['value']).zfill(2)} {str(self.hr.diag['hour']['value']).zfill(2)}:{str(self.hr.diag['minute']['value']).zfill(2)}:{str(self.hr.diag['second']['value']).zfill(2)}"
        }

    def return_system_readings(self):
        """ logger and ipack system information

        returns
        -------
        dict
            see ipackaccess.registers for more info

        """
        start_reg = 0
        length = 21

        self.read_result = self.read_single_register([start_reg, length],
                                                     singles=True)

        self.hr.logger['signed_num_ex']['value'] = combine_u32_registers(
            self.read_result[0:2])
        self.hr.logger['unsigned_num_ex']['value'] = combine_u32_registers(
            self.read_result[2:4])
        self.hr.logger['unsigned_16_num_ex']['value'] = self.read_result[4]
        self.hr.logger['site_number']['value'] = combine_u32_registers(
            self.read_result[5:7])
        self.hr.logger['sn']['value'] = combine_u32_registers(
            self.read_result[7:9])
        self.hr.logger['model']['value'] = self.read_result[9]
        self.hr.logger['hw_ver']['value'] = combine_u32_registers(
            self.read_result[10:12])
        self.hr.logger['fw_ver']['value'] = combine_u32_registers(
            self.read_result[12:14])
        self.hr.ipack['sn']['value'] = combine_u32_registers(
            self.read_result[14:16])
        self.hr.ipack['model']['value'] = self.read_result[16]
        self.hr.ipack['hw_ver']['value'] = combine_u32_registers(
            self.read_result[17:19])
        self.hr.ipack['fw_ver']['value'] = combine_u32_registers(
            self.read_result[19:21])

    def return_all_channel_data(self):
        """
        poll statistical registers
        """
        for ch in self.hr.data_ch:
            for i in self.hr.data_ch[ch]:
                self.hr.data_ch[ch][i]['value'] = self.read_single_register(
                    self.hr.data_ch[ch][i]['reg'])

    def return_channel_data(self, channel):
        """
        poll statistical registers

        parameters
        ----------
            channel : int
                channel number to poll

        returns
        -------
        dict
            populates value of channel dict

        example
        -------
        >>> poller.return_channel_data(1)
        >>> poller.data_ch[1]

        """
        for i in self.hr.data_ch[channel]:
            self.hr.data_ch[channel][i]['value'] = self.read_single_register(
                self.hr.data_ch[channel][i]['reg'])

    def return_time(self):
        """
        returns time from config registers
        """
        self.read_result = self.read_single_register([1500, 6], singles=True)

        self.hr.samp_time['year']['value'] = self.read_result[0]
        self.hr.samp_time['month']['value'] = self.read_result[1]
        self.hr.samp_time['day']['value'] = self.read_result[2]
        self.hr.samp_time['hour']['value'] = self.read_result[3]
        self.hr.samp_time['minute']['value'] = self.read_result[4]
        self.hr.samp_time['second']['value'] = self.read_result[5]
        self.hr.samp_time['datetime'] = {
            'value':
            f"{str(self.hr.samp_time['year']['value'])}-{str(self.hr.samp_time['month']['value']).zfill(2)}-{str(self.hr.samp_time['day']['value']).zfill(2)} {str(self.hr.samp_time['hour']['value']).zfill(2)}:{str(self.hr.samp_time['minute']['value']).zfill(2)}:{str(self.hr.samp_time['second']['value']).zfill(2)}"
        }

    def return_rt_data_readings(self):
        """ refresh all 'samp' data values """
        self.return_time()

        start_reg = 1506
        length = 100

        self.read_result = self.read_single_register([start_reg, length],
                                                     singles=True)
        ch = 1
        for i in range(0, len(self.read_result), 2):
            self.hr.data_ch[ch]['samp']['value'] = combine_registers(
                self.read_result[i:i + 2])
            ch += 1

        start_reg = 3500
        length = 20

        self.read_result = self.read_single_register([start_reg, length],
                                                     singles=True)
        ch = 100
        for i in range(0, len(self.read_result), 2):
            self.hr.data_ch[ch]['samp']['value'] = combine_registers(
                self.read_result[i:i + 2])
            ch += 1

    def read_registers(self, list_of_registers_to_read):
        """
        returns array of converted values
        """
        return_values = []
        for reg in list_of_registers_to_read:
            try:
                return_values.append(self.read_single_register(reg))
            except:
                return_values.append(9999)
        return return_values

    def read_single_register(self, register, singles=False):
        """
        wrapper for pymodbus, returns single value
        """
        try:
            rr = self.client.read_holding_registers(register[0],
                                                    register[1],
                                                    unit=1)
            self.rr = rr

            if register[1] == 2 and singles is False:
                flo = combine_registers(rr.registers)

            elif register[1] > 2 and singles is False:
                flo = []
                for i in range(0, len(rr.registers), 2):
                    temp = combine_registers(
                        [rr.registers[i], rr.registers[i + 1]])
                    flo.append(temp)

            elif register[1] > 2 and singles is True:
                flo = rr.registers

            else:
                flo = rr.registers[0]

            return flo

        except Exception as e:
            self.e = e
            self.rr = rr
            return 9999

    def monitor(self):
        """

        """
        pass