Termostat bojlera, włączający i wyłączający grzałkę, tryb AUTO i MANUAL

User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Cześć, poniżej szkic do termostatu włączającego grzałkę kiedy temperatura spadnie poniżej ustawionej wartości i wyłączającą grzałkę kiedy temperatura osiągnie lub przekroczy drugą ustawioną wartość. Termostat działa oczywiście automatycznie, ale można go przestawić w tryb manualny i wtedy ręcznie włączać lub wyłączać grzałkę.
Jutro postaram się wrzucić jakiś film.
Szkic:

Code: Select all

#include <Wire.h> 
#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 <OneWire.h>
#include <DallasTemperature.h>
#include <Timers.h>

Supla::ESPWifi wifi("xxx", "xxx);/////

#define ONE_WIRE D1
OneWire oneWire0(D1);
DallasTemperature t1(&oneWire0);
Timer sekund30;
Supla::Control::Relay *relay1 = nullptr;
Supla::Control::Relay *relay2 = nullptr;
Supla::Control::VirtualRelay *vrelay = nullptr;

int 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] = {xxx};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xxx};

  relay1 =   new Supla::Control::Relay(D5, false);
  relay2 =   new Supla::Control::Relay(D6, false);
  vrelay = new Supla::Control::VirtualRelay();
  new Supla::Sensor::DS18B20(ONE_WIRE);
  new RelayAsInput1();
  new RelayAsInput();
  
  t1.begin();  
       dsSTART();
  SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "svrxx.supla.org",  // SUPLA server address//////////
                    "xxx",   // Email address used to login to Supla Cloud/////////////
                    AUTHKEY);          // Authorization key
}

void loop() {
   SuplaDevice.iterate();
   ds();
   relayOnOff();
}

void ds(){
  if(sekund30.available()){
  t1.requestTemperatures(); 
  temp = (t1.getTempCByIndex(0));
  sekund30.restart();
  }
}
void dsSTART(){
  t1.requestTemperatures(); 
  temp = (t1.getTempCByIndex(0));
}
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;
    }
}
Feedback mile widziany, co poprawić.
Np. chciałbym wiedzieć jak pobierać wartość temp z ds z suplowej klasy, a nie samemu go dodatkowo czytać.
Last edited by SOYER on Tue Jun 20, 2023 5:16 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
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Screenshot
You do not have the required permissions to view the files attached to this post.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
lukasz06
Posts: 2543
Joined: Sun Jul 17, 2022 6:53 pm
Has thanked: 45 times
Been thanked: 21 times

Post

Może głupie pytanie, ale na warunkowaniu tego nie zrobisz?
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Robię to dla kolegi. Chciał wszystko ustawiane z apk. Nie zna się na scripts, cloud itd.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
YoMan
Posts: 3521
Joined: Thu Apr 30, 2020 5:18 pm
Location: Częstochowa
Has thanked: 3 times
Been thanked: 3 times

Post

Może głupie pytanie ale nie lepiej było poczekać chwilkę skoro zaraz mają wejść termostaty natywnie?
YoMan
________________________________________
Wziąłem udział w SOP2023 & SOP2024
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

YoMan wrote: Fri Jun 16, 2023 7:02 am Może głupie pytanie ale nie lepiej było poczekać chwilkę skoro zaraz mają wejść termostaty natywnie?
Znasz znaczenie pojęcia "za chwilę" na forum Supla😁?
Poza tym kumpel to chce na wczoraj, a ja lubię takie wyzwania.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
lukfud
Posts: 2480
Joined: Thu Nov 23, 2017 11:33 pm
Location: Warszawa
Has thanked: 13 times
Been thanked: 11 times

Post

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.
kolega @lukasz06 miał na myśli (tak mi się wydaje) warunki w kodzie.

Twój szkic lekko zmodyfikowany. Nie sprawdzałem działania.

Code: 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();
}
Pobieranie wartości z czujnika temperatury, w przypadku DS'a

Code: Select all

double temperature = temperature_sensor->getChannel()->getValueDouble();
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Ooo widzę spore zmiany, przeanalizuję wieczorem.
Dzięki🍻
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
YoMan
Posts: 3521
Joined: Thu Apr 30, 2020 5:18 pm
Location: Częstochowa
Has thanked: 3 times
Been thanked: 3 times

Post

SOYER wrote: Fri Jun 16, 2023 7:20 am
YoMan wrote: Fri Jun 16, 2023 7:02 am Może głupie pytanie ale nie lepiej było poczekać chwilkę skoro zaraz mają wejść termostaty natywnie?
Znasz znaczenie pojęcia "za chwilę" na forum Supla😁?
Poza tym kumpel to chce na wczoraj, a ja lubię takie wyzwania.
Ja oczywiście rozumiem sytuację dlatego piszę "głupie pytanie" bo można zrobić bardziej dla siebie i satysfakcji a jeszcze jak komuś się przyda ... :)
No to drugie głupie pytanie ... soft od elmaya chyba działa tak samo? Wolałeś się sam bawić skoro było na wczoraj?
YoMan
________________________________________
Wziąłem udział w SOP2023 & SOP2024
krycha88
Posts: 5575
Joined: Fri Nov 16, 2018 7:25 am
Been thanked: 5 times

Post

YoMan wrote: Fri Jun 16, 2023 11:53 am Wolałeś się sam bawić skoro było na wczoraj?
To czego przy okazji się nauczył to jego ;)
https://gui-generic-builder.supla.io/

Return to “Projekty użytkowników”