mirror of
https://github.com/esphome/esphome.git
synced 2025-09-08 06:12:20 +01:00
Add Select for modbus (#3032)
Co-authored-by: Oxan van Leeuwen <oxan@oxanvanleeuwen.nl>
This commit is contained in:
@@ -195,7 +195,7 @@ inline bool coil_from_vector(int coil, const std::vector<uint8_t> &data) {
|
||||
*/
|
||||
template<typename N> N mask_and_shift_by_rightbit(N data, uint32_t mask) {
|
||||
auto result = (mask & data);
|
||||
if (result == 0) {
|
||||
if (result == 0 || mask == 0xFFFFFFFF) {
|
||||
return result;
|
||||
}
|
||||
for (size_t pos = 0; pos < sizeof(N) << 3; pos++) {
|
||||
@@ -205,22 +205,23 @@ template<typename N> N mask_and_shift_by_rightbit(N data, uint32_t mask) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** convert float value to vector<uint16_t> suitable for sending
|
||||
* @param value float value to cconvert
|
||||
/** Convert float value to vector<uint16_t> suitable for sending
|
||||
* @param data target for payload
|
||||
* @param value float value to convert
|
||||
* @param value_type defines if 16/32 or FP32 is used
|
||||
* @return vector containing the modbus register words in correct order
|
||||
*/
|
||||
std::vector<uint16_t> float_to_payload(float value, SensorValueType value_type);
|
||||
void number_to_payload(std::vector<uint16_t> &data, int64_t value, SensorValueType value_type);
|
||||
|
||||
/** convert vector<uint8_t> response payload to float
|
||||
* @param value float value to cconvert
|
||||
/** Convert vector<uint8_t> response payload to number.
|
||||
* @param data payload with the data to convert
|
||||
* @param sensor_value_type defines if 16/32/64 bits or FP32 is used
|
||||
* @param offset offset to the data in data
|
||||
* @param bitmask bitmask used for masking and shifting
|
||||
* @return float version of the input
|
||||
* @return 64-bit number of the payload
|
||||
*/
|
||||
float payload_to_float(const std::vector<uint8_t> &data, SensorValueType sensor_value_type, uint8_t offset,
|
||||
uint32_t bitmask);
|
||||
int64_t payload_to_number(const std::vector<uint8_t> &data, SensorValueType sensor_value_type, uint8_t offset,
|
||||
uint32_t bitmask);
|
||||
|
||||
class ModbusController;
|
||||
|
||||
@@ -348,11 +349,11 @@ class ModbusCommandItem {
|
||||
* @param modbusdevice pointer to the device to execute the command
|
||||
* @param start_address modbus address of the first register to read
|
||||
* @param register_count number of registers to read
|
||||
* @param values uint16_t array to be written to the registers
|
||||
* @param value uint16_t single register value to write
|
||||
* @return ModbusCommandItem with the prepared command
|
||||
*/
|
||||
static ModbusCommandItem create_write_single_command(ModbusController *modbusdevice, uint16_t start_address,
|
||||
int16_t value);
|
||||
uint16_t value);
|
||||
/** Create modbus write single registers command
|
||||
* Function 05 (05hex) Write Single Coil
|
||||
* @param modbusdevice pointer to the device to execute the command
|
||||
@@ -446,13 +447,36 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
|
||||
uint16_t command_throttle_;
|
||||
};
|
||||
|
||||
/** convert vector<uint8_t> response payload to float
|
||||
* @param value float value to cconvert
|
||||
/** Convert vector<uint8_t> response payload to float.
|
||||
* @param data payload with data
|
||||
* @param item SensorItem object
|
||||
* @return float version of the input
|
||||
* @return float value of data
|
||||
*/
|
||||
inline float payload_to_float(const std::vector<uint8_t> &data, const SensorItem &item) {
|
||||
return payload_to_float(data, item.sensor_value_type, item.offset, item.bitmask);
|
||||
int64_t number = payload_to_number(data, item.sensor_value_type, item.offset, item.bitmask);
|
||||
|
||||
float float_value;
|
||||
if (item.sensor_value_type == SensorValueType::FP32 || item.sensor_value_type == SensorValueType::FP32_R) {
|
||||
float_value = bit_cast<float>(static_cast<uint32_t>(number));
|
||||
} else {
|
||||
float_value = static_cast<float>(number);
|
||||
}
|
||||
|
||||
return float_value;
|
||||
}
|
||||
|
||||
inline std::vector<uint16_t> float_to_payload(float value, SensorValueType value_type) {
|
||||
int64_t val;
|
||||
|
||||
if (value_type == SensorValueType::FP32 || value_type == SensorValueType::FP32_R) {
|
||||
val = bit_cast<uint32_t>(value);
|
||||
} else {
|
||||
val = llroundf(value);
|
||||
}
|
||||
|
||||
std::vector<uint16_t> data;
|
||||
number_to_payload(data, val, value_type);
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace modbus_controller
|
||||
|
Reference in New Issue
Block a user