A ja to rozumiem i szanuję ...
Termostat bojlera, włączający i wyłączający grzałkę, tryb AUTO i MANUAL
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Co się nauczyłem to moje. Tak już wolę. Ciągle próbuję polubić Suplę bardziej, a to forum fajnie działa i bardziej doświadczeni koledzy pomagają.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Bardzo ciekawe @lukfud, daj jakiegoś fajnego linka gdzie w prosty sposób poczytam o action handler.lukfud wrote: Fri Jun 16, 2023 7:20 amkolega @lukasz06 miał na myśli (tak mi się wydaje) warunki w kodzie.SOYER wrote: Fri Jun 16, 2023 6:22 am Robię to dla kolegi. Chciał wszystko ustawiane z apk. Nie zna się na scripts, cloud itd.
Twój szkic lekko zmodyfikowany. Nie sprawdzałem działania.Pobieranie wartości z czujnika temperatury, w przypadku DS'aCode: Select all
#include <SuplaDevice.h> #include <supla/control/relay.h> #include <supla/sensor/DS18B20.h> #include <supla/storage/eeprom.h> #include <supla/control/virtual_relay.h> #include <supla/sensor/virtual_thermometer.h> #include <supla/network/esp_wifi.h> #define DS_PIN D1 int tempON, tempOFF; Supla::Eeprom eeprom(); Supla::ESPWifi wifi("x","y"); Supla::Control::Relay *heater = nullptr; Supla::Control::VirtualRelay *vrelay = nullptr; Supla::Sensor::DS18B20 *temperature_sensor = nullptr; class RelayAsInput1; RelayAsInput1 *autoOntemperature = nullptr; class RelayAsInput; RelayAsInput *autoOfftemperature = nullptr; class RelayAsInput : public Supla::Control::VirtualRelay { //temp wył. grzałki public: explicit RelayAsInput(int step = 1) : step(step) { } virtual ~RelayAsInput() {} void onInit() override {} void turnOn(_supla_int_t duration = 0) override { (void)(duration); int newTemp = temp.getValue() + step; if (newTemp > 90) { newTemp = 90; } temp.setValue(newTemp); tempOFF = newTemp; Supla::Storage::ScheduleSave(2000); } void turnOff(_supla_int_t duration = 0) override { (void)(duration); int newTemp = temp.getValue() - step; if (newTemp <= (tempON +3)) { newTemp = tempON +3; } temp.setValue(newTemp); tempOFF = newTemp; Supla::Storage::ScheduleSave(2000); } int getValue() { return temp.getValue(); } void setValue(int value) { temp.setValue(value); Supla::Storage::ScheduleSave(2000); } void onLoadState() override { int temperature = 0; Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&temperature), sizeof(int)); temp.setValue(temperature); tempOFF = temperature; } void onSaveState() override { int temperature = temp.getValue(); Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&temperature), sizeof(int)); } protected: Supla::Sensor::VirtualThermometer temp; int step = 1; }; class RelayAsInput1 : public Supla::Control::VirtualRelay { //temp wł. grzałki public: explicit RelayAsInput1(int step = 1) : step(step) { } virtual ~RelayAsInput1() {} void onInit() override {} void turnOn(_supla_int_t duration = 0) override { (void)(duration); int newTemp = temp.getValue() + step; if (newTemp >= (tempOFF -3)) { newTemp = tempOFF -3; } temp.setValue(newTemp); tempON = newTemp; Supla::Storage::ScheduleSave(2000); } void turnOff(_supla_int_t duration = 0) override { (void)(duration); int newTemp = temp.getValue() - step; if (newTemp < 5) { newTemp = 5; } temp.setValue(newTemp); tempON = newTemp; Supla::Storage::ScheduleSave(2000); } int getValue() { return temp.getValue(); } void setValue(int value) { temp.setValue(value); Supla::Storage::ScheduleSave(2000); } void onLoadState() override { int temperature = 0; Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&temperature), sizeof(int)); temp.setValue(temperature); tempON = temperature; } void onSaveState() override { int temperature = temp.getValue(); Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&temperature), sizeof(int)); } protected: Supla::Sensor::VirtualThermometer temp; int step = 1; }; enum auto_actions { AUTO_TURN_ON, AUTO_TURN_OFF }; class addedActionsClass : public Supla::ActionHandler { public: addedActionsClass() {} void handleAction(int event, int action) { if (action == AUTO_TURN_ON && vrelay->isOn()) { heater->turnOn(); } if (action == AUTO_TURN_OFF && vrelay->isOn()) { heater->turnOff(); } } }; addedActionsClass *custAct = new addedActionsClass; void setup() { Serial.begin(115200); char GUID[SUPLA_GUID_SIZE] = {}; char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {}; heater = new Supla::Control::Relay(D5, false); vrelay = new Supla::Control::VirtualRelay(); temperature_sensor = new Supla::Sensor::DS18B20(DS_PIN); autoOntemperature = new RelayAsInput1(); autoOfftemperature = new RelayAsInput(); SuplaDevice.begin(GUID, "svrXX.supla.org", "@", AUTHKEY); temperature_sensor->addAction(AUTO_TURN_ON, custAct, OnLess(autoOntemperature->getValue())); temperature_sensor->addAction(AUTO_TURN_OFF, custAct, OnGreater(autoOfftemperature->getValue())); } void loop() { SuplaDevice.iterate(); }Code: Select all
double temperature = temperature_sensor->getChannel()->getValueDouble();
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Jeszcze jedno pytanie, dlaczego po pierwszym wgraniu szkicu z tymi RelayAsInput pierwsze wartości to zdaje się minus 200 coś, nie pamiętam, pewnie -256, zapewne ma to związek z typem zmiennej(int). Jak to na przyszłość zmienić, by inicjować do z jakąś sensowną wartością.
Dopisać wartość inicjującą tu:
void onInit() override {???}
?
Dopisać wartość inicjującą tu:
void onInit() override {???}
?
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
-
lukfud
- Posts: 2480
- Joined: Thu Nov 23, 2017 11:33 pm
- Location: Warszawa
- Has thanked: 13 times
- Been thanked: 11 times
Dopisz i zobacz co się pokażeSOYER wrote: Fri Jun 16, 2023 3:18 pm Jeszcze jedno pytanie, dlaczego po pierwszym wgraniu szkicu z tymi RelayAsInput pierwsze wartości to zdaje się minus 200 coś, nie pamiętam, pewnie -256, zapewne ma to związek z typem zmiennej(int). Jak to na przyszłość zmienić, by inicjować do z jakąś sensowną wartością.
Dopisać wartość inicjującą tu:
void onInit() override {???}
?
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Nie mam teraz gdzie tego sprawdzić, napisz jak to rozwiązać. Z int to się wygłupiłem.
Gdzie poczytać o action handler?
Gdzie poczytać o action handler?
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
-
lukfud
- Posts: 2480
- Joined: Thu Nov 23, 2017 11:33 pm
- Location: Warszawa
- Has thanked: 13 times
- Been thanked: 11 times
SOYER wrote: Fri Jun 16, 2023 6:21 pm Nie mam teraz gdzie tego sprawdzić, napisz jak to rozwiązać. Z int to się wygłupiłem.
Gdzie poczytać o action handler?
Code: Select all
void onInit() override {
if (temperature == TEMPERATURE_NOT_AVAILABLE) {
temp.setValue(25);
}
}
Ten wątek już widziałeś
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
Cześć, nowa wersja termostatu bojlera:
Dzięki @lukfud za info jak pobierać temperaturę.
Co do actionHandlera to jeszcze nie miałem czasu się zagłębić, a jako, że niespecjalnie lubię wstawiać kluczowe linijki na zasadzie ctrl+v, kiedy nie rozumiem jak to działa, to na razie pominąłem.
W powyższym kodzie dodałem też kilka linijek odpowiedzialnych za trochę inną logike działania trybu auto/manual. Teraz nawet kiedy termostat jest w fazie wychładzania/grzania to można przestawić się na manual, zmienić mu wychładzanie<->grzanie i od razu znowu włączyć trym AUTO.
To tylko te kilka linijek:
Mam jeszcze pytanie, mam takie dwie funkcje:
ds() i dsSTART(), ta druga robi odczyt na starcie, w SETUP, a druga co określony czas nadpisuje zmienną temp odczytem z czujnika.
Ja wiem, że to się pewnie da zrobić inaczej, za pomocą actionHandlera na przykład, ale czy mógłbym pominąć tą funkcję ds() co 30s czytającą czujnik ds18 i nadpisać w ramach supli również moją zmienną temp?
Code: Select all
#include <SuplaDevice.h>
#include <supla/control/relay.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>
#include <supla/storage/eeprom.h>
Supla::Eeprom eeprom(0);
#include <supla/storage/storage.h>
#include <supla/control/virtual_relay.h>
#include <supla/sensor/virtual_thermometer.h>
#include <Timers.h>
#define ONE_WIRE D1
Supla::ESPWifi wifi(xxx", "xxx);/////"xx
Timer sekund30;
Supla::Control::Relay *relay1 = nullptr;
Supla::Control::Relay *relay2 = nullptr;
Supla::Control::VirtualRelay *vrelay = nullptr;
Supla::Sensor::DS18B20 *tempBojler = nullptr;
double temp;
int przek1 = 0;
int tempON = 30;
int tempOFF = 65;
int histereza = 3;
int wyslanoON = 0;
int wyslanoOFF = 0;
int stanVirtuala = 0;
int stanGrzalki = 0;
class RelayAsInput : public Supla::Control::VirtualRelay {//temp wył. grzałki
public:
explicit RelayAsInput(int step = 1) : step(step) {
}
virtual ~RelayAsInput() {}
void onInit() override {}
void turnOn(_supla_int_t duration = 0) override {
(void)(duration);
int newTemp = temp.getValue() + step;
if (newTemp > 90) {
newTemp = 90;
}
temp.setValue(newTemp);
tempOFF = newTemp;
wyslanoON = 0;
wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
void turnOff(_supla_int_t duration = 0) override {
(void)(duration);
int newTemp = temp.getValue() - step;
if (newTemp <= (tempON +3)) {
newTemp = tempON +3;
}
temp.setValue(newTemp);
tempOFF = newTemp;
wyslanoON = 0;
wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
int getValue() {
return temp.getValue();
}
void setValue(int value) {
temp.setValue(value);
Supla::Storage::ScheduleSave(2000);
}
void onLoadState() override {
int temperature = 0;
Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&temperature),
sizeof(int));
temp.setValue(temperature);
tempOFF = temperature;
}
void onSaveState() override {
int temperature = temp.getValue();
Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&temperature),
sizeof(int));
}
protected:
Supla::Sensor::VirtualThermometer temp;
int step = 1;
};
class RelayAsInput1 : public Supla::Control::VirtualRelay {//////////temp wł. grzałki
public:
explicit RelayAsInput1(int step = 1) : step(step) {
}
virtual ~RelayAsInput1() {}
void onInit() override {}
void turnOn(_supla_int_t duration = 0) override {
(void)(duration);
int newTemp = temp.getValue() + step;
if (newTemp >= (tempOFF -3)) {
newTemp = tempOFF -3;
}
temp.setValue(newTemp);
tempON = newTemp;
wyslanoON = 0;
wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
void turnOff(_supla_int_t duration = 0) override {
(void)(duration);
int newTemp = temp.getValue() - step;
if (newTemp < 5) {
newTemp = 5;
}
temp.setValue(newTemp);
tempON = newTemp;
wyslanoON = 0;
wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
int getValue() {
return temp.getValue();
}
void setValue(int value) {
temp.setValue(value);
Supla::Storage::ScheduleSave(2000);
}
void onLoadState() override {
int temperature = 0;
Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&temperature),
sizeof(int));
temp.setValue(temperature);
tempON = temperature;
}
void onSaveState() override {
int temperature = temp.getValue();
Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&temperature),
sizeof(int));
}
protected:
Supla::Sensor::VirtualThermometer temp;
int step = 1;
};
void setup() {
Serial.begin(9600);
sekund30.begin(14898);
// Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
char GUID[SUPLA_GUID_SIZE] = {xx};
// Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xx};
relay1 = new Supla::Control::Relay(D5, false);
relay2 = new Supla::Control::Relay(D6, false);
vrelay = new Supla::Control::VirtualRelay();
tempBojler = new Supla::Sensor::DS18B20(ONE_WIRE);
new RelayAsInput1();
new RelayAsInput();
dsSTART();
SuplaDevice.begin(GUID, // Global Unique Identifier
"svrxx.supla.org", // SUPLA server address//////////xx.supla.org
"xxxx", // Email address used to login to Supla Cloud/////////////xx
AUTHKEY); // Authorization key
}
void loop() {
SuplaDevice.iterate();
ds();
relayOnOff();
}
void ds(){
if(sekund30.available()){
temp = tempBojler->getChannel()->getValueDouble();
}
}
void dsSTART(){
temp = tempBojler->getChannel()->getValueDouble();
}
void relayOnOff(){
stanV();
if(temp>=tempOFF){
przek1=0;
}
else if(temp<tempON){
przek1=1;
}
if(!vrelay->isOn()){
if((przek1 == 1) && (wyslanoON==0)){
relay2->turnOn();
wyslanoON=1;
wyslanoOFF=0;
}
else if((przek1==0) && (wyslanoOFF==0)){
relay2->turnOff();
wyslanoON=0;
wyslanoOFF=1;
}
}
}
void stanV(){
int r2 = relay2->isOn();
if(r2 != stanGrzalki){
stanGrzalki = r2;
wyslanoON=0;
wyslanoOFF=0;
}
int vr = vrelay->isOn();
if(vr != stanVirtuala){
stanVirtuala = vr;
wyslanoON=0;
wyslanoOFF=0;
}
if(vrelay->isOn()){
if(relay2->isOn()){
przek1=1;
}
else if(!relay2->isOn()){
przek1=0;
}
}
}Co do actionHandlera to jeszcze nie miałem czasu się zagłębić, a jako, że niespecjalnie lubię wstawiać kluczowe linijki na zasadzie ctrl+v, kiedy nie rozumiem jak to działa, to na razie pominąłem.
W powyższym kodzie dodałem też kilka linijek odpowiedzialnych za trochę inną logike działania trybu auto/manual. Teraz nawet kiedy termostat jest w fazie wychładzania/grzania to można przestawić się na manual, zmienić mu wychładzanie<->grzanie i od razu znowu włączyć trym AUTO.
To tylko te kilka linijek:
Code: Select all
if(vrelay->isOn()){
if(relay2->isOn()){
przek1=1;
}
else if(!relay2->isOn()){
przek1=0;
}
}ds() i dsSTART(), ta druga robi odczyt na starcie, w SETUP, a druga co określony czas nadpisuje zmienną temp odczytem z czujnika.
Ja wiem, że to się pewnie da zrobić inaczej, za pomocą actionHandlera na przykład, ale czy mógłbym pominąć tą funkcję ds() co 30s czytającą czujnik ds18 i nadpisać w ramach supli również moją zmienną temp?
Last edited by SOYER on Tue Jun 20, 2023 5:51 pm, edited 1 time in total.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
-
SOYER
- Posts: 1623
- Joined: Wed Aug 10, 2022 12:29 pm
- Location: Kryry
- Been thanked: 2 times
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
-
konstal2004
- Posts: 2
- Joined: Sun Aug 27, 2023 2:07 pm
Witam
Od dłuższego czasu właśnie taki projekt siedział mi w głowie, a teraz rozpocząłem jego realizację. Nadmienię tylko, że jest to mój pierwszy projekt na Supli, a w programowaniu miałem prawie 20 lat przerwy..
Zmodyfikowałem nieco kod pod siebie, uzupełniłem o "onInit()" przypisującą jakieś "normalne" wartości temperatur, o której wspominał lukfud.
Chcę to jeszcze rozbudować o wykorzystanie autokonsumpcji prądu z fotowoltaiki. W tym celu do Wemosa podpiąłem płytkę PZEM-004.
Idea jest taka, że gdy wartość napięcia odczytana na PZEM przekroczy określony próg, to automatyka załączy grzałkę w zasobniku CWU.
Grzałka sterowana grupowo, za pomocą przekaźnika SSR. Stanąłem na odczytaniu wartości napięcia z PZEM.
Przypuszczam, że jest możliwość pobrania napięcia w podobny sposób, jak temperaturę, tzn:
Niestety nie wiem jak to zaimplementować w przypadku napięcia.
Poniżej kod z moimi modyfikacjami
Od dłuższego czasu właśnie taki projekt siedział mi w głowie, a teraz rozpocząłem jego realizację. Nadmienię tylko, że jest to mój pierwszy projekt na Supli, a w programowaniu miałem prawie 20 lat przerwy..
Zmodyfikowałem nieco kod pod siebie, uzupełniłem o "onInit()" przypisującą jakieś "normalne" wartości temperatur, o której wspominał lukfud.
Chcę to jeszcze rozbudować o wykorzystanie autokonsumpcji prądu z fotowoltaiki. W tym celu do Wemosa podpiąłem płytkę PZEM-004.
Idea jest taka, że gdy wartość napięcia odczytana na PZEM przekroczy określony próg, to automatyka załączy grzałkę w zasobniku CWU.
Grzałka sterowana grupowo, za pomocą przekaźnika SSR. Stanąłem na odczytaniu wartości napięcia z PZEM.
Przypuszczam, że jest możliwość pobrania napięcia w podobny sposób, jak temperaturę, tzn:
Code: Select all
double temperature = temperature_sensor->getChannel()->getValueDouble(); Poniżej kod z moimi modyfikacjami
Code: Select all
#include <SuplaDevice.h>
#include <supla/control/relay.h>
#include <supla/sensor/DS18B20.h>
#include <supla/sensor/PzemV3.h>
#include <supla/network/esp_wifi.h>
#include <supla/storage/eeprom.h>
Supla::Eeprom eeprom(0);
#include <supla/storage/storage.h>
#include <supla/control/virtual_relay.h>
#include <supla/sensor/virtual_thermometer.h>
#include <Timers.h>
#define ONE_WIRE D3
Supla::ESPWifi wifi("", "");
Timers sekund10;
//Supla::Control::Relay *SSR = nullptr;
//Supla::Control::Relay *relay2 = nullptr;
Supla::Control::VirtualRelay *vrelay = nullptr;
Supla::Sensor::DS18B20 *tempBojler = nullptr;
const int SSR = 14; ///GPIO14 = D5
double temp;
double napiecie;
int przek1 = 0;
int tempON = 40;
int tempOFF = 45;
int histereza = 3;
//int wyslanoON = 0;
//int wyslanoOFF = 0;
int stanVirtuala = 0;
int stanGrzalki = 0;
int napiecie_ust = 245;
int delta_U = 3;
int temperatura_fotowoltaiki = 80;
int time_H=0;
int time_L=250;
class RelayAsInput : public Supla::Control::VirtualRelay //temperatura wyłączenia grzałki przy korzystaniu z prądu sieciowego
{
public:
explicit RelayAsInput(int step = 1) : step(step) {}
virtual ~RelayAsInput() {}
void onInit() override
{
if (temp.getValue() == TEMPERATURE_NOT_AVAILABLE)
temp.setValue(tempOFF);
}
void turnOn(_supla_int_t duration = 0) override
{
(void)(duration);
int newTemp = temp.getValue() + step;
if (newTemp > 85)
newTemp = 85;
temp.setValue(newTemp);
tempOFF = newTemp;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
void turnOff(_supla_int_t duration = 0) override
{
(void)(duration);
int newTemp = temp.getValue() - step;
if (newTemp <= (tempON +3))
newTemp = tempON +3;
temp.setValue(newTemp);
tempOFF = newTemp;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
int getValue()
{
return temp.getValue();
}
void setValue(int value)
{
temp.setValue(value);
Supla::Storage::ScheduleSave(2000);
}
void onLoadState() override
{
int temperature = 0;
Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&temperature),sizeof(int));
temp.setValue(temperature);
tempOFF = temperature;
}
void onSaveState() override
{
int temperature = temp.getValue();
Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&temperature),sizeof(int));
}
protected:
Supla::Sensor::VirtualThermometer temp;
int step = 1;
};
class RelayAsInput1 : public Supla::Control::VirtualRelay //temperatura włączenia grzałki przy korzystaniu z prądu sieciowego
{
public:
explicit RelayAsInput1(int step = 1) : step(step) {}
virtual ~RelayAsInput1() {}
void onInit() override
{
if (temp.getValue() == TEMPERATURE_NOT_AVAILABLE)
temp.setValue(tempON);
}
void turnOn(_supla_int_t duration = 0) override
{
(void)(duration);
int newTemp = temp.getValue() + step;
if (newTemp >= (tempOFF -3))
newTemp = tempOFF -3;
temp.setValue(newTemp);
tempON = newTemp;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
void turnOff(_supla_int_t duration = 0) override
{
(void)(duration);
int newTemp = temp.getValue() - step;
if (newTemp < 5)
newTemp = 5;
temp.setValue(newTemp);
tempON = newTemp;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
int getValue()
{
return temp.getValue();
}
void setValue(int value)
{
temp.setValue(value);
Supla::Storage::ScheduleSave(2000);
}
void onLoadState() override
{
int temperature = 0;
Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&temperature),sizeof(int));
temp.setValue(temperature);
tempON = temperature;
}
void onSaveState() override
{
int temperature = temp.getValue();
Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&temperature),sizeof(int));
}
protected:
Supla::Sensor::VirtualThermometer temp;
int step = 1;
};
class Napiecie_ustawione : public Supla::Control::VirtualRelay // ustawione napięcie graniczne, powyżej którego następuje załączenie grzałki CWU
{
public:
explicit Napiecie_ustawione(int step = 1) : step(step) {}
virtual ~Napiecie_ustawione() {}
void onInit() override
{
// if (temp.getValue() == TEMPERATURE_NOT_AVAILABLE)
temp.setValue(napiecie_ust);
}
void turnOn(_supla_int_t duration = 0) override
{
(void)(duration);
int new_U = temp.getValue() + step;
temp.setValue(new_U);
napiecie_ust = new_U;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
void turnOff(_supla_int_t duration = 0) override
{
(void)(duration);
int new_U = temp.getValue() - step;
temp.setValue(new_U);
napiecie_ust = new_U;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
int getValue()
{
return temp.getValue();
}
void setValue(int value)
{
temp.setValue(value);
Supla::Storage::ScheduleSave(2000);
}
void onLoadState() override
{
int napiecie = 0;
Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&napiecie),sizeof(int));
temp.setValue(napiecie);
napiecie_ust = napiecie;
}
void onSaveState() override
{
int napiecie = temp.getValue();
Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&napiecie),sizeof(int));
}
protected:
Supla::Sensor::VirtualThermometer temp;
int step = 1;
};
class temp_fotowoltaika : public Supla::Control::VirtualRelay //temperatura wyłączenia grzałki przy korzystaniu z fotowoltaiki
{
public:
explicit temp_fotowoltaika(int step = 1) : step(step) {}
virtual ~temp_fotowoltaika() {}
void onInit() override
{
if (temp.getValue() == TEMPERATURE_NOT_AVAILABLE)
temp.setValue(temperatura_fotowoltaiki);
}
void turnOn(_supla_int_t duration = 0) override
{
(void)(duration);
int newTemp = temp.getValue() + step;
if (newTemp > 85)
newTemp = 85;
temp.setValue(newTemp);
temperatura_fotowoltaiki = newTemp;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
void turnOff(_supla_int_t duration = 0) override
{
(void)(duration);
int newTemp = temp.getValue() - step;
temp.setValue(newTemp);
temperatura_fotowoltaiki = newTemp;
// wyslanoON = 0;
// wyslanoOFF = 0;
Supla::Storage::ScheduleSave(2000);
}
int getValue()
{
return temp.getValue();
}
void setValue(int value)
{
temp.setValue(value);
Supla::Storage::ScheduleSave(2000);
}
void onLoadState() override
{
int temperature = 0;
Supla::Storage::ReadState(reinterpret_cast<unsigned char *>(&temperature),sizeof(int));
temp.setValue(temperature);
temperatura_fotowoltaiki = temperature;
}
void onSaveState() override
{
int temperature = temp.getValue();
Supla::Storage::WriteState(reinterpret_cast<unsigned char *>(&temperature),sizeof(int));
}
protected:
Supla::Sensor::VirtualThermometer temp;
int step = 1;
};
void setup()
{
Serial.begin(9600);
sekund10.start(15000);
// Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
char GUID[SUPLA_GUID_SIZE] = {};
// Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {};
pinMode(SSR, OUTPUT);
// relay2 = new Supla::Control::Relay(D6, false);
vrelay = new Supla::Control::VirtualRelay(); //wyłącznik grzałki
tempBojler = new Supla::Sensor::DS18B20(ONE_WIRE); // temperatura bojlera
new RelayAsInput1(); // temperatura załączania grzałki przy korzystaniu z prądu sieciowego
new RelayAsInput(); // temperatura wyłączania grzałki przy korzystaniu z prądu sieciowego
new temp_fotowoltaika(); // temperatura wyłączania grzałki przy korzystaniu z fotowoltaiki
new Napiecie_ustawione(); // ustawione napięcie graniczne, powyżej którego następuje załączenie grzałki CWU
new Supla::Sensor::PZEMv3(5, 4); // (RX,TX) "PZEM Addr default to 0xF8"
dsSTART();
SuplaDevice.begin(GUID, // Global Unique Identifier
"", // SUPLA server address
"", // Email address used to login to Supla Cloud
"");
}
void loop()
{
SuplaDevice.iterate();
ds();
relayOnOff();
}
void ds()
{
if(sekund10.available())
{
temp = tempBojler->getChannel()->getValueDouble();
temp = 45;
napiecie=240;
}
////obliczenie długości czasu załączenia i czasu przerwy przekaźnika SSR
if (napiecie > (napiecie_ust + delta_U))
if (time_H<250)
time_H+=10;
if (napiecie < (napiecie_ust - delta_U))
if (time_H>0)
time_H-=10;
time_L=250-time_H;
}
void dsSTART()
{
temp = tempBojler->getChannel()->getValueDouble();
temp = 45;
napiecie=240;
}
void relayOnOff()
{
// stanV();
if (!vrelay->isOn()) //jeżeli grzałka wyłączona, SSR wyłączony
digitalWrite(SSR, LOW);
else if (vrelay->isOn()) //jeżeli grzałka włączona
{
if (time_H==0) //jeżeli napięcie nie przekracza napięcia ustawionego
{
if (temp>tempOFF) //jeżeli temperatura wyższa od temperatury wyłączenia to wyłącz grzałkę
digitalWrite(SSR, LOW);
if (temp<tempON) //jeżeli temperatura niższa od temperatury załączenia to załącz grzałkę
digitalWrite(SSR, HIGH);
}
if (time_H>0) //jeżeli napięcie przekracza napięcie ustawione
{
if (temp<temperatura_fotowoltaiki) //jeżeli temperatura niższa od temperatury ustawionej przy podgrzewaniu wody prądem z fotowoltaiki
{
digitalWrite(SSR, HIGH);
delay(time_H);
digitalWrite(SSR, LOW);
delay(time_L);
}
if (temp>temperatura_fotowoltaiki)
digitalWrite(SSR, LOW);
}
}
}
