Hello!
I have searched through the forums and other parts of the Internet (e.g. Home Assistant and ESPHome), but cannot find any information of how to config multiple types of sensors AND a controller (which is a single instance!) simultaneously.
Basically I have a custom board that has an ESP32 that should run an Arduino “sketch” as the RelayController. This class has the setup() and loop() functions to be called upon creation and execution in the same way it is normally done when not using ESPHome.
The RelaySwitches and RelaySensors classes needs to access the getUpdatedMessage() function from the singleton RelayController instance whenever their update() function is called to get the latest values from the RelayController.
The question I have is how to use my class RelayController in the yaml configuration file to implement this? I suppose the RelayController must be registered as a component somehow for the setup() and loop() functions to work properly? Maybe I have missed a better way to set this up in ESPHome?
I have good knowledge of Arduino programming in general but I just cannot get my head around the ESPHome configuration in order to add the sensors for Home Assistant in this case.
I hope that you guys can help me out here? All help and suggestions are welcome!
Thanks!
esp-controller.yaml
esphome:
name: esp-controller
includes:
- relay-controller.h
- relay-sensors.h
- relay-switches.h
libraries:
- Wire
- LiquidCrystal_I2C
esp32:
board: esp32dev
framework:
type: arduino
wifi:
ssid: !secret wwww
password: !secret pppp
logger:
level: INFO
baud_rate: 0
api:
password: !secret xxxx
ota:
password: !secret yyyy
sensor:
- platform: custom
lambda: |-
auto relay_sensors = new RelaySensors();
App.register_component(relay_sensors);
return {
relay_sensors->outdoorBrightness
};
sensors:
- name: "Outdoor brightness"
id: relay_controller_outdoor_brightness
unit_of_measurement: lx
device_class: "illuminance"
state_class: "measurement"
accuracy_decimals: 0
binary_sensor:
- platform: custom
lambda: |-
auto relay_switches = new RelaySwitches();
App.register_component(relay_switches);
return {
relay_switches->relay_1
};
binary_sensors:
- name: "Relay 1"
id: relay_controller_relay_1
device_class: "light"
I suppose the RelayController must be registered as a component somehow in this yaml-file to call the setup() and loop() functions? How do I do this?
I guess something similar to this:
RelayController &relay_controller = RelayController::getInstance();
App.register_component(relay_controller);
relay-controller.h
#include "esphome.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
class Message {
public:
double outdoorBrightness;
bool relay_1;
};
class RelayController : public Component {
private:
// Singleton!
RelayController() {}
public:
static RelayController& getInstance() {
static RelayController instance;
return instance;
}
// Preventing copies of the singleton appearing.
RelayController(RelayController const& copy) = delete;
void operator=(RelayController const& copy) = delete;
void setup() override {
ESP_LOGI("exe", " >> SETUP Relay Controller ...");
}
void loop() override {
// Do a lot of exiting stuff .... :)
}
Message getUpdatedMessage() {
ESP_LOGI("exe", " > Getting Updated Message ...");
// Hardcoded example!
Message message = Message();
message.outdoorBrightness = 1234;
message.relay_1 = true;
return message;
}
}
relay-sensors.h
class RelaySensors : public PollingComponent, public Sensor {
public:
Sensor *outdoorBrightness = new Sensor();
RelayController &theRelayController = RelayController::getInstance();
RelaySensors() : PollingComponent(15000) {
}
float get_setup_priority() const override { return esphome::setup_priority::HARDWARE; }
void setup() override {
ESP_LOGI("exe", " >> SETUP Relay Sensors ...");
}
void update() override {
ESP_LOGI("exe", " > Publishing Relay Sensors ...");
Message message = theRelayController.getUpdatedMessage();
publishSensors(&message);
}
private:
void publishSensors(Message* message) {
outdoorBrightness->publish_state(message->outdoorBrightness);
}
};
relay-switches.h
class RelaySwitches : public PollingComponent, public BinarySensor {
public:
RelayController &theRelayController = RelayController::getInstance();
BinarySensor *relay_1 = new BinarySensor();
RelaySwitches() : PollingComponent(15000) {
}
float get_setup_priority() const override { return esphome::setup_priority::HARDWARE; }
void setup() override {
ESP_LOGI("exe", " >> SETUP Relay Switches ...");
}
void update() override {
ESP_LOGI("exe", " > Publishing Relay Switches ...");
Message message = theRelayController.getUpdatedMessage();
publishSensors(&message);
}
private:
void publishSensors(Message* message) {
relay_1->publish_state(message->relay_1);
}
};