initial commit
This commit is contained in:
commit
26604c8c57
7481 changed files with 489518 additions and 0 deletions
BIN
ESP32-C3_pinout.png
Normal file
BIN
ESP32-C3_pinout.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
33
ESP_STM32F4_OTA/.gitignore
vendored
Normal file
33
ESP_STM32F4_OTA/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# ---------- Arduino ----------
|
||||
*.bin
|
||||
*.elf
|
||||
*.hex
|
||||
*.eep
|
||||
*.map
|
||||
*.out
|
||||
*.lst
|
||||
build/
|
||||
.pio/
|
||||
.pioenvs/
|
||||
.vscode/
|
||||
|
||||
# Libraries (non versionarle)
|
||||
libdeps/
|
||||
libraries/
|
||||
|
||||
# ---------- STM32CubeIDE ----------
|
||||
*.ioc
|
||||
*.elf
|
||||
*.bin
|
||||
*.hex
|
||||
Debug/
|
||||
Release/
|
||||
*.o
|
||||
*.d
|
||||
|
||||
# ---------- OS / Editor ----------
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
51
ESP_STM32F4_OTA/LICENSE
Normal file
51
ESP_STM32F4_OTA/LICENSE
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
---
|
||||
title: MIT License
|
||||
spdx-id: MIT
|
||||
featured: true
|
||||
hidden: false
|
||||
|
||||
description: A short and simple permissive license with conditions only requiring preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.
|
||||
|
||||
how: Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file. Replace [year] with the current year and [fullname] with the name (or names) of the copyright holders.
|
||||
|
||||
using:
|
||||
Babel: https://github.com/babel/babel/blob/master/LICENSE
|
||||
.NET: https://github.com/dotnet/runtime/blob/main/LICENSE.TXT
|
||||
Rails: https://github.com/rails/rails/blob/master/MIT-LICENSE
|
||||
|
||||
permissions:
|
||||
- commercial-use
|
||||
- modifications
|
||||
- distribution
|
||||
- private-use
|
||||
|
||||
conditions:
|
||||
- include-copyright
|
||||
|
||||
limitations:
|
||||
- liability
|
||||
- warranty
|
||||
|
||||
---
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) [year] [fullname]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
7
ESP_STM32F4_OTA/README.md
Normal file
7
ESP_STM32F4_OTA/README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Aggiornamento OTA ESP32 ↔ STM32F446
|
||||
|
||||
Sistema di aggiornamento firmware Over-The-Air basato su
|
||||
- **ESP32** (Arduino IDE)
|
||||
- **STM32F446** (STM32CubeIDE)
|
||||
|
||||
Tutti i requisiti sono descritti in REQUISITI_PROGETTO.md.
|
||||
13
ESP_STM32F4_OTA/REQUISITI_PROGETTO.md
Normal file
13
ESP_STM32F4_OTA/REQUISITI_PROGETTO.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Requisiti di Progetto
|
||||
|
||||
## Funzionali
|
||||
| Codice | Descrizione | Priorità |
|
||||
|--------|-------------------------------------------|----------|
|
||||
| RF-ESP-OTA | Aggiornare ESP32 via HTTPS o altro metodo remoto | Alta |
|
||||
| RF-ESP-INT | Integrazione attuale firmware nel nuovo sistema | Alta |
|
||||
| RF-STM-OTA | Aggiornametno OTA STM32F446, inoltrare aggiornamento firmware STM32 su UART proveniente via ESP32 | Media |
|
||||
| RF-UART-ENC| Cifratura AES-128 CTR sulla UART con meccanismo basato su ID microcontrollore | Media |
|
||||
|
||||
## Non funzionali
|
||||
- Server OTA basato su **GitHub Releases** e manifest.json oppure framework ESPHOME.
|
||||
- Nel primo caso, Partizionamento ESP32 a doppio slot + rollback.
|
||||
0
ESP_STM32F4_OTA/docs/.gitkeep
Normal file
0
ESP_STM32F4_OTA/docs/.gitkeep
Normal file
0
ESP_STM32F4_OTA/docs/.keep
Normal file
0
ESP_STM32F4_OTA/docs/.keep
Normal file
0
ESP_STM32F4_OTA/firmware/esp32/.gitkeep
Normal file
0
ESP_STM32F4_OTA/firmware/esp32/.gitkeep
Normal file
0
ESP_STM32F4_OTA/firmware/esp32/.keep
Normal file
0
ESP_STM32F4_OTA/firmware/esp32/.keep
Normal file
359
ESP_STM32F4_OTA/firmware/esp32/Sblocco_NodeRED.ino
Normal file
359
ESP_STM32F4_OTA/firmware/esp32/Sblocco_NodeRED.ino
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
#include <WiFi.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include "protocol.h"
|
||||
//#include "wifi_login.h"
|
||||
#include "device_login.h"
|
||||
#include "server_url.h"
|
||||
#include <WiFiManager.h>
|
||||
|
||||
#define NR_TIMEOUT 30
|
||||
#define WF_TIMEOUT 1
|
||||
|
||||
#define RXD2 16
|
||||
#define TXD2 17
|
||||
|
||||
#define COM_BAUD 115200
|
||||
|
||||
HardwareSerial comSerial(1);
|
||||
|
||||
// Variabili globali
|
||||
bool treatmentRunning = true;
|
||||
|
||||
uint8_t RXData;
|
||||
int incomingByte;
|
||||
|
||||
uint8_t prev_wfConn = WL_NO_SHIELD;
|
||||
uint8_t wfConn = WL_NO_SHIELD;
|
||||
|
||||
uint8_t prev_nrConn = 0;
|
||||
uint8_t nrConn = 0;
|
||||
|
||||
unsigned long time1,time2;
|
||||
|
||||
|
||||
|
||||
int getRemainingTime(void);
|
||||
int sendConsumedTime(uint32_t timeConsumed, const char* treatment);
|
||||
|
||||
|
||||
bool isEnabled = false;
|
||||
int timeRem = 0;
|
||||
|
||||
int sec_counter=0;
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
comSerial.begin(COM_BAUD, SERIAL_8N1, RXD2, TXD2);
|
||||
comSerial.begin(115200);
|
||||
Serial.println("start");
|
||||
|
||||
time1=millis();
|
||||
time2=millis();
|
||||
|
||||
WiFi.begin();
|
||||
// delay (1000);
|
||||
// prev_wConn = WiFi.status();
|
||||
|
||||
// Connessione al Wi-Fi
|
||||
// Serial.print("Connessione a Wi-Fi");
|
||||
/*
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(1000);
|
||||
// Serial.print(".");
|
||||
}
|
||||
*/
|
||||
// Serial.println("\nConnesso al Wi-Fi!");
|
||||
|
||||
/*
|
||||
if (getWifiConn()==0){
|
||||
Serial.println ("CONNESSO AL WIFI");
|
||||
if(checkNodeRedConnection()){
|
||||
Serial.println ("SERVER ONLINE");
|
||||
Serial.print("TEMPO RIMANENTE: ");
|
||||
int j = getRemainingTime();
|
||||
Serial.println(j);
|
||||
if(isEnabled){
|
||||
Serial.println("UTENTE ABILITATO");
|
||||
}
|
||||
else{
|
||||
Serial.println("UTENTE NON ABILITATO");
|
||||
}
|
||||
}
|
||||
else{
|
||||
Serial.println ("SERVER OFFLINE");
|
||||
}
|
||||
}
|
||||
else{
|
||||
Serial.println ("NON CONNESSO AL WIFI");
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
|
||||
|
||||
|
||||
time1=millis();
|
||||
if(time1-time2>= 1000){
|
||||
sec_counter++;
|
||||
// Serial.print(".");
|
||||
time2=time1;
|
||||
wfConn = WiFi.status();
|
||||
if(wfConn != WL_CONNECTED){
|
||||
sec_counter=0;
|
||||
}
|
||||
if ((wfConn != prev_wfConn)){//&&((wfConn == WL_CONNECTED)||(prev_wfConn == WL_CONNECTED))){
|
||||
prev_wfConn=wfConn;
|
||||
|
||||
if (wfConn != WL_CONNECTED){
|
||||
Serial.println("connessione livello 0");
|
||||
PCmd_refreshCONN(0);
|
||||
}
|
||||
else{
|
||||
sec_counter = NR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sec_counter >= NR_TIMEOUT){
|
||||
sec_counter=0;
|
||||
// Serial.print("+");
|
||||
|
||||
HTTPClient http;
|
||||
http.begin(serverURL_getConnection);
|
||||
|
||||
nrConn = http.GET();
|
||||
if(nrConn != prev_nrConn){
|
||||
prev_nrConn = nrConn;
|
||||
if (nrConn == 200) {
|
||||
Serial.println("connessione livello 2");
|
||||
PCmd_refreshCONN(2);
|
||||
} else {
|
||||
Serial.println("connessione livello 1");
|
||||
PCmd_refreshCONN(1);
|
||||
}
|
||||
}
|
||||
|
||||
http.end();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (comSerial.available() > 0) {
|
||||
incomingByte = comSerial.read();
|
||||
RXData=(uint8_t)incomingByte;
|
||||
checkComData();
|
||||
}
|
||||
}
|
||||
|
||||
int getRemainingTime() {
|
||||
// Controlla se siamo connessi al Wi-Fi
|
||||
|
||||
HTTPClient http;
|
||||
http.begin(serverURL_getRemaining); // Inizializza la connessione all'endpoint
|
||||
http.addHeader("Content-Type", "application/json"); // Aggiunge l'header per JSON
|
||||
|
||||
// Costruiamo il body JSON con le credenziali
|
||||
StaticJsonDocument<200> jsonDoc;
|
||||
jsonDoc["username"] = username;
|
||||
jsonDoc["password"] = devicePassword;
|
||||
|
||||
String requestBody;
|
||||
serializeJson(jsonDoc, requestBody);
|
||||
|
||||
int httpResponseCode = http.POST(requestBody);
|
||||
|
||||
if (httpResponseCode > 0) {
|
||||
String response = http.getString();
|
||||
|
||||
StaticJsonDocument<200> responseDoc;
|
||||
DeserializationError error = deserializeJson(responseDoc, response);
|
||||
if (!error) {
|
||||
const char* status = responseDoc["status"];
|
||||
if (status && String(status) == "success") {
|
||||
timeRem = responseDoc["time_remaining"];
|
||||
Serial.print("TEMPO RIMANENTE: ");
|
||||
Serial.println(timeRem);
|
||||
http.end();
|
||||
isEnabled = responseDoc["enabled"] | false;
|
||||
Serial.println("UTENTE ABILITATO");
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
Serial.println("UTENTE NON ABILITATO");
|
||||
}
|
||||
} else {
|
||||
Serial.println("Errore di parsing JSON nella risposta.");
|
||||
}
|
||||
} else {
|
||||
Serial.println("system error");
|
||||
}
|
||||
|
||||
http.end();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getWifiConn(){
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.println ("NON CONNESSO AL WIFI");
|
||||
// Serial.println("WiFi not connected!!!");
|
||||
return -1;
|
||||
}
|
||||
Serial.println ("CONNESSO AL WIFI");
|
||||
// Serial.println("WiFi connected!!!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sendConsumedTime(uint32_t timeConsumed, const char* treatment) {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
HTTPClient http;
|
||||
|
||||
// Inizializza la connessione all'endpoint Node-RED
|
||||
http.begin(serverURL_setConsumedTime);
|
||||
http.setTimeout(5000);
|
||||
http.addHeader("Content-Type", "application/json");
|
||||
|
||||
// Costruisci il payload JSON
|
||||
StaticJsonDocument<200> jsonDoc;
|
||||
jsonDoc["username"] = username;
|
||||
jsonDoc["password"] = devicePassword;
|
||||
jsonDoc["time_consumed"] = timeConsumed;
|
||||
jsonDoc["treatment"] = treatment;
|
||||
|
||||
String jsonData;
|
||||
serializeJson(jsonDoc, jsonData);
|
||||
|
||||
// Invia la richiesta POST
|
||||
int httpResponseCode = http.POST(jsonData);
|
||||
if (httpResponseCode > 0) {
|
||||
String response = http.getString();
|
||||
if(httpResponseCode==200){
|
||||
//send ackconn
|
||||
Serial.println("Sending ACK");
|
||||
http.end();
|
||||
return 0;
|
||||
|
||||
}
|
||||
// Serial.println("Response: " + response);
|
||||
} else {
|
||||
http.end();
|
||||
return -1;
|
||||
// Serial.print("Error on sending POST: ");
|
||||
// Serial.println(http.errorToString(httpResponseCode));
|
||||
}
|
||||
|
||||
} else {
|
||||
// Serial.println("WiFi not connected");
|
||||
}
|
||||
}
|
||||
|
||||
int checkNodeRedConnection() {
|
||||
// Verifica prima di tutto la connessione WiFi
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
// Serial.println("WiFi non connesso.");
|
||||
return -1; // Errore WiFi
|
||||
}
|
||||
|
||||
HTTPClient http;
|
||||
http.begin(serverURL_getConnection);
|
||||
|
||||
int httpResponseCode = http.GET();
|
||||
if (httpResponseCode > 0) {
|
||||
// Leggiamo la risposta solo se vogliamo ispezionarla
|
||||
// String response = http.getString();
|
||||
// Serial.print("Risposta dal server: ");
|
||||
// Serial.println(response);
|
||||
|
||||
if (httpResponseCode == 200) {
|
||||
Serial.println ("SERVER ONLINE");
|
||||
// Serial.println("Connessione OK a Node-RED!");
|
||||
http.end();
|
||||
return 1; // Connessione riuscita
|
||||
}
|
||||
} else {
|
||||
Serial.println ("SERVER OFFLINE");
|
||||
// Serial.print("Errore di connessione HTTP: ");
|
||||
// Serial.println(httpResponseCode);
|
||||
}
|
||||
|
||||
http.end();
|
||||
return 0; // Errore generico
|
||||
}
|
||||
|
||||
WiFiManager wm; // global wm instance
|
||||
WiFiManagerParameter custom_field; // global param ( for non blocking w params )
|
||||
void setWiFi(){
|
||||
|
||||
// test custom html(radio)
|
||||
const char* custom_radio_str = "<br/><label for='customfieldid'>Custom Field Label</label><input type='radio' name='customfieldid' value='1' checked> One<br><input type='radio' name='customfieldid' value='2'> Two<br><input type='radio' name='customfieldid' value='3'> Three";
|
||||
new (&custom_field) WiFiManagerParameter(custom_radio_str); // custom html input
|
||||
|
||||
wm.addParameter(&custom_field);
|
||||
wm.setSaveParamsCallback(saveParamCallback);
|
||||
|
||||
std::vector<const char *> menu = {"wifi","info","param","sep","restart","exit"};
|
||||
wm.setMenu(menu);
|
||||
|
||||
// set dark theme
|
||||
wm.setClass("invert");
|
||||
|
||||
wm.setConnectTimeout(60); // how long to try to connect for before continuing
|
||||
wm.setConfigPortalTimeout(10); // auto close configportal after n seconds
|
||||
bool res;
|
||||
// res = wm.autoConnect(); // auto generated AP name from chipid
|
||||
// res = wm.autoConnect("AutoConnectAP"); // anonymous ap
|
||||
res = wm.autoConnect("AutoConnectAP","password"); // password protected ap
|
||||
|
||||
if(!res) {
|
||||
Serial.println("Failed to connect or hit timeout");
|
||||
// ESP.restart();
|
||||
}
|
||||
else {
|
||||
//if you get here you have connected to the WiFi
|
||||
Serial.println("connected...yeey :)");
|
||||
}
|
||||
|
||||
// check for button press
|
||||
|
||||
Serial.println("Erasing Config, restarting");
|
||||
// wm.resetSettings();
|
||||
// ESP.restart();
|
||||
|
||||
// start portal w delay
|
||||
Serial.println("Starting config portal");
|
||||
wm.setConfigPortalTimeout(120);
|
||||
|
||||
if (!wm.startConfigPortal("OnDemandAP","password")) {
|
||||
Serial.println("failed to connect or hit timeout");
|
||||
delay(3000);
|
||||
// ESP.restart();
|
||||
} else {
|
||||
//if you get here you have connected to the WiFi
|
||||
Serial.println("connected...yeey :)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String getParam(String name){
|
||||
//read parameter from server, for customhmtl input
|
||||
String value;
|
||||
if(wm.server->hasArg(name)) {
|
||||
value = wm.server->arg(name);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void saveParamCallback(){
|
||||
Serial.println("[CALLBACK] saveParamCallback fired");
|
||||
Serial.println("PARAM customfieldid = " + getParam("customfieldid"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
0
ESP_STM32F4_OTA/firmware/stm32/.gitkeep
Normal file
0
ESP_STM32F4_OTA/firmware/stm32/.gitkeep
Normal file
0
ESP_STM32F4_OTA/firmware/stm32/.keep
Normal file
0
ESP_STM32F4_OTA/firmware/stm32/.keep
Normal file
0
ESP_STM32F4_OTA/ota_server/.gitkeep
Normal file
0
ESP_STM32F4_OTA/ota_server/.gitkeep
Normal file
0
ESP_STM32F4_OTA/ota_server/.keep
Normal file
0
ESP_STM32F4_OTA/ota_server/.keep
Normal file
0
ESP_STM32F4_OTA/scripts/.gitkeep
Normal file
0
ESP_STM32F4_OTA/scripts/.gitkeep
Normal file
0
ESP_STM32F4_OTA/scripts/.keep
Normal file
0
ESP_STM32F4_OTA/scripts/.keep
Normal file
33
_stuff/starter-components-main/.github/workflows/ci.yml
vendored
Normal file
33
_stuff/starter-components-main/.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 7 * * *' # Every day at 07:00 UTC
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref}}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.esphome-version }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
esphome-version:
|
||||
- stable
|
||||
- beta
|
||||
- dev
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
uses: esphome/build-action@v7
|
||||
with:
|
||||
version: ${{ matrix.esphome-version }}
|
||||
yaml-file: test_empty_components.yaml
|
||||
24
_stuff/starter-components-main/.github/workflows/yaml-lint.yml
vendored
Normal file
24
_stuff/starter-components-main/.github/workflows/yaml-lint.yml
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
name: YAML lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "**.yaml"
|
||||
- "**.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "**.yaml"
|
||||
- "**.yml"
|
||||
|
||||
jobs:
|
||||
yamllint:
|
||||
name: yamllint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: ⤵️ Check out code from GitHub
|
||||
uses: actions/checkout@v4
|
||||
- name: 🚀 Run yamllint
|
||||
run: yamllint --strict .
|
||||
147
_stuff/starter-components-main/.gitignore
vendored
Normal file
147
_stuff/starter-components-main/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Hide sublime text stuff
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# Intellij Idea
|
||||
.idea
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.cproject
|
||||
.pydevproject
|
||||
.settings/
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
|
||||
# Hide some OS X stuff
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
.esphome
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
cov.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# asdf
|
||||
.tool-versions
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
venv-*/
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.pio
|
||||
.vscode/
|
||||
!.vscode/tasks.json
|
||||
CMakeListsPrivate.txt
|
||||
CMakeLists.txt
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/dynamic.xml
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
/*.cbp
|
||||
|
||||
.clang_complete
|
||||
.gcc-flags.json
|
||||
|
||||
config/
|
||||
tests/build/
|
||||
tests/.esphome/
|
||||
/.temp-clang-tidy.cpp
|
||||
/.temp/
|
||||
.pio/
|
||||
|
||||
sdkconfig.*
|
||||
!sdkconfig.defaults
|
||||
|
||||
.tests/
|
||||
|
||||
/managed_components
|
||||
|
||||
**/src/
|
||||
**/platformio.ini
|
||||
/secrets.yaml
|
||||
19
_stuff/starter-components-main/.yamllint
Normal file
19
_stuff/starter-components-main/.yamllint
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
extends: default
|
||||
|
||||
ignore-from-file: .gitignore
|
||||
|
||||
rules:
|
||||
document-start: disable
|
||||
empty-lines:
|
||||
level: error
|
||||
max: 1
|
||||
max-start: 0
|
||||
max-end: 1
|
||||
indentation:
|
||||
level: error
|
||||
spaces: 2
|
||||
indent-sequences: true
|
||||
check-multi-line-strings: false
|
||||
line-length: disable
|
||||
truthy: disable
|
||||
36
_stuff/starter-components-main/README.md
Normal file
36
_stuff/starter-components-main/README.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<a href="https://esphome.io/">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./logo-text-on-dark.svg", alt="ESPHome Logo">
|
||||
<img src="./logo-text-on-light.svg" alt="ESPHome Logo">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
# ESPHome starter components
|
||||
|
||||
This repository contains a number of examples in the form of empty components which can be used as templates to quickly
|
||||
develop your own ([external](https://esphome.io/components/external_components)) components for
|
||||
[ESPHome](https://esphome.io).
|
||||
|
||||
## How to use the examples in this repository
|
||||
|
||||
All examples are in the [`components`](components/) directory of this repository. The
|
||||
[`test_empty_components.yaml`](test_empty_components.yaml) file contains configuration examples for the various
|
||||
components.
|
||||
|
||||
The easiest way to develop components/platforms for use within ESPHome is to use
|
||||
[external components](https://esphome.io/components/external_components). To use a particular component from this
|
||||
repository for your project:
|
||||
|
||||
1. Create an `external_components` directory in your ESPHome configuration directory (the directory where your `.yaml`
|
||||
files are located).
|
||||
1. Copy the directory (and all of its contents!) of an empty component into your `external_components` directory. You
|
||||
should end up with something like this: `external_components/empty_sensor/`
|
||||
1. Find the configuration entry for the empty component in [`test_empty_components.yaml`](test_empty_components.yaml)
|
||||
and copy it into your own `.yaml` file.
|
||||
1. Compile with `esphome compile your_config.yaml` where `your_config.yaml` is your own `.yaml` file.
|
||||
1. No errors? Great! You can now start modifying the empty component to turn it into your own (external) component.
|
||||
|
||||
## Going further
|
||||
|
||||
- [Developer documentation](https://developers.esphome.io)
|
||||
- [Component architecture overview](https://developers.esphome.io/architecture/components/)
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
from esphome import automation
|
||||
from esphome.automation import maybe_simple_id
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_ON_STATE,
|
||||
CONF_STATE,
|
||||
CONF_TRIGGER_ID,
|
||||
)
|
||||
|
||||
empty_automation_ns = cg.esphome_ns.namespace("empty_automation")
|
||||
EmptyAutomation = empty_automation_ns.class_("EmptyAutomation", cg.Component)
|
||||
# Actions
|
||||
EmptyAutomationSetStateAction = empty_automation_ns.class_(
|
||||
"EmptyAutomationSetStateAction", automation.Action
|
||||
)
|
||||
# Conditions
|
||||
EmptyAutomationCondition = empty_automation_ns.class_(
|
||||
"EmptyAutomationCondition", automation.Condition
|
||||
)
|
||||
# Triggers
|
||||
StateTrigger = empty_automation_ns.class_(
|
||||
"StateTrigger", automation.Trigger.template(bool)
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptyAutomation),
|
||||
cv.Optional(CONF_ON_STATE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger),
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
EMPTY_AUTOMATION_ACTION_SCHEMA = cv.maybe_simple_value(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(EmptyAutomation),
|
||||
cv.Required(CONF_STATE): cv.boolean,
|
||||
},
|
||||
key=CONF_STATE,
|
||||
)
|
||||
|
||||
|
||||
EMPTY_AUTOMATION_CONDITION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(EmptyAutomation),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"empty_automation.set_state",
|
||||
EmptyAutomationSetStateAction,
|
||||
EMPTY_AUTOMATION_ACTION_SCHEMA,
|
||||
)
|
||||
async def empty_automation_set_state_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
cg.add(var.set_state(config[CONF_STATE]))
|
||||
return var
|
||||
|
||||
|
||||
@automation.register_condition(
|
||||
"empty_automation.component_on",
|
||||
EmptyAutomationCondition,
|
||||
EMPTY_AUTOMATION_CONDITION_SCHEMA,
|
||||
)
|
||||
async def empty_automation_component_on_to_code(
|
||||
config, condition_id, template_arg, args
|
||||
):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(condition_id, template_arg, paren, True)
|
||||
|
||||
|
||||
@automation.register_condition(
|
||||
"empty_automation.component_off",
|
||||
EmptyAutomationCondition,
|
||||
EMPTY_AUTOMATION_CONDITION_SCHEMA,
|
||||
)
|
||||
async def empty_automation_component_off_to_code(
|
||||
config, condition_id, template_arg, args
|
||||
):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(condition_id, template_arg, paren, False)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
||||
for conf in config.get(CONF_ON_STATE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
await automation.build_automation(trigger, [(bool, "x")], conf)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "empty_automation.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_automation {
|
||||
|
||||
template<typename... Ts> class EmptyAutomationSetStateAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit EmptyAutomationSetStateAction(EmptyAutomation *ea) : ea_(ea) {}
|
||||
TEMPLATABLE_VALUE(bool, state)
|
||||
|
||||
void play(Ts... x) override {
|
||||
auto val = this->state_.value(x...);
|
||||
this->ea_->set_state(val);
|
||||
}
|
||||
|
||||
protected:
|
||||
EmptyAutomation *ea_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class EmptyAutomationCondition : public Condition<Ts...> {
|
||||
public:
|
||||
EmptyAutomationCondition(EmptyAutomation *parent, bool state) : parent_(parent), state_(state) {}
|
||||
bool check(Ts... x) override { return this->parent_->state == this->state_; }
|
||||
|
||||
protected:
|
||||
EmptyAutomation *parent_;
|
||||
bool state_;
|
||||
};
|
||||
|
||||
class StateTrigger : public Trigger<bool> {
|
||||
public:
|
||||
explicit StateTrigger(EmptyAutomation *parent) {
|
||||
parent->add_on_state_callback([this](bool state) { this->trigger(state); });
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace empty_automation
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#include "empty_automation.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_automation {
|
||||
|
||||
static const char *const TAG = "empty_automation";
|
||||
|
||||
void EmptyAutomation::add_on_state_callback(std::function<void(bool)> &&callback) {
|
||||
this->state_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void EmptyAutomation::set_state(bool state) {
|
||||
ESP_LOGD(TAG, "Set state to %s", TRUEFALSE(state));
|
||||
this->state = state;
|
||||
this->state_callback_.call(state);
|
||||
}
|
||||
|
||||
} // namespace empty_automation
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_automation {
|
||||
|
||||
class EmptyAutomation : public Component {
|
||||
public:
|
||||
void add_on_state_callback(std::function<void(bool)> &&callback);
|
||||
void set_state(bool state);
|
||||
|
||||
bool state{false};
|
||||
|
||||
protected:
|
||||
CallbackManager<void(bool)> state_callback_{};
|
||||
};
|
||||
|
||||
} // namespace empty_automation
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
output:
|
||||
- platform: empty_binary_output
|
||||
id: empty_binary_output_1
|
||||
```
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_binary_output.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_binary_output {
|
||||
|
||||
static const char *TAG = "empty_binary_output.binary_output";
|
||||
|
||||
void EmptyBinaryOutput::setup(){
|
||||
|
||||
}
|
||||
|
||||
void EmptyBinaryOutput::write_state(bool state){
|
||||
|
||||
}
|
||||
|
||||
void EmptyBinaryOutput::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Empty binary output");
|
||||
}
|
||||
|
||||
} //namespace empty_binary_output
|
||||
} //namespace esphome
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/output/binary_output.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_binary_output {
|
||||
|
||||
class EmptyBinaryOutput : public output::BinaryOutput, public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
void write_state(bool state) override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
|
||||
} //namespace empty_binary_output
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import output
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
empty_binary_output_ns = cg.esphome_ns.namespace("empty_binary_output")
|
||||
EmptyBinaryOutput = empty_binary_output_ns.class_(
|
||||
"EmptyBinaryOutput", output.BinaryOutput, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = output.BINARY_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(EmptyBinaryOutput),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await output.register_output(var, config)
|
||||
await cg.register_component(var, config)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
binary_sensor:
|
||||
- platform: empty_binary_sensor
|
||||
name: Empty binary sensor
|
||||
```
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
empty_binary_sensor_ns = cg.esphome_ns.namespace("empty_binary_sensor")
|
||||
EmptyBinarySensor = empty_binary_sensor_ns.class_(
|
||||
"EmptyBinarySensor", binary_sensor.BinarySensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
binary_sensor.binary_sensor_schema(EmptyBinarySensor)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptyBinarySensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await binary_sensor.new_binary_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_binary_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_binary_sensor {
|
||||
|
||||
static const char *TAG = "empty_binary_sensor.binary_sensor";
|
||||
|
||||
void EmptyBinarySensor::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyBinarySensor::update() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyBinarySensor::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Empty binary sensor");
|
||||
}
|
||||
|
||||
} //namespace empty_binary_sensor
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_binary_sensor {
|
||||
|
||||
class EmptyBinarySensor : public binary_sensor::BinarySensor, public PollingComponent {
|
||||
public:
|
||||
void setup() override;
|
||||
void update() override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
} //namespace empty_binary_sensor
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
empty_component:
|
||||
id: empty_component_1
|
||||
```
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
empty_component_ns = cg.esphome_ns.namespace("empty_component")
|
||||
EmptyComponent = empty_component_ns.class_("EmptyComponent", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptyComponent),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_component {
|
||||
|
||||
static const char *TAG = "empty_component.component";
|
||||
|
||||
void EmptyComponent::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyComponent::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyComponent::dump_config(){
|
||||
ESP_LOGCONFIG(TAG, "Empty component");
|
||||
}
|
||||
|
||||
|
||||
} // namespace empty_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_component {
|
||||
|
||||
class EmptyComponent : public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
|
||||
} // namespace empty_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
sensor:
|
||||
- platform: empty_compound_sensor
|
||||
sensor1:
|
||||
name: Sensor 1
|
||||
sensor2:
|
||||
name: Sensor 2
|
||||
sensor3:
|
||||
name: Sensor 3
|
||||
```
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_compound_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_compound_sensor {
|
||||
|
||||
static const char *TAG = "empty_compound_sensor.sensor";
|
||||
|
||||
void EmptyCompoundSensor::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyCompoundSensor::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyCompoundSensor::update() {
|
||||
if (this->sensor1_ != nullptr)
|
||||
this->sensor1_->publish_state(1.0f);
|
||||
if (this->sensor2_ != nullptr)
|
||||
this->sensor2_->publish_state(2.0f);
|
||||
if (this->sensor3_ != nullptr)
|
||||
this->sensor3_->publish_state(3.0f);
|
||||
}
|
||||
|
||||
void EmptyCompoundSensor::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Empty compound sensor");
|
||||
}
|
||||
|
||||
} //namespace empty_compound_sensor
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_compound_sensor {
|
||||
|
||||
class EmptyCompoundSensor : public sensor::Sensor, public PollingComponent {
|
||||
public:
|
||||
void set_sensor1(sensor::Sensor *sensor1) { sensor1_ = sensor1; }
|
||||
void set_sensor2(sensor::Sensor *sensor2) { sensor2_ = sensor2; }
|
||||
void set_sensor3(sensor::Sensor *sensor3) { sensor3_ = sensor3; }
|
||||
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void update() override;
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
sensor::Sensor *sensor1_;
|
||||
sensor::Sensor *sensor2_;
|
||||
sensor::Sensor *sensor3_;
|
||||
};
|
||||
|
||||
} //namespace empty_compound_sensor
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, UNIT_EMPTY, ICON_EMPTY
|
||||
|
||||
empty_compound_sensor_ns = cg.esphome_ns.namespace("empty_compound_sensor")
|
||||
EmptyCompoundSensor = empty_compound_sensor_ns.class_(
|
||||
"EmptyCompoundSensor", cg.PollingComponent
|
||||
)
|
||||
|
||||
CONF_SENSOR1 = "sensor1"
|
||||
CONF_SENSOR2 = "sensor2"
|
||||
CONF_SENSOR3 = "sensor3"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptyCompoundSensor),
|
||||
cv.Optional(CONF_SENSOR1): sensor.sensor_schema(
|
||||
EmptyCompoundSensor,
|
||||
unit_of_measurement=UNIT_EMPTY,
|
||||
icon=ICON_EMPTY,
|
||||
accuracy_decimals=1,
|
||||
).extend(),
|
||||
cv.Optional(CONF_SENSOR2): sensor.sensor_schema(
|
||||
EmptyCompoundSensor,
|
||||
unit_of_measurement=UNIT_EMPTY,
|
||||
icon=ICON_EMPTY,
|
||||
accuracy_decimals=1,
|
||||
).extend(),
|
||||
cv.Optional(CONF_SENSOR3): sensor.sensor_schema(
|
||||
EmptyCompoundSensor,
|
||||
unit_of_measurement=UNIT_EMPTY,
|
||||
icon=ICON_EMPTY,
|
||||
accuracy_decimals=1,
|
||||
).extend(),
|
||||
}
|
||||
).extend(cv.polling_component_schema("60s"))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
||||
if CONF_SENSOR1 in config:
|
||||
sens = await sensor.new_sensor(config[CONF_SENSOR1])
|
||||
cg.add(var.set_sensor1(sens))
|
||||
|
||||
if CONF_SENSOR2 in config:
|
||||
sens = await sensor.new_sensor(config[CONF_SENSOR2])
|
||||
cg.add(var.set_sensor2(sens))
|
||||
|
||||
if CONF_SENSOR3 in config:
|
||||
sens = await sensor.new_sensor(config[CONF_SENSOR3])
|
||||
cg.add(var.set_sensor3(sens))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
cover:
|
||||
platform: empty_cover
|
||||
name: Empty cover
|
||||
```
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import cover
|
||||
|
||||
empty_cover_ns = cg.esphome_ns.namespace("empty_cover")
|
||||
EmptyCover = empty_cover_ns.class_("EmptyCover", cover.Cover, cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cover.cover_schema(EmptyCover).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await cover.new_cover(config)
|
||||
await cg.register_component(var, config)
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_cover.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_cover {
|
||||
|
||||
static const char *TAG = "empty_cover.cover";
|
||||
|
||||
void EmptyCover::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyCover::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyCover::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Empty cover");
|
||||
}
|
||||
|
||||
cover::CoverTraits EmptyCover::get_traits() {
|
||||
auto traits = cover::CoverTraits();
|
||||
traits.set_is_assumed_state(false);
|
||||
traits.set_supports_position(false);
|
||||
traits.set_supports_tilt(false);
|
||||
|
||||
return traits;
|
||||
}
|
||||
|
||||
void EmptyCover::control(const cover::CoverCall &call) {
|
||||
|
||||
}
|
||||
|
||||
} // namespace empty_cover
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/cover/cover.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_cover {
|
||||
|
||||
class EmptyCover : public cover::Cover, public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
cover::CoverTraits get_traits() override;
|
||||
|
||||
protected:
|
||||
void control(const cover::CoverCall &call) override;
|
||||
};
|
||||
|
||||
} // namespace empty_cover
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
fan:
|
||||
- platform: empty_fan
|
||||
name: Empty fan
|
||||
output: gpio_d1
|
||||
|
||||
output:
|
||||
- platform: gpio
|
||||
pin: D1
|
||||
id: gpio_d1
|
||||
```
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import esphome.codegen as cg
|
||||
|
||||
empty_fan_ns = cg.esphome_ns.namespace('empty_fan')
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import esphome.codegen as cg
|
||||
from esphome.components import fan, output
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_DIRECTION_OUTPUT,
|
||||
CONF_OSCILLATION_OUTPUT,
|
||||
CONF_OUTPUT,
|
||||
CONF_OUTPUT_ID,
|
||||
)
|
||||
from .. import empty_fan_ns
|
||||
|
||||
EmptyFan = empty_fan_ns.class_("EmptyFan", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
fan.fan_schema(EmptyFan)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(EmptyFan),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
cv.Optional(CONF_OSCILLATION_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
cv.Optional(CONF_DIRECTION_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await fan.new_fan(config)
|
||||
await cg.register_component(var, config)
|
||||
|
||||
output_ = await cg.get_variable(config[CONF_OUTPUT])
|
||||
cg.add(var.set_output(output_))
|
||||
|
||||
if CONF_OSCILLATION_OUTPUT in config:
|
||||
oscillation_output = await cg.get_variable(config[CONF_OSCILLATION_OUTPUT])
|
||||
cg.add(var.set_oscillating(oscillation_output))
|
||||
|
||||
if CONF_DIRECTION_OUTPUT in config:
|
||||
direction_output = await cg.get_variable(config[CONF_DIRECTION_OUTPUT])
|
||||
cg.add(var.set_direction(direction_output))
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#include "empty_fan.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_fan {
|
||||
|
||||
static const char *TAG = "empty_fan.fan";
|
||||
|
||||
void EmptyFan::setup() {
|
||||
// Construct traits
|
||||
this->traits_ = fan::FanTraits(this->direction_output_ != nullptr, false, this->oscillating_output_ != nullptr, 0);
|
||||
}
|
||||
|
||||
void EmptyFan::dump_config() { ESP_LOGCONFIG(TAG, "Empty fan"); }
|
||||
|
||||
void EmptyFan::control(const fan::FanCall &call) {
|
||||
if (call.get_state().has_value()) {
|
||||
this->state = *call.get_state();
|
||||
}
|
||||
if (call.get_oscillating().has_value()) {
|
||||
this->oscillating = *call.get_oscillating();
|
||||
}
|
||||
if (call.get_direction().has_value()) {
|
||||
this->direction = *call.get_direction();
|
||||
}
|
||||
|
||||
this->write_state_();
|
||||
this->publish_state();
|
||||
}
|
||||
|
||||
void EmptyFan::write_state_() {
|
||||
if (this->oscillating_output_ != nullptr) {
|
||||
this->oscillating_output_->set_state(this->oscillating);
|
||||
}
|
||||
if (this->direction_output_ != nullptr) {
|
||||
this->direction_output_->set_state(this->direction == fan::FanDirection::REVERSE);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace empty_fan
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/output/binary_output.h"
|
||||
#include "esphome/components/fan/fan_state.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_fan {
|
||||
|
||||
class EmptyFan : public fan::Fan, public Component {
|
||||
public:
|
||||
void set_direction(output::BinaryOutput *output) { this->direction_output_ = output; }
|
||||
void set_oscillating(output::BinaryOutput *output) { this->oscillating_output_ = output; }
|
||||
void set_output(output::BinaryOutput *output) { this->output_ = output; }
|
||||
fan::FanTraits get_traits() override { return this->traits_; }
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
void control(const fan::FanCall &call) override;
|
||||
void write_state_();
|
||||
|
||||
fan::FanTraits traits_;
|
||||
output::BinaryOutput *direction_output_;
|
||||
output::BinaryOutput *oscillating_output_;
|
||||
output::BinaryOutput *output_;
|
||||
};
|
||||
|
||||
} // namespace empty_fan
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
output:
|
||||
- platform: empty_float_output
|
||||
id: empty_float_output_1
|
||||
```
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_float_output.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_float_output {
|
||||
|
||||
static const char *TAG = "empty_float_output.output";
|
||||
|
||||
void EmptyFloatOutput::setup(){
|
||||
|
||||
}
|
||||
|
||||
void EmptyFloatOutput::write_state(float state){
|
||||
|
||||
}
|
||||
|
||||
void EmptyFloatOutput::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Empty float output");
|
||||
}
|
||||
|
||||
} //namespace empty_float_output
|
||||
} //namespace esphome
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/output/float_output.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_float_output {
|
||||
|
||||
class EmptyFloatOutput : public output::FloatOutput, public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
void write_state(float state) override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
|
||||
} //namespace empty_float_output
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import output
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
empty_float_output_ns = cg.esphome_ns.namespace("empty_float_output")
|
||||
EmptyFloatOutput = empty_float_output_ns.class_(
|
||||
"EmptyFloatOutput", output.FloatOutput, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(EmptyFloatOutput),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await output.register_output(var, config)
|
||||
await cg.register_component(var, config)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
empty_gpio_component:
|
||||
id: empty_gpio_component_1
|
||||
pin: 5
|
||||
```
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_PIN
|
||||
from esphome.cpp_helpers import gpio_pin_expression
|
||||
|
||||
empty_gpio_component_ns = cg.esphome_ns.namespace("empty_gpio_component")
|
||||
EmptyGPIOComponent = empty_gpio_component_ns.class_("EmptyGPIOComponent", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptyGPIOComponent),
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
||||
pin = await gpio_pin_expression(config[CONF_PIN])
|
||||
cg.add(var.set_output_pin(pin))
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_gpio_component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_gpio_component {
|
||||
|
||||
static const char *TAG = "empty_gpio_component.component";
|
||||
|
||||
void EmptyGPIOComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up Empty GPIO component...");
|
||||
this->pin_->setup();
|
||||
this->pin_->digital_write(true);
|
||||
}
|
||||
|
||||
void EmptyGPIOComponent::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyGPIOComponent::dump_config(){
|
||||
ESP_LOGCONFIG(TAG, "Empty GPIO component");
|
||||
LOG_PIN(" Pin: ", this->pin_);
|
||||
}
|
||||
|
||||
|
||||
} // namespace empty_gpio_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_gpio_component {
|
||||
|
||||
class EmptyGPIOComponent : public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
|
||||
void set_output_pin(GPIOPin *pin) { this->pin_ = pin; }
|
||||
|
||||
protected:
|
||||
GPIOPin *pin_;
|
||||
};
|
||||
|
||||
} // namespace empty_gpio_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
empty_i2c_component:
|
||||
id: empty_i2c_component_1
|
||||
address: 0x01 # optional
|
||||
|
||||
i2c:
|
||||
sda: 4
|
||||
scl: 5
|
||||
```
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
empty_i2c_component_ns = cg.esphome_ns.namespace("empty_i2c_component")
|
||||
EmptyI2CComponent = empty_i2c_component_ns.class_(
|
||||
"EmptyI2CComponent", cg.Component, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptyI2CComponent),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x01))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_i2c_component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_i2c_component {
|
||||
|
||||
static const char *TAG = "empty_i2c_component.component";
|
||||
|
||||
void EmptyI2CComponent::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyI2CComponent::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptyI2CComponent::dump_config(){
|
||||
ESP_LOGCONFIG(TAG, "Empty I2C component");
|
||||
}
|
||||
|
||||
|
||||
} // namespace empty_i2c_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_i2c_component {
|
||||
|
||||
class EmptyI2CComponent : public i2c::I2CDevice, public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
|
||||
} // namespace empty_i2c_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
sensor:
|
||||
- platform: empty_i2c_sensor
|
||||
name: Empty I2C sensor
|
||||
|
||||
i2c:
|
||||
sda: 4
|
||||
scl: 5
|
||||
```
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_i2c_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_i2c_sensor {
|
||||
|
||||
static const char *TAG = "empty_i2c_sensor.sensor";
|
||||
|
||||
void EmptyI2CSensor::setup(){
|
||||
|
||||
}
|
||||
|
||||
void EmptyI2CSensor::update(){
|
||||
|
||||
}
|
||||
|
||||
void EmptyI2CSensor::dump_config(){
|
||||
|
||||
}
|
||||
|
||||
} // namespace EmptyI2CSensor
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_i2c_sensor {
|
||||
|
||||
class EmptyI2CSensor : public sensor::Sensor, public PollingComponent, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
void update() override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
} // namespace EmptyI2CSensor
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import ICON_EMPTY, UNIT_EMPTY
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
empty_i2c_sensor_ns = cg.esphome_ns.namespace("empty_i2c_sensor")
|
||||
EmptyI2CSensor = empty_i2c_sensor_ns.class_(
|
||||
"EmptyI2CSensor", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
EmptyI2CSensor,
|
||||
unit_of_measurement=UNIT_EMPTY,
|
||||
icon=ICON_EMPTY,
|
||||
accuracy_decimals=1,
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x01))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
light:
|
||||
- platform: empty_light
|
||||
name: Empty light
|
||||
output: pwm_output
|
||||
|
||||
output:
|
||||
- platform: esp8266_pwm
|
||||
pin: D1
|
||||
frequency: 1000 Hz
|
||||
id: pwm_output
|
||||
```
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_light.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_light {
|
||||
|
||||
static const char *TAG = "empty_light.light";
|
||||
|
||||
void EmptyLightOutput::setup() {
|
||||
|
||||
}
|
||||
|
||||
light::LightTraits EmptyLightOutput::get_traits() {
|
||||
auto traits = light::LightTraits();
|
||||
traits.set_supported_color_modes({light::ColorMode::RGB});
|
||||
return traits;
|
||||
}
|
||||
|
||||
void EmptyLightOutput::write_state(light::LightState *state) {
|
||||
|
||||
}
|
||||
|
||||
void EmptyLightOutput::dump_config(){
|
||||
ESP_LOGCONFIG(TAG, "Empty light");
|
||||
}
|
||||
|
||||
} //namespace empty_light
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/output/float_output.h"
|
||||
#include "esphome/components/light/light_output.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_light {
|
||||
|
||||
class EmptyLightOutput : public light::LightOutput, public Component {
|
||||
public:
|
||||
void setup() override;
|
||||
light::LightTraits get_traits() override;
|
||||
void set_output(output::FloatOutput *output) { output_ = output; }
|
||||
void write_state(light::LightState *state) override;
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
output::FloatOutput *output_;
|
||||
};
|
||||
|
||||
} //namespace empty_light
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import light, output
|
||||
from esphome.components.light import LightType
|
||||
from esphome.const import CONF_OUTPUT_ID, CONF_OUTPUT
|
||||
|
||||
empty_light_ns = cg.esphome_ns.namespace("empty_light")
|
||||
EmptyLightOutput = empty_light_ns.class_("EmptyLightOutput", light.LightOutput)
|
||||
|
||||
CONFIG_SCHEMA = light.light_schema(
|
||||
EmptyLightOutput, type_=LightType.BRIGHTNESS_ONLY
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.FloatOutput),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await light.new_light(config)
|
||||
out = await cg.get_variable(config[CONF_OUTPUT])
|
||||
cg.add(var.set_output(out))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
sensor:
|
||||
- platform: empty_sensor
|
||||
name: Empty sensor
|
||||
```
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_sensor {
|
||||
|
||||
static const char *TAG = "empty_sensor.sensor";
|
||||
|
||||
void EmptySensor::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySensor::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySensor::update() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySensor::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Empty sensor");
|
||||
}
|
||||
|
||||
} //namespace empty_sensor
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_sensor {
|
||||
|
||||
class EmptySensor : public sensor::Sensor, public PollingComponent {
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void update() override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
} //namespace empty_sensor
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import UNIT_EMPTY, ICON_EMPTY
|
||||
|
||||
empty_sensor_ns = cg.esphome_ns.namespace("empty_sensor")
|
||||
EmptySensor = empty_sensor_ns.class_("EmptySensor", cg.PollingComponent)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
EmptySensor,
|
||||
unit_of_measurement=UNIT_EMPTY,
|
||||
icon=ICON_EMPTY,
|
||||
accuracy_decimals=1,
|
||||
).extend(cv.polling_component_schema("60s"))
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
empty_sensor_hub:
|
||||
id: empty_sensor_hub_1
|
||||
|
||||
sensor:
|
||||
- platform: empty_sensor_hub
|
||||
name: Sensor for empty sensor hub 1
|
||||
empty_sensor_hub_id: empty_sensor_hub_1
|
||||
|
||||
- platform: empty_sensor_hub
|
||||
name: Sensor for empty sensor hub 2
|
||||
empty_sensor_hub_id: empty_sensor_hub_1
|
||||
|
||||
text_sensor:
|
||||
- platform: empty_sensor_hub
|
||||
name: Text sensor for empty sensor hub 1
|
||||
empty_sensor_hub_id: empty_sensor_hub_1
|
||||
|
||||
- platform: empty_sensor_hub
|
||||
name: Text sensor for empty sensor hub 2
|
||||
empty_sensor_hub_id: empty_sensor_hub_1
|
||||
|
||||
binary_sensor:
|
||||
- platform: empty_sensor_hub
|
||||
name: Binary sensor for empty sensor hub 1
|
||||
empty_sensor_hub_id: empty_sensor_hub_1
|
||||
|
||||
- platform: empty_sensor_hub
|
||||
name: Binary sensor for empty sensor hub 2
|
||||
empty_sensor_hub_id: empty_sensor_hub_1
|
||||
```
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_EMPTY_SENSOR_HUB_ID = "empty_sensor_hub_id"
|
||||
|
||||
empty_sensor_hub_ns = cg.esphome_ns.namespace("empty_sensor_hub")
|
||||
EmptySensorHub = empty_sensor_hub_ns.class_("EmptySensorHub", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptySensorHub),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_ID
|
||||
from . import EmptySensorHub, CONF_EMPTY_SENSOR_HUB_ID
|
||||
|
||||
DEPENDENCIES = ["empty_sensor_hub"]
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
binary_sensor.binary_sensor_schema()
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_EMPTY_SENSOR_HUB_ID): cv.use_id(EmptySensorHub),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
paren = await cg.get_variable(config[CONF_EMPTY_SENSOR_HUB_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await binary_sensor.register_binary_sensor(var, config)
|
||||
cg.add(paren.register_binary_sensor(var))
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#include "empty_sensor_hub.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_sensor_hub {
|
||||
|
||||
static const char *TAG = "empty_sensor_hub.component";
|
||||
|
||||
void EmptySensorHub::setup(){
|
||||
|
||||
}
|
||||
|
||||
void EmptySensorHub::dump_config(){
|
||||
for (auto *sensor : this->sensors_) {
|
||||
LOG_SENSOR(" ", "Sensor", sensor);
|
||||
}
|
||||
|
||||
for(auto *text_sensor : this->text_sensors_){
|
||||
LOG_TEXT_SENSOR(" ", "Text sensor", text_sensor);
|
||||
}
|
||||
|
||||
for(auto *binary_sensor : this->binary_sensors_){
|
||||
LOG_BINARY_SENSOR(" ", "Binary sensor", binary_sensor);
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace empty_sensor_hub
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_sensor_hub {
|
||||
|
||||
class EmptySensorHub : public Component {
|
||||
public:
|
||||
void register_sensor(sensor::Sensor *obj) { this->sensors_.push_back(obj); }
|
||||
void register_text_sensor(text_sensor::TextSensor *obj) { this->text_sensors_.push_back(obj); }
|
||||
void register_binary_sensor(binary_sensor::BinarySensor *obj) { this->binary_sensors_.push_back(obj); }
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
|
||||
protected:
|
||||
std::vector<sensor::Sensor *> sensors_;
|
||||
std::vector<text_sensor::TextSensor *> text_sensors_;
|
||||
std::vector<binary_sensor::BinarySensor *> binary_sensors_;
|
||||
};
|
||||
|
||||
} //namespace empty_sensor_hub
|
||||
} //namespace esphome
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, UNIT_EMPTY, ICON_EMPTY
|
||||
from . import EmptySensorHub, CONF_EMPTY_SENSOR_HUB_ID
|
||||
|
||||
DEPENDENCIES = ["empty_sensor_hub"]
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_EMPTY, icon=ICON_EMPTY, accuracy_decimals=1
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_EMPTY_SENSOR_HUB_ID): cv.use_id(EmptySensorHub),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
paren = await cg.get_variable(config[CONF_EMPTY_SENSOR_HUB_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await sensor.register_sensor(var, config)
|
||||
cg.add(paren.register_sensor(var))
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import text_sensor
|
||||
from esphome.const import CONF_ID
|
||||
from . import EmptySensorHub, CONF_EMPTY_SENSOR_HUB_ID
|
||||
|
||||
DEPENDENCIES = ["empty_sensor_hub"]
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
text_sensor.text_sensor_schema()
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_EMPTY_SENSOR_HUB_ID): cv.use_id(EmptySensorHub),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
paren = await cg.get_variable(config[CONF_EMPTY_SENSOR_HUB_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await text_sensor.register_text_sensor(var, config)
|
||||
cg.add(paren.register_text_sensor(var))
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
empty_spi_component:
|
||||
id: empty_spi_component_1
|
||||
cs_pin: D8
|
||||
|
||||
spi:
|
||||
clk_pin: D5
|
||||
miso_pin: D6
|
||||
```
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import spi
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
empty_spi_component_ns = cg.esphome_ns.namespace("empty_spi_component")
|
||||
EmptySPIComponent = empty_spi_component_ns.class_(
|
||||
"EmptySPIComponent", cg.Component, spi.SPIDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EmptySPIComponent),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(spi.spi_device_schema(cs_pin_required=True))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await spi.register_spi_device(var, config)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_spi_component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_spi_component {
|
||||
|
||||
static const char *TAG = "empty_spi_component.component";
|
||||
|
||||
void EmptySPIComponent::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySPIComponent::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySPIComponent::dump_config(){
|
||||
ESP_LOGCONFIG(TAG, "Empty SPI component");
|
||||
}
|
||||
|
||||
} // namespace empty_spi_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/spi/spi.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_spi_component {
|
||||
|
||||
class EmptySPIComponent : public Component,
|
||||
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST,spi::CLOCK_POLARITY_LOW,
|
||||
spi::CLOCK_PHASE_LEADING,spi::DATA_RATE_1KHZ> {
|
||||
public:
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
|
||||
} // namespace empty_spi_component
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
sensor:
|
||||
- platform: empty_spi_sensor
|
||||
name: Empty SPI sensor
|
||||
cs_pin: D8
|
||||
|
||||
spi:
|
||||
clk_pin: D5
|
||||
miso_pin: D6
|
||||
```
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#include "esphome/core/log.h"
|
||||
#include "empty_spi_sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_spi_sensor {
|
||||
|
||||
static const char *TAG = "empty_spi_sensor.sensor";
|
||||
|
||||
void EmptySPISensor::setup() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySPISensor::update() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySPISensor::loop() {
|
||||
|
||||
}
|
||||
|
||||
void EmptySPISensor::dump_config(){
|
||||
ESP_LOGCONFIG(TAG, "Empty SPI sensor");
|
||||
}
|
||||
|
||||
} // namespace empty_spi_sensor
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/spi/spi.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace empty_spi_sensor {
|
||||
|
||||
class EmptySPISensor : public sensor::Sensor,
|
||||
public PollingComponent,
|
||||
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
|
||||
spi::DATA_RATE_1KHZ> {
|
||||
public:
|
||||
void setup() override;
|
||||
void update() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
};
|
||||
|
||||
} // namespace empty_spi_sensor
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import spi, sensor
|
||||
from esphome.const import ICON_EMPTY, UNIT_EMPTY
|
||||
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
empty_spi_sensor_ns = cg.esphome_ns.namespace("empty_spi_sensor")
|
||||
EmptySPISensor = empty_spi_sensor_ns.class_(
|
||||
"EmptySPISensor", cg.PollingComponent, spi.SPIDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
EmptySPISensor,
|
||||
unit_of_measurement=UNIT_EMPTY,
|
||||
icon=ICON_EMPTY,
|
||||
accuracy_decimals=1,
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
await spi.register_spi_device(var, config)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
```yaml
|
||||
# example configuration:
|
||||
|
||||
switch:
|
||||
- platform: empty_switch
|
||||
name: Empty switch
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue