Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master #2494

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Master #2494

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ struct CONFIG_T {

INVERTER_CONFIG_T Inverter[INV_MAX_COUNT];
char Dev_PinMapping[DEV_MAX_MAPPING_NAME_STRLEN + 1];

struct {
bool R01;
bool R02;
} Relay;

};

class ConfigurationClass {
Expand Down
1 change: 1 addition & 0 deletions include/MqttHandleHass.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class MqttHandleHassClass {
void publishInverterButton(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* deviceClass, const char* subTopic, const char* payload);
void publishInverterNumber(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* commandTopic, const char* stateTopic, const char* unitOfMeasure, const int16_t min = 1, const int16_t max = 100, float step = 1.0);
void publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off);
void publishBinarySensor(const char* caption, const char* subTopic, const char* payload_on, const char* payload_off);

static void createInverterInfo(JsonDocument& doc, std::shared_ptr<InverterAbstract> inv);
static void createDtuInfo(JsonDocument& doc);
Expand Down
5 changes: 4 additions & 1 deletion include/PinMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ struct PinMapping_t {
uint8_t display_cs;
uint8_t display_reset;
int8_t led[PINMAPPING_LED_COUNT];

uint8_t relay_r01;
uint8_t relay_r02;
};

class PinMappingClass {
Expand All @@ -55,4 +58,4 @@ class PinMappingClass {
PinMapping_t _pinMapping;
};

extern PinMappingClass PinMapping;
extern PinMappingClass PinMapping;
24 changes: 24 additions & 0 deletions include/Relay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "PinMapping.h"
#include <TaskSchedulerDeclarations.h>
#include <TimeoutHelper.h>

class Relay
{
public:
static const uint8_t ON = 0; //!< Relay state: on.
static const uint8_t OFF = 1; //!< Relay state: off.

Relay(uint8_t pin);
void on(); //!< Turns the relay on.
void off(); //!< Turns the relay off.
void toggle(); //!< Toggles the relay state.
boolean isStat(); //!< @return True iff the relay is on.

uint8_t getState(); //!< @return The current relay state (Relay::OFF or Relay::ON).
void setState(uint8_t state //!< The new state to switch to (Relay::OFF or Relay::ON).
); //!< Sets a relay state.

protected:
uint8_t _state; //!< state model
uint8_t _pin; //!< pin model
};
2 changes: 2 additions & 0 deletions include/WebApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "WebApi_ntp.h"
#include "WebApi_power.h"
#include "WebApi_prometheus.h"
#include "WebApi_relay.h"
#include "WebApi_security.h"
#include "WebApi_sysstatus.h"
#include "WebApi_webapp.h"
Expand Down Expand Up @@ -65,6 +66,7 @@ class WebApiClass {
WebApiWebappClass _webApiWebapp;
WebApiWsConsoleClass _webApiWsConsole;
WebApiWsLiveClass _webApiWsLive;
WebApiRelayClass _webApiRelay;
};

extern WebApiClass WebApi;
16 changes: 16 additions & 0 deletions include/WebApi_relay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h>

class WebApiRelayClass {
public:
void init(AsyncWebServer& server, Scheduler& scheduler);

private:
void onRelayGet(AsyncWebServerRequest* request);
void onRelayPost(AsyncWebServerRequest* request);

void onAuthenticateGet(AsyncWebServerRequest* request);
};
8 changes: 8 additions & 0 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ bool ConfigurationClass::write()
}
}

JsonObject relay = device["relay"].to<JsonObject>();
relay["relay_01"] = config.Relay.R01;
relay["relay_02"] = config.Relay.R02;

if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
return false;
}
Expand Down Expand Up @@ -317,6 +321,10 @@ bool ConfigurationClass::read()
}
}

JsonArray relay = device["relay"];
config.Relay.R01 = relay["relay_01"];
config.Relay.R02 = relay["relay_02"];

