Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom binary sensor #162

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions components/samsung_ac/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import uart, sensor, switch, select, number, climate
from esphome.components import uart, sensor, switch, select, number, climate, binary_sensor
from esphome.const import (
CONF_ID,
DEVICE_CLASS_TEMPERATURE,
Expand All @@ -19,7 +19,7 @@

CODEOWNERS = ["matthias882", "lanwin"]
DEPENDENCIES = ["uart"]
AUTO_LOAD = ["sensor", "switch", "select", "number", "climate"]
AUTO_LOAD = ["sensor", "switch", "select", "number", "climate", "binary_sensor"]
MULTI_CONF = False

CONF_SAMSUNG_AC_ID = "samsung_ac_id"
Expand Down Expand Up @@ -67,6 +67,7 @@
CONF_DEVICE_CLIMATE = "climate"
CONF_DEVICE_ROOM_HUMIDITY = "room_humidity"
CONF_DEVICE_CUSTOM = "custom_sensor"
CONF_DEVICE_CUSTOM_BINARY = "custom_binary_sensor"
CONF_DEVICE_CUSTOM_MESSAGE = "message"
CONF_DEVICE_CUSTOM_RAW_FILTERS = "raw_filters"

Expand Down Expand Up @@ -116,6 +117,10 @@ def preset_entry(
cv.Required(CONF_DEVICE_CUSTOM_MESSAGE): cv.hex_int,
})

CUSTOM_BINARY_SENSOR_SCHEMA = binary_sensor.binary_sensor_schema().extend({
cv.Required(CONF_DEVICE_CUSTOM_MESSAGE): cv.hex_int,
})


def custom_sensor_schema(
message: int,
Expand Down Expand Up @@ -192,6 +197,7 @@ def humidity_sensor_schema(message: int):
cv.Optional(CONF_DEVICE_WATER_HEATER_MODE): SELECT_WATER_HEATER_MODE_SCHEMA,
cv.Optional(CONF_DEVICE_CLIMATE): CLIMATE_SCHEMA,
cv.Optional(CONF_DEVICE_CUSTOM, default=[]): cv.ensure_list(CUSTOM_SENSOR_SCHEMA),
cv.Optional(CONF_DEVICE_CUSTOM_BINARY, default=[]): cv.ensure_list(CUSTOM_BINARY_SENSOR_SCHEMA),

# keep CUSTOM_SENSOR_KEYS in sync with these
cv.Optional(CONF_DEVICE_WATER_TEMPERATURE): temperature_sensor_schema(0x4237),
Expand Down Expand Up @@ -372,6 +378,12 @@ async def to_code(config):
sens = await sensor.new_sensor(cust_sens)
cg.add(var_dev.add_custom_sensor(
cust_sens[CONF_DEVICE_CUSTOM_MESSAGE], sens))

if CONF_DEVICE_CUSTOM_BINARY in device:
for cust_bin_sens in device[CONF_DEVICE_CUSTOM_BINARY]:
bin_sens = await binary_sensor.new_binary_sensor(cust_bin_sens)
cg.add(var_dev.add_custom_binary_sensor(
cust_bin_sens[CONF_DEVICE_CUSTOM_MESSAGE], bin_sens))

for key in CUSTOM_SENSOR_KEYS:
if key in device:
Expand Down
2 changes: 2 additions & 0 deletions components/samsung_ac/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ namespace esphome
virtual void set_swing_horizontal(const std::string address, bool horizontal) = 0;
virtual optional<std::set<uint16_t>> get_custom_sensors(const std::string address) = 0;
virtual void set_custom_sensor(const std::string address, uint16_t message_number, float value) = 0;
virtual optional<std::set<uint16_t>> get_custom_binary_sensors(const std::string address) = 0;
virtual void set_custom_binary_sensor(const std::string address, uint16_t message_number, bool value) = 0;
};

struct ProtocolRequest
Expand Down
17 changes: 14 additions & 3 deletions components/samsung_ac/protocol_nasa.cpp
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atanasenko @lanwin interested on what you think the best way to handle the different custom sensor types is? If you think this way is ok I could create as enum, but any better ideas?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. In main I removed the custom parameter compleatly and just call set_custom_sensor every time. If there is no custom sensor, this does nothing.

So the best would be if you do the same.

Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ namespace esphome
}
}

void process_messageset(std::string source, std::string dest, MessageSet &message, optional<std::set<uint16_t>> &custom, MessageTarget *target)
void process_messageset(std::string source, std::string dest, MessageSet &message, optional<std::set<uint16_t>> &custom, MessageTarget *target, int type)
{
if (debug_mqtt_connected())
{
Expand All @@ -546,10 +546,15 @@ namespace esphome
}
}

if (custom && custom.value().find((uint16_t)message.messageNumber) != custom.value().end())
if (custom && type == 0 && custom.value().find((uint16_t)message.messageNumber) != custom.value().end())
{
target->set_custom_sensor(source, (uint16_t)message.messageNumber, (float)message.value);
}

if (custom && type == 1 && custom.value().find((uint16_t)message.messageNumber) != custom.value().end())
{
target->set_custom_binary_sensor(source, (uint16_t)message.messageNumber, (bool)message.value);
}

