Exemple #1
0
def test_send_message_with_timeout():
    """ Test if TimoutError is raised when serial port doesn't receive enough
    data.
    """
    s = serial_for_url('loop://', timeout=0)
    # As we are using a loop, the sent request will be read back as response.
    # To test timeout use a request that needs more bytes for the response.
    message = read_coils(slave_id=0, starting_address=1, quantity=40)

    with pytest.raises(ValueError):
        send_message(message, s)
Exemple #2
0
def do_sendregs(devnum, parmlist):
    # parms = <regnum as int> <stringdata as string>
    try:
        regnum = int(parmlist[0])
    except:
        print("<register> can only be a number")
        return
    dataString = parmlist[1]

    # Send the command
    message = rtu.write_multiple_registers(slave_id=devnum,
                                           starting_address=regnum,
                                           values=string2list(parmlist))

    try:
        response = rtu.send_message(message, serial_port)
    except Timeout:
        print("Timeout error, ignoring", file=sys.stderr)
        if ignore_timeouts:
            return
        sys.exit(1)
    except:
        e = sys.exc_info()[0]
        print("Some other exception: %" % repr(e))
        sys.exit(3)

    # print("Got a response back!");
    # import pdb; pdb.set_trace()

    return
    def read_discrete_inputs(self, start_discrete_address, number_of_inputs):
        """ Modbus command : Read discrete input(s) (function code = 02)

            @Argument :
            start_discrete_address (int16) : Start discrete input address where to read a input data
            number_of_inputs (int)         : number of discrete input(s) to read

            @Return :
            response : Discrete input(s) data
        """
        response = None

        # Generate modbus RTU message
        try:
            message = modbus_rtu.read_discrete_inputs(
                slave_id=self.device_id,
                starting_address=start_discrete_address,
                quantity=number_of_inputs)
        except Exception as e:
            print("Error during generate modbus message.")

        # Send message via serial port
        try:
            if self.serialport.is_open:
                response = modbus_rtu.send_message(message, self.serialport)
                print("response={}".format(response))
            else:
                print("Error : Cannot send data. Serial port is closed.")
        except Exception as e:
            print("Error during send modbus message.")
            print(e)

        return response
    def read_coils(self, start_coil_address, number_of_coils):
        """ Modbus command : Read coil data(s) (function code = 01)

            @Argument :
            start_coil_address (int16) : Start coil address where to read a coil data
            number_of_coil (int)       : number of coil(s) to read

            @Return :
            response : Coil data (Byte)
                        The coils in the response message are packed as one coil per bit of the
                        data field. Status is indicated as 1= ON and 0= OFF.
        """
        response = None

        # Generate modbus RTU message
        try:
            message = modbus_rtu.read_coils(
                slave_id=self.device_id,
                starting_address=start_coil_address,
                quantity=number_of_coils)
        except Exception as e:
            print("Error during generate modbus message.")

        # Send message via serial port
        try:
            if self.serialport.is_open:
                response = modbus_rtu.send_message(message, self.serialport)
                print("response={}".format(response))
            else:
                print("Error : Cannot send data. Serial port is closed.")
        except Exception as e:
            print("Error during send modbus message.")
            print(e)

        return response
    def write_coils(self, coil_start_address, write_values):
        """ Modbus command : write multiple coils data (function code = 15)

            @Argument :
            coil_start_address (int16) : Coil start address where to write a set of coils data
            write_values (int)    : write value(s)
        """

        # Generate modbus RTU message
        try:
            message = modbus_rtu.write_multiple_coils(
                slave_id=self.device_id,
                starting_address=coil_start_address,
                values=write_values)
        except Exception as e:
            print("Error during generate modbus message.")

        # Send message via serial port
        try:
            if self.serialport.is_open:
                response = modbus_rtu.send_message(message, self.serialport)
                print("response={}".format(response))
            else:
                print("Error : Cannot send data. Serial port is closed.")
        except Exception as e:
            print("Error during send modbus message.")
            print(e)
Exemple #6
0
def main():
    # import pdb; pdb.set_trace()
    # import pdb; pdb.set_trace()

    # tempval = string2list("ABCDEFGHIJ");        # Even Number
    tempval = string2list("ABCDEFGHI")
    # Odd Number

    serial_port = get_serial_port()

    # Returns a message or Application Data Unit (ADU) specific for doing
    # Modbus RTU.
    # message = rtu.write_multiple_coils(slave_id=1, starting_address=1, values=[1, 0, 1, 1])
    message = rtu.write_multiple_registers(slave_id=1,
                                           starting_address=1,
                                           values=string2list("ABCDEFG"))

    # Response depends on Modbus function code. In this case, it's the number
    # of registers written.

    try:
        response = rtu.send_message(message, serial_port)
    except Timeout:
        print("Timeout error")
        sys.exit(1)
    except:
        e = sys.exc_info()[0]
        print("Some other exception: %" % repr(e))
        sys.exit(3)

    serial_port.close()
Exemple #7
0
    def read_input_registers(self, slave_id, address, quantity):
        """
        Get raw data from input registers.

        Parameters
        ----------
        slave_id
            Slave identifier number (targeted device)
        address
            Register starting address
        quantity
            Quantity of registers to read

        Returns
        -------
        bytes
            Raw data from targeted registers
        """
        message = rtu.read_input_registers(slave_id=slave_id,
                                           starting_address=address,
                                           quantity=quantity)
        logger.debug("-> Transmit ADU : 0x%s", str(bytes(message).hex()))
        try:
            response = rtu.send_message(message, self.serial_port)
        except (ValueError, KeyError) as e:
            logger.error(
                "--> Please match your configurations and the values set with the dip-switches on the device: ",
                e)
        except ModbusError as e:
            logger.error("--> Modbus error : ", e)
        else:
            hex_response = ' '.join(hex(x) for x in response)
            logger.debug("<- Receive data : %s", str(hex_response))
            return response
Exemple #8
0
 def write_coil_register(self, slave_id, address, port, value):
     self.serial_port = self.get_serial_port(port)
     add = int(address) - 1
     message = rtu.write_single_coil(slave_id=int(slave_id), address=add, value=int(value))
     response = rtu.send_message(message, self.serial_port)
     print(response)
     self.serial_port.close()
Exemple #9
0
    def get_thermi(
            self,
            th=0):  # to get the thermistor value, returns the thermistor value
        self.thermi = th

        try:
            serial_port = self.get_serial_port()

            if self.thermi == 0:  # get the value of all the thermistors
                message = rtu.read_input_registers(SLAVE_ID, THERMI1_REG, 4)
            elif self.thermi == 1:  # get the thermistor 1 value
                message = rtu.read_input_registers(SLAVE_ID, THERMI1_REG, 1)
            elif self.thermi == 2:  # get the thermistor 2 value
                message = rtu.read_input_registers(SLAVE_ID, THERMI2_REG, 1)
            elif self.thermi == 3:  # get the thermistor 3 value
                message = rtu.read_input_registers(SLAVE_ID, THERMI3_REG, 1)
            elif self.thermi == 4:  # get the thermistor 4 value
                message = rtu.read_input_registers(SLAVE_ID, THERMI4_REG, 1)
            else:
                print("ERROR: no thermistor was found at this value")

            response = rtu.send_message(message, serial_port)

            self.close_serial_port()
        except:
            traceback.print_exc()

        return response
def get_tariff():
    message = rtu.read_holding_registers(slave_id=1,
                                         starting_address=0x6048,
                                         quantity=1)
    response = rtu.send_message(message, serial_port)
    tariff = [-1, 1, 0]
    print(response)
    return {"tariff_val": tariff[response[0]]}
