mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 00:18:11 +01:00
teleinfo: use text_sensor and sensor. (#1403)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Otto winter <otto@otto-winter.com>
This commit is contained in:
parent
48b5ea9e59
commit
afa436fe8f
11 changed files with 163 additions and 87 deletions
|
@ -1 +1,28 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import uart
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
CODEOWNERS = ["@0hax"]
|
CODEOWNERS = ["@0hax"]
|
||||||
|
|
||||||
|
teleinfo_ns = cg.esphome_ns.namespace("teleinfo")
|
||||||
|
TeleInfo = teleinfo_ns.class_("TeleInfo", cg.PollingComponent, uart.UARTDevice)
|
||||||
|
CONF_TELEINFO_ID = "teleinfo_id"
|
||||||
|
|
||||||
|
CONF_HISTORICAL_MODE = "historical_mode"
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(TeleInfo),
|
||||||
|
cv.Optional(CONF_HISTORICAL_MODE, default=False): cv.boolean,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.polling_component_schema("60s"))
|
||||||
|
.extend(uart.UART_DEVICE_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], config[CONF_HISTORICAL_MODE])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield uart.register_uart_device(var, config)
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
import esphome.codegen as cg
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome.components import sensor, uart
|
|
||||||
from esphome.const import (
|
|
||||||
CONF_ID,
|
|
||||||
CONF_SENSOR,
|
|
||||||
DEVICE_CLASS_POWER,
|
|
||||||
ICON_EMPTY,
|
|
||||||
UNIT_WATT_HOURS,
|
|
||||||
)
|
|
||||||
|
|
||||||
DEPENDENCIES = ["uart"]
|
|
||||||
|
|
||||||
teleinfo_ns = cg.esphome_ns.namespace("teleinfo")
|
|
||||||
TeleInfo = teleinfo_ns.class_("TeleInfo", cg.PollingComponent, uart.UARTDevice)
|
|
||||||
|
|
||||||
CONF_TAG_NAME = "tag_name"
|
|
||||||
TELEINFO_TAG_SCHEMA = cv.Schema(
|
|
||||||
{
|
|
||||||
cv.Required(CONF_TAG_NAME): cv.string,
|
|
||||||
cv.Required(CONF_SENSOR): sensor.sensor_schema(
|
|
||||||
UNIT_WATT_HOURS, ICON_EMPTY, 0, DEVICE_CLASS_POWER
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
CONF_TAGS = "tags"
|
|
||||||
CONF_HISTORICAL_MODE = "historical_mode"
|
|
||||||
CONFIG_SCHEMA = (
|
|
||||||
cv.Schema(
|
|
||||||
{
|
|
||||||
cv.GenerateID(): cv.declare_id(TeleInfo),
|
|
||||||
cv.Optional(CONF_HISTORICAL_MODE, default=False): cv.boolean,
|
|
||||||
cv.Optional(CONF_TAGS): cv.ensure_list(TELEINFO_TAG_SCHEMA),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.extend(cv.polling_component_schema("60s"))
|
|
||||||
.extend(uart.UART_DEVICE_SCHEMA)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
|
||||||
var = cg.new_Pvariable(config[CONF_ID], config[CONF_HISTORICAL_MODE])
|
|
||||||
await cg.register_component(var, config)
|
|
||||||
await uart.register_uart_device(var, config)
|
|
||||||
|
|
||||||
if CONF_TAGS in config:
|
|
||||||
for tag in config[CONF_TAGS]:
|
|
||||||
sens = await sensor.new_sensor(tag[CONF_SENSOR])
|
|
||||||
cg.add(var.register_teleinfo_sensor(tag[CONF_TAG_NAME], sens))
|
|
26
esphome/components/teleinfo/sensor/__init__.py
Normal file
26
esphome/components/teleinfo/sensor/__init__.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import sensor
|
||||||
|
from esphome.const import CONF_ID, ICON_FLASH, UNIT_WATT_HOURS
|
||||||
|
|
||||||
|
from .. import teleinfo_ns, TeleInfo, CONF_TELEINFO_ID
|
||||||
|
|
||||||
|
CONF_TAG_NAME = "tag_name"
|
||||||
|
|
||||||
|
TeleInfoSensor = teleinfo_ns.class_("TeleInfoSensor", sensor.Sensor, cg.Component)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_WATT_HOURS, ICON_FLASH, 0).extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(TeleInfoSensor),
|
||||||
|
cv.GenerateID(CONF_TELEINFO_ID): cv.use_id(TeleInfo),
|
||||||
|
cv.Required(CONF_TAG_NAME): cv.string,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], config[CONF_TAG_NAME])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield sensor.register_sensor(var, config)
|
||||||
|
teleinfo = yield cg.get_variable(config[CONF_TELEINFO_ID])
|
||||||
|
cg.add(teleinfo.register_teleinfo_listener(var))
|
14
esphome/components/teleinfo/sensor/teleinfo_sensor.cpp
Normal file
14
esphome/components/teleinfo/sensor/teleinfo_sensor.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "teleinfo_sensor.h"
|
||||||
|
namespace esphome {
|
||||||
|
namespace teleinfo {
|
||||||
|
|
||||||
|
static const char *TAG = "teleinfo_sensor";
|
||||||
|
TeleInfoSensor::TeleInfoSensor(const char *tag) { this->tag = std::string(tag); }
|
||||||
|
void TeleInfoSensor::publish_val(std::string val) {
|
||||||
|
auto newval = parse_float(val);
|
||||||
|
publish_state(*newval);
|
||||||
|
}
|
||||||
|
void TeleInfoSensor::dump_config() { LOG_SENSOR(" ", tag.c_str(), this); }
|
||||||
|
} // namespace teleinfo
|
||||||
|
} // namespace esphome
|
16
esphome/components/teleinfo/sensor/teleinfo_sensor.h
Normal file
16
esphome/components/teleinfo/sensor/teleinfo_sensor.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
#include "esphome/components/teleinfo/teleinfo.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace teleinfo {
|
||||||
|
|
||||||
|
class TeleInfoSensor : public TeleInfoListener, public sensor::Sensor, public Component {
|
||||||
|
public:
|
||||||
|
TeleInfoSensor(const char *tag);
|
||||||
|
void publish_val(std::string val) override;
|
||||||
|
void dump_config() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace teleinfo
|
||||||
|
} // namespace esphome
|
|
@ -149,16 +149,14 @@ void TeleInfo::loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TeleInfo::publish_value_(std::string tag, std::string val) {
|
void TeleInfo::publish_value_(std::string tag, std::string val) {
|
||||||
/* It will return 0 if tag is not a float. */
|
for (auto element : teleinfo_listeners_) {
|
||||||
auto newval = parse_float(val);
|
if (tag != element->tag)
|
||||||
for (auto element : teleinfo_sensors_)
|
continue;
|
||||||
if (tag == element->tag)
|
element->publish_val(val);
|
||||||
element->sensor->publish_state(*newval);
|
}
|
||||||
}
|
}
|
||||||
void TeleInfo::dump_config() {
|
void TeleInfo::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "TeleInfo:");
|
ESP_LOGCONFIG(TAG, "TeleInfo:");
|
||||||
for (auto element : teleinfo_sensors_)
|
|
||||||
LOG_SENSOR(" ", element->tag, element->sensor);
|
|
||||||
this->check_uart_settings(baud_rate_, 1, uart::UART_CONFIG_PARITY_EVEN, 7);
|
this->check_uart_settings(baud_rate_, 1, uart::UART_CONFIG_PARITY_EVEN, 7);
|
||||||
}
|
}
|
||||||
TeleInfo::TeleInfo(bool historical_mode) {
|
TeleInfo::TeleInfo(bool historical_mode) {
|
||||||
|
@ -175,10 +173,7 @@ TeleInfo::TeleInfo(bool historical_mode) {
|
||||||
baud_rate_ = 9600;
|
baud_rate_ = 9600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TeleInfo::register_teleinfo_sensor(const char *tag, sensor::Sensor *sensor) {
|
void TeleInfo::register_teleinfo_listener(TeleInfoListener *listener) { teleinfo_listeners_.push_back(listener); }
|
||||||
const TeleinfoSensorElement *teleinfo_sensor = new TeleinfoSensorElement{tag, sensor};
|
|
||||||
teleinfo_sensors_.push_back(teleinfo_sensor);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace teleinfo
|
} // namespace teleinfo
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/components/sensor/sensor.h"
|
|
||||||
#include "esphome/components/uart/uart.h"
|
#include "esphome/components/uart/uart.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
@ -14,20 +13,20 @@ static const uint8_t MAX_TAG_SIZE = 64;
|
||||||
static const uint16_t MAX_VAL_SIZE = 256;
|
static const uint16_t MAX_VAL_SIZE = 256;
|
||||||
static const uint16_t MAX_BUF_SIZE = 1024;
|
static const uint16_t MAX_BUF_SIZE = 1024;
|
||||||
|
|
||||||
struct TeleinfoSensorElement {
|
class TeleInfoListener {
|
||||||
const char *tag;
|
public:
|
||||||
sensor::Sensor *sensor;
|
std::string tag;
|
||||||
|
virtual void publish_val(std::string val){};
|
||||||
};
|
};
|
||||||
|
|
||||||
class TeleInfo : public PollingComponent, public uart::UARTDevice {
|
class TeleInfo : public PollingComponent, public uart::UARTDevice {
|
||||||
public:
|
public:
|
||||||
TeleInfo(bool historical_mode);
|
TeleInfo(bool historical_mode);
|
||||||
void register_teleinfo_sensor(const char *tag, sensor::Sensor *sensors);
|
void register_teleinfo_listener(TeleInfoListener *listener);
|
||||||
void loop() override;
|
void loop() override;
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void update() override;
|
void update() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
std::vector<const TeleinfoSensorElement *> teleinfo_sensors_{};
|
std::vector<TeleInfoListener *> teleinfo_listeners_{};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t baud_rate_;
|
uint32_t baud_rate_;
|
||||||
|
|
28
esphome/components/teleinfo/text_sensor/__init__.py
Normal file
28
esphome/components/teleinfo/text_sensor/__init__.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import text_sensor
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
from .. import teleinfo_ns, TeleInfo, CONF_TELEINFO_ID
|
||||||
|
|
||||||
|
CONF_TAG_NAME = "tag_name"
|
||||||
|
|
||||||
|
TeleInfoTextSensor = teleinfo_ns.class_(
|
||||||
|
"TeleInfoTextSensor", text_sensor.TextSensor, cg.Component
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(TeleInfoTextSensor),
|
||||||
|
cv.GenerateID(CONF_TELEINFO_ID): cv.use_id(TeleInfo),
|
||||||
|
cv.Required(CONF_TAG_NAME): cv.string,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], config[CONF_TAG_NAME])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield text_sensor.register_text_sensor(var, config)
|
||||||
|
teleinfo = yield cg.get_variable(config[CONF_TELEINFO_ID])
|
||||||
|
cg.add(teleinfo.register_teleinfo_listener(var))
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "teleinfo_text_sensor.h"
|
||||||
|
namespace esphome {
|
||||||
|
namespace teleinfo {
|
||||||
|
|
||||||
|
static const char *TAG = "teleinfo_text_sensor";
|
||||||
|
TeleInfoTextSensor::TeleInfoTextSensor(const char *tag) { this->tag = std::string(tag); }
|
||||||
|
void TeleInfoTextSensor::publish_val(std::string val) { publish_state(val); }
|
||||||
|
void TeleInfoTextSensor::dump_config() { LOG_TEXT_SENSOR(" ", tag.c_str(), this); }
|
||||||
|
} // namespace teleinfo
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "esphome/components/teleinfo/teleinfo.h"
|
||||||
|
#include "esphome/components/text_sensor/text_sensor.h"
|
||||||
|
namespace esphome {
|
||||||
|
namespace teleinfo {
|
||||||
|
class TeleInfoTextSensor : public TeleInfoListener, public text_sensor::TextSensor, public Component {
|
||||||
|
public:
|
||||||
|
TeleInfoTextSensor(const char *tag);
|
||||||
|
void publish_val(std::string val) override;
|
||||||
|
void dump_config() override;
|
||||||
|
};
|
||||||
|
} // namespace teleinfo
|
||||||
|
} // namespace esphome
|
|
@ -888,25 +888,11 @@ sensor:
|
||||||
name: 'AQI'
|
name: 'AQI'
|
||||||
calculation_type: 'CAQI'
|
calculation_type: 'CAQI'
|
||||||
- platform: teleinfo
|
- platform: teleinfo
|
||||||
uart_id: uart0
|
tag_name: "HCHC"
|
||||||
tags:
|
name: "hchc"
|
||||||
- tag_name: 'HCHC'
|
unit_of_measurement: "Wh"
|
||||||
sensor:
|
icon: mdi:flash
|
||||||
name: 'hchc'
|
teleinfo_id: myteleinfo
|
||||||
unit_of_measurement: 'Wh'
|
|
||||||
icon: mdi:flash
|
|
||||||
- tag_name: 'HCHP'
|
|
||||||
sensor:
|
|
||||||
name: 'hchp'
|
|
||||||
unit_of_measurement: 'Wh'
|
|
||||||
icon: mdi:flash
|
|
||||||
- tag_name: 'PAPP'
|
|
||||||
sensor:
|
|
||||||
name: 'papp'
|
|
||||||
unit_of_measurement: 'VA'
|
|
||||||
icon: mdi:flash
|
|
||||||
update_interval: 60s
|
|
||||||
historical_mode: true
|
|
||||||
- platform: mcp9808
|
- platform: mcp9808
|
||||||
name: 'MCP9808 Temperature'
|
name: 'MCP9808 Temperature'
|
||||||
update_interval: 15s
|
update_interval: 15s
|
||||||
|
@ -1975,6 +1961,7 @@ display:
|
||||||
row_start: 0
|
row_start: 0
|
||||||
lambda: |-
|
lambda: |-
|
||||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
|
||||||
tm1651:
|
tm1651:
|
||||||
id: tm1651_battery
|
id: tm1651_battery
|
||||||
clk_pin: GPIO23
|
clk_pin: GPIO23
|
||||||
|
@ -2163,6 +2150,10 @@ text_sensor:
|
||||||
- platform: version
|
- platform: version
|
||||||
name: 'ESPHome Version No Timestamp'
|
name: 'ESPHome Version No Timestamp'
|
||||||
hide_timestamp: True
|
hide_timestamp: True
|
||||||
|
- platform: teleinfo
|
||||||
|
tag_name: "OPTARIF"
|
||||||
|
name: "optarif"
|
||||||
|
teleinfo_id: myteleinfo
|
||||||
|
|
||||||
sn74hc595:
|
sn74hc595:
|
||||||
- id: 'sn74hc595_hub'
|
- id: 'sn74hc595_hub'
|
||||||
|
@ -2193,3 +2184,9 @@ canbus:
|
||||||
lambda: 'return x[0] == 0x11;'
|
lambda: 'return x[0] == 0x11;'
|
||||||
then:
|
then:
|
||||||
light.toggle: ${roomname}_lights
|
light.toggle: ${roomname}_lights
|
||||||
|
|
||||||
|
teleinfo:
|
||||||
|
id: myteleinfo
|
||||||
|
uart_id: uart0
|
||||||
|
update_interval: 60s
|
||||||
|
historical_mode: true
|
||||||
|
|
Loading…
Reference in a new issue