diff --git a/README.md b/README.md index 072cda91..3b4bdf9f 100644 --- a/README.md +++ b/README.md @@ -30,11 +30,6 @@ Pages on nspanel are generated from the array at the begin of the pages function ![image](https://user-images.githubusercontent.com/29555657/151675593-dadd53cb-a38e-49bd-9f40-832fc8edd017.png) - -# EspHome component - -See Readme in esphome folder. - # NsPanel Custom UI This is a replacement for the stock ui on nspanel, it can be controlled via custom serial command, like the stock one (but with different commands). This enables a user experiance, where it's possible to use nspanel with custom UI, but without messing around with Nextion Editor, because it's possible to configure widgets. diff --git a/components/nextion_custom/__init__.py b/components/nextion_custom/__init__.py deleted file mode 100644 index beeeccc4..00000000 --- a/components/nextion_custom/__init__.py +++ /dev/null @@ -1,62 +0,0 @@ -from esphome import automation -import esphome.config_validation as cv -import esphome.codegen as cg - -from esphome.components import uart, time, switch, sensor -from esphome.const import ( - CONF_ID, - CONF_NAME, - CONF_ON_CLICK, - CONF_TEMPERATURE, - CONF_THEN, - CONF_TIME_ID, - CONF_TYPE, - CONF_TRIGGER_ID, -) - -AUTO_LOAD = ["text_sensor"] -CODEOWNERS = ["@joBr99"] -DEPENDENCIES = ["uart", "wifi", "esp32"] - - -nextion_custom_ns = cg.esphome_ns.namespace("NextionCustom") -NextionCustom = nextion_custom_ns.class_("NextionCustom", cg.Component, uart.UARTDevice) - - -NextionCustomMsgIncomingTrigger = nextion_custom_ns.class_( - "NextionCustomMsgIncomingTrigger", - automation.Trigger.template(cg.std_string) -) - -CONF_INCOMING_MSG = 'on_incoming_msg' - - -CONFIG_SCHEMA = cv.All( - cv.Schema( - { - cv.GenerateID(): cv.declare_id(NextionCustom), - cv.Required(CONF_INCOMING_MSG): automation.validate_automation( - cv.Schema( - { - cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(NextionCustomMsgIncomingTrigger), - } - ) - ), - } - ) - .extend(uart.UART_DEVICE_SCHEMA) - .extend(cv.COMPONENT_SCHEMA), - cv.only_with_arduino, -) - - -async def to_code(config): - var = cg.new_Pvariable(config[CONF_ID]) - await cg.register_component(var, config) - await uart.register_uart_device(var, config) - - for conf in config.get(CONF_INCOMING_MSG, []): - trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) - await automation.build_automation(trigger, [(cg.std_string, "x")], conf) - - cg.add_define("USE_NEXTIONCUSTOM") \ No newline at end of file diff --git a/components/nextion_custom/automation.h b/components/nextion_custom/automation.h deleted file mode 100644 index ec0a7d0c..00000000 --- a/components/nextion_custom/automation.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -#include "esphome/core/component.h" -#include "esphome/core/automation.h" -#include "nextion_custom.h" - -namespace esphome { -namespace NextionCustom { - -class NextionCustomMsgIncomingTrigger : public Trigger { - public: - explicit NextionCustomMsgIncomingTrigger(NextionCustom *parent) { - parent->add_incoming_msg_callback([this](const std::string &value) { this->trigger(value); }); - } -}; - -} // namespace NextionCustom -} // namespace esphome \ No newline at end of file diff --git a/components/nextion_custom/nextion_custom.cpp b/components/nextion_custom/nextion_custom.cpp deleted file mode 100644 index a3b86258..00000000 --- a/components/nextion_custom/nextion_custom.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "nextion_custom.h" - -#ifdef USE_ESP32_FRAMEWORK_ARDUINO - -#include "esphome/components/wifi/wifi_component.h" -#include "esphome/core/application.h" -#include "esphome/core/helpers.h" -#include "esphome/core/util.h" -#include "esphome/core/version.h" - -namespace esphome { -namespace NextionCustom { - -static const char *const TAG = "nextion_custom"; - -static const char *const SUCCESS_RESPONSE = "{\"error\":0}"; - -static const uint8_t WAKE_RESPONSE[7] = {0xFF, 0xFF, 0xFF, 0x88, 0xFF, 0xFF, 0xFF}; - -void NextionCustom::setup() { -} - -void NextionCustom::loop() { - uint8_t d; - - while (this->available()) { - this->read_byte(&d); - this->buffer_.push_back(d); - //ESP_LOGD(TAG, "ReceivedD: 0x%02x", d); - if (!this->process_data_()) { - ESP_LOGD(TAG, "Received: 0x%02x", d); - this->buffer_.clear(); - } - } - -} - -bool NextionCustom::process_data_() { - uint32_t at = this->buffer_.size() - 1; - auto *data = &this->buffer_[0]; - uint8_t new_byte = data[at]; - -// if (data[0] == WAKE_RESPONSE[0]) { // Screen wake message -// if (at < 6) -// return new_byte == WAKE_RESPONSE[at]; -// if (new_byte == WAKE_RESPONSE[at]) { -// ESP_LOGD(TAG, "Screen wake message received"); -// this->initialize(); -// return false; -// } -// return false; -// } -// - // Byte 0: HEADER1 (always 0x55) - if (at == 0) - return new_byte == 0x55; - // Byte 1: HEADER2 (always 0xBB) - if (at == 1) - return new_byte == 0xBB; - - // length - if (at == 2){ - return true; - } - uint8_t length = data[2]; - - // Wait until all data comes in - if (at - 3 < length){ - //ESP_LOGD(TAG, "Message Length: (%d/%d)", at - 2, length); - //ESP_LOGD(TAG, "Received: 0x%02x", new_byte); - return true; - } - - - // Wait for CRC - if (at == 2 + length || at == 2 + length + 1) - return true; - - uint16_t crc16 = encode_uint16(data[3 + length + 1], data[3 + length]); - uint16_t calculated_crc16 = NextionCustom::crc16(data, 3 + length); - - if (crc16 != calculated_crc16) { - ESP_LOGW(TAG, "Received invalid message checksum %02X!=%02X", crc16, calculated_crc16); - return false; - }else{ - ESP_LOGD(TAG, "Received valid message checksum %02X==%02X", crc16, calculated_crc16); - } - - const uint8_t *message_data = data + 3; - std::string message(message_data, message_data + length); - - #if ESPHOME_VERSION_CODE >= VERSION_CODE(2022, 1, 0) - ESP_LOGD(TAG, "Received NextionCustom: PAYLOAD=%s RAW=[%s]", message.c_str(), - format_hex_pretty(message_data, length).c_str()); - #else - ESP_LOGD(TAG, "Received NextionCustom: PAYLOAD=%s RAW=[%s]", message.c_str(), - hexencode(message_data, length).c_str()); - #endif - this->process_command_(message); - return false; -} - -void NextionCustom::process_command_(const std::string &message) { - this->incoming_msg_callback_.call(message); -} - -void NextionCustom::add_incoming_msg_callback(std::function callback) { - this->incoming_msg_callback_.add(std::move(callback)); -} - -void NextionCustom::dump_config() { ESP_LOGCONFIG(TAG, "NextionCustom:"); } - - -void NextionCustom::send_command_(const std::string &command) { - ESP_LOGD(TAG, "Sending: %s", command.c_str()); - this->write_str(command.c_str()); - const uint8_t to_send[3] = {0xFF, 0xFF, 0xFF}; - this->write_array(to_send, sizeof(to_send)); -} - -void NextionCustom::send_special_hex_cmd(const std::string &command) { - ESP_LOGD(TAG, "Sending: special hex cmd"); - - const uint8_t to_send[3] = {0x09, 0x19, 0x08}; - this->write_array(to_send, sizeof(to_send)); - //this->write_str(" fffb 0002 0000 0020"); - this->write_str(command.c_str()); - const uint8_t to_send2[3] = {0xFF, 0xFF, 0xFF}; - this->write_array(to_send2, sizeof(to_send2)); -} - -void NextionCustom::send_custom_command(const std::string &command) { - ESP_LOGD(TAG, "Sending custom command: %s", command.c_str()); - std::vector data = {0x55, 0xBB}; - data.push_back(command.length() & 0xFF); - //data.push_back((command.length() >> 8) & 0xFF); - data.insert(data.end(), command.begin(), command.end()); - auto crc = crc16(data.data(), data.size()); - data.push_back(crc & 0xFF); - data.push_back((crc >> 8) & 0xFF); - this->write_array(data); - - #if ESPHOME_VERSION_CODE >= VERSION_CODE(2022, 1, 0) - ESP_LOGD(TAG, "Send NextionCustom: PAYLOAD=%s RAW=[%s]", command.c_str(), - format_hex_pretty(&data[0], data.size()).c_str()); - #else - ESP_LOGD(TAG, "Send NextionCustom: PAYLOAD=%s RAW=[%s]", command.c_str(), - hexencode(&data[0], data.size()).c_str()); - #endif -} - -uint16_t NextionCustom::crc16(const uint8_t *data, uint16_t len) { - uint16_t crc = 0xFFFF; - while (len--) { - crc ^= *data++; - for (uint8_t i = 0; i < 8; i++) { - if ((crc & 0x01) != 0) { - crc >>= 1; - crc ^= 0xA001; - } else { - crc >>= 1; - } - } - } - return crc; -} - -} // namespace NextionCustom -} // namespace esphome - -#endif // USE_ESP32_FRAMEWORK_ARDUINO \ No newline at end of file diff --git a/components/nextion_custom/nextion_custom.h b/components/nextion_custom/nextion_custom.h deleted file mode 100644 index 5edbe2a4..00000000 --- a/components/nextion_custom/nextion_custom.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#ifdef USE_ESP32_FRAMEWORK_ARDUINO - -#include - -#include "esphome/components/text_sensor/text_sensor.h" -#include "esphome/components/switch/switch.h" -//#include "esphome/components/time/real_time_clock.h" -#include "esphome/components/uart/uart.h" -#include "esphome/core/automation.h" -#include "esphome/core/component.h" -#include "esphome/core/defines.h" - -namespace esphome { -namespace NextionCustom { - -class NextionCustom : public Component, public uart::UARTDevice { - public: - void setup() override; - void loop() override; - - float get_setup_priority() const override { return setup_priority::DATA; } - - void dump_config() override; - - void send_custom_command(const std::string &command); - - - void send_special_hex_cmd(const std::string &command); - - void add_incoming_msg_callback(std::function callback); - - void send_command_(const std::string &command); - - - protected: - static uint16_t crc16(const uint8_t *data, uint16_t len); - - bool process_data_(); - void process_command_(const std::string &message); - - CallbackManager incoming_msg_callback_; - - std::vector buffer_; -}; - - -} // namespace NextionCustom -} // namespace esphome - -#endif // USE_ESP32_FRAMEWORK_ARDUINO \ No newline at end of file diff --git a/esphome/README.md b/esphome/README.md deleted file mode 100644 index 1a616a7a..00000000 --- a/esphome/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# EspHome component - -See my esphome.yaml for the config used on the nspanel device. -Messages are currently handled on the "on_incoming_msg" lambda. -An proper implementation where you can configure the pages within esphome yaml is currently missing. -It should be possible to recact to buttonPress Events within this lambda. (through calling a home assistant service or something like that) - -To flash a new tft file I'm currently switching to the offical nextion component, which is also in the esphome.yaml -It might be needed to switch to hidden page and disable recmod/reparse mod. To access hidden page press the hidden button 10 times. - -![image](https://user-images.githubusercontent.com/29555657/149628769-2caa3ebc-1019-421b-b316-1845c55acf09.png) diff --git a/esphome/esphome.yaml b/esphome/esphome.yaml deleted file mode 100644 index f11dc0d9..00000000 --- a/esphome/esphome.yaml +++ /dev/null @@ -1,208 +0,0 @@ -# Set some variables for convenience -substitutions: - node_name: nspanel-test - device_name: Test NSPanel - -external_components: - - source: github://joBr99/nspanel-lovelance-ui@main - components: [nextion_custom] - refresh: 1h - -web_server: - port: 80 - -esphome: - name: $node_name - comment: $device_name - -esp32: - board: esp32dev - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - -# Enable logging -logger: - -# Enable wireless updates -ota: - -# A reboot button is always useful -button: - - platform: restart - name: Restart $device_name - -# Define some inputs -binary_sensor: - - platform: gpio - name: $device_name Left Button - pin: - number: 14 - inverted: true - on_click: - - switch.toggle: relay_1 - - - platform: gpio - name: $device_name Right Button - pin: - number: 27 - inverted: true - on_click: - - switch.toggle: relay_2 - -sensor: - - platform: wifi_signal - name: $device_name WiFi Signal - update_interval: 60s - - - platform: ntc - id: temperature - sensor: resistance_sensor - calibration: - b_constant: 3950 - reference_temperature: 25°C - reference_resistance: 10kOhm - name: $device_name Temperature - - - platform: resistance - id: resistance_sensor - sensor: ntc_source - configuration: DOWNSTREAM - resistor: 11.2kOhm - - - platform: adc - id: ntc_source - pin: 38 - update_interval: 10s - attenuation: 11db - - -# Define some outputs -switch: - # The two relays - - platform: gpio - name: $device_name Relay 1 - id: relay_1 - pin: - number: 22 - - platform: gpio - name: $device_name Relay 2 - id: relay_2 - pin: - number: 19 - - # Pin 4 always needs to be on to power up the display - - platform: gpio - id: screen_power - entity_category: config - pin: - number: 4 - inverted: true - restore_mode: ALWAYS_ON - -#number: -# platform: template -# name: $device_name Brightness -# id: brightness -# entity_category: config -# unit_of_measurement: '%' -# min_value: 0 -# max_value: 100 -# step: 1 -# initial_value: 30 -# set_action: -# then: -# - lambda: 'id(disp1).set_backlight_brightness(x/100);' - -# Configure the internal bleeper -output: - - platform: ledc - id: buzzer_out - pin: - number: 21 - -# Enable ringtone music support -rtttl: - id: buzzer - output: buzzer_out - -# Configure UART for communicating with the screen -uart: - id: tf_uart - tx_pin: 16 - rx_pin: 17 - baud_rate: 115200 - - -# Configure the screen itself -#display: -# - platform: nextion -# id: disp1 -# uart_id: tf_uart -# tft_url: http://192.168.75.30:8123/local/nspanel-custom.tft -#api: -# services: -# - service: upload_tft -# then: -# - lambda: 'id(disp1)->upload_tft();' - -nextion_custom: - id: nextcustom_id - on_incoming_msg: - then: - - lambda: |- - ESP_LOGD("KEKW", "Got incoming message from nextion panel %s", x.c_str()); - - std::string input = x; - std::string word = ""; - std::vector args; - - while (input.compare(word) != 0) - { - auto index = input.find_first_of(","); - word = input.substr(0,index); - input = input.substr(index+1, input.length()); - args.push_back(word); - } - - int pages = 2; - if(args.at(0) == "event"){ - if(args.at(1) == "pageOpen"){ - int recvPage = std::atoi(args.at(2).c_str()); - int destPage = abs(recvPage%pages); - ESP_LOGD("KEKW", "navigate to page: %d", destPage); - - if(destPage == 0 ){ - id(nextcustom_id).send_custom_command("entityUpdHeading,Rolladen"); - id(nextcustom_id).send_custom_command("entityUpd,1,0,Fenster Eingang,shutter"); - id(nextcustom_id).send_custom_command("entityUpd,2,0,Fenster Terrasse,shutter"); - id(nextcustom_id).send_custom_command("entityUpd,3,0,Terrassentür,shutter"); - } - if(destPage == 1 ){ - id(nextcustom_id).send_custom_command("entityUpdHeading,Page2"); - id(nextcustom_id).send_custom_command("entityUpd,1,1,test,light,0"); - id(nextcustom_id).send_custom_command("entityUpd,2,0,test,shutter"); - id(nextcustom_id).send_custom_command("entityUpd,3,1,test,light,1"); - id(nextcustom_id).send_custom_command("entityUpd,4,1,test,light,1"); - } - } - } - - - -# Enable Home Assistant API -api: - services: - - service: send_nextion_custom - variables: - cmd: string - then: - - lambda: |- - id(nextcustom_id).send_custom_command(cmd); - - service: send_nextion_cmd - variables: - cmd: string - then: - - lambda: |- - id(nextcustom_id).send_command_(cmd); \ No newline at end of file