Exemple #11
0
    def read_input_registers(self, slave_id, address, quantity, port):
        self.serial_port = self.get_serial_port(port)
        add = int(address) - 1
        message = rtu.read_input_registers(slave_id=int(slave_id), starting_address=add, quantity=int(quantity))
        hexadecimal_string = message.hex()
        print(hexadecimal_string)
        response = rtu.send_message(message, self.serial_port)

        print("response", response)

        result = []
        # return response
        count = 0
        for offset in range(int(address), int(address) + int(quantity)):
            print("offset", offset)
            # for i in response:
            if offset == 100:
                res = response[count] / 10
                print("Factory value", res)

            elif offset == 101:
                res = response[count] / 10
                print("Factory value", res)

            elif offset == 102:
                res = response[count] / 10
                print("Factory value", res)
            # print("count",count)
            elif offset == 103:
                res = response[count] / 10
                print("Factory value", res)
            # print("count",count)
            elif offset == 10:
                res = response[count] / 10
                print("Factory value", res)
            # print("count",count)
            elif offset == 124:
                res = response[count] / 10
                print("Factory value", res)

            elif offset == 131:
                res = response[count] / 10
                print("Factory value", res)

            elif offset == 183:
                res = response[count] / 10
                print("Factory value", res)
            else:
                res = response[count]
                print(res)
            count = count + 1
            result.append(res)

        return result, hexadecimal_string
        self.serial_port.close()
Exemple #12
0
 def read_input(self, reg):  # read a single input register at reg address
     try:
         serial_port = self.get_serial_port()
         message = rtu.read_input_registers(SLAVE_ID, reg, 1)
         response = rtu.send_message(message, serial_port)
         self.release_serial_port()
         return response[0]
     except:
         traceback.print_exc()
         self.close_serial_port()
     return None
Exemple #13
0
 def get_battery_percentage(self):
     """ Return the current charge percentage of the batteries."""
     ret_status = True
     message = rtu.read_holding_registers(slave_id=self.slave_id,
                                          starting_address=self.BATTPCT,
                                          quantity=1)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = [-1]
     return ret_status, response[0]
Exemple #14
0
 def set_auto(self):
     """ Switch inverter to AUTO."""
     ret_status = True
     message = write_passive_register(slave_id=self.slave_id,
                                      address=self.AUTO,
                                      value=0)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = 0
     return ret_status, response
Exemple #15
0
 def set_standby(self):
     """ Switch inverter to STANDBY."""
     ret_status = True
     message = write_passive_register(slave_id=self.slave_id,
                                      address=self.STANDBY,
                                      value=self.STANDBY_VAL)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = 0
     return ret_status, response
Exemple #16
0
 def read_holding(self):
     """ Read all the holding registers from inverter."""
     ret_status = True
     message = rtu.read_holding_registers(slave_id=self.slave_id,
                                          starting_address=self.ME_HOLDING,
                                          quantity=self.NUM_HOLDING)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = 0
     return ret_status, response
Exemple #17
0
 def write_holding(self, reg,
                   val):  # write val in the holding register at reg address
     try:
         serial_port = self.get_serial_port()
         message = rtu.write_single_register(SLAVE_ID, reg, val)
         response = rtu.send_message(message, serial_port)
         self.release_serial_port()
         return response
     except:
         traceback.print_exc()
         self.close_serial_port()
     return None
Exemple #18
0
 def get_inverter_state(self):
     """ Return the inverter state."""
     ret_status = True
     message = rtu.read_holding_registers(slave_id=self.slave_id,
                                          starting_address=self.ME_STATE,
                                          quantity=1)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = [-1]
     return ret_status, response[0], self.INV_STATES[response[0]]
Exemple #19
0
 def set_discharge(self, discharge=3000):
     """ Set discharge value."""
     ret_status = True
     message = write_passive_register(slave_id=self.slave_id,
                                      address=self.DISCHARGE,
                                      value=discharge)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = 0
     return ret_status, response
