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
class Modbus:
    def __init__(self, host, port, unit):
        self.client = ModbusClient(host, port, unit, timeout=3)

    def __enter__(self):
        self.client.open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.client.close()

    def toFloat(self, ushorts):
        bs = struct.pack('H', ushorts[0]) + struct.pack('H', ushorts[1])
        return struct.unpack('f', bs)

    def openConnect(self):
        try:
            if not self.isOpen:
                self.client.open()
        except:
            self.closeConnect()

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

    @property
    def isOpen(self):
        return self.client.is_open()

    def getValue(self, addr):
        return self.toFloat(self.client.read_holding_registers(addr, 2))[0]

    def getValues(self, tags):
        return [(tag, self.getValue(tag)) for tag in tags]
Exemplo n.º 3
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)
def modbus_com(SERVER_HOST, SERVER_PORT, function_code, start_register,
               amount_of_registers):
    c = ModbusClient()
    c.host(SERVER_HOST)
    c.port(SERVER_PORT)
    cnt = 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, read register (modbus function 0x03)
        if c.is_open():
            if function_code == "3":
                # Read the amount_of_registers from start_register
                regs = c.read_holding_registers(int(start_register),
                                                int(amount_of_registers))
                # if success display registers
                if regs:
                    print("reg address" + str(start_register) + "to" + str(
                        int(start_register) + int(amount_of_registers) - 1) +
                          ":" + str(regs))
            elif function_code == "16":
                #Future support
                pass

        cnt += 1
        if cnt >= 2:
            print("クライアント通信終了")
            c.close()
            break
        # sleep 1s before next polling
        time.sleep(1)
Exemplo n.º 5
0
class com(object):
    """This class implements the modbusTCP connection functions """
    def __init__(self):
        ''' Constructor for this class. '''
        self._port = 0


    def __del__(self):
        ''' Destructor for this class. '''
        if self._port !=0:
            self.close()




    def open (self,SERVER_HOST = "192.168.0.210",SERVER_PORT = 502,SERVER_UNIT = 201):
        """Open modbus connection to the ComBox

        Args:
            SERVER_HOST: network address of the ComBox. Default='192.168.0.210'
            SERVER_PORT: modbus TCP port. Default='502'
            SERVER_UNIT: modbus address of the ComBox. Default='201'

        Returns: Boolean value True or False

        """
        self._port = ModbusClient(SERVER_HOST, SERVER_PORT, SERVER_UNIT)
        if not self._port.is_open():
            if not self._port.open():
                print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT))

        return self._port.is_open()

    def close(self):
        """Closes the modbusTCP connection

        Returns: Boolean value True or False

        """
        self._port.close()
        return not self._port.is_open()

    def is_connected(self):
        """This function checks if the connection to the Schneider Conext ComBox is established
        and if it responds to readout commands. It requests the firmware version of the ComBox
        and checks for an received bitstream.

        Returns: Boolean value True or False

        return
        """
        bitstream = self._port.read_holding_registers(0x001E, 7)  # 0x001E Firmware Version str20 r
        if bitstream:
            return True
        else:
            return False
Exemplo n.º 6
0
def make_summary():
    SERVER_HOST = "192.168.43.239"
    SERVER_PORT = 502
    SERVER_UNIT_ID = 2

    c = ModbusClient()
    c.host(SERVER_HOST)
    c.port(SERVER_PORT)
    c.unit_id(SERVER_UNIT_ID)
    if not c.is_open():
            if not c.open():
                print("cannot connect ....")

    if c.is_open():
    # read 54 registers at address 0, store result in regs list
            regs = c.read_input_registers(0,54)
    # if success change register value to float
            if regs:
                abc = [utils.decode_ieee(f) for f in utils.word_list_to_long(regs)]
                data = {
                "Power KWH" : "%0.3f"%abc[0],
                "Power KVAH" : "%0.3f"%abc[1],
                "Power KVArP" : "%0.3f"%abc[2],
                "Power KVArN" : "%0.3f"%abc[3],
                "Line Voltages V RY" : "%0.3f"%abc[4],
                "Line Voltages V YB" : "%0.3f"%abc[5],
                "Line Voltages V BR" : "%0.3f"%abc[6],
                "Line Current IR" : "%0.3f"%abc[7],
                "Line Current IY" : "%0.3f"%abc[8],
                "Line Current IB" : "%0.3f"%abc[9],
                "Active Power Consumed" : "%0.3f"%abc[10],
                "Reactive Power Consumed" : "%0.3f"%abc[11],
                "Apparent Power Consumed" : "%0.3f"%abc[12],
                "Phase Voltages VRN" : "%0.3f"%abc[13],
                "Phase Voltages VYN" : "%0.3f"%abc[14],
                "Phase Voltages VBN" : "%0.3f"%abc[15],
                "Power Factor" : "%0.3f"%abc[16],
                "Frequency" : "%0.3f"%abc[17],
                "Real Power on R" : "%0.3f"%abc[18],
                "Real Power on Y" : "%0.3f"%abc[19],
                "Real Power on B" : "%0.3f"%abc[20],
                "Reactive Power on R" : "%0.3f"%abc[21],
                "Reactive Power on Y" : "%0.3f"%abc[22],
                "Reactive Power on B" : "%0.3f"%abc[23],
                "Apparent Power on R" : "%0.3f"%abc[24],
                "Apparent Power on Y" : "%0.3f"%abc[25],
                "Apparent Power on B" : "%0.3f"%abc[26] 
                }
                mydate = datetime.datetime.now()
                date=datetime.datetime.strftime(mydate,'%Y/%m/%d--%H:%M:%S')
                abc.insert(27,date)
                myfile = open('data.csv','a')
                with myfile:
                    writer = csv.writer(myfile, delimiter=',', quoting=csv.QUOTE_ALL)
                    writer.writerow(abc)
                return data
Exemplo n.º 7
0
def save_data(self, name_x):
    SERVER_HOST = name_x
    SERVER_PORT = 502
    c = ModbusClient()
    c.host(SERVER_HOST)
    c.port(SERVER_PORT)

    if not c.is_open():
        if not c.open():
            toast("failed")
    if c.is_open():
        toast("connected")
Exemplo n.º 8
0
def tcp_function_escrita(Porta, Endereco, BaudRate, Registrador, Valor):
    TCPIP_MODBUS = ModbusClient()
    TCPIP_MODBUS.host(Endereco)
    TCPIP_MODBUS.port(Porta)

    if not TCPIP_MODBUS.is_open():
        if not TCPIP_MODBUS.open():
            print('Cannot connect to the Modbus TCP/IP Server/Slave')

    if TCPIP_MODBUS.is_open():

        TCPIP_DATA = TCPIP_MODBUS.write_single_register(Registrador, Valor)
        if TCPIP_DATA:
            print('TCP/IP successfully Write')
        else:
            print('Write Errors in TCP/IP Server/Slave')
Exemplo n.º 9
0
def callback(msg):
    global DATA_TO_HOLDING, DATA_FROM_HOLDING, DATA_FROM_COIL, DATA_TO_COIL
    global start_addr, test_signal_coil, test_signal_holding
    global addr_num
    vx = msg.linear.x * 1000
    vy = msg.linear.y * 1000
    vz = msg.linear.z * 1000
    rx = msg.angular.x * 1000
    ry = msg.angular.y * 1000
    rz = msg.angular.z * 1000
    DATA_TO_HOLDING = [vx, vy, vz, rx, ry, rz]
    c = ModbusClient(host=MODBUS_SPEC['SERVER_HOST'],
                     port=MODBUS_SPEC['SERVER_PORT'])
    ## polling loop
    # keep TCP open
    if not c.is_open():
        c.open()
    #print('DATA_TO_HOLDING = %s' % (DATA_TO_HOLDING))
    if DATA_TO_HOLDING is not None and len(DATA_TO_HOLDING) is not 0:
        if c.write_multiple_registers(MDS_ADDR_W['addr_start_holding_W'],
                                      DATA_TO_HOLDING):
            print('write holding ok from addr %s with list %s' %
                  (MDS_ADDR_W['addr_start_holding_W'], DATA_TO_HOLDING))
        else:
            print('write holding error from addr %s with list %s' %
                  (MDS_ADDR_W['addr_start_holding_W'], DATA_TO_HOLDING))
    else:
        print('holding data missing with %s with desired len %s' %
              (DATA_TO_HOLDING, MDS_ADDR_W['addr_num_holding_W']))
    time.sleep(0.1)
