Exemplo n.º 1
2
class ModbusClientRS:
    def __init__(self):
        self.client = ModbusClient()

    def writeRegister(self, address, value):
        if self.client.is_open():
            return self.client.write_single_register(address, value)
        return None

    def readRegister(self, address, value):
        if self.client.is_open():
            self.client.read_holding_registers(address, value)

    def connect(self, host, port):
        # self.client.debug(True)
        self.client.host(SERVER_HOST)
        self.client.port(SERVER_PORT)

        if not self.client.is_open():
            if not self.client.open():
                print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT))

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

    def disconnect(self):
        return self.client.close()
Exemplo n.º 2
1
def test():
    c = ModbusClient()
    # uncomment this line to see debug message
    # c.debug(True)
    # define modbus server host, port
    c.host(SERVER_HOST)
    c.port(SERVER_PORT)
    while True:
        # open or reconnect TCP to server
        if not c.is_open():
            if not c.open():
                print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT))

        # if open() is ok, read register (modbus function 0x03)
        if c.is_open():
            print c.write_single_register(504, intToUint16(-216))

        # sleep 2s before next polling
        time.sleep(2)
Exemplo n.º 3
0
class TestClientServer(unittest.TestCase):

    def setUp(self):
        # modbus server
        self.server = ModbusServer(port=5020, no_block=True)
        self.server.start()
        # modbus client
        self.client = ModbusClient(port=5020)
        self.client.open()

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

    def test_read_and_write(self):
        # word space
        self.assertEqual(self.client.read_holding_registers(0), [0], 'Default value is 0 when server start')
        self.assertEqual(self.client.read_input_registers(0), [0], 'Default value is 0 when server start')
        # single read/write
        self.assertEqual(self.client.write_single_register(0, 0xffff), True)
        self.assertEqual(self.client.read_input_registers(0), [0xffff])
        # multi-write at max size
        words_l = [randint(0, 0xffff)] * 0x7b
        self.assertEqual(self.client.write_multiple_registers(0, words_l), True)
        self.assertEqual(self.client.read_holding_registers(0, len(words_l)), words_l)
        self.assertEqual(self.client.read_input_registers(0, len(words_l)), words_l)
        # write over sized
        words_l = [randint(0, 0xffff)] * 0x7c
        self.assertEqual(self.client.write_multiple_registers(0, words_l), None)
        # bit space
        self.assertEqual(self.client.read_coils(0), [False], 'Default value is False when server start')
        self.assertEqual(self.client.read_discrete_inputs(0), [False], 'Default value is False when server start')
        # single read/write
        self.assertEqual(self.client.write_single_coil(0, True), True)
        self.assertEqual(self.client.read_coils(0), [True])
        self.assertEqual(self.client.read_discrete_inputs(0), [True])
        # multi-write at min size
        bits_l = [getrandbits(1)] * 0x1
        self.assertEqual(self.client.write_multiple_coils(0, bits_l), True)
        self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l)
        self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l)
        # multi-write at max size
        bits_l = [getrandbits(1)] * 0x7b0
        self.assertEqual(self.client.write_multiple_coils(0, bits_l), True)
        self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l)
        self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)), bits_l)
        # multi-write over sized
        bits_l = [getrandbits(1)] * 0x7b1
        self.assertEqual(self.client.write_multiple_coils(0, bits_l), None)
Exemplo n.º 4
0
class Plugin(LoggerPlugin):
    """
Zeichnet die Messdaten einer Heliotherm-Wärmepumpe (mit Remote Control Gateway X SERIES EL-005-0001 ab v1.0.3.2 - 10.12.2018) auf.
Modbus-TCP muss im Webinterface der Wärmepumpe aktiviert sein und im Anschluss die IP-Adresse der Wärmepumpe im Parameter "IP_Adresse" eingetragen werden.
    """
    def __init__(self, *args, **kwargs):
        # Plugin setup
        super(Plugin, self).__init__(*args, **kwargs)
        self.setDeviceName('Heliotherm')
        
        self._connected = False
        self.__doc_connected__ = "Zeigt an, ob eine Wärmepumpe verbunden ist"
        self.status = ""
        self.__doc_status__ = "Zeigt Verbindungs-Informationen an, falls vorhanden"
        self._firstStart = True
        self._lastStoerung = False
        self._lastExtAnf = True
        self._lastMode = 0
        self._c = None

        # Initialize persistant attributes
        self.IP_Adresse = self.initPersistentVariable('IP_Adresse', '')
        self.__doc_IP_Adresse__ = "IP-Adresse des RCG2 der Heliotherm-Wärmepumpe"
        self.samplerate = self.initPersistentVariable('samplerate', 1)
        self.__doc_samplerate__ = "Aufzeichnungsrate in Herz"
        self.Port = self.initPersistentVariable('Port', 502)
        self.__doc_Port__ = "ModbusTCP-Port (Standart: 502)"
        self._groups = self.initPersistentVariable('_groups', {'Global': True})
        # Load mapping.json file
        self._groupInfo = {}
        self._mappingWrite = []
        self._mappingRead = []
        self._loadMapping()

        # Update self._groups
        for group in self._groupInfo.keys():
            if group not in self._groups.keys():
                self._groups[group] = False

        self._createGroupAttributes(self._groups)

        # Create attributes for
        self._createAttributes(self._mappingWrite)
        self.connect()

    @property
    def connected(self):
        return self._connected

    @connected.setter
    def connected(self, value):
        if value is True:
            self.connect()
        elif value is False:
            self.disconnect()
        # self._connected = value

    def _loadMapping(self):
        packagedir = self.getDir(__file__)
        with open(packagedir+"/mapping.json", encoding="UTF-8") as jsonfile:
            mapping = json.load(jsonfile, encoding="UTF-8")

        self._groupInfo = mapping['groups']
        self._mappingWrite = mapping['mappingWrite']
        self._mappingRead = mapping['mappingRead']


    def _createAttributes(self, mappingWrite):
        groups = self._activeGroups()
        for parameter in mappingWrite:
            if parameter['group'] in groups:
                # Replace invalid chars for attribute names
                name = self._formatAttributeName(parameter['sname'])
                # Create 'private' parameter with _ in front: self._name
                setattr(self.__class__, '_'+name, None)

                # This intermediate function handles the strange double self arguments
                def setter(self, name, parameter, selfself, value):
                    self._setAttribute(name, value, parameter)

                # Make sure, that the parameters are "the values, which would be represented at this point with print(...)"
                setpart = partial(setter, self, name, parameter)
                getpart = partial(getattr, self, '_'+name)

                # Create an attribute with the actual name. The getter refers to it's self._name attribute. The setter function to self._setGroupAttribute(name, value, parameter)
                setattr(self.__class__, name, property(getpart, setpart))

                # If parameter contains docs, create a third attribute at self.__doc_PARNAME__
                if "doc" in parameter.keys():
                    setattr(self, '__doc_'+name+'__', parameter['doc'])

    def _activeGroups(self):
        groups = []
        for group in self._groups.keys():
            if self._groups[group] is True:
                groups.append(group)

        return groups

    def _createGroupAttributes(self, groups):
        for groupname in groups.keys():
                # Replace invalid chars for attribute names
                name = 'Gruppe_'+self._formatAttributeName(groupname)
                # Create 'private' parameter with _ in front: self._name
                setattr(self.__class__, '_'+name, groups[groupname])

                # This intermediate function handles the strange double self arguments
                def setter(self, name, parameter, selfself, value):
                    self._setGroupAttribute(name, value, parameter)

                # Make sure, that the parameters are "the values, which would be represented at this point with print(...)"
                setpart = partial(setter, self, name, groupname)
                getpart = partial(getattr, self, '_'+name)

                # Create an attribute with the actual name. The getter refers to it's self._name attribute. The setter function to self._setAttribute(name, value, parameter)
                setattr(self.__class__, name, property(getpart, setpart))

                setattr(self, '__doc_'+name+'__', self._groupInfo[groupname])

    def _setAttribute(self, name, value, parameter):
        if self._c is None:
            return

        if parameter['write'] is False:
            self.warning('This parameter cannot be changed')
            self.status = 'This parameter cannot be changed'
        else:
            ok = self._writeModbusRegister(parameter, value)
            if ok:
                self.info('Wrote register in WP')
                self.status = 'Wrote register in WP'
            else:
                self.error('Failed to write register in WP')
                self.status = 'Failed to write register in WP'

    def _setAttributeRef(self, name, value, parameter):
        name = self._formatAttributeName(name)
        setattr(self, '_'+name, value)

    def _formatAttributeName(self, name):
        return name.replace(' ','_').replace('/','_').replace('.','_').replace('-','_')

    def _setGroupAttribute(self, name, value, groupname):
        name = self._formatAttributeName(name)
        setattr(self, '_'+name, value)
        self._groups[groupname] = value
        self.savePersistentVariable('_groups', self._groups)

    def connect(self, ip=None):
        """
Verbinde dich mit einer Heliotherm Wärmepumpe (mit RCG2). Gib dazu die IP-Adresse/den Hostnamen an. Wenn die IP-Adresse schonmal konfiguriert wurde, lasse das Feld einfach leer.
        """
        if ip != None and ip != '' and type(ip) is str:
            self.IP_Adresse = ip
            self.savePersistentVariable('IP_Adresse', self.IP_Adresse)
        self.info('Connecting with {}'.format(self.IP_Adresse))
        if not self._connected:
            try:
                self.setPerpetualTimer(self._readModbusRegisters, samplerate=self.samplerate)
                self._c = ModbusClient(host=self.IP_Adresse, port=self.Port, auto_open=True, auto_close=True)
                if self._c is None:
                    self.error('Could not connect with {}'.format(self.IP_Adresse))
                    self.status = 'Could not connect with {}'.format(self.IP_Adresse)
                    return False
                self._c.timeout(10)
                self.status = 'Trying to connect...'
                self.start()
                self._connected = True
                return True
            except Exception as e:
                self.error('Could not connect with {}:\n{}'.format(self.IP_Adresse, e))
                self.status = 'Could not connect with {}:\n{}'.format(self.IP_Adresse, e)
                return False
        else:
            self.status = 'Already connected. Disconnect first'
            return False
    
    def disconnect(self):
        """
Trenne die Verbindung zu der Heliotherm Wärmepumpe
        """
        if self._connected:
            self.cancel()
            self._connected = False
            self._c = None
            self.status = 'Successfully disconnected'
            return True
        else:
            self.status = 'Cannot disconnect. Not connected.'
            return False
    
    def _mappingMinMaxRegister(self, mapping):
        min = 9999999999999
        max = 0
        for parameter in mapping:
            if parameter['register']> max:
                max = parameter['register']
            if parameter['register']< min:
                min = parameter['register']
        return min, max

    def _readModbusRegisters(self):
        if self._c == None:
            return
        active_groups = self._activeGroups()

        writeStart=100
        writeEnd=159
        resultWrite = self._c.read_holding_registers(writeStart, writeEnd-writeStart+1)
        if type(resultWrite) != list:
            writeStart=100
            writeEnd=134
            resultWrite = self._c.read_holding_registers(writeStart, writeEnd-writeStart+1)

        ans = {}
        if type(resultWrite) == list:
            for parameter in self._mappingWrite:
                if parameter['group'] in active_groups:
                    regIdx= parameter['register']-writeStart
                    if regIdx >= len(resultWrite):
                        continue

                    writeableValue = resultWrite[regIdx]
                    if writeableValue>=2 **16/2:
                        writeableValue = 2 **16 - writeableValue
                    writeableValue = writeableValue/parameter['scale']

                    if parameter['record']:
                        ans[parameter['sname']]=[writeableValue, parameter['unit']]

                    # if parameter['write'] is True:
                    self._setAttributeRef(self._formatAttributeName(parameter['sname']), writeableValue, parameter)

                    if parameter['sname'] == "Betriebsart":
                        if not self._firstStart and writeableValue != self._lastMode:
                            mode = self._modes[writeableValue]
                            self.event('Betriebsart wurde verändert: {}'.format(mode),parameter['sname'],self._devicename, 0, 'ModusChanged')
                        self._lastMode = writeableValue
                    elif parameter['sname'] == "Externe Anforderung":
                        if not self._firstStart and writeableValue != self._lastExtAnf:
                            if writeableValue == 1:
                                self.event('Externe Anforderung angeschaltet',parameter['sname'],self._devicename, 0, 'ExtAnfAn')
                            else:
                                self.event('Externe Anforderung ausgeschaltet',parameter['sname'],self._devicename, 0, 'ExtAnfAus')
                        self._lastExtAnf = writeableValue
        else:
            self.warning('Could not read writeable-registers, {}'.format(resultWrite))
            self.status = 'Could not read writeable-registers, {}'.format(resultWrite)

        readStart=10
        readEnd=75
        resultRead = self._c.read_input_registers(readStart, readEnd-readStart+1)
        
        if type(resultRead) == list:
            for parameter in self._mappingRead:
                if parameter['group'] in active_groups:
                    regIdx= parameter['register']-readStart
                    if regIdx >= len(resultRead):
                        continue

                    writeableValue = resultRead[regIdx]
                    if writeableValue>=2 **16/2:
                        writeableValue = 2 **16 - writeableValue
                    writeableValue = writeableValue/parameter['scale']

                    if parameter['record']:
                        ans[parameter['sname']]=[writeableValue, parameter['unit']]

                    if parameter['sname'] == 'Stoerung':
                        if not self._firstStart and writeableValue != self._lastStoerung:
                            if writeableValue != 0:
                                self.event('Störung aufgetreten: {}!'.format(writeableValue),parameter['sname'],self._devicename, 2, 'StoerungAn')
                            else:
                                self.event('Störung wurde behoben!',parameter['sname'],self._devicename, 0, 'StoerungAus')
                        self._lastStoerung = writeableValue

            self._firstStart = False
            self.status = 'Connected'
        else:
            self.warning('Could not read read-registers, {}'.format(resultRead))
            self.status = 'Could not read read-registers, {}'.format(resultRead)

        self.stream(sdict={self._devicename:ans})

    def _writeModbusRegister(self, parameter, reg_value):
        # if str(reg_addr) in self._mappingWrite.keys():
        ans = self._c.write_single_register(parameter['register'],reg_value*parameter['scale'])
        if ans == True:
            return True
        else:
            return False
Exemplo n.º 5
0
class TestClientServer(unittest.TestCase):
    port = 5020

    def setUp(self):
        # modbus server
        self.server = ModbusServer(port=TestClientServer.port, no_block=True)
        self.server.start()
        # modbus client
        self.client = ModbusClient(port=TestClientServer.port)
        self.client.open()
        # to prevent address taken errors
        TestClientServer.port += 1

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

    @repeat
    def test_word_init(self):
        # word space
        self.assertEqual(self.client.read_holding_registers(0), [0],
                         'Default value is 0 when server start')
        self.assertEqual(self.client.read_input_registers(0), [0],
                         'Default value is 0 when server start')

    @repeat
    def test_word_single(self):
        # single read/write
        self.assertEqual(self.client.write_single_register(0, 0xffff), True)
        self.assertEqual(self.client.read_input_registers(0), [0xffff])

    @repeat
    def test_word_multi(self):
        # multi-write at max size
        words_l = [randint(0, 0xffff)] * 0x7b
        self.assertEqual(self.client.write_multiple_registers(0, words_l),
                         True)
        self.assertEqual(self.client.read_holding_registers(0, len(words_l)),
                         words_l)
        self.assertEqual(self.client.read_input_registers(0, len(words_l)),
                         words_l)

    @repeat
    def test_word_oversize(self):
        # write over sized
        words_l = [randint(0, 0xffff)] * 0x7c
        self.assertEqual(self.client.write_multiple_registers(0, words_l),
                         None)

    @repeat
    def test_bit_init(self):
        # bit space
        self.assertEqual(self.client.read_coils(0), [False],
                         'Default value is False when server start')
        self.assertEqual(self.client.read_discrete_inputs(0), [False],
                         'Default value is False when server start')

    @repeat
    def test_bit_single(self):
        # single read/write
        self.assertEqual(self.client.write_single_coil(0, True), True)
        self.assertEqual(self.client.read_coils(0), [True])
        self.assertEqual(self.client.read_discrete_inputs(0), [True])

    @repeat
    def test_bit_multi_min(self):
        # multi-write at min size
        bits_l = [getrandbits(1)] * 0x1
        self.assertEqual(self.client.write_multiple_coils(0, bits_l), True)
        self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l)
        self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)),
                         bits_l)

    @repeat
    def test_bit_multi_max(self):
        # multi-write at max size
        bits_l = [getrandbits(1)] * 0x7b0
        self.assertEqual(self.client.write_multiple_coils(0, bits_l), True)
        self.assertEqual(self.client.read_coils(0, len(bits_l)), bits_l)
        self.assertEqual(self.client.read_discrete_inputs(0, len(bits_l)),
                         bits_l)

    @repeat
    def test_bit_multi_oversize(self):
        # multi-write over sized
        bits_l = [getrandbits(1)] * 0x7b1
        self.assertEqual(self.client.write_multiple_coils(0, bits_l), None)
Exemplo n.º 6
0
class ModbusClass():
    def __init__(self, host, port):
        self.c = ModbusClient(host=host, port=port)
        self.registers = {i: 0 for i in range(10)}
        self.connectLock = threading.Lock()
        self.regiLock = threading.Lock()
        # count = 5
        if self.c.open():
            print("connect success")
        else:
            print("connect failed")

        print("start reading threading")
        readThread = threading.Thread(target=self.readFromSlaveLoop)
        readThread.start()

    def connection(f):
        def checkConnection(self, *args, **kwargs):
            while not self.c.is_open():
                self.connectLock.acquire()
                self.c.open()
                print("reconnecting")
                self.connectLock.release()
                if self.c.is_open():
                    print("reconnected")
                    break
                time.sleep(2)

            f(self)

        return checkConnection

    def readFromSlaveLoop(self):
        while True:
            self.readFromSlave()

    @connection
    def readFromSlave(self):

        self.regiLock.acquire()
        self.connectLock.acquire()
        if self.c.is_open():
            # print("reading...")
            tempR = self.registers
            try:
                t = self.c.read_holding_registers(0, 10)
                self.registers = {i: t[i] for i in range(0, len(t))}
                print(self.registers)
            except:
                self.registers = tempR
            # print("end reading")
        self.regiLock.release()
        self.connectLock.release()

        time.sleep(1)

    def writeToSlave(self, writeDict):
        self.connectLock.acquire()
        if self.c.is_open():
            for k, v in writeDict.items():
                self.c.write_single_register(k, v)
            print("write success")
            return True
        self.connectLock.release()
        return False

    # def getGoodsFromAGV(self, orderId):
    #     self.writeToSlave(self.addSerialNum(orderId, COMMAND['TakeGoodsToAGV']))

    # def takeGoodsToAGV(self, orderId):
    #     self.writeToSlave(self.addSerialNum(orderId, COMMAND['GetGoodsFromAGV']))

    def getRegisters(self):
        self.regiLock.acquire()
        temp = self.registers
        self.regiLock.release()
        for k, v in temp.items():
            temp[k] = "%04d" % int(v)
        return temp

    def addSerialNum(self, work_order, wDict):
        wDict[0] = ord(work_order[0]) * 10 + int(work_order[1])
        wDict[1] = int(work_order[2]) * 1000 + int(work_order[3]) * 100 + int(
            work_order[4]) * 10 + int(work_order[5]) * 1
        return wDict

    def reconnect(self):
        self.c.open()
Exemplo n.º 7
0
def set_FW_power(ModbusClient):
    # Sets the forward power set point to 200 W
    # c is ModbusClient
    wr = ModbusClient.write_single_register(0, 0)
    print('set_FW_power:' + str(int(wr)))
    return wr
Exemplo n.º 8
0
while True:
    # open or reconnect TCP to server
    if not c.is_open():
        if not c.open():
            print("unable to connect to " + SERVER_HOST + ":" +
                  str(SERVER_PORT))

    # if open() is ok, write coils (modbus function 0x01)
    if c.is_open():
        # write 4 bits in modbus address 0 to 3
        print("")
        print("write register")
        print("----------")
        print("")
        if (toggle):
            is_ok = c.write_single_register(addr, 0xF0)
            if is_ok:
                print("register #" + str(addr) + ": write to " + str(0xF0))
            else:
                print("bit #" + str(addr) + ": unable to write " + str(0xF0))
            time.sleep(0.5)
        else:
            is_ok = c.write_single_register(addr, 0x0F)
            if is_ok:
                print("register #" + str(addr) + ": write to " + str(0x0F))
            else:
                print("bit #" + str(addr) + ": unable to write " + str(0x0F))
            time.sleep(0.5)

        time.sleep(1)
Exemplo n.º 9
0
from pyModbusTCP.client import ModbusClient
import time

SERVER_HOST = "192.168.0.104"
SERVER_PORT = 502

c = ModbusClient()

# uncomment this line to see debug message
#c.debug(True)

# define modbus server host, port
c.host(SERVER_HOST)
c.port(SERVER_PORT)

while True:
    # open or reconnect TCP to server
    if not c.is_open():
        if not c.open():
            print("unable to connect to "+SERVER_HOST+":"+str(SERVER_PORT))

    # if open() is ok, read register (modbus function 0x03)
    if c.is_open():
        print c.write_single_register(544, 220)

    # sleep 2s before next polling
    time.sleep(2)