Exemple #20
0
 def read_input(self):
     """ Read the inverter's input registers."""
     ret_status = True
     message = rtu.read_input_registers(slave_id=self.slave_id,
                                        starting_address=self.ME_INPUT,
                                        quantity=self.NUM_INPUT)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = 0
     return ret_status, response
Exemple #21
0
 def read_deye_register(self, start_address, number_addresses):
     """ read specific register from inverter."""
     ret_status = True
     message = rtu.read_holding_registers(slave_id=self.slave_id,
                                          starting_address=start_address,
                                          quantity=number_addresses)
     try:
         response = rtu.send_message(message, self.serial_port)
     except:
         ret_status = False
         response = 0
     return ret_status, response
Exemple #22
0
    def get_pump_servo(
            self):  # to get the pump speed returned by the servo of the pump
        response = None
        try:
            serial_port = self.get_serial_port()

            message = rtu.read_input_registers(SLAVE_ID,
                                               PUMP_SERVO_PERIODMAX_REG, 3)
            response = rtu.send_message(message, serial_port)

            message = rtu.read_holding_registers(SLAVE_ID,
                                                 PUMP_SERVO_PULSES_REG, 1)
            response2 = rtu.send_message(message, serial_port)
            response.append(response2[0])

            # Auto re-init every second...
            #message = rtu.write_single_register(SLAVE_ID, PUMP_SERVO_PULSES_REG , 0)
            #response3 = rtu.send_message(message, serial_port)

            self.close_serial_port()
        except:
            traceback.print_exc()

        return response
Exemple #23
0
    def write_holding_register(self, slave_id, address, port, value):
        self.serial_port = self.get_serial_port(port)
        add = int(address) - 1

        if int(value) < 0:
            value1 = int(value) + 2 ** 16
        else:
            value1 = int(value)
        print(value1)
        message = rtu.write_single_register(slave_id=int(slave_id), address=add, value=int(value1))
        print(message)
        hexadecimal_string = message.hex()
        print(hexadecimal_string)
        response = rtu.send_message(message, self.serial_port)
        print(response)
        print(type(response))
        self.serial_port.close()
def get_data(start=0x4000, length=0x02):
    message = rtu.read_holding_registers(slave_id=1,
                                         starting_address=start,
                                         quantity=length)
    response = rtu.send_message(message, serial_port)

    count = 0
    data = {}

    while count < len(response):
        h = format(response[count + 0], '04X')
        l = format(response[count + 1], '04X')
        d = h + l
        val = struct.unpack('!f', bytes.fromhex(d))[0]
        key = str(format(start + count, '04X'))
        data[key] = val
        count += 2

    return data
Exemple #25
0
def do_sendreg(devnum, parmlist):
    # parms = <regnum> <single_word> in dec or hex (if "0x" prepended)
    baseConv = 10
    # print("-- do_sendreg: DEV({}), WORD({})".format(devnum, repr(parmlist)))
    try:
        regnum = int(parmlist[0])
    except:
        print("<register> can only be a number")
        return

    singleWord_s = parmlist[1]
    if singleWord_s.startswith("0x"):
        baseConv = 16
        singleWord_s = singleWord_s[2:]
    try:
        singleWord = int(singleWord_s, baseConv)
    except ValueError:
        print("<singleWord> can only be a dec or hex (0x) number")
        return

    # Send the command
    # def write_single_register(slave_id, address, value):

    message = rtu.write_single_register(slave_id=devnum,
                                        address=regnum,
                                        value=singleWord)

    try:
        response = rtu.send_message(message, serial_port)
    except TimeoutError:
        print("Timeout error, ignoring", file=sys.stderr)
        if ignore_timeouts:
            return
        sys.exit(1)
    except:
        e = sys.exc_info()[0]
        print("Some other exception: %" % repr(e))
        sys.exit(3)

    print("Got a response back!")
    import pdb
    pdb.set_trace()
    def read_input_registers(self, start_register_address,
                             number_of_registers):
        """ Modbus command : Read data to input registers (function code = 04)

            @Argument :
            start_register_address (int16) : Start address where to read a data
            number_of_registers (int)      : number of register(s) in register-line where to read a data

            @Return :
            response : Read data(s). Return as list of read data (sequently) if number_of_register > 1
        """
        response = None

        # Enable byte system of modbus to be signed-value type
        if self.signed_type == True:
            conf.SIGNED_VALUES = True
        else:
            conf.SIGNED_VALUES = False

        # Generate modbus RTU message
        try:
            message = modbus_rtu.read_input_registers(
                slave_id=self.device_id,
                starting_address=start_register_address,
                quantity=number_of_registers)
        except Exception as e:
            print("Error during generate modbus message.")

        # Send message via serial port
        try:
            if self.serialport.is_open:
                response = modbus_rtu.send_message(message, self.serialport)
                print("response={}".format(response))
            else:
                print("Error : Cannot send data. Serial port is closed.")
        except Exception as e:
            print("Error during send modbus message.")
            print(e)

        return response
Exemple #27
0
    def send(self,
             message: bytes,
             timeout: float,
             retries: int = 1) -> Optional[List[int]]:

        with self.lock:

            for i in range(retries):
                self.__wait()

                try:
                    self.set_timeout(timeout)

                    response = modbus.send_message(adu=message,
                                                   serial_port=self._serial)
                    return response

                except (KeyError, ValueError) as e:
                    return None

                finally:
                    self.__last = datetime.now()
    def write_registers(self, start_register_address, write_values):
        """ Modbus command : Write data to multiple registers (function code = 16)

            Argument :
            start_register_address (int16) : Start address where to write a data
            write_values (int16)           : Write data(s) 
        """

        # Enable byte system to be signed-value type
        if self.signed_type == True:
            conf.SIGNED_VALUES = True
        else:
            conf.SIGNED_VALUES = False

        # Generate modbus RTU message
        try:
            message = modbus_rtu.write_multiple_registers(
                slave_id=self.device_id,
                starting_address=start_register_address,
                values=write_values)
        except Exception as e:
            print("Error during generate modbus message.")
            print(
                "\tMaybe, write value is less than 0 as signed integer and .signed_type is set to 'False'."
            )

        # Send message via serial port
        try:
            if self.serialport.is_open:
                response = modbus_rtu.send_message(message, self.serialport)
                print("response={}".format(response))
            else:
                print("Error : Cannot send data. Serial port is closed.")
        except Exception as e:
            print("Error during send modbus message.")
            print(e)
import struct
from serial import Serial, PARITY_NONE

from umodbus.client.serial import rtu


def get_serial_port():
    """ Return serial.Serial instance, ready to use for RS485."""
    port = Serial(port='/dev/ttyS1', baudrate=9600, parity=PARITY_NONE,
                  stopbits=1, bytesize=8, timeout=1)

    fh = port.fileno()

    # A struct with configuration for serial port.
    serial_rs485 = struct.pack('hhhhhhhh', 1, 0, 0, 0, 0, 0, 0, 0)
    fcntl.ioctl(fh, 0x542F, serial_rs485)

    return port

serial_port = get_serial_port()

# Returns a message or Application Data Unit (ADU) specific for doing
# Modbus RTU.
message = rtu.write_multiple_coils(slave_id=1, address=1, values=[1, 0, 1, 1])

# Response depends on Modbus function code. This particular returns the
# amount of coils written, in this case it is.
response = rtu.send_message(message, serial_port)

serial_port.close()
Exemple #30
0
 def get_frequency(self):
     message = rtu.read_holding_registers(DEVICE_ADDRESS, REG_OUTPUT_FREQ,
                                          1)
     (response, ) = rtu.send_message(message, self.serial)
     return response * 0.01  # Hz
Exemple #31
0
 def stop(self):
     message = rtu.write_single_register(DEVICE_ADDRESS, REG_STATUS_CONTROL,
                                         0b1)
     response = rtu.send_message(message, self.serial)
     return response