Exemplo n.º 10
0
def readValueIP(address, port, addr, reg):
    c = ModbusIPClient()
    c.host(address)
    c.port(int(port))
    value = -1
    if not c.is_open():
        if not c.open():
            print("Unable to connect to "+address+":"+str(port))
    if c.is_open():
        try:
            value = c.read_holding_registers(int(addr), int(reg))
        except Exception as e:
            raise e
        finally:
            c.close()
    return value[0]
Exemplo n.º 11
0
def tcp_function(Porta, Endereco, BaudRate, Registrador, Linhas):
    TCPIP_MODBUS = ModbusClient()
    TCPIP_MODBUS.host(Endereco)
    TCPIP_MODBUS.port(Porta)

    if not TCPIP_MODBUS.is_open():
        if not TCPIP_MODBUS.open():
            print('Cannot connect to the Modbus TCP/IP Server/Slave')

    if TCPIP_MODBUS.is_open():

        TCPIP_DATA = TCPIP_MODBUS.read_input_registers(Registrador, Linhas)
        if TCPIP_DATA:
            print('TCP/IP successfully read')
        else:
            print('Read Errors in TCP/IP Server/Slave')
    return TCPIP_DATA
Exemplo n.º 12
0
def connect(host, port):
    """Connects to the defined HOST AND PORT. returns the client"""
    c = ModbusClient()
    c.host(host)
    c.port(port)
    if not c.is_open():
        if not c.open():
            raise Exception()
    return c
Exemplo n.º 13
0
def reader(worker, job):
    c = ModbusClient(host="localhost", port=502)

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

    if c.is_open():

        holdingRegisters = c.read_holding_registers(1, 4)

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

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

        out = {"energy": energy, "power": power}
        return json.dumps(out)
    return None
Exemplo n.º 14
0
def readPDTemp(num):
    c = ModbusClient(host='192.168.0.4',
                     port=502,
                     unit_id=4,
                     auto_open=True,
                     auto_close=True)
    if c.is_open():
        registerPD = None
        registerTemp = None
    else:
        c.open()
        registerPD = None
        registerTemp = None
    if num == 4:
        registerPD = c.read_holding_registers(reg_addr=450, reg_nb=1)
        registerTemp = c.read_holding_registers(reg_addr=418, reg_nb=3)

    elif num == 5:
        registerPD = c.read_holding_registers(reg_addr=451, reg_nb=1)
        registerTemp = c.read_holding_registers(reg_addr=421, reg_nb=3)

    elif num == 6:
        registerPD = c.read_holding_registers(reg_addr=452, reg_nb=1)
        registerTemp = c.read_holding_registers(reg_addr=424, reg_nb=3)
    else:
        print("system error!")
    param = num, round(time.time()), registerTemp[0] / 10, registerTemp[
        1] / 10, registerTemp[2] / 10, registerPD[0]
    if registerPD:
        if registerTemp:
            try:
                with conn.cursor() as cursor:
                    cursor.execute(qry, param)
                    conn.commit()
            except TypeError:
                print('connection error with Db. Check it.')
                pass
        else:
            print("reboot CAM-4 to get temperature")
    else:
        print("reboot CAM-4 to get PD")
    c.close()

    result = {
        'i': param[0],
        'time': param[1],
        'Temp_R': param[2],
        'Temp_S': param[3],
        'Temp_T': param[4],
        'PD': param[5]
    }
    return result
Exemplo n.º 15
0
def checkConnection(host): # A simple function to check if the Modbus connection is open
                           #...using the pyModbus.ModbusClient.is_open() method.
    client = ModbusClient()
    client.host(host)
    client.open()
    
    if client.is_open():
        status = True
    else:
        status = False
        
    client.close()
    
    return status
Exemplo n.º 16
0
    def polling_thread(self):

        c = ModbusClient(host=self.SERVER_HOST, port=self.SERVER_PORT)
        # polling loop
        while True:

            # keep TCP open
            if not c.is_open():
                if not c.open():

                    print("unable to connect to " + self.SERVER_HOST + ":" +
                          str(self.SERVER_PORT))

            # do modbus reading on socket
            if c.is_open():
                print("connection")
                reg_list = c.read_holding_registers(0, 10)
                # if read is ok, store result in regs (with thread lock synchronization)
                if reg_list:
                    with self.regs_lock:
                        self.regs = list(reg_list)
                    # 1s before next polling
                time.sleep(1)
Exemplo n.º 17
0
def polling_thread():
    global regs
    c = ModbusClient(host=SERVER_HOST, port=SERVER_PORT)
    # polling loop
    while True:
        # keep TCP open
        if not c.is_open():
            c.open()
        # do modbus reading on socket
        reg_list = c.read_holding_registers(0, 10)
        # if read is ok, store result in regs (with thread lock synchronization)
        if reg_list:
            with regs_lock:
                regs = list(reg_list)
        # 1s before next polling
        time.sleep(1)
def polling_thread():
    global regs
    c = ModbusClient(host=SERVER_HOST, port=SERVER_PORT)
    # polling loop
    while True:
        # keep TCP open
        if not c.is_open():
            c.open()
        # do modbus reading on socket
        reg_list = c.read_holding_registers(0, 10)
        # if read is ok, store result in regs (with thread lock synchronization)
        if reg_list:
            with regs_lock:
                regs = list(reg_list)
        # 1s before next polling
        time.sleep(1)
Exemplo n.º 19
0
class Alicat(Adapter):
    """Alicat device (e.g. pressure controller) with a Modbus/TCP interface"""
    def __init__(self, ip_address):
        super(Alicat, self).__init__(ip_address)
        self.mb_client = ModbusClient(host=ip_address, timeout=5)

    def start(self):
        while True:
            self.mb_client.open()
            if self.mb_client.is_open():
                break

            print 'Unable to connect to Alicat device at {}; retrying...'.format(
                self.ip_address)
            sleep(1)

    def stop(self):
        self.mb_client.close()

    def read_all(self):
        if self.a_ins:
            data = self.mb_client.read_input_registers(
                self.a_in_range[0],
                self.a_in_range[1] - self.a_in_range[0] + 1)
            if not data:
                raise ConnectionError

            i0 = self.a_in_range[
                0]  # Starting index for looking up values from the data list
            for d in self.a_ins.values():
                if d.length == 2:
                    d.val = data[d.address - i0:d.address - i0 + 2]
                elif d.length == 1:
                    d.val = data[d.address - i0]

    def write_all(self):
        # print 'Write outputs'
        if self.a_outs:
            data = []
            for d in self.a_outs.values():
                if d.length == 2:
                    data += d.raw_array
                elif d.length == 1:
                    data.append(d.raw_array)

            self.mb_client.write_multiple_registers(self.a_out_range[0], data)
Exemplo n.º 20
0
def polling_thread():
    global regs, poll_cycle
    c = ModbusClient(host=args.host, port=args.port, unit_id=args.unit_id)
    # polling loop
    while True:
        # keep TCP open
        if not c.is_open():
            c.open()
        # do modbus reading on socket
        reg_list = c.read_holding_registers(20610,20)
        # if read is ok, store result in regs (with thread lock synchronization)
        with regs_lock:
            if reg_list:
                regs = list(reg_list)
                poll_cycle += 1
            else:
                poll_cycle = 0
        # 1s before next polling
        time.sleep(0.2)
Exemplo n.º 21
0
    def check_connection(self, *args):
        global c
        c = ModbusClient(host=ip_,
                         port=int(port_),
                         timeout=0.1,
                         auto_open=True)
        """There is the bug here, as if it is false (c.is_open() = False)
        it doesnt show an update on the GUI

        debug: The c object above is constant"""

        if not c.is_open():
            if not c.open():
                self.connection_status = "Disconnected"
                # print("Unable to connect to " + ip_ + ":" + str(port_))
            else:
                self.connection_status = "Connected"

        return self.connection_status