Exemplo n.º 10
0
class DRV90L():
    """The "DRV90L" class contains methods to control the robot.
    """
    def __init__(self):
        rospy.init_node("RobotArm")
        ip = rospy.get_param("/robot_ip")
        self.resetService = rospy.Service('/reset_robot', reset_errors, self.resetErrors)
        self.powerService = rospy.Service('/power_robot', power, self.powerCallback)
        self.teachService = rospy.Service("/teach_position", teach_position, self.teachCurrentToolPose)
        self.c = ModbusClient(host=ip, auto_open=True, auto_close=False, port=502, debug=False, unit_id=2)
        self.bits = 0
        self.name = getpass.getuser()

    def enableRobot(self):
        """This function enables the robot. After this function is called, the robot is ready to move.
        !!!Be aware the motors get enabled after calling this function!!!
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            self.c.write_single_register(0x0006, 0x101)
            self.c.write_single_register(0x0007, 0x101)
            self.c.write_single_register(0x0000, 0x101)
            print("Enabling robot...")
            time.sleep(3)

    def disableRobot(self):
        """This function disables the robot. After this function is called, the robot can't move. The motors aren't powered anymore.
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            self.c.write_single_register(0x0006, 0x000)
            self.c.write_single_register(0x0007, 0x000)
            self.c.write_single_register(0x0000, 0x000)
            time.sleep(3)
            print("Robot is disabled")

    def sendPositionMove(self, x, y, z, rx, ry, rz, speed, frame):
        """This function is used to move the end effector of the robot to a certain position.
        !!!The robot needs to be enables for this function to work!!!
        
        Arguments:
            x {int} -- [x position in mm]
            y {int} -- [y position in mm]
            z {int} -- [z position in mm]
            rx {int} -- [rotation around x axis in degrees]
            ry {int} -- [rotation around y axis in degrees]
            rz {int} -- [rotation around z axis in degrees]
            speed {int} -- [speed in % [0 to 100]]
            frame {string} -- [Reference frame (world is base of robot)]
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            xu = int(np.binary_repr(x*1000, width=32), 2)
            yu = int(np.binary_repr(y*1000, width=32), 2)
            zu = int(np.binary_repr(z*1000, width=32), 2)
            rxu = int(np.binary_repr(rx*1000, width=32), 2)
            ryu = int(np.binary_repr(ry*1000, width=32), 2)
            rzu = int(np.binary_repr(rz*1000, width=32), 2)
            xh = xu >> 16
            xl = xu & 0x0000FFFF
            yh = yu >> 16
            yl = yu & 0x0000FFFF
            zh = zu >> 16
            zl = zu & 0x0000FFFF
            rxh = rxu >> 16
            rxl = rxu & 0x0000FFFF
            ryh = ryu >> 16
            ryl = ryu & 0x0000FFFF
            rzh = rzu >> 16
            rzl = rzu & 0x0000FFFF
            print("Moving to position: x=%s, y=%s, z=%s, rx=%s, ry=%s, rz=%s" % (x,y,z,rx,ry,rz))
            self.c.write_single_register(0x0330, xl)
            self.c.write_single_register(0x0331, xh)
            self.c.write_single_register(0x0332, yl)
            self.c.write_single_register(0x0333, yh)
            self.c.write_single_register(0x0334, zl)
            self.c.write_single_register(0x0335, zh)
            self.c.write_single_register(0x0336, rxl)
            self.c.write_single_register(0x0337, rxh)
            self.c.write_single_register(0x0338, ryl)
            self.c.write_single_register(0x0339, ryh)
            self.c.write_single_register(0x033A, rzl)
            self.c.write_single_register(0x033B, rzh)
            self.c.write_single_register(0x033E, 0)
            self.c.write_single_register(0x0324, speed)
            self.c.write_single_register(0x300, 301)
            self.waitForEndMove([x,y,z,rx,ry,rz])

    def sendArcMove(self, p1, p2):
        """With this function it's possible to do a arc move. The arm will move to p2 through p1.
        
        Arguments:
            p1 {list} -- 1st position [x,y,z,rx,ry,rz]
            p2 {list} -- 2nd position [x,y,z,rx,ry,rz]
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            x1 = int(np.binary_repr(p1[0], width=16), 2)
            y1 = int(np.binary_repr(p1[1], width=16), 2)
            z1 = int(np.binary_repr(p1[2], width=16), 2)
            rx1 = int(np.binary_repr(p1[3], width=16), 2)
            ry1 = int(np.binary_repr(p1[4], width=16), 2)
            rz1 = int(np.binary_repr(p1[5], width=16), 2)
            x2 = int(np.binary_repr(p2[0], width=16), 2)
            y2 = int(np.binary_repr(p2[1], width=16), 2)
            z2 = int(np.binary_repr(p2[2], width=16), 2)
            rx2 = int(np.binary_repr(p2[3], width=16), 2)
            ry2 = int(np.binary_repr(p2[4], width=16), 2)
            rz2 = int(np.binary_repr(p2[5], width=16), 2)
            self.c.write_single_register(0x1000, x1)
            self.c.write_single_register(0x1001, y1)
            self.c.write_single_register(0x1002, z1)
            self.c.write_single_register(0x1003, rx1)
            self.c.write_single_register(0x1004, ry1)
            self.c.write_single_register(0x1005, rz1)
            self.c.write_single_register(0x1006, x2)
            self.c.write_single_register(0x1007, y2)
            self.c.write_single_register(0x1008, z2)
            self.c.write_single_register(0x1009, rx2)
            self.c.write_single_register(0x100A, ry2)
            self.c.write_single_register(0x100B, rz2)
            self.c.write_single_register(0x0220, 4)
            self.c.write_single_register(0x0228, 6)
            print("Moving arc through %s to %s" % (p1, p2))
            self.waitForEndMove(p2)

    def jogRobot(self, direction, stop=False):
        """With this function it's possible to jog the robot in a certain direction.
        
        Arguments:
            direction {string} -- "X+", "Y+", "Z+", "RX+", "RY+", "RZ+", "X-", "Y-", "Z-", "RX-", "RY-", "RZ-"
        
        Keyword Arguments:
            stop {bool} -- if True the robot will stop jogging (default: {False})
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            self.c.write_single_register(0x033E, 0)
            self.c.write_single_register(0x0324, 80)
            if stop == True:
                self.c.write_single_register(0x0300, 0)
            elif direction == "X+":
                self.c.write_single_register(0x0300, 601)
            elif direction == "X-":
                self.c.write_single_register(0x0300, 602)
            elif direction == "Y+":
                self.c.write_single_register(0x0300, 603)
            elif direction == "Y-":
                self.c.write_single_register(0x0300, 604)
            elif direction == "Z+":
                self.c.write_single_register(0x0300, 605)
            elif direction == "Z-":
                self.c.write_single_register(0x0300, 606)
            elif direction == "RX+":
                self.c.write_single_register(0x0300, 607)
            elif direction == "RX-":
                self.c.write_single_register(0x0300, 608)
            elif direction == "RY+":
                self.c.write_single_register(0x0300, 609)
            elif direction == "RY-":
                self.c.write_single_register(0x0300, 610)
            elif direction == "RZ+":
                self.c.write_single_register(0x0300, 611)
            elif direction == "RZ-":
                self.c.write_single_register(0x0300, 612)

    def goHome(self):
        """This function moves the robot to the home position that is set in the robot software.
        !!!The robot needs to be enables for this function to work!!!
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            self.c.write_single_register(0x0300, 1405)
            print("Arm is homing...")
            #self.waitForEndMove()

    def writeDigitalOutput(self, output, state):
        """With this function it's possible to control the user digital outputs of the robot.
        
        Arguments:
            output {int} -- [The user digital output number that needs to be used [1 to 12]
            state {boolean} -- [The state that the output needs to be [True=HIGH (24V), False=LOW (0V)]]
        """
        if state == True:
            self.bits = self.bits | (1 << output-1)
        elif state == False:
            self.bits = self.bits & (0 << output-1)

        self.b = format(self.bits, 'b').zfill(16)
        print(self.b)
        self.c.write_single_register(0x02FE, int(self.b, 2))

    def getUserDigitalInputs(self):
        """With this function it's possible to get the states of all user digital inputs.
        
        Returns:
            [list] -- [Containing all states of the digital inputs [0 or 1]]
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            di = list(map(int, "{0:b}".format(self.c.read_holding_registers(0x02FA, 2)[0])))[::-1]
            l = 24 - len(di)
            for _ in range(0, l):
                di.append(0)
            print(di)
            return di

    def getUserDigitalOutputs(self):
        """With this function it's possible to get the states of all user digital outputs.
        
        Returns:
            [list] -- [Containing all states of the digital outputs [0 or 1]]
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            do = list(map(int, "{0:b}".format(self.c.read_holding_registers(0x02FC, 2)[0])))[::-1]
            l = 12 - len(do)
            for _ in range(0, l):
                do.append(0)
            print(do)
            return do

    def getToolPosition(self):
        """With this function it's possible to get the tool position.
        
        Returns:
            [list] -- [x,y,z,rx,ry,rz] in mm / degrees
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            x_r = self.c.read_holding_registers(0x00F0, 2)
            x = struct.unpack('i', struct.pack('HH', x_r[0], x_r[1]))[0]/1000
            y_r = self.c.read_holding_registers(0x00F2, 2)
            y = struct.unpack('i', struct.pack('HH', y_r[0], y_r[1]))[0]/1000
            z_r = self.c.read_holding_registers(0x00F4, 2)
            z = struct.unpack('i', struct.pack('HH', z_r[0], z_r[1]))[0]/1000
            rx_r = self.c.read_holding_registers(0x00F6, 2)
            rx = struct.unpack('i', struct.pack('HH', rx_r[0], rx_r[1]))[0]/1000
            ry_r = self.c.read_holding_registers(0x00F8, 2)
            ry = struct.unpack('i', struct.pack('HH', ry_r[0], ry_r[1]))[0]/1000
            rz_r = self.c.read_holding_registers(0x00FA, 2)
            rz = struct.unpack('i', struct.pack('HH', rz_r[0], rz_r[1]))[0]/1000
            return [x,y,z,rx,ry,rz]

    def getJointPositions(self):
        """With this function it's possible to get the joint positions
        
        Returns:
            [list] -- [1, 2, 3, 4, 5, 6] joint angles in radians
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            j1 = self.c.read_holding_registers(0x0168, 2)
            j1_a = struct.unpack('i', struct.pack('HH', j1[0], j1[1]))[0]
            j1_angle = radians(j1_a/1000)
            j2 = self.c.read_holding_registers(0x016A, 2)
            j2_a = struct.unpack('i', struct.pack('HH', j2[0], j2[1]))[0]
            j2_angle = radians(j2_a/1000)
            j3 = self.c.read_holding_registers(0x016C, 2)
            j3_a = struct.unpack('i', struct.pack('HH', j3[0], j3[1]))[0]
            j3_angle = radians(j3_a/1000)
            j4 = self.c.read_holding_registers(0x016E, 2)
            j4_a = struct.unpack('i', struct.pack('HH', j4[0], j4[1]))[0]
            j4_angle = radians(j4_a/1000)
            j5 = self.c.read_holding_registers(0x0150, 2)
            j5_a = struct.unpack('i', struct.pack('HH', j5[0], j5[1]))[0]
            j5_angle = radians(j5_a/1000)
            j6 = self.c.read_holding_registers(0x0152, 2)
            j6_a = struct.unpack('i', struct.pack('HH', j6[0], j6[1]))[0]
            j6_angle = radians(j6_a/1000)
            return [j1_angle, j2_angle, j3_angle, j4_angle, j5_angle, j6_angle]

    def saveToolPose(self, name, pose):
        """With this function it's possible to save a position to the poses.yaml yaml file.
        
        Arguments:
            name {string} -- Position name
            pose {[type]} -- [x,y,z,rx,ry,rz] position in mm / degrees
        
        Returns:
            [type] -- [description]
        """
        f = open('/home/%s/catkin_ws/src/delta/arm_driver/yaml/poses.yaml' % self.name, 'r')
        d = yaml.load(f)
        try:
            for n in d:
                if n == name:
                    f.close()
                    print("Pose %s already exists, delete the old pose and try again" % name)
                    return False
        except TypeError:
            pass
        f = open('/home/%s/catkin_ws/src/delta/arm_driver/yaml/poses.yaml' % self.name, 'a')
        d = {name: pose}
        yaml.dump(d, f, default_flow_style=False)
        f.close()
        print("Pose %s is saved" % name)
        return True

    def teachCurrentToolPose(self, msg):
        """With this function it's possible to save the current robot position to the poses.yaml yaml file.
        
        Arguments:
            msg {teach_position.srv} -- Name = position name
        
        Returns:
            [bool] -- True if succesfull
        """
        return self.saveToolPose(msg.name, self.getToolPosition())

    def getSavedToolPose(self, name):
        """Load a position from the poses.yaml yaml file.
        
        Arguments:
            name {string} -- Position name to load
        
        Returns:
            [list] -- [x,y,z,rx,ry,rz] position in mm /degrees
        """
        f = open('/home/%s/catkin_ws/src/delta/arm_driver/yaml/poses.yaml' % self.name, 'r')
        d = yaml.load(f)
        f.close()
        try:
            return d.get(name)
        except AttributeError:
            return "Position does not exist"

    def resetUserDigitalOutputs(self):
        """With this function it's possible to reset all user digital outputs to 0.
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")

        if self.c.is_open():
            self.c.write_single_register(0x02FE, 0)

    def resetErrors(self, msg):
        """With this function it's possible to reset all errors.
        !!!ONLY USE THIS FUNCTION WHEN IT'S SAFE!!!
        """
        if not self.c.is_open():
            if not self.c.open():
                print("Unable to connect\nTrying to connect...")
                return False

        if self.c.is_open():
            self.c.write_single_register(0x0180, 0xFFFF)
            time.sleep(0.1)
            self.c.write_single_register(0x0180, 0x0000)
            return True

    def waitForEndMove(self, pos):
        done = 0
        while done == 0:
            if self.getToolPosition() == pos and self.c.read_holding_registers(0x00E0, 1)[0] == 0:
                done = 1
        print("Position reached")
        time.sleep(1)

    def powerCallback(self, msg):
        if msg.on == True:
            self.enableRobot()
            return True
        elif msg.on == False:
            self.disableRobot()
            return True
        else:
            return False
Exemplo n.º 11
0
	"""
	#Given
    fsm = fsm_targets[unit.value]
    fnd_api = fsm.get_fnd_api()
    sleep(10)
    setup_modbus_gateway(logger, fsm, io_channel)
    sleep(2)
    ip_target = fsm_targets[unit.value].get_ip_eth_point(io_channel)
    logger.info("Target ip is {}".format(ip_target))
    modbus_client = ModbusClient(host=ip_target, port=502, auto_open=True, auto_close=True)
    logger.info("modbus_client response {}".format(modbus_client))
	
	#When
	#Then
    logger.info("Write on single register")
    modbus_client.write_single_register(30001,1)
    sleep(0.4)
    current_time = datetime.now()
    sleep(5)
    response = get_command_to_run_journal(logger,fsm_targets,current_time,4)
    assert response <= 10.00
    sleep(5)
    

