initial commit

This commit is contained in:
Salvatore Carotenuto 2025-06-22 16:02:04 +02:00
commit 26604c8c57
7481 changed files with 489518 additions and 0 deletions

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
View 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
View 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.

View 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.

View 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.

View file

View file

View file

View file

View 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"));
}

View file

View file

View file

View file

View file

View file

View 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

View 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 .

View 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

View 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

View 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/)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,7 @@
```yaml
# example configuration:
output:
- platform: empty_binary_output
id: empty_binary_output_1
```

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,7 @@
```yaml
# example configuration:
binary_sensor:
- platform: empty_binary_sensor
name: Empty binary sensor
```

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,6 @@
```yaml
# example configuration:
empty_component:
id: empty_component_1
```

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,12 @@
```yaml
# example configuration:
sensor:
- platform: empty_compound_sensor
sensor1:
name: Sensor 1
sensor2:
name: Sensor 2
sensor3:
name: Sensor 3
```

View file

@ -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

View file

@ -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

View file

@ -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))

View file

@ -0,0 +1,7 @@
```yaml
# example configuration:
cover:
platform: empty_cover
name: Empty cover
```

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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
```

View file

@ -0,0 +1,3 @@
import esphome.codegen as cg
empty_fan_ns = cg.esphome_ns.namespace('empty_fan')

View file

@ -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))

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,7 @@
```yaml
# example configuration:
output:
- platform: empty_float_output
id: empty_float_output_1
```

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,7 @@
```yaml
# example configuration:
empty_gpio_component:
id: empty_gpio_component_1
pin: 5
```

View file

@ -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))

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,11 @@
```yaml
# example configuration:
empty_i2c_component:
id: empty_i2c_component_1
address: 0x01 # optional
i2c:
sda: 4
scl: 5
```

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,11 @@
```yaml
# example configuration:
sensor:
- platform: empty_i2c_sensor
name: Empty I2C sensor
i2c:
sda: 4
scl: 5
```

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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
```

View file

@ -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

View file

@ -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

View file

@ -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))

View file

@ -0,0 +1,7 @@
```yaml
# example configuration:
sensor:
- platform: empty_sensor
name: Empty sensor
```

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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
```

View file

@ -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)

View file

@ -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))

View file

@ -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

View file

@ -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

View file

@ -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))

View file

@ -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))

View file

@ -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
```

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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
```

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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