Ejemplo n.º 1
1
    def testBasicSyncSerialClient(self, mock_serial):
        ''' Test the basic methods for the serial sync client'''

        # receive/send
        mock_serial.in_waiting = 0
        mock_serial.write = lambda x: len(x)

        mock_serial.read = lambda size: b'\x00' * size
        client = ModbusSerialClient()
        client.socket = mock_serial
        client.state = 0
        self.assertEqual(0, client._send(None))
        client.state = 0
        self.assertEqual(1, client._send(b'\x00'))
        self.assertEqual(b'\x00', client._recv(1))

        # connect/disconnect
        self.assertTrue(client.connect())
        client.close()

        # already closed socket
        client.socket = False
        client.close()

        self.assertEqual('ModbusSerialClient(ascii baud[19200])', str(client))
Ejemplo n.º 2
1
def get_data():
    # choose the serial client
    client = ModbusClient(method='rtu', port=args.tty, baudrate=9600, timeout=args.timeout)

    client.connect()
    log.debug(client)

    # read the registers
    # for information about modbus registers see doc TSMPPT.APP.Modbus.EN.10.2.pdf
    rr = client.read_holding_registers(0,count=60,unit=1)
    if rr == None:
        client.close()
        log.error("couldn't connect")
        exit(1)

    # scaling
    v_scale = rr.registers[0] + rr.registers[1]/(2**16)
    i_scale = rr.registers[2] + rr.registers[3]/(2**16)

    # the stuff we want (the numbers are decimal but the registers are listed in hex)
    data={}
    data["batt-voltage" ] = ( rr.registers[24] * float(v_scale )) / (2**15)	# 0x18
    data["array-voltage" ] = ( rr.registers[27] * float(v_scale )) / (2**15)	# 0x1b
    data["batt-current" ] = ( rr.registers[28] * float(i_scale )) / (2**15)	# 0x1c
    data["array-current" ] = ( rr.registers[29] * float(i_scale )) / (2**15)	# 0x1d
    data["batt-temp" ] = rr.registers[37] 				# 0x25
    data["power-out" ] = ( rr.registers[58] * float(v_scale)*float(i_scale)) / (2**17)	# 0x3a
    data["power-in" ] = ( rr.registers[59] * float(v_scale)*float(i_scale)) / (2**17)	# 0x3b

    # close the client
    client.close()

    # debug
    log.info("got data from mppt via modbus")
    log.debug(datetime.datetime.now())
    for key in keys:
        log.debug("%-15s : %.2f" % (key, data[key]))

    return data
Ejemplo n.º 3
0
def main(host, port, mqtt_username, mqtt_password, instance, name, serial_port):
    modbus = ModbusClient(method='rtu', port=serial_port, baudrate=9600, timeout=1)

    if not modbus.connect():
        logger.error("Cannot connect to modbus")
        return

    client = mqtt.Client()
    client.loop_start()

    client.connect(host, port, 60)
    if mqtt_username is not None:
        client.username_pw_set(mqtt_username, mqtt_password)

    try:
        while True:
            now = int(time())
            r = modbus.read_holding_registers(0, 16, unit=1)

            bat_volt = r.registers[8] * 96.667 * 2**(-15)
            bat_curr = r.registers[11] * 316.67 * 2**(-15)
            bat_temp = r.registers[15]

            client.publish('{}/{}/power'.format(instance, name), "{} {:0.2f}".format(now, bat_volt * bat_curr), 0)
            client.publish('{}/{}/voltage'.format(instance, name), "{} {:0.2f}".format(now, bat_volt), 0)
            client.publish('{}/{}/current'.format(instance, name), "{} {:0.2f}".format(now, bat_curr), 0)
            client.publish('{}/{}/temperature'.format(instance, name), "{} {}".format(now, bat_temp), 0)

            sleep(5)
    except KeyboardInterrupt:
        pass
    client.disconnect()
    client.loop_stop()
    modbus.close()
Ejemplo n.º 4
0
def request(reg, num, modbus_id):
    distance = None
    logger.debug("Measuring distance...")
    try:
        modbus_client = ModbusClient(method="rtu",
                                     port=PORT,
                                     stopbits=1,
                                     bytesize=8,
                                     parity="N",
                                     baudrate=9600,
                                     timeout=0.1)
        if modbus_client.connect():
            height_query = modbus_client.read_holding_registers(reg,
                                                                count=num,
                                                                unit=modbus_id)
            distance = BinaryPayloadDecoder.fromRegisters(
                height_query.registers,
                byteorder=Endian.Big,
                wordorder=Endian.Big)
            distance = distance.decode_32bit_float()
            modbus_client.close()
        else:
            logger.error(f'Could not connecto to {PORT} port')
    except Exception as ex:
        logger.error('Error trying to read rs485 sensor')
    return height_query.registers, distance
Ejemplo n.º 5
0
def readDcPZEM(chanPort, chanAddr):
    voltage = 0
    amperage = 0
    power = 0
    energy = 0
    highVoltAlarmStatus = 0
    lowVoltAlarmStatus = 0

    #Connect to the serial modbus server
    client = ModbusClient(method="rtu",
                          port=chanPort,
                          stopbits=1,
                          bytesize=8,
                          parity='N',
                          baudrate=9600)

    if client.connect():
        try:
            result = client.read_input_registers(0x0000, 8, unit=chanAddr)
            voltage = scaleFactor(result.registers[0:1], 100)
            amperage = scaleFactor(result.registers[1:2], 100)
            power = scaleFactor(result.registers[2:4], 10)
            energy = scaleFactor(result.registers[4:6], 1)
            highVoltAlarmStatus = int(result.registers[6])
            lowVoltAlarmStatus = int(result.registers[7])

        except Exception as e:
            print('Exception reading DC PZEM: ' + str(e))

        finally:
            client.close()

    return voltage, amperage, power, energy, highVoltAlarmStatus, lowVoltAlarmStatus
Ejemplo n.º 6
0
def readAcPZEM(chanPort, chanAddr):
    voltage = 0
    amperage = 0
    power = 0
    energy = 0
    frequency = 0
    powerFactor = 0
    alarmStatus = 0

    client = ModbusClient(method="rtu",
                          port=chanPort,
                          stopbits=1,
                          bytesize=8,
                          parity='N',
                          baudrate=9600)

    if client.connect():
        try:
            result = client.read_input_registers(0x0000, 10, unit=chanAddr)
            voltage = scaleFactor(result.registers[0:1], 10)
            amperage = scaleFactor(result.registers[1:3], 1000)
            power = scaleFactor(result.registers[3:5], 10)
            energy = scaleFactor(result.registers[5:7], 1)
            frequency = scaleFactor(result.registers[7:8], 10)
            powerFactor = scaleFactor(result.registers[8:9], 100)
            alarmStatus = int(result.registers[9])

        except Exception as e:
            print('Exception reading AC PZEM: ' + str(e))

        finally:
            client.close()

    return voltage, amperage, power, energy, frequency, powerFactor, alarmStatus
Ejemplo n.º 7
0
def main():
    parser = argparse.ArgumentParser(
        description='Talk to a voegtlin red-y flow controller')
    parser.add_argument(
        'port',
        help='The serial interface your Modbus device is connected to.')
    parser.add_argument('--unit',
                        default=247,
                        type=int,
                        help='The slave address of the Modbus device')
    args = parser.parse_args()

    logging.basicConfig()
    log = logging.getLogger()
    #log.setLevel(logging.DEBUG)

    client = ModbusClient(method='rtu',
                          port=args.port,
                          stopbits=2,
                          baudrate=9600)
    try:
        client.connect()

        redy = RedY(unit=args.unit, modbus_client=client)
        redy.read_all()

    finally:
        client.close()
Ejemplo n.º 8
0
def main():

    client = ModbusClient(method='rtu', port='/dev/ttyAMA0', baudrate=38400, parity='N', bytesize=8, stopbits=2, timeout=1)

    # request modbus register values from device
    client.connect()
    start = timer()
    reg_values = {}
    for addr, size in SDM630_BLOCKS.items():
        resp = client.read_input_registers(addr, size * 2, unit=1)
        block = resp.registers
        reg_values.update({ (addr + i): block[i] for i in range(0, len(block)) })
    request_time = timer() - start
    client.close() # close the client

    # convert modbus register values to float
    start = timer()
    mod_values = {}
    for name, r in SDM630_REGISTER.items():
        w0 = reg_values[r.address + 0]
        w1 = reg_values[r.address + 1]
        mod_values[name] = struct.unpack('>f', struct.pack('>HH', w0, w1))[0]
    conversion_time = timer() - start

    # print all values in order of their modbus address
    for (name, _) in sorted(SDM630_REGISTER.items(), key = lambda x: x[1].address):
        v = mod_values[name]
        u = SDM630_REGISTER[name].unit
        print("{:40}: {:10.2f} {}".format(name, v, "" if u is None else str(u)))

    print("request took %.3f seconds" % request_time)
Ejemplo n.º 9
0
def main(args):
    global PUMP_TIME
    global SENSOR_TIME
    try:
        PUMP_TIME = int(args[1])
        SENSOR_TIME = int(args[2])
        print('using custom args. pump time: %d sensor time: %d' % (PUMP_TIME, SENSOR_TIME))
    except:
        PUMP_TIME = 3
        SENSOR_TIME = 5
        print('using default args. pump time: %d sensor time: %d' % (PUMP_TIME, SENSOR_TIME))

    startMeasurement()

    # Connect to sensor and record data
    try:
        client = ModbusClient(method = "rtu", port="/dev/ttyS0",stopbits = 1, bytesize = 8, parity = 'N', baudrate= 9600)
        # Connect to the serial modbus server
        connection = client.connect()
        if connection:
            recordData(client)
        # Closes the underlying socket connection
        client.close()

    except Exception as error:
        print('CO2 measurement failed: ' + repr(error))
    finally:
        endMeasurement()
Ejemplo n.º 10
0
def getLoadCurrent():
    client = ModbusClient(method='rtu', port=PORT, baudrate=BAUDRATE)
    client.connect()
    result = client.read_input_registers(0x3100, 15, unit=1)
    data = float(result.registers[13] / 100.0)
    client.close()
    return data
Ejemplo n.º 11
0
def main(args):
    global PUMP_TIME
    global SENSOR_TIME
    try:
        PUMP_TIME = int(args[1])
        SENSOR_TIME = int(args[2])
        print('using custom args. pump time: %d sensor time: %d' %
              (PUMP_TIME, SENSOR_TIME))
    except:
        PUMP_TIME = 3
        SENSOR_TIME = 5
        print('using default args. pump time: %d sensor time: %d' %
              (PUMP_TIME, SENSOR_TIME))

    startMeasurement()

    # Connect to sensor and record data
    try:
        client = ModbusClient(method="rtu",
                              port="/dev/ttyS0",
                              stopbits=1,
                              bytesize=8,
                              parity='N',
                              baudrate=9600)
        # Connect to the serial modbus server
        connection = client.connect()
        if connection:
            recordData(client)
        # Closes the underlying socket connection
        client.close()

    except Exception as error:
        print('CO2 measurement failed: ' + repr(error))
    finally:
        endMeasurement()