Exemplo n.º 22
0
def polling_thread():
    global regs, client
    client = ModbusClient(host=SERVER_HOST, port=SERVER_PORT)
    isOpen = False
    # polling loop
    while True:
        # keep TCP open
        if not client.is_open():
            print("unable to connect to " + SERVER_HOST + ":" +
                  str(SERVER_PORT))
            client = ModbusClient(host=SERVER_HOST, port=SERVER_PORT)
            client.open()

        # do modbus reading on socket
        reg_list = client.read_holding_registers(0, 10)
        # if read is ok, store result in regs (with thread lock synchronization)
        if reg_list:
            with threadlock:
                regs = list(reg_list)
        # 1s before next polling
        time.sleep(1)
Exemplo n.º 23
0
def send_data():
        SERVER_HOST = "169.254.0.12"
        SERVER_PORT = 502        #this has to be 502 for tcp/ip modbus
        SERVER_UNIT_ID = 100     #slave id is 100 for schneider powerlogic ion 7650

#default value for ionmeter
#subnet mask= 255.240.0.0
#gateway= 0.0.0.0

#Required Registers to be read :-
#Va= 40166  2 registers  ie. c.read_input_registers(40166,2)
#power kw a = 40198  2 registers
#kVAR a= 40208 2 registers
#kVA a= 40218 2 registers
#frequency = 40159  1 register 
#Ia= 40150 1 register

#this function reads the float value for address and number of bits (not required)
#def read_float( address, number=1):
#   reg_l = c.read_holding_registers(address, number ) #can change to read_input_registers just to check
#   if reg_l:
#       return [utils.decode_ieee(f) for f in utils.word_list_to_long(reg_l)]
#   else:
#       return None

        c = ModbusClient()
        c.host(SERVER_HOST)
        c.port(SERVER_PORT)
        c.unit_id(SERVER_UNIT_ID) #default slave id for schneider is 100

        if not c.is_open():
    	       if not c.open():
        	            print("cannot connect ....")

        if c.is_open():
        #read_holding_registers has an offset of 4000 to begin with
    	       while True:
                        voltage_a=c.read_holding_registers(166,1)#list output for integer take voltage_a[0]
        		#voltage_a=voltage_a[0]
                #print voltage_a
                        current_a=c.read_holding_registers(150,1)
        		#current_a=current_a[0]
                #print current_a
                        real_power_a=c.read_holding_registers(208,1)
        		#real_power_a=real_power_a[0]
                #print real_power_a
                        reactive_power_a=c.read_holding_registers(218,1)
        		#reactive_power_a=reactive_power_a[0]
                #print reactive_power_a
                        apparent_power_a=c.read_holding_registers(218,1)
        		#apparent_power_a=apparent_power_a[0]
                #print apparent_power_a
                        freq=c.read_holding_registers(159,1)
                        freq=freq[0]/10
                #print freq
                        np.array(voltage_a,dtype=float)
                        np.array(current_a,dtype=float)
                        np.array(real_power_a,dtype=float)
                        np.array(reactive_power_a,dtype=float)
                        np.array(apparent_power_a,dtype=float)
                        np.array(freq,dtype=float)
                        data = {
                                    "voltage_reading" : voltage_a,
                                    "current_reading" : current_a,
                                    "real_power_rating" : real_power_a,
                                    "reactive_power_rating" : reactive_power_a,
                                    "apparent_power_rating" : apparent_power_a,
                                    "frequency_reading" : freq
                        }
                        print (data)
                        return data
Exemplo n.º 24
0
class Storage_Data(object):
    def __init__(self):
        # self.host = input("请输入IP地址:")
        # self.port = int(input("请输入端口号:"))
        # self.username = input("请输入用户名:")
        # self.password = input("请输入密码:")
        self.host = "192.168.1.30"
        self.port = 2121
        self.username = "******"
        self.password = "******"
        self.remote_path = "/data/mgrid/sampler/modbus_map.xml"
        self.__file = "./modbus_map.xml"
        self.__old_str = "&"
        self.__new_str = "-"
        self.equipid_list = []
        self.sigid_list = []
        self.reg_addr_list = []
        self.name_list = []
        self.__client = ModbusClient(host=self.host,
                                     port=502,
                                     debug=True,
                                     auto_open=True)
        self.__address = 0
        self.__register = 50
        self.i = 0
        self.__conn = connect(host='localhost',
                              port=3306,
                              database="MOTTA_data",
                              user="******",
                              password="******",
                              charset="utf8")
        self.__cur = self.__conn.cursor()
        self.float_data = []  # 检测获取到的数据

    # 1.获取map表(xml格式)
    def ftp_connect(self):
        # 初始化FTP
        ftp = FTP()
        # 连接IP地址和端口
        ftp.connect(self.host, self.port)
        # 输入帐号密码登录,如果匿名登录则用空串代替即可
        ftp.login(self.username, self.password)
        # 返回FTP对象
        return ftp

    # 2.下载xml文件
    def download_file(self):
        # 调用ftp_connect()方法 下载文件
        ftp = self.ftp_connect()
        # 设置缓冲块大小
        bufsize = 1024
        # 以写模式在本地打开文件(当前目录)
        fp = open("./modbus_map.xml", 'wb')
        # 接收服务器上文件并写入本地文件
        ftp.retrbinary('RETR ' + self.remote_path, fp.write, bufsize)
        # 关闭文件
        fp.close()
        # 退出FTP
        self.ftp_connect().quit()

    # -------------------------------------《处理下载的xml文件》--------------------------------------------------

    # 3.替换字符串&,符串&在xml文件中属于特殊字符串,在解析获取xml文件内容时会因为字符串报错
    def replace_string(self):
        self.download_file()
        # 将xml文件中的&替换成-(XML文件有五个不允许出现的特殊字符)
        file_data = ""
        # 打开下载到本地的xml文件
        with open(self.__file, "r", encoding="utf-8") as f:
            # 遍历xml文件行
            for line in f:
                if self.__old_str in line:
                    # Python replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。
                    line = line.replace(self.__old_str, self.__new_str)
                file_data += line
        # w:打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
        with open(self.__file, "w", encoding="utf-8") as f:
            # 替换含有$字符串的行
            f.write(file_data)

    # 4.获取数据列表(equipid=[...] sigid=[...] reg_addr=[...] name=[...])
    def get_data_list(self):
        self.replace_string()
        # 打开下载到本地的xml文档对象
        dom = xmldom.parse(self.__file)
        # 得到文档元素对象 documentElement 属性可返回文档的根节点。
        root = dom.documentElement
        # getElementsByTagName() 方法可返回带有指定标签名的对象的集合(是一个文档对象)
        document_object = root.getElementsByTagName('signal')
        # 遍历<signal>标签 对象集合
        for item in document_object:
            # getAttribute()方法返回指定属性名的属性值。
            equipid = item.getAttribute("equipid")
            # 将获取的‘equipid’属性值,存到equipid_list列表中
            self.equipid_list.append(equipid)
            sigid = item.getAttribute("sigid")
            self.sigid_list.append(sigid)
            reg_addr = item.getAttribute("reg_addr")
            self.reg_addr_list.append(reg_addr)
            name = item.getAttribute("name")
            self.name_list.append(name)

    # -------------------------------------《IP地址和int类型的互相转换》---------------------------------------
    # IP转int型
    def iptoint(self, num):
        list = []
        s = num.split(".")
        for temp in s:
            a = bin(int(temp))[2:]
            a = a.zfill(8)
            list.append(a)
        g = "".join(list)
        e = int(g, 2)
        return e

    def inttoip(self, num):
        s = bin(num)[2:]
        s = s.zfill(32)
        g = []
        h = []
        for i in range(0, 32, 8):
            g.append(s[i:i + 8])
        for temp in g:
            h.append(str(int(temp, 2)))
        e = ".".join(h)
        return e

    # -------------------------------------《通过modbus-tcp协议获取实时数据》---------------------------------------

    # 5.实时更新数据并添加到数据库(实时通过while循环反复存储)
    def get_realtime_data(self):
        # 判断是否连接成功 (否 否为真)
        if not self.__client.is_open() and not self.__client.open():
            # 在次连接一次,没有连接上则抛出错误
            raise RuntimeError('无法连接:请检查端口或IP地址是否正确')
        while True:
            # time.sleep(3)
            if self.__address < len(self.name_list):
                """
                1.改写源码(read_holding_registers):源码返回的数据为32位 协议为64位数据对不上,通过调试模式返Rx数据,返回数据为(registers, re_debug)
                2.开启调试模式获re_debug 
                """
                registers, re_debug = self.__client.read_holding_registers(
                    self.__address, self.__register)
                # 获取50个数据(字符串类型)
                # print(re_debug)
                str_list = re_debug.split(" ")[9:-1]
                a = [str_list[x:x + 4] for x in range(0, len(str_list), 4)]
                # print(len(a))
                for x in a:
                    b = "".join(x)
                    # print(b)
                    # 前面四位不动 后面四位两两交换位置(注意转浮点数时候大端小端问题)
                    c = b[0:4] + b[-2:] + b[4:6]
                    # print(c)
                    # 4位16进制数 转浮点数
                    d = "%.2f" % struct.unpack('<f', bytes.fromhex(c))[0]
                    # print("%d正在获取(%s)的数据: %s" % (self.i, self.name_list[self.i], d))
                    print(d)
                    self.input_data(d)
                    self.i += 1
                self.__address += 50
            else:
                self.i = 0
                self.__address = 0
                # time.sleep(3)
                break

    # 6.存入数据库
    def input_data(self, float_data):

        # 将得到的浮点数数据存入到数据库
        # 获取当前时间
        nowTime = datetime.datetime.now()
        # 格式化当前时间
        strTime = nowTime.strftime("%Y-%m-%d %H:%M:%S")
        # 逻辑删除(在drf中自定义模型,逻辑删除健,设置了默认值,但是只有通过drf存储时才会有默认值,直接在数据库中存储是不会添加默认值的)
        is_delete = False
        # divice_ip = self.iptoint(self.host)
        divice_ip = self.host
        # print(type(divice_ip))
        data = [
            self.equipid_list[self.i], self.sigid_list[self.i],
            self.reg_addr_list[self.i], self.name_list[self.i], float_data,
            strTime, is_delete, divice_ip
        ]
        sql_str = '''insert into tb_xmldata (equipid, sigid, reg_addr, name, float_data, data_time, is_delete, divice_ip) values(%s, %s, %s, %s, %s, %s, %s, %s);'''
        self.__cur.execute(sql_str, data)
        self.__conn.commit()
