Compare commits
6 Commits
02b6ee04cc
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
a23dea333f
|
|||
|
32dfe237f8
|
|||
|
d5cc738a5c
|
|||
|
c3b8e366c7
|
|||
|
d6d37f1e27
|
|||
| 6b139cdc9b |
@@ -69,8 +69,9 @@ these can be configured in YAML.
|
|||||||
Since a lot of new connections will need to be made to ground, I recommend using
|
Since a lot of new connections will need to be made to ground, I recommend using
|
||||||
something like a perforated prototype board and make a single connection to
|
something like a perforated prototype board and make a single connection to
|
||||||
ground from the prototype board to the front panel control board, then connect
|
ground from the prototype board to the front panel control board, then connect
|
||||||
all other grounds needed for the circuiti to each other using the prototype
|
all other grounds needed for the circuit to each other using the prototype
|
||||||
board. A 2cm$\times$8cm board fits perfectly in the empty space below the front panel in the front panel assemple. I also made all connections to the back of
|
board. A 2cm $\times$ 8cm board fits perfectly in the empty space below the front panel in the front panel assembly. I also made all connections to the
|
||||||
|
back of
|
||||||
the front panel control board with wires with female Dupont connectors, then
|
the front panel control board with wires with female Dupont connectors, then
|
||||||
used male headers on the prototype board so that the additional circuitry can
|
used male headers on the prototype board so that the additional circuitry can
|
||||||
easily be removed.
|
easily be removed.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.components import fan, output
|
from esphome.components import fan, output
|
||||||
from esphome.const import CONF_OUTPUT_ID
|
from esphome.const import CONF_ID
|
||||||
from . import (
|
from . import (
|
||||||
HAUSLANE_SCHEMA,
|
HAUSLANE_SCHEMA,
|
||||||
CONF_HAUSLANE_ID,
|
CONF_HAUSLANE_ID,
|
||||||
@@ -16,14 +16,14 @@ HauslaneFan = hauslane_ns.class_(
|
|||||||
)
|
)
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
fan.FAN_SCHEMA.extend({
|
fan.fan_schema(HauslaneFan).extend({
|
||||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(HauslaneFan),
|
cv.GenerateID(CONF_HAUSLANE_ID): cv.use_id(HauslaneFan),
|
||||||
})
|
})
|
||||||
.extend(HAUSLANE_SCHEMA)
|
.extend(HAUSLANE_SCHEMA)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
await fan.register_fan(var,config)
|
await fan.register_fan(var,config)
|
||||||
|
|
||||||
paren = await cg.get_variable(config[CONF_HAUSLANE_ID])
|
paren = await cg.get_variable(config[CONF_HAUSLANE_ID])
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ void Hauslane::setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// register ESPHome API service named "command"
|
// register ESPHome API service named "command"
|
||||||
|
#if defined(USE_API)
|
||||||
register_service(&Hauslane::command, "command", {"command"});
|
register_service(&Hauslane::command, "command", {"command"});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hauslane::loop() {
|
void Hauslane::loop() {
|
||||||
@@ -49,6 +51,10 @@ void Hauslane::loop() {
|
|||||||
} else {
|
} else {
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
} else if (rx_message.size() > MAX_RX) {
|
||||||
|
parse_state();
|
||||||
|
reading = false;
|
||||||
|
pos = 0;
|
||||||
} else {
|
} else {
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
@@ -94,23 +100,24 @@ void Hauslane::loop() {
|
|||||||
button_press(pin_down, true);
|
button_press(pin_down, true);
|
||||||
}
|
}
|
||||||
} else if (this->light_cur != this->light_target) {
|
} else if (this->light_cur != this->light_target) {
|
||||||
if (this->power) {
|
if (this->speed==0 && !this->light_target) {
|
||||||
// press light button
|
// request light turn off and fan is off, so simply hit power button
|
||||||
button_press(pin_light, true);
|
|
||||||
} else {
|
|
||||||
// power on hood first
|
|
||||||
button_press(pin_power, true);
|
button_press(pin_power, true);
|
||||||
|
} else if (!this->power && this->light_target) {
|
||||||
|
// request light on and fan off, so power on hood first
|
||||||
|
button_press(pin_power, true);
|
||||||
|
} else if (this->power) {
|
||||||
|
// press light button to toggle
|
||||||
|
button_press(pin_light, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// target already met, so reset flag
|
// target already met, so reset flag
|
||||||
this->meet_target=false;
|
this->meet_target=false;
|
||||||
}
|
}
|
||||||
} else if (this->speed==0 && !this->light_cur) {
|
} else if (this->speed==0 && !this->light_cur && this->power) {
|
||||||
// reset power flag
|
// reset power flag
|
||||||
if(this->power) {
|
this->power=false;
|
||||||
this->power=false;
|
ESP_LOGD(TAG, "Hood power: %d", this->power);
|
||||||
ESP_LOGD(TAG, "Hood power: %d", this->power);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +149,7 @@ void Hauslane::set_speed(int new_speed) {
|
|||||||
|
|
||||||
// read message on rx line and turn into current state of fan and light
|
// read message on rx line and turn into current state of fan and light
|
||||||
void Hauslane::parse_state() {
|
void Hauslane::parse_state() {
|
||||||
size_t len = rx_message.size()-4;
|
size_t len = rx_message.size()-END_LEN;
|
||||||
std::string msg;
|
std::string msg;
|
||||||
std::vector<uint8_t> msg_hex;
|
std::vector<uint8_t> msg_hex;
|
||||||
|
|
||||||
@@ -158,20 +165,20 @@ void Hauslane::parse_state() {
|
|||||||
// oscilloscope, but as there is only one-way communication from the front
|
// oscilloscope, but as there is only one-way communication from the front
|
||||||
// panel to the main controller board, this would only be useful if
|
// panel to the main controller board, this would only be useful if
|
||||||
// replacing the front panel entirely
|
// replacing the front panel entirely
|
||||||
const std::vector<uint8_t> off_0{0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce};
|
const std::vector<uint8_t> off_0{0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0x00};
|
||||||
const std::vector<uint8_t> on_0{0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6};
|
const std::vector<uint8_t> on_0{0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xfe};
|
||||||
const std::vector<uint8_t> off_1{0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xce};
|
const std::vector<uint8_t> off_1{0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xce, 0xc0};
|
||||||
const std::vector<uint8_t> on_1{0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce};
|
const std::vector<uint8_t> on_1{0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xfe};
|
||||||
const std::vector<uint8_t> off_2{0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xce};
|
const std::vector<uint8_t> off_2{0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xce, 0xfe};
|
||||||
const std::vector<uint8_t> on_2{0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xc6};
|
const std::vector<uint8_t> on_2{0xce, 0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xc6, 0xfe};
|
||||||
const std::vector<uint8_t> off_3{0x38, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce};
|
const std::vector<uint8_t> off_3{0xce, 0x38, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xce, 0x00};
|
||||||
const std::vector<uint8_t> on_3{0x38, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce};
|
const std::vector<uint8_t> on_3{0xce, 0x38, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xfe};
|
||||||
const std::vector<uint8_t> off_4{0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xce, 0xce};
|
const std::vector<uint8_t> off_4{0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xce, 0xce, 0x00};
|
||||||
const std::vector<uint8_t> on_4{0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce};
|
const std::vector<uint8_t> on_4{0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xfe};
|
||||||
const std::vector<uint8_t> off_5{0xc6, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xc6, 0xce, 0xce};
|
const std::vector<uint8_t> off_5{0xc6, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xc6, 0xce, 0xce, 0x00};
|
||||||
const std::vector<uint8_t> on_5{0xc6, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xc6};
|
const std::vector<uint8_t> on_5{0xc6, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xc6, 0xce, 0xfe};
|
||||||
const std::vector<uint8_t> off_6{0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0x38, 0xce, 0xce};
|
const std::vector<uint8_t> off_6{0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0x38, 0xce, 0xce, 0x00};
|
||||||
const std::vector<uint8_t> on_6{0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0x38};
|
const std::vector<uint8_t> on_6{0xc6, 0xce, 0xc6, 0xce, 0xce, 0xce, 0xce, 0xce, 0x38, 0xce, 0xfe};
|
||||||
|
|
||||||
// print out formatted hex string to log
|
// print out formatted hex string to log
|
||||||
char buf[5];
|
char buf[5];
|
||||||
@@ -224,6 +231,10 @@ void Hauslane::set_state(bool set_light, uint8_t set_speed) {
|
|||||||
// save current state of light in memory
|
// save current state of light in memory
|
||||||
ESP_LOGD(TAG, "Received light state: %d", set_light);
|
ESP_LOGD(TAG, "Received light state: %d", set_light);
|
||||||
this->light_cur = set_light;
|
this->light_cur = set_light;
|
||||||
|
if (!this->meet_target) {
|
||||||
|
// sync target light state if changed by button press
|
||||||
|
this->light_target = set_light;
|
||||||
|
}
|
||||||
// send light state to API if it is active
|
// send light state to API if it is active
|
||||||
if (this->send_light_state) {
|
if (this->send_light_state) {
|
||||||
ESP_LOGD(TAG, "Sending new light state.");
|
ESP_LOGD(TAG, "Sending new light state.");
|
||||||
@@ -234,12 +245,20 @@ void Hauslane::set_state(bool set_light, uint8_t set_speed) {
|
|||||||
// save current state of fan in memory
|
// save current state of fan in memory
|
||||||
ESP_LOGD(TAG, "Received fan speed: %d", set_speed);
|
ESP_LOGD(TAG, "Received fan speed: %d", set_speed);
|
||||||
this->speed = set_speed;
|
this->speed = set_speed;
|
||||||
|
if (!this->meet_target) {
|
||||||
|
// sync target fan state if changed by button press
|
||||||
|
this->speed_target = set_speed;
|
||||||
|
}
|
||||||
// send fan state to API if it is active
|
// send fan state to API if it is active
|
||||||
if (this->send_fan_speed) {
|
if (this->send_fan_speed) {
|
||||||
ESP_LOGD(TAG,"Sending new fan speed.");
|
ESP_LOGD(TAG,"Sending new fan speed.");
|
||||||
this->send_fan_speed(set_speed);
|
this->send_fan_speed(set_speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!this->power && (set_speed > 0 || set_light)) {
|
||||||
|
// set power to on if light or fan are on
|
||||||
|
this->power = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom component API commands
|
// custom component API commands
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/components/uart/uart.h"
|
#include "esphome/components/uart/uart.h"
|
||||||
|
#ifdef USE_API
|
||||||
#include "esphome/components/api/custom_api_device.h"
|
#include "esphome/components/api/custom_api_device.h"
|
||||||
|
#endif
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
#include "esphome/components/light/light_output.h"
|
#include "esphome/components/light/light_output.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -13,10 +15,11 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace hauslane {
|
namespace hauslane {
|
||||||
|
|
||||||
static const unsigned char MSG_START[] = {0x08, 0x08, 0x08, 0xfe, 0xc0};
|
static const unsigned char MSG_START[] = {0x08, 0x08, 0x08, 0xfe, 0x00, 0xc0};
|
||||||
static const unsigned char MSG_END[] = {0xc0, 0xce, 0xce, 0xce};
|
static const unsigned char MSG_END[] = {0xc0, 0xce, 0xce, 0xce, 0xc6};
|
||||||
static const uint8_t START_LEN=5;
|
static const uint8_t START_LEN=6;
|
||||||
static const uint8_t END_LEN=4;
|
static const uint8_t END_LEN=5;
|
||||||
|
static const size_t MAX_RX=30;
|
||||||
static const int DELAY=250; // how long to press/release buttons in ms
|
static const int DELAY=250; // how long to press/release buttons in ms
|
||||||
|
|
||||||
class Hauslane : public Component, public uart::UARTDevice, public api::CustomAPIDevice {
|
class Hauslane : public Component, public uart::UARTDevice, public api::CustomAPIDevice {
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ esphome:
|
|||||||
|
|
||||||
esp32:
|
esp32:
|
||||||
board: esp32-c3-devkitm-1
|
board: esp32-c3-devkitm-1
|
||||||
|
platform:
|
||||||
|
type: esp-idf
|
||||||
|
|
||||||
# Enable logging
|
# Enable logging
|
||||||
logger:
|
logger:
|
||||||
level: DEBUG
|
level: DEBUG
|
||||||
|
|
||||||
api:
|
api:
|
||||||
|
custom_services: true
|
||||||
password: !secret api_password
|
password: !secret api_password
|
||||||
|
|
||||||
ota:
|
ota:
|
||||||
|
|||||||
Reference in New Issue
Block a user