懒人创建智能家居之二——智能控制节点创建和连接
1 概述
在完成基本Home Assistant 操作系统并创建路由服务器之后,就可以添加智能控制节点了。在这个Home Assistant 操作系统的控制面板中,已经有很多定制的工具了。这里需要添加并使用ESPhome插件ESPHome,这样才能够添加所述定制的开发板和节点,这里使用的是ESP32C3和Rasperberry Pico W。并同时连接温度湿度传感器ADH20和照度传感器,以及控制LED照度。
2 所需硬件
2.1 ESP32C3模块
2.2 Rasperberry Pico W
2.3 温度湿度传感器ADH20和照度传感器,以及LED。
3 开始搞一下
3.1 首先进入控制台的ESPHome,可以见到已经创建的节点ESP32C3
点击edit进入yaml编辑界面
这个界面是一个文本编辑器,描述了这个节点是在ESPhome插件下的,使用arduino创建并下载代码的esp32开发板,并且定义了无线连接的ssid接入点和密码,便于无线连接
esphome:
name: xiao-esp32c3
platformio_options:
board_build.flash_mode: dio
esp32:
board: seeed_xiao_esp32c3
variant: esp32c3
framework:
type: arduino
platform_version: 5.4.0
logger:
hardware_uart: UART0
api:
ota:
wifi:
ssid: "UMASS fried chicken"
password: "Zacharyloveschicken"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Xiao-Esp32C3 Fallback Hotspot"
password: "MoLTqZUvHwWI"
复制代码然后点击INSTALL安装,确实,就是在这里,用这个文本就算完成编程了。随后立刻跳出了这个硬件的选择,可以看出都是ESP系列的各种模块,以及PICO W.
接着把开发板模块连接在树莓派上,选择设备,就跳出了连接的串口,
选择这个串口,就开始如下显示,编译安装了。具体其中的魔法,在后面详述。
同时这里还提供了另一种安装方式,就是通过网页安装用esphome网页GUI,进入这个选项,这个是在后台自己独自跑圈,形成可下载的bin文件,
然后进入如下esphome gui直接上传并安装到连接到串口的开发板
下载安装成功后继续撒花。
这个过程其实还有另一个用处,就是用命令行创建并生成独立的bin文件,自行下载。
具体的这个操作所执行的过程就如下
如果一切顺利,就可以继续启动这个节点的运行,随后继续在这个页面显示log的过程。
这样这个节点就创建成功并成功运行了。现在可以安全关闭这个页面,进入原先的页面,看起来没没啥变换啊。
貌似没变化,但是注意这个右上角的字符已经显示时online了,这个节点已经被识别并上线了。
3.3 添加节点到控制台面板
回到主页,就可以看到已经发现了新的esphome节点的esp32
添加配置这个已经发现的设备
选择安装的位置,是在哪个房间
确认后,就可以成功添加到控制面板。
3.4 添加传感器节点
这个节点添加后,就需要安装对于传感器的采集,对于风机,照明等的控制。按照前面的连接方法连接传感器并修改前面提到的yaml文件,添加下述i2c和adc定义
captive_portal:
i2c:
sda: GPIO6
scl: GPIO7
scan: True
id: bus_0x38
sensor:
- platform: aht10
temperature:
name: "Living Room Temperature"
humidity:
name: "Living Room Humidity"
update_interval: 60s
- platform: adc
pin: GPIO2
name: "Light Sensor"
update_interval: 6s
复制代码成功下载
随后按照功能加节点的传感器读数
这里找到了照度传感器的读数,现在显示0.61V,这个添加到控制面板的控制台如下,这时是在暗处,只有0.08V,每隔6秒采样一下。
4 面向文本的低代码开发解密
4.1 采用pico w为例,先如前述在esphome中添加设备,并安装下载yaml
这样就在esphome中注册成功了
4.2 其实,上述的过程就是一个创建工程并安装的过程。那么具体可以在计算机的命令行来实现
首先使用
pip install esphome
来安装开发工具,随后补充安装缺失的插件,这里platformio因为版本不兼容,需要卸载原有包并新安装
然后选择
esphome picow.yaml compile
编译成功的是一个uf2格式的文件
成功以后把这个文件安装到pico w就可以自行启动了。不用再重复上面的过程。并且同样可以添加接点,设计功能。
4.3 解密时间
这个HomeAssistant操作系统中esphome的使用方法,是首先把yaml文件转换成了一个arduino程序。
// Auto generated code by esphome
// ========== AUTO GENERATED INCLUDE BLOCK BEGIN ===========
#include "esphome.h"
using namespace esphome;
using std::isnan;
using std::min;
using std::max;
using namespace light;
wifi::WiFiComponent *wifi_wificomponent;
mdns::MDNSComponent *mdns_mdnscomponent;
StartupTrigger *startuptrigger;
Automation<> *automation;
using namespace output;
gpio::GPIOBinaryOutput *LED;
rp2040::RP2040GPIOPin *rp2040_rp2040gpiopin;
rp2040_pwm::RP2040PWM *led;
rp2040::RP2040GPIOPin *rp2040_rp2040gpiopin_2;
interval::IntervalTrigger *interval_intervaltrigger;
Automation<> *automation_2;
output::TurnOnAction<> *output_turnonaction;
DelayAction<> *delayaction;
output::TurnOffAction<> *output_turnoffaction;
monochromatic::MonochromaticLightOutput *monochromatic_monochromaticlightoutput;
light::LightState *pulsating_led;
light::PulseLightEffect *light_pulselighteffect;
light::LightControlAction<> *light_lightcontrolaction;
#define yield() esphome::yield()
#define millis() esphome::millis()
#define micros() esphome::micros()
#define delay(x) esphome::delay(x)
#define delayMicroseconds(x) esphome::delayMicroseconds(x)
// ========== AUTO GENERATED INCLUDE BLOCK END ==========="
void setup() {
// ========== AUTO GENERATED CODE BEGIN ===========
// rp2040:
// board: rpipicow
// framework:
// platform_version: https:github.com/maxgerhardt/platform-raspberrypi.git
rp2040::setup_preferences();
// esphome:
// name: rpi-pico
// friendly_name: Raspberry Pi Pico W
// on_boot:
// - then:
// - light.turn_on:
// id: pulsating_led
// effect: Slow pulse
// state: true
// type_id: light_lightcontrolaction
// automation_id: automation
// trigger_id: startuptrigger
// priority: 600.0
// build_path: build/rpi-pico
// area: ''
// platformio_options: {}
// includes: []
// libraries: []
// name_add_mac_suffix: false
// min_version: 2023.12.3
App.pre_setup("rpi-pico", "Raspberry Pi Pico W", "", "", __DATE__ ", " __TIME__, false);
// light:
// wifi:
// ap:
wifi_wificomponent = new wifi::WiFiComponent();
wifi_wificomponent->set_use_address("rpi-pico.local");
{
wifi::WiFiAP wifi_wifiap_2 = wifi::WiFiAP();
wifi_wifiap_2.set_ssid("TP-LINK_2.4GHz_FFF1EC");
wifi_wifiap_2.set_password("13810963660");
wifi_wifiap_2.set_priority(0.0f);
wifi_wificomponent->add_sta(wifi_wifiap_2);
}
{
wifi::WiFiAP wifi_wifiap = wifi::WiFiAP();
wifi_wifiap.set_ssid("PICOW Fallback Hotspot");
wifi_wifiap.set_password("Checwifi0617");
wifi_wificomponent->set_ap(wifi_wifiap);
}
wifi_wificomponent->set_ap_timeout(60000);
wifi_wificomponent->set_reboot_timeout(900000);
wifi_wificomponent->set_power_save_mode(wifi::WIFI_POWER_SAVE_LIGHT);
wifi_wificomponent->set_fast_connect(false);
wifi_wificomponent->set_passive_scan(false);
wifi_wificomponent->set_enable_on_boot(true);
wifi_wificomponent->set_component_source("wifi");
App.register_component(wifi_wificomponent);
// mdns:
// id: mdns_mdnscomponent
// disabled: false
// services: []
mdns_mdnscomponent = new mdns::MDNSComponent();
mdns_mdnscomponent->set_component_source("mdns");
App.register_component(mdns_mdnscomponent);
startuptrigger = new StartupTrigger(600.0f);
startuptrigger->set_component_source("esphome.coroutine");
App.register_component(startuptrigger);
automation = new Automation<>(startuptrigger);
// output:
// output.gpio:
// platform: gpio
// pin:
// number: 25
// mode:
// output: true
// input: false
// open_drain: false
// pullup: false
// pulldown: false
// analog: false
// id: rp2040_rp2040gpiopin
// inverted: false
// id: LED
LED = new gpio::GPIOBinaryOutput();
LED->set_component_source("gpio.output");
App.register_component(LED);
rp2040_rp2040gpiopin = new rp2040::RP2040GPIOPin();
rp2040_rp2040gpiopin->set_pin(25);
rp2040_rp2040gpiopin->set_inverted(false);
rp2040_rp2040gpiopin->set_flags(gpio::Flags::FLAG_OUTPUT);
LED->set_pin(rp2040_rp2040gpiopin);
// output.rp2040_pwm:
// platform: rp2040_pwm
// pin:
// number: 15
// mode:
// output: true
// input: false
// open_drain: false
// pullup: false
// pulldown: false
// analog: false
// id: rp2040_rp2040gpiopin_2
// inverted: false
// id: led
// zero_means_zero: false
// frequency: 1000.0
led = new rp2040_pwm::RP2040PWM();
led->set_component_source("rp2040_pwm.output");
App.register_component(led);
led->set_zero_means_zero(false);
rp2040_rp2040gpiopin_2 = new rp2040::RP2040GPIOPin();
rp2040_rp2040gpiopin_2->set_pin(15);
rp2040_rp2040gpiopin_2->set_inverted(false);
rp2040_rp2040gpiopin_2->set_flags(gpio::Flags::FLAG_OUTPUT);
led->set_pin(rp2040_rp2040gpiopin_2);
led->set_frequency(1000.0f);
// interval:
// - interval: 500ms
// then:
// - output.turn_on:
// id: LED
// type_id: output_turnonaction
// - delay: 250ms
// type_id: delayaction
// - output.turn_off:
// id: LED
// type_id: output_turnoffaction
// trigger_id: trigger
// automation_id: automation_2
// id: interval_intervaltrigger
// startup_delay: 0s
interval_intervaltrigger = new interval::IntervalTrigger();
interval_intervaltrigger->set_component_source("interval");
App.register_component(interval_intervaltrigger);
automation_2 = new Automation<>(interval_intervaltrigger);
output_turnonaction = new output::TurnOnAction<>(LED);
delayaction = new DelayAction<>();
delayaction->set_component_source("interval");
App.register_component(delayaction);
delayaction->set_delay(250);
output_turnoffaction = new output::TurnOffAction<>(LED);
automation_2->add_actions({output_turnonaction, delayaction, output_turnoffaction});
interval_intervaltrigger->set_update_interval(500);
interval_intervaltrigger->set_startup_delay(0);
// light.monochromatic:
// platform: monochromatic
// output: led
// id: pulsating_led
// effects:
// - pulse:
// name: Slow pulse
// transition_length: 2s
// update_interval: 2s
// min_brightness: 0.0
// max_brightness: 1.0
// type_id: light_pulselighteffect
// disabled_by_default: false
// restore_mode: ALWAYS_OFF
// gamma_correct: 2.8
// default_transition_length: 1s
// flash_transition_length: 0s
// output_id: monochromatic_monochromaticlightoutput
// name: pulsating_led
// internal: true
monochromatic_monochromaticlightoutput = new monochromatic::MonochromaticLightOutput();
pulsating_led = new light::LightState(monochromatic_monochromaticlightoutput);
App.register_light(pulsating_led);
pulsating_led->set_component_source("light");
App.register_component(pulsating_led);
pulsating_led->set_name("pulsating_led");
pulsating_led->set_object_id("pulsating_led");
pulsating_led->set_disabled_by_default(false);
pulsating_led->set_internal(true);
pulsating_led->set_restore_mode(light::LIGHT_ALWAYS_OFF);
pulsating_led->set_default_transition_length(1000);
pulsating_led->set_flash_transition_length(0);
pulsating_led->set_gamma_correct(2.8f);
light_pulselighteffect = new light::PulseLightEffect("Slow pulse");
light_pulselighteffect->set_transition_on_length(2000);
light_pulselighteffect->set_transition_off_length(2000);
light_pulselighteffect->set_update_interval(2000);
light_pulselighteffect->set_min_max_brightness(0.0f, 1.0f);
pulsating_led->add_effects({light_pulselighteffect});
monochromatic_monochromaticlightoutput->set_output(led);
// network:
// enable_ipv6: false
light_lightcontrolaction = new light::LightControlAction<>(pulsating_led);
light_lightcontrolaction->set_state(true);
light_lightcontrolaction->set_effect("Slow pulse");
automation->add_actions({light_lightcontrolaction});
// =========== AUTO GENERATED CODE END ============
App.setup();
}
void loop() {
App.loop();
}
复制代码setup()
以及
void loop() {
App.loop();
}
复制代码#include "esphome.h"
复制代码
浏览图文,没有细读细想,不是因为懒,而是因为不会这技术,倒是想关注实用性、适用性