Exemplo n.º 25
0
from pyModbusTCP import utils

try:
    c = ModbusClient(host="localhost", port=502)
except ValueError:
    print("Error with host or port params")

c = ModbusClient(host="localhost", auto_open=True)

if c.open():
    regs_list_1 = c.read_holding_registers(0, 10)
    regs_list_2 = c.read_holding_registers(55, 10)
    c.close()

while True:
    if c.is_open():
        regs_list_1 = c.read_holding_registers(0, 10)
        regs_list_2 = c.read_holding_registers(55, 10)
    else:
        c.open()
    time.sleep(1)

list_16_bits = [0x0123, 0x4567, 0x89ab, 0xcdef]

# big endian sample (default)
list_32_bits = utils.word_list_to_long(list_16_bits)
# display "['0x1234567', '0x89abcdef']"
print([hex(i) for i in list_32_bits])

# little endian sample
list_32_bits = utils.word_list_to_long(list_16_bits, big_endian=False)
Exemplo n.º 26
0
class AmpSwitch(object):
    def __init__(self, host, port=502, switches=(), debug=False):
        """ """

        self.host = host
        self.port = port
        self.debug = debug
        self.switches = switches

        self.dev = None

        self.connect()

    def __str__(self):
        return "AmpSwitch(host=%s, port=%s, dev=%s>" % (self.host,
                                                        self.port,
                                                        self.dev)
    def setDebug(self, state):
        self.debug = state
        self.connect()
        
    def close(self):
        if self.dev is not None:
            self.dev.close()
            self.dev = None

    def connect(self):
        """ (re-) establish a connection to the device. """

        if self.dev is None:
            self.dev = ModbusClient()
            self.dev.debug(self.debug)
            self.dev.host(self.host)
            self.dev.port(self.port)

        if self.dev.is_open():
            return True

        ret = self.dev.open()
        if not ret:
            raise RuntimeError("failed to connect to %s:%s" % (self.host,
                                                               self.port))

        return True

    def readCoils(self):
        """ Return the state of all our switches. """

        self.connect()

        regs = self.dev.read_coils(0, 16)
        return regs

    def setCoils(self, on=(), off=()):
        """Turn on and off a given set of switches. 

        Argunents
        ---------

        on, off : list-like, or a single integer.

        Notes:
        ------

        The off set is executed first. . There is a command to change
        all switchees at once, but I have not made it work yet.

        """
        self.connect()

        if isinstance(on, int):
            on = on,
        if isinstance(off, int):
            off = off,

        regs0 = self.readCoils()
        regs1 = regs0[:]
        for c in off:
            ret = self.dev.write_single_coil(c, False)
            regs1[c] = False
        for c in on:
            ret = self.dev.write_single_coil(c, True)
            regs1[c] = True
        
        # ret = self.dev.write_multiple_registers(0, regs1)
        ret = self.readCoils()
        return ret

    def chooseCoil(self, n):
        return self.setCoils(on=n, off=list(range(16)))
Exemplo n.º 27
0
class ComBox():
    """This class implements functions specific to the Schneider ComBox """
    def __init__(self):
        ''' Constructor for this class. '''
        self._port = 0


    def __del__(self):
        ''' Destructor for this class. '''
        if self._port !=0:
            self.close()

    def open (self,SERVER_HOST = "192.168.0.210",SERVER_PORT = 502,SERVER_UNIT = 201):
        """Open modbus connection to the ComBox

        Args:
            SERVER_HOST: network address of the ComBox. Default='192.168.0.210'
            SERVER_PORT: modbus TCP port. Default='502'
            SERVER_UNIT: modbus address of the ComBox. Default='201'

        Returns: Boolean value True or False

        """
        self._port = ModbusClient(SERVER_HOST, SERVER_PORT, SERVER_UNIT)
        if not self._port.is_open():
            if not self._port.open():
                print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT))

        return self._port.is_open()

    def close(self):
        """Closes the modbusTCP connection

        Returns: Boolean value True or False

        """
        self._port.close()
        return not self._port.is_open()

    def is_connected(self):
        """This function checks if the connection to the Schneider Conext ComBox is established
        and if it responds to readout commands. It requests the firmware version of the ComBox
        and checks for an received bitstream.

        Returns: Boolean value True or False

        return
        """
        bitstream = self._port.read_holding_registers(0x001E, 7)  # 0x001E Firmware Version str20 r
        if bitstream:
            return True
        else:
            return False

    def read_firmware(self):
        """This function reads the firmware version of the ComBox and returns it as a string.

        Returns: string {firmware version}

        """
        bitstream = self._port.read_holding_registers(0x001E, 7)# 0x001E Firmware Version str20 r
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = decoder.decode_string(14)
        return result


    def read_Grid_Voltage(self):
        """This function reads the Grid Voltage from the ComBox and returns Volt.

        Returns: float {Grid Voltage in Volt}

        """
        bitstream = self._port.read_holding_registers(0x004C, 2)# 0x004C Grid Voltage uint32 r
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result =(decoder.decode_32bit_uint())/1000.0
        return result

    def read_Grid_Frequency(self):
        """This function reads the Grid Frequency from the ComBox and returns it in Hz.

        Returns: float {Grid Frequency in Hz}

        """
        bitstream = self._port.read_holding_registers(0x004E, 2)# 0x004E Grid Frequency uint32 r
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result =(decoder.decode_32bit_uint())/100.0
        return result
Exemplo n.º 28
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()
Exemplo n.º 29
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))
Exemplo n.º 30
0
    help='Modbus server to raise alert <address>:[<port=502>]/<register>')
parser.add_argument('authorized_hosts',
                    nargs='*',
                    help="list of authorized hosts")
args = parser.parse_args()

# Add own IP address to authorized hosts
args.authorized_hosts.append(socket.gethostbyname(socket.gethostname()))