Ejemplo n.º 12
0
def main():
  if len(sys.argv) != 4:
    print(
"""Usage: ./orno_modbus.py serial_port device_address target_device_address
Example: ./orno_modbus.py /dev/ttyUSB0 1 11

If you have only one device you can set the device_address to 0 to change its address.
""")
    sys.exit(0)

  port = sys.argv[1]
  address = int(sys.argv[2])
  target_address = int(sys.argv[3])

  client = ModbusClient(method="rtu", port=port, baudrate=9600)
  client.connect()

  request = SendOrnoPassword('00000000', unit=address)
  client.execute(request)

  response = client.write_registers(15, [target_address], unit=address)
  if response:
    if address:
      print "Success. Changed address from %d to %d." % (address, target_address)
    else:
      print "Success. Changed address to %d." % (target_address)
  else:
    print "Address change failed"

  client.close()
Ejemplo n.º 13
0
def run_sync_client():

    clearScreen()

    print("Enter 1 to take reading, 0 to quit")

    running = True

    while running == True:
        client = ModbusClient(method='rtu',
                              port='/dev/ttyUSB0',
                              timeout=1,
                              baudrate=9600)
        client.connect()
        hr = client.read_holding_registers(7, 3, unit=SLAVE)

        value = input(":")

        if value == 0:
            running = False
        else:
            temperature = hr.registers[0] / 10.0
            humidity = hr.registers[1] / 10.0
            dewpoint = hr.registers[2] / 10.0
            print("Temperature : " + str(temperature))
            print("Humidity : " + str(humidity))
            print("Dew Point : " + str(dewpoint))

    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
Ejemplo n.º 14
0
def main():
    if len(sys.argv) != 4:
        print(
            """Usage: ./orno_modbus.py serial_port device_address target_device_address
Example: ./orno_modbus.py /dev/ttyUSB0 1 11

If you have only one device you can set the device_address to 0 to change its address.
""")
        sys.exit(0)

    port = sys.argv[1]
    address = int(sys.argv[2])
    target_address = int(sys.argv[3])

    client = ModbusClient(method="rtu", port=port, baudrate=9600)
    client.connect()

    request = SendOrnoPassword('00000000', unit=address)
    client.execute(request)

    response = client.write_registers(15, [target_address], unit=address)
    if response:
        if address:
            print "Success. Changed address from %d to %d." % (address,
                                                               target_address)
        else:
            print "Success. Changed address to %d." % (target_address)
    else:
        print "Address change failed"

    client.close()
Ejemplo n.º 15
0
    def testBasicSyncSerialClient(self, mock_serial):
        ''' Test the basic methods for the serial sync client'''

        # receive/send
        mock_serial.in_waiting = 0
        mock_serial.write = lambda x: len(x)

        mock_serial.read = lambda size: b'\x00' * size
        client = ModbusSerialClient()
        client.socket = mock_serial
        client.state = 0
        self.assertEqual(0, client._send(None))
        client.state = 0
        self.assertEqual(1, client._send(b'\x00'))
        self.assertEqual(b'\x00', client._recv(1))

        # connect/disconnect
        self.assertTrue(client.connect())
        client.close()

        # already closed socket
        client.socket = False
        client.close()

        self.assertEqual('ModbusSerialClient(ascii baud[19200])', str(client))
Ejemplo n.º 16
0
def run_sync_client():

    iteration_counter = 0
    success_counter = 0
    fail_counter = 0
    client = ModbusClient(method='rtu',
                          port='/dev/ttyUSB0',
                          timeout=1,
                          baudrate=115200)
    client.connect()
    while (iteration_counter < 10000):

        time.sleep(2)
        try:

            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)

            time.sleep(0.5)  # 이것을 넣지 않으면 에러가 뿜뿜. --> 마찬가지...
            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

            # 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
        except AssertionError:
            print('ASSERT ERROR')
            fail_counter += 1
        except pymodbus.exceptions.ModbusIOException:
            print('REGISTER ERROR')
            fail_counter += 1
        else:
            success_counter += 1

        iteration_counter += 1
        print('iteration # : ', iteration_counter, ' success : ',
              success_counter, ' fail : ', fail_counter, ' rate : ',
              float(success_counter / iteration_counter) * 100, '%')

    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
Ejemplo n.º 17
0
    def onHeartbeat(self):
        Domoticz.Log("onHeartbeat called")
       
        # Wich serial port settings to use?
        if (Parameters["Mode3"] == "S1B7PN"): StopBits, ByteSize, Parity = 1, 7, "N"
        if (Parameters["Mode3"] == "S1B7PE"): StopBits, ByteSize, Parity = 1, 7, "E"
        if (Parameters["Mode3"] == "S1B7PO"): StopBits, ByteSize, Parity = 1, 7, "O"
        if (Parameters["Mode3"] == "S1B8PN"): StopBits, ByteSize, Parity = 1, 8, "N"
        if (Parameters["Mode3"] == "S1B8PE"): StopBits, ByteSize, Parity = 1, 8, "E"
        if (Parameters["Mode3"] == "S1B8PO"): StopBits, ByteSize, Parity = 1, 8, "O"
        if (Parameters["Mode3"] == "S2B7PN"): StopBits, ByteSize, Parity = 2, 7, "N"
        if (Parameters["Mode3"] == "S2B7PE"): StopBits, ByteSize, Parity = 2, 7, "E"
        if (Parameters["Mode3"] == "S2B7PO"): StopBits, ByteSize, Parity = 2, 7, "O"
        if (Parameters["Mode3"] == "S2B8PN"): StopBits, ByteSize, Parity = 2, 8, "N"
        if (Parameters["Mode3"] == "S2B8PE"): StopBits, ByteSize, Parity = 2, 8, "E"
        if (Parameters["Mode3"] == "S2B8PO"): StopBits, ByteSize, Parity = 2, 8, "O"

        ###################################
        # pymodbus: RTU / ASCII
        ###################################
        if (Parameters["Mode1"] == "rtu" or Parameters["Mode1"] == "ascii"):
            Domoticz.Debug("MODBUS DEBUG USB SERIAL HW - Port="+Parameters["SerialPort"]+", BaudRate="+Parameters["Mode2"]+", StopBits="+str(StopBits)+", ByteSize="+str(ByteSize)+" Parity="+Parity)
            Domoticz.Debug("MODBUS DEBUG USB SERIAL CMD - Method="+Parameters["Mode1"])
            try:
                client = ModbusSerialClient(method=Parameters["Mode1"], port=Parameters["SerialPort"], stopbits=StopBits, bytesize=ByteSize, parity=Parity, baudrate=int(Parameters["Mode2"]), timeout=1, retries=2)
            except:
                Domoticz.Log("Error opening Serial interface on "+Parameters["SerialPort"])
                #Devices[1].Update(0, "0") # Update device in Domoticz

        ###################################
        # pymodbus: RTU over TCP
        ###################################
        if (Parameters["Mode1"] == "rtutcp"):
          Domoticz.Debug("MODBUS DEBUG TCP CMD - Method="+Parameters["Mode1"])
          try:
            client = ModbusTcpClient(host=UnitAddress, port=int(Parameters["Port"]), framer=ModbusRtuFramer, auto_open=True, auto_close=True, timeout=5)
          except:
            Domoticz.Log("Error opening TCP interface on address: "+UnitAddress)
            #Devices[1].Update(0, "0") # Update device in Domoticz

        ###################################
        # pymodbusTCP: TCP/IP
        ###################################
        if (Parameters["Mode1"] == "tcpip"):
          Domoticz.Debug("MODBUS DEBUG TCP CMD - Method="+Parameters["Mode1"]+", Address="+UnitAddress+", Port="+Parameters["Port"]+", Unit ID="+self.UnitIdForIp+", Register="+Parameters["Password"]+", Data type="+Parameters["Mode6"])
          try:
            client = ModbusClient(host=UnitAddress, port=int(Parameters["Port"]), unit_id=self.UnitIdForIp, auto_open=True, auto_close=True, timeout=5)
          except:
            Domoticz.Log("Error opening TCP/IP interface on address: "+UnitAddress)
            #Devices[1].Update(0, "0") # Update device in Domoticz
        try:
            #Domoticz.Log("Before update. Number of devices:"+str(len(Devices)))
            for i in reg:
                i.update(client,Domoticz)
            #Domoticz.Log("After update")
        except Exception as e:
            Domoticz.Log("Error calling update "+repr(e))
           
        client.close()
Ejemplo n.º 18
0
def main(args):
    global PUMP_TIME
    global SENSOR_TIME
    co2Runtotal = []
    tempRuntotal = []
    rhRuntotal = []

    try:
        PUMP_TIME = int(args[1])
        SENSOR_TIME = int(args[2])
        print('using custom args. pump time: %d sensor time: %d' % (PUMP_TIME, SENSOR_TIME))
    except:
        PUMP_TIME = 600
        SENSOR_TIME = 300
        print('using default args. pump time: %d sensor time: %d' % (PUMP_TIME, SENSOR_TIME))

    if not os.path.isfile(DATAFILE_PATH):
        file = open(DATAFILE, "w")
        file.write('"TIMESTAMP","CO2","TEMPERATURE","HUMIDITY"\n"UTC","PPM","DEG_C","RH"\n')
        file.close()

    startMeasurement()

    # Connect to sensor and record data
    try:
        client = ModbusClient(method = "rtu", port="/dev/ttyS0",stopbits = 1, bytesize = 8, parity = 'N', baudrate= 9600)
        # Connect to the serial modbus server
        connection = client.connect()
        if connection:
            for x in range(0, PUMP_TIME, 30): #take a measurement every 30 secs until the pump and sensor time is over
                outputList = (recordData(client)) #return the co2, temp and rh data after every call and append it to list variables
                co2Runtotal.append(outputList[0])
                tempRuntotal.append(outputList[1])
                rhRuntotal.append(outputList[2])
                time.sleep(30)

            writeMean(co2Runtotal, tempRuntotal, rhRuntotal)
            endPump()

            co2Runtotal = []
            tempRuntotal = []
            rhRuntotal = []

            for x in range(0, SENSOR_TIME, 30):
                outputList = (recordData(client))
                co2Runtotal.append(outputList[0])
                tempRuntotal.append(outputList[1])
                rhRuntotal.append(outputList[2])
                time.sleep(30)

            writeMean(co2Runtotal, tempRuntotal, rhRuntotal)
        # Closes the underlying socket connection
        client.close()

    except Exception as error:
        print('CO2 measurement failed: ' + repr(error))
    finally:
        endMeasurement()
Ejemplo n.º 19
0
class communication:
    def __init__(self):
        self.client = None

    def connectToDevice(self, device):
        """Connection to the client - the method takes the IP address (as a string, e.g. '192.168.1.11') as an argument."""
        self.client = ModbusSerialClient(method='rtu',
                                         port=device,
                                         stopbits=1,
                                         bytesize=8,
                                         baudrate=115200,
                                         timeout=0.2)
        if not self.client.connect():
            print "Unable to connect to %s" % device
            return False
        #print "It connected"
        return True

    def disconnectFromDevice(self):
        """Close connection"""
        self.client.close()

    def sendCommand(self, data):
        """Send a command to the Gripper - the method takes a list of uint8 as an argument. The meaning of each variable depends on the Gripper model (see support.robotiq.com for more details)"""
        #make sure data has an even number of elements
        if (len(data) % 2 == 1):
            data.append(0)

        #Initiate message as an empty list
        message = []

        #Fill message by combining two bytes in one register
        for i in range(0, len(data) / 2):
            message.append((data[2 * i] << 8) + data[2 * i + 1])

        #To do!: Implement try/except
        self.client.write_registers(0x03E8, message, unit=0x0009)

    def getStatus(self, numBytes):
        """Sends a request to read, wait for the response and returns the Gripper status. The method gets the number of bytes to read as an argument"""
        numRegs = int(ceil(numBytes / 2.0))

        #To do!: Implement try/except
        #Get status from the device
        response = self.client.read_holding_registers(0x07D0,
                                                      numRegs,
                                                      unit=0x0009)

        #Instantiate output as an empty list
        output = []

        #Fill the output with the bytes in the appropriate order
        for i in range(0, numRegs):
            output.append((response.getRegister(i) & 0xFF00) >> 8)
            output.append(response.getRegister(i) & 0x00FF)

        #Output the result
        return output
Ejemplo n.º 20
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/cu.wchusbserial14310', 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("Write to a holding register and read back")
    rr = client.read_holding_registers(0, 8, unit=UNIT)
    print(rr.registers)    # test the expected value


    client.close()
Ejemplo n.º 21
0
def write_modbus_rtu(id=1, addr=10, value=1, unit=0x01):
    client = ModbusClient(method="rtu", port="/dev/tty.usbserial-AK066TL5", stopbits = 1, bytesize = 8, parity='N', baudrate = 9600)
    connection = client.connect()
    if(connection is not True): print('ModbusClient connection error')

    rq=client.write_register(1, 10, unit=UNIT)
    assert(not rq.isError())

    client.close()    
Ejemplo n.º 22
0
def connect(ad1, comport):
    client = ModbusSerialClient(method='rtu',
                                port=comport,
                                baudrate=9600,
                                timeout=3,
                                parity='N',
                                stopbits=1,
                                bytesize=8)

    if client.connect():
        #ad1=int(input("address1: ")) # Address input normal
        register = int(ad1)

        try:
            result1 = client.read_input_registers(address=register - 1,
                                                  count=1,
                                                  unit=1)  #Uint32/1
            result2 = client.read_input_registers(address=register,
                                                  count=1,
                                                  unit=1)  #Uint32/2
            r = result2.registers + result1.registers  #[Uint32/2, Uint32/1]
        except AttributeError:
            connect(ad1, comport)
        try:

            try:
                b = struct.pack('HH', r[0], r[1])
                ans = struct.unpack('f', b)[0]
                ans = '%.2f' % ans
                allans = ans
                print('Ans: ', allans)
                client.close()
                return allans
            except UnboundLocalError:
                print(
                    "!!!!!!!!!!!!!!!!!!!!!!!!!!!UnboundLocalError!!!!!!!!!!!!!!!!!!!!!!!!!!"
                )
                connect(ad1, comport)
        except:
            messagebox.askretrycancel(
                "Message", "Cannot connect to the Modbus Server/Slave")
            print(
                "!!!!!!!!!!!!!!!!!!!!!!!!!!!Cannot connect to the Modbus Server/Slave!!!!!!!!!!!!!!!!!!!!!!!!!!"
            )
            connect(ad1, comport)
            raise

    else:

        print('Cannot connect to the Modbus Server/Slave')
        tryy = messagebox.askretrycancel("Message",
                                         "Please Check USB Cable or USB port")
        if (tryy):
            connect(ad1, comport)
Ejemplo n.º 23
0
def read_modbus_rtu():

    client = ModbusClient(method="rtu", port="/dev/tty.usbserial-AK066TL5", stopbits = 1, bytesize = 8, parity='N', baudrate = 9600)
    connection = client.connect()
    if(connection is not True): print('ModbusClient connection error')

    rr = client.read_holding_registers(address=1, count=1, unit=UNIT)
    # assert(not rr.isError())
    print(rr)

    client.close()    
Ejemplo n.º 24
0
def write_data_rs485(configuration, device):
    client= ModbusClient(method = "rtu", port="/dev/ttyUSB0",stopbits = 1, bytesize = 8, parity = 'E',baudrate= 9600)
    #Connect to the serial modbus server
    connection = client.connect()
    print(connection)
    #Starting add, num of reg to read, slave unit.
    #result= client.read_holding_registers(0x00,2,unit= 0xff)
    #print(result)
    client.write_register(0x00,"1")
    #Closes the underlying socket connection
    client.close()
Ejemplo n.º 25
0
def run_sync_client():
    #enabling modbus communication
    client = ModbusClient(method='rtu',
                          port=MODBUS_DEVICE,
                          timeout=MODBUS_TIMEOUT,
                          baudrate=MODBUS_BAUDRATE)
    client.connect()

    MyBoiler.registers = []
    id_stop = -1

    for mbrange in cfg['modbus']['register_ranges']:
        id_start = mbrange[0]
        MyBoiler.registers.extend([None] * (id_start - id_stop - 1))
        id_stop = mbrange[1]

        for i in range(MODBUS_RETRIES):
            log.debug("Attempt {} to read registers from {} to {}".format(
                i, id_start, id_stop))
            rr = client.read_holding_registers(count=(id_stop - id_start + 1),
                                               address=id_start,
                                               unit=MODBUS_UNIT)
            if rr.isError():
                log.error(rr.message)
                MyBoiler.registers.extend([None] * (id_stop - id_start + 1))
            else:
                MyBoiler.registers.extend(rr.registers)
                break
    client.close()

    #parsing registers to push data in Object attributes
    MyBoiler.browse_registers()
    log.info("Dumping values\n" + MyBoiler.dump())

    #pushing data to influxdb
    if args.backend and args.backend == 'influxdb':
        timestamp = int(time.time() * 1000)  #milliseconds
        influx_json_body = [{
            "measurement": "diematic",
            "tags": {
                "host": "raspberrypi",
            },
            "timestamp": timestamp,
            "fields": MyBoiler.fetch_data()
        }]

        influx_client = InfluxDBClient(cfg['influxdb']['host'],
                                       cfg['influxdb']['port'],
                                       cfg['influxdb']['user'],
                                       cfg['influxdb']['password'],
                                       cfg['influxdb']['database'])

        log.debug("Write points: {0}".format(influx_json_body))
        influx_client.write_points(influx_json_body, time_precision='ms')
Ejemplo n.º 26
0
def write_via_rtu_modbus(state):
    client = ModbusSerialClient(method='rtu',
                                port=PORT,
                                timeout=1,
                                baudrate=460800)
    log.debug("Writing Coils")
    rq = client.write_coil(1, state, unit=UNIT)
    log.debug(rq)
    log.debug("Reading Coils")
    rr = client.read_coils(1, 1, unit=UNIT)
    log.debug(rr)
    client.close()
Ejemplo n.º 27
0
class communication:	

   def __init__(self):
      self.client = None
      
   def connectToDevice(self, device):
      """Connection to the client - the method takes the IP address (as a string, e.g. '192.168.1.11') as an argument."""
      self.client = ModbusSerialClient(method='rtu',port=device,stopbits=1, bytesize=8, baudrate=115200, timeout=0.2)
      if not self.client.connect():
          print "Unable to connect to %s" % device
          return False
      return True

   def disconnectFromDevice(self):
      """Close connection"""
      self.client.close()

   def sendCommand(self, data):   
      """Send a command to the Gripper - the method takes a list of uint8 as an argument. The meaning of each variable depends on the Gripper model (see support.robotiq.com for more details)"""
      #make sure data has an even number of elements   
      if(len(data) % 2 == 1):
         data.append(0)

      #Initiate message as an empty list
      message = []

      #Fill message by combining two bytes in one register
      for i in range(0, len(data)/2):
         message.append((data[2*i] << 8) + data[2*i+1])

      #To do!: Implement try/except 
      self.client.write_registers(0x03E8, message, unit=0x0009)

   def getStatus(self, numBytes):
      """Sends a request to read, wait for the response and returns the Gripper status. The method gets the number of bytes to read as an argument"""
      numRegs = int(ceil(numBytes/2.0))

      #To do!: Implement try/except 
      #Get status from the device
      response = self.client.read_holding_registers(0x07D0, numRegs, unit=0x0009)

      #Instantiate output as an empty list
      output = []

      #Fill the output with the bytes in the appropriate order
      for i in range(0, numRegs):
         output.append((response.getRegister(i) & 0xFF00) >> 8)
         output.append( response.getRegister(i) & 0x00FF)
      
      #Output the result
      return output
Ejemplo n.º 28
0
def change_station_id(modbusid, serialport, id_setting, current_baudrate):
    instrument = ModbusSerialClient(method='rtu',
                                    port=serialport,
                                    baudrate=current_baudrate)

    builder = BinaryPayloadBuilder(byteorder=Endian.Big)

    builder.add_16bit_int(id_setting)
    payload = builder.build()

    pld = payload[0][1] | (payload[0][0] << 8)

    instrument.connect()
    instrument.write_register(1000, pld, unit=modbusid, timeout=.1)
    instrument.close()
Ejemplo n.º 29
0
class EPsolarTracerClient:
    ''' EPsolar Tracer client
    '''

    def __init__(self, unit = 1, serialclient = None, **kwargs):
        ''' Initialize a serial client instance
        '''
        self.unit = unit
        if serialclient == None:
            port = kwargs.get('port', '/dev/ttyXRUSB0')
            baudrate = kwargs.get('baudrate', 115200)
            self.client = ModbusClient(method = 'rtu', port = port, baudrate = baudrate, kwargs = kwargs)
        else:
            self.client = serialclient

    def connect(self):
        ''' Connect to the serial
        :returns: True if connection succeeded, False otherwise
        '''
        return self.client.connect()

    def close(self):
        ''' Closes the underlying connection
        '''
        return self.client.close()

    def read_device_info(self):
        request = ReadDeviceInformationRequest (unit = self.unit)
        response = self.client.execute(request)
        return response

    def read_input(self, name):
        register = registerByName(name)
        if register.is_coil():
            response = self.client.read_coils(register.address, register.size, unit = self.unit)
        elif register.is_discrete_input():
            response = self.client.read_discrete_inputs(register.address, register.size, unit = self.unit)
        elif register.is_input_register():
            response = self.client.read_input_registers(register.address, register.size, unit = self.unit)
        else:
            response = self.client.read_holding_registers(register.address, register.size, unit = self.unit)
        return register.decode(response)

    def write_output(self, name, value):
        register = registerByName(name)
        values = register.encode(value)
        response = False
        if register.is_coil():
            self.client.write_coil(register.address, values, unit = self.unit)
            response = True
        elif register.is_discrete_input():
            _logger.error("Cannot write discrete input " + repr(name))
            pass
        elif register.is_input_register():
            _logger.error("Cannot write input register " + repr(name))
            pass
        else:
            self.client.write_registers(register.address, values, unit = self.unit)
            response = True
        return response
Ejemplo n.º 30
0
class Torqueforce(crappy.inout.InOut):
  def __init__(self,port='/dev/ttyUSB0',baudrate=115200):
    self.port = port
    self.baudrate = baudrate
    self.m = ModbusSerialClient('rtu',port=self.port,baudrate=self.baudrate,
        parity='E')

  def open(self):
    self.m.connect()

  def get_data(self):
    l = self.m.read_holding_registers(32,4,unit=1).registers
    return [time(),tofloat(l[:2]),tofloat(l[2:])]

  def close(self):
    self.m.close()
Ejemplo n.º 31
0
def looo_read_modbus_rtu_message():

    client = ModbusClient(method="rtu", port="/dev/tty.usbserial-AK066TL5", stopbits = 1, bytesize = 8, parity='N', baudrate = 9600)
    connection = client.connect()
    if(connection is not True): print('ModbusClient connection error')

    while True:
        try:
            rr = client.read_input_registers(address=1, count=1, unit=1)
            break
        except ValueError:
            print('{} has some error'.format(rr))
        else:
            print('Error: ', type(rr))

    client.close()       
