m5stack co2 sensor
This commit is contained in:
80
my_components/neopool/__init__.py
Normal file
80
my_components/neopool/__init__.py
Normal file
@@ -0,0 +1,80 @@
|
||||
from esphome.components import select
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
|
||||
|
||||
from esphome.const import CONF_ID, CONF_ADDRESS
|
||||
from esphome.components.modbus_controller import (
|
||||
add_modbus_base_properties,
|
||||
modbus_controller_ns,
|
||||
modbus_calc_properties,
|
||||
validate_modbus_register,
|
||||
ModbusItemBaseSchema,
|
||||
SensorItem,
|
||||
MODBUS_REGISTER_TYPE,
|
||||
)
|
||||
|
||||
from ..const import (
|
||||
CONF_BITMASK,
|
||||
CONF_FORCE_NEW_RANGE,
|
||||
CONF_MODBUS_CONTROLLER_ID,
|
||||
CONF_REGISTER_TYPE,
|
||||
CONF_SKIP_UPDATES,
|
||||
CONF_USE_WRITE_MULTIPLE,
|
||||
CONF_WRITE_LAMBDA,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["modbus_controller"]
|
||||
CODEOWNERS = ["@mabau"]
|
||||
|
||||
|
||||
NeopoolFiltrationMode = modbus_controller_ns.class_(
|
||||
"NeopoolFiltrationMode", cg.Component, select.Select, SensorItem
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
select.select_schema(NeopoolFiltrationMode)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
#.extend(ModbusItemBaseSchema)
|
||||
#.extend(
|
||||
# {
|
||||
# cv.Required(CONF)
|
||||
# cv.Optional(CONF_REGISTER_TYPE): cv.enum(MODBUS_REGISTER_TYPE),
|
||||
# cv.Optional(CONF_USE_WRITE_MULTIPLE, default=False): cv.boolean,
|
||||
# cv.Optional(CONF_WRITE_LAMBDA): cv.returning_lambda,
|
||||
# }
|
||||
#),
|
||||
#validate_modbus_register,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
byte_offset, _ = modbus_calc_properties(config)
|
||||
var = cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
config[CONF_REGISTER_TYPE],
|
||||
config[CONF_ADDRESS],
|
||||
byte_offset,
|
||||
config[CONF_BITMASK],
|
||||
config[CONF_SKIP_UPDATES],
|
||||
config[CONF_FORCE_NEW_RANGE],
|
||||
)
|
||||
await cg.register_component(var, config)
|
||||
await switch.register_switch(var, config)
|
||||
|
||||
paren = await cg.get_variable(config[CONF_MODBUS_CONTROLLER_ID])
|
||||
cg.add(var.set_parent(paren))
|
||||
cg.add(var.set_use_write_mutiple(config[CONF_USE_WRITE_MULTIPLE]))
|
||||
cg.add(paren.add_sensor_item(var))
|
||||
if CONF_WRITE_LAMBDA in config:
|
||||
template_ = await cg.process_lambda(
|
||||
config[CONF_WRITE_LAMBDA],
|
||||
[
|
||||
(ModbusSwitch.operator("ptr"), "item"),
|
||||
(cg.bool_, "x"),
|
||||
(cg.std_vector.template(cg.uint8).operator("ref"), "payload"),
|
||||
],
|
||||
return_type=cg.optional.template(bool),
|
||||
)
|
||||
cg.add(var.set_write_template(template_))
|
||||
await add_modbus_base_properties(var, config, ModbusSwitch, bool, bool)
|
||||
89
my_components/neopool/filtration_mode.cpp
Normal file
89
my_components/neopool/filtration_mode.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "filtration_mode.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
|
||||
namespace esphome {
|
||||
namespace neopool {
|
||||
|
||||
void FiltrationSelect::dump_config() { LOG_SELECT(TAG, "Modbus Neopool Filtration Select", this); }
|
||||
|
||||
void FiltrationSelect::parse_and_publish(const std::vector<uint8_t> &data)
|
||||
{
|
||||
int64_t value = payload_to_number(data, this->sensor_value_type, this->offset, this->bitmask);
|
||||
|
||||
ESP_LOGD(TAG, "New select value %lld from payload", value);
|
||||
|
||||
optional<std::string> new_state;
|
||||
|
||||
if (this->transform_func_.has_value()) {
|
||||
auto val = (*this->transform_func_)(this, value, data);
|
||||
if (val.has_value()) {
|
||||
new_state = *val;
|
||||
ESP_LOGV(TAG, "lambda returned option %s", new_state->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_state.has_value()) {
|
||||
auto map_it = std::find(this->mapping_.cbegin(), this->mapping_.cend(), value);
|
||||
|
||||
if (map_it != this->mapping_.cend()) {
|
||||
size_t idx = std::distance(this->mapping_.cbegin(), map_it);
|
||||
new_state = this->traits.get_options()[idx];
|
||||
ESP_LOGV(TAG, "Found option %s for value %lld", new_state->c_str(), value);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "No option found for mapping %lld", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_state.has_value()) {
|
||||
this->publish_state(new_state.value());
|
||||
}
|
||||
}
|
||||
|
||||
void FiltrationSelect::control(const std::string &value) {
|
||||
auto options = this->traits.get_options();
|
||||
auto opt_it = std::find(options.cbegin(), options.cend(), value);
|
||||
size_t idx = std::distance(options.cbegin(), opt_it);
|
||||
optional<int64_t> mapval = this->mapping_[idx];
|
||||
ESP_LOGD(TAG, "Found value %lld for option '%s'", *mapval, value.c_str());
|
||||
|
||||
std::vector<uint16_t> data;
|
||||
|
||||
if (this->write_transform_func_.has_value()) {
|
||||
auto val = (*this->write_transform_func_)(this, value, *mapval, data);
|
||||
if (val.has_value()) {
|
||||
mapval = *val;
|
||||
ESP_LOGV(TAG, "write_lambda returned mapping value %lld", *mapval);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Communication handled by write_lambda - exiting control");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.empty()) {
|
||||
number_to_payload(data, *mapval, this->sensor_value_type);
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Using payload from write lambda");
|
||||
}
|
||||
|
||||
if (data.empty()) {
|
||||
ESP_LOGW(TAG, "No payload was created for updating select");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16_t write_address = this->start_address + this->offset / 2;
|
||||
ModbusCommandItem write_cmd;
|
||||
if ((this->register_count == 1) && (!this->use_write_multiple_)) {
|
||||
write_cmd = ModbusCommandItem::create_write_single_command(parent_, write_address, data[0]);
|
||||
} else {
|
||||
write_cmd = ModbusCommandItem::create_write_multiple_command(parent_, write_address, this->register_count, data);
|
||||
}
|
||||
|
||||
parent_->queue_command(write_cmd);
|
||||
|
||||
if (this->optimistic_)
|
||||
this->publish_state(value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
56
my_components/neopool/filtration_mode.h
Normal file
56
my_components/neopool/filtration_mode.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/components/modbus_controller/modbus_controller.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace neopool {
|
||||
/**
|
||||
* @brief Controls the filtration mode of the Neopool device connected via modbus
|
||||
*
|
||||
* Possible states:
|
||||
* - automatic
|
||||
* - off
|
||||
* - slow
|
||||
* - medium
|
||||
* - fast
|
||||
*
|
||||
* To read the state:
|
||||
* reads relay register 0x010E, with bitmasks
|
||||
* - 0x0100 slow
|
||||
* - 0x0200 medium
|
||||
* - 0x0400 high
|
||||
* - 0x0010 filtering
|
||||
* auto / non-auto: 0x0411:
|
||||
* - MBV_PAR_FILT_MANUAL = 0, // This mode allows to turn the filtration (and all other systems that depend on it) on and off manually.
|
||||
* MBV_PAR_FILT_AUTO = 1, // This mode allows filtering to be turned on and off according to the settings of the TIMER1, TIMER2 and TIMER3 timers.
|
||||
*
|
||||
* To set the manual state:
|
||||
* set filtration speed to addr 0x050F (MBF_PAR_FILTRATION_CONF), register needs to be read first to be correctly modified
|
||||
* set MBF_EXEC to 1
|
||||
* set filtration mode to manual (=0) via MBF_PAR_FILT_MODE (0x0411)
|
||||
* set manual mode filtration to on 0x0413 to 0, 1, 2, ?
|
||||
*
|
||||
*/
|
||||
class FiltrationMode : public Component, public select::Select {
|
||||
public:
|
||||
void set_parent(ModbusController *const parent) { this->parent_ = parent; }
|
||||
|
||||
void dump_config() override;
|
||||
void control(const std::string &value) override;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
ModbusController *parent_;
|
||||
};
|
||||
|
||||
} // namespace modbus_controller
|
||||
} // namespace esphome
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user