# Open Modbus client if needed
if args.alert is not None:
    adr = parse_address(args.alert)
    args.__dict__.update({k: adr[k] for k in ["host", "port", "register"]})

    c = ModbusClient(host=args.host, port=args.port, auto_open=True)
    if not c.is_open():
        if not c.open():
            raise ConnectionError(
                f'cannot connect to Modbus server at {args.host}:{args.port}')


# Function called for every paquet handled by the sniffer
def callback(p):
    src = p['IP'].src
    dst = p['IP'].dst
    if src not in args.authorized_hosts:
        if args.alert is not None:
            c.write_single_register(args.register, 1)
        print(f"Request from {src} to {dst} detected!")

Exemplo n.º 31
0
class modBusWriteRead():
    def __init__(self,client_host):
        self.client_host = client_host
        self.client_port = 502
        self.err_list = []
        self.connect() #buradan bağlantı yapılacak;

    def connect(self):
        self.modbus_c = ModbusClient()
        self.modbus_c.host(self.client_host)
        self.modbus_c.port(self.client_port)
        if not self.modbus_c.is_open():
            if not self.modbus_c.open():
                text="unable to connect to " + self.client_host + ":" + str(self.client_port)
                print(text)

    def write_data_reg(self,address,list):
        if self.modbus_c.open():
            if len(list)>120:
                sent_list = self.hazirla_dizi_to_write(list)
                i = 0
                hedef_reg_taban = address
                for list_to_sent in sent_list:
                    hedef_reg = hedef_reg_taban + (i * 120)
                    a = self.modbus_c.write_multiple_registers(hedef_reg, list_to_sent)
                    if a == None or a == False:
                        self.err_list.append(False)
                    i += 1
            else:
                a = self.modbus_c.write_multiple_registers(address, list)
                if a == None or a == False:
                    self.err_list.append(False)
        if len(self.err_list) > 0:
            self.err_list = []
            pass
            # dikkat
            # print("data göndermede hata oluştu, tekrar deneyin !")

    def hazirla_dizi_to_write(self,d_list):
        # eğer gönderilecek değer 120 den büyük ise aşağıdaki fonksiyon 120 lik diziler döndürüyor
        r_list = []
        g_list = []
        i = 0
        for index in range(len(d_list)):
            g_list.append(d_list[index])
            i += 1
            if i > 119:
                i = 0
                r_list.append(g_list)
                g_list = []
            if (len(d_list) - 1) == index and i < 119:
                r_list.append(g_list)
        return r_list

    def read_data_reg(self,address,reg_count,read_float=False ):
        # burada 16 lık ya da float olarak okunabiliyor
        if self.modbus_c.is_open():
            if read_float == False:
                plc_list_int = self.modbus_c.read_holding_registers(address, reg_count)
                return plc_list_int
            elif read_float == True:
                plc_list_f_16=self.modbus_c.read_holding_registers(address,reg_count)
                if plc_list_f_16 is not None:
                    plc_list_float=self.long_to_float(plc_list_f_16)
                    return plc_list_float

    def long_to_float(self,list_16):
        list_float=[]
        list_16.reverse()
        list_long=utils.word_list_to_long(list_16)
        for any_long in list_long:
            list_float.append(utils.decode_ieee(any_long))
        list_float.reverse()
        return list_float
class JointStatePublisher():
    def __init__(self):
        ip = rospy.get_param("/robot_ip")
        self.c = ModbusClient(host=ip,
                              auto_open=True,
                              auto_close=False,
                              port=502,
                              debug=False,
                              unit_id=2)

        rospy.init_node("joint_pos_pub")
        self.p = rospy.Publisher('/joint_states', JointState, queue_size=1)

        name = getpass.getuser()
        f = open(
            '/home/%s/catkin_ws/src/delta/arm_driver/yaml/joint_limits.yaml' %
            name, 'r')
        d = yaml.load(f)
        f.close()

        self.dP = d["PUU_limits"]
        self.dA = d["Angle_limits"]

        self.joint_states = JointState()
        self.joint_states.name = [
            'shoulder', 'elbow', 'wrist1', 'wrist2', 'wrist3', 'wrist4'
        ]

    def pubAngles(self):
        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]
            self.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]
            self.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]
            self.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]
            self.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]
            self.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]
            self.j6_angle = radians(j6_a / 1000)

            self.joint_states.position = [
                self.j1_angle, self.j2_angle, -self.j3_angle, -self.j4_angle,
                -self.j5_angle, -self.j6_angle
            ]
            self.joint_states.header.stamp = rospy.Time.now()
            self.p.publish(self.joint_states)
Exemplo n.º 33
0
class Kostal:
    # Class attributes
    GridFrequency = 0  # address 0x98 (152)
    TotalDCPower = 0  # address 0x64 (100)
    HomeFromGrid = 0  # address 0x6c (108)
    HomeFromPV = 0  # address 0x72 (114)

    #
    # Constructor
    #
    def __init__(self, master):
        self.master = master
        self.config = master.config
        self.lastUpdate = 0

        # try to read the config file
        try:
            self.configConfig = master.config["config"]
            self.configKostal = master.config["sources"]["Kostal"]
        except KeyError:
            self.configConfig = {}
            self.configKostal = {}

        # read configuration values and initialize variables
        self.enabled = self.configKostal.get("enabled", False)
        self.host = self.configKostal.get("serverIP", None)
        self.port = int(self.configKostal.get("modbusPort", 1502))
        self.unitID = int(self.configKostal.get("unitID", 71))

        # Unload if this module is disabled or misconfigured
        if (not self.enabled) or (not self.host):
            self.master.releaseModule("lib.TWCManager.EMS", "Kostal")
            return None

        # try to open open the Modbus connection
        try:
            self.modbus = ModbusClient(host=self.host,
                                       port=self.port,
                                       unit_id=self.unitID,
                                       auto_open=True)
            if not self.modbus.open() is True:
                raise ValueError
        except ValueError:
            # if connection not possible, print error message and unload module
            logger.info(
                "ERROR connecting to inverter. Please check your configuration!"
            )
            self.master.releaseModule("lib.TWCManager.EMS", "Kostal")
        else:
            # detected byte order (Little/Big Endian) by reading register 0x05
            self.byteorder = ENDIAN_LITTLE
            if self.modbus.read_holding_registers(5, 1)[0] == ENDIAN_BIG:
                self.byteorder = ENDIAN_BIG

            # get basic inverter info and output informations into log
            inv_model = self.__readModbus(768, "String")
            inv_class = self.__readModbus(800, "String")
            inv_serial = self.__readModbus(559, "String")
            logger.info(inv_model + " " + inv_class + " (S/N: " + inv_serial +
                        ") found.")

            # module successfully loaded update all values
            self.__update()

    #
    # Destructor
    # Makes sure that an open Modbus-Connection is gracefully closed
    #
    def __del(self):
        if self.modbus.is_open() is True:
            self.modbus.close()

    #
    # Privat Method for reading Modbus values
    # read registers directly from the inverter via Modbus protocol
    #
    def __readModbus(self, address, data_format="Float"):

        # open the Modbus connection if neccessary
        if not self.modbus.is_open():
            self.modbus.open()

        # default data length is 1 ('U16')
        length = 1

        # if we are retreiving floats, its two bytes
        if data_format == "Float":
            length = 2

        # for strings its either 8, 16 or 32 byte, depending on the register
        elif data_format == "String":
            if address in [8, 14, 38, 46, 420, 428, 436, 446, 454, 517]:
                length = 8
            elif address in [535, 559]:
                length = 16
            else:
                length = 32

        # read the raw data from the given Modbus address
        raw = self.modbus.read_holding_registers(address, length)
        if raw is None:
            return False

        # decode the raw_data
        if data_format == "U16":
            return int(raw[0])

        elif data_format == "Float":
            if self.byteorder == ENDIAN_BIG:
                return float(utils.decode_ieee((raw[0] << 16) + raw[1]))
            else:
                return float(utils.decode_ieee((raw[1] << 16) + raw[0]))

        elif data_format == "String":
            data_string = ""
            for value in raw:
                hex_value = str(hex(value)[2:])
                left = int(str(hex_value)[:2], 16)
                right = int(str(hex_value)[-2:], 16)
                data_string += chr(left) + chr(right)

            return str(data_string)

        # if all failed, return false
        return False

    #
    # Private Method
    # Update the cached values by reading them from the Modbus
    #
    def __update(self):
        if (int(time.time()) - self.lastUpdate) > MIN_CACHE_SECONDS:
            # Cache has expired. Fetch values from inverter via Modbus

            self.GridFrequency = self.__readModbus(152, "Float")
            self.TotalDCPower = self.__readModbus(100, "Float")
            self.HomeFromGrid = self.__readModbus(108, "Float")
            self.HomeFromPV = self.__readModbus(116, "Float")

            # set the lastUpdate variable to "now"
            self.lastUpdate = time.time()

    #
    # Public Method
    # Return the total consumption by the household
    # deduct charger load - if car(s) charging
    #
    def getConsumption(self):
        # update value if neccessary
        self.__update()

        # return the total household consumption
        total = self.HomeFromGrid + self.HomeFromPV
        logger.debug("Current Home consumption: {:.2f} W".format(total))
        return float(self.HomeFromGrid + self.HomeFromPV)

    #
    # Public Method
    # Return the generated power by the inverter
    #
    def getGeneration(self):
        # update value if neccessary
        self.__update()

        # return the Solar generation power
        logger.debug("Current Solar generation: {:.2f} W".format(
            self.TotalDCPower))
        return float(self.TotalDCPower)
Exemplo n.º 34
0
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)

toggle = True

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 bits")
        print("----------")
        print("")
        for addr in range(4):
            is_ok = c.write_single_coil(addr, toggle)
            if is_ok:
                print("bit #" + str(addr) + ": write to " + str(toggle))
            else:
Exemplo n.º 35
0
def get_points(conn, devices):
    for device in devices:
        try:
            cur = conn.cursor()
            #Get IP Address and port from database
            cur.execute("SELECT ip, port FROM device WHERE devID = ?",
                        (device, ))
            request = cur.fetchone()
            ip = request[0]
            port = request[1]

            client = ModbusClient()
            client.host(ip)
            client.port(port)

            client_connected = True
            if (client.is_open() == False):
                if (client.open() == False):
                    print("Unable to connect to " + ip + ":" + str(port))
                    client_connected = False

            if (client_connected == True):
                cur.execute(
                    "SELECT name, address, type, pointID, mult_factor FROM device_points WHERE devID = ? AND deleted = 0",
                    (device, ))
                rows = cur.fetchall()

                for row in rows:
                    if (row[2] == "dig_in"):
                        req = client.read_discrete_inputs(int(row[1]), 1)

                        datetime_str = datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S.%f")
                        point_ID = row[3]
                        value = req[0] * row[4]
                        print(datetime_str + " | " + str(point_ID) + " | " +
                              str(value))
                        cur.execute("INSERT INTO point_data VALUES (?, ?, ?)",
                                    (datetime_str, point_ID, value))
                        #print("Value for point " + row[0] + ": " + str(req) + datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"))

                    if (row[2] == "dig_out"):
                        req = client.read_coils(int(row[1]), 1)

                        datetime_str = datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S.%f")
                        point_ID = row[3]
                        value = req[0] * row[4]
                        error_code = 0
                        print(datetime_str + " | " + str(point_ID) + " | " +
                              str(value))
                        cur.execute("INSERT INTO point_data VALUES (?, ?, ?)",
                                    (datetime_str, point_ID, value))
                        #print("Value for point " + row[0] + ": " + str(req) + datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"))

                    if (row[2] == "an_in"):
                        req = client.read_input_registers(int(row[1]), 1)

                        datetime_str = datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S.%f")
                        point_ID = row[3]
                        value = req[0] * row[4]
                        error_code = 0
                        print(datetime_str + " | " + str(point_ID) + " | " +
                              str(value))
                        cur.execute("INSERT INTO point_data VALUES (?, ?, ?)",
                                    (datetime_str, point_ID, value))
                        #print("Value for point " + row[0] + ": " + str(req) + datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"))

                    if (row[2] == "an_out"):
                        req = client.read_holding_registers(int(row[1]), 1)

                        datetime_str = datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S.%f")
                        point_ID = row[3]
                        value = req[0] * row[4]
                        error_code = 0
                        print(datetime_str + " | " + str(point_ID) + " | " +
                              str(value))
                        cur.execute("INSERT INTO point_data VALUES (?, ?, ?)",
                                    (datetime_str, point_ID, value))
                        #print("Value for point " + row[0] + ": " + str(req) + datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f"))

                print("\n")
                conn.commit()
                cur.close()
                client.close()

        except Error as e:
            print(e)
            conn.close()
            database = "./database/SCADADB.db"
            conn = create_connection(database)