Ejemplo n.º 32
0
def write_register(reg_add, val, mod_adress):
    try:
        client = ModbusClient(method='rtu',
                              port=com,
                              baudrate=2400,
                              stopbits=1,
                              parity='N',
                              bytesize=8,
                              timeout=3)
        client.connect()
        time.sleep(0.3)
        client.write_register(reg_add, val, unit=mod_adress)
        client.close()
    except AttributeError:
        print('Połaczenie z adresem {} nie udane'.format(mod_adress))
    return print('Nowa wartosc zapisana')
Ejemplo n.º 33
0
def main():
    try:
        modbus = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=9600, timeout=1, parity='E', bytesize=8)
        modbus.connect()
        voltage = validator(modbus.read_holding_registers(3910, 2, unit=1))
        current = validator(modbus.read_holding_registers(3928, 2, unit=1))
        factor = validator(modbus.read_holding_registers(3922, 2, unit=1))
        freq = validator(modbus.read_holding_registers(3914, 2, unit=1))
        print("Voltage: {} V".format(round(voltage, 2)))
        print("Current: {} A".format(current))
        print("Factor: {}".format(factor))
        print("Frequency: {} Hz".format(freq))
        modbus.close()
        return voltage, current, factor, freq
    except AttributeError as e:
        print(e)
        return None
Ejemplo n.º 34
0
def modbus_session():
    modbus = ModbusSerialClient(
        method=cfg.modbus.method,
        baudrate=cfg.modbus.baudr,
        parity=cfg.modbus.parity,
        port=cfg.modbus.portname,
        timeout=cfg.modbus.timeout
    )
    try:
        modbus.connect()
    except (OSError, ModbusException, serial.SerialException) as e:
        logger.error("Unable connect to the boiler via modbus: {}".format(e))
        raise
    else:
        yield modbus
    finally:
        modbus.close()
Ejemplo n.º 35
0
def read_data_rs485_holding():
    client = ModbusClient(method="rtu",
                          port="/dev/ttyUSB0",
                          stopbits=1,
                          bytesize=8,
                          parity='N',
                          baudrate=9600)
    #Connect to the serial modbus server
    connection = client.connect()
    print(connection)
    #Starting add, num of reg to read, slave unit.
    result = client.read_holding_registers(0x17, 2, unit=1)
    print(result)
    #Closes the underlying socket connection
    client.close()
    print(result.registers[0] * 0.001)
    return result.registers[0]
Ejemplo n.º 36
0
class SynchronousRtuClient(Runner, unittest.TestCase):
    """
    These are the integration tests for the synchronous
    serial rtu client.
    """

    def setUp(self):
        """ Initializes the test environment """
        super(Runner, self).setUp()
        self.initialize(["../tools/reference/diagslave", "-m", "rtu", "/dev/pts/14"])
        self.client = ModbusClient(method='rtu', timeout=0.2, port='/dev/pts/13')
        self.client.connect()

    def tearDown(self):
        """ Cleans up the test environment """
        self.client.close()
        super(Runner, self).tearDown()
Ejemplo n.º 37
0
    def read_holding(self,reg_start, reg_lenght, mod_adress):





        try:
            client = ModbusClient(method='rtu', port=com, baudrate=2400, stopbits=1, parity='N', bytesize=8, timeout=3)
            connection = client.connect()
            time.sleep(0.3)
            massure = client.read_holding_registers(reg_start - 1, reg_lenght, unit=mod_adress)
            print('Rejestry :', massure.registers[0:])
            # print(connection)
            client.close()
            return connection, massure.registers
        except AttributeError:
            print('Połaczenie z adresem {} nie udane'.format(mod_adress))
Ejemplo n.º 38
0
class Worker(QtCore.QObject):
    """opc-сервер"""
    finished = QtCore.pyqtSignal()

    def __init__(self,
                 port: str = '',
                 baud: int = 9600,
                 timeout: float = 0.05,
                 parent=None):
        super().__init__(parent)
        self.running = False
        self.name = port
        try:
            self.port = Client(method='rtu',
                               port=port,
                               timeout=timeout,
                               baudrate=baud,
                               retry_on_empty=True,
                               retries=5,
                               strict=False)
            print(
                f'Порт {self.name} baud = {baud} таймаут {timeout*1000:.0f} мс'
            )
        except Exception as exc:
            print(exc)

        self.dev = []

    def run(self):
        if self.port.connect():
            print(f'Открыт порт {self.name}')
            self.running = True
        else:
            print(f'Порт {self.name} не удалось открыть')

        while self.running:
            for dev in self.dev:
                # if self.thread() == dev.thread(): print(self.thread(), dev.thread(), dev)
                dev.update()
                self.thread().msleep(2)
                if not self.running:
                    break
        self.port.close()
        print('Остановлен сервер {}'.format(self.name))
        self.finished.emit()
Ejemplo n.º 39
0
class SynchronousAsciiClient(Runner, unittest.TestCase):
    '''
    These are the integration tests for the synchronous
    serial ascii client.
    '''

    def setUp(self):
        ''' Initializes the test environment '''
        super(Runner, self).setUp()
        #    "../tools/nullmodem/linux/run",
        self.initialize(["../tools/reference/diagslave", "-m", "ascii", "/dev/pts/14"])
        self.client = ModbusClient(method='ascii', timeout=0.2, port='/dev/pts/13')
        self.client.connect()

    def tearDown(self):
        ''' Cleans up the test environment '''
        self.client.close()
        super(Runner, self).tearDown()
Ejemplo n.º 40
0
    def testBasicSyncSerialClient(self):
        ''' Test the basic methods for the serial sync client'''

        # receive/send
        client = ModbusSerialClient()
        client.socket = mockSocket()
        self.assertEqual(0, client._send(None))
        self.assertEqual(1, client._send('\x00'))
        self.assertEqual('\x00', client._recv(1))

        # connect/disconnect
        self.assertTrue(client.connect())
        client.close()

        # already closed socket
        client.socket = False
        client.close()

        self.assertEqual('ascii baud[19200]', str(client))
Ejemplo n.º 41
0
def run_motor_gui_standalone():

    client = ModbusClient(method="rtu", port="/dev/ttyUSB0", stopbits=1, \
        bytesize=8, parity='E', baudrate=9600, timeout=0.1)
    
    # connect to the serial modbus server
    connection = client.connect()
    print("Connection = " + str(connection))
    # Create and set up the GUI object
    root = Tk()
    root.title("WIFIS Motor Controller")
    root.geometry("275x375")
    #root.protocol("WM_DELETE_WINDOW", on_closing)

    app = MainApplication(root,client)

    root.mainloop()

    # closes the underlying socket connection
    client.close()
Ejemplo n.º 42
0
class TristarPWM(object):
    """ tristar pwm ts45 or ts60 for data logging,
    it can read the holding/input register and save to csv file
    """

    def __init__(self, method, port, baudrate, stopbits, parity, timeout,
                 DT=10, COUNT=6,
                 debug_flag=True, log_flag=True, thingspeak_flag=True):
        self.method = method
        self.port = port
        self.baudrate = baudrate
        self.stopbits = stopbits
        self.parity = parity
        self.timeout = timeout
        self.DT = DT
        self.COUNT = COUNT
        self.debug_flag = debug_flag
        self.log_flag = log_flag
        self.thingspeak_flag = thingspeak_flag
        self.register_dict={}

    def connect(self):
        """ connect to modbus client """
        try:
            self.client = ModbusClient(method=self.method,
                                  port=self.port,
                                  baudrate=self.baudrate,
                                  stopbits=self.stopbits,
                                  parity=self.parity,
                                  timeout=self.timeout)
            self.client.connect()
            print "connected"
        except KeyboardInterrupt:
            self.client.close()

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

    def read_registers(self):
        """ read holding registers """
        # read the registers from logical address 0 to 0x1e.
        response = self.client.read_holding_registers(0x00, 0x1e, unit=1)
        # the stuff we want
        batt_V = (response.registers[adc_vb_f] * v_scale) / (2**15)
        batt_sens_V = (response.registers[adc_vs_f] * v_scale) / (2**15)
        array_V = (response.registers[adc_vx_f] * array_scale) / (2**15)
        charge_I = (response.registers[adc_ipv_f] * i_scale) / (2**15)
        load_I = (response.registers[adc_iload_f] * iload_scale) / (2**15)
        batt_V_slow = (response.registers[vb_f] * v_scale) / (2**15)
        heatsink_T = response.registers[t_hs]
        batt_T = response.registers[t_batt]
        reference_V = (response.registers[v_ref] * v_scale) / (2**15)
        ah_reset = (response.registers[ah_r_hi]<<8 + \
        response.registers[ah_r_lo] ) * ah_scale
        ah_total = (response.registers[ah_t_hi]<<8 + \
        response.registers[ah_t_lo] ) * ah_scale
        hourmeter = response.registers[hourmeter_hi]<<8 + \
        response.registers[hourmeter_lo]
        alarm_bits = response.registers[alarm_hi]<<8 + \
        response.registers[alarm_lo]
        fault_bits = response.registers[fault]
        dip_num = response.registers[dip_switch]
        mode_num = response.registers[control_mode]
        state_num = response.registers[control_state]
        pwm_duty = response.registers[d_filt] /230.0

        if pwm_duty > 1:
            pwm_duty = 100.0  # p. 13 0: 0%, >=230: 100%
        else:
            pwm_duty *= 100.0 # convert to percentage

        powerIn = batt_V * charge_I

        mode = control_mode_turple[mode_num]
        if mode_num == 0 or mode_num ==2:  # charge of diversion
            state = charge_div_state_turple[state_num]
        else:  # load and lighting mode
            state = load_light_state_turple[state_num]

        return {"batt_V":batt_V,"batt_sens_V":batt_sens_V,
                "array_V":array_V,"charge_I":charge_I,"load_I":load_I,
                "batt_V_slow":batt_V_slow,"heatsink_T":heatsink_T,
                "batt_T":batt_T,"reference_V":reference_V,
                "ah_reset":ah_reset,"ah_total":ah_total,
                "hourmeter":hourmeter,"alarm_bits":alarm_bits,
                "fault_bits":fault_bits,"dip_num":dip_num,
                "mode_num":mode_num,"state_num":state_num,
                "pwm_duty":pwm_duty,"powerIn":powerIn,
                "mode":mode,"state":state}

    def read_modbus(self):
        """read output from modbus,
        save them into a list"""
        assert(self.client is not None), "client not connected"
        counter = 1
        # initialize list
        batt_V_list = []
        batt_sens_V_list = []
        array_V_list = []
        charge_I_list = []
        load_I_list = []
        batt_V_slow_list = []
        heatsink_T_list = []
        batt_T_list = []
        pwm_duty_list = []
        powerIn_list = []

        while counter <= self.COUNT:
            try:
                self.register_dict = self.read_registers()
            except KeyboardInterrupt:
                print "interrupted"
                break
            except:
                print "port not available"
                continue

            # debug
            if self.debug_flag:
                print self.register_dict.items()
                # for key in register_dict:
                #     print key
                #     print register_dict[key]

            # calculate average
            batt_V_list.append(self.register_dict["batt_V"])
            batt_sens_V_list.append(self.register_dict["batt_sens_V"])
            array_V_list.append(self.register_dict["array_V"])
            charge_I_list.append(self.register_dict["charge_I"])
            load_I_list.append(self.register_dict["load_I"])
            batt_V_slow_list.append(self.register_dict["batt_V_slow"])
            heatsink_T_list.append(self.register_dict["heatsink_T"])
            batt_T_list.append(self.register_dict["batt_T"])
            pwm_duty_list.append(self.register_dict["pwm_duty"])
            powerIn_list.append(self.register_dict["powerIn"])

            # return value
            counter += 1
            time.sleep(self.DT)
        else:
            # add time point
            tid = time.strftime("%Y/%m/%d %H:%M:%S")
            self.register_dict["tid"] = str(tid)
            # calculate average
            self.register_dict["batt_V"] = mean(batt_V_list)
            self.register_dict["array_V"] = mean(array_V_list)
            self.register_dict["charge_I"] = mean(charge_I_list)
            self.register_dict["pwm_duty"] = mean(pwm_duty_list)
            self.register_dict["heatsinke_T"] = mean(heatsink_T_list)
            self.register_dict["powerIn"] = mean(powerIn_list)

    def write_thingspeak(self, field_id, field_var_name):
        """ write certain fields to thingspeak, while loop """
        if self.thingspeak_flag:
            channel = thingspeak.channel()
            try:
                while True:
                    # register_dict = self.read_modbus()
                    self.read_modbus()
                    field_var = [self.register_dict[i] for i in field_var_name]
                    channel.update(field_id, field_var)
            except KeyboardInterrupt:
                self.close()
        else:
            pass

    def write_thingspeak_oneshot(self, field_id, field_var_name):
        """ write certain fields to thingspeak, no loop """
        if self.thingspeak_flag:
            channel = thingspeak.channel()
            self.read_modbus()
            field_var = [self.register_dict[i] for i in field_var_name]
            channel.update(field_id, field_var)
        else:
            pass

    def log_data(self, field_var_name, filename, tid=None):
        """ log data into a file
        Changelog 20160308: insert external tid for data to have same tid
        """
        if self.log_flag:
            filename_new = filename + time.strftime("%Y%m%d") + '.csv'
            if not os.path.isfile(filename_new):  # write new file with header
                # create new file
                os.mknod(filename_new)
                # chmod
                os.chmod(filename_new, 0o755)
                fil = open(filename_new, 'w+')
                # write header
                # select items to write
                header = ",".join(field_var_name)
                fil.write(header+"\n")
            else:  # append
                if not os.access(filename_new, os.W_OK):
                    # chmod
                    os.chmod(filename_new, 0o755)
                else:
                    fil = open(filename_new, 'a+')

            # pass register_dict to file write
            # check if have external tid
            if tid is not None:
                self.register_dict['tid'] = str(tid)
            field_var = [str(self.register_dict[i]) for i in field_var_name]
            output_text = ",".join(field_var)
            # print output_text
            fil.write(output_text+"\n")
            fil.close()
        else:  # no log
            pass