f.close();
return true;
}
Expand Down
37 changes: 37 additions & 0 deletions src/MqttHandleHass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
/*
* Copyright (C) 2022-2024 Thomas Basler and others
*/
#include "Relay.h"
#include "PinMapping.h"
#include "MqttHandleHass.h"
#include "MqttHandleInverter.h"
#include "MqttSettings.h"
Expand Down Expand Up @@ -62,6 +64,7 @@ void MqttHandleHassClass::publishConfig()
publishDtuSensor("WiFi Signal", "signal_strength", "diagnostic", "", "dBm", "rssi");
publishDtuSensor("Uptime", "duration", "diagnostic", "", "s", "");
publishDtuBinarySensor("Status", "connectivity", "diagnostic", config.Mqtt.Lwt.Value_Online, config.Mqtt.Lwt.Value_Offline, config.Mqtt.Lwt.Topic);
publishBinarySensor("Relay", "status/get_relay", "1", "0");

yield();

Expand Down Expand Up @@ -289,6 +292,40 @@ void MqttHandleHassClass::publishInverterBinarySensor(std::shared_ptr<InverterAb
publish(configTopic, buffer);
}

void MqttHandleHassClass::publishBinarySensor(const char* caption, const char* subTopic, const char* payload_on, const char* payload_off)
{
String sensorId = caption;
sensorId.replace(" ", "_");
sensorId.toLowerCase();

const String configTopic = "binary_sensor/dtu_" + sensorId + "/config";

const String statTopic = MqttSettings.getPrefix() + "/" + subTopic;

JsonDocument root;

const auto& pin = PinMapping.get();
Relay Cmd_Relay_R01 = Relay(pin.relay_r01);
Relay Cmd_Relay_R02 = Relay(pin.relay_r02);

root["name"] = caption;
root["stat_t"] = statTopic;
root["pl_on"] = payload_on;
root["pl_off"] = payload_off;
root["status_R01"] = Cmd_Relay_R01.isStat();
root["status_R02"] = Cmd_Relay_R02.isStat();

createDtuInfo(root);

if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}

String buffer;
serializeJson(root, buffer);
publish(configTopic, buffer);
}

void MqttHandleHassClass::publishDtuSensor(const char* name, const char* device_class, const char* category, const char* icon, const char* unit_of_measure, const char* subTopic)
{
String id = name;
Expand Down
37 changes: 37 additions & 0 deletions src/MqttHandleInverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
/*
* Copyright (C) 2022-2024 Thomas Basler and others
*/
#include "Relay.h"
#include "PinMapping.h"
#include "MqttHandleInverter.h"
#include "MessageOutput.h"
#include "MqttSettings.h"
Expand All @@ -14,6 +16,9 @@
#define TOPIC_SUB_POWER "power"
#define TOPIC_SUB_RESTART "restart"

#define TOPIC_SUB_RELAY_R01 "Relay R01"
#define TOPIC_SUB_RELAY_R02 "Relay R02"

#define PUBLISH_MAX_INTERVAL 60000

MqttHandleInverterClass MqttHandleInverter;
Expand Down Expand Up @@ -150,6 +155,10 @@ void MqttHandleInverterClass::onMqttMessage(const espMqttClientTypes::MessagePro
{
const CONFIG_T& config = Configuration.get();

const auto& pin = PinMapping.get();
Relay Cmd_Relay_R01 = Relay(pin.relay_r01);
Relay Cmd_Relay_R02 = Relay(pin.relay_r02);

char token_topic[MQTT_MAX_TOPIC_STRLEN + 40]; // respect all subtopics
strncpy(token_topic, topic, MQTT_MAX_TOPIC_STRLEN + 40); // convert const char* to char*

Expand Down Expand Up @@ -232,6 +241,27 @@ void MqttHandleInverterClass::onMqttMessage(const espMqttClientTypes::MessagePro
} else {
MessageOutput.println("Ignored because retained or numeric value not '1'");
}
} else if (!strcmp(setting, TOPIC_SUB_RELAY_R01)) {
// Turn relay on or off
MessageOutput.printf("Set relay R01 to: %d\r\n", int(payload_val));
//Relay Cmd_Relay_R01 = Relay(pin.relay_r01);
if (payload_val == 1) {
Cmd_Relay_R01.on();
}
else {
Cmd_Relay_R01.off();
}

} else if (!strcmp(setting, TOPIC_SUB_RELAY_R02)) {
// Turn relay on or off
MessageOutput.printf("Set relay R02 to: %d\r\n", int(payload_val));
//Relay Cmd_Relay_R02 = Relay(pin.relay_r02);
if (payload_val == 1) {
Cmd_Relay_R02.on();
}
else {
Cmd_Relay_R02.off();
}
}
}

Expand All @@ -251,6 +281,9 @@ void MqttHandleInverterClass::subscribeTopics()
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_ABSOLUTE), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_POWER), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_RESTART), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));

MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_RELAY_R01), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
MqttSettings.subscribe(String(topic + "+/cmd/" + TOPIC_SUB_RELAY_R02), 0, std::bind(&MqttHandleInverterClass::onMqttMessage, this, _1, _2, _3, _4, _5, _6));
}

void MqttHandleInverterClass::unsubscribeTopics()
Expand All @@ -262,4 +295,8 @@ void MqttHandleInverterClass::unsubscribeTopics()
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_LIMIT_NONPERSISTENT_ABSOLUTE));
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_POWER));
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_RESTART));

MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_RELAY_R01));
MqttSettings.unsubscribe(String(topic + "+/cmd/" + TOPIC_SUB_RELAY_R02));

}
14 changes: 14 additions & 0 deletions src/PinMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@
#define CMT_SDIO -1
#endif

#ifndef RELAY_R01_GPIO
#define RELAY_R01_GPIO -1
#endif

#ifndef RELAY_R02_GPIO
#define RELAY_R02_GPIO -1
#endif

PinMappingClass PinMapping;

PinMappingClass::PinMappingClass()
Expand Down Expand Up @@ -124,6 +132,9 @@ PinMappingClass::PinMappingClass()

_pinMapping.led[0] = LED0;
_pinMapping.led[1] = LED1;

_pinMapping.relay_r01 = RELAY_R01_GPIO;
_pinMapping.relay_r02 = RELAY_R02_GPIO;
}

PinMapping_t& PinMappingClass::get()
Expand Down Expand Up @@ -186,6 +197,9 @@ bool PinMappingClass::init(const String& deviceMapping)
_pinMapping.led[0] = doc[i]["led"]["led0"] | LED0;
_pinMapping.led[1] = doc[i]["led"]["led1"] | LED1;

_pinMapping.relay_r01 = doc[i]["relay"]["R01"] | RELAY_R01_GPIO;
_pinMapping.relay_r02 = doc[i]["relay"]["R02"] | RELAY_R02_GPIO;

return true;
}
}
Expand Down
56 changes: 56 additions & 0 deletions src/Relay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "Relay.h"
#include "Configuration.h"
#include "Datastore.h"
#include "MqttSettings.h"
#include "MessageOutput.h"

Relay::Relay(uint8_t pin) {
this->_pin = pin;
pinMode(pin, OUTPUT);
//digitalWrite(pin, LOW);
}

void Relay::on(void)
{
this->setState(ON); //!< explicitly set to ON
}

void Relay::off(void)
{
this->setState(OFF); //!< explicitly set to OFF
}

void Relay::toggle(void)
{
this->setState(HIGH ^ this->_state); //!< invert the state
}

uint8_t Relay::getState(void)
{
return this->_state; //!< get stored state
}

void Relay::setState(uint8_t state)
{
if (this->_state != state) { //!< check for actual state change
this->_state = (OFF == state ? OFF : ON); //!< store new state, explicitly 'casting' to ON or OFF
MessageOutput.printf("Relay Pin: ");
MessageOutput.print(_pin);
MessageOutput.print(" St:");
MessageOutput.println(_state);
digitalWrite(this->_pin, this->_state); //!< apply logic mode and set pin state
}
}

boolean Relay::isStat(void)
{
MessageOutput.print("Relay Status?");
MessageOutput.print(_pin);
MessageOutput.print(" State:");
//MessageOutput.println(!getState());
//return (ON == this->getState());
bool status = digitalRead(_pin);
MessageOutput.println(status);
return (status);
}

1 change: 1 addition & 0 deletions src/WebApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void WebApiClass::init(Scheduler& scheduler)
_webApiWebapp.init(_server, scheduler);
_webApiWsConsole.init(_server, scheduler);
_webApiWsLive.init(_server, scheduler);
_webApiRelay.init(_server, scheduler);

_server.begin();
}
Expand Down
4 changes: 4 additions & 0 deletions src/WebApi_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
led["brightness"] = config.Led_Single[i].Brightness;
}

auto RelayPinObj = curPin.createNestedObject("relay");
RelayPinObj["R01"] = pin.relay_r01;
RelayPinObj["R02"] = pin.relay_r02;

WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
}

Expand Down
Loading