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]]}
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
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
def read_holding(self, reg): # read a single holding register at reg address try: serial_port = self.get_serial_port() message = rtu.read_holding_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
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]]
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]
def __init__(self, context: ModbusContext, unit: int, identification_code: int): self.__context = context self.__unit = unit self.__identification_code = identification_code serial_message = modbus.read_holding_registers(slave_id=unit, starting_address=20480, quantity=7) response = context.send(serial_message, timeout=0.5) self.__serial = util.decode_response_str(response) super().__init__(context, ALL_STRUCTS, unit)
def __read_all_values(self, observer: Observer): message1 = modbus.read_holding_registers(slave_id=self.__unit, starting_address=0, quantity=50) message2 = modbus.read_holding_registers(slave_id=self.__unit, starting_address=50, quantity=50) message3 = modbus.read_holding_registers(slave_id=self.__unit, starting_address=100, quantity=2) first_batch = self.__context.send(message1, 0.5) second_batch = self.__context.send(message2, 0.5) message3 = self.__context.send(message3, 0.5) all_values = first_batch + second_batch values = struct.unpack("23i6h25i", struct.pack("102H", *all_values)) for k, v in VALUE_MAP.items(): observer.on_next(DeviceValue(self, v, values[k]))
def __init__(self, context: ModbusContext, unit: int, identification_code: int): super().__init__(unit) assert identification_code in PRODUCT_MAP self.__context = context self.__unit = unit self.__identification_code = identification_code read_serial: bytes = modbus.read_holding_registers( slave_id=self.__unit, starting_address=20480, quantity=7) serial_response = context.send(message=read_serial, timeout=0.5) self.__serial_number = util.decode_response_str(serial_response)
def scan(self, unit: int) -> Optional[ModbusDevice]: try: message = modbus.read_holding_registers(slave_id=unit, starting_address=0x0b, quantity=1) response = self._context.send(message, timeout=0.25) if response is None: return identification_code = response[0] if 330 <= identification_code <= 346: return Ex300(self._context, unit, identification_code) except (ValueError, CRCError, ModbusError): pass
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
def __read_struct(self, s: _ModbusStruct) -> None: message = modbus.read_holding_registers( slave_id=self.__unit, starting_address=s.start_address, quantity=s.length) response = self.__context.send(message, 0.5, 3) if response is None: raise RuntimeError("Communication timed out") values = struct.unpack(s.fmt, struct.pack(f"{s.length}H", *response)) for i in range(len(values)): if i not in s.type_map: continue super()._publish_value( DeviceValue(device=self, type=s.type_map[i], value=values[i]))
def read_holding_registers(self, start_register_address, number_of_registers): """ Modbus command : Read data to holding registers (function code = 03) @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_holding_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
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
def read_holding_registers(self, slave_id, address, quantity, port): self.serial_port = self.get_serial_port(port) add = int(address) - 1 message = rtu.read_holding_registers(slave_id=int(slave_id), starting_address=add, quantity=int(quantity)) print(message) hexadecimal_string = message.hex() print(hexadecimal_string) response = rtu.send_message(message, self.serial_port) print("response", response) index = 0 for i in response: if (i & 0x8000): s16 = -(((~i) & 0xFFFF) + 1) else: s16 = i response[index] = s16 index = index + 1 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) self.serial_port.close() return result
array_message = [] for i in range(0, len(raw_message), 2): array_message.append((ord(raw_message[i]) << 8) | ord(raw_message[i+1])) for e in array_message: print(hex(e)) serial_port = get_serial_port() message = rtu.write_multiple_registers(slave_id=1, starting_address=1, values=array_message) print(message) response = rtu.send_message(message, serial_port) print("response", response) time.sleep(1) message = rtu.read_holding_registers(slave_id=1, starting_address=1, quantity=30) response = rtu.send_message(message, serial_port) print("response", response) restored_message = "" for i in response: restored_message += chr(i & ((1 << 8) - 1)) restored_message += chr(i >> 8) print("restored message: ", restored_message) serial_port.close()
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
def is_running(self): message = rtu.read_holding_registers(DEVICE_ADDRESS, REG_STATUS_CONTROL, 1) (response, ) = rtu.send_message(message, self.serial) return bool(response & 0x1)
def get_frequency(self): message = rtu.read_holding_registers(DEVICE_ADDRESS, REG_PI2_ACTUAL_SPEED, 1) (response,) = rtu.send_message(message, self.serial) return response
def is_running(self): message = rtu.read_holding_registers(DEVICE_ADDRESS, REG_PI1_STATUS_WORD, 1) (response,) = rtu.send_message(message, self.serial) return bool(response & 0b0000010000000000)
def read_parameter(self, slave_id, address): """ Read a parameter from a targeted device as a float. Note ----- All parameters accessible from *RCC* can also be accessed with the *Modbus* protocol.\n It is possible to read the actual value of the parameter from Flash, but also the minimum and the maximum value.\n To distinguish between these, we use a different register address offset as explained below:\n - read value from flash : offset is 0 (READ_PARAM_FLASH_OFFSET)\n - read min allowed value : offset is 2000 (READ_PARAM_MIN_OFFSET)\n - read max allowed value : offset is 4000 (READ_PARAM_MAX_OFFSET)\n Parameters ---------- slave_id: int Slave identifier number (targeted device) address: int Register starting address, see Studer Modbus RTU Appendix for the complete list of accessible register per device Returns ------- float parameter read Example -------- .. code-block:: python # Read parameter 1107, Maximum current of AC source, (Modbus register 14) from the first Xtender # Run this example within the 'examples/' folder using 'python ex_read_param.py' from a CLI # after installing xcom485i package with 'pip install xcom485i' import serial from xcom485i.client import Xcom485i SERIAL_PORT_NAME = 'COM4' # your serial port interface name SERIAL_PORT_BAUDRATE = 9600 # baudrate used by your serial interface DIP_SWITCHES_ADDRESS_OFFSET = 0 # your modbus address offset as set inside the Xcom485i device if __name__ == "__main__": try: serial_port = serial.Serial(SERIAL_PORT_NAME, SERIAL_PORT_BAUDRATE, parity=serial.PARITY_EVEN, timeout=1) except serial.serialutil.SerialException as e: print("Check your serial configuration : ", e) else: xcom485i = Xcom485i(serial_port, DIP_SWITCHES_ADDRESS_OFFSET, debug=True) # read actual value stored into flash memory read_value = xcom485i.read_parameter(xcom485i.addresses.xt_1_device_id, 14 + xcom485i.addresses.read_param_flash_offset) print('read_value:', read_value) # read minimum value of this parameter read_value = xcom485i.read_parameter(xcom485i.addresses.xt_1_device_id, 14 + xcom485i.addresses.read_param_min_offset) assert read_value == 2.0 # only for 1107 parameter print('read_min_value:', read_value) # read maximum value of this parameter read_value = xcom485i.read_parameter(xcom485i.addresses.xt_1_device_id, 14 + xcom485i.addresses.read_param_max_offset) assert read_value == 50.0 # only for 1107 parameter print('read_max_value:', read_value) """ message = rtu.read_holding_registers(slave_id=slave_id, starting_address=address, quantity=2) 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: ba = pack('>HH', response[0], response[1]) float_response = unpack('>f', ba)[0] logger.debug("<- Receive data : 0x%s", str(ba.hex())) return float_response