Ejemplo n.º 43
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/ttyS3', baudrate=9600, timeout=1)
    client.connect()
    
    # ----------------------------------------------------------------------- #
    # 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).
    # ----------------------------------------------------------------------- #

    # 读模块型号
    rr = client.read_holding_registers(40001, 1, unit=UNIT)
    print(rr.registers[0])
    
    # 读两路输入(寄存器地址200,共2个)
    log.debug("Read discrete inputs")
    rr = client.read_discrete_inputs(200, 2, unit=UNIT)
    print(rr.bits)  # bit0表示DI1的状态,bit1表示DI2

    # 写单个输出DO1(寄存器地址100)
    log.debug("Write to a Coil and read back")
    rq = client.write_coil(100, True, unit=UNIT)
    rr = client.read_coils(100, 1, unit=UNIT)
    assert(rq.function_code < 0x80)     # test that we are not an error
    assert(rr.bits[0] == True)          # test the expected value
    
    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
Ejemplo n.º 44
0
class SunSaverMPPT(object):
    """ sunsaver mppt 15 for data logging,
    it can read the holding/input register and save to csv file
    """

    def __init__(self, method, port, baudrate, stopbits, parity, timeout,
                 DT=10, COUNT=6,
                 debug_flag=True, log_flag=True, thingspeak_flag=True):
        self.method = method
        self.port = port
        self.baudrate = baudrate
        self.stopbits = stopbits
        self.parity = parity
        self.timeout = timeout
        self.DT = DT
        self.COUNT = COUNT
        self.debug_flag = debug_flag
        self.log_flag = log_flag
        self.thingspeak_flag = thingspeak_flag

    def connect(self):
        """ connect to modbus client """
        try:
            self.client = ModbusClient(method=self.method,
                                  port=self.port,
                                  baudrate=self.baudrate,
                                  stopbits=self.stopbits,
                                  parity=self.parity,
                                  timeout=self.timeout)
            self.client.connect()
        except KeyboardInterrupt:
            self.client.close()

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

    def read_registers(self):
        """ read holding registers """
        # read the registers from logical address 0 to 0x1e.
        response = self.client.read_holding_registers(0x00, 0x3e, unit=1)
        # the stuff we want
        batt_V = (response.registers[Adc_vb_f] * v_scale) / (2**15)
        array_V = (response.registers[Adc_va_f] * v_scale) / (2**15)
        load_V = (response.registers[Adc_vl_f] * v_scale) / (2**15)
        charge_I = (response.registers[Adc_ic_f] * i_scale) / (2**15)
        load_I = (response.registers[Adc_il_f] * i_scale) / (2**15)
        batt_V_slow = (response.registers[Vb_f] * v_scale) / (2**15)
        heatsink_T = response.registers[t_hs]
        ah_reset = (response.registers[Ahc_r_HI]<<8 + \
        response.registers[Ahc_r_LO] ) * ah_scale
        ah_total = (response.registers[Ahc_t_HI]<<8 + \
        response.registers[Ahc_t_LO] ) * ah_scale
        hourmeter = response.registers[hourmeter_HI]<<8 + \
        response.registers[hourmeter_LO]
        alarm_bits = response.registers[alarm_HI]<<8 + \
        response.registers[alarm_LO]
        dip_num = response.registers[dip_switch]
        led_num = response.registers[led_state]
        power_out = (response.registers[Power_out] * p_scale) / (2**15)

        mode = control_mode_turple[mode_num]
        if mode_num == 0 or mode_num ==2:  # charge of diversion
            state = charge_div_state_turple[state_num]
        else:  # load and lighting mode
            state = load_light_state_turple[state_num]

        return {"batt_V":batt_V,"batt_sens_V":batt_sens_V,
                "array_V":array_V,"charge_I":charge_I,"load_I":load_I,
                "batt_V_slow":batt_V_slow,"heatsink_T":heatsink_T,
                "batt_T":batt_T,"reference_V":reference_V,
                "ah_reset":ah_reset,"ah_total":ah_total,
                "hourmeter":hourmeter,"alarm_bits":alarm_bits,
                "fault_bits":fault_bits,"dip_num":dip_num,
                "mode_num":mode_num,"state_num":state_num,
                "pwm_duty":pwm_duty,"powerIn":powerIn,
                "mode":mode,"state":state}

    def read_modbus(self):
        """read output from modbus,
        save them into a list"""
        assert(self.client is not None), "client not connected"
        counter = 1
        # initialize list
        batt_V_list = []
        batt_sens_V_list = []
        array_V_list = []
        charge_I_list = []
        load_I_list = []
        batt_V_slow_list = []
        heatsink_T_list = []
        batt_T_list = []
        pwm_duty_list = []
        powerIn_list = []

        while counter <= self.COUNT:
            register_dict = self.read_registers()

            # debug
            if self.debug_flag:
                print register_dict.items()
                # for key in register_dict:
                #     print key
                #     print register_dict[key]

            # calculate average
            batt_V_list.append(register_dict["batt_V"])
            batt_sens_V_list.append(register_dict["batt_sens_V"])
            array_V_list.append(register_dict["array_V"])
            charge_I_list.append(register_dict["charge_I"])
            load_I_list.append(register_dict["load_I"])
            batt_V_slow_list.append(register_dict["batt_V_slow"])
            heatsink_T_list.append(register_dict["heatsink_T"])
            batt_T_list.append(register_dict["batt_T"])
            pwm_duty_list.append(register_dict["pwm_duty"])
            powerIn_list.append(register_dict["powerIn"])

            # return value
            counter += 1
            time.sleep(self.DT)
        else:
            # add time point
            tid = time.strftime("%Y/%m/%d %H:%M:%S")
            register_dict["tid"] = str(tid)
            # calculate average
            register_dict["batt_V"] = mean(batt_V_list)
            register_dict["array_V"] = mean(array_V_list)
            register_dict["charge_I"] = mean(charge_I_list)
            register_dict["pwm_duty"] = mean(pwm_duty_list)
            register_dict["heatsinke_T"] = mean(heatsink_T_list)
            register_dict["powerIn"] = mean(powerIn_list)

            # return result
            return register_dict

    def write_thingspeak(self, field_id, field_var_name):
        """ write certain fields to thingspeak, while loop """
        if self.thingspeak_flag:
            channel = thingspeak.channel()
            try:
                while True:
                    register_dict = self.read_modbus()
                    field_var = [register_dict[i] for i in field_var_name]
                    channel.update(field_id, field_var)
            except KeyboardInterrupt:
                self.close()
        else:
            pass

    def write_thingspeak_oneshot(self, field_id, field_var_name):
        """ write certain fields to thingspeak, no loop """
        if self.thingspeak_flag:
            channel = thingspeak.channel()
            register_dict = self.read_modbus()
            field_var = [register_dict[i] for i in field_var_name]
            channel.update(field_id, field_var)
        else:
            pass

    def log_data(self, field_var_name, filename):
        """ log data into a file """
        if self.log_flag:
            filename_new = filename + time.strftime("%Y%m%d") + '.csv'
            if not os.path.isfile(filename_new):  # write new file with header
                fil = open(filename_new, 'w')
                # write header
                # select items to write
                header = ",".join(field_var_name)
                fil.write(header+"\n")
            else:  # append
                fil = open(filename_new, 'a')

            # read modbus
            register_dict = self.read_modbus()
            field_var = [str(register_dict[i]) for i in field_var_name]
            output_text = ",".join(field_var)
            print output_text
            fil.write(output_text+"\n")
            fil.close()
        else:  # no log
            pass