switch (message.messageNumber)
{
Expand Down Expand Up @@ -802,7 +807,13 @@ namespace esphome
optional<std::set<uint16_t>> custom = target->get_custom_sensors(source);
for (auto &message : packet_.messages)
{
process_messageset(source, dest, message, custom, target);
process_messageset(source, dest, message, custom, target, 0);
}

optional<std::set<uint16_t>> custom_binary = target->get_custom_binary_sensors(source);
for (auto &message : packet_.messages)
{
process_messageset(source, dest, message, custom_binary, target, 1);
}
}

Expand Down
10 changes: 5 additions & 5 deletions components/samsung_ac/protocol_non_nasa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,9 @@ namespace esphome
return Mode::Auto;
}
}
// TODO
WaterHeaterMode nonnasa_water_heater_mode_to_mode(int value)
// TODO
WaterHeaterMode nonnasa_water_heater_mode_to_mode(int value)
{
switch (value)
{
Expand Down Expand Up @@ -591,8 +591,8 @@ namespace esphome
// TODO
target->set_water_heater_power(nonpacket_.src, false);
target->set_mode(nonpacket_.src, nonnasa_mode_to_mode(nonpacket_.command20.mode));
// TODO
target->set_water_heater_mode(nonpacket_.src, nonnasa_water_heater_mode_to_mode(-0));
// TODO
target->set_water_heater_mode(nonpacket_.src, nonnasa_water_heater_mode_to_mode(-0));
target->set_fanmode(nonpacket_.src, nonnasa_fanspeed_to_fanmode(nonpacket_.command20.fanspeed));
// TODO
target->set_altmode(nonpacket_.src, 0);
Expand Down
15 changes: 15 additions & 0 deletions components/samsung_ac/samsung_ac.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ namespace esphome
if (dev != nullptr)
dev->update_custom_sensor(message_number, value);
}

optional<std::set<uint16_t>> /*MessageTarget::*/ get_custom_binary_sensors(const std::string address) override
{
Samsung_AC_Device *dev = find_device(address);
if (dev != nullptr)
return optional<std::set<uint16_t>>(dev->get_custom_binary_sensors());
return optional<std::set<uint16_t>>();
}

void /*MessageTarget::*/ set_custom_binary_sensor(const std::string address, uint16_t message_number, bool value) override
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please check the indentation here.

{
Samsung_AC_Device *dev = find_device(address);
if (dev != nullptr)
dev->update_custom_binary_sensor(message_number, value);
}

protected:
Samsung_AC_Device *find_device(const std::string address)
Expand Down
31 changes: 31 additions & 0 deletions components/samsung_ac/samsung_ac_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "esphome/core/helpers.h"
#include "esphome/components/switch/switch.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/binary_sensor/binary_sensor.h"
#include "esphome/components/select/select.h"
#include "esphome/components/number/number.h"
#include "esphome/components/climate/climate.h"
Expand Down Expand Up @@ -91,6 +92,12 @@ namespace esphome
uint16_t message_number;
sensor::Sensor *sensor;
};

struct Samsung_AC_Binary_Sensor
{
uint16_t message_number;
binary_sensor::BinarySensor *binary_sensor;
};

class Samsung_AC_Device
{
Expand All @@ -114,6 +121,7 @@ namespace esphome
Samsung_AC_Water_Heater_Mode_Select *waterheatermode{nullptr};
Samsung_AC_Climate *climate{nullptr};
std::vector<Samsung_AC_Sensor> custom_sensors;
std::vector<Samsung_AC_Binary_Sensor> custom_binary_sensors;
float room_temperature_offset{0};

void set_room_temperature_sensor(sensor::Sensor *sensor)
Expand All @@ -133,6 +141,14 @@ namespace esphome
cust_sensor.sensor = sensor;
custom_sensors.push_back(std::move(cust_sensor));
}

void add_custom_binary_sensor(int message_number, binary_sensor::BinarySensor *binary_sensor)
{
Samsung_AC_Binary_Sensor cust_binary_sensor;
cust_binary_sensor.message_number = (uint16_t)message_number;
cust_binary_sensor.binary_sensor = binary_sensor;
custom_binary_sensors.push_back(std::move(cust_binary_sensor));
}

std::set<uint16_t> get_custom_sensors()
{
Expand All @@ -141,6 +157,14 @@ namespace esphome
numbers.insert(sensor.message_number);
return numbers;
}

std::set<uint16_t> get_custom_binary_sensors()
{
std::set<uint16_t> numbers;
for (auto &binary_sensor : custom_binary_sensors)
numbers.insert(binary_sensor.message_number);
return numbers;
}

void set_power_switch(Samsung_AC_Switch *switch_)
{
Expand Down Expand Up @@ -375,6 +399,13 @@ namespace esphome
if (sensor.message_number == message_number)
sensor.sensor->publish_state(value);
}

void update_custom_binary_sensor(uint16_t message_number, bool value)
{
for (auto &binary_sensor : custom_binary_sensors)
if (binary_sensor.message_number == message_number)
binary_sensor.binary_sensor->publish_state(value);
}

void publish_request(ProtocolRequest &request)
{
Expand Down