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

rebase and cleanup #67

Open
wants to merge 11 commits into
base: nextion_upload
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
5 changes: 5 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ esphome/components/midea_ac/* @dudanov
esphome/components/midea_dongle/* @dudanov
esphome/components/mitsubishi/* @RubyBailey
esphome/components/network/* @esphome/core
esphome/components/nextion/* @senexcrenshaw
esphome/components/nextion/binary_sensor/* @senexcrenshaw
esphome/components/nextion/sensor/* @senexcrenshaw
esphome/components/nextion/switch/* @senexcrenshaw
esphome/components/nextion/text_sensor/* @senexcrenshaw
esphome/components/nfc/* @jesserockz
esphome/components/ota/* @esphome/core
esphome/components/output/* @esphome/core
Expand Down
5 changes: 5 additions & 0 deletions esphome/components/nextion/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import esphome.codegen as cg
from esphome.components import uart

nextion_ns = cg.esphome_ns.namespace("nextion")
Nextion = nextion_ns.class_("Nextion", cg.PollingComponent, uart.UARTDevice)
nextion_ref = Nextion.operator("ref")

CONF_NEXTION_ID = "nextion_id"
30 changes: 30 additions & 0 deletions esphome/components/nextion/automation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once
#include "esphome/core/automation.h"
#include "nextion.h"

namespace esphome {
namespace nextion {

class SetupTrigger : public Trigger<> {
public:
explicit SetupTrigger(Nextion *nextion) {
nextion->add_setup_state_callback([this]() { this->trigger(); });
}
};

class SleepTrigger : public Trigger<> {
public:
explicit SleepTrigger(Nextion *nextion) {
nextion->add_sleep_state_callback([this]() { this->trigger(); });
}
};

class WakeTrigger : public Trigger<> {
public:
explicit WakeTrigger(Nextion *nextion) {
nextion->add_wake_state_callback([this]() { this->trigger(); });
}
};

} // namespace nextion
} // namespace esphome
128 changes: 128 additions & 0 deletions esphome/components/nextion/base_component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
from string import ascii_letters, digits
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.components import color
from esphome.core import coroutine

from . import CONF_NEXTION_ID
from . import Nextion

CONF_VARIABLE_NAME = "variable_name"
CONF_COMPONENT_NAME = "component_name"
CONF_WAVE_CHANNEL_ID = "wave_channel_id"
CONF_WAVE_MAX_VALUE = "wave_max_value"
CONF_PRECISION = "precision"
CONF_WAVEFORM_SEND_LAST_VALUE = "waveform_send_last_value"
CONF_TFT_URL = "tft_url"
CONF_ON_SLEEP = "on_sleep"
CONF_ON_WAKE = "on_wake"
CONF_ON_SETUP = "on_setup"
CONF_TOUCH_SLEEP_TIMEOUT = "touch_sleep_timeout"
CONF_WAKE_UP_PAGE = "wake_up_page"
CONF_AUTO_WAKE_ON_TOUCH = "auto_wake_on_touch"
CONF_WAVE_MAX_LENGTH = "wave_max_length"
CONF_BACKGROUND_COLOR = "background_color"
CONF_BACKGROUND_PRESSED_COLOR = "background_pressed_color"
CONF_FOREGROUND_COLOR = "foreground_color"
CONF_FOREGROUND_PRESSED_COLOR = "foreground_pressed_color"
CONF_FONT_ID = "font_id"
CONF_VISIBLE = "visible"


def NextionName(value):
valid_chars = ascii_letters + digits + "."
if not isinstance(value, str) or len(value) > 29:
raise cv.Invalid("Must be a string less than 29 characters")

for char in value:
if char not in valid_chars:
raise cv.Invalid(
"Must only consist of upper/lowercase characters, numbers and the period '.'. The character '{}' cannot be used.".format(
char
)
)

return value


CONFIG_BASE_COMPONENT_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_NEXTION_ID): cv.use_id(Nextion),
cv.Optional(CONF_BACKGROUND_COLOR): cv.use_id(color),
cv.Optional(CONF_FOREGROUND_COLOR): cv.use_id(color),
cv.Optional(CONF_VISIBLE, default=True): cv.boolean,
}
)


CONFIG_TEXT_COMPONENT_SCHEMA = CONFIG_BASE_COMPONENT_SCHEMA.extend(
cv.Schema(
{
cv.Required(CONF_COMPONENT_NAME): NextionName,
cv.Optional(CONF_FONT_ID): cv.int_range(min=0, max=255),
}
)
)

CONFIG_BINARY_SENSOR_SCHEMA = CONFIG_BASE_COMPONENT_SCHEMA.extend(
cv.Schema(
{
cv.Optional(CONF_COMPONENT_NAME): NextionName,
cv.Optional(CONF_VARIABLE_NAME): NextionName,
}
)
)

CONFIG_SENSOR_COMPONENT_SCHEMA = CONFIG_BINARY_SENSOR_SCHEMA.extend(
cv.Schema(
{
cv.Optional(CONF_FONT_ID): cv.int_range(min=0, max=255),
}
)
)


CONFIG_SWITCH_COMPONENT_SCHEMA = CONFIG_SENSOR_COMPONENT_SCHEMA.extend(
cv.Schema(
{
cv.Optional(CONF_FOREGROUND_PRESSED_COLOR): cv.use_id(color),
cv.Optional(CONF_BACKGROUND_PRESSED_COLOR): cv.use_id(color),
}
)
)


@coroutine
async def setup_component_core_(var, config, arg):

if CONF_VARIABLE_NAME in config:
cg.add(var.set_variable_name(config[CONF_VARIABLE_NAME]))
elif CONF_COMPONENT_NAME in config:
cg.add(
var.set_variable_name(
config[CONF_COMPONENT_NAME],
config[CONF_COMPONENT_NAME] + arg,
)
)

if CONF_BACKGROUND_COLOR in config:
color_component = await cg.get_variable(config[CONF_BACKGROUND_COLOR])
cg.add(var.set_background_color(color_component))

if CONF_BACKGROUND_PRESSED_COLOR in config:
color_component = await cg.get_variable(config[CONF_BACKGROUND_PRESSED_COLOR])
cg.add(var.set_background_pressed_color(color_component))

if CONF_FOREGROUND_COLOR in config:
color_component = await cg.get_variable(config[CONF_FOREGROUND_COLOR])
cg.add(var.set_foreground_color(color_component))

if CONF_FOREGROUND_PRESSED_COLOR in config:
color_component = await cg.get_variable(config[CONF_FOREGROUND_PRESSED_COLOR])
cg.add(var.set_foreground_pressed_color(color_component))

if CONF_FONT_ID in config:
cg.add(var.set_font_id(config[CONF_FONT_ID]))

if CONF_VISIBLE in config:
cg.add(var.set_visible(config[CONF_VISIBLE]))
34 changes: 0 additions & 34 deletions esphome/components/nextion/binary_sensor.py

This file was deleted.

54 changes: 54 additions & 0 deletions esphome/components/nextion/binary_sensor/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor

from esphome.const import CONF_COMPONENT_ID, CONF_PAGE_ID, CONF_ID
from .. import nextion_ns, CONF_NEXTION_ID


from ..base_component import (
setup_component_core_,
CONFIG_BINARY_SENSOR_SCHEMA,
CONF_VARIABLE_NAME,
CONF_COMPONENT_NAME,
)

CODEOWNERS = ["@senexcrenshaw"]

NextionBinarySensor = nextion_ns.class_(
"NextionBinarySensor", binary_sensor.BinarySensor, cg.PollingComponent
)

CONFIG_SCHEMA = cv.All(
binary_sensor.BINARY_SENSOR_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(NextionBinarySensor),
cv.Optional(CONF_PAGE_ID): cv.uint8_t,
cv.Optional(CONF_COMPONENT_ID): cv.uint8_t,
}
)
.extend(CONFIG_BINARY_SENSOR_SCHEMA)
.extend(cv.polling_component_schema("never")),
cv.has_at_least_one_key(
CONF_PAGE_ID,
CONF_COMPONENT_ID,
CONF_COMPONENT_NAME,
CONF_VARIABLE_NAME,
),
)


async def to_code(config):
hub = await cg.get_variable(config[CONF_NEXTION_ID])
var = cg.new_Pvariable(config[CONF_ID], hub)
await binary_sensor.register_binary_sensor(var, config)
await cg.register_component(var, config)

if config.keys() >= {CONF_PAGE_ID, CONF_COMPONENT_ID}:
cg.add(hub.register_touch_component(var))
cg.add(var.set_component_id(config[CONF_COMPONENT_ID]))
cg.add(var.set_page_id(config[CONF_PAGE_ID]))

if CONF_COMPONENT_NAME in config or CONF_VARIABLE_NAME in config:
await setup_component_core_(var, config, ".val")
cg.add(hub.register_binarysensor_component(var))
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "nextion_binarysensor.h"
#include "esphome/core/util.h"
#include "esphome/core/log.h"

namespace esphome {
namespace nextion {

static const char *TAG = "nextion_binarysensor";

void NextionBinarySensor::process_bool(const std::string &variable_name, bool state) {
if (!this->nextion_->is_setup())
return;

if (this->variable_name_.empty()) // This is a touch component
return;

if (this->variable_name_ == variable_name) {
this->publish_state(state);
ESP_LOGD(TAG, "Processed binarysensor \"%s\" state %s", variable_name.c_str(), state ? "ON" : "OFF");
}
}

void NextionBinarySensor::process_touch(uint8_t page_id, uint8_t component_id, bool state) {
if (this->page_id_ == page_id && this->component_id_ == component_id) {
this->publish_state(state);
}
}

void NextionBinarySensor::update() {
if (!this->nextion_->is_setup())
return;

if (this->variable_name_.empty()) // This is a touch component
return;

this->nextion_->add_to_get_queue(this);
}

void NextionBinarySensor::set_state(bool state, bool publish, bool send_to_nextion) {
if (!this->nextion_->is_setup())
return;

if (this->component_id_ == 0) // This is a legacy touch component
return;

if (send_to_nextion) {
if (this->nextion_->is_sleeping() || !this->visible_) {
this->needs_to_send_update_ = true;
} else {
this->needs_to_send_update_ = false;
this->nextion_->add_no_result_to_queue_with_set(this, (int) state);
}
}

if (publish) {
this->publish_state(state);
} else {
this->state = state;
this->has_state_ = true;
}

this->update_component_settings();

ESP_LOGN(TAG, "Wrote state for sensor \"%s\" state %s", this->variable_name_.c_str(),
ONOFF(this->variable_name_.c_str()));
}

} // namespace nextion
} // namespace esphome
42 changes: 42 additions & 0 deletions esphome/components/nextion/binary_sensor/nextion_binarysensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/binary_sensor/binary_sensor.h"
#include "../nextion_component.h"
#include "../nextion_base.h"

namespace esphome {
namespace nextion {
class NextionBinarySensor;

class NextionBinarySensor : public NextionComponent,
public binary_sensor::BinarySensorInitiallyOff,
public PollingComponent {
public:
NextionBinarySensor(NextionBase *nextion) { this->nextion_ = nextion; }

void update_component() override { this->update(); }
void update() override;
void send_state_to_nextion() override { this->set_state(this->state, false); };
void process_bool(const std::string &variable_name, bool state) override;
void process_touch(uint8_t page_id, uint8_t component_id, bool state) override;

// Set the components page id for Nextion Touch Component
void set_page_id(uint8_t page_id) { page_id_ = page_id; }
// Set the components component id for Nextion Touch Component
void set_component_id(uint8_t component_id) { component_id_ = component_id; }

void set_state(bool state) override { this->set_state(state, true, true); }
void set_state(bool state, bool publish) override { this->set_state(state, publish, true); }
void set_state(bool state, bool publish, bool send_to_nextion) override;

NextionQueueType get_queue_type() override { return NextionQueueType::BINARY_SENSOR; }
void set_state_from_string(const std::string &state_value, bool publish, bool send_to_nextion) override {}
void set_state_from_int(int state_value, bool publish, bool send_to_nextion) override {
this->set_state(state_value == 0 ? false : true, publish, send_to_nextion);
}

protected:
uint8_t page_id_;
};
} // namespace nextion
} // namespace esphome
Loading