class SenseAirDevice(object):

	def __init__(self):
		#---------------------------------------------------------------------------#
		# This will simply send everything logged to console
		#---------------------------------------------------------------------------#
		logging.basicConfig()
		log = logging.getLogger()
		log.setLevel(logging.DEBUG)
		self.client = None

	def connect(self, deviceName):
	  self.client = ModbusSerialClient(method='rtu',port=deviceName,stopbits=1, bytesize=8, baudrate=9600, timeout=0.2)
	  if not self.client.connect():
	      rospy.logerr("Unable to connect to %s", device)
	      return False
	  return True

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

	# Not working right now
	def getDeviceIdentification(self, objectId):

		rq = ReadDeviceInformationRequest(read_code=4, object_id=objectId, unit=0xFE)
		#rospy.loginfo("encoded: %h", encoded[0])
		rr = self.client.execute(rq)
		print rr

		return ""
		if rr is None:
			rospy.logerr("No response from device")
			return None

		if rr.function_code < 0x80:                 # test that we are not an error
			return  rr.information[0]
			#vendor_name = rr.information[0]
			#product_code = rr.information[1]
			#code_revision = rr.information[2]

			#rospy.loginfo("vendor: %s", vendor_name)
			#rospy.loginfo("product code: %s", product_code)
			#rospy.loginfo("revision: %s", code_revision)

		else:
			rospy.logwarn("error reading device identification: %h", rr.function_code)


	def getVendor(self):

		vendor = self.getDeviceIdentification(0)
		print vendor

	def readCO2(self):
		response = self.client.read_input_registers(address=3, count=1, unit=0xFE )
		return response.getRegister(0)

	def readTemperature(self):
		response = self.client.read_input_registers(address=4, count=1, unit=0xFE )
		return response.getRegister(0)*100.0

	def sendCommand(self, data):
	  #make sure data has an even number of elements
	  if(len(data) % 2 == 1):
	     data.append(0)

	  #Initiate message as an empty list
	  message = []

	  #Fill message by combining two bytes in one register
	  for i in range(0, len(data)/2):
	     message.append((data[2*i] << 8) + data[2*i+1])

	  #To do!: Implement try/except
	  self.client.write_registers(0x03E8, message, unit=0x0009)


	def getStatus(self, numBytes):
	  """Sends a request to read, wait for the response and returns the Gripper status. The method gets the number of bytes to read as an argument"""
	  numRegs = int(ceil(numBytes/2.0))

	  #To do!: Implement try/except
	  #Get status from the device
	  response = self.client.read_holding_registers(0x07D0, numRegs, unit=0x0009)

	  #Instantiate output as an empty list
	  output = []

	  #Fill the output with the bytes in the appropriate order
	  for i in range(0, numRegs):
	     output.append((response.getRegister(i) & 0xFF00) >> 8)
	     output.append( response.getRegister(i) & 0x00FF)

	  #Output the result
	  return output
Ejemplo n.º 46
0
class Device:
    """
    Modbus device (Master) class
    """

    def __init__(self, device):
        self.device = device
        self._address = device.modbusdevice.ip_address
        self._unit_id = device.modbusdevice.unit_id
        self._port = device.modbusdevice.port
        self._protocol = device.modbusdevice.protocol
        self._framer = device.modbusdevice.framer
        self._stopbits = device.modbusdevice.stopbits
        self._bytesize = device.modbusdevice.bytesize
        self._parity = device.modbusdevice.parity
        self._baudrate = device.modbusdevice.baudrate
        self._timeout = device.modbusdevice.timeout
        self._device_not_accessible = 0
        # stopbits
        if self._stopbits == 0:
            self._stopbits = Defaults.Stopbits
        # bytesize
        if self._bytesize == 0:
            self._bytesize = Defaults.Bytesize
        # parity
        parity_list = {0: Defaults.Parity, 1: 'N', 2: 'E', 3: 'O'}
        self._parity = parity_list[self._parity]
        # baudrate
        if self._baudrate == 0:
            self._baudrate = Defaults.Baudrate
        # timeout
        if self._timeout == 0:
            self._timeout = Defaults.Timeout

        self.trans_input_registers = []
        self.trans_coils = []
        self.trans_holding_registers = []
        self.trans_discrete_inputs = []
        self.variables = {}
        self._variable_config = self._prepare_variable_config(device)
        self.data = []

    def _prepare_variable_config(self, device):

        for var in device.variable_set.filter(active=1):
            if not hasattr(var, 'modbusvariable'):
                continue
            f_c = var.modbusvariable.function_code_read
            if f_c == 0:
                continue

            # add some attr to the var model 
            var.add_attr(accessible=1)
            # add the var to the list of 
            self.variables[var.pk] = var

            if f_c == 1:  # coils
                self.trans_coils.append([var.modbusvariable.address, var.pk, f_c])
            elif f_c == 2:  # discrete inputs
                self.trans_discrete_inputs.append([var.modbusvariable.address, var.pk, f_c])
            elif f_c == 3:  # holding registers
                self.trans_holding_registers.append(
                    [var.modbusvariable.address, var.decode_value, var.get_bits_by_class(), var.pk, f_c])
            elif f_c == 4:  # input registers
                self.trans_input_registers.append(
                    [var.modbusvariable.address, var.decode_value, var.get_bits_by_class(), var.pk, f_c])
            else:
                continue

        self.trans_discrete_inputs.sort(key=lambda x: x[0])
        self.trans_holding_registers.sort(key=lambda x: x[0])
        self.trans_coils.sort(key=lambda x: x[0])
        self.trans_input_registers.sort(key=lambda x: x[0])
        out = []

        # input registers
        old = -2
        regcount = 0
        for entry in self.trans_input_registers:
            if (entry[0] != old) or regcount > 122:
                regcount = 0
                out.append(InputRegisterBlock())  # start new register block
            out[-1].insert_item(entry[3], entry[0], entry[1], entry[2])  # add item to block
            old = entry[0] + entry[2] / 16
            regcount += entry[2] / 16

        # holding registers
        old = -2
        regcount = 0
        for entry in self.trans_holding_registers:
            if (entry[0] != old) or regcount > 122:
                regcount = 0
                out.append(HoldingRegisterBlock())  # start new register block
            out[-1].insert_item(entry[3], entry[0], entry[1], entry[2])  # add item to block
            old = entry[0] + entry[2] / 16
            regcount += entry[2] / 16

        # coils
        old = -2
        for entry in self.trans_coils:
            if entry[0] != old + 1:
                out.append(CoilBlock())  # start new coil block
            out[-1].insert_item(entry[1], entry[0])
            old = entry[0]
        # discrete inputs
        old = -2
        for entry in self.trans_discrete_inputs:
            if entry[0] != old + 1:
                out.append(DiscreteInputBlock())  # start new coil block
            out[-1].insert_item(entry[1], entry[0])
            old = entry[0]
        return out

    def _connect(self):
        """
        connect to the modbus slave (server)
        """
        framer = None
        if self._framer == 0:  # Socket Framer
            framer = ModbusSocketFramer
        elif self._framer == 1:  # RTU Framer
            framer = ModbusRtuFramer
        elif self._framer == 2:  # ASCII Framer
            framer = ModbusAsciiFramer
        elif self._framer == 3:  # Binary Framer
            framer = ModbusBinaryFramer

        if self._protocol == 0:  # TCP
            if self._framer is None:  # No Framer
                self.slave = ModbusTcpClient(self._address, int(self._port))
            else:
                self.slave = ModbusTcpClient(self._address, int(self._port), framer=framer)
        elif self._protocol == 1:  # UDP
            if self._framer is None:  # No Framer
                self.slave = ModbusUdpClient(self._address, int(self._port))
            else:
                self.slave = ModbusUdpClient(self._address, int(self._port), framer=framer)
        elif self._protocol in (2, 3, 4):  # serial
            method_list = {2: 'ascii', 3: 'rtu', 4: 'binary'}
            self.slave = ModbusSerialClient(
                method=method_list[self._protocol],
                port=self._port,
                stopbits=self._stopbits,
                bytesize=self._bytesize,
                parity=self._parity,
                baudrate=self._baudrate,
                timeout=self._timeout)
        else:
            raise NotImplementedError("Protocol not supported")
        status = self.slave.connect()
        return status

    def _disconnect(self):
        """
        close the connection to the modbus slave (server)
        """
        self.slave.close()

    def request_data(self):
        """
    
        """
        if not driver_ok:
            return None
        if not self._connect():
            if self._device_not_accessible == -1:  #
                logger.error("device with id: %d is not accessible" % self.device.pk)
            self._device_not_accessible -= 1
            return []
        output = []
        for register_block in self._variable_config:
            result = register_block.request_data(self.slave, self._unit_id)
            if result is None:
                self._disconnect()
                self._connect()
                result = register_block.request_data(self.slave, self._unit_id)

            if result is not None:
                for variable_id in register_block.variables:
                    if self.variables[variable_id].update_value(result[variable_id], time()):
                        recorded_data_element = self.variables[variable_id].create_recorded_data_element()
                        if recorded_data_element is not None:
                            output.append(recorded_data_element)
                    if self.variables[variable_id].accessible < 1:
                        logger.info("variable with id: %d is now accessible" % variable_id)
                        self.variables[variable_id].accessible = 1
            else:
                for variable_id in register_block.variables:
                    if self.variables[variable_id].accessible == -1:
                        logger.error("variable with id: %d is not accessible" % variable_id)
                        self.variables[variable_id].update_value(None, time())
                    self.variables[variable_id].accessible -= 1

        # reset device not accessible status 
        if self._device_not_accessible <= -1:
            logger.info("device with id: %d is now accessible" % self.device.pk)
        if self._device_not_accessible < 1:
            self._device_not_accessible = 1

        self._disconnect()
        return output

    def write_data(self, variable_id, value, task):
        """
        write value to single modbus register or coil
        """
        if variable_id not in self.variables:
            return False

        if not self.variables[variable_id].writeable:
            return False

        if self.variables[variable_id].modbusvariable.function_code_read == 3:
            # write register
            if 0 <= self.variables[variable_id].modbusvariable.address <= 65535:

                if self._connect():
                    if self.variables[variable_id].get_bits_by_class() / 16 == 1:
                        # just write the value to one register
                        self.slave.write_register(self.variables[variable_id].modbusvariable.address, int(value),
                                                  unit=self._unit_id)
                    else:
                        # encode it first
                        self.slave.write_registers(self.variables[variable_id].modbusvariable.address,
                                                   list(self.variables[variable_id].encode_value(value)),
                                                   unit=self._unit_id)
                    self._disconnect()
                    return True
                else:
                    logger.info("device with id: %d is now accessible" % self.device.pk)
                    return False
            else:
                logger.error('Modbus Address %d out of range' % self.variables[variable_id].modbusvariable.address)
                return False
        elif self.variables[variable_id].modbusvariable.function_code_read == 1:
            # write coil
            if 0 <= self.variables[variable_id].modbusvariable.address <= 65535:
                if self._connect():
                    self.slave.write_coil(self.variables[variable_id].modbusvariable.address, bool(value),
                                          unit=self._unit_id)
                    self._disconnect()
                    return True
                else:
                    logger.info("device with id: %d is now accessible" % self.device.pk)
                    return False
            else:
                logger.error('Modbus Address %d out of range' % self.variables[variable_id].modbusvariable.address)
        else:
            logger.error('wrong type of function code %d' %
                         self.variables[variable_id].modbusvariable.function_code_read)
            return False