Exemplo n.º 36
0
class XW():
    """This class implements functions specific to the Schneider ComBox """
    def __init__(self):
        ''' Constructor for this class. '''
        self._port = 0


    def __del__(self):
        ''' Destructor for this class. '''
        if self._port !=0:
            self.close()

    def open (self,SERVER_HOST = "192.168.0.210",SERVER_PORT = 502,SERVER_UNIT = 10):
        """Open modbus connection to the ComBox

        Args:
            SERVER_HOST: network address of the ComBox. Default='192.168.0.210'
            SERVER_PORT: modbus TCP port. Default='502'
            SERVER_UNIT: modbus address of the ComBox. Default='201'

        Returns: Boolean value True or False

        """
        self._port = ModbusClient(SERVER_HOST, SERVER_PORT, SERVER_UNIT)
        if not self._port.is_open():
            if not self._port.open():
                print("unable to connect to " + SERVER_HOST + ":" + str(SERVER_PORT))

        return self._port.is_open()

    def close(self):
        """Closes the modbusTCP connection

        Returns: Boolean value True or False

        """
        self._port.close()
        return not self._port.is_open()

    def is_connected(self):
        """This function checks if the connection to the Schneider Conext XW+ is established
        and if it responds to readout commands. It requests the firmware version of the XW+
        and checks for an received bitstream.

        Returns: Boolean value True or False

        return
        """
        bitstream = self._port.read_holding_registers(0x001E, 7)  # 0x001E Firmware Version str20 r
        if bitstream:
            return True
        else:
            return False

    def read_firmware(self):
        """This function reads the firmware version of the XW+ inverter and returns it as a string.

        Returns: string {firmware version}

        """
        bitstream = self._port.read_holding_registers(0x001E, 7)# 0x001E Firmware Version str20 r
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = decoder.decode_string(14)
        return result

    def read_Grid_Voltage(self):
        """This function reads the Grid Voltage from the XW+ inverter and returns Volt.

        Returns: float {Grid Voltage in Volt}

        """
        bitstream = self._port.read_holding_registers(0x0062, 2)  # 0x0062 Grid Voltage uint32 r
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_32bit_uint()) / 1000.0
        return result

    def read_Grid_Frequency(self):
        """This function reads the Grid Frequency from the XW+ inverter and returns it in Hz.

        Returns: float {Grid Frequency in Hz}

        """
        bitstream = self._port.read_holding_registers(0x0061, 1)  # 0x0061 Grid Frequency uint16 r
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint()) / 100.0
        return result

    def read_Low_Battery_Cut_Out(self):
        """This function reads the Low_Battery_Cut_Out Voltage from the XW+ inverter and returns it in Volt.

        Returns: float {Low Battery Cut Out in Volt}

        """
        bitstream = self._port.read_holding_registers(0x017C, 2)  # 0x017C Low Battery Cut Out uint32 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_32bit_uint()) / 1000.0
        return result

    def read_Low_Battery_Cut_Out_Delay(self):
        """This function reads the Low Battery Cut Out Delay from the XW+ inverter and returns it in Seconds.

        Returns: float {Low Battery Cut Out Delay in Seconds}

        """
        bitstream = self._port.read_holding_registers(0x017E, 1)  # 0x017E Low Battery Cut Out Delay uint16 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint()) / 100.0
        return result

    def read_Inverter_Status(self):
        """This function reads the Inverter Status from the XW+ inverter and returns the status as a string.

        Returns: string {status}

        """
        bitstream = self._port.read_holding_registers(0x007A, 1)  # 0x007A Inverter Status uint16 r
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint())
        if result == 1024:
            return str('Invert')
        elif result == 1025:
            return str('AC Pass Through')
        elif result == 1026:
            return str('APS Only')
        elif result == 1027:
            return str('Load Sense')
        elif result == 1028:
            return str('Inverter Disabled')
        elif result == 1029:
            return str('Load Sense Ready')
        elif result == 1030:
            return str('Engaging Inverter')
        elif result == 1031:
            return str('Invert Fault')
        elif result == 1032:
            return str('Inverter Standby')
        elif result == 1033:
            return str('Grid-Tied')
        elif result == 1034:
            return str('Grid Support')
        elif result == 1035:
            return str('Gen Support')
        elif result == 1036:
            return str('Sell-to-Grid')
        elif result == 1037:
            return str('Load Shaving')
        elif result == 1038:
            return str('Grid Frequency Stabilization')
        else:
            return str('UNKNOWN STATE!')


    def write_Low_Battery_Cut_Out_Delay(self, delay=0.1):
        """This function writes the Low Battery Cut Out Delay to the XW+ inverter and returns the value in the register.

        Returns: float {Low Battery Cut Out Delay in Seconds}

        """
        delay = np.uint16(delay * 100)
        Upper_limit = np.uint16(100 * 190) #upper limit 60 Seconds
        Lower_limit = np.uint16(100 * 1)#Lower limit 1 Seconds
        if delay in range(Lower_limit, Upper_limit):
            self._port.write_single_register(0x017E, delay)
        else:
            print ('ERROR: delay value out of range!')

        bitstream = self._port.read_holding_registers(0x017E, 1)  # 0x017E Low Battery Cut Out Delay uint16 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint()) / 100.0
        return result

    def write_Low_Battery_Cut_Out(self, voltage=47):
        """This function writes the Low Battery Cut Out to the XW+ inverter and returns the value in the register.

        Returns: float {Low Battery Cut Out in Volt}

        """
        voltage = np.uint32(voltage * 1000)
        Upper_limit = np.uint32(1000 * 49) #upper limit 60 Seconds
        Lower_limit = np.uint32(1000 * 46)#Lower limit 1 Seconds
        if voltage in range(Lower_limit, Upper_limit):
            self._port.write_multiple_registers(0x017C, [voltage, 00000])
        else:
            print ('ERROR: delay value out of range!')

        bitstream = self._port.read_holding_registers(0x017C, 2)  # 0x017C Low Battery Cut Out uint32 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint()) / 1000.0
        return result



    def read_Load_Shave_Status(self):
        """This function reads the Load Shave status from the XW+ inverter and returns the state.

        Returns: str {Load Shave state}

        """
        bitstream = self._port.read_holding_registers(0x01B2, 1)  # 0x017E Low Battery Cut Out Delay uint16 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint())
        if result == 0:
            return str('Disable')
        if result == 1:
            return str('Enable')

    def write_Load_Shave_Status(self, status):
        """This function writes the Load Shave to the XW+ inverter and returns the value in the register.

        Returns: str {Load Shave state}

        """
        if status == 'enable' or status == 'Enable' or status == 'ENABLE':
            self._port.write_single_register(0x01B2, 1)
        elif status == 'disable' or status == 'Disable' or status == 'DISABLE':
            self._port.write_single_register(0x01B2, 0)
        else:
            print ('ERROR: Input Parameter must be: "enable" or "disable"')

        bitstream = self._port.read_holding_registers(0x01B2, 1)  # 0x01B2 Load Shave uint16 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint())
        if result == 0:
            return str('Disable')
        if result == 1:
            return str('Enable')


    def read_Hysteresis(self):
        """This function reads the Low_Battery_Cut_Out Hysteresis from the XW+ inverter and returns it in Volt.

        Returns: float {Low Battery Cut Out Hysteresis in Volt}

        """

        bitstream = self._port.read_holding_registers(0x01F2, 2)  # 0x017C Low Battery Cut Out Hysteresis uint32 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_32bit_uint()) / 1000.0
        return result

    def write_Hysteresis(self, voltage=2.3):
        """This function writes the Low Battery Cut Out Hysteresis to the XW+ inverter and returns the value in the register.

        Returns: float {Low Battery Cut Out in Volt}

        """
        voltage = np.uint32(voltage * 1000)
        Upper_limit = np.uint32(1000 * 5) #upper limit 5 Volt
        Lower_limit = np.uint32(1000 * 1)#Lower limit 1 Volt
        if voltage in range(Lower_limit, Upper_limit):
            self._port.write_multiple_registers(0x01F2, [voltage, 00000])
        else:
            print ('ERROR: delay value out of range!')

        bitstream = self._port.read_holding_registers(0x01F2, 2)  # 0x017C Low Battery Cut Out Hysteresis uint32 r/w
        decoder = BinaryPayloadDecoder.fromRegisters(bitstream)
        result = (decoder.decode_16bit_uint()) / 1000.0
        return result
Exemplo n.º 37
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
Exemplo n.º 38
0
from pyModbusTCP.client import ModbusClient

import time

if __name__ == "__main__":

    host = input("\nPlease enter IP address [127.0.0.1]: ")
    port = input("Please enter port [502]: ")

    if not host:
        host = "172.16.143.146"

    if not port:
        port = 502

    c = ModbusClient(timeout=5)
    c.host(host)
    c.port(port)

    print("\nTrying to connect to " + host + ":" + str(port))

    if c.open():
        print("Opened")

    print(c.is_open())

    if c.close():
        print("Closed")

    print(c.is_open())
Exemplo n.º 39
0
def run_gui():
    global x, y, x1, y1
    # Declaring Modbus PLC
    print("The IP address of the PLC is:", sys.argv[1])

    #Declaring the modbus client
    try:
        client = ModbusClient(host=sys.argv[1], port=502)
    except ValueError:
        print("Error with host or port number")

    # Declaring the colors required int he graphics. This is in RGB format
    BLACK = (0, 0, 0)
    GREY = (169, 169, 169)
    BLUE = (0, 0, 255)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)

    # Drawing the robotic arm in pygame. The one time initilization is performed to use the Pygame instance
    pygame.init()
    size = [600, 600]
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption("Robotic Arm-Rishabh Das-UAH")
    message = pygame.font.SysFont("monospace", 15)
    header = pygame.font.SysFont("monospace", 30)

    run = True
    # This is the main loop that gets the current position of the robotic arm and updates the graphics after
    # every 100 ms
    while run:
        # -----------------------------------------------------------------------------------------
        # MODBUS Section of the loop. The reading of the registers are collected fromt he PLC memory
        # -----------------------------------------------------------------------------------------
        # check the connectivity of the TCP client to the GUI to the PLC
        if not client.is_open():
            if not client.open():
                print("Unable to Connect to " + sys.argv[1] + ":502")

        # Reading the registers for current lengths and the thetas
        theta_list = client.read_input_registers(2, reg_nb=2)
        length_list = client.read_holding_registers(4, reg_nb=2)

        # Print the list of the thetas
        # print(theta_list)
        # print(length_list)

        # Get the length of the arms from the MODBUS memory of the PLC to local variables
        length_1 = length_list[0]
        length_2 = length_list[1]

        if length_1 != 0 and length_2 != 0:
            ratio = (length_1 / length_2)
        else:
            print("Warning! \nArm length set to 0")
            if length_1 != 0:  #Dulplicate arm length value
                length_2 = length_1
            elif length_2 != 0:  #Dulplicate arm length value
                length_1 = length_2
            else:  #Default Values of the Robotic arm length
                length_1 = 10
                length_2 = 10
            ratio = (length_1 / length_2)
            # sys.exit(0)
        length_2 = 250 / (ratio + 1)
        length_1 = 250 - length_2

        if length_1 > 0 and length_2 > 0:
            # Get the current Theta positions of the arms from the MODBUS memory of the PLC to local variables
            Theta_1 = theta_list[0]
            Theta_2 = theta_list[0] + theta_list[1]

            # Calculate the coordinates
            calculate_coordinates(length_1, length_2, Theta_1, Theta_2)

            # -----------------------------------------------------------------------------------------
            # This section of the loop creates the GUI of the robotic arm using the pygame library
            # -----------------------------------------------------------------------------------------
            screen.fill(BLACK)
            # Drawing the robotic arm in pygame
            pygame.draw.line(screen, GREEN, [275, 275], [275 + x1, 275 - y1],
                             5)
            pygame.draw.line(screen, GREEN, [275 + x1, 275 - y1],
                             [275 + x, 275 - y], 5)
            pygame.draw.circle(screen, BLUE, [275, 275], 7)
            pygame.draw.circle(screen, BLUE,
                               [275 + round(x1), 275 - round(y1)], 7)
            pygame.draw.circle(screen, BLUE, [275 + round(x), 275 - round(y)],
                               7)

            # Calculate the coordinates
            calculate_coordinates(length_list[0], length_list[1], Theta_1,
                                  Theta_2)
            disp_coor1 = message.render(
                "(" + str(int(x1)) + "," + str(int(y1)) + ")", 1, GREEN)
            disp_coor2 = message.render(
                "(" + str(int(x)) + "," + str(int(y)) + ")", 1, GREEN)
            calculate_coordinates(length_1, length_2, Theta_1, Theta_2)
            screen.blit(disp_coor1, (275 + round(x1), 275 - round(y1)))
            screen.blit(disp_coor2, (275 + round(x), 275 - round(y)))

            #Displaying Heading
            title = header.render("Robotic Arm", 1, GREEN)
            screen.blit(title, (10, 1))

            #Displaying Theta values
            theta1_values = message.render(
                "Theta first joint:" + str(theta_list[0]), 1, GREEN)
            theta2_values = message.render(
                "Theta second joint:" + str(theta_list[1]), 1, GREEN)
            screen.blit(theta1_values, (400, 550))
            screen.blit(theta2_values, (400, 570))

            # Checking if the user clicked on the close button
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    run = False
                    sys.exit(0)
            pygame.display.update()

            #Controls the refresh rate of the robotic arm
            time.sleep(0.05)
        else:
            print("Invalid length! The GUI cannot be rendered!")
            sys.exit(0)
