Compare commits
7 Commits
9bebffc743
...
ba48154940
| Author | SHA1 | Date | |
|---|---|---|---|
| ba48154940 | |||
| de21cff76c | |||
| aa357b224b | |||
| a31521cdfe | |||
| f1896d5c54 | |||
| c390829f35 | |||
| 1cbb33600a |
131
platformio.ini
131
platformio.ini
@ -6,68 +6,99 @@ build.filesystem = littlefs
|
||||
lib_deps = bblanchon/ArduinoJson @ 7.4.2
|
||||
knolleary/PubSubClient
|
||||
|
||||
[Sonoff4ChPro]
|
||||
[ESP8285]
|
||||
platform = espressif8266
|
||||
board = esp8285
|
||||
build_flags = -D Sonoff4ChPro -D WIFI_HOSTNAME_FALLBACK=\"PatrixSonoff4ChPro\"
|
||||
framework = ${common.framework}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
build.filesystem = ${common.build.filesystem}
|
||||
lib_deps = ${common.lib_deps}
|
||||
board_build.ldscript = eagle.flash.1m64.ld
|
||||
|
||||
[GosundSP111]
|
||||
platform = espressif8266
|
||||
board = esp8285
|
||||
build_flags = -D GosundSP111 -D WIFI_HOSTNAME_FALLBACK=\"PatrixGosundSP111\"
|
||||
[Ch4Pro]
|
||||
platform = ${ESP8285.platform}
|
||||
board = ${ESP8285.board}
|
||||
framework = ${ESP8285.framework}
|
||||
upload_speed = ${ESP8285.upload_speed}
|
||||
monitor_speed = ${ESP8285.monitor_speed}
|
||||
build.filesystem = ${ESP8285.build.filesystem}
|
||||
lib_deps = ${ESP8285.lib_deps}
|
||||
board_build.ldscript = ${ESP8285.board_build.ldscript}
|
||||
build_flags = -D Ch4Pro
|
||||
|
||||
[SP111]
|
||||
platform = ${ESP8285.platform}
|
||||
board = ${ESP8285.board}
|
||||
framework = ${ESP8285.framework}
|
||||
upload_speed = ${ESP8285.upload_speed}
|
||||
monitor_speed = ${ESP8285.monitor_speed}
|
||||
build.filesystem = ${ESP8285.build.filesystem}
|
||||
lib_deps = ${ESP8285.lib_deps}
|
||||
board_build.ldscript = ${ESP8285.board_build.ldscript}
|
||||
build_flags = -D SP111
|
||||
|
||||
[ESP32_TEST]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = ${common.framework}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
build_type = debug
|
||||
debug_tool = esp-prog
|
||||
monitor_filters = esp32_exception_decoder
|
||||
build.filesystem = ${common.build.filesystem}
|
||||
lib_deps = ${common.lib_deps}
|
||||
build_flags = -D ESP32_TESTBOARD -D CORE_DEBUG_LEVEL=0
|
||||
|
||||
[env:Sonoff4ChPro]
|
||||
platform = ${Sonoff4ChPro.platform}
|
||||
board = ${Sonoff4ChPro.board}
|
||||
framework = ${common.framework}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
build.filesystem = ${common.build.filesystem}
|
||||
lib_deps = ${common.lib_deps}
|
||||
[env:ESP32_Ch4Pro]
|
||||
platform = ${ESP32_TEST.platform}
|
||||
board = ${ESP32_TEST.board}
|
||||
framework = ${ESP32_TEST.framework}
|
||||
upload_speed = ${ESP32_TEST.upload_speed}
|
||||
monitor_speed = ${ESP32_TEST.monitor_speed}
|
||||
build_type = ${ESP32_TEST.build_type}
|
||||
debug_tool = ${ESP32_TEST.debug_tool}
|
||||
monitor_filters = ${ESP32_TEST.monitor_filters}
|
||||
build.filesystem = ${ESP32_TEST.build.filesystem}
|
||||
lib_deps = ${ESP32_TEST.lib_deps}
|
||||
build_flags = ${Ch4Pro.build_flags} -D WIFI_HOSTNAME_FALLBACK=\"ESP32_Test_Ch4Pro\" ${ESP32_TEST.build_flags}
|
||||
|
||||
[env:ESP32_SP111]
|
||||
platform = ${ESP32_TEST.platform}
|
||||
board = ${ESP32_TEST.board}
|
||||
framework = ${ESP32_TEST.framework}
|
||||
upload_speed = ${ESP32_TEST.upload_speed}
|
||||
monitor_speed = ${ESP32_TEST.monitor_speed}
|
||||
build_type = ${ESP32_TEST.build_type}
|
||||
debug_tool = ${ESP32_TEST.debug_tool}
|
||||
monitor_filters = ${ESP32_TEST.monitor_filters}
|
||||
build.filesystem = ${ESP32_TEST.build.filesystem}
|
||||
lib_deps = ${ESP32_TEST.lib_deps}
|
||||
build_flags = ${SP111.build_flags} -D WIFI_HOSTNAME_FALLBACK=\"ESP32_Test_SP111\" ${ESP32_TEST.build_flags}
|
||||
|
||||
[env:Gewaechshaus]
|
||||
platform = ${Ch4Pro.platform}
|
||||
board = ${Ch4Pro.board}
|
||||
framework = ${Ch4Pro.framework}
|
||||
upload_speed = ${Ch4Pro.upload_speed}
|
||||
monitor_speed = ${Ch4Pro.monitor_speed}
|
||||
build.filesystem = ${Ch4Pro.build.filesystem}
|
||||
lib_deps = ${Ch4Pro.lib_deps}
|
||||
board_build.ldscript = ${Ch4Pro.board_build.ldscript}
|
||||
build_flags = ${Ch4Pro.build_flags} -D WIFI_HOSTNAME_FALLBACK=\"Gewaechshaus\"
|
||||
upload_protocol = espota
|
||||
upload_port = 10.0.0.178
|
||||
build_flags = ${Sonoff4ChPro.build_flags}
|
||||
|
||||
[env:Sonoff4ChPro_ESP32]
|
||||
platform = ${ESP32_TEST.platform}
|
||||
board = ${ESP32_TEST.board}
|
||||
framework = ${common.framework}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
build_type = ${ESP32_TEST.build_type}
|
||||
debug_tool = ${ESP32_TEST.debug_tool}
|
||||
monitor_filters = ${ESP32_TEST.monitor_filters}
|
||||
build.filesystem = ${common.build.filesystem}
|
||||
lib_deps = ${common.lib_deps}
|
||||
build_flags = ${Sonoff4ChPro.build_flags} ${ESP32_TEST.build_flags}
|
||||
|
||||
[env:GosundSP111]
|
||||
platform = ${GosundSP111.platform}
|
||||
board = ${GosundSP111.board}
|
||||
framework = ${common.framework}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
build.filesystem = ${common.build.filesystem}
|
||||
lib_deps = ${common.lib_deps}
|
||||
build_flags = ${GosundSP111.build_flags}
|
||||
|
||||
[env:GosundSP111_ESP32]
|
||||
platform = ${ESP32_TEST.platform}
|
||||
board = ${ESP32_TEST.board}
|
||||
framework = ${common.framework}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
build_type = ${ESP32_TEST.build_type}
|
||||
debug_tool = ${ESP32_TEST.debug_tool}
|
||||
monitor_filters = ${ESP32_TEST.monitor_filters}
|
||||
build.filesystem = ${common.build.filesystem}
|
||||
lib_deps = ${common.lib_deps}
|
||||
build_flags = ${GosundSP111.build_flags} ${ESP32_TEST.build_flags}
|
||||
[env:Infrarotheizung]
|
||||
platform = ${SP111.platform}
|
||||
board = ${SP111.board}
|
||||
framework = ${SP111.framework}
|
||||
upload_speed = ${SP111.upload_speed}
|
||||
monitor_speed = ${SP111.monitor_speed}
|
||||
build.filesystem = ${SP111.build.filesystem}
|
||||
lib_deps = ${SP111.lib_deps}
|
||||
board_build.ldscript = ${SP111.board_build.ldscript}
|
||||
build_flags = ${SP111.build_flags} -D WIFI_HOSTNAME_FALLBACK=\"Infrarotheizung\"
|
||||
upload_protocol = espota
|
||||
upload_port = 10.0.0.179
|
||||
|
||||
41
src/Property.h
Normal file
41
src/Property.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef PROPERTY_H
|
||||
#define PROPERTY_H
|
||||
|
||||
#include <LittleFS.h>
|
||||
|
||||
template<class T>
|
||||
class Property {
|
||||
|
||||
public:
|
||||
|
||||
const String path;
|
||||
|
||||
T fallback;
|
||||
|
||||
void load() {
|
||||
String content = "";
|
||||
if (auto file = LittleFS.open(path, "r")) {
|
||||
content = file.readString();
|
||||
file.close();
|
||||
}
|
||||
value = toValue(content);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
T value;
|
||||
|
||||
explicit Property(const String &path, const T fallback)
|
||||
: path(path),
|
||||
fallback(fallback),
|
||||
value(fallback) {
|
||||
//
|
||||
}
|
||||
|
||||
virtual ~Property() = default;
|
||||
|
||||
virtual T toValue(const String &content) =0;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
34
src/PropertyBool.h
Normal file
34
src/PropertyBool.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef PROPERTY_BOOL_H
|
||||
#define PROPERTY_BOOL_H
|
||||
|
||||
#include <Property.h>
|
||||
|
||||
class PropertyBool final : public Property<bool> {
|
||||
|
||||
public:
|
||||
|
||||
PropertyBool(const String &name, const bool fallback)
|
||||
: Property(name, fallback) {
|
||||
//
|
||||
}
|
||||
|
||||
// ReSharper disable once CppNonExplicitConversionOperator
|
||||
operator bool() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
bool toValue(const String &content) override {
|
||||
if (content == "true") {
|
||||
return true;
|
||||
}
|
||||
if (content == "false") {
|
||||
return false;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
28
src/PropertyLong.h
Normal file
28
src/PropertyLong.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef PROPERTY_LONG_H
|
||||
#define PROPERTY_LONG_H
|
||||
|
||||
#include <Property.h>
|
||||
|
||||
class PropertyLong final : public Property<long> {
|
||||
|
||||
public:
|
||||
|
||||
PropertyLong(const String &name, const long fallback)
|
||||
: Property(name, fallback) {
|
||||
//
|
||||
}
|
||||
|
||||
// ReSharper disable once CppNonExplicitConversionOperator
|
||||
operator long() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
long toValue(const String &content) override {
|
||||
return content.toInt();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
169
src/Relay2.h
Normal file
169
src/Relay2.h
Normal file
@ -0,0 +1,169 @@
|
||||
#ifndef RELAY2_H
|
||||
#define RELAY2_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "PropertyBool.h"
|
||||
#include "PropertyLong.h"
|
||||
|
||||
class Relay2 {
|
||||
|
||||
bool state = false;
|
||||
|
||||
unsigned long stateSince = 0;
|
||||
|
||||
unsigned long manualSince = 0;
|
||||
|
||||
public:
|
||||
|
||||
const int index;
|
||||
|
||||
const int pin;
|
||||
|
||||
const bool inverted;
|
||||
|
||||
String prefix;
|
||||
|
||||
PropertyBool initialState;
|
||||
|
||||
PropertyBool maxOnEnabled;
|
||||
|
||||
PropertyLong maxOnSeconds;
|
||||
|
||||
PropertyBool maxOffEnabled;
|
||||
|
||||
PropertyLong maxOffSeconds;
|
||||
|
||||
PropertyBool buttonOnEnabled;
|
||||
|
||||
PropertyLong buttonOnSeconds;
|
||||
|
||||
PropertyBool buttonOffEnabled;
|
||||
|
||||
PropertyLong buttonOffSeconds;
|
||||
|
||||
PropertyBool powerOnEnabled;
|
||||
|
||||
PropertyLong powerOnThreshold;
|
||||
|
||||
PropertyLong powerOnSeconds;
|
||||
|
||||
PropertyBool powerOffEnabled;
|
||||
|
||||
PropertyLong powerOffThreshold;
|
||||
|
||||
PropertyLong powerOffSeconds;
|
||||
|
||||
Relay2(const int index, const int pin, const bool inverted)
|
||||
: index(index),
|
||||
pin(pin),
|
||||
inverted(inverted),
|
||||
prefix("/relay" + String(index)),
|
||||
initialState(prefix + "initialState", false),
|
||||
maxOnEnabled(prefix + "maxOnEnabled", false),
|
||||
maxOnSeconds(prefix + "maxOnSeconds", 0),
|
||||
maxOffEnabled(prefix + "maxOffEnabled", false),
|
||||
maxOffSeconds(prefix + "maxOffSeconds", 0),
|
||||
buttonOnEnabled(prefix + "buttonOnEnabled", false),
|
||||
buttonOnSeconds(prefix + "buttonOnSeconds", 0),
|
||||
buttonOffEnabled(prefix + "buttonOffEnabled", false),
|
||||
buttonOffSeconds(prefix + "buttonOffSeconds", 0),
|
||||
powerOnEnabled(prefix + "powerOnEnabled", false),
|
||||
powerOnThreshold(prefix + "powerOnThreshold", 0),
|
||||
powerOnSeconds(prefix + "powerOnSeconds", 0),
|
||||
powerOffEnabled(prefix + "powerOffEnabled", false),
|
||||
powerOffThreshold(prefix + "powerOffThreshold", 0),
|
||||
powerOffSeconds(prefix + "powerOffSeconds", 0) {
|
||||
//
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(pin, OUTPUT);
|
||||
|
||||
load();
|
||||
|
||||
state = !initialState;
|
||||
setState(initialState, false);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
const auto stateAge = millis() - stateSince;
|
||||
loopMax(stateAge);
|
||||
if (manualSince > 0) {
|
||||
loopManual(stateAge);
|
||||
} else {
|
||||
loopPower(stateAge);
|
||||
}
|
||||
}
|
||||
|
||||
bool getState() const {
|
||||
return state;
|
||||
}
|
||||
|
||||
void setManual(const bool newState) {
|
||||
setState(newState, false);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void setState(const bool newState, const bool manual) {
|
||||
if (manual) {
|
||||
manualSince = max(1UL, millis());
|
||||
} else {
|
||||
manualSince = 0;
|
||||
}
|
||||
if (state != newState) {
|
||||
info("[RELAY%d] %s", index, state ? "ON" : "OFF");
|
||||
state = newState;
|
||||
stateSince = millis();
|
||||
digitalWrite(pin, state ^ inverted ? HIGH : LOW);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void loopMax(const long stateAge) {
|
||||
if (state && maxOnEnabled && maxOnSeconds && stateAge >= maxOnSeconds) {
|
||||
setState(false, false);
|
||||
}
|
||||
if (!state && maxOffEnabled && maxOffSeconds && stateAge >= maxOffSeconds) {
|
||||
setState(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void loopManual(const long stateAge) {
|
||||
if (state && buttonOnEnabled && buttonOnSeconds && stateAge >= buttonOnSeconds) {
|
||||
setState(false, false);
|
||||
}
|
||||
if (!state && buttonOffEnabled && buttonOffSeconds && stateAge >= buttonOffSeconds) {
|
||||
setState(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void loopPower(const long stateAge) {
|
||||
const auto valid = !isnan(gridPowerDeltaValue) && millis() - gridPowerDeltaMillis <= 10000;
|
||||
// TODO
|
||||
}
|
||||
|
||||
void load() {
|
||||
initialState.load();
|
||||
maxOnEnabled.load();
|
||||
maxOnSeconds.load();
|
||||
maxOffEnabled.load();
|
||||
maxOffSeconds.load();
|
||||
buttonOnEnabled.load();
|
||||
buttonOnSeconds.load();
|
||||
buttonOffEnabled.load();
|
||||
buttonOffSeconds.load();
|
||||
powerOnEnabled.load();
|
||||
powerOnThreshold.load();
|
||||
powerOnSeconds.load();
|
||||
powerOffEnabled.load();
|
||||
powerOffThreshold.load();
|
||||
powerOffSeconds.load();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -95,7 +95,7 @@ void httpStatus() {
|
||||
|
||||
const auto relays = json["relays"].to<JsonArray>();
|
||||
relay0.json(relays.add<JsonObject>());
|
||||
#ifdef Sonoff4ChPro
|
||||
#ifdef Ch4Pro
|
||||
relay1.json(relays.add<JsonObject>());
|
||||
relay2.json(relays.add<JsonObject>());
|
||||
relay3.json(relays.add<JsonObject>());
|
||||
@ -117,7 +117,7 @@ void httpSet() {
|
||||
httpString("mqttPassword", mqttSetPassword);
|
||||
|
||||
httpRelay(0, relay0);
|
||||
#ifdef Sonoff4ChPro
|
||||
#ifdef Ch4Pro
|
||||
httpRelay(1, relay1);
|
||||
httpRelay(2, relay2);
|
||||
httpRelay(3, relay3);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "io.h"
|
||||
|
||||
#ifdef GosundSP111
|
||||
#ifdef SP111
|
||||
|
||||
#ifndef ESP32_TESTBOARD
|
||||
#define STATUS_PIN 0
|
||||
@ -11,13 +11,13 @@ Button button0(13, true, true, [](const ButtonEvent event) { buttonCallback(rela
|
||||
|
||||
Relay relay0(0, "fallback/relay0", "RELAY #0", 15, false, true);
|
||||
|
||||
#ifdef GosundSP111
|
||||
#ifdef SP111
|
||||
Output relay0Led("relay0Led", 2, true, false);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef Sonoff4ChPro
|
||||
#ifdef Ch4Pro
|
||||
|
||||
#ifndef ESP32_TESTBOARD
|
||||
#define STATUS_PIN 13
|
||||
|
||||
15
src/io.h
15
src/io.h
@ -3,6 +3,7 @@
|
||||
|
||||
#include "Relay.h"
|
||||
#include "Button.h"
|
||||
#include "Relay2.h"
|
||||
|
||||
void buttonCallback(Output &output, ButtonEvent event);
|
||||
|
||||
@ -10,13 +11,15 @@ extern Output status;
|
||||
|
||||
extern Button button0;
|
||||
|
||||
extern Relay2 relay99;
|
||||
|
||||
extern Relay relay0;
|
||||
|
||||
#ifdef GosundSP111
|
||||
#ifdef SP111
|
||||
extern Output relay0Led;
|
||||
#endif
|
||||
|
||||
#ifdef Sonoff4ChPro
|
||||
#ifdef Ch4Pro
|
||||
|
||||
extern Button button1;
|
||||
|
||||
@ -36,10 +39,10 @@ inline void ioSetup() {
|
||||
status.setup();
|
||||
button0.setup();
|
||||
relay0.setup();
|
||||
#ifdef GosundSP111
|
||||
#ifdef SP111
|
||||
relay0Led.setup();
|
||||
#endif
|
||||
#ifdef Sonoff4ChPro
|
||||
#ifdef Ch4Pro
|
||||
button1.setup();
|
||||
button2.setup();
|
||||
button3.setup();
|
||||
@ -53,11 +56,11 @@ inline void ioLoop() {
|
||||
status.loop();
|
||||
button0.loop();
|
||||
relay0.loop();
|
||||
#ifdef GosundSP111
|
||||
#ifdef SP111
|
||||
relay0Led.set(relay0.get());
|
||||
relay0Led.loop();
|
||||
#endif
|
||||
#ifdef Sonoff4ChPro
|
||||
#ifdef Ch4Pro
|
||||
button1.loop();
|
||||
button2.loop();
|
||||
button3.loop();
|
||||
|
||||
13
src/log.cpp
Normal file
13
src/log.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "log.h"
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
#include <cstdio>
|
||||
|
||||
void info(const char *format, ...) {
|
||||
char message[512];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(message, sizeof(message), format, args);
|
||||
Serial.println(message);
|
||||
va_end(args);
|
||||
}
|
||||
6
src/log.h
Normal file
6
src/log.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
void info(const char *format, ...);
|
||||
|
||||
#endif
|
||||
@ -7,8 +7,10 @@ minify index.html | sed 's|http://10.42.0.204||g' > index.html.min || exit 2
|
||||
#curl -s 'http://10.42.0.204/upload/index' -F "file=@index.html.min"
|
||||
#curl -s 'http://10.42.0.204/upload/icon' -F "file=@icon.svg"
|
||||
|
||||
#curl -s 'http://10.0.0.178/upload/index' -F "file=@index.html.min"
|
||||
# Greenhouse
|
||||
curl -s 'http://10.0.0.178/upload/index' -F "file=@index.html.min"
|
||||
#curl -s 'http://10.0.0.178/upload/icon' -F "file=@icon.svg"
|
||||
|
||||
curl -s 'http://10.0.0.179/upload/index' -F "file=@index.html.min"
|
||||
# InfraredHeater
|
||||
#curl -s 'http://10.0.0.179/upload/index' -F "file=@index.html.min"
|
||||
#curl -s 'http://10.0.0.179/upload/icon' -F "file=@icon.svg"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user