Ejemplo n.º 47
0
"""

import time                                            # For sleep functionality
import logging                                         # For detailed error output
from pymodbus.client.sync import ModbusSerialClient \
as ModbusClient                                        # Import MODBUS support class

comSettings = {    
                "method"   : 'rtu',
                "port"     : 'COM3',
                "stopbits" : 1,                
                "bytesize" : 8,                
                "parity"   : 'N',
                "baudrate" : 9600,
                "timeout"  : 1
              }

logging.basicConfig()                                   # Setup error logging
log = logging.getLogger()                               # Start logging

client = ModbusClient(**comSettings)                    # Setup connection object
client.connect()                                        # Open the MODBUS connection

while(True):
    client.write_register(3,1000,unit=0x01)             # Write valve to 100%
    time.sleep(4)                                       # Sleep 4 seconds
    client.write_register(3,0,unit=0x01)                # Write valve to 0%
    time.sleep(4)                                       # Sleep 4 seconds

client.close()                                          # Close the connection
Ejemplo n.º 48
0
class modbusClient:
    """Class to carry out MODBUS read/write requests
    
    Usage:  Ensure all params are setup in the 'modbusSettings' file
            Call 'openConnection' to connect to the assigned server
            Use 'dataHandler' to read or write data to the server
            Call 'closeConnection' to safely close the connection
    """

    def __init__(self):
        """Load settings and connect to the designated slave"""
        
        self.modbusCfg = yamlImport.importYAML("./cfg/modbusSettings.yaml")
        if self.modbusCfg['logging'] == "enable":
            self.log = self.__logging()
        if self.__setupClient() == 0:
            return 0
        if self.openConnection() == 0:
            return 0
            
            
    def __logging(self):
        """Setup and enable logging on the client
        
        :return: enabled log instance
        """
        import logging
        logging.basicConfig()
        log = logging.getLogger()
        log.setLevel(logging.INFO)
        return log
        
        
    def __setupClient(self):
        """Setup MODBUS client object"""
        if self.modbusCfg['method'] == "tcp":
            try:
                self.client = ModbusTcpClient(self.modbusCfg['ip'],\
                                              self.modbusCfg['tcpPort'])
            except:
                raise
                return 0
        elif self.modbusCfg['method'] == "rtu":
            try:
                self.client = ModbusSerialClient(self.modbusCfg['method'],\
                                                 self.modbusCfg['rtuPort'],\
                                                 self.modbusCfg['stopbits'],\
                                                 self.modbusCfg['bytesize'],\
                                                 self.modbusCfg['parity'],\
                                                 self.modbusCfg['baudrate'],\
                                                 self.modbusCfg['timeout'])
            except:
                raise
                return 0
            else:
                raise NameError("Unsupported method")
                return 0
            
            
    def openConnection(self):
        """Attempt connection with the MODBUS server"""
        for i in range(3):
            if self.client.connect() == True:
                return 1
            else:
                print "Attempt " + str(i) + " failed"
            if i == 2:
                raise IOError("Failed to connect to specified server")
                return 0
            time.sleep(0.5)
   

    def closeConnection(self):
        """Close connection with the MODBUS server"""
        try:
            self.client.close()
        except:
            print("Error - See log for details")
            return 0
        return 1
        
    
    def dataHandler(self, op, reg, addr, length=None, data=None, encoding=1):
        """Handle the MODBUS read/write requests and pass to the appropriate function
        
        Arguments:
        :param op: Operation to perform (R/W)
        :param reg: Modbus register to access (1-4)
        :param addr: Address to start operation at
        :type op:  string
        :type reg: int
        :type addr: int
        
        Keyword Arguments:
        :param length: Length of registers to read (default None)
        :param data: Data to write to the slave
        :type length: int
        :type data: list
        
        :return: List containing the requested data or confimation of send.
        """
        if op == 'r':
            for i in range(3):
                r = self.__readData(reg, addr, length, encoding)
                if (r == ConnectionException) or (r == ModbusIOException):
                    print("Read attempt " + str(i) + " failed")
                    if i == 2:
                        #TODO: remove sys exit and handle properly
                        raise SystemExit('Modbus Error: Failed 3 Attemps')
                elif r == ValueError:
                    #TODO: remove sys exit and handle properly
                    raise SystemExit('Invalid Register - Use 15 or 16')
                else:
                    return r
        if op == 'w':
            for i in range(3):
                w = self.__writeData(reg, addr, data, encoding)
                if (w == ConnectionException) or (w == ModbusIOException):
                    print("Write attempt " + str(i) + " failed")
                    if i == 2:
                        #TODO: remove sys exit and handle properly
                        raise SystemExit('Modbus Error: Failed 3 Attemps')
                elif w == ValueError:
                    #TODO: remove sys exit and handle properly
                    raise SystemExit('Invalid Register - Use 15 or 16')
                else:
                    return w
        return ValueError('Invalid Operation')
            
    
    def __readData(self, reg, addr, length, encoding):
        """Read data from the MODBUS Slave
        
        Called by 'dataHandler' in modbusClient.py
        
        Arguments:
        :param reg:      Modbus register to access (1-4)
        :param addr:     Address to start reading from
        :param length:   Quantity of registers to read
        :param encoding: States whether data should be decoded
        :type reg:       int
        :type addr:      int
        :type length:    int
        :type encoding: int
        
        :return:         List containing the requested data or failure exception.
        """
        data = []
        
        if 1 <= reg <= 2:
            try:
                if reg == 1:
                    co = self.client.read_coils(addr,length,unit=0x01)
                else:
                    co = self.client.read_discrete_inputs(addr,length,unit=0x01)
            except ConnectionException:
                return ConnectionException
            
            if co.function_code != reg:
                return ModbusIOException
                
            for i in range(length):
                data.append(co.getBit(i))
            return data
        
        
        elif 3 <= reg <= 4:
            try:
                if reg == 3:
                    hr = self.client.read_holding_registers(addr,length,unit=0x01)
                else:
                    hr = self.client.read_input_registers(addr,length,unit=0x01)
            except ConnectionException:
                return ConnectionException
            
            if hr.function_code != reg:
                return ModbusIOException
                
            for i in range(length):
                data.append(hr.getRegister(i))
            
            if encoding == 1:
                return self.__decodeData(data)
            return data
        
        else:
            return ValueError
            
    
    def __writeData(self, reg, addr, data, encoding):
        """Write data to the MODBUS slave
        
        Called by 'dataHandler' in modbusClient.py
        
        Arguments:
        :param reg:      Modbus register to access (15 or 16)
        :param addr:     Address to start writing to
        :param data:     List of data to write to the device
        :param encoding: States whether data should be encoded first
        :type reg:       int
        :type addr:      int
        :type length:    int
        :type encoding: int
        
        :return:         success or failure exception
        """
        if reg == 15:
            try:
                co = self.client.write_coils(addr,data,unit=0x01)
            except ConnectionException:
                return ConnectionException
            
            if co.function_code != reg:
                return ModbusIOException
        
        elif reg == 16:
            if encoding == 1:
                data = self.__encodeData(data)
            
            try:
                hr = self.client.write_registers(addr,data,unit=0x01)
            except ConnectionException:
                return ConnectionException
            
            if hr.function_code != reg:
                return ModbusIOException
            
        else:
            return ValueError
        
    
    def __encodeData(self, data):
        """Encode data to 32bit float
        
        Function encodes a list of data passed to it into a 32 bit float
        packet that can be written directly to the MODBUS server table.
        
        Arguments:
        :param data: Float to be encoded
        :type data: list
        """
        builder = BinaryPayloadBuilder(endian=Endian.Little)
        try:
            for i in range(0,len(data)):
                builder.add_32bit_float(data[i])
        except TypeError:
            builder.add_32bit_float(data)
        return builder.to_registers()

    def __decodeData(self, data):
        """Decode MODBUS data to float
        
        Function decodes a list of MODBUS 32bit float data passed to it
        into its respective list of floats.
        
        Arguments:
        :param data: Data to be decoded
        :type data: list
        """
        returnData = [0]*(len(data)/2)
        decoder = BinaryPayloadDecoder.fromRegisters(data, endian=Endian.Little)
        for i in range(0,len(data)/2):
            returnData[i] = round(decoder.decode_32bit_float(),2)
        return returnData
Ejemplo n.º 49
0
def execute_extended_requests():
    # ------------------------------------------------------------------------# 
    # 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.
    #
    # It should be noted that you can supply an ipv4 or an ipv6 host address 
    # for both the UDP and TCP clients.
    # ------------------------------------------------------------------------# 
    client = ModbusClient(method='rtu', port="/dev/ttyp0")
    # client = ModbusClient('127.0.0.1', port=5020)
    client.connect()

    # ----------------------------------------------------------------------- # 
    # extra requests
    # ----------------------------------------------------------------------- # 
    # If you are performing a request that is not available in the client
    # mixin, you have to perform the request like this instead::
    #
    # from pymodbus.diag_message import ClearCountersRequest
    # from pymodbus.diag_message import ClearCountersResponse
    #
    # request  = ClearCountersRequest()
    # response = client.execute(request)
    # if isinstance(response, ClearCountersResponse):
    #     ... do something with the response
    #
    #
    # What follows is a listing of all the supported methods. Feel free to
    # comment, uncomment, or modify each result set to match with your ref.
    # ----------------------------------------------------------------------- # 

    # ----------------------------------------------------------------------- # 
    # information requests
    # ----------------------------------------------------------------------- #
    log.debug("Running ReadDeviceInformationRequest")
    rq = ReadDeviceInformationRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)              # not supported by reference
    # assert (rr.function_code < 0x80)  # test that we are not an error
    # assert (rr.information[0] == b'Pymodbus')  # test the vendor name
    # assert (rr.information[1] == b'PM')  # test the product code
    # assert (rr.information[2] == b'1.0')  # test the code revision

    log.debug("Running ReportSlaveIdRequest")
    rq = ReportSlaveIdRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                        # not supported by reference
    # assert(rr.function_code < 0x80)           # test that we are not an error
    # assert(rr.identifier  == 0x00)            # test the slave identifier
    # assert(rr.status  == 0x00)                # test that the status is ok

    log.debug("Running ReadExceptionStatusRequest")
    rq = ReadExceptionStatusRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                        # not supported by reference
    # assert(rr.function_code < 0x80)           # test that we are not an error
    # assert(rr.status == 0x55)                 # test the status code

    log.debug("Running GetCommEventCounterRequest")
    rq = GetCommEventCounterRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                       # not supported by reference
    # assert(rr.function_code < 0x80)          # test that we are not an error
    # assert(rr.status == True)                # test the status code
    # assert(rr.count == 0x00)                 # test the status code

    log.debug("Running GetCommEventLogRequest")
    rq = GetCommEventLogRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                       # not supported by reference
    # assert(rr.function_code < 0x80)          # test that we are not an error
    # assert(rr.status == True)                # test the status code
    # assert(rr.event_count == 0x00)           # test the number of events
    # assert(rr.message_count == 0x00)         # test the number of messages
    # assert(len(rr.events) == 0x00)           # test the number of events

    # ------------------------------------------------------------------------# 
    # diagnostic requests
    # ------------------------------------------------------------------------#
    log.debug("Running ReturnQueryDataRequest")
    rq = ReturnQueryDataRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                      # not supported by reference
    # assert(rr.message[0] == 0x0000)         # test the resulting message

    log.debug("Running RestartCommunicationsOptionRequest")
    rq = RestartCommunicationsOptionRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                     # not supported by reference
    # assert(rr.message == 0x0000)           # test the resulting message

    log.debug("Running ReturnDiagnosticRegisterRequest")
    rq = ReturnDiagnosticRegisterRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                     # not supported by reference

    log.debug("Running ChangeAsciiInputDelimiterRequest")
    rq = ChangeAsciiInputDelimiterRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                    # not supported by reference

    log.debug("Running ForceListenOnlyModeRequest")
    rq = ForceListenOnlyModeRequest(unit=UNIT)
    rr = client.execute(rq)  # does not send a response
    print(rr)

    log.debug("Running ClearCountersRequest")
    rq = ClearCountersRequest()
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                   # not supported by reference

    log.debug("Running ReturnBusCommunicationErrorCountRequest")
    rq = ReturnBusCommunicationErrorCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                    # not supported by reference

    log.debug("Running ReturnBusExceptionErrorCountRequest")
    rq = ReturnBusExceptionErrorCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                   # not supported by reference

    log.debug("Running ReturnSlaveMessageCountRequest")
    rq = ReturnSlaveMessageCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                  # not supported by reference

    log.debug("Running ReturnSlaveNoResponseCountRequest")
    rq = ReturnSlaveNoResponseCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)                  # not supported by reference

    log.debug("Running ReturnSlaveNAKCountRequest")
    rq = ReturnSlaveNAKCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)               # not supported by reference
    
    log.debug("Running ReturnSlaveBusyCountRequest")
    rq = ReturnSlaveBusyCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)               # not supported by reference

    log.debug("Running ReturnSlaveBusCharacterOverrunCountRequest")
    rq = ReturnSlaveBusCharacterOverrunCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)               # not supported by reference

    log.debug("Running ReturnIopOverrunCountRequest")
    rq = ReturnIopOverrunCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)               # not supported by reference

    log.debug("Running ClearOverrunCountRequest")
    rq = ClearOverrunCountRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)               # not supported by reference

    log.debug("Running GetClearModbusPlusRequest")
    rq = GetClearModbusPlusRequest(unit=UNIT)
    rr = client.execute(rq)
    print(rr)
    # assert(rr == None)               # not supported by reference

    # ------------------------------------------------------------------------# 
    # close the client
    # ------------------------------------------------------------------------# 
    client.close()
Ejemplo n.º 50
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()
Ejemplo n.º 51
0
 def close(self):
     if self.socket:
         self.ioloop.remove_handler(self.socket.fileno())
     return ModbusSerialClient.close(self)
Ejemplo n.º 52
0
class BmsLionModbus:
    
    #init
    def __init__(self, configuration):
        self.config = configuration
        self.client = 0
        self.busy = 0
        self.device = ''
        self.datalayer = 0
        self.thread = 0
        self.connection = 0
        self.connected = 0
        self.terminate_flag = 0
        self.running_flag = 0
        self.commands = ['v','t','b','c','e','s']
        self.logfile = ''
        self.logfileH = ''
        self.filemode = False
        self.clearFileFlag = False
    
    #join
    def terminate(self):
        self.terminate_flag = 1
        self.thread.join()
    
    #module can receive GET messages
    def http_get(self, key, name, value):
        # we receive only string at the moment and pass it over serial (=value)
        
        # we only get further when key = pass
        if key != "pass":
            return
        
        if (name == "download"):
            return "not implemented yet!"
            # TODO: sd card readout
            # self.datalayer.allfile
        if name == "configload":
            self.readConfig()
            
        if name == "configsave":
            print("Will send following config regs to CPU module:")
            #struct to 16bit register conversion (big endian)
            regs = [ int(value[i:i+4],16) for i in range(0, len(value), 4)]
            #struct to 16bit register conversion (little endian)
            #regs = [ int(value[i:i+2],16)+int(value[i+2:i+4],16)*256 for i in range(0, len(value), 4)]
            print(regs)
            try:
                rq = self.client.write_registers(4000,regs,unit=1)
                print ("Config registers written!")
            except Exception as e:
                print ("Could not write CONFIG registers!")
        
        return ''
        
    def status(self):
        
        return "OK, PEC: "+str(self.datalayer.cpuPEC)+"%"
        
    # menu items offered by module
    # each menu item is connected with a view
    def menu(self):
        return {
        'view_modulesm' :'overview',
        'view_settingsm':'settings',
        }
    
    #items visible on each page  
    def sticky(self):
        return {}
    
    #fork    
    def start(self):
        self.datalayer = Datalayer()
        self.datalayer.sqllog = 0
        
        if 0 == self.running_flag:
            self.thread = threading.Thread(target=self.run)
            self.terminate_flag = 0
            self.thread.start()
            self.datalayer.message = "started new reading process"
        else:
            self.datalayer.message = "one process already running"
        
    def run(self):
        self.running_flag = 1
        currentMod = 0
        
        while not self.terminate_flag:

            if not self.connected:
                for self.device in self.config['ports']:
                    try:
                        self.datalayer.status = 'opening '+self.device
                        self.client = ModbusSerialClient(method = "rtu", port=self.device, baudrate=self.config['modbus_speed'], stopbits=1, bytesize=8, timeout=self.config['modbus_timeout'])
                        time.sleep(0.1)
                        if not self.client.connect():
                            self.connected = 0
                            self.datalayer.status = 'retry in 2s, no connection '+self.device
                            time.sleep(1)
                            continue
                        self.connected = 1
                        self.datalayer.receivecounter = 0
                        self.datalayer.status = 'connected to '+self.device
                    except Exception as e:
                        
                        print(str(e))
                        self.connected = 0
                        time.sleep(1)
                        continue
                        
                    if not self.readConfig():
                        continue
                    
                    # must exit "connection trying loop" because when it gets here --> successfully made connection
                    break
            
            # this is needed when for loop per device finishes
            # we cannot continue without proper connection
            if not self.connected:
                print ("No success with connection. Will test configured devices again...")
                time.sleep(1)
                continue            
            
            # here is the "worker code"    
            error = 0
            try:
                if self.busy:
                    time.sleep(self.config['sleeptime_comm'])
                    continue
                self.busy = 1;
                rq = self.client.read_holding_registers(1000+currentMod*100,30,unit=1)
                #if hasattr(rq, 'registers'):
                self.datalayer.modulesRegsParse(currentMod, rq.registers)
                self.datalayer.receivecounter += 1
                currentMod += 1
                if currentMod == self.datalayer.numModules:
                    currentMod = 0
                    
                self.busy = 0;
                # configurable delay
                time.sleep(self.config['sleeptime_comm'])
                self.datalayer.status = "connected: "+self.device
            
            except AttributeError:
                self.datalayer.status = 'Read holding registers exception (attr error): '+self.device
                print(self.datalayer.status)
                self.busy = 0;
                
            except ModbusException as e:
                self.busy = 0;
                self.datalayer.status = 'Read holding registers exception: '+self.device
                print(self.datalayer.status)
                self.connected = 0
                self.client.close()
                time.sleep(1)
        
        #cleanup only if connection was established...
        if self.connected:
            self.client.close()          
            self.connected = 0
            self.datalayer.message = "closing connection, thread exit"
            self.running_flag = 0
            
    def readConfig(self):
        # read config
        print ("MODBUS connected - will read config 58 regs")
        timeout = 10
        while (self.busy == 1) and (timeout > 0):
            print ("Waiting for connection 100ms")
            timeout -= 1
            time.sleep(0.1)
        
        if timeout == 0:
            print("Timeout - no configuration read")
            return False
            
        try:
            self.busy = 1;
            rq = self.client.read_holding_registers(4000,58,unit=1)
            self.datalayer.configRegsParse(rq.registers)
            self.busy = 0;
        except Exception as e:
            print ("Could not read BMS config! Maybe some other program blocks the connection?")
            self.connected = 0
            self.busy = 0;
            return False
        print ("Config successfully loaded!")
        return True
Ejemplo n.º 53
0
            words_per_channel += 1
            rval = response.registers
            for i in range(len(files)):
                files[i][1].write(str(bin(rval[i]))[2:])
    finally:
        finalize_runinfo(rtime)
        for s, f in files:
            f.close()


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--port', default='/dev/ttyACM1',
                        help="Serial Port",)
    parser.add_argument('-b', '--baudrate', default=256000, type=int,
                        help="Baud Rate. Not applicable to USB CDC links")
    parser.add_argument('source', choices=['entropy', 'all',
                                           'lfsr16', 'lfsr32', 'lfsr64',
                                           'sg16', 'sg32', 'sg64',
                                           'asg16', 'asg32', 'asg64',
                                           'entropium', 'rand'],
                        default='entropy', help='Data stream to use')
    args = parser.parse_args()
    mclient = ModbusClient(method='rtu', port=args.port, timeout=0.1,
                           baudrate=args.baudrate)
    mclient.connect()
    try:
        acquire(args.source)
    finally:
        mclient.close()
Ejemplo n.º 54
0
class comClient:
    def __init__(self):
        self.__parseConfig()
        # Configure logging on the client
        logging.basicConfig()
        self.log = logging.getLogger()
        # Change to DEBUG for full information during runtime
        self.log.setLevel(logging.INFO)
        #  Setup and Open the connection
        self.client = ModbusClient(**self.comSettings)

    def __parseConfig(self):
        try:
            with open("../../cfg/connection.yaml", "r") as f:  # safely opens the file and gets the text
                config = yaml.load(f)  # parses the data into python
                self.comSettings = config  # saves config to member variable

        except IOError:
            print ("Failed to set config from file. Falling back to default values:")
            self.comSettings = {
                "method": "rtu",
                "port": "COM3",  # FALL BACK VALUES ONLY
                "stopbits": 1,
                "bytesize": 8,
                "parity": "N",
                "baudrate": 9600,
                "timeout": 1,
            }

    def dataHandler(self, operation, *data):
        if operation == "r":
            for i in range(3):
                r = self.__readData()  # Attempt to read MODBUS data
                if r != IOError:  # If success, carry on
                    break
                elif i == 2:  # Retry 3 times on failure
                    raise SystemExit("Modbus Error: Failed 3 Attemps")
                time.sleep(5)
            return r

        elif operation == "w":
            try:
                self.__writeData(data[0])  # Attempt to write MODBUS data
            except IndexError:
                raise SystemExit("No data passed to write!")
            return

        else:
            raise ValueError("Invalid Operation")

    def __readData(self):
        # Function to write data to controller
        try:
            self.client.connect()
            # REMEMBER: Controller is unit 0x01
            r = self.client.read_holding_registers(0, 4, unit=0x01)
            self.client.close()
            return r
        except:
            print "Modbus Error: Read Connection Failed"
            return IOError

    def __writeData(self, op):
        # Set to write data to the controller output (MODBUS HR 3)
        self.client.connect()
        w = self.client.write_register(3, op, unit=0x01)
        self.client.close()
        return w
Ejemplo n.º 55
0
# Andrew Elwell <*****@*****.**> 2013-09-01

from pymodbus.client.sync import ModbusSerialClient as ModbusClient
import time

result = {}
result['timestamp'] = time.time()

client = ModbusClient(method='rtu', port='/dev/ttyUSB0', baudrate=9600, stopbits=1, parity='N', bytesize=8, timeout=1)
client.connect()

# can'r read the whole lot in one pass, so grab each chunk
# addr / descriptions  lifted from http://code.google.com/p/pvbeancounter/source/browse/trunk_v2/PVSettings/Device_Growatt.xml
rr = []
rr = client.read_input_registers(2,3)
result['PV_W'], result['PV_V'], result['PV_A'] = rr.registers

rr = []
rr = client.read_input_registers(12,3)
result['Out_W'], result['AC_Hz'], result['AC_V'] = rr.registers

#rr = client.read_input_registers(17, 1)
#result['wtf2'] = rr.registers[0]

#rr = client.read_input_registers(29,3)
#print rr.registers

client.close()

print result,
Ejemplo n.º 56
0
t_date = format(strftime('%Y%m%d'))
t_time = format(strftime('%H:%M'))

pv_volts=0.0
pv_power=0.0
Wh_today=0
current_temp=0.0
cmo_str='None'

for i in range(NoInvert):
# Read data from inverter
  inverter = ModbusClient(method='rtu', port='/dev/ttyUSB'+str(i), baudrate=9600, stopbits=1, parity='N', bytesize=8, timeout=1)
  inverter.connect()
  rr = inverter.read_input_registers(1,27)
  inverter.close()
  value=rr.registers[2]
  pv_volts=pv_volts+(float(value)/10)
  value=rr.registers[11]
  pv_power=pv_power+(float(value)/10)
  value=rr.registers[26]
  Wh_today=Wh_today+(float(value)*100)

if OWMKey<>'':
  owm = OWM(OWMKey)
  if owm.API_online:
    obs = owm.weather_at_coords(OWMLat, OWMLon)
    w = obs.get_weather()
    w_stat = w.get_detailed_status()
    temp = w.get_temperature(unit='celsius')
    current_temp = temp['temp']