Exemplo n.º 40
0
class AcuvimIITCPMODBUS:
    def __init__(self, server_host, port, unit_id):
        self.c = ModbusClient()
        self.c.host(server_host)
        self.c.port(port)
        self.c.unit_id(unit_id)
        self.map = self.__import_map()

    def __import_map(self):
        with open('map.json') as json_file:
            return json.load(json_file)

    def __read_16_bit(self, address):
        if not self.c.is_open():
            self.c.open()
        return self.c.read_holding_registers(address, 1)[0]

    def __read_32_bit(self, address, number=1):
        if not self.c.is_open():
            self.c.open()
        reg_l = self.c.read_holding_registers(address, number * 2)
        if reg_l:
            return [
                utils.decode_ieee(f) for f in utils.word_list_to_long(reg_l)
            ][0]
        else:
            return None

    def __what_is_the_access_property(self, dict):
        if dict['Access Property'] == 'R':
            return 0
        if dict['Access Property'] == 'W':
            return 2
        else:
            return 1

    def __get_registry(self, dict):
        if dict['Data Type'] == 'Word':
            return (self.__read_16_bit(dict["Address(D)"]))
        elif dict['Data Type'] == 'Float':
            return (self.__read_32_bit(dict["Address(D)"]))
        elif dict['Data Type'] == 'Dword':
            return (self.__read_32_bit(dict["Address(D)"]))
        elif dict['Data Type'] == 'int':
            return (self.__read_16_bit(dict["Address(D)"]))
        elif dict['Data Type'] == 'Bit':
            return (self.__read_16_bit(dict["Address(D)"]))

    def get_clock(self):
        if not self.c.is_open():
            self.c.open()
        read_datetime = self.c.read_holding_registers(4159, 7)
        return datetime.datetime(read_datetime[1], read_datetime[2],
                                 read_datetime[3], read_datetime[4],
                                 read_datetime[5], read_datetime[6])

    def read_value(self, parameter=None, address=None):
        if parameter is not None:
            temp_dict = list(
                filter(lambda d: d['Parameter'] == parameter, self.map))
            if not len(temp_dict) == 0 and self.__what_is_the_access_property(
                    temp_dict[0]) <= 1:
                return (self.__get_registry(temp_dict[0]))

        elif address is not None:
            temp_dict = list(
                filter(lambda d: d['Address(D)'] == address, self.map))
            if not len(temp_dict) == 0 and self.__what_is_the_access_property(
                    temp_dict) <= 1:
                return (self.__get_registry(temp_dict[0]))

        else:
            return None
# Register Addresses
addr = [10, 11, 12, 13, 14, 15]  # Unused Register Addresses
toggle = [1, 2, 3, 4, 5, 6]  # Register Values for writing ...

hosts = [SERVER_HOST1, SERVER_HOST2]

while True:
    # print("Enter Port Number ( 0 : MASTER-1 ---- 1 : MASTER2 )")
    HOST = int(
        input("Enter Port Number (MASTER-1 :  1 ***** MASTER-2 : 2 ) :  "))
    if (HOST == 1):
        print("MASTER - 1 ( IP : {0} ) is choosen.".format(SERVER_HOST1))
        SERVER_HOST = SERVER_HOST1
        c.host(SERVER_HOST)
        c.port(SERVER_PORT)
        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
            addr = 10
            toggle = 22
            is_ok = c.write_single_register(addr, toggle)
            if is_ok:
                print("Writint register to " + str(addr) + " : " + str(toggle))
            else:
                print("Unable to write " + str(addr) + " : " + str(toggle))
class AsyncModbusClient(object):
    """Asyncio Modbus client."""
    def __init__(self, *, queue=None, host='127.0.0.1', timeout=1):
        """
        Set up client.

        ::host:: str - By default client runs on localhost.
        ::port:: int - Port 502 is constant for ModdbusTCP.
        """
        self.queue = queue
        self.host = host
        self.port = 502
        self.timeout = timeout
        self.client = ModbusClient(host=self.host, port=self.port)
        self.func_read_dict = {
            'hr': self.client.read_holding_registers,
            'c': self.client.read_coils,
            'di': self.client.read_discrete_inputs,
            'ir': self.client.read_input_registers,
        }
        self.func_write_dict = {
            'hr': self.client.write_multiple_registers,
            'c': self.client.write_multiple_coils,
        }
        self.registers_dict = {}
        self.reg_current_value = {}
        self.name_stack = []

    def add_registers(self, reg_type, adr, num, name, write=False):
        """
        Add register to the Modbus Client.

        ::reg_type::    str - values from 'hr', 'di', 'c' or 'ir',
        ::adr::         int - value starting from 0 to 65535,
        ::number::      int - from 1 to 2000 (AsyncModbusClient.max_number),
        ::name::        str - any unique name
        ::write::       int(0,1) - 0 for reading, 1 for writing.
        """
        adr = mdb.validate_adr(adr)
        num = mdb.validate_num(num)
        write = mdb.validate_write(write)
        name = mdb.validate_name(self.name_stack, name)
        self.name_stack.append(name)

        if write:
            pass  # Not implemented yet
        else:
            try:
                self.registers_dict.setdefault(
                    self.func_read_dict[reg_type],
                    [],
                ).append({
                    'adr': adr,
                    'num': num,
                    'name': name,
                })

            except Exception as err:
                raise ModbusClientError('Wrong modbus register type.', err)

    async def run_task(self):
        """Run asyncio client."""
        executor = concurrent.futures.ThreadPoolExecutor(
            max_workers=1,  # We can increase number
            # of workers if we increase queue line
        )
        task = asyncio.create_task(self._awaitable(executor))
        await task

    def _read_reg(self):
        self.read_regs = {}
        for func in self.registers_dict:
            for reg in self.registers_dict[func]:
                adr = reg['adr']
                num = reg['num']
                name = reg['name']
                reg_func = func(adr, num)
                if name in self.read_regs:
                    raise Exception(
                        """Name {0} is not unique. Create unique name.
                        """.format(name), )
                self.read_regs[name] = reg_func
        return self.read_regs

    async def _awaitable(self, executor):
        loop = asyncio.get_event_loop()
        while True:
            if self.client.is_open():
                self.reg_current_value = await loop.run_in_executor(
                    executor,
                    self._read_reg,
                )

            else:
                self.reg_current_value = 'Lost connection with Modbus server'
                self.client.open()

            if self.queue is not None:
                await self.queue.put(self.reg_current_value)
            await asyncio.sleep(self.timeout)