@pytest.mark.parametrize("unit, io_channel", unit_io_tuples, ids=unit_io_ids)	
def test_modbus_log_invalid_input_registers(target_testrig, logger, fsm_targets, unit, io_channel):

	"""
        Requirement : WINGDECSAT-213
		Description
		Test Case 1: Modbus: Log unsuccessful master read access with invalid address
Exemplo n.º 12
0
        found, x, y = Kuka.find(mask)
        cv2.circle(frame, (x, y), 7, (0, 0, 0), -1)
        cv2.putText(frame, "Red", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
        if found:
            color = 3

    if blue and color == 0:
        mask = cv2.inRange(hsv, thresholds[6], thresholds[7])
        found, x, y = Kuka.find(mask)
        cv2.circle(frame, (x, y), 7, (0, 0, 0), -1)
        cv2.putText(frame, "Blue", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
        if found:
            color = 4

    # write variables for x- and y-position and color to modbus
    client.write_single_register(32001, x)
    client.write_single_register(32002, y)
    client.write_single_register(32003, color)

    #show video feed
    cv2.imshow("result", frame)

    # if esc key is pressed, break the loop and end the program
    key = cv2.waitKey(5)
    if key == 27:
        break
    if event == 'quit':
        break

Cap.release()
cv2.destroyAllWindows()
Exemplo n.º 13
0
                pass
            elif (keyboard.is_pressed('p')):
                aux = vOut + 10
                vOut = 100 if (aux > 90) else aux
                pass

            #System
            canoIn = True if (vIn > 0) else False
            canoOut = True if (vOut > 0) else False

            aux = nivel + vIn / 10 - vOut / 10
            nivel = 100 if (aux > 99) else (0 if (aux < 1) else aux)

            ledAlarm = True if (nivel >= 75) else False
            vIn = 0 if (nivel == 100) else vIn

            # Sending Data to ScadaBr
            c.write_single_register(0, vIn)
            c.write_single_register(1, vOut)
            c.write_single_register(2, nivel)
            c.write_single_coil(3, canoIn)
            c.write_single_coil(4, canoOut)
            c.write_single_coil(5, ledAlarm)

            # Terminal Data Printing
            print("vIn: %d" % vIn)
            print("vOut: %d" % vOut)
            print("Nivel: %d" % nivel)

            # Waiting Time
            time.sleep(0.2)
Exemplo n.º 14
0
from pyModbusTCP.client import ModbusClient
client = ModbusClient("192.168.1.192", 502)
print("open:", client.open())
while True:
    action = input("action: ")
    client.open()
    try:
        adr = int(input("adress: "))
        if action == "rr":
            print(f"value at {adr}: {client.read_holding_registers(adr)}")
        if action == "rc":
            print(f"value at {adr}: {client.read_coils(adr)}")
        if action == "wr":
            val = int(input("value: "))
            print(f"old value at {adr}: {client.read_holding_registers(adr)}")
            client.write_single_register(adr, val)
            time.sleep(0.1)
            print(f"new value at {adr}: {client.read_holding_registers(adr)}")
        if action == "wc":
            val = input("value: ")
            print(f"old value at {adr}: {client.read_coils(adr)}")
            if val == "t":
                client.write_single_coil(adr, True)
                time.sleep(0.1)
                print(f"new value at {adr}: {client.read_coils(adr)}")
            else:
                client.write_single_coil(adr, False)
                time.sleep(0.1)
                print(f"new value at {adr}: {client.read_coils(adr)}")
    except:
        print("Try again")
c2.host("192.168.1.30")
c2.port(502)
c2.unit_id(1)
c2.open()
c2.close()

cmds = ["config switch physical-port", "edit port4", "set status down", "end"]
exec_ssh_cmds(cmds)

# open or reconnect TCP to server
if not c.is_open():
    if not c.open():
        print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT))

if c.is_open():
    while True:
        # Turn pump on
        c.write_single_coil(1, True)
        # Set pump to 100%
        c.write_single_register(3, 0x64)
        val = c.read_coils(5)[0]
        print(val)

        c2.write_single_coil(1, True)

        if val:
            c.write_single_coil(1, False)

        time.sleep(0.2)
Exemplo n.º 16
0
class ConveyorNode(object):
    __reg_A_servo_on = 0
    __reg_A_command = 1
    __reg_A_velocity = 2
    __reg_B_servo_on = 3
    __reg_B_command = 4
    __reg_B_velocity = 5

    def __init__(self):
        rospy.init_node("conveyor_node")
        rospy.loginfo("Starting ConveyorNode as conveyor_node.")
        host = rospy.get_param("~host", default="10.42.0.21")
        port = rospy.get_param("~port", default=502)
        publish_rate = rospy.get_param("~rate", default=20)
        self.ratio_vel_A = rospy.get_param("~ratio_vel_A", default="1")
        self.ratio_vel_B = rospy.get_param("~ratio_vel_B", default="1")
        self.ratio_cmd_A = rospy.get_param("~ratio_cmd_A", default="1")
        self.ratio_cmd_B = rospy.get_param("~ratio_cmd_B", default="1")
        self.min_vel = rospy.get_param("~min_vel", default="-0.2")
        self.max_vel = rospy.get_param("~max_vel", default="0.2")

        self.rate = rospy.Rate(publish_rate)

        rospy.Subscriber("conveyorA/command", Float32,
                         self.set_velocityA)  # unit [m/s]
        self.stateA_pub = rospy.Publisher("conveyorA/state",
                                          conveyor,
                                          queue_size=1)  # state of conveyor
        rospy.Subscriber("conveyorB/command", Float32,
                         self.set_velocityB)  # unit [m/s]
        self.stateB_pub = rospy.Publisher("conveyorB/state",
                                          conveyor,
                                          queue_size=1)  # state of conveyor

        self.stateA_msg = conveyor()
        self.stateA_msg.target_vel = 0.0
        self.stateA_msg.current_vel = 0.0
        self.stateB_msg = conveyor()
        self.stateB_msg.target_vel = 0.0
        self.stateB_msg.current_vel = 0.0

        self.__timeout_timeA = time.time()
        self.__timeout_timeB = time.time()

        try:
            self.client = ModbusClient(host, port, auto_open=True)
            rospy.loginfo("Setup complete")
        except ValueError:
            rospy.logerr("Error with conveyor Host or Port params")

        self.__register_data = None
        self.__input_data = None

    @staticmethod
    def clamp(n, minn, maxn):
        return max(min(maxn, n), minn)

    @staticmethod
    def map_velocity_to_value(velocity):
        # value = (velocity/0.05*100*2*math.pi*60)/500
        velocity = (velocity * 60) / (0.052 * 2 * math.pi * 4)
        value = int(velocity / 10.0 * 27648.0)
        return utils.get_2comp(value) & 0xFFFF

    @staticmethod
    def map_value_to_velocity(value):
        voltage = float(utils.get_2comp(value)) / 27648.0 * 10.0
        velocity = voltage * 4.0 * 2.0 * math.pi * 0.052 / 60.0
        return velocity

    def set_velocityA(self, msg):

        self.stateA_msg.target_vel = self.clamp(msg.data, self.min_vel,
                                                self.max_vel)  # [m/s]
        self.__timeout_timeA = time.time()

    def set_velocityB(self, msg):
        self.stateB_msg.target_vel = self.clamp(msg.data, self.min_vel,
                                                self.max_vel)  # [m/s]
        self.__timeout_timeB = time.time()

    def run(self):
        while not rospy.is_shutdown():
            try:
                self.__input_data = self.client.read_discrete_inputs(0, 6)
                self.stateA_msg.sensor_1 = self.__input_data[0]
                self.stateA_msg.sensor_2 = self.__input_data[1]
                self.stateA_msg.sensor_3 = self.__input_data[2]

                self.stateB_msg.sensor_1 = self.__input_data[3]
                self.stateB_msg.sensor_2 = self.__input_data[4]
                self.stateB_msg.sensor_3 = self.__input_data[5]

                self.__register_data = self.client.read_holding_registers(0, 6)

                if time.time() - self.__timeout_timeA > 1.0:
                    self.stateA_msg.target_vel = 0
                    self.client.write_single_register(self.__reg_A_servo_on, 0)
                else:
                    value = self.map_velocity_to_value(
                        self.stateA_msg.target_vel) * self.ratio_cmd_A
                    self.client.write_single_register(self.__reg_A_servo_on, 1)
                    self.client.write_single_register(self.__reg_A_command,
                                                      value)

                if time.time() - self.__timeout_timeB > 1.0:
                    self.stateB_msg.target_vel = 0
                    self.client.write_single_register(self.__reg_B_servo_on, 0)
                else:
                    value = self.map_velocity_to_value(
                        self.stateB_msg.target_vel) * self.ratio_cmd_B
                    self.client.write_single_register(self.__reg_B_servo_on, 1)
                    self.client.write_single_register(self.__reg_B_command,
                                                      value)

                velocity = self.map_value_to_velocity(
                    self.__register_data[self.__reg_A_velocity])
                self.stateA_msg.current_vel = velocity * self.ratio_vel_A
                velocity = self.map_value_to_velocity(
                    self.__register_data[self.__reg_B_velocity])
                self.stateB_msg.current_vel = velocity * self.ratio_vel_B
                self.stateA_pub.publish(self.stateA_msg)
                self.stateB_pub.publish(self.stateB_msg)

            except Exception as e:
                rospy.logerr(e)

            self.rate.sleep()
Exemplo n.º 17
0
class Modbus():

    def __init__(self, smarthome, gateway_ip, gateway_port=502, gateway_id=1, update_cycle=60):
        logger.info("Modbus: init plugin")
        self._sh = smarthome
        self._gateway_id = int(gateway_id)
        self._update_cycle = int(update_cycle)
        self._keylist = {}
        #self._client = ModbusTcpClient(gateway_ip,port=gateway_port)
        self._client = ModbusClient(host=gateway_ip, port=gateway_port, auto_open=True, auto_close=True)
        self._client.unit_id(2)
        self._client.debug(True)
        if not self._client.is_open():
            if not self._client.open():
                logger.error("Modbus: connection to gateway can not be established")
            else:
                logger.info("Modbus: connection to gateway established")
                self._client.close()

    def run(self):
        self.alive = True
        self._sh.scheduler.add('MODBUS', self._update_values, prio=5, cycle=self._update_cycle)

    def stop(self):
        self.alive = False
        self._sh.scheduler.remove('MODBUS')

    def parse_item(self, item):
        if 'modbus_gateway_id' in item.conf:
            gateid = int(item.conf['modbus_gateway_id'])
        else:
            gateid = 1
        if gateid != self._gateway_id:
            #logger.debug("Modbus: parse item error (gateway_id is not configured as plugin): {0}".format(item))
            return None

        if 'modbus_cmd' not in item.conf:
            #logger.debug("Modbus: parse item error (modbus_cmd missing): {0}".format(item))
            return None

        if 'modbus_scaling' not in item.conf:
            #logger.debug("Modbus: parse item error (modbus_scaling missing): {0}".format(item))
            return None

        if 'modbus_register' in item.conf:
            logger.debug("Modbus: parse item: {0}".format(item))
            register = item.conf['modbus_register']
            if not register in self._keylist:
                self._keylist[register] = {'items': [item], 'logics': []}
            else:
                self._keylist[register]['items'].append(item) 
        return None
       #    return self.update_item
       #else:
       #    return None


    def parse_logic(self, logic):
        pass

    def _update_values(self):
        for register in self._keylist:
            for item in self._keylist[register]['items']:
                if int(item.conf['modbus_cmd']) == 4:
                    reg_list = self._client.read_input_registers(int(item.conf['modbus_register'])-30001, 1)
                    logger.info("Modbus: Plain value: {}".format(str(reg_list[0])))
                    if reg_list is None:
                        return None
                    if len(reg_list) > 0:
                        phys_value = reg_list[0] / (int(item.conf['modbus_scaling']))# * pow(10, int(item.conf['modbus_decimal']))
                        logger.info("Modbus: Physical value: {0}".format(phys_value))
                        item(phys_value, 'MODBUS', ' {0}'.format(phys_value))
                elif int(item.conf['modbus_cmd']) == 6:
                    sendvalue = int(item()*int(item.conf['modbus_scaling']))
                    reg_list = self._client.write_single_register(int(item.conf['modbus_register'])-40001, sendvalue)
                    if not reg_list:
                        logger.info("Modbus: Error writing register")


    def update_item(self, item, caller=None, source=None, dest=None):
        if caller != 'MODBUS':
            logger.info("update item: {0}".format(item.id()))
            if int(item.conf['modbus_cmd']) == 4:
                reg_list = self._client.read_input_registers(int(item.conf['modbus_register'])-30001, 1)
                logger.info("Modbus: Plain value: {}".format(str(reg_list[0])))
                if reg_list is None:
                    return None
                if len(reg_list) > 0:
                    phys_value = reg_list[0] / (int(item.conf['modbus_scaling']))# * pow(10, int(item.conf['modbus_decimal']))
                    logger.info("Modbus: Physical value: {0}".format(phys_value))
                    item(phys_value, 'MODBUS', ' {0}'.format(phys_value))
 def set_start_mode_ramp(ModbusClient):
     # Sets the start mode to ramp
     # c is ModbusClient
     wr = ModbusClient.write_single_register(3, 2)
     # print('set_start_mode_ramp:' + str(int(wr)))
     return wr
Exemplo n.º 19
0
    def onCommand(self, u, Command, Level, Hue):
        Domoticz.Debug(
            str(Devices[u].DeviceID) + ": onCommand called: Parameter '" +
            str(Command) + "', Level: " + str(Level))

        try:
            client = ModbusClient(host=self.TCP_IP,
                                  port=int(self.TCP_PORT),
                                  unit_id=int(1),
                                  auto_open=True,
                                  auto_close=True,
                                  timeout=2)
        except:
            Domoticz.Error("Can not connect to Modbus TCP/IP: " + self.TCP_IP +
                           ":" + self.TCP_PORT)

        try:
            # == ControlMode  : man = 1, auto = 0, docasny = 2 |  "|Manuál|Automat|Dočasný"
            if (u == self.uControlMode):
                #if Level == 10: atreaControlMode = 1
                if Level == 20: atreaControlMode = 0
                elif Level == 30: atreaControlMode = 2
                client.write_single_register(1015, atreaControlMode)
                client.write_single_register(1016, atreaControlMode)

            # == HeatingSeason  : 0 = non-heating, 1 = heating
            elif (u == self.uHeatingSeason):
                client.write_single_coil(1200, int(Command == "On"))

            # == NightlyCooling  : 0 = recuperation, 1 = cooling
            elif (u == self.uNightlyCooling):
                client.write_single_coil(902, int(Command == "On"))

            # == uPowerCur
            # == uPowerReq
            elif (u == self.uPowerCur):
                atreaPower = int(self._powerDomoticzValueToPercent(Level))
                Domoticz.Debug(
                    str(Devices[u].DeviceID) + ": COMMAND: Level=" +
                    str(Level) + ", atreaPower='" + str(atreaPower) + "'")
                client.write_single_register(1009, atreaPower)
                client.write_single_register(1013, atreaPower)
                client.write_single_register(1015, 2)
                client.write_single_register(1016, 2)

            # == ModeCur                                                        "Vypnuto |    Periodické větrání |    Větrání |Čidlo vlhkosti|IN2|D1|D2|Koupelny+WC|Odsavač kuchyň|Náběh|Doběh|Odmrazování rekuperátoru"
            # == ModeReq                                                        "Vypnuto |    Periodické větrání |    Větrání"
            #       H01008 Nastavení požadovaného režimu, pokud H01015=1,                 0 = Periodické větrání, 1 = Větrání
            #       H01012 Nastavení požadovaného režimu, pokud H01015= 0/2, 0 = Vypnuto, 1 = Periodické větrání, 2 = Větrání
            elif (u == self.uModeCur):
                if Level == 0:
                    atreaMode = 1
                    self.onCommand(self.uPowerCur, Command, 0, Hue)
                elif Level == 10:
                    atreaMode = 0
                elif Level == 20:
                    atreaMode = 1
                Domoticz.Debug(
                    str(Devices[u].DeviceID) + ": COMMAND: Level=" +
                    str(Level) + ", atreaMode='" + str(atreaMode) + "'")
                client.write_single_register(1008, atreaMode)
                client.write_single_register(1012, atreaMode)
                client.write_single_register(1015, 2)
                client.write_single_register(1016, 2)

        except:
            Domoticz.Error(
                str(Devices[u].DeviceID) +
                ": Modbus update error. Check it out!")

        # Update values now!
        self.onHeartbeat()
        return
        c.write_single_coil(1, coil_value)
        logger.debug(f"写 coil,值为 {coil_value}")
        coil_value = not coil_value

        time.sleep(1)

        # 读 discrete_inputs
        inputs = c.read_discrete_inputs(1)
        if inputs is None:
            logger.error("读 discrete_inputs 失败")
            time.sleep(2)
            continue
        logger.debug(f"读 discrete_input,值为 {inputs[0]}")

        # 写 holding_registers
        c.write_single_register(1, holding_reg_value)
        logger.debug(f"写 holding_register,值为 {holding_reg_value}")
        holding_reg_value = (holding_reg_value + 1) % range_value

        time.sleep(1)

        # 读 input_register
        regs = c.read_input_registers(1)
        if regs is None:
            logger.error("读 input_registers 失败")
            time.sleep(2)
            continue
        logger.debug(f"读 input_register,值为 {regs[0]}")

        time.sleep(1)
Exemplo n.º 21
0
if not c.is_open():
    if not c.open():
        print("unable to connect to " + client_host + ":" + str(client_port))


def int32_to_int8(n):
    mask = (1 << 16) - 1
    return [(n >> k) & mask for k in range(0, 32, 16)]


var_int = utils.encode_ieee(7.5)
print(var_int)
sonuc=int32_to_int8(var_int)
print(sonuc)
if c.is_open():
    # read 10 registers at address 0, store result in regs list
    print(var_int)
    c.write_single_register(0,5)
    c.write_multiple_registers(1,sonuc)

    regs = c.read_holding_registers(0,100)
    # if success display registers
    if regs:
        print("reg ad #0 to 9: " , regs)

    bits = c.read_discrete_inputs(0, 16)
    # if success display registers
    if bits:
        print("bit ad #0 to 9: " + str(bits))
Exemplo n.º 22
0
def doTest():
    # TCP auto connect on modbus request, close after it
    c = ModbusClient(host="192.168.1.1", auto_open=True, auto_close=True)

    regs = c.read_holding_registers(0, 100)
    if regs:
        print(regs)
    else:
        print("read error")


def doWrite(goToPos):
    c = ModbusClient(host="192.168.1.1", auto_open=True, auto_close=True)

    if c.write_single_register(1, goToPos):
        print("write ok")
    else:
        print("write error")


if __name__ == '__main__':
    c = ModbusClient(host="192.168.1.1", auto_open=True, auto_close=True)
    while (True):
        if c.write_single_register(0, 0):
            print("Waiting for instruction")
        goto = int(input("Enter Go To Pos: "))
        doWrite(goto)
        if c.write_single_register(0, 1):
            print("Going!")
        time.sleep(.1)
Exemplo n.º 23
0
class MitsubishiAirConditioner:
    # 自上次读取一次新信息起经过了多久
    lastRefreshTimestamp = time.time()

    client = None
    messageQueue = None
    messageThread = None

    # 待发送的需要等待回复的命令,成员格式为:{"code":"XX", "cmd":"XXXXXXX", "type": "query", "timestamp": timestamp}
    arrayCmdNeedWait = []

    # 正在等待回应的命令
    dicCmdWaiting = None

    # 存储各个空调控制器的dic, key:字符串表示的控制器模块编码(HEX) value:LJAircon对象
    dicAircon = {}

    # nValue/sValue至寄存器Payload的map - 开关
    mapVPPowerOn = None
    # 寄存器Payload至nValue/sValue的map - 开关
    mapPVPowerOn = None
    # nValue/sValue至寄存器Payload的map - 运行模式
    mapVPMode = None
    # 寄存器Payload至nValue/sValue的map - 运行模式
    mapPVMode = None
    # nValue/sValue至寄存器Payload的map - 风速
    mapVPFanSpeed = None
    # 寄存器Payload至nValue/sValue的map - 风速
    mapPVFanSpeed = None
    # nValue/sValue至寄存器Payload的map - 目标温度
    mapVPSetPoint = None
    # 寄存器Payload至nValue/sValue的map - 目标温度
    mapPVSetPoint = None
    # nValue/sValue至寄存器Payload的map - 室温
    mapVPRoomPoint = None
    # 寄存器Payload至nValue/sValue的map - 室温
    mapPVRoomPoint = None
    # nValue/sValue至寄存器Payload的map - 风向
    mapVPFanDirect = None
    # 寄存器Payload至nValue/sValue的map - 风向
    mapPVFanDirect = None

    def __init__(self):
        self.messageQueue = queue.Queue()
        self.messageThread = threading.Thread(
            name="QueueThread",
            target=MitsubishiAirConditioner.handleMessage,
            args=(self, ))

        # 0:关1:开
        self.mapVPPowerOn = {0: 0, 1: 1}
        self.mapPVPowerOn = self.revertDic(self.mapVPPowerOn)
        # 0:自动,1:制冷,2:送风,3:除湿,4:制热
        self.mapVPMode = {'10': 0, '20': 1, '30': 2, '40': 3, '50': 4}
        self.mapPVMode = self.revertDic(self.mapVPMode)
        # 0:自动,2:低,3:中2,5:中1,6:高
        self.mapVPFanSpeed = {'10': 0, '20': 2, '30': 3, '40': 5, '50': 6}
        self.mapPVFanSpeed = self.revertDic(self.mapVPFanSpeed)
        # 16~31°C (x10),最小单位0.5°C
        self.mapPVSetPoint = {}
        for i in range(190, 300, 5):
            self.mapPVSetPoint[i] = str((int((i - 190) / 5) + 1) * 10)
        self.mapVPSetPoint = self.revertDic(self.mapPVSetPoint)
        # 10~38°C (x10),最小单位1°C
        self.mapPVRoomPoint = {}
        for i in range(100, 385, 5):
            if i % 10 == 0:
                self.mapPVRoomPoint[i] = str(i // 10)
            elif i % 5 == 0:
                self.mapPVRoomPoint[i] = str(float(i) / 10)
        self.mapVPRoomPoint = self.revertDic(self.mapPVRoomPoint)
        # 0:自动,1~5:位置1~5 7:摆风
        self.mapVPFanDirect = {
            '10': 0,
            '20': 1,
            '30': 2,
            '40': 3,
            '50': 4,
            '60': 5,
            '70': 7
        }
        self.mapPVFanDirect = self.revertDic(self.mapVPFanDirect)
        return

    def onStart(self):
        Domoticz.Heartbeat(5)

        if Parameters["Mode2"] == "Debug":
            Domoticz.Debugging(1)
        else:
            Domoticz.Debugging(0)

        # 从Domoticz重新加载硬件和设备信息
        self.reloadFromDomoticz()

        debug = False
        if Parameters["Mode2"] == "Debug":
            debug = True
        if self.client and self.client.is_open():
            self.client.close()
        self.client = ModbusClient(host=Parameters["Address"],
                                   port=Parameters["Port"],
                                   auto_open=True,
                                   auto_close=False,
                                   timeout=1)
        self.messageThread.start()
        self.client.mode(2)

        self.messageQueue.put({
            "Type": "Log",
            "Text": "Heartbeat test message"
        })

    def onStop(self):
        # signal queue thread to exit
        self.messageQueue.put(None)
        Domoticz.Log("Clearing message queue...")
        self.messageQueue.join()

        # Wait until queue thread has exited
        Domoticz.Log("Threads still active: " + str(threading.active_count()) +
                     ", should be 1.")
        while (threading.active_count() > 1):
            for thread in threading.enumerate():
                if (thread.name != threading.current_thread().name):
                    Domoticz.Log(
                        "'" + thread.name +
                        "' is still running, waiting otherwise Domoticz will abort on plugin exit."
                    )
            time.sleep(0.1)
        return

    def onConnect(self, Connection, Status, Description):
        return

    def onMessage(self, Connection, Data):
        return

    def clientConnected(self):
        if not self.client: return False

        if self.client.is_open():
            return True
        elif not self.client.open():
            Domoticz.Log('Warning: Modbus connect failed')
            return False

    def handleMessage(self):
        try:
            Domoticz.Debug("Entering message handler")
            while True:
                Message = self.messageQueue.get(block=True)
                if Message is None:
                    Domoticz.Debug("Exiting message handler")
                    self.messageQueue.task_done()
                    break

                self.queryStatus()
                self.messageQueue.task_done()
        except Exception as err:
            Domoticz.Error("handleMessage: " + str(err))

    def queryStatus(self):
        if not self.clientConnected():
            for aircon in self.dicAircon.values():
                aircon.goOffline()
            return

        for aircon in self.dicAircon.values():
            #if not aircon.online:
            #continue
            # 设备已连接才发送查询指令

            dicOptions = aircon.devicePowerOn.Options
            if not dicOptions or 'LJCode' not in dicOptions or 'LJShift' not in dicOptions:
                return
            self.client.unit_id(int(dicOptions['LJCode'], 16))
            time.sleep(0.2)

            regs = self.client.read_holding_registers(0, 7)
            if not regs or regs is None:
                Domoticz.Log('Warning: Reading Regs Fail! 0x' +
                             dicOptions['LJCode'])
                aircon.goOffline()
                continue
            elif len(regs) != 7:
                Domoticz.Log(
                    'Warning: Reading Regs Fail! 0x{}, recevied:{}'.format(
                        dicOptions['LJCode'], str(regs)))
                aircon.goOffline()
                continue

            aircon.goOnline()
            Domoticz.Debug('Receive Regs:' + str(regs))
            if aircon.devicePowerOn and regs[0] in self.mapPVPowerOn:
                nValue = self.mapPVPowerOn[regs[0]]
                sValue = aircon.devicePowerOn.sValue
                device = aircon.devicePowerOn
                UpdateDevice(Unit=int(device.Options['LJUnit']),
                             nValue=nValue,
                             sValue=sValue,
                             TimedOut=0)

            if aircon.deviceMode and regs[1] in self.mapPVMode:
                nValue = 1
                sValue = self.mapPVMode[regs[1]]
                device = aircon.deviceMode
                UpdateDevice(Unit=int(device.Options['LJUnit']),
                             nValue=nValue,
                             sValue=sValue,
                             TimedOut=0)

            if aircon.deviceFanSpeed and regs[2] in self.mapPVFanSpeed:
                nValue = 1
                sValue = self.mapPVFanSpeed[regs[2]]
                device = aircon.deviceFanSpeed
                UpdateDevice(Unit=int(device.Options['LJUnit']),
                             nValue=nValue,
                             sValue=sValue,
                             TimedOut=0)

            if aircon.deviceSetPoint and regs[3] in self.mapPVSetPoint:
                nValue = 1
                sValue = self.mapPVSetPoint[regs[3]]
                device = aircon.deviceSetPoint
                UpdateDevice(Unit=int(device.Options['LJUnit']),
                             nValue=nValue,
                             sValue=sValue,
                             TimedOut=0)

            if aircon.deviceRoomPoint and regs[4] in self.mapPVRoomPoint:
                nValue = 1
                sValue = self.mapPVRoomPoint[regs[4]]
                device = aircon.deviceRoomPoint
                UpdateDevice(Unit=int(device.Options['LJUnit']),
                             nValue=nValue,
                             sValue=sValue,
                             TimedOut=0)

            if aircon.deviceFanDirect and regs[5] in self.mapPVFanDirect:
                nValue = 1
                sValue = self.mapPVFanDirect[regs[5]]
                device = aircon.deviceFanDirect
                UpdateDevice(Unit=int(device.Options['LJUnit']),
                             nValue=nValue,
                             sValue=sValue,
                             TimedOut=0)

            if aircon.deviceFaultCode:
                nValue = 1
                hexText = str(hex(regs[6]))
                if len(hexText) >= 4 and hexText[-4:] == '8000':
                    sValue = '运行正常'
                else:
                    sValue = '错误!故障代码: ' + hexText
                device = aircon.deviceFaultCode
                UpdateDevice(Unit=int(device.Options['LJUnit']),
                             nValue=nValue,
                             sValue=sValue,
                             TimedOut=0)

    def onCommand(self, Unit, Command, Level, Hue):
        if not self.clientConnected():
            Domoticz.Log('Modbus connect failed!')
            for aircon in self.dicAircon.values():
                aircon.goOffline()
            return
        Domoticz.Log("onCommand called for Unit " + str(Unit) +
                     ": Parameter '" + str(Command) + "', Level: " +
                     str(Level))
        Command = Command.strip()
        action, sep, params = Command.partition(' ')
        action = action.capitalize()
        params = params.capitalize()
        device = Devices[Unit]
        options = device.Options
        if not options or 'LJCode' not in options or 'LJShift' not in options or 'LJUnit' not in options:
            return
        code = device.Options['LJCode']
        shift = device.Options['LJShift']

        if not code or code not in self.dicAircon or not shift or int(
                shift) < 0 or int(shift) > 6:
            return
        aircon = self.dicAircon[code]
        #if not aircon.online:
        #return

        if shift == '00':
            # 开关
            if action == 'On':
                nValue = 1
            elif action == 'Off':
                nValue = 0
            self.sendCmdByNValue(aircon, self.mapVPPowerOn,
                                 aircon.devicePowerOn, nValue)

        elif shift == '01':
            # 模式
            if action == 'Set' and params == 'Level':
                if aircon.devicePowerOn.nValue == 0:
                    # 关机状态,先开机 #TODO测试连续写
                    self.sendCmdByNValue(aircon, self.mapVPPowerOn,
                                         aircon.devicePowerOn, 1)
                self.sendCmdBySValue(aircon, self.mapVPMode, aircon.deviceMode,
                                     str(Level))
        elif shift == '02':
            # 风速
            if action == 'Set' and params == 'Level':
                if aircon.devicePowerOn.nValue == 0:
                    # 关机状态,先开机
                    self.sendCmdByNValue(aircon, self.mapVPPowerOn,
                                         aircon.devicePowerOn, 1)
                self.sendCmdBySValue(aircon, self.mapVPFanSpeed,
                                     aircon.deviceFanSpeed, str(Level))
        elif shift == '03':
            # 温度
            if action == 'Set' and params == 'Level':
                if aircon.devicePowerOn.nValue == 0:
                    # 关机状态,先开机
                    self.sendCmdByNValue(aircon, self.mapVPPowerOn,
                                         aircon.devicePowerOn, 1)
                self.sendCmdBySValue(aircon, self.mapVPSetPoint,
                                     aircon.deviceSetPoint, str(Level))
        elif shift == '04':
            # 室温
            if action == 'Set' and params == 'Level':
                if aircon.devicePowerOn.nValue == 0:
                    # 关机状态,先开机
                    self.sendCmdByNValue(aircon, self.mapVPPowerOn,
                                         aircon.devicePowerOn, 1)
                self.sendCmdBySValue(aircon, self.mapVPRoomPoint,
                                     aircon.deviceRoomPoint, str(Level))
        elif shift == '05':
            # 风向
            if action == 'Set' and params == 'Level':
                if aircon.devicePowerOn.nValue == 0:
                    # 关机状态,先开机
                    self.sendCmdByNValue(aircon, self.mapVPPowerOn,
                                         aircon.devicePowerOn, 1)
                self.sendCmdBySValue(aircon, self.mapVPFanDirect,
                                     aircon.deviceFanDirect, str(Level))

    # 从sValue取值,找Payload,并写寄存器
    def sendCmdBySValue(self, aircon, mapVP, device, sValue):
        if not self.clientConnected(): return
        Domoticz.Log('sendCmdBySValue\(mapVP={}, device={}, sValue={}'.format(
            mapVP, device, sValue))  # TODO
        if not device or not mapVP or sValue not in mapVP:
            return None
        registerText = device.Options['LJShift']
        self.client.unit_id(int(device.Options['LJCode'], 16))
        if (self.client.write_single_register(int(registerText, 16),
                                              mapVP[str(sValue)])):
            Domoticz.Log('write_single_register\(0x{}, {}\) success!'.format(
                registerText, mapVP[sValue]))  # TODO
            timedOut = 0
            result = True
        else:
            Domoticz.Log('write_single_register\(0x{}, {}\) failed!'.format(
                registerText, mapVP[sValue]))  # TODO
            timedOut = 1
            result = False
            aircon.goOffline()
            sValue = device.sValue

        UpdateDevice(Unit=int(device.Options['LJUnit']),
                     nValue=device.nValue,
                     sValue=str(sValue),
                     TimedOut=timedOut)
        return result

    # 从nValue取值,找Payload,并写寄存器
    def sendCmdByNValue(self, aircon, mapVP, device, nValue):
        if not self.clientConnected(): return
        Domoticz.Log('sendCmdByNValue\(mapVP={}, device={}, nValue={}'.format(
            mapVP, device, nValue))  # TODO
        if not device or not mapVP or nValue not in mapVP:
            return None
        registerText = device.Options['LJShift']
        self.client.unit_id(int(device.Options['LJCode'], 16))
        if (self.client.write_single_register(int(registerText, 16),
                                              mapVP[nValue])):
            Domoticz.Log('write_single_register\(0x{}, {}\) success!'.format(
                registerText, mapVP[nValue]))  # TODO
            timedOut = 0
            result = True
        else:
            Domoticz.Log('write_single_register\(0x{}, {}\) failed!'.format(
                registerText, mapVP[nValue]))  # TODO
            timedOut = 1
            result = False
            aircon.goOffline()
            nValue = device.nValue
        UpdateDevice(Unit=int(device.Options['LJUnit']),
                     nValue=nValue,
                     sValue=str(device.sValue),
                     TimedOut=timedOut)
        return result

    def onNotification(self, Name, Subject, Text, Status, Priority, Sound,
                       ImageFile):
        Domoticz.Log("Notification: " + Name + "," + Subject + "," + Text +
                     "," + Status + "," + str(Priority) + "," + Sound + "," +
                     ImageFile)

    def onDisconnect(self, Connection):
        Domoticz.Log("onDisconnect called")

    def onHeartbeat(self):
        # Domoticz.Log('onHeartbeat Called ---------------------------------------')
        # 如果没连接则尝试重新连接
        if not self.clientConnected():
            for aircon in self.dicAircon.values():
                aircon.goOffline()
            return

        # 查询空调状态
        self.messageQueue.put({
            "Type": "Log",
            "Text": "Heartbeat test message"
        })

    def reloadFromDomoticz(self):
        self.dicAircon = {}
        strListCode = Parameters["Mode1"]
        strListCode = strListCode.replace(',', '')
        strListCode = strListCode.replace('|', '')
        strListCode = strListCode.replace(' ', '')
        strListCode = strListCode.replace('0X', '0x')
        strListCode = strListCode.replace('X', '0x')
        setCode = set(strListCode.split('0x'))
        setCode2 = set([])
        for tmp in setCode:
            if not tmp:
                continue
            setCode2.add(tmp.upper())
        for tmp2 in setCode2:
            if not tmp2:
                continue
            if len(tmp2) > 2: tmp2 = tmp2[-2:]
            tmp2 = '{:0>2}'.format(tmp2)
            Domoticz.Log('Detected Code:' + tmp2)
            self.dicAircon[tmp2] = LJAircon(tmp2)

        # 记录已有的unit
        setUnit = set([])
        # 待删除的device对应的unit
        setUnitDel = set([])
        # 所有的Unit集合
        setUnitAll = set(range(1, 256))
        # 将Device放入对应的控制器对象中,多余的device删除
        for unit in Devices:
            device = Devices[unit]
            dicOptions = device.Options
            Domoticz.Log("DEVICE FROM PANEL " +
                         descDevice(device=device, unit=unit))

            shouldDelete = False
            if dicOptions and 'LJCode' in dicOptions and 'LJShift' in dicOptions and dicOptions[
                    'LJCode'] in self.dicAircon:
                # 有匹配的控制器,赋值
                aircon = self.dicAircon[dicOptions['LJCode']]
                if dicOptions['LJShift'] == '00':
                    # 开关
                    if aircon.devicePowerOn:
                        #已经有现成的设备,加入待删除
                        Domoticz.Log(
                            'Already have devicePowerOn, add to delete list. '
                            + device.Name)
                        shouldDelete = True
                    else:
                        aircon.devicePowerOn = device
                        aircon.dicDevice[unit] = device
                elif dicOptions['LJShift'] == '01':
                    # 运行模式
                    if aircon.deviceMode:
                        #已经有现成的设备,加入待删除
                        Domoticz.Log(
                            'Already have deviceMode, add to delete list. ' +
                            device.Name)
                        shouldDelete = True
                    else:
                        aircon.deviceMode = device
                        aircon.dicDevice[unit] = device
                elif dicOptions['LJShift'] == '02':
                    # 风速
                    if aircon.deviceFanSpeed:
                        #已经有现成的设备,加入待删除
                        Domoticz.Log(
                            'Already have deviceFanSpeed, add to delete list. '
                            + device.Name)
                        shouldDelete = True
                    else:
                        aircon.deviceFanSpeed = device
                        aircon.dicDevice[unit] = device
                elif dicOptions['LJShift'] == '03':
                    # 目标温度
                    if aircon.deviceSetPoint:
                        #已经有现成的设备,加入待删除
                        Domoticz.Log(
                            'Already have deviceSetPoint, add to delete list. '
                            + device.Name)
                        shouldDelete = True
                    else:
                        aircon.deviceSetPoint = device
                        aircon.dicDevice[unit] = device
                elif dicOptions['LJShift'] == '04':
                    # 室温
                    if aircon.deviceRoomPoint:
                        #已经有现成的设备,加入待删除
                        Domoticz.Log(
                            'Already have deviceRoomPoint, add to delete list. '
                            + device.Name)
                        shouldDelete = True
                    else:
                        aircon.deviceRoomPoint = device
                        aircon.dicDevice[unit] = device
                elif dicOptions['LJShift'] == '05':
                    # 风向
                    if aircon.deviceFanDirect:
                        #已经有现成的设备,加入待删除
                        Domoticz.Log(
                            'Already have deviceFanDirect, add to delete list. '
                            + device.Name)
                        shouldDelete = True
                    else:
                        aircon.deviceFanDirect = device
                        aircon.dicDevice[unit] = device
                elif dicOptions['LJShift'] == '06':
                    # 状态
                    if aircon.deviceFaultCode:
                        #已经有现成的设备,加入待删除
                        Domoticz.Log(
                            'Already have deviceFaultCode, add to delete list. '
                            + device.Name)
                        shouldDelete = True
                    else:
                        aircon.deviceFaultCode = device
                        aircon.dicDevice[unit] = device
                else:
                    shouldDelete = True
            else:
                shouldDelete = True

            if shouldDelete:
                setUnitDel.add(unit)
            else:
                setUnit.add(unit)
        Domoticz.Log("DELETE DEVICES IN UNIT: " + str(setUnitDel))

        # 删除多余的Device
        for unit in setUnitDel:
            Devices[unit].Delete()

        # Check if images are in database
        #if "LJCountDown" not in Images:
        #    Domoticz.Image("LJCountDown.zip").Create()
        #image = Images["LJCountDown"].ID

        # 遍历控制器,补全控制器对应的device
        for aircon in self.dicAircon.values():
            setAvariable = setUnitAll.difference(setUnit)
            if not setAvariable or len(setAvariable) == 0:
                continue
            if not aircon.devicePowerOn:
                newUnit = setAvariable.pop()
                setUnit.add(newUnit)
                optionsCustom = {
                    "LJUnit": str(newUnit),
                    'LJCode': aircon.code,
                    'LJShift': '00'
                }
                name = '0x{} 开关'.format(aircon.code)
                aircon.devicePowerOn = Domoticz.Device(Name=name,
                                                       Unit=newUnit,
                                                       Type=244,
                                                       Subtype=73,
                                                       Switchtype=0,
                                                       Options=optionsCustom)
                aircon.devicePowerOn.Create()
                aircon.dicDevice[newUnit] = aircon.devicePowerOn
                Domoticz.Log(
                    'ADD DEVICE :' +
                    descDevice(device=aircon.devicePowerOn, unit=newUnit))
            if not aircon.deviceMode and len(setAvariable) > 0:
                newUnit = setAvariable.pop()
                setUnit.add(newUnit)
                optionsCustom = {
                    "LJUnit": str(newUnit),
                    'LJCode': aircon.code,
                    'LJShift': '01'
                }
                levelNames = 'Off|自动|制冷|送风|除湿|制热'
                optionsGradient = {
                    'LevelActions': '|' * levelNames.count('|'),
                    'LevelNames': levelNames,
                    'LevelOffHidden': 'true',
                    'SelectorStyle': '0'
                }
                name = '0x{} 模式'.format(aircon.code)
                aircon.deviceMode = Domoticz.Device(Name=name,
                                                    Unit=newUnit,
                                                    TypeName="Selector Switch",
                                                    Switchtype=18,
                                                    Image=0,
                                                    Options=dict(
                                                        optionsCustom,
                                                        **optionsGradient))
                aircon.deviceMode.Create()
                aircon.dicDevice[newUnit] = aircon.deviceMode
                Domoticz.Log(
                    'ADD DEVICE :' +
                    descDevice(device=aircon.deviceMode, unit=newUnit))
            if not aircon.deviceFanSpeed and len(setAvariable) > 0:
                newUnit = setAvariable.pop()
                setUnit.add(newUnit)
                optionsCustom = {
                    "LJUnit": str(newUnit),
                    'LJCode': aircon.code,
                    'LJShift': '02'
                }
                levelNames = 'Off|自动|低|中2|中1|高'
                optionsGradient = {
                    'LevelActions': '|' * levelNames.count('|'),
                    'LevelNames': levelNames,
                    'LevelOffHidden': 'true',
                    'SelectorStyle': '0'
                }
                name = '0x{} 风速'.format(aircon.code)
                aircon.deviceFanSpeed = Domoticz.Device(
                    Name=name,
                    Unit=newUnit,
                    TypeName="Selector Switch",
                    Switchtype=18,
                    Image=0,
                    Options=dict(optionsCustom, **optionsGradient))
                aircon.deviceFanSpeed.Create()
                aircon.dicDevice[newUnit] = aircon.deviceFanSpeed
                Domoticz.Log(
                    'ADD DEVICE :' +
                    descDevice(device=aircon.deviceFanSpeed, unit=newUnit))
            if not aircon.deviceSetPoint and len(setAvariable) > 0:
                newUnit = setAvariable.pop()
                setUnit.add(newUnit)
                optionsCustom = {
                    "LJUnit": str(newUnit),
                    'LJCode': aircon.code,
                    'LJShift': '03'
                }
                levelNames = 'Off'
                for i in range(190, 300, 5):
                    if i % 10 == 0:
                        levelNames += '|' + str(i // 10) + '℃'
                    elif i % 5 == 0:
                        levelNames += '|' + str(float(i) / 10) + '℃'

                optionsGradient = {
                    'LevelActions': '|' * levelNames.count('|'),
                    'LevelNames': levelNames,
                    'LevelOffHidden': 'true',
                    'SelectorStyle': '1'
                }
                name = '0x{} 设定温度'.format(aircon.code)
                aircon.deviceSetPoint = Domoticz.Device(
                    Name=name,
                    Unit=newUnit,
                    TypeName="Selector Switch",
                    Switchtype=18,
                    Image=0,
                    Options=dict(optionsCustom, **optionsGradient))
                aircon.deviceSetPoint.Create()
                aircon.dicDevice[newUnit] = aircon.deviceSetPoint
                Domoticz.Log(
                    'ADD DEVICE :' +
                    descDevice(device=aircon.deviceSetPoint, unit=newUnit))
            if not aircon.deviceRoomPoint and len(setAvariable) > 0:
                newUnit = setAvariable.pop()
                setUnit.add(newUnit)
                optionsCustom = {
                    "LJUnit": str(newUnit),
                    'LJCode': aircon.code,
                    'LJShift': '04'
                }
                name = '0x{} 室温'.format(aircon.code)
                aircon.deviceRoomPoint = Domoticz.Device(
                    Name=name,
                    Unit=newUnit,
                    TypeName="Temperature",
                    Options=optionsCustom)
                aircon.deviceRoomPoint.Create()
                aircon.dicDevice[newUnit] = aircon.deviceRoomPoint
                Domoticz.Log(
                    'ADD DEVICE :' +
                    descDevice(device=aircon.deviceRoomPoint, unit=newUnit))
            if not aircon.deviceFanDirect and len(setAvariable) > 0:
                newUnit = setAvariable.pop()
                setUnit.add(newUnit)
                optionsCustom = {
                    "LJUnit": str(newUnit),
                    'LJCode': aircon.code,
                    'LJShift': '05'
                }
                levelNames = 'Off|自动|位置1|位置2|位置3|位置4|位置5|摆风'
                optionsGradient = {
                    'LevelActions': '|' * levelNames.count('|'),
                    'LevelNames': levelNames,
                    'LevelOffHidden': 'true',
                    'SelectorStyle': '0'
                }
                name = '0x{} 风向'.format(aircon.code)
                aircon.deviceFanDirect = Domoticz.Device(
                    Name=name,
                    Unit=newUnit,
                    TypeName="Selector Switch",
                    Switchtype=18,
                    Image=0,
                    Options=dict(optionsCustom, **optionsGradient))
                aircon.deviceFanDirect.Create()
                aircon.dicDevice[newUnit] = aircon.deviceFanDirect
                Domoticz.Log(
                    'ADD DEVICE :' +
                    descDevice(device=aircon.deviceFanDirect, unit=newUnit))
            if not aircon.deviceFaultCode and len(setAvariable) > 0:
                newUnit = setAvariable.pop()
                setUnit.add(newUnit)
                optionsCustom = {
                    "LJUnit": str(newUnit),
                    'LJCode': aircon.code,
                    'LJShift': '06'
                }
                name = '0x{} 状态'.format(aircon.code)
                aircon.deviceRoomPoint = Domoticz.Device(Name=name,
                                                         Unit=newUnit,
                                                         TypeName="Text",
                                                         Image=17,
                                                         Options=optionsCustom)
                aircon.deviceRoomPoint.Create()
                aircon.dicDevice[newUnit] = aircon.deviceRoomPoint
                Domoticz.Log(
                    'ADD DEVICE :' +
                    descDevice(device=aircon.deviceRoomPoint, unit=newUnit))

    def revertDic(self, dic):
        if dic:
            return {v: k for k, v in dic.items()}
        return None
Exemplo n.º 24
0
def set_start_time(ModbusClient):
    # Sets the start time to 60s
    # c is ModbusClient
    wr = ModbusClient.write_single_register(4, 200)
    print('set_start_time:' + str(int(wr)))
    return wr
Exemplo n.º 25
0
from pyModbusTCP.client import ModbusClient
import time

#TCP auto connect on first Modbus Request
c = ModbusClient(host="localhost", port=502, auto_open=True)

#TCP auto connect on Modbus Request, close after it
c = ModbusClient(host="127.0.0.1", auto_open=True, auto_close=True)
c = ModbusClient()
c.host("localhost")
c.port(502)

cont = 0
tanque = c.write_single_register(2, 0)
valvula = c.write_single_register(3, 0)
LED = c.write_single_register(1, 0)

while True:
    # managing TCP sessions with call to c.open()/c.close()
    c.open()
    led = c.read_holding_registers(1)
    tanque_valor = c.read_holding_registers(2)

    if led[0] == 1:
        cont = cont + 1
        c.write_single_register(2, cont)
        tanque_valor = c.read_holding_registers(2)

    if tanque_valor[0] == 10:
        c.write_single_register(1, 0)
    if led[0] == 0:
Exemplo n.º 26
0
def set_freq(ModbusClient):
    # Sets the reflected power set point to 100 W
    # c is ModbusClient
    wr = ModbusClient.write_single_register(9, 24000)
    print('set_freq:' + str(int(wr)))
    return wr
class ClientGUI:
    def __init__(self):
        self.lock = RLock()
        self.calibgui = None
        self.client = ModbusClient()
        self.register_values_widgets = {}
        self.counter = 1
        self.find_thread = None
        self.obj_data = None
        self.stop_signal = False
        self.__build_ui()

    def run_ui(self):
        self.root.mainloop()

    def __build_ui(self):
        # ui hierarchy:
        #
        #root
        #   connectframe
        #       connectlabel
        #       connectbutton
        #       snapshotbutton
        #       calibbuton
        #   mainframe
        #       registerframe
        #           reglabel
        #           registergridframe
        #               ...
        #       outputframe
        #           outputlabel
        #           outputtext

        root = Tk()
        self.root = root
        root.wm_title("RemoteSurf Modbus Client")
        root.protocol("WM_DELETE_WINDOW", self.__delete_window)

        self.font = tkFont.Font(root=root, family="Helvetica", size=12)

        connectframe = Frame(root)
        connectbutton = Button(connectframe,
                               text="Connect",
                               command=self.__connectbutton_click)
        connectlabel = Label(connectframe, text="Not connected.")
        calibbutton = Button(connectframe,
                             text="Calibrate",
                             command=self.__calibbutton_click)
        homebutton = Button(connectframe,
                            text="Home",
                            command=self.__homebutton_click)
        findbutton = Button(connectframe,
                            text="Find",
                            command=self.__findbutton_click)
        mainframe = Frame(root)
        registerframe = Frame(mainframe)
        reglabel = Label(registerframe, text="Set registers")
        registergridframe = Frame(registerframe)
        # outputframe = Frame(mainframe)
        # outputlabel = Label(outputframe, text = "Output")
        # vscrollbar = Scrollbar(outputframe)
        # hscrollbar = Scrollbar(outputframe)
        # outputtext = ThreadSafeConsole(outputframe, root, vscrollbar, font = self.font, wrap = NONE)

        connectframe.pack(side=TOP, fill=X)
        connectlabel.pack(side=BOTTOM, anchor=W)
        homebutton.pack(side=RIGHT)
        findbutton.pack(side=RIGHT)
        calibbutton.pack(side=RIGHT)
        connectbutton.pack(side=RIGHT)
        mainframe.pack(side=BOTTOM, fill=BOTH, expand=YES)
        registerframe.pack(side=TOP, expand=YES, anchor=W)
        # outputframe.pack(side = BOTTOM, fill = BOTH, expand = YES)
        reglabel.pack(side=TOP, anchor=CENTER)
        registergridframe.pack(side=BOTTOM, anchor=W)
        # registerframe.config(bg = "cyan")
        # mainframe.config(bg = "pink")
        # registergridframe.config(bg = "red")

        registergridframe.columnconfigure(0, weight=1)
        registergridframe.columnconfigure(1, weight=1)
        registergridframe.columnconfigure(2, weight=1)
        registergridframe.columnconfigure(3, weight=1)

        self.x_pad = 10
        registergrid_widgets = []
        titles = ["Address", "Label", "Value", ""]
        col = 0
        for title in titles:
            title_label = Label(registergridframe, text=title)
            title_label.grid(row=0, column=col, padx=self.x_pad)
            registergrid_widgets.append(title_label)
            col += 1

        registers_data = [
            (500, "x"),
            (501, "y"),
            (502, "z"),
            (503, "A"),
            (504, "B"),
            (505, "C"),
        ]

        for i in range(len(registers_data)):
            reg_data = registers_data[i]
            row = i + 1
            self.__add_register(registergridframe, reg_data, row,
                                registergrid_widgets)

        # hscrollbar.config(orient = HORIZONTAL, command = outputtext.xview)
        # hscrollbar.pack(side = BOTTOM, fill = X)
        # outputtext.config(state = DISABLED, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)  #must change to NORMAL before writing text programmatically
        # outputtext.pack(side = LEFT, fill = BOTH, expand = YES, padx = x_padding, pady = y_padding)
        # vscrollbar.config(command = outputtext.yview)
        # vscrollbar.pack(side = RIGHT, fill = Y)

        self.connectframe = connectframe
        self.connectlabel = connectlabel
        self.connectbutton = connectbutton
        self.mainframe = mainframe
        self.registerframe = registerframe
        self.reglabel = reglabel
        self.registergridframe = registergridframe
        self.calibbutton = calibbutton
        # self.outputframe = outputframe
        # self.outputlabel = outputlabel
        # self.vscrollbar = vscrollbar
        # self.hscrollbar = hscrollbar
        # self.outputtext = outputtext

        root.update()
        w, h = root.winfo_width(), root.winfo_height()
        root.minsize(w, h)
        x, y = MAINFRAME_POS
        root.geometry('%dx%d+%d+%d' % (w, h, x, y))

    def __homebutton_click(self):
        values = {
            500: 300,
            501: 0,
            502: 500,
            503: 180,
            504: 0,
            505: 180,
        }
        self.set_values(values, go_to_value=False)

    def __add_register(self, master, data, row, widget_list):
        regaddresslabel = Label(master, text=str(data[0]))
        regaddresslabel.grid(row=row, column=0)
        reglabellabel = Label(master, text=data[1])
        reglabellabel.grid(row=row, column=1)
        regvalueentry = AccessibleEntry(master, justify=RIGHT)
        regvalueentry.set("0")
        regvalueentry.grid(row=row, column=2, padx=self.x_pad)
        regsetbtn = Button(master, text="Set", command=self.__setbutton_click)
        regsetbtn.grid(row=row, column=3)
        widget_list.append(regaddresslabel)
        widget_list.append(reglabellabel)
        widget_list.append(regvalueentry)
        widget_list.append(regsetbtn)
        self.register_values_widgets[data[0]] = (0, regvalueentry)

    def __calibbutton_click(self):
        if not self.calibgui:
            self.calibgui = CalibGUI(self)

    def __findbutton_click(self):
        if self.find_thread is None:
            self.find_thread = Thread(target=self.__find_object)
            self.find_thread.start()

    def __find_object(self):
        import DataCache as DC
        from glob import glob
        from os.path import join
        import numpy as np
        from SFMSolver import SFMSolver, find_ext_params
        import Utils

        print "FINDING"

        np.set_printoptions(precision=3, suppress=True)

        files_dir = "out/2017_3_8__14_51_22/"
        files = glob(join(files_dir, "*.jpg"))
        masks = []
        for f in files:
            m = f.replace(".jpg", "_mask.png")
            masks.append(m)
        sfm = SFMSolver(files, masks)
        if self.obj_data is None:
            imgs, kpts, points, data = sfm.calc_data_from_files_triang_simple()
            self.obj_data = imgs, kpts, points, data
        else:
            imgs, kpts, points, data = self.obj_data

        arr_calib = DC.getData("out/%s/arrangement_calib.p" %
                               ARRANGEMENT_CALIB_DIR)
        ttc = arr_calib["ttc"]
        tor = arr_calib["tor"]
        if "cam_mtx" in arr_calib:
            print "camMtx, distcoeffs load"
            Utils.camMtx = arr_calib["cam_mtx"]
            Utils.dist_coeffs = arr_calib["dist_coeffs"]

        if self.stop_signal:
            self.stop_signal = False
            return

        for point in FIND_POINTS:
            values = {
                500: point[0],
                501: point[1],
                502: point[2],
                503: point[3],
                504: point[4],
                505: point[5],
            }
            print "set_values call"
            self.set_values(values, True)
            print "set_values return"

            time.sleep(0.5)
            CamGrabber.capture_if_no_chessboard = True
            CamGrabber.capture = True
            time.sleep(0.5)

            if self.stop_signal:
                self.stop_signal = False
                return

        find_dir = logger.outputdir
        files = glob("%s/*.jpg" % find_dir)
        print files
        # files_dir = "out/2017_4_5__15_57_20/"
        # files = glob(join(files_dir, "*.jpg"))
        files.sort()
        files = files[-len(FIND_POINTS):]
        results = []

        for f in files:
            res = find_ext_params(f, imgs, kpts, points, data, tor, ttc)
            results.append(res)
            if self.stop_signal:
                self.stop_signal = False
                return

        for i in range(len(results)):
            print i, results[i]
            write_log((i, results[i]))
        result = max(results, key=lambda x: x[2])
        write_log(result)

        values = {
            500: int(result[0][0] * 10),
            501: int(result[0][1] * 10),
            502: int(result[0][2] * 10) + 200,
            503: int(result[1][2]),
            504: int(result[1][1]),
            505: int(result[1][0]),
        }

        print "num inl: ", result[2]
        pprint(values)
        self.set_values(values, go_to_value=False)
        self.find_thread = None

    def __connectbutton_click(self):
        if self.client.is_open():
            self.client.close()
        else:
            self.client.host(SERVER_HOST)
            self.client.port(SERVER_PORT)
            if self.client.open():
                write_log("Connection established")
                self.refresh_values()
                self.read_robot_pos()
            else:
                write_log("ERROR: Connecting failed")
        self.__update_gui()

    def read_robot_pos(self):
        write_log("Reading robot position:")
        posdict = {}
        for i in range(1000, 1006):
            if self.client.is_open():
                with self.lock:
                    real_val_uint = self.client.read_input_registers(i)[0]
                    real_val_holding_uint = self.client.read_holding_registers(
                        i)[0]
                assert real_val_uint == real_val_holding_uint
                real_val_int = uintToInt16(real_val_uint)
                posdict[i] = real_val_int
                write_log("%d, %d" % (i, real_val_int))
            else:
                write_log(
                    "ERROR: Read could not be completed, client not connected."
                )
                self.__update_gui()
                break
        write_log("Read done.")
        return posdict

    def refresh_values(self):
        for address in self.register_values_widgets:
            if self.client.is_open():
                value, widget = self.register_values_widgets[address]
                with self.lock:
                    real_val_uint = self.client.read_input_registers(
                        address)[0]
                    real_val_holding_uint = self.client.read_holding_registers(
                        address)[0]
                assert real_val_uint == real_val_holding_uint
                real_val_int = uintToInt16(real_val_uint)
                widget.set(str(real_val_int))
                self.register_values_widgets[address] = (real_val_int, widget)
            else:
                write_log(
                    "ERROR: Read could not be completed, client not connected."
                )
                self.__update_gui()
                break
        write_log("Refresh done.")
        return self.register_values_widgets

    def __update_gui(self):
        if self.client.is_open():
            self.connectlabel.config(text="Connected to: %s:%d" %
                                     (SERVER_HOST, SERVER_PORT))
            self.connectbutton.config(text="Disconnect")
        else:
            self.connectbutton.config(text="Connect")
            self.connectlabel.config(text="Not connected.")
        self.root.update()

    def __print_memory(self):
        self.refresh_values()
        write_log("Memory dump:")
        write_log("------------")
        for address in self.register_values_widgets:
            val, widget = self.register_values_widgets[address]
            write_log("%d, %d" % (address, val))
        write_log("------------")

    def __setbutton_click(self, wait=False):
        if not self.client.is_open():
            write_log("ERROR: Not connected to client")
            return

        # writing message counter
        retval = self.__write_register(COUNTER_REGISTER_OUT, self.counter)
        if not retval:
            self.__update_gui()
            return

        # writing registers
        for address in self.register_values_widgets:
            value, widget = self.register_values_widgets[address]
            widgetvalue_int = None
            try:
                widgetvalue_int = int(widget.get())
            except ValueError:
                write_log(
                    "ERROR: Wrong input format in value entry for address: %d"
                    % address)
                continue

            if value == widgetvalue_int:
                continue

            retval = self.__write_register(address, widgetvalue_int)
            if retval:
                self.register_values_widgets[address] = (widgetvalue_int,
                                                         widget)
            else:
                self.__update_gui()
        self.refresh_values()

        # message counter wait
        if wait:
            global break_wait
            while not break_wait:
                with self.lock:
                    counter = self.client.read_input_registers(
                        COUNTER_REGISTER_IN)[0]
                if counter == self.counter:
                    break
                time.sleep(0.1)
            break_wait = False

        # counter increment
        self.counter = (self.counter + 1) % 20

        if PRINT_ALL_MEMORY_ON_WRITE:
            self.__print_memory()
            self.read_robot_pos()

    def __write_register(self, address, value):
        if not (-32768 <= value <= 32767):
            write_log(
                "ERROR: -32768 <= value <= 32767 is false for address: %d" %
                address)
            return False

        widgetvalue_uint = intToUint16(value)
        if self.client.is_open():
            with self.lock:
                retval = self.client.write_single_register(
                    address, widgetvalue_uint)
            if retval:
                write_log("Register written. Address: %d, value: %d" %
                          (address, value))
                return True
            else:
                write_log("ERROR: Write failed. Address: %d, value: %d" %
                          (address, value))
        else:
            write_log("ERROR: client not connected.")
        return False

    def set_values(self, values, wait=True, go_to_value=True):
        """
        :param values: dictionary of { address : value} both int
        :return:
        """
        for address in values:
            if address not in self.register_values_widgets:
                continue

            val, widget = self.register_values_widgets[address]
            widget.set(str(values[address]))
        if go_to_value:
            self.__setbutton_click(wait)

    def __delete_window(self):
        CamGrabber.exit = True
        self.stop_signal = True
        self.client.close()
        self.root.quit()
Exemplo n.º 28
0
# define o cliente
c = ModbusClient()

# debug do cliente
#c.debug(True)

# ip/porta do servidor modbus (para se conectar)
c.host("10.13.110.215")
c.port(502)

while True:
    # para abrir a conexao TCP com o servidor
    if not c.is_open():
        if not c.open():
            print ("unable to connect")
    
    # read_coils() para leitura de dados vindo do servidor/supervisorio
    on = c.read_coils(6)

    # se a conexao estabelecida, entao escreve (write coils (modbus function 0x01))
    if c.is_open():
        
        c.write_single_coil(v1, valvula1)
        c.write_single_coil(v2, valvula2)

        c.write_single_register(n1, nivel1)
        c.write_single_register(n2, nivel2)
        
        # ... logica de codigo a implementar de acordo com a aplicacao a ser desenvolvida
Exemplo n.º 29
0
class ClienteMODBUS():
    """
    Classe Cliente MODBUS
    """
    def __init__(self,
                 server_ip,
                 porta,
                 device_id=1,
                 scan_time=0.1,
                 valor=0,
                 dbpath="C:\database.db"):
        """
        Construtor
        """
        self._scan_time = scan_time
        self._server_ip = server_ip
        self._device_id = device_id
        self._port = porta
        self._cliente = ModbusClient(host=server_ip,
                                     port=porta,
                                     unit_id=device_id)

        self._dbpath = dbpath
        self._valor = valor
        self._con = sqlite3.connect(self._dbpath)
        self._cursor = self._con.cursor()

    def atendimento(self):
        """
        Método para atendimento do usuário
        """
        try:
            self._cliente.open()
            print('\n\033[33m --> Cliente Modbus conectado..\033[m\n')

        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

        try:
            atendimento = True
            while atendimento:
                print('-' * 100)
                print('\033[34mCliente Modbus\033[m'.center(100))
                print('-' * 100)
                sel = input(
                    "Qual serviço? \n1- Leitura \n2- Escrita \n3- Configuração \n4- Sair \nNº Serviço: "
                )
                if sel == '1':
                    self.createTable()
                    self.createTableF01()
                    self.createTableF02()
                    self.createTableF03()
                    self.createTableF04()
                    print('\nQual tipo de dado deseja ler?')
                    print(
                        "1- Coil Status \n2- Input Status \n3- Holding Register \n4- Input Register"
                    )
                    while True:
                        tipo = int(input("Type: "))
                        if tipo > 4:
                            print('\033[31mDigite um tipo válido..\033[m')
                            sleep(0.5)
                        else:
                            break

                    if tipo == 3 or tipo == 4:
                        while True:
                            val = int(
                                input(
                                    "\n1- Decimal \n2- Floating Point \n3- Float Swapped \nLeitura: "
                                ))
                            if val > 3:
                                print('\033[31mDigite um tipo válido..\033[m')
                                sleep(0.5)
                            else:
                                break
                        if val == 1:  #valores decimais
                            addr = int(input(f'\nAddress: '))
                            leng = int(input(f'Length: '))
                            nvezes = input('Quantidade de leituras: ')
                            print('\nComeçando leitura Decimal..\n')
                            sleep(0.5)
                            try:
                                for i in range(0, int(nvezes)):
                                    print(f'\033[33mLeitura {i+1}:\033[m',
                                          end='')
                                    print(
                                        self.lerDado(int(tipo), int(addr),
                                                     leng))
                                    sleep(self._scan_time)
                                print(
                                    '\nValores lidos e inseridos no DB com sucesso!!\n'
                                )
                                sleep(0.5)
                            except Exception as e:
                                print('\033[31mERRO: ', e.args, '\033[m')
                                try:
                                    sleep(0.5)
                                    print(
                                        '\033[33m\nTentando novamente..\033[m')
                                    if not self._cliente.is_open():
                                        self._cliente.open()
                                    sleep(0.5)
                                    for i in range(0, int(nvezes)):
                                        print(
                                            f'\033[33mLeitura {i + 1}:\033[m',
                                            end='')
                                        print(
                                            self.lerDado(
                                                int(tipo), int(addr), leng))
                                        sleep(self._scan_time)
                                    print(
                                        '\nValores lidos e inseridos no DB com sucesso!!\n'
                                    )
                                    sleep(0.5)
                                except Exception as e:
                                    print('\033[31mERRO: ', e.args, '\033[m')
                                    print(
                                        '\nO Cliente não conseguiu receber uma resposta.. \nVoltando ao menu..\n\n'
                                    )
                                    sleep(1.5)

                        elif val == 2:  #valores FLOAT
                            addr = input(f'\nAddress: ')
                            leng = int(input(f'Length: '))
                            nvezes = input('Quantidade de leituras: ')
                            print('\nComeçando leitura FLOAT..\n')
                            sleep(0.5)
                            try:
                                for i in range(0, int(nvezes)):
                                    print(f'\033[33mLeitura {i + 1}:\033[m',
                                          end='')
                                    print(
                                        self.lerDadoFloat(
                                            int(tipo), int(addr), leng))
                                    sleep(self._scan_time)
                                print(
                                    '\nValores lidos e inseridos no DB com sucesso!!\n'
                                )
                                sleep(0.5)
                            except Exception as e:
                                print('\033[31mERRO: ', e.args, '\033[m\n')
                                print(
                                    'O Cliente não conseguiu receber uma resposta.. \nVoltando ao menu..\n\n'
                                )
                                sleep(1.5)

                        elif val == 3:  #valores FLOAT SWAPPED
                            addr = input(f'\nAddress: ')
                            leng = int(input(f'Length: '))
                            nvezes = input('Quantidade de leituras: ')
                            print('\nComeçando leitura FLOAT SWAPPED..\n')
                            sleep(0.5)
                            try:
                                for i in range(0, int(nvezes)):
                                    print(f'\033[33mLeitura {i + 1}:\033[m',
                                          end='')
                                    print(
                                        self.lerDadoFloatSwapped(
                                            int(tipo), int(addr), leng))
                                    sleep(self._scan_time)
                                print(
                                    '\nValores lidos e inseridos no DB com sucesso!!\n'
                                )
                                sleep(0.5)
                            except Exception as e:
                                print('\033[31mERRO: ', e.args, '\033[m\n')
                                print(
                                    'O Cliente não conseguiu receber uma resposta.. \nVoltando ao menu..\n\n'
                                )
                                sleep(1.5)

                        else:
                            print('\033[31mSeleção inválida..\033[m\n')
                            sleep(0.7)

                    else:
                        addr = input(f'\nAddress: ')
                        leng = int(input(f'Length: '))
                        nvezes = input('Quantidade de leituras: ')
                        print('\nComeçando leitura..\n')
                        sleep(0.5)
                        try:
                            for i in range(0, int(nvezes)):
                                print(f'\033[33mLeitura {i + 1}:\033[m',
                                      end='')
                                print(self.lerDado(int(tipo), int(addr), leng))
                                sleep(self._scan_time)
                            print(
                                '\nValores lidos e inseridos no DB com sucesso!!\n'
                            )
                            sleep(0.5)
                        except Exception as e:
                            print('\033[31mERRO: ', e.args, '\033[m\n')
                            print(
                                'O Cliente não conseguiu receber uma resposta.. \nVoltando ao menu..\n\n'
                            )
                            sleep(1.5)

                elif sel == '2':
                    print(
                        '\nQual tipo de dado deseja escrever? \n1- Coil Status \n2- Holding Register'
                    )
                    while True:
                        tipo = int(input("Tipo: "))
                        if tipo > 2:
                            print('\033[31mDigite um tipo válido..\033[m')
                            sleep(0.5)
                        else:
                            break
                    addr = input(f'Digite o endereço: ')
                    valor = int(input(f'Digite o valor que deseja escrever: '))
                    try:
                        print('\nEscrevendo..')
                        sleep(0.5)
                        self.escreveDado(int(tipo), int(addr), valor)
                    except Exception as e:
                        print('\033[31mERRO: ', e.args, '\033[m')
                        print(
                            '\nO Cliente não conseguiu escrever.. \nVoltando ao menu..\n\n'
                        )
                        sleep(1.5)

                elif sel == '3':
                    print('')
                    print('-' * 100)
                    print('Configurações de Leitura'.center(100))
                    print(
                        f'\n\033[32m->\033[m Configuração atual: - IP Addrs: \033[35m{self._server_ip}\033[m - TCP Port: \033[35m{self._port}\033[m - Device ID: \033[35m{self._device_id}\033[m - Scan_Time: \033[35m{self._scan_time}\033[ms'
                    )
                    print(
                        '\nQual tipo de configuração deseja fazer? \n1- Endereço IP \n2- Porta TCP \n3- Device ID \n4- ScanTime \n5- Voltar'
                    )
                    config = int(input("Configuração: "))
                    if config == 1:
                        ipserv = str(input(' Novo endereço IP: '))
                        try:
                            self._cliente.close()
                            self._server_ip = ipserv
                            self._cliente = ModbusClient(host=self._server_ip)
                            self._cliente.open()
                            print(
                                f'\nServer IP alterado para {ipserv} com sucesso!!\n'
                            )
                            sleep(0.5)
                        except Exception as e:
                            print('\033[31mERRO: ', e.args, '\033[m')
                            print(
                                '\nNão foi possível alterar o endereço IP.. \nVoltando ao menu..\n\n'
                            )
                            sleep(0.5)
                    elif config == 2:
                        porttcp = input(' Nova porta TCP: ')
                        try:
                            self._cliente.close()
                            self._port = int(porttcp)
                            self._cliente = ModbusClient(port=self._port)
                            self._cliente.open()
                            print(
                                f'\nTCP port alterado para {porttcp} com sucesso!!\n'
                            )
                            sleep(0.5)
                        except Exception as e:
                            print('\033[31mERRO: ', e.args, '\033[m')
                            print(
                                '\nNão foi possível alterar a porta.. \nVoltando ao menu..\n\n'
                            )
                            sleep(0.5)
                    elif config == 3:
                        while True:
                            iddevice = input(' Novo device ID: ')
                            if 0 <= int(iddevice) < 256:
                                break
                            else:
                                print(
                                    '\033[31mDevice ID deve ser um número inteiro entre 0 e 256.\033[m',
                                    end='')
                                sleep(0.5)
                        try:
                            self._cliente.close()
                            self._device_id = int(iddevice)
                            self._cliente = ModbusClient(
                                unit_id=self._device_id)
                            self._cliente.open()
                            print(
                                f'\nDevice ID alterado para {iddevice} com sucesso!!\n'
                            )
                            sleep(0.5)
                        except Exception as e:
                            print('\033[31mERRO: ', e.args, '\033[m')
                            print(
                                '\nNão foi possível alterar o ID do device.. \nVoltando ao menu..\n\n'
                            )
                            sleep(0.5)
                    elif config == 4:
                        scant = input(' Novo tempo de varredura [s]: ')
                        try:
                            self._scan_time = float(scant)
                            print(
                                f'\nScan_time alterado para {scant}s com sucesso!!\n'
                            )
                        except Exception as e:
                            print('\033[31mERRO: ', e.args, '\033[m')
                            print(
                                '\nNão foi possível alterar o tempo de varredura.. \nVoltando ao menu..\n\n'
                            )
                            sleep(0.5)
                    elif config == 5:
                        print('\nVoltando ao menu inicial..\n')
                        sleep(0.5)
                    else:
                        print('\033[31mSeleção inválida..\033[m\n')
                        sleep(0.7)

                elif sel == '4':
                    sleep(0.2)
                    print('\n\033[32mFechando sistema..\033[m')
                    sleep(0.5)
                    self._cliente.close()
                    atendimento = False

                else:
                    print('\033[31mSeleção inválida..\033[m\n')
                    sleep(0.7)
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def createTable(self):
        """
        Método que cria a tabela para armazenamento dos dados, caso ela não exista
        """
        try:
            sql_str = f"""
            CREATE TABLE IF NOT EXISTS pointValues (
                ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Address TEXT, Type TEXT, Display TEXT, Value REAL, TimeStamp1 TEXT NOT NULL)
                """
            self._cursor.execute(sql_str)
            self._con.commit()
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def inserirDB(self, addrs, tipo, disp, value):
        """
        Método para inserção dos dados no DB
        """
        try:
            date = str(
                datetime.datetime.fromtimestamp(int(
                    time.time())).strftime("%Y-%m-%d %H:%M:%S"))
            str_values = f"'{addrs}', {tipo}, {disp}, {value}, '{date}'"
            sql_str = f'INSERT INTO pointValues (Address, Type, Display, Value, TimeStamp1) VALUES ({str_values})'
            self._cursor.execute(sql_str)
            self._con.commit()
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def createTableF01(self):
        """
        Método que cria a tabela para armazenamento dos dados, caso ela não exista
        """
        try:
            sql_str = f"""
            CREATE TABLE IF NOT EXISTS pointValuesF01 (
                ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Address TEXT, Type TEXT, Display TEXT, Value REAL, TimeStamp1 TEXT NOT NULL)
                """
            self._cursor.execute(sql_str)
            self._con.commit()
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def createTableF02(self):
        """
        Método que cria a tabela para armazenamento dos dados, caso ela não exista
        """
        try:
            sql_str = f"""
            CREATE TABLE IF NOT EXISTS pointValuesF02 (
                ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Address TEXT, Type TEXT, Display TEXT, Value REAL, TimeStamp1 TEXT NOT NULL)
                """
            self._cursor.execute(sql_str)
            self._con.commit()
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def createTableF03(self):
        """
        Método que cria a tabela para armazenamento dos dados, caso ela não exista
        """
        try:
            sql_str = f"""
            CREATE TABLE IF NOT EXISTS pointValuesF03 (
                ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Address TEXT, Type TEXT, Display TEXT, Value REAL, TimeStamp1 TEXT NOT NULL)
                """
            self._cursor.execute(sql_str)
            self._con.commit()
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def createTableF04(self):
        """
        Método que cria a tabela para armazenamento dos dados, caso ela não exista
        """
        try:
            sql_str = f"""
            CREATE TABLE IF NOT EXISTS pointValuesF04 (
                ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Address TEXT, Type TEXT, Display TEXT, Value REAL, TimeStamp1 TEXT NOT NULL)
                """
            self._cursor.execute(sql_str)
            self._con.commit()
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def inserirDBF0(self, addrs, tipo, disp, value):
        """
        Método para inserção dos dados no DB
        """
        try:
            if tipo == "'F01-CoilStatus'":
                date = str(
                    datetime.datetime.fromtimestamp(int(
                        time.time())).strftime("%Y-%m-%d %H:%M:%S"))
                str_values = f"'{addrs}', {tipo}, {disp}, {value}, '{date}'"
                sql_str = f'INSERT INTO pointValuesF01 (Address, Type, Display, Value, TimeStamp1) VALUES ({str_values})'
                self._cursor.execute(sql_str)
                self._con.commit()
            elif tipo == "'F02-InputStatus'":
                date = str(
                    datetime.datetime.fromtimestamp(int(
                        time.time())).strftime("%Y-%m-%d %H:%M:%S"))
                str_values = f"'{addrs}', {tipo}, {disp}, {value}, '{date}'"
                sql_str = f'INSERT INTO pointValuesF02 (Address, Type, Display, Value, TimeStamp1) VALUES ({str_values})'
                self._cursor.execute(sql_str)
                self._con.commit()
            elif tipo == "'F03-HoldingRegister'":
                date = str(
                    datetime.datetime.fromtimestamp(int(
                        time.time())).strftime("%Y-%m-%d %H:%M:%S"))
                str_values = f"'{addrs}', {tipo}, {disp}, {value}, '{date}'"
                sql_str = f'INSERT INTO pointValuesF03 (Address, Type, Display, Value, TimeStamp1) VALUES ({str_values})'
                self._cursor.execute(sql_str)
                self._con.commit()
            elif tipo == "'F04-InputRegister'":
                date = str(
                    datetime.datetime.fromtimestamp(int(
                        time.time())).strftime("%Y-%m-%d %H:%M:%S"))
                str_values = f"'{addrs}', {tipo}, {disp}, {value}, '{date}'"
                sql_str = f'INSERT INTO pointValuesF04 (Address, Type, Display, Value, TimeStamp1) VALUES ({str_values})'
                self._cursor.execute(sql_str)
                self._con.commit()
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def inserirDBFP(self, addrs, tipo, disp, value):
        """
        Método para inserção dos dados no DB
        """
        try:
            if tipo == "'F03-HoldingRegister'":
                date = str(
                    datetime.datetime.fromtimestamp(int(
                        time.time())).strftime("%Y-%m-%d %H:%M:%S"))
                str_values = f"'{addrs}', {tipo}, {disp}, {value}, '{date}'"
                sql_str = f'INSERT INTO pointValuesF03 (Address, Type, Display, Value, TimeStamp1) VALUES ({str_values})'
                self._cursor.execute(sql_str)
                self._con.commit()
            elif tipo == "'F04-InputRegister'":
                date = str(
                    datetime.datetime.fromtimestamp(int(
                        time.time())).strftime("%Y-%m-%d %H:%M:%S"))
                str_values = f"'{addrs}', {tipo}, {disp}, {value}, '{date}'"
                sql_str = f'INSERT INTO pointValuesF04 (Address, Type, Display, Value, TimeStamp1) VALUES ({str_values})'
                self._cursor.execute(sql_str)
                self._con.commit()
            else:
                print(
                    "Erro ao inserir no DB com Floating Point e Float Swapped!!"
                )
        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')

    def lerDado(self, tipo, addr, leng=1):
        """
        Método para leitura MODBUS
        """
        if tipo == 1:
            co = self._cliente.read_coils(addr - 1, leng)
            ic = 0
            while ic <= leng:
                if ic == leng:
                    break
                else:
                    value = co[0 + ic]
                    ic += 1
                    # print(value)
                    if value == True:
                        value = 1
                    else:
                        value = 0
                    ende = str(addr + ic - 1).zfill(5)
                    self.inserirDB(addrs=str(ende),
                                   tipo="'F01-CoilStatus'",
                                   disp="'Booleano'",
                                   value=value)
                    self.inserirDBF0(addrs=str(ende),
                                     tipo="'F01-CoilStatus'",
                                     disp="'Booleano'",
                                     value=value)
            return co

        elif tipo == 2:
            di = self._cliente.read_discrete_inputs(addr - 1, leng)
            idi = 0
            while idi <= leng:
                if idi == leng:
                    break
                else:
                    value = di[0 + idi]
                    idi += 1
                    # print(value)
                    self.inserirDB(addrs=(10000 + addr + idi - 1),
                                   tipo="'F02-InputStatus'",
                                   disp="'Booleano'",
                                   value=value)
                    self.inserirDBF0(addrs=(10000 + addr + idi - 1),
                                     tipo="'F02-InputStatus'",
                                     disp="'Booleano'",
                                     value=value)
            return di

        elif tipo == 3:
            hr = self._cliente.read_holding_registers(addr - 1, leng)
            ihr = 0
            while ihr <= leng:
                if ihr == leng:
                    break
                else:
                    value = hr[0 + ihr]
                    ihr += 1
                    # print(value)
                    self.inserirDB(addrs=(40000 + addr + ihr - 1),
                                   tipo="'F03-HoldingRegister'",
                                   disp="'Decimal'",
                                   value=value)
                    self.inserirDBF0(addrs=(40000 + addr + ihr - 1),
                                     tipo="'F03-HoldingRegister'",
                                     disp="'Decimal'",
                                     value=value)
            return hr

        elif tipo == 4:
            ir = self._cliente.read_input_registers(addr - 1, leng)
            iir = 0
            while iir <= leng:
                if iir == leng:
                    break
                else:
                    value = ir[0 + iir]
                    iir += 1
                    # print(value)
                    self.inserirDB(addrs=(30000 + addr + iir - 1),
                                   tipo="'F04-InputRegister'",
                                   disp="'Decimal'",
                                   value=value)
                    self.inserirDBF0(addrs=(30000 + addr + iir - 1),
                                     tipo="'F04-InputRegister'",
                                     disp="'Decimal'",
                                     value=value)
            return ir

        else:
            print('Tipo de leitura inválido..')

    def lerDadoFloat(self, tipo, addr, leng):
        """
        Método para leitura FLOAT MODBUS
        """
        i = 0
        g = 0
        e1 = []
        listfloat = []
        while i < leng:
            if tipo == 3:
                i1 = self._cliente.read_holding_registers(addr - 1 + g, 2)
                tipore = "'F03-HoldingRegister'"
                ende = 40000
            elif tipo == 4:
                i1 = self._cliente.read_input_registers(addr - 1 + g, 2)
                tipore = "'F04-InputRegister'"
                ende = 30000
            else:
                print('Tipo inválido..')
            for x in i1:
                x = bin(x).lstrip("0b")
                e1.insert(0 + g, x)
            i += 1
            g += 2
        e = 0
        while e <= leng:
            e2 = ''
            for x in e1:
                e2 = str(f'{e2}{x.rjust(16, "0")} ')
            e += 1
        b2 = str(f'{e2}')
        e3 = b2.split()
        y = 0
        while y < len(e3):
            ieee = f'{e3[0+y]}{e3[1+y]}'
            sign = int(ieee[0])
            expo = str(ieee[1:9])
            expodec = 0
            expopot = 7
            for i in range(8):
                expodec = expodec + (int(expo[i]) * (2**expopot))
                expopot -= 1
            mant = str(ieee[9:])
            mantdec = 0
            mantpot = -1
            for i in range(23):
                mantdec = mantdec + (int(mant[i]) * (2**mantpot))
                mantpot -= 1
            value = ((-1)**sign) * (1 + mantdec) * 2**(expodec - 127)
            # print(f'{round(value, 3)}')
            listfloat.append(round(value, 3))
            y += 2
            self.inserirDB(addrs=(ende + addr + y - 2),
                           tipo=tipore,
                           disp="'Floating Point'",
                           value=round(value, 3))
            self.inserirDBFP(addrs=(ende + addr + y - 2),
                             tipo=tipore,
                             disp="'Floating Point'",
                             value=round(value, 3))
        return listfloat

    def lerDadoFloatSwapped(self, tipo, addr, leng):
        """
        Método para leitura FLOAT SWAPPED MODBUS
        """
        i = 0
        g = 0
        e1 = []
        listfloatsp = []
        while i < leng:
            if tipo == 3:
                i1 = self._cliente.read_holding_registers(addr - 1 + g, 2)
                tipore = "'F03-HoldingRegister'"
                ende = 40000
            elif tipo == 4:
                i1 = self._cliente.read_input_registers(addr - 1 + g, 2)
                tipore = "'F04-InputRegister'"
                ende = 30000
            else:
                print('Tipo inválido..')
            i2 = i1[::-1]
            for x in i2:
                x = bin(x).lstrip("0b")
                e1.insert(0 + g, x)
            i += 1
            g += 2
        e = 0
        while e <= leng:
            e2 = ''
            for x in e1:
                e2 = str(f'{e2}{x.rjust(16, "0")} ')
            e += 1
        b2 = str(f'{e2}')
        e3 = b2.split()
        y = 0
        while y < len(e3):
            ieee = f'{e3[0+y]}{e3[1+y]}'
            sign = int(ieee[0])
            expo = str(ieee[1:9])
            expodec = 0
            expopot = 7
            for i in range(8):
                expodec = expodec + (int(expo[i]) * (2**expopot))
                expopot -= 1
            mant = str(ieee[9:])
            mantdec = 0
            mantpot = -1
            for i in range(23):
                mantdec = mantdec + (int(mant[i]) * (2**mantpot))
                mantpot -= 1
            value = ((-1)**sign) * (1 + mantdec) * 2**(expodec - 127)
            # print(f'{round(value, 3)}')
            listfloatsp.append(round(value, 3))
            y += 2
            self.inserirDB(addrs=(ende + addr + y - 2),
                           tipo=tipore,
                           disp="'Float (Swapped)'",
                           value=round(value, 3))
            self.inserirDBFP(addrs=(ende + addr + y - 2),
                             tipo=tipore,
                             disp="'Float (Swapped)'",
                             value=round(value, 3))
        return listfloatsp

    def escreveDado(self, tipo, addr, valor):
        """
        Método para escrita MODBUS
        """
        try:
            if tipo == 1:
                print(
                    f'\033[33mValor {valor} escrito no endereço {addr}\033[m\n'
                )
                return self._cliente.write_single_coil(addr - 1, valor)
            elif tipo == 2:
                print(
                    f'\033[33mValor {valor} escrito no endereço {addr}\033[m\n'
                )
                return self._cliente.write_single_register(addr - 1, valor)
            else:
                print('Tipo de escrita inválido..\n')

        except Exception as e:
            print('\033[31mERRO: ', e.args, '\033[m')
Exemplo n.º 30
0
class ET7000:
    ranges = {
        0x00: {
            'min': -0.015,
            'max': 0.015,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x01: {
            'min': -0.05,
            'max': 0.05,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x02: {
            'min': -0.1,
            'max': 0.1,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x03: {
            'min': -0.5,
            'max': 0.5,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x04: {
            'min': -1.,
            'max': 1.,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x05: {
            'min': -2.5,
            'max': 2.5,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x06: {
            'min': -20.0e-3,
            'max': 20.0e-3,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'A'
        },
        0x07: {
            'units': 'A',
            'min': 4.0e-3,
            'min_code': 0x0000,
            'max_code': 0xffff,
            'max': 20.0e-3
        },
        0x08: {
            'units': 'V',
            'min': -10.,
            'max': 10.,
            'min_code': 0x8000,
            'max_code': 0x7fff,
        },
        0x09: {
            'units': 'V',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -5.,
            'max': 5.
        },
        0x0A: {
            'units': 'V',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -1.,
            'max': 1.
        },
        0x0B: {
            'units': 'V',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -.5,
            'max': .5
        },
        0x0C: {
            'units': 'V',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -.15,
            'max': .15
        },
        0x0D: {
            'min': -20.0e-3,
            'max': 20.0e-3,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'A'
        },
        0x0E: {
            'units': 'degC',
            'min_code': 0xdca2,
            'max_code': 0x7fff,
            'min': -210.0,
            'max': 760.0
        },
        0x0F: {
            'units': 'degC',
            'min_code': 0xe6d0,
            'max_code': 0x7fff,
            'min': -270.0,
            'max': 1372.0
        },
        0x10: {
            'units': 'degC',
            'min_code': 0xa99a,
            'max_code': 0x7fff,
            'min': -270.0,
            'max': 400.0
        },
        0x11: {
            'units': 'degC',
            'min_code': 0xdd71,
            'max_code': 0x7fff,
            'min': -270.0,
            'max': 1000.0
        },
        0x12: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 1768.0
        },
        0x13: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 1768.0
        },
        0x14: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 1820.0
        },
        0x15: {
            'units': 'degC',
            'min_code': 0xe56b,
            'max_code': 0x7fff,
            'min': -270.0,
            'max': 1300.0
        },
        0x16: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 2320.0
        },
        0x17: {
            'units': 'degC',
            'min_code': 0xe000,
            'max_code': 0x7fff,
            'min': -200.0,
            'max': 800.0
        },
        0x18: {
            'units': 'degC',
            'min_code': 0x8000,
            'max_code': 0x4000,
            'min': -200.0,
            'max': 100.0
        },
        0x19: {
            'units': 'degC',
            'min_code': 0xe38e,
            'max_code': 0xffff,
            'min': -200.0,
            'max': 900.0
        },
        0x1A: {
            'min': 0.0,
            'max': 20.0e-3,
            'min_code': 0x0000,
            'max_code': 0xffff,
            'units': 'A'
        },
        0x20: {
            'units': 'degC',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -100.0,
            'max': 100.0
        },
        0x21: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 100.0
        },
        0x22: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 200.0
        },
        0x23: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 600.0
        },
        0x24: {
            'units': 'degC',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -100.0,
            'max': 100.0
        },
        0x25: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 100.0
        },
        0x26: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 200.0
        },
        0x27: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 600.0
        },
        0x28: {
            'units': 'degC',
            'min_code': 0x999a,
            'max_code': 0x7fff,
            'min': -80.0,
            'max': 100.0
        },
        0x29: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 100.0
        },
        0x2A: {
            'units': 'degC',
            'min_code': 0xd556,
            'max_code': 0x7fff,
            'min': -200.0,
            'max': 600.0
        },
        0x2B: {
            'units': 'degC',
            'min_code': 0xeeef,
            'max_code': 0x7fff,
            'min': -20.0,
            'max': 150.0
        },
        0x2C: {
            'units': 'degC',
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 200.0
        },
        0x2D: {
            'units': 'degC',
            'min_code': 0xeeef,
            'max_code': 0x7fff,
            'min': -20.0,
            'max': 150.0
        },
        0x2E: {
            'units': 'degC',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -200.0,
            'max': 200.0
        },
        0x2F: {
            'units': 'degC',
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'min': -200.0,
            'max': 200.0
        },
        0x80: {
            'units': 'degC',
            'min_code': 0xd556,
            'max_code': 0x7fff,
            'min': -200.0,
            'max': 600.0
        },
        0x81: {
            'units': 'degC',
            'min_code': 0xd556,
            'max_code': 0x7fff,
            'min': -200.0,
            'max': 600.0
        },
        0x82: {
            'units': 'degC',
            'min_code': 0xd556,
            'max_code': 0x7fff,
            'min': -50.0,
            'max': 150.0
        },
        0x83: {
            'min_code': 0xd556,
            'max_code': 0x7fff,
            'units': 'degC',
            'min': -60.0,
            'max': 180.0
        },
        0x30: {
            'min_code': 0x0000,
            'max_code': 0xffff,
            'min': 0.0,
            'max': 20.0e-3,
            'units': 'A'
        },
        0x31: {
            'min_code': 0x0000,
            'max_code': 0xffff,
            'min': 4.0e-3,
            'max': 20.0e-3,
            'units': 'A'
        },
        0x32: {
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'min': 0.0,
            'max': 10.0,
            'units': 'V'
        },
        0x33: {
            'min': -10.0,
            'max': 10.0,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x34: {
            'min': 0.0,
            'max': 5.0,
            'min_code': 0x0000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0x35: {
            'min': -5.0,
            'max': 5.0,
            'min_code': 0x8000,
            'max_code': 0x7fff,
            'units': 'V'
        },
        0xff: {
            'min': 0,
            'max': 0xffff,
            'min_code': 0x0000,
            'max_code': 0xffff,
            'units': '?'
        }
    }
    devices = {0x7015: {}, 0x7016: {}, 0x7018: {}, 0x7060: {}, 0x7026: {}}

    @staticmethod
    def range(r):
        if r in ET7000.ranges:
            return (ET7000.ranges[r])
        return ET7000.ranges[0xff]

    # default conversion from quanta to real units
    @staticmethod
    def convert(b, amin, amax):
        b = float(b)
        # обрабатывается 2 случая - минимум нулевой или больше 0
        if amin >= 0 and amax > 0:
            return amin + (amax - amin) * b / 0xffff
        # и минимум  и максимум разного знака
        if amin < 0 and amax > 0:
            range = max(-amin, amax)
            if b <= 0x7fff:
                return range * b / 0x7fff
            else:
                return range * (0x8000 - b) / 0x8000
        # в других случаях ошибка
        return float('nan')

    @staticmethod
    def ai_convert_function(r):
        v_min = 0
        v_max = 0xffff
        c_min = 0
        c_max = 0xffff
        try:
            v_min = ET7000.ranges[r]['min']
            v_max = ET7000.ranges[r]['max']
            c_min = ET7000.ranges[r]['min_code']
            c_max = ET7000.ranges[r]['max_code']
        except:
            pass
        if c_min < c_max:
            k = (v_max - v_min) / (c_max - c_min)
            b = v_min - k * c_min
            return lambda x: k * x + b
        k_max = v_max / c_max
        k_min = v_min / (0x10000 - c_min)
        #return lambda x: (x < 0x8000) * k_max * x + (x >= 0x8000) *  k_min * (0x10000 - x)
        return lambda x: k_max * x if x < 0x8000 else k_min * (0x10000 - x)

    @staticmethod
    def ao_convert_function(r):
        v_min = 0
        v_max = 0xffff
        c_min = 0
        c_max = 0xffff
        try:
            v_min = ET7000.ranges[r]['min']
            v_max = ET7000.ranges[r]['max']
            c_min = ET7000.ranges[r]['min_code']
            c_max = ET7000.ranges[r]['max_code']
        except:
            pass
        #print(hex(r), v_min, v_max, c_min, c_max)
        if c_min < c_max:
            k = (c_max - c_min) / (v_max - v_min)
            b = c_min - k * v_min
            return lambda x: int(k * x + b)
        k_max = c_max / v_max
        k_min = (0xffff - c_min) / v_min
        #return lambda x: int((x >= 0) * k_max * x + (x < 0) * (0xffff - k_min * x))
        return lambda x: int(k_max * x) if (x >= 0) else int(0xffff - k_min * x
                                                             )

    @staticmethod
    def convert_to_raw(v, amin, amax):
        v = float(v)
        # обрабатывается 2 случая - минимум нулевой или больше 0
        if amin >= 0 and amax > 0:
            return int((v - amin) / (amax - amin) * 0xffff)
        # и минимум  и максимум разного знака
        if amin < 0 and amax > 0:
            if v >= 0.0:
                return int(v * 0x7fff / amax)
            else:
                return int(0x8000 - v / amax * 0x7fff)
        # в других случаях ошибка
        return 0

    def __init__(self, host, port=502, timeout=0.15, logger=None):
        self.host = host
        self.port = port
        # logger confid
        if logger is None:
            logger = logging.getLogger(__name__)
        self.logger = logger
        # default device type
        self._name = 0
        self.type = '0000'
        # default ai
        self.AI_n = 0
        self.AI_masks = []
        self.AI_ranges = []
        self.AI_min = []
        self.AI_max = []
        self.AI_units = []
        self.AI_raw = []
        self.AI_values = []
        # default ao
        self.AO_n = 0
        self.AO_masks = []
        self.AO_ranges = []
        self.AO_min = []
        self.AO_max = []
        self.AO_units = []
        self.AO_raw = []
        self.AO_values = []
        self.AO_write_raw = []
        self.AO_write_values = []
        self.AO_write_result = False
        # default di
        self.DI_n = 0
        self.DI_values = []
        # default do
        self.DO_n = 0
        self.DO_values = []
        # modbus client
        self._client = ModbusClient(host,
                                    port,
                                    auto_open=True,
                                    auto_close=True,
                                    timeout=timeout)
        status = self._client.open()
        if not status:
            self.logger.error('ET7000 device at %s is offline' % host)
            return
        # read module name
        self._name = self.read_module_name()
        self.type = hex(self._name).replace('0x', '')
        if self._name not in ET7000.devices:
            self.logger.warning(
                'ET7000 device type %s probably not supported' %
                hex(self._name))
        # ai
        self.AI_n = self.read_AI_n()
        self.AI_masks = [False] * self.AI_n
        self.AI_ranges = [0xff] * self.AI_n
        self.AI_raw = [0] * self.AI_n
        self.AI_values = [float('nan')] * self.AI_n
        self.AI_units = [''] * self.AI_n
        self.read_AI_masks()
        self.read_AI_ranges()
        self.AI_convert = [lambda x: x] * self.AI_n
        for n in range(self.AI_n):
            r = self.AI_ranges[n]
            self.AI_units[n] = ET7000.ranges[r]['units']
            self.AI_convert[n] = ET7000.ai_convert_function(r)
        # ao
        self.AO_n = self.read_AO_n()
        self.AO_masks = [True] * self.AO_n
        self.read_AO_masks()
        self.AO_ranges = [0xff] * self.AO_n
        self.AO_raw = [0] * self.AO_n
        self.AO_values = [float('nan')] * self.AO_n
        self.AO_write_values = [float('nan')] * self.AO_n
        self.AO_units = [''] * self.AO_n
        self.AO_write = [0] * self.AO_n
        self.AO_write_raw = [0] * self.AO_n
        self.read_AO_ranges()
        self.AO_convert = [lambda x: x] * self.AI_n
        self.AO_convert_write = [lambda x: 0] * self.AI_n
        for n in range(self.AO_n):
            r = self.AO_ranges[n]
            self.AO_units[n] = ET7000.ranges[r]['units']
            self.AO_convert[n] = ET7000.ai_convert_function(
                r)  # !!! ai_convert for reading
            self.AO_convert_write[n] = ET7000.ao_convert_function(
                r)  # !!! ao_convert for writing
        # di
        self.DI_n = self.read_DI_n()
        self.DI_values = [False] * self.DI_n
        # do
        self.DO_n = self.read_DO_n()
        self.DO_values = [False] * self.DO_n
        self.DO_write = [False] * self.DO_n

    def read_module_name(self):
        regs = self._client.read_holding_registers(559, 1)
        if regs and regs[0] != 0:
            return regs[0]
        regs = self._client.read_holding_registers(260, 1)
        if regs:
            return regs[0]
        return 0

    # AI functions
    def read_AI_n(self):
        regs = self._client.read_input_registers(320, 1)
        if regs and regs[0] != 0:
            return regs[0]
        regs = self._client.read_input_registers(120, 1)
        if regs:
            return regs[0]
        return 0

    def read_AI_masks(self):
        coils = self._client.read_coils(595, self.AI_n)
        if coils and len(coils) == self.AI_n:
            self.AI_masks = coils
        return coils

    def read_AI_ranges(self):
        regs = self._client.read_holding_registers(427, self.AI_n)
        if regs and len(regs) == self.AI_n:
            self.AI_ranges = regs
        return regs

    def read_AI_raw(self, channel=None):
        if channel is None:
            n = self.AI_n
            channel = 0
        else:
            n = 1
        regs = self._client.read_input_registers(0 + channel, n)
        if regs and len(regs) == n:
            self.AI_raw[channel:channel + n] = regs
        if n == 1:
            return regs[0]
        return regs

    def convert_AI(self):
        for k in range(self.AI_n):
            if self.AI_masks[k]:
                self.AI_values[k] = self.AI_convert[k](self.AI_raw[k])
            else:
                self.AI_values[k] = float('nan')
        return self.AI_values

    def read_AI(self, channel=None):
        if channel is None:
            self.read_AI_raw()
            self.convert_AI()
            return self.AI_values
        return self.read_AI_channel(channel)

    def read_AI_channel(self, k: int):
        v = float('nan')
        if self.AI_masks[k]:
            regs = self._client.read_input_registers(0 + k, 1)
            if regs:
                self.AI_raw[k] = regs[0]
                v = self.AI_convert[k](regs[0])
        self.AI_values[k] = v
        return v

    # AO functions
    def read_AO_n(self):
        regs = self._client.read_input_registers(330, 1)
        if regs and regs[0] != 0:
            return regs[0]
        regs = self._client.read_input_registers(130, 1)
        if regs:
            return regs[0]
        return 0

    def read_AO_masks(self):
        return self.AO_masks

    def read_AO_ranges(self):
        regs = self._client.read_holding_registers(459, self.AO_n)
        if regs and len(regs) == self.AO_n:
            self.AO_ranges = regs
        return regs

    def read_AO_raw(self, channel=None):
        if channel is None:
            n = self.AO_n
            channel = 0
        else:
            n = 1
        regs = self._client.read_holding_registers(0 + channel, n)
        if regs and len(regs) == n:
            self.AO_raw[channel:channel + n] = regs
        if n == 1:
            return regs[0]
        return regs

    def write_AO_raw(self, regs):
        result = self._client.write_multiple_registers(0, regs)
        self.AO_write_result = result
        if len(regs) == self.AO_n:
            self.AO_write_raw = regs
        return result

    def convert_AO(self):
        raw = self.AO_raw
        for k in range(self.AO_n):
            self.AO_values[k] = self.AO_convert[k](raw[k])
        return self.AO_values

    def convert_to_raw_AO(self, values=None):
        if values is None:
            values = self.AO_write_values
        answer = []
        for k in range(len(values)):
            answer.append(self.AO_convert_write[k](values[k]))
        return answer

    def read_AO(self):
        self.AO_raw = self.read_AO_raw()
        self.convert_AO()
        return self.AO_values

    def read_AO_channel(self, k: int):
        v = float('nan')
        if self.AO_masks[k]:
            regs = self._client.read_holding_registers(0 + k, 1)
            if regs:
                v = self.AO_convert[k](regs[0])
                self.AO_values[k] = v
        return v

    def write_AO(self, values):
        self.AO_write_values = values
        regs = ET7000.convert_to_raw_AO(values)
        result = self.write_AO_raw(regs)
        return result

    def write_AO_channel(self, k: int, value):
        raw = self.AO_convert_write[k](value)
        result = self._client.write_single_register(0 + k, raw)
        self.AO_write_result = result
        if result:
            self.AO_write_values[k] = value
            self.AO_write_raw[k] = raw
            pass
        return result

    # DI functions
    def read_DI_n(self):
        regs = self._client.read_input_registers(300, 1)
        if regs and regs[0] != 0:
            return regs[0]
        regs = self._client.read_input_registers(100, 1)
        if regs:
            return regs[0]
        return 0

    def read_DI(self):
        regs = self._client.read_discrete_inputs(0, self.DI_n)
        if regs:
            self.DI_values = regs
        return self.DI_values

    def read_DI_channel(self, k: int):
        reg = self._client.read_discrete_inputs(0 + k, 1)
        if reg:
            self.DI_values[k] = reg[0]
            return reg[0]
        return None

    # DO functions
    def read_DO_n(self):
        self.DO_time = time.time()
        regs = self._client.read_input_registers(310, 1)
        if regs and regs[0] != 0:
            return regs[0]
        regs = self._client.read_input_registers(110, 1)
        if regs:
            return regs[0]
        return 0

    def read_DO(self):
        regs = self._client.read_coils(0, self.DI_n)
        if regs:
            self.DI_values = regs
        return self.DI_values

    def read_DO_channel(self, k: int):
        reg = self._client.read_coils(0 + k, 1)
        if reg:
            self.DO_values[k] = reg[0]
            return reg[0]
        return None

    def write_DO(self, values):
        self.DO_write = values
        self.DO_write_result = self._client.write_multiple_coils(0, values)
        return self.DO_write_result

    def write_DO_channel(self, k: int, value: bool):
        result = self._client.write_single_coil(0 + k, value)
        self.DO_write_result = result
        if result:
            self.DO_write[k] = value
        return result
Exemplo n.º 31
0
class HeatPump():
    def __init__(self, ipOrHostName, portNumber, unitId, code):
        self.code = code
        self.registers = HeatPumpRegisters()
        self.mbClient = ModbusClient()
        self.mbClient.host(ipOrHostName)
        self.mbClient.port(portNumber)
        self.mbClient.unit_id(unitId)
        self.mbClient.open()

        self.outsideTemperature = HeatPumpConstants.NAN_VALUE
        self.currentRoomTemperature = HeatPumpConstants.NAN_VALUE
        self.currentExhaustFanSpeed = HeatPumpConstants.NAN_VALUE
        self.currentSupplyFanSpeed = HeatPumpConstants.NAN_VALUE
        self.airingLevelDay = HeatPumpConstants.NAN_VALUE
        self.airingLevelNight = HeatPumpConstants.NAN_VALUE
        self.powerConsumptionHeatingDay = HeatPumpConstants.NAN_VALUE
        self.powerConsumptionWarmWaterDay = HeatPumpConstants.NAN_VALUE

        return

    def setAiringLevelDay(self, airingLevel, code):
        return self._setAiringLevel(self.registers.AIRING_LEVEL_DAY.Address, airingLevel, code)

    def setAiringLevelNight(self, airingLevel, code):
        return self._setAiringLevel(self.registers.AIRING_LEVEL_NIGHT.Address, airingLevel, code)

    def _setAiringLevel(self, registerAddress, airingLevel, code):
        if int(code) != self.code:
            return (False, "Invalid security code")

        if not self.mbClient.is_open() and not self.mbClient.open():
            return (False, "Unable to connect to {}:{}".format(self.mbClient.host(), self.mbClient.port()))

        if type(airingLevel) == str:
            try:
                airingLevel = int(airingLevel)
            except:
                raise TypeError("Could not convert {} to type 'int'".format(airingLevel))

        retVal = self.mbClient.write_single_register(registerAddress, airingLevel)

        if not retVal:
            return (False, "Failed to set airing level")
        else:
            return (True, "Setting airing level successful")

    def readCurrentValues(self):
        if not self.mbClient.is_open() and not self.mbClient.open():
            print ("Unable to connect to {}:{}".format(self.mbClient.host(), self.mbClient.port()))
            return False

        regVal_outsideTemperature = self.mbClient.read_input_registers(self.registers.OUTSIDE_TEMPERATURE.Address, 
                                                                       self.registers.OUTSIDE_TEMPERATURE.SequenceSize)
        regVal_currentRoomTemperature = self.mbClient.read_input_registers(self.registers.CURRENT_ROOM_TEMPERATURE.Address, 
                                                                           self.registers.CURRENT_ROOM_TEMPERATURE.SequenceSize)
        regVal_currentExhaustFanSpeed = self.mbClient.read_input_registers(self.registers.CURRENT_EXHAUST_FAN_SPEED.Address, 
                                                                           self.registers.CURRENT_EXHAUST_FAN_SPEED.SequenceSize)
        regVal_currentSupplyFanSpeed = self.mbClient.read_input_registers(self.registers.CURRENT_SUPPLY_FAN_SPEED.Address, 
                                                                          self.registers.CURRENT_SUPPLY_FAN_SPEED.SequenceSize)
        regVal_airingLevelDay = self.mbClient.read_holding_registers(self.registers.AIRING_LEVEL_DAY.Address, 
                                                                     self.registers.AIRING_LEVEL_DAY.SequenceSize)
        regVal_airingLevelNight = self.mbClient.read_holding_registers(self.registers.AIRING_LEVEL_NIGHT.Address, 
                                                                       self.registers.AIRING_LEVEL_NIGHT.SequenceSize)
        regVal_powerConsumptionHeatingDay = self.mbClient.read_input_registers(self.registers.POWER_CONSUMPTION_HEATING_DAY.Address, 
                                                                               self.registers.POWER_CONSUMPTION_HEATING_DAY.SequenceSize)
        regVal_powerConsumptionWarmWaterDay = self.mbClient.read_input_registers(self.registers.POWER_CONSUMPTION_WARMWATER_DAY.Address, 
                                                                                 self.registers.POWER_CONSUMPTION_WARMWATER_DAY.SequenceSize)

        outsideTemperature = self.registers.shiftValue(regVal_outsideTemperature, 
                                                       self.registers.OUTSIDE_TEMPERATURE.SequenceSize)

        # outsideTemperature can be less than zero
        self.outsideTemperature = self.registers.convertSignedValue(outsideTemperature, HeatPumpConstants.MBREG_BITWIDTH) * 0.1

        self.currentRoomTemperature = self.registers.shiftValue(regVal_currentRoomTemperature, 
                                                                self.registers.CURRENT_ROOM_TEMPERATURE.SequenceSize) * 0.1
        self.currentExhaustFanSpeed = self.registers.shiftValue(regVal_currentExhaustFanSpeed, 
                                                                self.registers.CURRENT_EXHAUST_FAN_SPEED.SequenceSize)
        self.currentSupplyFanSpeed = self.registers.shiftValue(regVal_currentSupplyFanSpeed, 
                                                               self.registers.CURRENT_SUPPLY_FAN_SPEED.SequenceSize)
        self.airingLevelDay = self.registers.shiftValue(regVal_airingLevelDay, 
                                                        self.registers.AIRING_LEVEL_DAY.SequenceSize)
        self.airingLevelNight = self.registers.shiftValue(regVal_airingLevelNight, 
                                                          self.registers.AIRING_LEVEL_NIGHT.SequenceSize)

        self.powerConsumptionHeatingDay = self.registers.shiftValue(regVal_powerConsumptionHeatingDay, 
                                                          self.registers.POWER_CONSUMPTION_HEATING_DAY.SequenceSize)

        self.powerConsumptionWarmWaterDay = self.registers.shiftValue(regVal_powerConsumptionWarmWaterDay, 
                                                          self.registers.POWER_CONSUMPTION_WARMWATER_DAY.SequenceSize)

        return True
import time
from pyModbusTCP.client import ModbusClient

# Equipamentos no chão de fábrica
nivel0 = 0
nivel1 = 0
nivel2 = 0

c = ModbusClient('172.17.115.225', port=502, unit_id=1)

while True:
    if c.is_open():
        c.write_single_register(0, nivel0)
        c.write_single_register(1, nivel1)
        c.write_single_register(2, nivel2)
        print('nivel0: ' + str(nivel0) + '; nivel1: ' + str(nivel1) +
              '; nivel2: ' + str(nivel2))

        nivel0 = nivel0 + 2
        nivel1 = nivel1 + 3
        nivel2 = nivel2 + 5
    else:
        print('opening client...')
        c.open()
        print('client open!')

    time.sleep(1)
Exemplo n.º 33
0
            #contours1, hierarchy1 = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            contours1, hierarchy1 = cv2.findContours(roi, cv2.RETR_EXTERNAL,
                                                     cv2.CHAIN_APPROX_SIMPLE)
            approx_result = cv2.approxPolyDP(contours1[0], 30, True)
            cv2.drawContours(roi, contours1, -1, (0, 255, 0), 3)
            cv2.drawContours(roi, [approx_result], -1, (0, 255, 0), 3)

            length = (len(approx_result))
            print(length)
            result = length
            #print(result)
            if length == 6:
                cv2.putText(frame, "Hexagon", (x, y + 30),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0))
                print('Hexagon')
                rc = c.write_single_register(0x1100, 6)
                rc = c.write_single_register(0x1101, 1)
                #動作
                #print(length)
            elif length == 4:
                cv2.putText(frame, "Rectangle", (x, y + 30),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0))
                print('Rectangle')
                rc = c.write_single_register(0x1100, 4)
                rc = c.write_single_register(0x1101, 1)
                #print(length)

            elif length == 3:
                cv2.putText(frame, "Triangle", (x, y + 30),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0))
                print('Triangle')
def send_heartbeat(ModbusClient):
    # sends MODBUS heart beat
    # c is ModbusClient
    wr = ModbusClient.write_single_register(20, 128)  # modbus heartbeat
Exemplo n.º 35
0
class Storage:
    def __init__(
            self,
            maxpower=3300,
            addr_command=63245,
            addr_time=63243,
            addr_disPower=63248,
            addr_chaPower=63246,
            timeBatt=36000,
            SERVER_HOST="192.168.0.51",
            SERVER_PORT=502,
            PWRNET_API_BASE_URL='http://pwrnet-158117.appspot.com/api/v1/'):
        self.maxPower = maxpower
        self.addr_command = addr_command
        self.addr_time = addr_time
        self.addr_disPower = addr_disPower
        self.addr_chaPower = addr_chaPower
        self.timeBatt = timeBatt  # How long to (dis)charge [s]: uint32
        self.SERVER_HOST = SERVER_HOST
        self.SERVER_PORT = SERVER_PORT
        self.tcpClient = ModbusClient(host=self.SERVER_HOST,
                                      port=self.SERVER_PORT,
                                      unit_id=247,
                                      timeout=2,
                                      auto_open=True)
        self.PWRNET_API_BASE_URL = PWRNET_API_BASE_URL

        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
        self.handler = RotatingFileHandler('my_log.log',
                                           maxBytes=2000,
                                           backupCount=10)
        self.logger.addHandler(self.handler)
        self.logger.info('Storage class called')

    def realtime(self, battVal=0.0, cosPhi=1.0):
        #self.logger.info('StorageRT function called')
        if battVal > 0:
            command_mode = 4  # Discharging (positive values)
        elif battVal < 0:
            command_mode = 3  # Charging (negative values)
        else:
            command_mode = 1

        # Battery power
        battPower = abs(battVal)  # [W]: float32: [-3300W ... 3300W]
        powerFloat = utils.encode_ieee(battPower)  # Converting to ieee float32

        if self.tcpClient.is_open():
            # Setting time
            self.tcpClient.write_multiple_registers(
                self.addr_time,
                [self.timeBatt & 0xffff, (self.timeBatt & 0xffff0000) >> 16])

            # Setting mode
            self.tcpClient.write_single_register(self.addr_command,
                                                 command_mode)

            # Setting power
            if command_mode == 4:
                regs_disPower = self.tcpClient.write_multiple_registers(
                    self.addr_disPower,
                    [powerFloat & 0xffff, (powerFloat & 0xffff0000) >> 16])
                if str(regs_disPower
                       ) != "True":  # Check if write function worked
                    return 0
                else:
                    return float(time.time())

            elif command_mode == 3:
                regs_chaPower = self.tcpClient.write_multiple_registers(
                    self.addr_chaPower,
                    [powerFloat & 0xffff, (powerFloat & 0xffff0000) >> 16])
                if str(regs_chaPower
                       ) != "True":  # Check if write function worked
                    return 0
                else:
                    return float(time.time())

            else:
                return 0

        else:

            self.tcpClient.open()
            return -1

    def urlBased(self, devId, state=None, powerReal=0, cosPhi=1.0):
        #self.logger.info('Storage URL function called')
        if state == None:
            batt = requests.get(url=self.PWRNET_API_BASE_URL + "device/" +
                                devId + "/",
                                timeout=10)
            battStatus = batt.json()["status"]
            power = batt.json()["value"]
            phi = batt.json()["cosphi"]
            print "power: ", power
            print "phi: ", phi
        else:
            battStatus = state

        if (battStatus == "DISCHARGE"):
            command_mode = 4

        elif (battStatus == "CHARGE"):
            command_mode = 3

        else:
            command_mode = 1
        powerFloat = utils.encode_ieee(
            powerReal)  # Converting power to ieee float32
        #powerFloat = utils.encode_ieee(power) # Converting power to ieee float32

        if self.tcpClient.is_open():
            #print 'TCP battery Opened!'
            # Setting time
            self.tcpClient.write_multiple_registers(
                self.addr_time,
                [self.timeBatt & 0xffff, (self.timeBatt & 0xffff0000) >> 16])

            # Setting mode
            self.tcpClient.write_single_register(self.addr_command,
                                                 command_mode)

            # Setting cosphi
            #print "writing cosphi"
            #regs_cosphi = self.writeCosPhi(valCosPhi=phi)
            regs_cosphi = self.writeCosPhi(valCosPhi=cosPhi)
            #print "regs_cosphi: ", regs_cosphi
            if regs_cosphi == False:
                return -1

            # Setting power
            if (command_mode == 4):
                regs_disPower = self.tcpClient.write_multiple_registers(
                    self.addr_disPower,
                    [powerFloat & 0xffff, (powerFloat & 0xffff0000) >> 16])
                if (str(regs_disPower) !=
                        "True"):  # Check if write function worked
                    return 0
                else:
                    return float(time.time())

            elif (command_mode == 3):
                regs_chaPower = self.tcpClient.write_multiple_registers(
                    self.addr_chaPower,
                    [powerFloat & 0xffff, (powerFloat & 0xffff0000) >> 16])
                if (str(regs_chaPower) !=
                        "True"):  # Check if write function worked
                    return 0
                else:
                    return float(time.time())

            else:
                return 0

        else:
            #self.logger.debug('tcpClient is not open')
            self.tcpClient.open()
            #print 'Returning batt...'
            return -1

    def battery_thread(self, q_batt):
        self.logger.info('Battery Thread called')
        print 'BATTERY THREAD...'
        print "battery thread"
        state = "OFF"
        fct = "url"  # Which function to call, url or realtime
        battval = 0
        cosphi = 1.0
        while True:
            if not q_batt.empty():
                print "q_battery empty"
                try:
                    queue_param = q_batt.get(True, 1)
                    state = queue_param[0]  # State: CHARGING, DISCHARGING, OFF
                    fct = queue_param[1]  # Function: url, realtime
                    battval = queue_param[2]
                    cosphi = queue_param[3]
                    q_batt.task_done()
                    print "Queue battery: ", queue_param
                except Exception as exc:
                    self.logger.exception(exc)
                    client.captureException()
            if fct == "url":
                print "url"
                batt = self.urlBased(19, state, battval, cosphi)
                if batt == -1:
                    try:
                        batt = self.urlBased(19, state, battval, cosphi)
                        print "Called tcp"
                    except Exception as exc:
                        self.logger.exception(exc)
                        client.captureException()
            else:
                print "else RT"
                batt = self.realtime(battval)
                if batt == -1:
                    try:
                        batt = self.realtime(battval)
                    except Exception as exc:
                        self.logger.exception(exc)
                        client.captureException()

    def battery_act(self, q_batt):
        self.logger.info('Battery Thread called')
        print 'BATTERY THREAD...'
        print "battery_act"
        state = q_batt[0]
        fct = q_batt[1]  # Which function to call, url or realtime
        battval = q_batt[2]
        cosphi = q_batt[3]
        b_id = q_batt[4]
        print "q_batt: ", q_batt
        if fct == "url":
            batt = self.urlBased(b_id, state, battval, cosphi)
            if batt == -1:
                try:
                    batt = self.urlBased(b_id, state, battval, cosphi)
                    print "SUCCEED"
                except Exception as exc:
                    self.logger.exception(exc)
                    client.captureException()
        else:
            print "RT"
            batt = self.realtime(battval)
            if batt == -1:
                try:
                    batt = self.realtime(battval)
                except Exception as exc:
                    self.logger.exception(exc)
                    client.captureException()

    def readSOE(self, ):
        self.logger.info('readSOE called')
        addr = 62852  # Modbus address of SOE

        if self.tcpClient.is_open():
            try:
                resp = self.tcpClient.read_holding_registers(
                    addr, 2)  # Reading 2 registers, int16
                Lh = hex(resp[0])
                Mh = hex(resp[1])
                Sh = Mh[2:] + Lh[2:]
                val = struct.unpack('f', struct.pack('i', int(
                    Sh, 16)))  # Converting from hex to float
                return val[0]

            except Exception as exc:
                self.logger.exception(exc)
                client.captureException()
        else:
            self.tcpClient.open()
            return -1

    def readDC(self, ):
        self.logger.info('readSOE called')
        addrI = 62834  # Modbus address of I_DC
        addrV = 62832  # Modbus address of V_DC
        addrSOE = 62852  # Modbus address of SOE
        addr = [addrI, addrV, addrSOE]
        vals_dc = []
        self.realtime(-1500)
        for i in addr:
            if self.tcpClient.is_open():
                print "TCP client open"
                try:
                    resp = self.tcpClient.read_holding_registers(
                        i, 2)  # Reading 2 registers, int16
                    Lh = hex(resp[0])
                    Mh = hex(resp[1])
                    Sh = Mh[2:] + Lh[2:]
                    print 'Sh: ', Sh
                    val = val = struct.unpack(
                        '!f', Sh.decode('hex'))  # Converting from hex to float
                    vals_dc.append(val[0])

                except Exception as exc:
                    print 'error in: ', i
                    self.logger.exception(exc)
                    client.captureException()
            else:
                self.tcpClient.open()
                return -1
        vals_dc.append(datetime.now())
        return vals_dc

    def readCosPhi(self):
        self.logger.info('readCosPhi called')
        addr = 61706  # Modbus address of FixedCosPhi

        if self.tcpClient.is_open():
            try:
                resp = self.tcpClient.read_holding_registers(
                    addr, 2)  # Reading 2 registers, int16
                Lh = hex(resp[0])
                Mh = hex(resp[1])
                if Lh[2:] == '0':
                    Sh = Mh[2:] + '0000'
                else:
                    Sh = Mh[2:] + Lh[2:]
                val = struct.unpack(
                    '!f', Sh.decode('hex'))  # Converting from hex to float
                return val[0]

            except Exception as exc:
                self.logger.exception(exc)
                client.captureException()
                return -9
        else:
            self.tcpClient.open()
            return -9  # cannot be -1 as cosPhi can be thos number

    def writeCosPhi(self, valCosPhi=1.0, test=False):
        #self.logger.info('writeCosPhi called')
        addr = 61706  # Modbus address of FixedCosPhi
        if test:  # Check to see if this function is going to be used for testing or just writing to register
            if self.tcpClient.is_open():
                try:
                    data_conv = utils.encode_ieee(valCosPhi)
                    regs_data = self.tcpClient.write_multiple_registers(
                        addr,
                        [data_conv & 0xffff, (data_conv & 0xffff0000) >> 16])
                    return str(regs_data)
                except Exception as exc:
                    self.logger.exception(exc)
                    client.captureException()
                    return False
            else:
                self.tcpClient.open()
                return False
        else:
            try:
                data_conv = utils.encode_ieee(valCosPhi)
                regs_data = self.tcpClient.write_multiple_registers(
                    addr, [data_conv & 0xffff, (data_conv & 0xffff0000) >> 16])
                return str(regs_data)
            except Exception as exc:
                self.logger.exception(exc)
                client.captureException()
                return False
Exemplo n.º 36
0
import sys
from math import *
from multiprocessing import *
from mpu6050_process_1 import MPU6050_Process_1
from mpu6050_process_2 import MPU6050_Process_2
from pyModbusTCP.client import ModbusClient

with Manager() as manager:

    # Open a modbus client
    try:
        c = ModbusClient(host="140.116.82.50", port=7654)
    except ValueError:
        print("Error with host or port params")
    c.open()
    is_ok = c.write_single_register(0, 1)
    if not is_ok:
        print("open error")
        c.open()

    def exit_handler():
        is_ok = c.write_multiple_registers(0, [0, 0, 0, 0, 0])
        c.close()

    # registing exit handler
    atexit.register(exit_handler)

    # data sampling period
    interval = 120
    sleep_time = 1 / interval
    i = 0
Exemplo n.º 37
0
class ClientGUI:
    def __init__(self):
        self.lock = RLock()
        self.calibgui = None
        self.client = ModbusClient()
        self.register_values_widgets = {}
        self.counter = 1
        self.find_thread = None
        self.obj_data = None
        self.stop_signal = False
        self.__build_ui()

    def run_ui(self):
        self.root.mainloop()

    def __build_ui(self):
        # ui hierarchy:
        #
        #root
        #   connectframe
        #       connectlabel
        #       connectbutton
        #       snapshotbutton
        #       calibbuton
        #   mainframe
        #       registerframe
        #           reglabel
        #           registergridframe
        #               ...
        #       outputframe
        #           outputlabel
        #           outputtext

        root = Tk()
        self.root = root
        root.wm_title("RemoteSurf Modbus Client")
        root.protocol("WM_DELETE_WINDOW", self.__delete_window)

        self.font = tkFont.Font(root = root, family = "Helvetica", size = 12)

        connectframe = Frame(root)
        connectbutton = Button(connectframe, text = "Connect", command = self.__connectbutton_click)
        connectlabel = Label(connectframe, text = "Not connected.")
        calibbutton = Button(connectframe, text = "Calibrate", command = self.__calibbutton_click)
        homebutton = Button(connectframe, text = "Home", command = self.__homebutton_click)
        findbutton = Button(connectframe, text = "Find", command = self.__findbutton_click)
        mainframe = Frame(root)
        registerframe = Frame(mainframe)
        reglabel = Label(registerframe, text = "Set registers")
        registergridframe = Frame(registerframe)
        # outputframe = Frame(mainframe)
        # outputlabel = Label(outputframe, text = "Output")
        # vscrollbar = Scrollbar(outputframe)
        # hscrollbar = Scrollbar(outputframe)
        # outputtext = ThreadSafeConsole(outputframe, root, vscrollbar, font = self.font, wrap = NONE)

        connectframe.pack(side = TOP, fill = X)
        connectlabel.pack(side = BOTTOM, anchor = W)
        homebutton.pack(side = RIGHT)
        findbutton.pack(side = RIGHT)
        calibbutton.pack(side = RIGHT)
        connectbutton.pack(side = RIGHT)
        mainframe.pack(side = BOTTOM, fill = BOTH, expand = YES)
        registerframe.pack(side = TOP, expand = YES, anchor = W)
        # outputframe.pack(side = BOTTOM, fill = BOTH, expand = YES)
        reglabel.pack(side = TOP, anchor = CENTER)
        registergridframe.pack(side = BOTTOM, anchor = W)
        # registerframe.config(bg = "cyan")
        # mainframe.config(bg = "pink")
        # registergridframe.config(bg = "red")

        registergridframe.columnconfigure(0, weight = 1)
        registergridframe.columnconfigure(1, weight = 1)
        registergridframe.columnconfigure(2, weight = 1)
        registergridframe.columnconfigure(3, weight = 1)

        self.x_pad = 10
        registergrid_widgets = []
        titles = ["Address", "Label", "Value", ""]
        col = 0
        for title in titles:
            title_label = Label(registergridframe, text = title)
            title_label.grid(row = 0, column = col, padx = self.x_pad)
            registergrid_widgets.append(title_label)
            col += 1

        registers_data = [(500, "x"),
                     (501, "y"),
                     (502, "z"),
                     (503, "A"),
                     (504, "B"),
                     (505, "C"),
                     ]

        for i in range(len(registers_data)):
            reg_data = registers_data[i]
            row = i + 1
            self.__add_register(registergridframe, reg_data, row, registergrid_widgets)

        # hscrollbar.config(orient = HORIZONTAL, command = outputtext.xview)
        # hscrollbar.pack(side = BOTTOM, fill = X)
        # outputtext.config(state = DISABLED, yscrollcommand = vscrollbar.set, xscrollcommand = hscrollbar.set)  #must change to NORMAL before writing text programmatically
        # outputtext.pack(side = LEFT, fill = BOTH, expand = YES, padx = x_padding, pady = y_padding)
        # vscrollbar.config(command = outputtext.yview)
        # vscrollbar.pack(side = RIGHT, fill = Y)

        self.connectframe = connectframe
        self.connectlabel = connectlabel
        self.connectbutton = connectbutton
        self.mainframe = mainframe
        self.registerframe = registerframe
        self.reglabel = reglabel
        self.registergridframe = registergridframe
        self.calibbutton = calibbutton
        # self.outputframe = outputframe
        # self.outputlabel = outputlabel
        # self.vscrollbar = vscrollbar
        # self.hscrollbar = hscrollbar
        # self.outputtext = outputtext

        root.update()
        w, h = root.winfo_width(), root.winfo_height()
        root.minsize(w, h)
        x, y = MAINFRAME_POS
        root.geometry('%dx%d+%d+%d' % (w, h, x, y))

    def __homebutton_click(self):
        values = {
            500: 300,
            501: 0,
            502: 500,
            503: 180,
            504: 0,
            505: 180,
        }
        self.set_values(values, go_to_value = False)

    def __add_register(self, master, data, row, widget_list):
        regaddresslabel = Label(master, text=str(data[0]))
        regaddresslabel.grid(row=row, column=0)
        reglabellabel = Label(master, text=data[1])
        reglabellabel.grid(row=row, column=1)
        regvalueentry = AccessibleEntry(master, justify = RIGHT)
        regvalueentry.set("0")
        regvalueentry.grid(row=row, column=2, padx=self.x_pad)
        regsetbtn = Button(master, text="Set", command = self.__setbutton_click)
        regsetbtn.grid(row=row, column=3)
        widget_list.append(regaddresslabel)
        widget_list.append(reglabellabel)
        widget_list.append(regvalueentry)
        widget_list.append(regsetbtn)
        self.register_values_widgets[data[0]] = (0, regvalueentry)

    def __calibbutton_click(self):
        if not self.calibgui:
            self.calibgui = CalibGUI(self)

    def __findbutton_click(self):
        if self.find_thread is None:
            self.find_thread = Thread(target=self.__find_object)
            self.find_thread.start()

    def __find_object(self):
        import DataCache as DC
        from glob import glob
        from os.path import join
        import numpy as np
        from SFMSolver import SFMSolver, find_ext_params
        import Utils

        print "FINDING"

        np.set_printoptions(precision=3, suppress=True)

        files_dir = "out/2017_3_8__14_51_22/"
        files = glob(join(files_dir, "*.jpg"))
        masks = []
        for f in files:
            m = f.replace(".jpg", "_mask.png")
            masks.append(m)
        sfm = SFMSolver(files, masks)
        if self.obj_data is None:
            imgs, kpts, points, data = sfm.calc_data_from_files_triang_simple()
            self.obj_data = imgs, kpts, points, data
        else:
            imgs, kpts, points, data = self.obj_data

        arr_calib = DC.getData("out/%s/arrangement_calib.p" % ARRANGEMENT_CALIB_DIR)
        ttc = arr_calib["ttc"]
        tor = arr_calib["tor"]
        if "cam_mtx" in arr_calib:
            print "camMtx, distcoeffs load"
            Utils.camMtx = arr_calib["cam_mtx"]
            Utils.dist_coeffs = arr_calib["dist_coeffs"]

        if self.stop_signal:
            self.stop_signal = False
            return

        for point in FIND_POINTS:
            values = {
                500: point[0],
                501: point[1],
                502: point[2],
                503: point[3],
                504: point[4],
                505: point[5],
            }
            print "set_values call"
            self.set_values(values, True)
            print "set_values return"

            time.sleep(0.5)
            CamGrabber.capture_if_no_chessboard = True
            CamGrabber.capture = True
            time.sleep(0.5)

            if self.stop_signal:
                self.stop_signal = False
                return

        find_dir = logger.outputdir
        files = glob("%s/*.jpg" % find_dir)
        print files
        # files_dir = "out/2017_4_5__15_57_20/"
        # files = glob(join(files_dir, "*.jpg"))
        files.sort()
        files = files[-len(FIND_POINTS):]
        results = []

        for f in files:
            res = find_ext_params(f, imgs, kpts, points, data, tor, ttc)
            results.append(res)
            if self.stop_signal:
                self.stop_signal = False
                return

        for i in range(len(results)):
            print i, results[i]
            write_log((i, results[i]))
        result = max(results, key=lambda x: x[2])
        write_log(result)


        values = {
            500: int(result[0][0] * 10),
            501: int(result[0][1] * 10),
            502: int(result[0][2] * 10) + 200,
            503: int(result[1][2]),
            504: int(result[1][1]),
            505: int(result[1][0]),
        }

        print "num inl: ", result[2]
        pprint(values)
        self.set_values(values, go_to_value=False)
        self.find_thread = None

    def __connectbutton_click(self):
        if self.client.is_open():
            self.client.close()
        else:
            self.client.host(SERVER_HOST)
            self.client.port(SERVER_PORT)
            if self.client.open():
                write_log("Connection established")
                self.refresh_values()
                self.read_robot_pos()
            else:
                write_log("ERROR: Connecting failed")
        self.__update_gui()

    def read_robot_pos(self):
        write_log("Reading robot position:")
        posdict = {}
        for i in range(1000, 1006):
            if self.client.is_open():
                with self.lock:
                    real_val_uint = self.client.read_input_registers(i)[0]
                    real_val_holding_uint = self.client.read_holding_registers(i)[0]
                assert real_val_uint == real_val_holding_uint
                real_val_int = uintToInt16(real_val_uint)
                posdict[i] = real_val_int
                write_log("%d, %d" % (i, real_val_int))
            else:
                write_log("ERROR: Read could not be completed, client not connected.")
                self.__update_gui()
                break
        write_log("Read done.")
        return posdict

    def refresh_values(self):
        for address in self.register_values_widgets:
            if self.client.is_open():
                value, widget = self.register_values_widgets[address]
                with self.lock:
                    real_val_uint = self.client.read_input_registers(address)[0]
                    real_val_holding_uint = self.client.read_holding_registers(address)[0]
                assert real_val_uint == real_val_holding_uint
                real_val_int = uintToInt16(real_val_uint)
                widget.set(str(real_val_int))
                self.register_values_widgets[address] = (real_val_int, widget)
            else:
                write_log("ERROR: Read could not be completed, client not connected.")
                self.__update_gui()
                break
        write_log("Refresh done.")
        return self.register_values_widgets

    def __update_gui(self):
        if self.client.is_open():
            self.connectlabel.config(text = "Connected to: %s:%d" % (SERVER_HOST, SERVER_PORT))
            self.connectbutton.config(text = "Disconnect")
        else:
            self.connectbutton.config(text = "Connect")
            self.connectlabel.config(text = "Not connected.")
        self.root.update()

    def __print_memory(self):
        self.refresh_values()
        write_log("Memory dump:")
        write_log("------------")
        for address in self.register_values_widgets:
            val, widget = self.register_values_widgets[address]
            write_log("%d, %d" % (address, val))
        write_log("------------")

    def __setbutton_click(self, wait = False):
        if not self.client.is_open():
            write_log("ERROR: Not connected to client")
            return

        # writing message counter
        retval = self.__write_register(COUNTER_REGISTER_OUT, self.counter)
        if not retval:
            self.__update_gui()
            return

        # writing registers
        for address in self.register_values_widgets:
            value, widget = self.register_values_widgets[address]
            widgetvalue_int = None
            try:
                widgetvalue_int = int(widget.get())
            except ValueError:
                write_log("ERROR: Wrong input format in value entry for address: %d" % address)
                continue

            if value == widgetvalue_int:
                continue

            retval = self.__write_register(address, widgetvalue_int)
            if retval:
                self.register_values_widgets[address] = (widgetvalue_int, widget)
            else:
                self.__update_gui()
        self.refresh_values()

        # message counter wait
        if wait:
            global break_wait
            while not break_wait:
                with self.lock:
                    counter = self.client.read_input_registers(COUNTER_REGISTER_IN)[0]
                if counter == self.counter:
                    break
                time.sleep(0.1)
            break_wait = False

        # counter increment
        self.counter = (self.counter + 1) % 20

        if PRINT_ALL_MEMORY_ON_WRITE:
            self.__print_memory()
            self.read_robot_pos()

    def __write_register(self, address, value):
        if not (-32768 <= value <= 32767):
            write_log("ERROR: -32768 <= value <= 32767 is false for address: %d" % address)
            return False

        widgetvalue_uint = intToUint16(value)
        if self.client.is_open():
            with self.lock:
                retval = self.client.write_single_register(address, widgetvalue_uint)
            if retval:
                write_log("Register written. Address: %d, value: %d" % (address, value))
                return True
            else:
                write_log("ERROR: Write failed. Address: %d, value: %d" % (address, value))
        else:
            write_log("ERROR: client not connected.")
        return False

    def set_values(self, values, wait = True, go_to_value = True):
        """
        :param values: dictionary of { address : value} both int
        :return:
        """
        for address in values:
            if address not in self.register_values_widgets:
                continue

            val, widget = self.register_values_widgets[address]
            widget.set(str(values[address]))
        if go_to_value:
            self.__setbutton_click(wait)

    def __delete_window(self):
        CamGrabber.exit = True
        self.stop_signal = True
        self.client.close()
        self.root.quit()