mirror of
https://github.com/esphome/esphome.git
synced 2024-11-24 07:58:09 +01:00
added manual configurable device_info text_sensor
This commit is contained in:
parent
a8ed21ae74
commit
d084160b33
9 changed files with 99 additions and 51 deletions
|
@ -4,7 +4,6 @@ import esphome.codegen as cg
|
||||||
from esphome.components import text_sensor as ts
|
from esphome.components import text_sensor as ts
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ADDRESS,
|
|
||||||
CONF_DIV_RATIO,
|
CONF_DIV_RATIO,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_LOGGER,
|
CONF_LOGGER,
|
||||||
|
@ -42,8 +41,6 @@ SENSOR_BASE_SCHEMA = cv.Schema(
|
||||||
cv.positive_time_period_milliseconds,
|
cv.positive_time_period_milliseconds,
|
||||||
cv.Range(min=core.TimePeriod(seconds=1), max=core.TimePeriod(seconds=1800)),
|
cv.Range(min=core.TimePeriod(seconds=1), max=core.TimePeriod(seconds=1800)),
|
||||||
),
|
),
|
||||||
cv.Required(CONF_ADDRESS): cv.hex_uint32_t,
|
|
||||||
# cv.Required(CONF_BYTES): cv.one_of(1, 2, 4, int=True),
|
|
||||||
cv.Optional(CONF_DIV_RATIO, default=1): cv.one_of(
|
cv.Optional(CONF_DIV_RATIO, default=1): cv.one_of(
|
||||||
1, 10, 100, 1000, 3600, int=True
|
1, 10, 100, 1000, 3600, int=True
|
||||||
),
|
),
|
||||||
|
@ -79,7 +76,6 @@ CONFIG_SCHEMA = cv.All(
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_LOGGER, default=False): cv.boolean,
|
cv.Optional(CONF_LOGGER, default=False): cv.boolean,
|
||||||
cv.Optional(CONF_STATE): cv.string,
|
cv.Optional(CONF_STATE): cv.string,
|
||||||
cv.Optional(CONF_DEVICE_INFO): cv.string,
|
|
||||||
}
|
}
|
||||||
).extend(cv.COMPONENT_SCHEMA),
|
).extend(cv.COMPONENT_SCHEMA),
|
||||||
cv.only_with_arduino,
|
cv.only_with_arduino,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.components import binary_sensor
|
from esphome.components import binary_sensor
|
||||||
from esphome.const import CONF_ADDRESS, CONF_ID
|
from esphome.const import CONF_ADDRESS, CONF_ID
|
||||||
from .. import SENSOR_BASE_SCHEMA, optolink_ns, CONF_OPTOLINK_ID
|
from .. import SENSOR_BASE_SCHEMA, optolink_ns, CONF_OPTOLINK_ID
|
||||||
|
@ -10,8 +11,16 @@ CODEOWNERS = ["@j0ta29"]
|
||||||
OptolinkBinarySensor = optolink_ns.class_(
|
OptolinkBinarySensor = optolink_ns.class_(
|
||||||
"OptolinkBinarySensor", binary_sensor.BinarySensor, cg.PollingComponent
|
"OptolinkBinarySensor", binary_sensor.BinarySensor, cg.PollingComponent
|
||||||
)
|
)
|
||||||
CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(OptolinkBinarySensor).extend(
|
|
||||||
SENSOR_BASE_SCHEMA
|
CONFIG_SCHEMA = (
|
||||||
|
binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(OptolinkBinarySensor),
|
||||||
|
cv.Required(CONF_ADDRESS): cv.hex_uint32_t,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.extend(SENSOR_BASE_SCHEMA)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ OptolinkNumber = optolink_ns.class_(
|
||||||
"OptolinkNumber", number.Number, cg.PollingComponent
|
"OptolinkNumber", number.Number, cg.PollingComponent
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
number.NUMBER_SCHEMA.extend(
|
number.NUMBER_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
|
@ -27,6 +28,7 @@ CONFIG_SCHEMA = (
|
||||||
cv.Required(CONF_MAX_VALUE): cv.float_,
|
cv.Required(CONF_MAX_VALUE): cv.float_,
|
||||||
cv.Required(CONF_MIN_VALUE): cv.float_range(min=0.0),
|
cv.Required(CONF_MIN_VALUE): cv.float_range(min=0.0),
|
||||||
cv.Required(CONF_STEP): cv.float_,
|
cv.Required(CONF_STEP): cv.float_,
|
||||||
|
cv.Required(CONF_ADDRESS): cv.hex_uint32_t,
|
||||||
cv.Required(CONF_BYTES): cv.one_of(1, 2, 4, int=True),
|
cv.Required(CONF_BYTES): cv.one_of(1, 2, 4, int=True),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -43,6 +43,7 @@ CONFIG_SCHEMA = (
|
||||||
cg.std_ns.class_("map").template(cg.std_string, cg.std_string)
|
cg.std_ns.class_("map").template(cg.std_string, cg.std_string)
|
||||||
),
|
),
|
||||||
cv.Required(CONF_MAP): cv.ensure_list(validate_mapping),
|
cv.Required(CONF_MAP): cv.ensure_list(validate_mapping),
|
||||||
|
cv.Required(CONF_ADDRESS): cv.hex_uint32_t,
|
||||||
cv.Required(CONF_BYTES): cv.one_of(1, 2, 4, int=True),
|
cv.Required(CONF_BYTES): cv.one_of(1, 2, 4, int=True),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,12 +17,14 @@ OptolinkSensor = optolink_ns.class_(
|
||||||
"OptolinkSensor", sensor.Sensor, cg.PollingComponent
|
"OptolinkSensor", sensor.Sensor, cg.PollingComponent
|
||||||
)
|
)
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
sensor.sensor_schema(OptolinkSensor)
|
sensor.SENSOR_SCHEMA.extend(
|
||||||
.extend(
|
|
||||||
{
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(OptolinkSensor),
|
||||||
|
cv.Required(CONF_ADDRESS): cv.hex_uint32_t,
|
||||||
cv.Required(CONF_BYTES): cv.one_of(1, 2, 4, int=True),
|
cv.Required(CONF_BYTES): cv.one_of(1, 2, 4, int=True),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
.extend(SENSOR_BASE_SCHEMA)
|
.extend(SENSOR_BASE_SCHEMA)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import switch
|
from esphome.components import switch
|
||||||
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_UPDATE_INTERVAL
|
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_UPDATE_INTERVAL
|
||||||
from .. import OptolinkComponent, optolink_ns
|
from .. import SENSOR_BASE_SCHEMA, optolink_ns
|
||||||
|
|
||||||
DEPENDENCIES = ["optolink"]
|
DEPENDENCIES = ["optolink"]
|
||||||
CODEOWNERS = ["@j0ta29"]
|
CODEOWNERS = ["@j0ta29"]
|
||||||
|
@ -14,17 +14,22 @@ OptolinkSwitch = optolink_ns.class_(
|
||||||
)
|
)
|
||||||
|
|
||||||
CONF_OPTOLINK_ID = "optolink_id"
|
CONF_OPTOLINK_ID = "optolink_id"
|
||||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend(
|
CONFIG_SCHEMA = (
|
||||||
{
|
switch.SWITCH_SCHEMA.extend(
|
||||||
cv.GenerateID(CONF_OPTOLINK_ID): cv.use_id(OptolinkComponent),
|
{
|
||||||
cv.GenerateID(): cv.declare_id(OptolinkSwitch),
|
cv.GenerateID(): cv.declare_id(OptolinkSwitch),
|
||||||
cv.Required(CONF_ADDRESS): cv.hex_uint32_t,
|
cv.Required(CONF_ADDRESS): cv.hex_uint32_t,
|
||||||
cv.Optional(CONF_UPDATE_INTERVAL, default="10s"): cv.All(
|
cv.Optional(CONF_UPDATE_INTERVAL, default="10s"): cv.All(
|
||||||
cv.positive_time_period_milliseconds,
|
cv.positive_time_period_milliseconds,
|
||||||
cv.Range(min=core.TimePeriod(seconds=1), max=core.TimePeriod(seconds=1800)),
|
cv.Range(
|
||||||
),
|
min=core.TimePeriod(seconds=1), max=core.TimePeriod(seconds=1800)
|
||||||
}
|
),
|
||||||
).extend(cv.COMPONENT_SCHEMA)
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.extend(SENSOR_BASE_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
|
|
|
@ -20,6 +20,7 @@ MODE = {
|
||||||
"RAW": TextSensorMode.RAW,
|
"RAW": TextSensorMode.RAW,
|
||||||
"DAY_SCHEDULE": TextSensorMode.DAY_SCHEDULE,
|
"DAY_SCHEDULE": TextSensorMode.DAY_SCHEDULE,
|
||||||
"DAY_SCHEDULE_SYNCHRONIZED": TextSensorMode.DAY_SCHEDULE_SYNCHRONIZED,
|
"DAY_SCHEDULE_SYNCHRONIZED": TextSensorMode.DAY_SCHEDULE_SYNCHRONIZED,
|
||||||
|
"DEVICE_INFO": TextSensorMode.DEVICE_INFO,
|
||||||
}
|
}
|
||||||
DAY_OF_WEEK = {
|
DAY_OF_WEEK = {
|
||||||
"MONDAY": 0,
|
"MONDAY": 0,
|
||||||
|
@ -93,15 +94,16 @@ def check_entity_id():
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
text_sensor.text_sensor_schema(OptolinkTextSensor)
|
text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||||
.extend(
|
|
||||||
{
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(OptolinkTextSensor),
|
||||||
cv.Optional(CONF_MODE, default="MAP"): cv.enum(MODE, upper=True),
|
cv.Optional(CONF_MODE, default="MAP"): cv.enum(MODE, upper=True),
|
||||||
cv.Optional(CONF_BYTES): cv.int_range(min=1, max=9),
|
cv.Optional(CONF_BYTES): cv.int_range(min=1, max=9),
|
||||||
cv.Optional(CONF_DAY_OF_WEEK): cv.enum(DAY_OF_WEEK, upper=True),
|
cv.Optional(CONF_DAY_OF_WEEK): cv.enum(DAY_OF_WEEK, upper=True),
|
||||||
cv.Optional(CONF_ENTITY_ID): cv.entity_id,
|
cv.Optional(CONF_ENTITY_ID): cv.entity_id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
.extend(SENSOR_BASE_SCHEMA),
|
.extend(SENSOR_BASE_SCHEMA),
|
||||||
check_bytes(),
|
check_bytes(),
|
||||||
check_dow(),
|
check_dow(),
|
||||||
|
@ -117,7 +119,8 @@ async def to_code(config):
|
||||||
await text_sensor.register_text_sensor(var, config)
|
await text_sensor.register_text_sensor(var, config)
|
||||||
|
|
||||||
cg.add(var.set_mode(config[CONF_MODE]))
|
cg.add(var.set_mode(config[CONF_MODE]))
|
||||||
cg.add(var.set_address(config[CONF_ADDRESS]))
|
if CONF_ADDRESS in config:
|
||||||
|
cg.add(var.set_address(config[CONF_ADDRESS]))
|
||||||
cg.add(var.set_div_ratio(config[CONF_DIV_RATIO]))
|
cg.add(var.set_div_ratio(config[CONF_DIV_RATIO]))
|
||||||
if CONF_BYTES in config:
|
if CONF_BYTES in config:
|
||||||
cg.add(var.set_bytes(config[CONF_BYTES]))
|
cg.add(var.set_bytes(config[CONF_BYTES]))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
|
#include "esphome/core/log.h"
|
||||||
#include "optolink_text_sensor.h"
|
#include "optolink_text_sensor.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "esphome/components/api/api_server.h"
|
#include "esphome/components/api/api_server.h"
|
||||||
|
@ -75,44 +76,55 @@ uint8_t *encode_time_string(std::string input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkTextSensor::setup() {
|
void OptolinkTextSensor::setup() {
|
||||||
if (mode_ == RAW) {
|
switch (mode_) {
|
||||||
div_ratio_ = 0;
|
case MAP:
|
||||||
} else if (mode_ == DAY_SCHEDULE) {
|
break;
|
||||||
div_ratio_ = 0;
|
case RAW:
|
||||||
bytes_ = 8;
|
div_ratio_ = 0;
|
||||||
address_ += (8 * dow_);
|
break;
|
||||||
} else if (mode_ == DAY_SCHEDULE_SYNCHRONIZED) {
|
case DAY_SCHEDULE:
|
||||||
writeable_ = true;
|
div_ratio_ = 0;
|
||||||
div_ratio_ = 0;
|
bytes_ = 8;
|
||||||
bytes_ = 8;
|
address_ += (8 * dow_);
|
||||||
address_ += (8 * dow_);
|
break;
|
||||||
api::global_api_server->subscribe_home_assistant_state(
|
case DAY_SCHEDULE_SYNCHRONIZED:
|
||||||
this->entity_id_, optional<std::string>(), [this](const std::string &state) {
|
writeable_ = true;
|
||||||
ESP_LOGD(TAG, "got time values from entity '%s': %s", this->entity_id_.c_str(), state.c_str());
|
div_ratio_ = 0;
|
||||||
uint8_t *data = encode_time_string(state);
|
bytes_ = 8;
|
||||||
if (data) {
|
address_ += (8 * dow_);
|
||||||
update_datapoint(data, 8);
|
api::global_api_server->subscribe_home_assistant_state(
|
||||||
} else {
|
this->entity_id_, optional<std::string>(), [this](const std::string &state) {
|
||||||
ESP_LOGW(TAG, "not changing any value of datapoint %s", datapoint_->getName());
|
ESP_LOGD(TAG, "got time values from entity '%s': %s", this->entity_id_.c_str(), state.c_str());
|
||||||
}
|
uint8_t *data = encode_time_string(state);
|
||||||
});
|
if (data) {
|
||||||
|
update_datapoint(data, 8);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "not changing any value of datapoint %s", datapoint_->getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case DEVICE_INFO:
|
||||||
|
set_entity_category(esphome::ENTITY_CATEGORY_DIAGNOSTIC);
|
||||||
|
bytes_ = 4;
|
||||||
|
address_ = 0x00f8;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
setup_datapoint();
|
setup_datapoint();
|
||||||
};
|
};
|
||||||
|
|
||||||
void OptolinkTextSensor::value_changed(uint8_t *state, size_t length) {
|
void OptolinkTextSensor::value_changed(uint8_t *value, size_t length) {
|
||||||
switch (mode_) {
|
switch (mode_) {
|
||||||
case RAW:
|
case RAW:
|
||||||
publish_state(std::string((const char *) state));
|
publish_state(std::string((const char *) value));
|
||||||
break;
|
break;
|
||||||
case DAY_SCHEDULE:
|
case DAY_SCHEDULE:
|
||||||
case DAY_SCHEDULE_SYNCHRONIZED:
|
case DAY_SCHEDULE_SYNCHRONIZED:
|
||||||
if (length == 8) {
|
if (length == 8) {
|
||||||
char buffer[6 * length + 1];
|
char buffer[6 * length + 1];
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
int hour = state[i] >> 3;
|
int hour = value[i] >> 3;
|
||||||
int minute = (state[i] & 0b111) * 10;
|
int minute = (value[i] & 0b111) * 10;
|
||||||
if (state[i] != 0xFF) {
|
if (value[i] != 0xFF) {
|
||||||
sprintf(buffer + i * 6, "%02d:%02d ", hour, minute);
|
sprintf(buffer + i * 6, "%02d:%02d ", hour, minute);
|
||||||
} else {
|
} else {
|
||||||
sprintf(buffer + i * 6, " ");
|
sprintf(buffer + i * 6, " ");
|
||||||
|
@ -123,12 +135,30 @@ void OptolinkTextSensor::value_changed(uint8_t *state, size_t length) {
|
||||||
unfitting_value_type();
|
unfitting_value_type();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DEVICE_INFO:
|
||||||
case MAP:
|
case MAP:
|
||||||
unfitting_value_type();
|
unfitting_value_type();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void OptolinkTextSensor::value_changed(uint32_t value) {
|
||||||
|
switch (mode_) {
|
||||||
|
case DEVICE_INFO: {
|
||||||
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %d", datapoint_->getName(), value);
|
||||||
|
uint8_t *bytes = (uint8_t *) &value;
|
||||||
|
uint16_t tmp = esphome::byteswap(*((uint16_t *) bytes));
|
||||||
|
std::string geraetekennung = esphome::format_hex_pretty(&tmp, 1);
|
||||||
|
std::string hardware_revision = esphome::format_hex_pretty((uint8_t *) bytes + 2, 1);
|
||||||
|
std::string software_index = esphome::format_hex_pretty((uint8_t *) bytes + 3, 1);
|
||||||
|
publish_state("Device ID: " + geraetekennung + "|Hardware Revision: " + hardware_revision +
|
||||||
|
"|Software Index: " + software_index);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
publish_state(std::to_string(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace optolink
|
} // namespace optolink
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace optolink {
|
namespace optolink {
|
||||||
|
|
||||||
enum TextSensorMode { MAP, RAW, DAY_SCHEDULE, DAY_SCHEDULE_SYNCHRONIZED };
|
enum TextSensorMode { MAP, RAW, DAY_SCHEDULE, DAY_SCHEDULE_SYNCHRONIZED, DEVICE_INFO };
|
||||||
|
|
||||||
class OptolinkTextSensor : public OptolinkSensorBase,
|
class OptolinkTextSensor : public OptolinkSensorBase,
|
||||||
public esphome::text_sensor::TextSensor,
|
public esphome::text_sensor::TextSensor,
|
||||||
|
@ -30,7 +30,7 @@ class OptolinkTextSensor : public OptolinkSensorBase,
|
||||||
void value_changed(float state) override { publish_state(std::to_string(state)); };
|
void value_changed(float state) override { publish_state(std::to_string(state)); };
|
||||||
void value_changed(uint8_t state) override { publish_state(std::to_string(state)); };
|
void value_changed(uint8_t state) override { publish_state(std::to_string(state)); };
|
||||||
void value_changed(uint16_t state) override { publish_state(std::to_string(state)); };
|
void value_changed(uint16_t state) override { publish_state(std::to_string(state)); };
|
||||||
void value_changed(uint32_t state) override { publish_state(std::to_string(state)); };
|
void value_changed(uint32_t state) override;
|
||||||
void value_changed(uint8_t *state, size_t length) override;
|
void value_changed(uint8_t *state, size_t length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue