updating configuration
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
# Gitignore settings for ESPHome
|
||||
# This is an example and may include too much for your use-case.
|
||||
# You can modify this file to suit your needs.
|
||||
/.esphome/
|
||||
**/.pioenvs/
|
||||
**/.piolibdeps/
|
||||
**/lib/
|
||||
**/src/
|
||||
**/platformio.ini
|
||||
/secrets.yaml
|
||||
@@ -0,0 +1,67 @@
|
||||
substitutions:
|
||||
# Уникальное имя этой конфигурации, стоит использовать только латинские буквы и цифры, никаких пробелов или
|
||||
# спецсимволов, например, "tclac". Если будет несколько модулей кондиционера, то device_name надо изменить,
|
||||
# например, добавляя цифры: tclac1, tclac2, tclac3...
|
||||
device_name: ac_bedroom
|
||||
# Человеческое имя для кондиционера, для интерфейса:
|
||||
humanly_name: "Кондиционер Спальня"
|
||||
# Настройки подключения к WiFI, данные могут храниться в файле "secret" в ESPHome, если нет- редактируем:
|
||||
# Имя точки доступа WiFI:
|
||||
wifi_ssid: !secret wifi_24_name
|
||||
# Пароль точки доступа WiFI:
|
||||
wifi_password: !secret wifi_24_pass
|
||||
# Пароль для точки доступа для восстановления, имя точки доступа будет: "{device_name} Fallback Hotspot"
|
||||
recovery_pass: !secret esphome_captive_pass
|
||||
# Пароль для обновления по воздуху, генерируется один раз и потом используется всегда на автомате:
|
||||
ota_pass: !secret api_encryption_key
|
||||
# Ключ подключения к Home Assistant API, новый ключ можно получить здесь: https://esphome.io/components/api.html:
|
||||
api_key: !secret api_encryption_key
|
||||
# Выводы модуля, к которым подключен UART:
|
||||
uart_rx: GPIO3
|
||||
uart_tx: GPIO1
|
||||
# Выводы модуля для подключения сигнальных светодиодов, для работы надо раскомментировать "leds" в "packages"
|
||||
# иначе работать не будет совсем и можно писать сюда вообще что угодною. Для тех, кто просил их удалить.
|
||||
receive_led: GPIO6
|
||||
transmit_led: GPIO4
|
||||
device_host: ac-bedroom.lan
|
||||
|
||||
# Подгружаемые файлы- загружаются и обновляются автоматически из интернета, раскомментировать нужные
|
||||
# Описание опций:
|
||||
# - packages/leds.yaml - светодиоды для индикации приема/передачи, пины указываются в receive_led / transmit_led
|
||||
#
|
||||
# Выравнивать раскомментированные строки обязательно по указанной позиции!
|
||||
packages:
|
||||
remote_package:
|
||||
url: https://github.com/I-am-nightingale/tclac.git
|
||||
ref: master
|
||||
files:
|
||||
- packages/core.yaml # Ядро всего сущего
|
||||
# - packages/leds.yaml
|
||||
refresh: 30s
|
||||
|
||||
wifi:
|
||||
use_address: ${device_host}
|
||||
|
||||
esp8266:
|
||||
board: d1_mini
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: superLongP4ss
|
||||
|
||||
sensor:
|
||||
- platform: template
|
||||
name: "Текущая точная температура"
|
||||
id: current_temperature_precise
|
||||
unit_of_measurement: "°C"
|
||||
accuracy_decimals: 2 # Настраиваем точность до сотых
|
||||
update_interval: 30s # Интервал обновления, можно настроить по необходимости
|
||||
lambda: |-
|
||||
// Возвращаем значение переменной current_temperature из компонента tclacClimate
|
||||
return id(${device_name}climate).current_temperature;
|
||||
|
||||
button:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
@@ -0,0 +1,67 @@
|
||||
substitutions:
|
||||
# Уникальное имя этой конфигурации, стоит использовать только латинские буквы и цифры, никаких пробелов или
|
||||
# спецсимволов, например, "tclac". Если будет несколько модулей кондиционера, то device_name надо изменить,
|
||||
# например, добавляя цифры: tclac1, tclac2, tclac3...
|
||||
device_name: ac_childroom
|
||||
# Человеческое имя для кондиционера, для интерфейса:
|
||||
humanly_name: "Кондиционер Детская"
|
||||
# Настройки подключения к WiFI, данные могут храниться в файле "secret" в ESPHome, если нет- редактируем:
|
||||
# Имя точки доступа WiFI:
|
||||
wifi_ssid: !secret wifi_24_name
|
||||
# Пароль точки доступа WiFI:
|
||||
wifi_password: !secret wifi_24_pass
|
||||
# Пароль для точки доступа для восстановления, имя точки доступа будет: "{device_name} Fallback Hotspot"
|
||||
recovery_pass: !secret esphome_captive_pass
|
||||
# Пароль для обновления по воздуху, генерируется один раз и потом используется всегда на автомате:
|
||||
ota_pass: !secret api_encryption_key
|
||||
# Ключ подключения к Home Assistant API, новый ключ можно получить здесь: https://esphome.io/components/api.html:
|
||||
api_key: !secret api_encryption_key
|
||||
# Выводы модуля, к которым подключен UART:
|
||||
uart_rx: GPIO3
|
||||
uart_tx: GPIO1
|
||||
# Выводы модуля для подключения сигнальных светодиодов, для работы надо раскомментировать "leds" в "packages"
|
||||
# иначе работать не будет совсем и можно писать сюда вообще что угодною. Для тех, кто просил их удалить.
|
||||
receive_led: GPIO6
|
||||
transmit_led: GPIO4
|
||||
device_host: ac-childroom.lan
|
||||
|
||||
# Подгружаемые файлы- загружаются и обновляются автоматически из интернета, раскомментировать нужные
|
||||
# Описание опций:
|
||||
# - packages/leds.yaml - светодиоды для индикации приема/передачи, пины указываются в receive_led / transmit_led
|
||||
#
|
||||
# Выравнивать раскомментированные строки обязательно по указанной позиции!
|
||||
packages:
|
||||
remote_package:
|
||||
url: https://github.com/I-am-nightingale/tclac.git
|
||||
ref: master
|
||||
files:
|
||||
- packages/core.yaml # Ядро всего сущего
|
||||
# - packages/leds.yaml
|
||||
refresh: 30s
|
||||
|
||||
esp8266:
|
||||
board: d1_mini
|
||||
|
||||
wifi:
|
||||
use_address: ${device_host}
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: superLongP4ss
|
||||
|
||||
sensor:
|
||||
- platform: template
|
||||
name: "Текущая точная температура"
|
||||
id: current_temperature_precise
|
||||
unit_of_measurement: "°C"
|
||||
accuracy_decimals: 2 # Настраиваем точность до сотых
|
||||
update_interval: 30s # Интервал обновления, можно настроить по необходимости
|
||||
lambda: |-
|
||||
// Возвращаем значение переменной current_temperature из компонента tclacClimate
|
||||
return id(${device_name}climate).current_temperature;
|
||||
|
||||
button:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
@@ -0,0 +1,88 @@
|
||||
#===============================================================================
|
||||
# Контроллер кондиционера в гостиной
|
||||
# Wemos D1 mini
|
||||
#===============================================================================
|
||||
substitutions:
|
||||
node_name: ac_kitchen # Use a unique name.
|
||||
hostname: ac-kitchen.lan
|
||||
friendly_node_name: "Кондиционер Кухня"
|
||||
|
||||
#===============================================================================
|
||||
# Общий конфиг
|
||||
#===============================================================================
|
||||
esphome:
|
||||
name: ${node_name}
|
||||
friendly_name: ${friendly_node_name}
|
||||
|
||||
esp8266:
|
||||
board: esp12e
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: superLongP4ss
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret api_encryption_key
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
use_address: 192.168.1.127 #${hostname}
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "${node_name} Fallback Hotspot"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
baud_rate: 0 # disable LOG output on UART as UART is used for Sinclair AC unit
|
||||
# level: VERBOSE
|
||||
|
||||
uart:
|
||||
tx_pin: 1
|
||||
rx_pin: 3
|
||||
baud_rate: 4800
|
||||
parity: EVEN
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
|
||||
external_components:
|
||||
- source: github://gekkehenkie11/esphome_gree_ac
|
||||
components: [sinclair_ac]
|
||||
refresh: 0s
|
||||
|
||||
climate:
|
||||
- platform: sinclair_ac
|
||||
name: ${node_name}
|
||||
horizontal_swing_select:
|
||||
name: ${node_name} Horizontal Swing Mode
|
||||
vertical_swing_select:
|
||||
name: ${node_name} Vertical Swing Mode
|
||||
display_select:
|
||||
name: ${node_name} Display Mode
|
||||
display_unit_select:
|
||||
name: ${node_name} Display Unit
|
||||
plasma_switch:
|
||||
name: ${node_name} Plasma
|
||||
sleep_switch:
|
||||
name: ${node_name} Sleep
|
||||
xfan_switch:
|
||||
name: ${node_name} X-fan
|
||||
save_switch:
|
||||
name: ${node_name} Save/8 Heat
|
||||
|
||||
button:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
@@ -0,0 +1,91 @@
|
||||
#===============================================================================
|
||||
# Контроллер кондиционера в гостиной
|
||||
# Wemos D1 mini
|
||||
#===============================================================================
|
||||
substitutions:
|
||||
node_name: ac_mainroom # Use a unique name.
|
||||
node_id: ac_mainroom # Use a unique id.
|
||||
deviceid: ac_mainroom
|
||||
devicename: ac_mainroom
|
||||
friendly_node_name: "Кондиционер Гостиная"
|
||||
device_host: ac-mainroom.lan
|
||||
|
||||
#===============================================================================
|
||||
# Общий конфиг
|
||||
#===============================================================================
|
||||
esphome:
|
||||
name: ${node_name}
|
||||
friendly_name: ${friendly_node_name}
|
||||
|
||||
esp8266:
|
||||
board: esp12e
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret api_encryption_key
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
use_address: ${device_host}
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "${devicename} Fallback Hotspot"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
baud_rate: 0 # disable LOG output on UART as UART is used for Sinclair AC unit
|
||||
# level: VERBOSE
|
||||
|
||||
uart:
|
||||
tx_pin: 1
|
||||
rx_pin: 3
|
||||
baud_rate: 4800
|
||||
parity: EVEN
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
|
||||
external_components:
|
||||
- source: github://gekkehenkie11/esphome_gree_ac
|
||||
components: [sinclair_ac]
|
||||
refresh: 0s
|
||||
|
||||
climate:
|
||||
- platform: sinclair_ac
|
||||
name: ${devicename}
|
||||
horizontal_swing_select:
|
||||
name: ${devicename} Horizontal Swing Mode
|
||||
vertical_swing_select:
|
||||
name: ${devicename} Vertical Swing Mode
|
||||
display_select:
|
||||
name: ${devicename} Display Mode
|
||||
display_unit_select:
|
||||
name: ${devicename} Display Unit
|
||||
plasma_switch:
|
||||
name: ${devicename} Plasma
|
||||
sleep_switch:
|
||||
name: ${devicename} Sleep
|
||||
xfan_switch:
|
||||
name: ${devicename} X-fan
|
||||
save_switch:
|
||||
name: ${devicename} Save/8 Heat
|
||||
|
||||
button:
|
||||
- platform: restart
|
||||
name: "Restart"
|
||||
@@ -0,0 +1,116 @@
|
||||
#===============================================================================
|
||||
# Контроллер кондиционера в гостиной
|
||||
# Wemos D1 mini
|
||||
#===============================================================================
|
||||
substitutions:
|
||||
node_name: ac_bedroom # Use a unique name.
|
||||
node_id: ac_bedroom # Use a unique id.
|
||||
deviceid: ac_bedroom
|
||||
devicename: ac_bedroom
|
||||
friendly_node_name: "Кондиционер Спальня"
|
||||
|
||||
#===============================================================================
|
||||
# Общий конфиг
|
||||
#===============================================================================
|
||||
esphome:
|
||||
name: ${node_name}
|
||||
friendly_name: ${friendly_node_name}
|
||||
includes:
|
||||
- ac_tcl_climate.h
|
||||
|
||||
esp8266:
|
||||
board: d1_mini
|
||||
|
||||
external_components:
|
||||
- source:
|
||||
type: git
|
||||
url: https://github.com/robertklep/esphome-custom-component
|
||||
components: [ custom, custom_component ]
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: superLongP4ss
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret api_encryption_key
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "${devicename} Fallback Hotspot"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
uart:
|
||||
id: uart_bus
|
||||
tx_pin: 1
|
||||
rx_pin: 3
|
||||
baud_rate: 9600
|
||||
parity: EVEN
|
||||
|
||||
logger:
|
||||
#level: VERBOSE
|
||||
baud_rate: 0
|
||||
|
||||
climate:
|
||||
- platform: custom
|
||||
lambda: |-
|
||||
auto my_custom_climate = new MyCustomClimate(id(uart_bus));
|
||||
App.register_component(my_custom_climate);
|
||||
return {my_custom_climate};
|
||||
|
||||
climates:
|
||||
- name: "TCL a/c"
|
||||
id: my_custom_climate
|
||||
|
||||
select:
|
||||
- platform: template
|
||||
name: Vertical swing
|
||||
id: vswing
|
||||
entity_category: config
|
||||
options:
|
||||
- "Last position"
|
||||
- "Fix top"
|
||||
- "Fix upper"
|
||||
- "Fix mid"
|
||||
- "Fix lower"
|
||||
- "Fix bottom"
|
||||
- "Move full"
|
||||
- "Move upper"
|
||||
- "Move lower"
|
||||
set_action:
|
||||
then:
|
||||
lambda: |-
|
||||
static_cast<MyCustomClimate*>(id(my_custom_climate))->control_vertical_swing(x);
|
||||
|
||||
- platform: template
|
||||
name: Horizontal swing
|
||||
id: hswing
|
||||
entity_category: config
|
||||
options:
|
||||
- "Last position"
|
||||
- "Fix left"
|
||||
- "Fix mid left"
|
||||
- "Fix mid"
|
||||
- "Fix mid right"
|
||||
- "Fix right"
|
||||
- "Move full"
|
||||
- "Move left"
|
||||
- "Move mid"
|
||||
- "Move right"
|
||||
set_action:
|
||||
then:
|
||||
lambda: |-
|
||||
static_cast<MyCustomClimate*>(id(my_custom_climate))->control_horizontal_swing(x);
|
||||
@@ -0,0 +1,117 @@
|
||||
#===============================================================================
|
||||
# Контроллер кондиционера в гостиной
|
||||
# Wemos D1 mini
|
||||
#===============================================================================
|
||||
substitutions:
|
||||
node_name: ac_childroom # Use a unique name.
|
||||
node_id: ac_childroom # Use a unique id.
|
||||
deviceid: ac_childroom
|
||||
devicename: ac_childroom
|
||||
friendly_node_name: "Кондиционер Детская"
|
||||
|
||||
#===============================================================================
|
||||
# Общий конфиг
|
||||
#===============================================================================
|
||||
esphome:
|
||||
name: ${node_name}
|
||||
friendly_name: ${friendly_node_name}
|
||||
includes:
|
||||
- ac_tcl_climate.h
|
||||
|
||||
esp8266:
|
||||
board: d1_mini
|
||||
|
||||
external_components:
|
||||
- source:
|
||||
type: git
|
||||
url: https://github.com/robertklep/esphome-custom-component
|
||||
components: [ custom, custom_component ]
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: superLongP4ss
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret api_encryption_key
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
use_address: 192.168.1.188
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "${devicename} Fallback Hotspot"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
uart:
|
||||
id: uart_bus
|
||||
tx_pin: 1
|
||||
rx_pin: 3
|
||||
baud_rate: 9600
|
||||
parity: EVEN
|
||||
|
||||
logger:
|
||||
level: VERBOSE
|
||||
baud_rate: 0
|
||||
|
||||
climate:
|
||||
- platform: custom
|
||||
lambda: |-
|
||||
auto my_custom_climate = new MyCustomClimate(id(uart_bus));
|
||||
App.register_component(my_custom_climate);
|
||||
return {my_custom_climate};
|
||||
|
||||
climates:
|
||||
- name: "TCL a/c"
|
||||
id: my_custom_climate
|
||||
|
||||
select:
|
||||
- platform: template
|
||||
name: Vertical swing
|
||||
id: vswing
|
||||
entity_category: config
|
||||
options:
|
||||
- "Last position"
|
||||
- "Fix top"
|
||||
- "Fix upper"
|
||||
- "Fix mid"
|
||||
- "Fix lower"
|
||||
- "Fix bottom"
|
||||
- "Move full"
|
||||
- "Move upper"
|
||||
- "Move lower"
|
||||
set_action:
|
||||
then:
|
||||
lambda: |-
|
||||
static_cast<MyCustomClimate*>(id(my_custom_climate))->control_vertical_swing(x);
|
||||
|
||||
- platform: template
|
||||
name: Horizontal swing
|
||||
id: hswing
|
||||
entity_category: config
|
||||
options:
|
||||
- "Last position"
|
||||
- "Fix left"
|
||||
- "Fix mid left"
|
||||
- "Fix mid"
|
||||
- "Fix mid right"
|
||||
- "Fix right"
|
||||
- "Move full"
|
||||
- "Move left"
|
||||
- "Move mid"
|
||||
- "Move right"
|
||||
set_action:
|
||||
then:
|
||||
lambda: |-
|
||||
static_cast<MyCustomClimate*>(id(my_custom_climate))->control_horizontal_swing(x);
|
||||
@@ -0,0 +1,190 @@
|
||||
sensor: []
|
||||
substitutions:
|
||||
board_name: Coffee Philips 5400
|
||||
device_name: coffee-philips-5400
|
||||
|
||||
esphome:
|
||||
name: ${device_name}
|
||||
friendly_name: ${board_name}
|
||||
comment: ${board_name}
|
||||
|
||||
esp32:
|
||||
board: esp32dev
|
||||
framework:
|
||||
type: arduino
|
||||
|
||||
# Enable logging
|
||||
#Журналирование
|
||||
logger:
|
||||
level: INFO #NONE
|
||||
baud_rate: 0
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
password: "S/6VwLrSJ+vRfPKWYzbg+iasPO6h3sXm3jY9Ko1YCOo="
|
||||
|
||||
#Учетные данные Wi-Fi для подключения платы к домашней сети
|
||||
wifi:
|
||||
ssid: "MonsterFNV"
|
||||
password: "7065485qwe"
|
||||
use_address: ${device_name}.lan
|
||||
|
||||
#Если не будет связи с WiFi, то поднимется точка доступа
|
||||
ap:
|
||||
ssid: ESP SmartCoffeePhilips
|
||||
password: ap_esp_password
|
||||
|
||||
uart:
|
||||
#UART подключение к панели управления. Считываем данные которые приходят от материнской плате в панель управления
|
||||
- id: uart_display
|
||||
rx_pin: GPIO16 #Считываем данные с панели управления
|
||||
tx_pin: GPIO17 #Посылаем данные в панель управления
|
||||
baud_rate: 115200
|
||||
stop_bits: 1
|
||||
data_bits: 8
|
||||
parity: NONE
|
||||
rx_buffer_size: 256
|
||||
|
||||
- id: uart_mainboard
|
||||
rx_pin: GPIO14 #Считываем данные с материнской платы
|
||||
tx_pin: GPIO5 #Посылаем данные в материнскую плату
|
||||
baud_rate: 115200
|
||||
stop_bits: 1
|
||||
data_bits: 8
|
||||
parity: NONE
|
||||
rx_buffer_size: 256
|
||||
|
||||
external_components:
|
||||
- source:
|
||||
type: local
|
||||
path: ./components
|
||||
|
||||
saeco_series_6000:
|
||||
id: saeco_series_6000_component
|
||||
uart_display: uart_display
|
||||
uart_mainboard: uart_mainboard
|
||||
debug: true
|
||||
state_sensor:
|
||||
name: Work State
|
||||
id: idControlSensor
|
||||
internal: True #Скрыть - True \показать - False
|
||||
on_value:
|
||||
then:
|
||||
- lambda: |-
|
||||
//Статус состояния кофемашины, включена или выключена
|
||||
if(x==2){
|
||||
id(idPowerStatus).publish_state(false);
|
||||
} else if(id(idPowerStatus).state==false){
|
||||
id(idPowerStatus).publish_state(true);
|
||||
}
|
||||
|
||||
//AA:AA:AA:B0 "Системные сенсоры"
|
||||
if(x==21){
|
||||
id(idStatus).publish_state("Выберите напиток");
|
||||
id(idWater).publish_state("Вода есть");
|
||||
id(idPallet).publish_state("Вставлен");
|
||||
id(idGrainTray).publish_state("Зерна есть");
|
||||
id(idCoffeeGroundsContainer).publish_state("Пустой");
|
||||
}
|
||||
|
||||
//AA:AA:AA:B0 "Статусы"
|
||||
else if(x==1){id(idStatus).publish_state("Что-то (07 01 00)");}
|
||||
else if(x==2){id(idStatus).publish_state("Выключено");}
|
||||
else if(x==3){id(idStatus).publish_state("Наливаем молоко");}
|
||||
else if(x==4){id(idStatus).publish_state("Наливаем кофе");}
|
||||
else if(x==5){id(idStatus).publish_state("Предварительное дозирование");}
|
||||
else if(x==6){id(idStatus).publish_state("Создание пара для молока");}
|
||||
else if(x==7){id(idStatus).publish_state("Заварочный узел в положение заваривания");}
|
||||
else if(x==8){id(idStatus).publish_state("Наслаждайтесь");}
|
||||
else if(x==9){id(idStatus).publish_state("Нагрев воды");}
|
||||
else if(x==10){id(idStatus).publish_state("Перемалываем зерна");}
|
||||
else if(x==11){id(idStatus).publish_state("Промывка");}
|
||||
else if(x==12){id(idGrainTray).publish_state("Зерна закончились");}
|
||||
else if(x==13){id(idStatus).publish_state("Что-то (07 08 14)");}
|
||||
else if(x==14){id(idStatus).publish_state("Нагревание");}
|
||||
else if(x==15){id(idStatus).publish_state("Наслаждайтесь");}
|
||||
else if(x==16){id(idStatus).publish_state("Что-то (07 0C 02)");}
|
||||
else if(x==17){id(idWater).publish_state("Вода есть");}
|
||||
else if(x==18){id(idPallet).publish_state("Вставлен");}
|
||||
else if(x==20){id(idCoffeeGroundsContainer).publish_state("Опорож. контейнер для коф. гущи");}
|
||||
else if(x==22){id(idWater).publish_state("Воды нет");}
|
||||
else if(x==23){id(idPallet).publish_state("Извлечен");}
|
||||
else if(x==24){id(idPallet).publish_state("Очистка от накипи. Шаг 1");}
|
||||
else if(x==25){id(idPallet).publish_state("Очистка от накипи. Шаг 2");}
|
||||
|
||||
|
||||
//AA:AA:AA:B5 "Error Code"
|
||||
else if(x==30){id(idErrorCode).publish_state("00");}
|
||||
else if(x==31){id(idErrorCode).publish_state("0B");}
|
||||
else if(x==32){id(idErrorCode).publish_state("E6");}
|
||||
else if(x==33){id(idErrorCode).publish_state("80");}
|
||||
else if(x==34){id(idErrorCode).publish_state("CB");}
|
||||
else if(x==35){id(idErrorCode).publish_state("FF");}
|
||||
else if(x==36){id(idErrorCode).publish_state("A0");}
|
||||
|
||||
#####################################################################################
|
||||
################################## Бинарный сенсор ##################################
|
||||
#Статус кофемашины: включена или выключена
|
||||
binary_sensor:
|
||||
- platform: template
|
||||
name: "Power Status"
|
||||
id: idPowerStatus
|
||||
icon: mdi:power
|
||||
|
||||
#####################################################################################
|
||||
################################### Текстовый сенсор ################################
|
||||
|
||||
text_sensor:
|
||||
- platform: template
|
||||
name: "Status"
|
||||
id: idStatus
|
||||
icon: mdi:coffee-to-go
|
||||
update_interval: never
|
||||
- platform: template
|
||||
name: "Water"
|
||||
id: idWater
|
||||
icon: mdi:cup-water
|
||||
update_interval: never
|
||||
- platform: template
|
||||
name: "Coffee Pallet"
|
||||
id: idPallet
|
||||
icon: mdi:spirit-level
|
||||
update_interval: never
|
||||
- platform: template
|
||||
name: "Grain Tray"
|
||||
id: idGrainTray
|
||||
icon: mdi:grain
|
||||
update_interval: never
|
||||
- platform: template
|
||||
name: "Coffee Grounds Container"
|
||||
id: idCoffeeGroundsContainer
|
||||
icon: mdi:train-car-centerbeam-full
|
||||
update_interval: never
|
||||
- platform: template
|
||||
name: "Error Code"
|
||||
id: idErrorCode
|
||||
icon: mdi:alert-circle-outline
|
||||
update_interval: never
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: "Американо"
|
||||
on_press:
|
||||
then:
|
||||
- lambda: |-
|
||||
id(saeco_series_6000_component)->send_packets_to_mainboard(
|
||||
std::vector<std::string>{
|
||||
"AA AA AA 93 0E 01 01 8B BD 33 EA 55",
|
||||
"AA AA AA 90 0F 0A 00 02 00 03 02 00 B4 00 00 00 67 48 E4 4B 55",
|
||||
"AA AA AA 91 10 01 03 56 9A 8C B8 55"
|
||||
}, 50);
|
||||
|
||||
#[20:45:34][I][saeco_series_6000:079]: Packet from Display: AA AA AA 93 0A 01 01 57 15 3A ED 55
|
||||
#[20:45:34][I][saeco_series_6000:079]: Packet from Display: AA AA AA 90 0B 0A 05 03 00 02 00 00 64 00 00 00 39 BF 5B 74 55
|
||||
#[20:45:35][I][saeco_series_6000:079]: Packet from Display: AA AA AA 91 0C 01 03 42 C0 B0 AD 55"
|
||||
@@ -0,0 +1,98 @@
|
||||
DEPENDENCIES = ["uart", "sensor"]
|
||||
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import uart, sensor, button
|
||||
from esphome.const import CONF_ID, CONF_DEBUG
|
||||
import esphome.automation as automation
|
||||
|
||||
CONF_STATE_SENSOR = "state_sensor"
|
||||
CONF_B0_STATUS_SENSOR = "b0_status_sensor"
|
||||
CONF_B5_STATUS_SENSOR = "b5_status_sensor"
|
||||
CONF_BA_STATUS_SENSOR = "ba_status_sensor"
|
||||
CONF_S90_STATUS_SENSOR = "s90_status_sensor"
|
||||
CONF_S91_STATUS_SENSOR = "s91_status_sensor"
|
||||
CONF_S93_STATUS_SENSOR = "s93_status_sensor"
|
||||
CONF_WATER_SENSOR = "water_sensor"
|
||||
CONF_COFFEE_GROUNDS_CONTAINER_SENSOR = "coffee_grounds_container_sensor"
|
||||
CONF_PALLET_SENSOR = "pallet_sensor"
|
||||
CONF_ERROR_CODE_SENSOR = "error_code_sensor"
|
||||
CONF_GRAIN_TRAY_SENSOR = "grain_tray_sensor"
|
||||
CONF_STATUS_TEXT_SENSOR = "status_text_sensor"
|
||||
CONF_PACKETS = "packets"
|
||||
CONF_SAECO_ID = "saeco_id"
|
||||
|
||||
saeco_series_6000_ns = cg.esphome_ns.namespace('saeco_series_6000')
|
||||
SaecoSeries6000 = saeco_series_6000_ns.class_('SaecoSeries6000', cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(cv.CONF_ID): cv.declare_id(SaecoSeries6000),
|
||||
cv.Required('uart_display'): cv.use_id(uart.UARTComponent),
|
||||
cv.Required('uart_mainboard'): cv.use_id(uart.UARTComponent),
|
||||
cv.Optional(CONF_DEBUG, default=False): cv.boolean,
|
||||
cv.Optional(CONF_STATE_SENSOR): sensor.sensor_schema(),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield cg.register_component(var, config)
|
||||
|
||||
uart_display = yield cg.get_variable(config['uart_display'])
|
||||
cg.add(var.set_uart_display(uart_display))
|
||||
|
||||
uart_mainboard = yield cg.get_variable(config['uart_mainboard'])
|
||||
cg.add(var.set_uart_mainboard(uart_mainboard))
|
||||
|
||||
if config[CONF_DEBUG]:
|
||||
cg.add(var.set_debug(True))
|
||||
|
||||
if CONF_STATE_SENSOR in config:
|
||||
sens = yield sensor.new_sensor(config[CONF_STATE_SENSOR])
|
||||
cg.add(var.set_status_sensor(sens))
|
||||
|
||||
def validate_packet(value):
|
||||
if isinstance(value, str):
|
||||
return [int(x, 16) for x in value.split()]
|
||||
return [cv.hex_uint8_t(x) for x in value]
|
||||
|
||||
SEND_PACKETS_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(SaecoSeries6000),
|
||||
cv.Required(CONF_PACKETS): [cv.All(validate_packet)],
|
||||
cv.Optional("delay_ms", default=10): cv.positive_int,
|
||||
})
|
||||
|
||||
SendPacketsAction = saeco_series_6000_ns.class_("SendPacketsAction", automation.Action)
|
||||
|
||||
@automation.register_action(
|
||||
"saeco_series_6000.send_packets",
|
||||
SendPacketsAction,
|
||||
SEND_PACKETS_ACTION_SCHEMA,
|
||||
)
|
||||
def send_packets_to_mainboard_action_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id)
|
||||
parent = yield cg.get_variable(config[CONF_ID])
|
||||
var.set_parent(parent)
|
||||
var.set_packets(config[CONF_PACKETS])
|
||||
var.set_delay_ms(config.get("delay_ms", 10))
|
||||
return var
|
||||
|
||||
SaecoSendPacketsButton = saeco_series_6000_ns.class_("SaecoSendPacketsButton", button.Button, cg.Component)
|
||||
|
||||
SAECO_SEND_PACKETS_BUTTON_SCHEMA = button.BUTTON_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(SaecoSendPacketsButton),
|
||||
cv.Required(CONF_ID): cv.use_id(SaecoSeries6000),
|
||||
cv.Required(CONF_PACKETS): [cv.All(validate_packet)],
|
||||
cv.Optional("delay_ms", default=10): cv.positive_int,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
async def saeco_send_packets_button_to_code(config):
|
||||
parent = await cg.get_variable(config[CONF_SAECO_ID])
|
||||
var = cg.new_Pvariable(config["id"])
|
||||
await cg.register_component(var, config)
|
||||
await button.register_button(var, config)
|
||||
cg.add(var.set_parent(parent))
|
||||
cg.add(var.set_packets(config[CONF_PACKETS]))
|
||||
cg.add(var.set_delay_ms(config.get("delay_ms", 10)))
|
||||
return var
|
||||
|
||||
button.register_button("saeco_series_6000", saeco_send_packets_button_to_code)
|
||||
@@ -0,0 +1,343 @@
|
||||
#include "saeco_series_6000.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace saeco_series_6000 {
|
||||
|
||||
static const char *TAG = "saeco_series_6000";
|
||||
static uint32_t last_activity_time = 0;
|
||||
|
||||
void SaecoSeries6000::loop() {
|
||||
uint8_t byte;
|
||||
|
||||
// Bridge from uart_display (display) to uart_mainboard (mainboard)
|
||||
while (uart_display_->available()) {
|
||||
uart_display_->read_byte(&byte);
|
||||
uart_mainboard_->write_byte(byte); // Mirror byte immediately
|
||||
process_display_byte(byte); // Process the "sniffed" byte
|
||||
}
|
||||
|
||||
// Bridge from uart_mainboard (mainboard) to uart_display (display)
|
||||
while (uart_mainboard_->available()) {
|
||||
uart_mainboard_->read_byte(&byte);
|
||||
uart_display_->write_byte(byte); // Mirror byte immediately
|
||||
process_mainboard_byte(byte); // Process the "sniffed" byte
|
||||
}
|
||||
// Контроль активности UART (выключение через 15 сек)
|
||||
static uint32_t last_check = 0;
|
||||
uint32_t now = millis();
|
||||
if (now - last_check > 1000) { // проверяем каждую секунду
|
||||
last_check = now;
|
||||
if (now - last_activity_time > 15000) {
|
||||
pub_status(2); // публикуем статус "выключено"
|
||||
last_activity_time = now; // чтобы не публиковать повторно
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaecoSeries6000::process_display_byte(uint8_t byte) {
|
||||
// Если получили первый 0xAA — начинаем новый пакет
|
||||
if (byte == 0xAA && display_buffer_pos_ == 0) {
|
||||
display_buffer_[display_buffer_pos_++] = byte;
|
||||
return;
|
||||
}
|
||||
// Если уже начали собирать пакет
|
||||
if (display_buffer_pos_ > 0 && display_buffer_pos_ < DISPLAY_BUFFER_SIZE) {
|
||||
display_buffer_[display_buffer_pos_++] = byte;
|
||||
if (byte == 0x55) {
|
||||
parse_display_packet(display_buffer_, display_buffer_pos_);
|
||||
display_buffer_pos_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaecoSeries6000::process_mainboard_byte(uint8_t byte) {
|
||||
// Если получили первый 0xAA — начинаем новый пакет
|
||||
if (byte == 0xAA && mainboard_buffer_pos_ == 0) {
|
||||
mainboard_buffer_[mainboard_buffer_pos_++] = byte;
|
||||
return;
|
||||
}
|
||||
// Если уже начали собирать пакет
|
||||
if (mainboard_buffer_pos_ > 0 && mainboard_buffer_pos_ < MAINBOARD_BUFFER_SIZE) {
|
||||
mainboard_buffer_[mainboard_buffer_pos_++] = byte;
|
||||
if (byte == 0x55) {
|
||||
parse_mainboard_packet(mainboard_buffer_, mainboard_buffer_pos_);
|
||||
mainboard_buffer_pos_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaecoSeries6000::update_display_counter_from_packet(const uint8_t* buffer, uint16_t size) {
|
||||
if (size > 4 && buffer[3] != 0xFF) {
|
||||
last_display_counter_ = buffer[4];
|
||||
}
|
||||
}
|
||||
|
||||
void SaecoSeries6000::parse_display_packet(const uint8_t* buffer, uint16_t size) {
|
||||
if (debug_) {
|
||||
std::vector<char> hex_buffer;
|
||||
hex_buffer.resize(size * 3 + 1);
|
||||
for (uint16_t i = 0; i < size; i++) {
|
||||
sprintf(hex_buffer.data() + i * 3, "%02X ", buffer[i]);
|
||||
}
|
||||
if (size > 4 && buffer[3] != 0xFF){
|
||||
ESP_LOGI(TAG, "Packet from Display: %s", hex_buffer.data());
|
||||
}
|
||||
}
|
||||
update_display_counter_from_packet(buffer, size);
|
||||
// Здесь больше не парсим B0-пакеты, только debug
|
||||
}
|
||||
|
||||
// Разбор пакета B0 (системные статусы кофемашины)
|
||||
// buffer[6], buffer[7], buffer[9] содержат коды состояния
|
||||
void SaecoSeries6000::parse_b0_packet(const uint8_t* buffer, uint16_t size) {
|
||||
if (size < 10) return;
|
||||
if (buffer[6] == 0x0E) {
|
||||
if (buffer[9] == 0x00) {
|
||||
pub_status(20); // 20: "Опорож. контейнер для коф. гущи"
|
||||
} else {
|
||||
if ((buffer[9] & 0x40) != 0) {
|
||||
pub_status(22); // 22: "Воды нет"
|
||||
} else {
|
||||
pub_status(17); // 17: "Вода есть"
|
||||
}
|
||||
if ((buffer[9] & 0x80) != 0) {
|
||||
pub_status(23); // 23: "Извлечен контейнер для жмыха"
|
||||
} else {
|
||||
pub_status(18); // 18: "Вставлен контейнер для жмыха"
|
||||
}
|
||||
}
|
||||
} else if (buffer[6] == 0x06) {
|
||||
pub_status(21); // 21: "Готово/Выберите напиток"
|
||||
} else if (buffer[6] == 0x0C) {
|
||||
if (buffer[7] == 0x01) {
|
||||
pub_status(8); // 8: "Наслаждайтесь"
|
||||
} else if (buffer[7] == 0x02) {
|
||||
pub_status(15); // 15: "Что-то (07 0C 02)"
|
||||
}
|
||||
} else if (buffer[6] == 0x07) {
|
||||
if (buffer[7] == 0x0E) {
|
||||
pub_status(9); // 9: "Нагрев воды"
|
||||
} else if (buffer[7] == 0x0D) {
|
||||
pub_status(10); // 10: "Перемалываем зерна"
|
||||
} else if (buffer[7] == 0x10) {
|
||||
pub_status(3); // 3: "Наливаем молоко"
|
||||
} else if (buffer[7] == 0x11) {
|
||||
pub_status(4); // 4: "Наливаем кофе"
|
||||
} else if (buffer[7] == 0x12) {
|
||||
pub_status(5); // 5: "Предварительное дозирование"
|
||||
} else if (buffer[7] == 0x13) {
|
||||
pub_status(6); // 6: "Создание пара для молока"
|
||||
} else if (buffer[7] == 0x14) {
|
||||
pub_status(7); // 7: "Заварочный узел в положение заваривания"
|
||||
} else if (buffer[7] == 0x15) {
|
||||
pub_status(15); // 15: "Наслаждайтесь"
|
||||
}
|
||||
} else if (buffer[6] == 0x08) {
|
||||
if (buffer[7] == 0x0E) {
|
||||
pub_status(14); // 14: "Нагревание"
|
||||
} else if (buffer[7] == 0x02) {
|
||||
pub_status(11); // 11: "Промывка"
|
||||
} else if (buffer[7] == 0x14) {
|
||||
pub_status(13); // 13: "Что-то (07 08 14)"
|
||||
} else if (buffer[7] == 0x05) {
|
||||
pub_status(12); // 12: "Зерна закончились"
|
||||
} else if (buffer[7] == 0x16) {
|
||||
pub_status(24); // 24: "Удаление накипи стадия 1"
|
||||
} else if (buffer[7] == 0x18) {
|
||||
pub_status(25); // 25: "Удаление накипи стадия 2"
|
||||
}
|
||||
} else if (buffer[7] == 0x00) {
|
||||
if (buffer[6] == 0x01) {
|
||||
pub_status(1); // 1: "Что-то (07 01 00)"
|
||||
} else if (buffer[6] == 0x05) {
|
||||
pub_status(2); // 2: "Выключено"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Разбор пакета B5 (коды ошибок кофемашины)
|
||||
// buffer[10], buffer[11] содержат коды ошибок
|
||||
void SaecoSeries6000::parse_b5_packet(const uint8_t* buffer, uint16_t size) {
|
||||
if (size <= 12) return;
|
||||
if (buffer[10] == 0x00) {
|
||||
if (buffer[11] == 0x00) pub_status(30); // 30: "Ошибка 0x00"
|
||||
else if (buffer[11] == 0x0B) pub_status(31); // 31: "Ошибка 0x0B"
|
||||
else if (buffer[11] == 0xE6) pub_status(32); // 32: "Ошибка 0xE6"
|
||||
else if (buffer[11] == 0x80) pub_status(33); // 33: "Ошибка 0x80"
|
||||
else if (buffer[11] == 0xCB) pub_status(34); // 34: "Ошибка 0xCB"
|
||||
else if (buffer[11] == 0xFF) pub_status(35); // 35: "Ошибка 0xFF"
|
||||
else if (buffer[11] == 0xA0) pub_status(36); // 36: "Ошибка 0xA0"
|
||||
} else if (buffer[10] == 0x01) {
|
||||
pub_status(37); // 37: "Статус2 0x01"
|
||||
}
|
||||
}
|
||||
|
||||
void SaecoSeries6000::parse_mainboard_packet(const uint8_t* buffer, uint16_t size) {
|
||||
last_activity_time = millis(); // сбрасываем таймер активности при любом пакете
|
||||
if (debug_) {
|
||||
// std::vector<char> hex_buffer;
|
||||
// hex_buffer.resize(size * 3 + 1);
|
||||
// for (uint16_t i = 0; i < size; i++) {
|
||||
// sprintf(hex_buffer.data() + i * 3, "%02X ", buffer[i]);
|
||||
// }
|
||||
//ESP_LOGD(TAG, "Packet from Mainboard: %s", hex_buffer.data());
|
||||
//ESP_LOGD(TAG, "parse_mainboard_packet: size=%u", size);
|
||||
}
|
||||
// Парсим B0
|
||||
if (size > 4 && buffer[3] == 0xB0) {
|
||||
parse_b0_packet(buffer, size);
|
||||
} else if (size > 12 && buffer[3] == 0xB5) {
|
||||
parse_b5_packet(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
void SaecoSeries6000::pub_status(uint8_t status) {
|
||||
if (status_sensor_ != nullptr) {
|
||||
status_sensor_->publish_state(status);
|
||||
}
|
||||
}
|
||||
|
||||
void SaecoSeries6000::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Saeco Series 6000 UART Bridge");
|
||||
ESP_LOGCONFIG(TAG, " UART Display (uart_display): %p", uart_display_);
|
||||
ESP_LOGCONFIG(TAG, " UART Mainboard (uart_mainboard): %p", uart_mainboard_);
|
||||
ESP_LOGCONFIG(TAG, " Debug mode: %s", ONOFF(this->debug_));
|
||||
}
|
||||
|
||||
void SaecoSeries6000::send_packet_to_mainboard(const std::vector<uint8_t> &data) {
|
||||
ESP_LOGI(TAG, "Send to Mainboard pressed.");
|
||||
for (auto b : data) {
|
||||
uart_mainboard_->write_byte(b);
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t SaecoSeries6000::BitReverse[256] = {
|
||||
0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
|
||||
0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
|
||||
0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
|
||||
0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
|
||||
0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
|
||||
0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
|
||||
0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
|
||||
0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
|
||||
0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
|
||||
0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
|
||||
0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
|
||||
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
|
||||
0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
|
||||
0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
|
||||
0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
|
||||
0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
|
||||
};
|
||||
|
||||
uint32_t SaecoSeries6000::calc_crc(const std::vector<uint8_t>& data, size_t start, size_t end) {
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
const uint32_t POLY = 0x04C11DB7;
|
||||
if (start >= end) return 0;
|
||||
// start
|
||||
uint8_t val = data[start];
|
||||
((uint8_t*)(&crc))[3] ^= BitReverse[val];
|
||||
for (uint8_t j = 0; j < 8; j++) {
|
||||
if (crc & 0x80000000) {
|
||||
crc = (crc << 1) ^ POLY;
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
// остальные байты
|
||||
for (size_t i = start + 1; i < end; i++) {
|
||||
uint8_t v = data[i];
|
||||
((uint8_t*)(&crc))[3] ^= BitReverse[v];
|
||||
for (uint8_t j = 0; j < 8; j++) {
|
||||
if (crc & 0x80000000) {
|
||||
crc = (crc << 1) ^ POLY;
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint32_t t32 = 0;
|
||||
((uint8_t*)(&t32))[0] = BitReverse[((uint8_t*)(&crc))[3]];
|
||||
((uint8_t*)(&t32))[1] = BitReverse[((uint8_t*)(&crc))[2]];
|
||||
((uint8_t*)(&t32))[2] = BitReverse[((uint8_t*)(&crc))[1]];
|
||||
((uint8_t*)(&t32))[3] = BitReverse[((uint8_t*)(&crc))[0]];
|
||||
crc = t32 ^ 0xFFFFFFFF;
|
||||
return crc;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> SaecoSeries6000::parse_hex_string_to_bytes(const std::string& hex_string) {
|
||||
std::vector<uint8_t> pkt;
|
||||
size_t pos = 0;
|
||||
while (pos < hex_string.size()) {
|
||||
while (pos < hex_string.size() && isspace(hex_string[pos])) ++pos;
|
||||
if (pos >= hex_string.size()) break;
|
||||
char* endptr = nullptr;
|
||||
uint8_t byte = static_cast<uint8_t>(std::strtoul(hex_string.c_str() + pos, &endptr, 16));
|
||||
pkt.push_back(byte);
|
||||
if (endptr == nullptr || endptr == hex_string.c_str() + pos) break;
|
||||
pos = endptr - hex_string.c_str();
|
||||
}
|
||||
return pkt;
|
||||
}
|
||||
|
||||
void SaecoSeries6000::send_packets_to_mainboard(const std::string& hex_packet, uint32_t delay_ms) {
|
||||
std::vector<std::vector<uint8_t>> pkts = {parse_hex_string_to_bytes(hex_packet)};
|
||||
send_packets_to_mainboard(pkts, delay_ms);
|
||||
}
|
||||
|
||||
void SaecoSeries6000::send_packets_to_mainboard(const std::vector<std::string>& hex_packets, uint32_t delay_ms) {
|
||||
std::vector<std::vector<uint8_t>> pkts;
|
||||
for (const auto& s : hex_packets) {
|
||||
pkts.push_back(parse_hex_string_to_bytes(s));
|
||||
}
|
||||
send_packets_to_mainboard(pkts, delay_ms);
|
||||
}
|
||||
|
||||
void SaecoSeries6000::send_packets_to_mainboard(const std::vector<std::vector<uint8_t>> &packets, uint32_t delay_ms) {
|
||||
uint8_t counter = (last_display_counter_ + 1) & 0xFF;
|
||||
for (size_t i = 0; i < packets.size(); ++i) {
|
||||
std::vector<uint8_t> pkt = packets[i];
|
||||
// Заменяем байт счетчика (4-й байт)
|
||||
if (pkt.size() > 4) {
|
||||
pkt[4] = counter;
|
||||
}
|
||||
// Пересчёт CRC: ищем преамбулу 0xAA 0xAA 0xAA, считаем CRC по данным между преамбулой и последними 5 байтами
|
||||
if (pkt.size() > 8) {
|
||||
size_t preamble = 0;
|
||||
if (pkt[0] == 0xAA && pkt[1] == 0xAA && pkt[2] == 0xAA) {
|
||||
preamble = 3;
|
||||
}
|
||||
size_t crc_start = preamble;
|
||||
size_t crc_end = pkt.size() - 5; // не включаем 4 CRC и 0x55
|
||||
uint32_t crc = calc_crc(pkt, crc_start, crc_end);
|
||||
// Заменяем последние 4 байта перед 0x55 на новую CRC
|
||||
pkt[pkt.size()-2] = (crc >> 24) & 0xFF;
|
||||
pkt[pkt.size()-3] = (crc >> 16) & 0xFF;
|
||||
pkt[pkt.size()-4] = (crc >> 8) & 0xFF;
|
||||
pkt[pkt.size()-5] = crc & 0xFF;
|
||||
// pkt[pkt.size()-5] = (crc >> 24) & 0xFF;
|
||||
// pkt[pkt.size()-4] = (crc >> 16) & 0xFF;
|
||||
// pkt[pkt.size()-3] = (crc >> 8) & 0xFF;
|
||||
// pkt[pkt.size()-2] = (crc) & 0xFF;
|
||||
}
|
||||
// Логируем пакет перед отправкой
|
||||
std::string log_str;
|
||||
char buf[8];
|
||||
for (auto b : pkt) {
|
||||
snprintf(buf, sizeof(buf), "%02X ", b);
|
||||
log_str += buf;
|
||||
}
|
||||
ESP_LOGI(TAG, "Send to Mainboard: %s", log_str.c_str());
|
||||
send_packet_to_mainboard(pkt);
|
||||
counter = (counter + 1) & 0xFF;
|
||||
delay(delay_ms);
|
||||
}
|
||||
last_display_counter_ = (counter - 1) & 0xFF;
|
||||
}
|
||||
|
||||
// Реализация SendPacketsAction полностью в header (saeco_series_6000.h)
|
||||
|
||||
} // namespace saeco_series_6000
|
||||
} // namespace esphome
|
||||
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/components/button/button.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace saeco_series_6000 {
|
||||
|
||||
// Buffer sizes for packet sniffing
|
||||
constexpr size_t DISPLAY_BUFFER_SIZE = 128;
|
||||
constexpr size_t MAINBOARD_BUFFER_SIZE = 128;
|
||||
|
||||
class SaecoSeries6000 : public Component {
|
||||
public:
|
||||
void set_uart_display(uart::UARTComponent *uart_display) { uart_display_ = uart_display; }
|
||||
void set_uart_mainboard(uart::UARTComponent *uart_mainboard) { uart_mainboard_ = uart_mainboard; }
|
||||
void set_debug(bool debug) { debug_ = debug; }
|
||||
void set_status_sensor(sensor::Sensor *sensor) { status_sensor_ = sensor; }
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
void send_packet_to_mainboard(const std::vector<uint8_t> &data);
|
||||
void send_packets_to_mainboard(const std::vector<std::vector<uint8_t>> &packets, uint32_t delay_ms = 10);
|
||||
void send_packets_to_mainboard(const std::vector<std::string>& hex_packets, uint32_t delay_ms = 10);
|
||||
void send_packets_to_mainboard(const std::string& hex_packet, uint32_t delay_ms = 10);
|
||||
|
||||
protected:
|
||||
uart::UARTComponent *uart_display_;
|
||||
uart::UARTComponent *uart_mainboard_;
|
||||
bool debug_{false};
|
||||
sensor::Sensor *status_sensor_{nullptr};
|
||||
|
||||
private:
|
||||
uint8_t display_buffer_[DISPLAY_BUFFER_SIZE];
|
||||
uint16_t display_buffer_pos_{0};
|
||||
|
||||
uint8_t mainboard_buffer_[MAINBOARD_BUFFER_SIZE];
|
||||
uint16_t mainboard_buffer_pos_{0};
|
||||
|
||||
uint8_t display_last_bytes_[3] = {0, 0, 0};
|
||||
uint8_t mainboard_last_bytes_[3] = {0, 0, 0};
|
||||
|
||||
uint8_t display_sync_count_{0};
|
||||
uint8_t mainboard_sync_count_{0};
|
||||
|
||||
uint8_t last_display_counter_{0};
|
||||
void update_display_counter_from_packet(const uint8_t* buffer, uint16_t size);
|
||||
|
||||
void process_display_byte(uint8_t byte);
|
||||
void process_mainboard_byte(uint8_t byte);
|
||||
|
||||
void parse_display_packet(const uint8_t* buffer, uint16_t size);
|
||||
void parse_mainboard_packet(const uint8_t* buffer, uint16_t size);
|
||||
void parse_b0_packet(const uint8_t* buffer, uint16_t size);
|
||||
void parse_b5_packet(const uint8_t* buffer, uint16_t size);
|
||||
void pub_status(uint8_t status);
|
||||
static const uint8_t BitReverse[256];
|
||||
uint32_t calc_crc(const std::vector<uint8_t>& data, size_t start, size_t end);
|
||||
std::vector<uint8_t> parse_hex_string_to_bytes(const std::string& hex_string);
|
||||
};
|
||||
|
||||
class SaecoSendPacketsButton : public esphome::button::Button, public esphome::Component {
|
||||
public:
|
||||
void set_parent(SaecoSeries6000 *parent) { parent_ = parent; }
|
||||
void set_packets(const std::vector<std::vector<uint8_t>> &packets) { packets_ = packets; }
|
||||
void set_delay_ms(uint32_t delay_ms) { delay_ms_ = delay_ms; }
|
||||
void press_action() override {
|
||||
if (parent_ != nullptr) {
|
||||
parent_->send_packets_to_mainboard(packets_, delay_ms_);
|
||||
}
|
||||
}
|
||||
private:
|
||||
SaecoSeries6000 *parent_{nullptr};
|
||||
std::vector<std::vector<uint8_t>> packets_;
|
||||
uint32_t delay_ms_{10};
|
||||
};
|
||||
|
||||
} // namespace saeco_series_6000
|
||||
} // namespace esphome
|
||||
@@ -0,0 +1,58 @@
|
||||
# --------------------------------------------------------------------------
|
||||
# Substitutions
|
||||
#
|
||||
# These are substitutions as used by the configuration packages from below.
|
||||
# You can uncomment and update the ones that you want to modify.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
substitutions:
|
||||
name: danil-bedside-lamp
|
||||
friendly_name: Danil Bedside Lamp
|
||||
#light_name: ${friendly_name} RGBWW Light
|
||||
#light_mode_text_sensor_name: ${friendly_name} Light Mode
|
||||
default_transition_length: 800ms
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Load configuration packages
|
||||
#
|
||||
# These provide a convenient way to compose your device configuration from
|
||||
# some functional building blocks. Pick and mix the blocks that you need.
|
||||
#
|
||||
# For customization you can override options in your config or you can
|
||||
# copy the contents of these packages directly in your config file as
|
||||
# an example for your own customizations.
|
||||
#
|
||||
# Available packages are:
|
||||
# - core.yaml : core components & hardware setup
|
||||
# - behavior_default.yaml : default device behavior
|
||||
# - ota_feedback.yaml : enable visual feedback during OTA updates
|
||||
# - activate_preset_svc.yaml : 'activate_preset' service for Home Assistant
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
packages:
|
||||
bslamp2:
|
||||
url: https://github.com/mmakaay/esphome-xiaomi_bslamp2
|
||||
ref: dev
|
||||
files:
|
||||
- packages/core.yaml
|
||||
- packages/behavior_default.yaml
|
||||
- packages/ota_feedback.yaml
|
||||
- packages/activate_preset_svc.yaml
|
||||
refresh: 0s
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Use your own preferences for these components.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
use_address: ${name}.lan
|
||||
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
password: !secret esphome_pass
|
||||
@@ -0,0 +1,387 @@
|
||||
substitutions:
|
||||
name: jk-bms
|
||||
device_description: "Monitor and control a JK-BMS v11 via bluetooth"
|
||||
external_components_source: github://syssi/esphome-jk-bms@main
|
||||
mac_address: C8:47:80:39:31:5D
|
||||
# Please use "JK02_24S" if you own a old JK-BMS < hardware version 11.0 (hardware version >= 6.0 and < 11.0)
|
||||
# Please use "JK02_32S" if you own a new JK-BMS >= hardware version 11.0 (f.e. JK-B2A8S20P hw 11.XW, sw 11.26)
|
||||
# Please use "JK04" if you have some old JK-BMS <= hardware version 3.0 (f.e. JK-B2A16S hw 3.0, sw. 3.3.0)
|
||||
protocol_version: JK02_32S
|
||||
device_host: jk-bms.lan
|
||||
|
||||
esphome:
|
||||
name: ${name}
|
||||
comment: ${device_description}
|
||||
min_version: 2024.6.0
|
||||
project:
|
||||
name: "syssi.esphome-jk-bms"
|
||||
version: 2.3.0
|
||||
|
||||
esp32:
|
||||
variant: esp32c3
|
||||
board: esp32-c3-devkitm-1
|
||||
framework:
|
||||
type: esp-idf
|
||||
|
||||
external_components:
|
||||
- source: ${external_components_source}
|
||||
refresh: 0s
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
use_address: ${device_host}
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
logs:
|
||||
esp32_ble_tracker: INFO
|
||||
esp32_ble_client: INFO
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: superLongP4ss
|
||||
|
||||
# If you don't use Home Assistant please remove this `api` section and uncomment the `mqtt` component!
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret api_encryption_key
|
||||
on_begin:
|
||||
then:
|
||||
- switch.turn_off: ble_client_switch0
|
||||
- logger.log: "BLE connection suspended for OTA update"
|
||||
|
||||
# mqtt:
|
||||
# broker: !secret mqtt_host
|
||||
# username: !secret mqtt_username
|
||||
# password: !secret mqtt_password
|
||||
# id: mqtt_client
|
||||
|
||||
esp32_ble_tracker:
|
||||
scan_parameters:
|
||||
active: false
|
||||
|
||||
ble_client:
|
||||
- mac_address: ${mac_address}
|
||||
id: client0
|
||||
|
||||
jk_bms_ble:
|
||||
- ble_client_id: client0
|
||||
protocol_version: ${protocol_version}
|
||||
throttle: 5s
|
||||
id: bms0
|
||||
|
||||
binary_sensor:
|
||||
- platform: jk_bms_ble
|
||||
balancing:
|
||||
name: "${name} balancing"
|
||||
charging:
|
||||
name: "${name} charging"
|
||||
discharging:
|
||||
name: "${name} discharging"
|
||||
heating:
|
||||
name: "${name} heating"
|
||||
online_status:
|
||||
name: "${name} online status"
|
||||
dry_contact_1:
|
||||
name: "${name} dry contact 1"
|
||||
dry_contact_2:
|
||||
name: "${name} dry contact 2"
|
||||
|
||||
button:
|
||||
- platform: jk_bms_ble
|
||||
retrieve_settings:
|
||||
name: "${name} retrieve settings"
|
||||
retrieve_device_info:
|
||||
name: "${name} retrieve device info"
|
||||
|
||||
number:
|
||||
- platform: jk_bms_ble
|
||||
jk_bms_ble_id: bms0
|
||||
balance_trigger_voltage:
|
||||
name: "${name} balance trigger voltage"
|
||||
cell_count:
|
||||
name: "${name} cell count"
|
||||
total_battery_capacity:
|
||||
name: "${name} total battery capacity"
|
||||
cell_voltage_overvoltage_protection:
|
||||
name: "${name} cell voltage overvoltage protection"
|
||||
cell_voltage_overvoltage_recovery:
|
||||
name: "${name} cell voltage overvoltage recovery"
|
||||
cell_voltage_undervoltage_protection:
|
||||
name: "${name} cell voltage undervoltage protection"
|
||||
cell_voltage_undervoltage_recovery:
|
||||
name: "${name} cell voltage undervoltage recovery"
|
||||
balance_starting_voltage:
|
||||
name: "${name} balance starting voltage"
|
||||
voltage_calibration:
|
||||
name: "${name} voltage calibration"
|
||||
current_calibration:
|
||||
name: "${name} current calibration"
|
||||
power_off_voltage:
|
||||
name: "${name} power off voltage"
|
||||
max_balance_current:
|
||||
name: "${name} max balance current"
|
||||
max_charge_current:
|
||||
name: "${name} max charge current"
|
||||
max_discharge_current:
|
||||
name: "${name} max discharge current"
|
||||
smart_sleep_voltage:
|
||||
name: "${name} smart sleep voltage"
|
||||
cell_soc100_voltage:
|
||||
name: "${name} cell soc100 voltage"
|
||||
cell_soc0_voltage:
|
||||
name: "${name} cell soc0 voltage"
|
||||
cell_request_charge_voltage:
|
||||
name: "${name} cell request charge voltage"
|
||||
cell_request_float_voltage:
|
||||
name: "${name} cell request float voltage"
|
||||
cell_request_charge_voltage_time:
|
||||
name: "${name} cell request charge voltage time"
|
||||
cell_request_float_voltage_time:
|
||||
name: "${name} cell request float voltage time"
|
||||
charge_overcurrent_protection_delay:
|
||||
name: "${name} charge overcurrent protection delay"
|
||||
charge_overcurrent_protection_recovery_time:
|
||||
name: "${name} charge overcurrent protection recovery time"
|
||||
discharge_overcurrent_protection_delay:
|
||||
name: "${name} discharge overcurrent protection delay"
|
||||
discharge_overcurrent_protection_recovery_time:
|
||||
name: "${name} discharge overcurrent protection recovery time"
|
||||
short_circuit_protection_delay:
|
||||
name: "${name} short circuit protection delay"
|
||||
short_circuit_protection_recovery_time:
|
||||
name: "${name} short circuit protection recovery time"
|
||||
charge_overtemperature_protection:
|
||||
name: "${name} charge overtemperature protection"
|
||||
charge_overtemperature_protection_recovery:
|
||||
name: "${name} charge overtemperature protection recovery"
|
||||
discharge_overtemperature_protection:
|
||||
name: "${name} discharge overtemperature protection"
|
||||
discharge_overtemperature_protection_recovery:
|
||||
name: "${name} discharge overtemperature protection recovery"
|
||||
charge_undertemperature_protection:
|
||||
name: "${name} charge undertemperature protection"
|
||||
charge_undertemperature_protection_recovery:
|
||||
name: "${name} charge undertemperature protection recovery"
|
||||
power_tube_overtemperature_protection:
|
||||
name: "${name} power tube overtemperature protection"
|
||||
power_tube_overtemperature_protection_recovery:
|
||||
name: "${name} power tube overtemperature protection recovery"
|
||||
discharge_precharge_time:
|
||||
name: "${name} discharge precharge time"
|
||||
heating_start_temperature:
|
||||
name: "${name} heating start temperature"
|
||||
heating_stop_temperature:
|
||||
name: "${name} heating stop temperature"
|
||||
|
||||
sensor:
|
||||
- platform: jk_bms_ble
|
||||
jk_bms_ble_id: bms0
|
||||
min_cell_voltage:
|
||||
name: "${name} min cell voltage"
|
||||
max_cell_voltage:
|
||||
name: "${name} max cell voltage"
|
||||
min_voltage_cell:
|
||||
name: "${name} min voltage cell"
|
||||
max_voltage_cell:
|
||||
name: "${name} max voltage cell"
|
||||
delta_cell_voltage:
|
||||
name: "${name} delta cell voltage"
|
||||
average_cell_voltage:
|
||||
name: "${name} average cell voltage"
|
||||
cell_voltage_1:
|
||||
name: "${name} cell voltage 1"
|
||||
cell_voltage_2:
|
||||
name: "${name} cell voltage 2"
|
||||
cell_voltage_3:
|
||||
name: "${name} cell voltage 3"
|
||||
cell_voltage_4:
|
||||
name: "${name} cell voltage 4"
|
||||
cell_voltage_5:
|
||||
name: "${name} cell voltage 5"
|
||||
cell_voltage_6:
|
||||
name: "${name} cell voltage 6"
|
||||
cell_voltage_7:
|
||||
name: "${name} cell voltage 7"
|
||||
cell_voltage_8:
|
||||
name: "${name} cell voltage 8"
|
||||
cell_voltage_9:
|
||||
name: "${name} cell voltage 9"
|
||||
cell_voltage_10:
|
||||
name: "${name} cell voltage 10"
|
||||
cell_voltage_11:
|
||||
name: "${name} cell voltage 11"
|
||||
cell_voltage_12:
|
||||
name: "${name} cell voltage 12"
|
||||
cell_voltage_13:
|
||||
name: "${name} cell voltage 13"
|
||||
cell_voltage_14:
|
||||
name: "${name} cell voltage 14"
|
||||
cell_voltage_15:
|
||||
name: "${name} cell voltage 15"
|
||||
cell_voltage_16:
|
||||
name: "${name} cell voltage 16"
|
||||
cell_voltage_17:
|
||||
name: "${name} cell voltage 17"
|
||||
cell_voltage_18:
|
||||
name: "${name} cell voltage 18"
|
||||
cell_voltage_19:
|
||||
name: "${name} cell voltage 19"
|
||||
cell_voltage_20:
|
||||
name: "${name} cell voltage 20"
|
||||
cell_voltage_21:
|
||||
name: "${name} cell voltage 21"
|
||||
cell_voltage_22:
|
||||
name: "${name} cell voltage 22"
|
||||
cell_voltage_23:
|
||||
name: "${name} cell voltage 23"
|
||||
cell_voltage_24:
|
||||
name: "${name} cell voltage 24"
|
||||
cell_resistance_1:
|
||||
name: "${name} cell resistance 1"
|
||||
cell_resistance_2:
|
||||
name: "${name} cell resistance 2"
|
||||
cell_resistance_3:
|
||||
name: "${name} cell resistance 3"
|
||||
cell_resistance_4:
|
||||
name: "${name} cell resistance 4"
|
||||
cell_resistance_5:
|
||||
name: "${name} cell resistance 5"
|
||||
cell_resistance_6:
|
||||
name: "${name} cell resistance 6"
|
||||
cell_resistance_7:
|
||||
name: "${name} cell resistance 7"
|
||||
cell_resistance_8:
|
||||
name: "${name} cell resistance 8"
|
||||
cell_resistance_9:
|
||||
name: "${name} cell resistance 9"
|
||||
cell_resistance_10:
|
||||
name: "${name} cell resistance 10"
|
||||
cell_resistance_11:
|
||||
name: "${name} cell resistance 11"
|
||||
cell_resistance_12:
|
||||
name: "${name} cell resistance 12"
|
||||
cell_resistance_13:
|
||||
name: "${name} cell resistance 13"
|
||||
cell_resistance_14:
|
||||
name: "${name} cell resistance 14"
|
||||
cell_resistance_15:
|
||||
name: "${name} cell resistance 15"
|
||||
cell_resistance_16:
|
||||
name: "${name} cell resistance 16"
|
||||
cell_resistance_17:
|
||||
name: "${name} cell resistance 17"
|
||||
cell_resistance_18:
|
||||
name: "${name} cell resistance 18"
|
||||
cell_resistance_19:
|
||||
name: "${name} cell resistance 19"
|
||||
cell_resistance_20:
|
||||
name: "${name} cell resistance 20"
|
||||
cell_resistance_21:
|
||||
name: "${name} cell resistance 21"
|
||||
cell_resistance_22:
|
||||
name: "${name} cell resistance 22"
|
||||
cell_resistance_23:
|
||||
name: "${name} cell resistance 23"
|
||||
cell_resistance_24:
|
||||
name: "${name} cell resistance 24"
|
||||
total_voltage:
|
||||
name: "${name} total voltage"
|
||||
current:
|
||||
name: "${name} current"
|
||||
heating_current:
|
||||
name: "${name} heating current"
|
||||
power:
|
||||
name: "${name} power"
|
||||
charging_power:
|
||||
name: "${name} charging power"
|
||||
discharging_power:
|
||||
name: "${name} discharging power"
|
||||
temperature_sensor_1:
|
||||
name: "${name} temperature sensor 1"
|
||||
temperature_sensor_2:
|
||||
name: "${name} temperature sensor 2"
|
||||
temperature_sensor_3:
|
||||
name: "${name} temperature sensor 3"
|
||||
temperature_sensor_4:
|
||||
name: "${name} temperature sensor 4"
|
||||
temperature_sensor_5:
|
||||
name: "${name} temperature sensor 5"
|
||||
power_tube_temperature:
|
||||
name: "${name} power tube temperature"
|
||||
balancing:
|
||||
name: "${name} balancing"
|
||||
state_of_charge:
|
||||
name: "${name} state of charge"
|
||||
state_of_health:
|
||||
name: "${name} state of health"
|
||||
capacity_remaining:
|
||||
name: "${name} capacity remaining"
|
||||
total_battery_capacity_setting:
|
||||
name: "${name} total battery capacity setting"
|
||||
charging_cycles:
|
||||
name: "${name} charging cycles"
|
||||
total_charging_cycle_capacity:
|
||||
name: "${name} total charging cycle capacity"
|
||||
total_runtime:
|
||||
name: "${name} total runtime"
|
||||
balancing_current:
|
||||
name: "${name} balancing current"
|
||||
errors_bitmask:
|
||||
name: "${name} errors bitmask"
|
||||
emergency_time_countdown:
|
||||
name: "${name} emergency time countdown"
|
||||
charge_status_id:
|
||||
name: "${name} charge status id"
|
||||
charge_status_time_elapsed:
|
||||
name: "${name} charge status time elapsed"
|
||||
|
||||
switch:
|
||||
- platform: jk_bms_ble
|
||||
charging:
|
||||
name: "${name} charging"
|
||||
discharging:
|
||||
name: "${name} discharging"
|
||||
balancer:
|
||||
name: "${name} balancer"
|
||||
emergency:
|
||||
name: "${name} emergency"
|
||||
heating:
|
||||
name: "${name} heating"
|
||||
disable_temperature_sensors:
|
||||
name: "${name} disable temperature sensors"
|
||||
display_always_on:
|
||||
name: "${name} display always on"
|
||||
smart_sleep:
|
||||
name: "${name} smart sleep"
|
||||
disable_pcl_module:
|
||||
name: "${name} disable pcl module"
|
||||
timed_stored_data:
|
||||
name: "${name} timed stored data"
|
||||
charging_float_mode:
|
||||
name: "${name} charging float mode"
|
||||
|
||||
- platform: ble_client
|
||||
ble_client_id: client0
|
||||
name: "${name} enable bluetooth connection"
|
||||
id: ble_client_switch0
|
||||
|
||||
text_sensor:
|
||||
- platform: jk_bms_ble
|
||||
errors:
|
||||
name: "${name} errors"
|
||||
total_runtime_formatted:
|
||||
name: "${name} total runtime formatted"
|
||||
charge_status:
|
||||
name: "${name} charge status"
|
||||
software_version:
|
||||
name: "${name} software version"
|
||||
hardware_version:
|
||||
name: "${name} hardware version"
|
||||
@@ -0,0 +1,85 @@
|
||||
#===============================================================================
|
||||
# Контроллер кондиционера в гостиной
|
||||
# Wemos D1 mini
|
||||
#===============================================================================
|
||||
substitutions:
|
||||
node_name: ac_childroom # Use a unique name.
|
||||
node_id: ac_childroom # Use a unique id.
|
||||
deviceid: ac_childroom
|
||||
devicename: ac_childroom
|
||||
friendly_node_name: "Кондиционер Детская Старый"
|
||||
|
||||
#===============================================================================
|
||||
# Общий конфиг
|
||||
#===============================================================================
|
||||
esphome:
|
||||
name: ${node_name}
|
||||
friendly_name: ${friendly_node_name}
|
||||
|
||||
esp8266:
|
||||
board: esp12e
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: admin
|
||||
password: superLongP4ss
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret api_encryption_key
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "${devicename} Fallback Hotspot"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
baud_rate: 0 # disable LOG output on UART as UART is used for Sinclair AC unit
|
||||
# level: VERBOSE
|
||||
|
||||
uart:
|
||||
tx_pin: 1
|
||||
rx_pin: 3
|
||||
baud_rate: 4800
|
||||
parity: EVEN
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
|
||||
external_components:
|
||||
- source: github://gekkehenkie11/esphome_gree_ac
|
||||
components: [sinclair_ac]
|
||||
refresh: 0s
|
||||
|
||||
climate:
|
||||
- platform: sinclair_ac
|
||||
name: ${devicename}
|
||||
horizontal_swing_select:
|
||||
name: ${devicename} Horizontal Swing Mode
|
||||
vertical_swing_select:
|
||||
name: ${devicename} Vertical Swing Mode
|
||||
display_select:
|
||||
name: ${devicename} Display Mode
|
||||
display_unit_select:
|
||||
name: ${devicename} Display Unit
|
||||
plasma_switch:
|
||||
name: ${devicename} Plasma
|
||||
sleep_switch:
|
||||
name: ${devicename} Sleep
|
||||
xfan_switch:
|
||||
name: ${devicename} X-fan
|
||||
save_switch:
|
||||
name: ${devicename} Save/8 Heat
|
||||
@@ -0,0 +1,69 @@
|
||||
esphome:
|
||||
name: ac_childroom
|
||||
|
||||
esp8266:
|
||||
board: d1_mini
|
||||
|
||||
# Disable logging over UART (required)
|
||||
logger:
|
||||
baud_rate: 0
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret api_encryption_key
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "Childroom AC Fallback"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
# UART settings for Midea dongle (required)
|
||||
uart:
|
||||
tx_pin: GPIO1 # hardware dependant
|
||||
rx_pin: GPIO3 # hardware dependant
|
||||
baud_rate: 9600
|
||||
debug:
|
||||
|
||||
# Main settings
|
||||
climate:
|
||||
- platform: midea
|
||||
name: childroom_ac # Use a unique name.
|
||||
# transmitter_id: # Optional. Add this option to use IR transmitter.
|
||||
period: 1s # Optional
|
||||
timeout: 2s # Optional
|
||||
num_attempts: 3 # Optional
|
||||
autoconf: true # Autoconfigure most options.
|
||||
beeper: true # Beep on commands.
|
||||
visual: # Optional. Example of visual settings override.
|
||||
min_temperature: 17 °C # min: 17
|
||||
max_temperature: 30 °C # max: 30
|
||||
temperature_step: 1 °C # min: 0.5
|
||||
supported_modes: # All capabilities in this section detected by autoconf.
|
||||
- FAN_ONLY # This capability is always used.
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
custom_fan_modes:
|
||||
- SILENT
|
||||
- TURBO
|
||||
supported_presets: # All capabilities in this section detected by autoconf.
|
||||
- ECO
|
||||
- BOOST
|
||||
- SLEEP # This capability is always used.
|
||||
custom_presets: # All capabilities in this section detected by autoconf.
|
||||
- FREEZE_PROTECTION
|
||||
supported_swing_modes:
|
||||
- VERTICAL # This capability is always used.
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
@@ -0,0 +1,66 @@
|
||||
esphome:
|
||||
name: mainroom_ac
|
||||
|
||||
esp8266:
|
||||
board: esp12e
|
||||
|
||||
# Disable logging over UART (required)
|
||||
logger:
|
||||
baud_rate: 0
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
ota:
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "Mainroom AC Fallback"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
# UART settings for Midea dongle (required)
|
||||
uart:
|
||||
tx_pin: GPIO1 # hardware dependant
|
||||
rx_pin: GPIO3 # hardware dependant
|
||||
baud_rate: 9600
|
||||
|
||||
# Main settings
|
||||
climate:
|
||||
- platform: midea
|
||||
name: mainroom_ac # Use a unique name.
|
||||
# transmitter_id: # Optional. Add this option to use IR transmitter.
|
||||
period: 1s # Optional
|
||||
timeout: 2s # Optional
|
||||
num_attempts: 3 # Optional
|
||||
autoconf: true # Autoconfigure most options.
|
||||
beeper: true # Beep on commands.
|
||||
visual: # Optional. Example of visual settings override.
|
||||
min_temperature: 17 °C # min: 17
|
||||
max_temperature: 30 °C # max: 30
|
||||
temperature_step: 1 °C # min: 0.5
|
||||
supported_modes: # All capabilities in this section detected by autoconf.
|
||||
- FAN_ONLY # This capability is always used.
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
custom_fan_modes:
|
||||
- SILENT
|
||||
- TURBO
|
||||
supported_presets: # All capabilities in this section detected by autoconf.
|
||||
- ECO
|
||||
- BOOST
|
||||
- SLEEP # This capability is always used.
|
||||
custom_presets: # All capabilities in this section detected by autoconf.
|
||||
- FREEZE_PROTECTION
|
||||
supported_swing_modes:
|
||||
- VERTICAL # This capability is always used.
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
@@ -0,0 +1,336 @@
|
||||
#include "esphome.h"
|
||||
|
||||
#define BLE_PIN D1
|
||||
|
||||
class HappyBubblesDevice : public Component, public CustomMQTTDevice {
|
||||
protected:
|
||||
// char hostname[20] = "hall";
|
||||
const char* hostname = "hall";
|
||||
String buf = "";
|
||||
int txPower = -59;
|
||||
char ble_mac_addr[13];
|
||||
char ble_rssi [5];
|
||||
char ble_is_scan_resp [2];
|
||||
char ble_type [2];
|
||||
char ble_data[100];
|
||||
|
||||
char tx_power [3];
|
||||
char beacon_uuid [33];
|
||||
char beacon_major [5];
|
||||
char beacon_minor [5];
|
||||
char instance_id [13];
|
||||
char json_ble_send[500];
|
||||
char topic [130];
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
uint8_t size;
|
||||
} ble_tok_t;
|
||||
|
||||
public:
|
||||
HappyBubblesDevice(const char* host_param) {
|
||||
hostname = host_param;
|
||||
}
|
||||
void setup() override
|
||||
{
|
||||
Serial.begin(115200);
|
||||
}
|
||||
void loop() override
|
||||
{
|
||||
while (Serial.available() > 0) {
|
||||
char inChar = Serial.read();
|
||||
|
||||
if (inChar == '\n') {
|
||||
//если буфер наполнен
|
||||
// parseData();
|
||||
char charBuf[120];
|
||||
buf.toCharArray(charBuf, 120);
|
||||
process_serial(charBuf);
|
||||
buf = "";
|
||||
}
|
||||
else if (inChar != '\r') {
|
||||
buf += inChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String getValue(String data, char separator, int index)
|
||||
{
|
||||
int found = 0;
|
||||
int strIndex[] = { 0, -1 };
|
||||
int maxIndex = data.length() - 1;
|
||||
|
||||
for (int i = 0; i <= maxIndex && found <= index; i++) {
|
||||
if (data.charAt(i) == separator || i == maxIndex) {
|
||||
found++;
|
||||
strIndex[0] = strIndex[1] + 1;
|
||||
strIndex[1] = (i == maxIndex) ? i + 1 : i;
|
||||
}
|
||||
}
|
||||
|
||||
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
|
||||
}
|
||||
|
||||
float calcDistance(int rssi, int txPower)
|
||||
{
|
||||
if (rssi == 0) {
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
float ratio = rssi * 1.0 / txPower;
|
||||
if (ratio < 1.0) {
|
||||
return pow(ratio, 10);
|
||||
}
|
||||
else {
|
||||
return (0.89976) * pow(ratio, 7.7095) + 0.111;
|
||||
}
|
||||
}
|
||||
|
||||
String floatToString(float x, byte precision = 2)
|
||||
{
|
||||
char tmp[50];
|
||||
dtostrf(x, 0, precision, tmp);
|
||||
return String(tmp);
|
||||
}
|
||||
|
||||
void process_serial(char *buf)
|
||||
{
|
||||
os_printf("********* got serial to process %d ** %s \n\r", strlen(buf), buf);
|
||||
char * pch;
|
||||
pch = strtok(buf, "|");
|
||||
int i = 0;
|
||||
|
||||
memset(ble_mac_addr, 0, 12);
|
||||
memset(ble_rssi, 0, 5);
|
||||
memset(ble_is_scan_resp, 0, 1);
|
||||
memset(ble_type, 0, 1);
|
||||
memset(ble_data, 0, 100);
|
||||
|
||||
while(pch != NULL)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
strcpy(ble_mac_addr, pch);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
strcpy(ble_rssi, pch);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
strcpy(ble_is_scan_resp, pch);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
strcpy(ble_type, pch);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
strcpy(ble_data, pch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
//os_printf("token: %s\n", pch);
|
||||
pch = strtok(NULL, "|");
|
||||
}
|
||||
|
||||
//basic filters
|
||||
//check mac is 12 chars
|
||||
int should_send = 0;
|
||||
if(strlen(ble_mac_addr) != 12)
|
||||
{
|
||||
os_printf("bad mac, not 12, %d, %s\n", strlen(ble_mac_addr), ble_mac_addr);
|
||||
should_send = 1;
|
||||
}
|
||||
//check mac is all hex
|
||||
if (!ble_mac_addr[strspn(ble_mac_addr, "0123456789abcdefABCDEF")] == 0)
|
||||
{
|
||||
os_printf("bad mac, not all hex %s\n", ble_mac_addr);
|
||||
should_send = 2;
|
||||
}
|
||||
//check data is all hex
|
||||
if (strlen(ble_data) < 8 || !ble_data[strspn(ble_data, "0123456789abcdefABCDEF")] == 0 )
|
||||
{
|
||||
os_printf("bad data %s\n", ble_data);
|
||||
should_send = 3;
|
||||
}
|
||||
//check rssi is all numbers
|
||||
if (strlen(ble_rssi) < 1 || !ble_rssi[strspn(ble_rssi, "-0123456789")] == 0)
|
||||
{
|
||||
os_printf("bad rssi %s\n", ble_rssi);
|
||||
should_send = 4;
|
||||
}
|
||||
//check scan_response is 0 or 1
|
||||
if (strlen(ble_is_scan_resp) < 1 || !ble_is_scan_resp[strspn(ble_is_scan_resp, "01")] == 0)
|
||||
{
|
||||
os_printf("bad scanresp %s\n", ble_is_scan_resp);
|
||||
should_send = 5;
|
||||
}
|
||||
//check ble_type is hex
|
||||
if (strlen(ble_type) < 1 || !ble_type[strspn(ble_type, "0123456789abcdefABCDEF")] == 0)
|
||||
{
|
||||
os_printf("bad type %s\n", ble_type);
|
||||
should_send = 6;
|
||||
}
|
||||
if(should_send == 0)
|
||||
{
|
||||
//os_printf("^^^^^^^^^GOT THROUGH FILTERS!\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//os_printf("xxxxxxxxxxFAIL FILTERS! %d \r\n", should_send);
|
||||
//os_printf("=====%s || %s || %s || %s || %s ===DONE\n", ble_mac_addr, ble_rssi, ble_is_scan_resp, ble_type, ble_data);
|
||||
return;
|
||||
}
|
||||
|
||||
//what type of beacon is this?
|
||||
int beacon_type = 99;
|
||||
|
||||
// iterate through the beacon data, but easier if it is bytes
|
||||
uint8_t adv_bytes[strlen(ble_data)/2];
|
||||
|
||||
for(int i=0; i<(strlen(ble_data)/2); i++) {
|
||||
uint8_t d1 = 0;
|
||||
|
||||
if(ble_data[i*2] > '9') {
|
||||
d1 += ((ble_data[i*2] - 'a' + 10) * 0x10);
|
||||
}
|
||||
else {
|
||||
d1 += ((ble_data[i*2] - '0') * 0x10);
|
||||
}
|
||||
|
||||
if(ble_data[i*2+1] > '9') {
|
||||
d1 += ble_data[i*2+1] - 'a' + 10;
|
||||
}
|
||||
else {
|
||||
d1 += ble_data[i*2+1] - '0';
|
||||
}
|
||||
|
||||
adv_bytes[i] = d1;
|
||||
}
|
||||
|
||||
// start with 6 tokens
|
||||
ble_tok_t tokens[6];
|
||||
|
||||
uint8_t token_i = 0;
|
||||
int stop = 0;
|
||||
int pos = 0;
|
||||
while(!stop) {
|
||||
tokens[token_i].size = adv_bytes[pos];
|
||||
tokens[token_i].type = adv_bytes[pos+1];
|
||||
tokens[token_i].start = pos+2;
|
||||
tokens[token_i].end = pos+tokens[token_i].size;
|
||||
|
||||
/*
|
||||
printf("tok: %d, size: %02hhx, type: %02hhx, start: %d end: %d\n", token_i, tokens[token_i].size, tokens[token_i].type, tokens[token_i].start, tokens[token_i].end);
|
||||
for(int j=tokens[token_i].start; j<=tokens[token_i].end; j++) {
|
||||
printf("%02hhx", adv_bytes[j]);
|
||||
}
|
||||
printf("\n\n");
|
||||
*/
|
||||
pos = tokens[token_i].end + 1;
|
||||
if(pos >= sizeof(adv_bytes)) {
|
||||
stop = 1;
|
||||
}
|
||||
token_i++;
|
||||
}
|
||||
|
||||
// iterate through the tokens and determine what kind of beacon it is
|
||||
for(int i = 0; i <= token_i; i++) {
|
||||
// is iBeacon?
|
||||
if(tokens[i].type == 0xff
|
||||
&& adv_bytes[tokens[i].start] == 0x4c
|
||||
&& adv_bytes[tokens[i].start+1] == 0x00
|
||||
&& adv_bytes[tokens[i].start+2] == 0x02
|
||||
&& adv_bytes[tokens[i].start+3] == 0x15) {
|
||||
|
||||
beacon_type = 1; //ibeacon
|
||||
|
||||
//now extract uuid
|
||||
memset(beacon_uuid, 0, 33);
|
||||
memcpy(beacon_uuid, &ble_data[(tokens[i].start+4)*2], 32);
|
||||
beacon_uuid[32] = '\0';
|
||||
|
||||
//extract major
|
||||
memset(beacon_major, 0, 5);
|
||||
memcpy(beacon_major, &ble_data[(tokens[i].start+20)*2], 4);
|
||||
beacon_major[4] = '\0';
|
||||
|
||||
//extract minor
|
||||
memset(beacon_minor, 0, 5);
|
||||
memcpy(beacon_minor, &ble_data[(tokens[i].start+22)*2], 4);
|
||||
beacon_minor[4] = '\0';
|
||||
|
||||
//extract tx_power
|
||||
memset(tx_power, 0, 3);
|
||||
memcpy(tx_power, &ble_data[(tokens[i].start+24)*2], 2);
|
||||
tx_power[3] = '\0';
|
||||
|
||||
os_printf("^^^^^ ibeacon %s %s %s %s\n", beacon_uuid, beacon_major, beacon_minor, tx_power);
|
||||
}
|
||||
}
|
||||
|
||||
//add some filters to
|
||||
if(beacon_type == 0)
|
||||
{
|
||||
//os_printf("send some mqtt for eddystone %s ========\n", beacon_uuid);
|
||||
// sendMQTTeddystone(ble_mac_addr, beacon_uuid, instance_id, tx_power, ble_rssi);
|
||||
}
|
||||
else if(beacon_type == 1)
|
||||
{
|
||||
//os_printf("send some mqtt for ibeacon %s ========\n", beacon_uuid);
|
||||
sendMQTTibeacon(ble_mac_addr, beacon_uuid, beacon_major, beacon_minor, tx_power, ble_rssi);
|
||||
}
|
||||
|
||||
//os_printf("send some mqtt for mac %s =====%d===\n", ble_mac_addr, strlen(ble_mac_addr));
|
||||
// sendMQTTraw(ble_mac_addr, ble_rssi, ble_is_scan_resp, ble_type, ble_data);
|
||||
}
|
||||
|
||||
// void sendMQTTeddystone(char *mac, char *namespace, char *instance_id, char *tx_power, char *rssi)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
void sendMQTTibeacon(char* mac, char* uuid, char* major, char* minor, char* tx_power, char* rssi)
|
||||
{
|
||||
float distance = calcDistance(atoi(rssi), 0x50);
|
||||
String distanceStr = floatToString(distance, 10);
|
||||
|
||||
memset(json_ble_send, 0, 500);
|
||||
os_sprintf(json_ble_send, "{\"hostname\": \"%s\",\"beacon_type\": \"ibeacon\",\"id\": \"%s\",\"rssi\": %s,\"uuid\": \"%s\",\"major\": \"%s\",\"minor\": \"%s\",\"tx_power\": \"%s\", \"distance\": \"%s\"}", hostname, mac, rssi, uuid, major, minor, tx_power, distanceStr.c_str());
|
||||
memset(topic, 0, 130);
|
||||
os_sprintf(topic, "home/presence/%s", hostname);
|
||||
publish(topic, json_ble_send);
|
||||
}
|
||||
// void sendMQTTraw(char * mac, char * rssi, char * is_scan, char * type, char * data)
|
||||
// {
|
||||
// memset(json_ble_send, 0, 500);
|
||||
// os_sprintf(json_ble_send, "{\"hostname\": \"%s\",\"mac\": \"%s\",\"rssi\": %s,\"is_scan_response\": \"%s\",\"type\": \"%s\",\r\n\"data\": \"%s\"}", hostname, mac, rssi, is_scan, type, data);
|
||||
// memset(topic, 0, 130);
|
||||
// os_sprintf(topic, "happy-bubbles/ble/%s/raw/%s", hostname, mac);
|
||||
// // publish(topic, json_ble_send);
|
||||
// }
|
||||
};
|
||||
|
||||
class BleSwitch : public Component, public Switch {
|
||||
public:
|
||||
void setup() override
|
||||
{
|
||||
// This will be called by App.setup()
|
||||
pinMode(BLE_PIN, OUTPUT);
|
||||
write_state(true);
|
||||
}
|
||||
void write_state(bool state) override
|
||||
{
|
||||
digitalWrite(BLE_PIN, !state);
|
||||
publish_state(state);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
#===============================================================================
|
||||
# Счетчик питьевой воды
|
||||
# NodeMCU ESP8266
|
||||
#===============================================================================
|
||||
substitutions:
|
||||
device_name: presence_bedroom
|
||||
upper_devicename: PresenceBedroom
|
||||
room: bedroom
|
||||
#===============================================================================
|
||||
esphome:
|
||||
name: ${device_name}
|
||||
platform: ESP8266
|
||||
board: d1_mini
|
||||
includes:
|
||||
- presence.h
|
||||
|
||||
# Настройки Wi-Fi
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "$upper_devicename Fallback"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
|
||||
api: # Enable Home Assistant API
|
||||
password: !secret esphome_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret esphome_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
logger:
|
||||
baud_rate: 0
|
||||
|
||||
mqtt:
|
||||
broker: !secret mqtt_ip
|
||||
username: !secret mqtt_user
|
||||
password: !secret mqtt_password
|
||||
|
||||
custom_component:
|
||||
- lambda: |-
|
||||
auto hb = new HappyBubblesDevice("${room}");
|
||||
App.register_component(hb);
|
||||
return {hb};
|
||||
|
||||
switch:
|
||||
- platform: custom
|
||||
lambda: |-
|
||||
auto ble_switch = new BleSwitch();
|
||||
App.register_component(ble_switch);
|
||||
return {ble_switch};
|
||||
|
||||
switches:
|
||||
name: "Ble scan enable"
|
||||
@@ -0,0 +1,62 @@
|
||||
#===============================================================================
|
||||
# Прошивка для пат Happy Bubbles
|
||||
# NodeMCU ESP8266
|
||||
#===============================================================================
|
||||
substitutions:
|
||||
device_name: presence_kladovka
|
||||
upper_devicename: PresenceKladovka
|
||||
room: kladovka
|
||||
#===============================================================================
|
||||
esphome:
|
||||
name: ${device_name}
|
||||
platform: ESP8266
|
||||
board: d1_mini
|
||||
includes:
|
||||
- presence.h
|
||||
|
||||
# Настройки Wi-Fi
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "$upper_devicename Fallback"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
|
||||
api: # Enable Home Assistant API
|
||||
password: !secret esphome_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret esphome_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
logger:
|
||||
baud_rate: 0
|
||||
|
||||
mqtt:
|
||||
broker: !secret mqtt_ip
|
||||
username: !secret mqtt_user
|
||||
password: !secret mqtt_password
|
||||
|
||||
custom_component:
|
||||
- lambda: |-
|
||||
auto hb = new HappyBubblesDevice("${room}");
|
||||
App.register_component(hb);
|
||||
return {hb};
|
||||
|
||||
switch:
|
||||
- platform: custom
|
||||
lambda: |-
|
||||
auto ble_switch = new BleSwitch();
|
||||
App.register_component(ble_switch);
|
||||
return {ble_switch};
|
||||
|
||||
switches:
|
||||
name: "Ble scan enable"
|
||||
@@ -0,0 +1,250 @@
|
||||
substitutions:
|
||||
# Set the device name
|
||||
name: presence_radar_bedroom
|
||||
# Set the friendly name
|
||||
friendly_name: Presence Radar Bedroom
|
||||
# Provide the wifi SSID
|
||||
wifi: !secret wifi_24_name
|
||||
#Provide the wifi password
|
||||
wifi_pass: !secret wifi_24_pass
|
||||
#Provide an OTA password:
|
||||
ota_pass: !secret api_encryption_key
|
||||
device_host: presence-radar-bedroom.lan
|
||||
|
||||
### No modifications needed below here ###
|
||||
####################################################################################
|
||||
|
||||
esphome:
|
||||
name: $name
|
||||
friendly_name: $friendly_name
|
||||
platformio_options:
|
||||
board_build.flash_mode: dio
|
||||
board_build.f_cpu: 80000000L
|
||||
name_add_mac_suffix: false
|
||||
|
||||
wifi:
|
||||
ssid: $wifi
|
||||
password: $wifi_pass
|
||||
power_save_mode: LIGHT
|
||||
use_address: 192.168.1.109 #${device_host}
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
|
||||
captive_portal:
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
esp32:
|
||||
board: lolin_c3_mini
|
||||
framework:
|
||||
type: esp-idf
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
encryption:
|
||||
key: $ota_pass
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: $ota_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
|
||||
uart:
|
||||
tx_pin: GPIO4
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 256000
|
||||
parity: NONE
|
||||
stop_bits: 1
|
||||
|
||||
ld2410:
|
||||
|
||||
binary_sensor:
|
||||
- platform: ld2410
|
||||
has_target:
|
||||
name: Presence
|
||||
has_moving_target:
|
||||
name: Moving Target
|
||||
has_still_target:
|
||||
name: Still Target
|
||||
out_pin_presence_status:
|
||||
name: Out Pin Presence Status
|
||||
|
||||
sensor:
|
||||
- platform: ld2410
|
||||
light:
|
||||
name: Light
|
||||
moving_distance:
|
||||
name : Moving Distance
|
||||
still_distance:
|
||||
name: Still Distance
|
||||
moving_energy:
|
||||
name: Move Energy
|
||||
still_energy:
|
||||
name: Still Energy
|
||||
detection_distance:
|
||||
name: Detection Distance
|
||||
g0:
|
||||
move_energy:
|
||||
name: g0 move energy
|
||||
still_energy:
|
||||
name: g0 still energy
|
||||
g1:
|
||||
move_energy:
|
||||
name: g1 move energy
|
||||
still_energy:
|
||||
name: g1 still energy
|
||||
g2:
|
||||
move_energy:
|
||||
name: g2 move energy
|
||||
still_energy:
|
||||
name: g2 still energy
|
||||
g3:
|
||||
move_energy:
|
||||
name: g3 move energy
|
||||
still_energy:
|
||||
name: g3 still energy
|
||||
g4:
|
||||
move_energy:
|
||||
name: g4 move energy
|
||||
still_energy:
|
||||
name: g4 still energy
|
||||
g5:
|
||||
move_energy:
|
||||
name: g5 move energy
|
||||
still_energy:
|
||||
name: g5 still energy
|
||||
g6:
|
||||
move_energy:
|
||||
name: g6 move energy
|
||||
still_energy:
|
||||
name: g6 still energy
|
||||
g7:
|
||||
move_energy:
|
||||
name: g7 move energy
|
||||
still_energy:
|
||||
name: g7 still energy
|
||||
g8:
|
||||
move_energy:
|
||||
name: g8 move energy
|
||||
still_energy:
|
||||
name: g8 still energy
|
||||
- platform: internal_temperature
|
||||
name: ESP Temperature
|
||||
unit_of_measurement: °C
|
||||
device_class: TEMPERATURE
|
||||
update_interval: 30s
|
||||
entity_category: "diagnostic"
|
||||
- platform: uptime
|
||||
name: Uptime
|
||||
id: sys_uptime
|
||||
update_interval: 10s
|
||||
- platform: wifi_signal
|
||||
name: WiFi RSSI
|
||||
id: wifi_signal_db
|
||||
update_interval: 30s
|
||||
entity_category: "diagnostic"
|
||||
|
||||
switch:
|
||||
- platform: ld2410
|
||||
engineering_mode:
|
||||
name: "LD2410 Engineering Mode"
|
||||
bluetooth:
|
||||
name: "LD2410 Bluetooth"
|
||||
|
||||
number:
|
||||
- platform: ld2410
|
||||
timeout:
|
||||
name: Timeout
|
||||
light_threshold:
|
||||
name: Light Threshold
|
||||
max_move_distance_gate:
|
||||
name: Max Move Distance Gate
|
||||
max_still_distance_gate:
|
||||
name: Max Still Distance Gate
|
||||
g0:
|
||||
move_threshold:
|
||||
name: g0 move threshold
|
||||
still_threshold:
|
||||
name: g0 still threshold
|
||||
g1:
|
||||
move_threshold:
|
||||
name: g1 move threshold
|
||||
still_threshold:
|
||||
name: g1 still threshold
|
||||
g2:
|
||||
move_threshold:
|
||||
name: g2 move threshold
|
||||
still_threshold:
|
||||
name: g2 still threshold
|
||||
g3:
|
||||
move_threshold:
|
||||
name: g3 move threshold
|
||||
still_threshold:
|
||||
name: g3 still threshold
|
||||
g4:
|
||||
move_threshold:
|
||||
name: g4 move threshold
|
||||
still_threshold:
|
||||
name: g4 still threshold
|
||||
g5:
|
||||
move_threshold:
|
||||
name: g5 move threshold
|
||||
still_threshold:
|
||||
name: g5 still threshold
|
||||
g6:
|
||||
move_threshold:
|
||||
name: g6 move threshold
|
||||
still_threshold:
|
||||
name: g6 still threshold
|
||||
g7:
|
||||
move_threshold:
|
||||
name: g7 move threshold
|
||||
still_threshold:
|
||||
name: g7 still threshold
|
||||
g8:
|
||||
move_threshold:
|
||||
name: g8 move threshold
|
||||
still_threshold:
|
||||
name: g8 still threshold
|
||||
|
||||
button:
|
||||
- platform: ld2410
|
||||
factory_reset:
|
||||
name: "LD2410 Factory Reset"
|
||||
restart:
|
||||
name: "LD2410 Reboot"
|
||||
query_params:
|
||||
name: "LD2410 Query Params"
|
||||
- platform: restart
|
||||
icon: mdi:power-cycle
|
||||
name: "ESP Reboot"
|
||||
|
||||
text_sensor:
|
||||
- platform: ld2410
|
||||
version:
|
||||
name: "LD2410 Firmware Version"
|
||||
mac_address:
|
||||
name: "LD2410 MAC Address"
|
||||
|
||||
select:
|
||||
- platform: ld2410
|
||||
distance_resolution:
|
||||
name: "Distance Resolution"
|
||||
baud_rate:
|
||||
name: "Baud Rate"
|
||||
light_function:
|
||||
name: Light Function
|
||||
out_pin_level:
|
||||
name: Out Pin Level
|
||||
|
||||
light:
|
||||
- platform: status_led
|
||||
name: sys_status
|
||||
pin:
|
||||
number: GPIO8
|
||||
inverted: True
|
||||
internal: True
|
||||
restore_mode: ALWAYS_OFF
|
||||
@@ -0,0 +1,225 @@
|
||||
esphome:
|
||||
name: presence_bedroom
|
||||
friendly_name: Presence Bedroom
|
||||
|
||||
esp32:
|
||||
board: esp32-c3-devkitm-1
|
||||
framework:
|
||||
type: arduino
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
encryption:
|
||||
key: !secret esphome_pass
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
password: !secret esphome_pass
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "Radar Hotspot"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
include_internal: true
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
light:
|
||||
- platform: binary
|
||||
name: "Blue Status Light"
|
||||
output: light_output
|
||||
id: led_light
|
||||
restore_mode: ALWAYS_OFF
|
||||
|
||||
output:
|
||||
- platform: gpio
|
||||
pin: GPIO2
|
||||
id: light_output
|
||||
|
||||
uart:
|
||||
id: ld2410_uart
|
||||
tx_pin: GPIO21 # TX
|
||||
rx_pin: GPIO20 # RX
|
||||
baud_rate: 256000
|
||||
parity: NONE
|
||||
stop_bits: 1
|
||||
|
||||
ld2410:
|
||||
uart_id: ld2410_uart
|
||||
throttle: 1500ms
|
||||
id: ld2410_comp
|
||||
|
||||
select:
|
||||
- platform: ld2410
|
||||
distance_resolution:
|
||||
name: distance resolution
|
||||
baud_rate:
|
||||
name: baud rate
|
||||
light_function:
|
||||
name: light function
|
||||
out_pin_level:
|
||||
name: out pin level
|
||||
|
||||
button:
|
||||
- platform: ld2410
|
||||
factory_reset:
|
||||
name: "factory reset"
|
||||
restart:
|
||||
name: "restart"
|
||||
query_params:
|
||||
name: query params
|
||||
|
||||
number:
|
||||
- platform: ld2410
|
||||
timeout:
|
||||
name: timeout
|
||||
max_move_distance_gate:
|
||||
name: max move distance gate
|
||||
max_still_distance_gate:
|
||||
name: max still distance gate
|
||||
g0:
|
||||
move_threshold:
|
||||
name: g0 move threshold
|
||||
still_threshold:
|
||||
name: g0 still threshold
|
||||
g1:
|
||||
move_threshold:
|
||||
name: g1 move threshold
|
||||
still_threshold:
|
||||
name: g1 still threshold
|
||||
g2:
|
||||
move_threshold:
|
||||
name: g2 move threshold
|
||||
still_threshold:
|
||||
name: g2 still threshold
|
||||
g3:
|
||||
move_threshold:
|
||||
name: g3 move threshold
|
||||
still_threshold:
|
||||
name: g3 still threshold
|
||||
g4:
|
||||
move_threshold:
|
||||
name: g4 move threshold
|
||||
still_threshold:
|
||||
name: g4 still threshold
|
||||
g5:
|
||||
move_threshold:
|
||||
name: g5 move threshold
|
||||
still_threshold:
|
||||
name: g5 still threshold
|
||||
g6:
|
||||
move_threshold:
|
||||
name: g6 move threshold
|
||||
still_threshold:
|
||||
name: g6 still threshold
|
||||
g7:
|
||||
move_threshold:
|
||||
name: g7 move threshold
|
||||
still_threshold:
|
||||
name: g7 still threshold
|
||||
g8:
|
||||
move_threshold:
|
||||
name: g8 move threshold
|
||||
still_threshold:
|
||||
name: g8 still threshold
|
||||
light_threshold:
|
||||
name: light threshold
|
||||
|
||||
text_sensor:
|
||||
- platform: ld2410
|
||||
version:
|
||||
name: "presenece sensor version"
|
||||
mac_address:
|
||||
name: "presenece sensor mac address"
|
||||
|
||||
switch:
|
||||
- platform: ld2410
|
||||
engineering_mode:
|
||||
name: "engineering mode"
|
||||
bluetooth:
|
||||
name: control Bluetooth
|
||||
|
||||
sensor:
|
||||
- platform: internal_temperature
|
||||
name: "Internal Temperature"
|
||||
|
||||
- platform: ld2410
|
||||
moving_distance:
|
||||
name: "Moving distance (cm)"
|
||||
still_distance:
|
||||
name: "Still Distance (cm)"
|
||||
moving_energy:
|
||||
name: "Move Energy (%)"
|
||||
still_energy:
|
||||
name: "Still Energy (%)"
|
||||
detection_distance:
|
||||
name: "Distance Detection (cm)"
|
||||
g0:
|
||||
move_energy:
|
||||
name: g0 move energy
|
||||
still_energy:
|
||||
name: g0 still energy
|
||||
g1:
|
||||
move_energy:
|
||||
name: g1 move energy
|
||||
still_energy:
|
||||
name: g1 still energy
|
||||
g2:
|
||||
move_energy:
|
||||
name: g2 move energy
|
||||
still_energy:
|
||||
name: g2 still energy
|
||||
g3:
|
||||
move_energy:
|
||||
name: g3 move energy
|
||||
still_energy:
|
||||
name: g3 still energy
|
||||
g4:
|
||||
move_energy:
|
||||
name: g4 move energy
|
||||
still_energy:
|
||||
name: g4 still energy
|
||||
g5:
|
||||
move_energy:
|
||||
name: g5 move energy
|
||||
still_energy:
|
||||
name: g5 still energy
|
||||
g6:
|
||||
move_energy:
|
||||
name: g6 move energy
|
||||
still_energy:
|
||||
name: g6 still energy
|
||||
g7:
|
||||
move_energy:
|
||||
name: g7 move energy
|
||||
still_energy:
|
||||
name: g7 still energy
|
||||
g8:
|
||||
move_energy:
|
||||
name: g8 move energy
|
||||
still_energy:
|
||||
name: g8 still energy
|
||||
light:
|
||||
name: light
|
||||
|
||||
binary_sensor:
|
||||
|
||||
- platform: ld2410
|
||||
has_target:
|
||||
name: Presence
|
||||
has_moving_target:
|
||||
name: Moving Target
|
||||
has_still_target:
|
||||
name: Still Target
|
||||
@@ -0,0 +1,81 @@
|
||||
# Need to turn off logging because senseair uses uart and have conflicts with logging
|
||||
logger:
|
||||
# baud_rate: 0
|
||||
|
||||
esphome:
|
||||
name: senseair
|
||||
platform: ESP8266
|
||||
board: d1_mini
|
||||
font:
|
||||
- file: "OpenSans-Light.ttf"
|
||||
id: open_sans_10
|
||||
size: 10
|
||||
- file: "OpenSans-Light.ttf"
|
||||
id: open_sans_14
|
||||
size: 14
|
||||
- file: "OpenSans-Light.ttf"
|
||||
id: open_sans_18
|
||||
size: 28
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "Senseair Fallback Hotspot"
|
||||
password: !secret esphome_captive_pass
|
||||
|
||||
captive_portal:
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
password: !secret esphome_pass
|
||||
|
||||
ota:
|
||||
password: !secret esphome_pass
|
||||
|
||||
# hass sensor =)
|
||||
time:
|
||||
- platform: homeassistant
|
||||
id: homeassistant_time
|
||||
timezone: Europe/Moscow
|
||||
|
||||
sensor:
|
||||
- platform: homeassistant
|
||||
id: co2_mainroom_bed
|
||||
entity_id: sensor.co2_mainroom_bed
|
||||
|
||||
- platform: homeassistant
|
||||
id: temperature_outside
|
||||
entity_id: sensor.temperature_outside
|
||||
|
||||
i2c:
|
||||
scl: D1
|
||||
sda: D2
|
||||
scan: False
|
||||
|
||||
#
|
||||
display:
|
||||
- platform: ssd1306_i2c
|
||||
model: "SSD1306 128x64"
|
||||
address: 0x3C
|
||||
lambda: |-
|
||||
it.strftime(90, 0, id(open_sans_14), "%H:%M", id(homeassistant_time).now());
|
||||
|
||||
if (id(temperature_outside).has_state()) {
|
||||
it.printf(0, 0, id(open_sans_14), TextAlign::TOP_LEFT , "%.1f°C", id(temperature_outside).state);
|
||||
}
|
||||
|
||||
it.printf(0, 20, id(open_sans_14), TextAlign::TOP_LEFT , "CO");
|
||||
it.printf(22, 27, id(open_sans_10), TextAlign::TOP_LEFT , "2");
|
||||
|
||||
int value = 0;
|
||||
if (id(co2_mainroom_bed).has_state() && !isnan(id(co2_mainroom_bed).state)) {
|
||||
it.printf(35, 18, id(open_sans_18), TextAlign::TOP_LEFT , "%.0f", id(co2_mainroom_bed).state);
|
||||
|
||||
value = (id(co2_mainroom_bed).state*100/2500)*128/100;
|
||||
}
|
||||
|
||||
it.rectangle(0, 57, 127, 7);
|
||||
it.filled_rectangle(0, 57, value, 7);
|
||||
@@ -0,0 +1,58 @@
|
||||
# --------------------------------------------------------------------------
|
||||
# Substitutions
|
||||
#
|
||||
# These are substitutions as used by the configuration packages from below.
|
||||
# You can uncomment and update the ones that you want to modify.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
substitutions:
|
||||
name: svetlana-bedside-lamp
|
||||
friendly_name: Svetlana Bedside Lamp
|
||||
#light_name: ${friendly_name} RGBWW Light
|
||||
#light_mode_text_sensor_name: ${friendly_name} Light Mode
|
||||
#default_transition_length: 800ms
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Load configuration packages
|
||||
#
|
||||
# These provide a convenient way to compose your device configuration from
|
||||
# some functional building blocks. Pick and mix the blocks that you need.
|
||||
#
|
||||
# For customization you can override options in your config or you can
|
||||
# copy the contents of these packages directly in your config file as
|
||||
# an example for your own customizations.
|
||||
#
|
||||
# Available packages are:
|
||||
# - core.yaml : core components & hardware setup
|
||||
# - behavior_default.yaml : default device behavior
|
||||
# - ota_feedback.yaml : enable visual feedback during OTA updates
|
||||
# - activate_preset_svc.yaml : 'activate_preset' service for Home Assistant
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
packages:
|
||||
bslamp2:
|
||||
url: https://github.com/mmakaay/esphome-xiaomi_bslamp2
|
||||
ref: dev
|
||||
files:
|
||||
- packages/core.yaml
|
||||
- packages/behavior_default.yaml
|
||||
- packages/ota_feedback.yaml
|
||||
- packages/activate_preset_svc.yaml
|
||||
refresh: 0s
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Use your own preferences for these components.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_24_name
|
||||
password: !secret wifi_24_pass
|
||||
use_address: ${name}.lan
|
||||
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
password: !secret esphome_pass
|
||||
Reference in New Issue
Block a user