ESP8266 Primary GUI - Termostat

tijo
Posty: 227
Rejestracja: pt gru 01, 2017 12:44 pm

kurus pisze: czw sty 05, 2023 6:45 am Nie lepiej użyć aktualnego gui z funkcją warunkowania przekaznika? Ja tak używam do kotła gazowego i sprawdza się super.
Macie to samo i zawsze aktualny soft bo ten z tematu to juz nie aktualizowany..

Mam podpięte tam 5 ds'ow bez razystora i wszystko działa pięknie, podłączam je pod pin który ma pulup z samego esp jak dobrze pamiętam d4.
GG nie ma opcji PWM....ten soft jest naprawdę super. Używam go od lat do sterowania webastem do ogrzewania w domku i do wędzarni z nadmuchem w palenisko (wentylatory sterowane PWM)
Awatar użytkownika
slawek
Posty: 2465
Rejestracja: pn mar 14, 2016 11:48 pm
Lokalizacja: Biała Podlaska

tijo pisze: pt sty 06, 2023 10:14 am
kurus pisze: czw sty 05, 2023 6:45 am Nie lepiej użyć aktualnego gui z funkcją warunkowania przekaznika? Ja tak używam do kotła gazowego i sprawdza się super.
Macie to samo i zawsze aktualny soft bo ten z tematu to juz nie aktualizowany..

Mam podpięte tam 5 ds'ow bez razystora i wszystko działa pięknie, podłączam je pod pin który ma pulup z samego esp jak dobrze pamiętam d4.
GG nie ma opcji PWM....ten soft jest naprawdę super. Używam go od lat do sterowania webastem do ogrzewania w domku i do wędzarni z nadmuchem w palenisko (wentylatory sterowane PWM)
GG nie ma też opcji zmiany temperatury ze smartfona...
TEORIA jest wtedy gdy wszystko wiemy i nic nie działa
PRAKTYKA jest wtedy gdy wszystko działa a my nie wiemy dlaczego
My łączymy teorię z praktyką czyli nic nie działa i nikt nie wie dlaczego
zzrr
Posty: 337
Rejestracja: śr paź 26, 2022 7:35 pm

Witam kolegów.
jeśli ktoś jest zainteresowany to udostępniam wsad do Wemosa D1 mini. Potrzebowałem takiego wg kryteriów jak poniżej więc go skleiłem do wersji działającej jak było mi potrzeba.
Na angielskojęzycznej stronie ten termostat jest w innych wersjach ale wszystkie które sprawdzałem były na nieaktualnych bibliotekach i albo nie działał tryb konfiguracji albo sterowanie było nie takie jak mi akurat potrzeba. Więc jeśli komuś ta wersja odpowiada to z przyjemnością udostępniam.
- zmieniłem obsługę pamięci w celu przedłużenia żywotności EEPROMA . Dane zapisywane są tylko przy zmianie stanu (1.auto/manual, 2.przek.wł/wył, 3. temp. termostatu i 4.histereza). Dane są przywracane z pamięci przy starcie WEMOSA, może pracować online przy awarii WiFi. Jedynie nie da się wtedy zmieniać histerezy. Histerezę jak i wszystkie inne parametry można ustawić z poziomu aplikacji w telefonie lub na stronie Supli. Temperatura i histereza ustawiana co 0.1C. i obie wartości widoczne na wyświetlaczu.
Przytrzymanie przycisku +/- powoduje szybkie przestawienie temperatury. Przełączenie termostatu w tryb konfiguracji pin D5 5s sterowany minusem. Po wgraniu Firmware config domyślnie uruchomi się z automatu. Wemos będzie rozgłaszał własną sieć. Adres standardowy 192.168.4.1 Zakres tem. 0 - 100C, zakres histerezy 0 - 10C.
Jedno klikniecie D5 przełączanie Auto/Manual. Dwa szybkie naciśnięcia D5 Wł/Wył przekaźnik w trybie manual. 5s D5 Config.
D7-UP | D6-DOWN | D5-AUTO/Manual, wł/wył przekaźnik, CONFIG | D1-przekaźnik (+ przy ON) | D2 - Sygnał z DS18B20 | D3-SDA OLED | D4-SCL OLED. OLED 1306
TermostatWemosHistCo01TempCo01.rar
(364.42 KiB) Pobrany 118 razy
20230116_195815.jpg
20230116_195815.jpg (77.94 KiB) Przejrzano 1167 razy
Screenshot_20230116-200501_SUPLA.jpg
Screenshot_20230116-200501_SUPLA.jpg (39.94 KiB) Przejrzano 1167 razy
Pozdrawiam.
mrprezident14
Posty: 44
Rejestracja: sob lis 26, 2022 4:27 pm
Lokalizacja: Żywiec

Ten termostat ma jeden mankament niema opcji chłodzenia.
zzrr pisze: wt sty 17, 2023 12:52 am Witam kolegów.
jeśli ktoś jest zainteresowany to udostępniam wsad do Wemosa D1 mini. Potrzebowałem takiego wg kryteriów jak poniżej więc go skleiłem do wersji działającej jak było mi potrzeba.
Na angielskojęzycznej stronie ten termostat jest w innych wersjach ale wszystkie które sprawdzałem były na nieaktualnych bibliotekach i albo nie działał tryb konfiguracji albo sterowanie było nie takie jak mi akurat potrzeba. Więc jeśli komuś ta wersja odpowiada to z przyjemnością udostępniam.
- zmieniłem obsługę pamięci w celu przedłużenia żywotności EEPROMA . Dane zapisywane są tylko przy zmianie stanu (1.auto/manual, 2.przek.wł/wył, 3. temp. termostatu i 4.histereza). Dane są przywracane z pamięci przy starcie WEMOSA, może pracować online przy awarii WiFi. Jedynie nie da się wtedy zmieniać histerezy. Histerezę jak i wszystkie inne parametry można ustawić z poziomu aplikacji w telefonie lub na stronie Supli. Temperatura i histereza ustawiana co 0.1C. i obie wartości widoczne na wyświetlaczu.
Przytrzymanie przycisku +/- powoduje szybkie przestawienie temperatury. Przełączenie termostatu w tryb konfiguracji pin D5 5s sterowany minusem. Po wgraniu Firmware config domyślnie uruchomi się z automatu. Wemos będzie rozgłaszał własną sieć. Adres standardowy 192.168.4.1 Zakres tem. 0 - 100C, zakres histerezy 0 - 10C.
Jedno klikniecie D5 przełączanie Auto/Manual. Dwa szybkie naciśnięcia D5 Wł/Wył przekaźnik w trybie manual. 5s D5 Config.
D7-UP | D6-DOWN | D5-AUTO/Manual, wł/wył przekaźnik, CONFIG | D1-przekaźnik (+ przy ON) | D2 - Sygnał z DS18B20 | D3-SDA OLED | D4-SCL OLED. OLED 1306
TermostatWemosHistCo01TempCo01.rar 20230116_195815.jpg Screenshot_20230116-200501_SUPLA.jpg

Pozdrawiam.
Awatar użytkownika
klew
Posty: 8178
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

mrprezident14 pisze: wt sty 17, 2023 4:47 pm Ten termostat ma jeden mankament niema opcji chłodzenia.
Jakie urządzenia chcesz podłączyć? Coś co tylko chłodzi, czy grzeje i chłodzi?
Widzimy się na Supla Offline Party vol. 2 :!:
mrprezident14
Posty: 44
Rejestracja: sob lis 26, 2022 4:27 pm
Lokalizacja: Żywiec

Chodzi mi konkretnie o chłodzenie ale to tej wersji z OLED i enkoderem na pokrętle do zmiany parametrów. Uprzedzając ten oryginalny z postu termostat mam i wykorzystuje na sonoffie do mojego biedakonwektora, płaski wentylator zamontowany pod grzejnikiem jak centralne puści ciepło na grzejnik załącza się wentylator.
klew pisze: wt sty 17, 2023 5:06 pm
mrprezident14 pisze: wt sty 17, 2023 4:47 pm Ten termostat ma jeden mankament niema opcji chłodzenia.
Jakie urządzenia chcesz podłączyć? Coś co tylko chłodzi, czy grzeje i chłodzi?
zzrr
Posty: 337
Rejestracja: śr paź 26, 2022 7:35 pm

mrprezident14 pisze: wt sty 17, 2023 5:31 pm Chodzi mi konkretnie o chłodzenie ale to tej wersji z OLED i enkoderem na pokrętle do zmiany parametrów. Uprzedzając ten oryginalny z postu termostat mam i wykorzystuje na sonoffie do mojego biedakonwektora, płaski wentylator zamontowany pod grzejnikiem jak centralne puści ciepło na grzejnik załącza się wentylator.
To co opisałeś, nie jest wadą tego rozwiązania tylko nie tym czego potrzebujesz. Ja testowałem tą wersję z encoderem i doceniam pomysł, robotę itd. jednak osobiście zrezygnowałem z tej wersji ponieważ nie spełniała moich kryteriów. Osobiście uważam że sterowanie przyciskami mając również opcję szybkiego przestawiania wartości jest wygodniejsze ale to tylko moje zdanie, po za tym ten o którym chyba napisałeś nie miał możliwości ustawienia histerezy ale przede wszystkim potrzebowałem też więcej wolnych pinów na podłączenie modułu radiowego do sterowania zdalnego. Podsumowując..., komu nie pasuje to trzeba po prostu inny. Ja tak jak napisałem potrzebowałem akurat tego i się tym podzieliłem.
A wracając do tego co napisałeś... Jeśli dobrze zrozumiałem to fakt że można by mieć wersję z przełączaniem grzanie/chłodzenie. Ale przecież skoro nie planujesz używać termostatu raz do grzania a raz do chłodzenia tylko docelowo pod grzejnikiem to wystarczy podłączyć przekaźnik wyzwalany minusem a nie plusem. Przekaźnik załączy się w momencie kiedy temperatura osiągnie ustawioną, czyli odwrotnie i tadam... jest chłodzenie. Nie namawiam do zmian skoro używasz już to co Ci potrzeba i działa. Ale jeśli komuś innemu akurat by taka opcja była potrzebna... Oczywiście podłączenie przekaźnika nie bezpośrednio tylko moduł lub układ z odseparowaniem cewki od samego układu WEMOSA. To tak na wszelki wypadek dopisałem żeby mi ktoś nie zarzucił że namawiam do podłączania przekaźnika bezpośrednio pod układ. Chociaż jak ktoś lubi kupować nowe w miejsce spalonych... ;-)

Pozdrawiam
radzik_r
Posty: 385
Rejestracja: ndz sie 11, 2019 5:32 pm

zzrr pisze: wt sty 17, 2023 12:52 am Witam kolegów.
jeśli ktoś jest zainteresowany to udostępniam wsad do Wemosa D1 mini. Potrzebowałem takiego wg kryteriów jak poniżej więc go skleiłem do wersji działającej jak było mi potrzeba.
Na angielskojęzycznej stronie ten termostat jest w innych wersjach ale wszystkie które sprawdzałem były na nieaktualnych bibliotekach i albo nie działał tryb konfiguracji albo sterowanie było nie takie jak mi akurat potrzeba. Więc jeśli komuś ta wersja odpowiada to z przyjemnością udostępniam.
- zmieniłem obsługę pamięci w celu przedłużenia żywotności EEPROMA . Dane zapisywane są tylko przy zmianie stanu (1.auto/manual, 2.przek.wł/wył, 3. temp. termostatu i 4.histereza). Dane są przywracane z pamięci przy starcie WEMOSA, może pracować online przy awarii WiFi. Jedynie nie da się wtedy zmieniać histerezy. Histerezę jak i wszystkie inne parametry można ustawić z poziomu aplikacji w telefonie lub na stronie Supli. Temperatura i histereza ustawiana co 0.1C. i obie wartości widoczne na wyświetlaczu.
Przytrzymanie przycisku +/- powoduje szybkie przestawienie temperatury. Przełączenie termostatu w tryb konfiguracji pin D5 5s sterowany minusem. Po wgraniu Firmware config domyślnie uruchomi się z automatu. Wemos będzie rozgłaszał własną sieć. Adres standardowy 192.168.4.1 Zakres tem. 0 - 100C, zakres histerezy 0 - 10C.
Jedno klikniecie D5 przełączanie Auto/Manual. Dwa szybkie naciśnięcia D5 Wł/Wył przekaźnik w trybie manual. 5s D5 Config.
D7-UP | D6-DOWN | D5-AUTO/Manual, wł/wył przekaźnik, CONFIG | D1-przekaźnik (+ przy ON) | D2 - Sygnał z DS18B20 | D3-SDA OLED | D4-SCL OLED. OLED 1306
TermostatWemosHistCo01TempCo01.rar 20230116_195815.jpg Screenshot_20230116-200501_SUPLA.jpg

Pozdrawiam.
pokaż soft
zzrr
Posty: 337
Rejestracja: śr paź 26, 2022 7:35 pm

radzik_r pisze: czw sty 19, 2023 9:08 pm pokaż soft
Ano proszę bardzo...

Kod: Zaznacz cały

/*the Copyright (C) AC SOFTWARE SP. Z O.O.
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include <Arduino.h>
#include <SuplaDevice.h>
#include <EEPROM.h>
#include <supla/control/relay.h>
#include <supla/control/virtual_relay.h>
#include <supla/control/button.h>
#include <supla/sensor/DS18B20.h>
#include <supla/control/dimmer_base.h>
#include <supla/network/esp_wifi.h>
#include <supla/control/action_trigger.h>
#include <supla/device/status_led.h>
#include <supla/storage/littlefs_config.h>
#include <supla/network/esp_web_server.h>
#include <supla/network/html/device_info.h>
#include <supla/network/html/protocol_parameters.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/network/html/wifi_parameters.h>
#include <supla/device/supla_ca_cert.h>
#include <supla/events.h>
#include <OneWire.h>

// #define STORAGE_OFFSET 512
// #include <supla/storage/eeprom.h>
// Supla::Eeprom eeprom;   //linia zapisywania pamięci
Supla::ESPWifi wifi; //------ Do not change----wifimanager takes care------
Supla::LittleFsConfig configSupla;
Supla::EspWebServer suplaServer;
// Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); // inverted state

#include "SSD1306Wire.h"
SSD1306Wire display(0x3c, 0, 2); // D3-SDA  D4-SCL

// !!!
// #include "SH1106Wire.h"
// SH1106Wire display(0x3c, 0, 2); // D3-SDA  D4-SCL

// w repozytorium "esp8266-oled-ssd1306" w bibliotece SSD1306Wire.h jest literówka którą należy sprawdzić
// skutkuje tym że OLED 1306 działa tylko na pinach D4 i D5 i nie da się OLEDa przypisać do pinów D3 i D4
// należy sprawdzić tą linię kodu           "#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH8266)"
// i jeśli jest tak jak powyżej poprawić na "#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ARCH_ESP8266)"
// po poprawce OLED 1306 128x64 0.96" i 1.3" można przypisywać do dowolnych pinów.

Supla::Html::DeviceInfo htmlDeviceInfo(&SuplaDevice);
Supla::Html::WifiParameters htmlWifi;
Supla::Html::ProtocolParameters htmlProto;
Supla::Html::StatusLedParameters htmlStatusLed;

#define relay_pin 5    // D1 --  5
#define ds_pin 4       // D2 --  4
#define button2_pin 12 // D6 --  12
#define button3_pin 13 // D7 --  13
#define button_pin 14  // D5 --  14

bool relayOnLevel = HIGH; // "HIGH" for active high relay, "LOW" for active low relay.
bool Protected = false;   // if "true" disables the possibility of activating the relay in manual mode.
double poprzedniX = 0;    // zmienna pomocnicza
double his;
double his2;
char Supla_name[51] = ("Thermostat3");
char Supla_status[51] = ("No server address");
bool shouldSaveConfig = false;
bool initialConfig = false;
int s;
double ThermostatTemperature = 30;
double actualTemp = -127.0;
double Term_Hist = 1;
bool doSaveTermSetTemp = false;
bool doSafeHistSetTemp = false;
bool WiFiConected = false;
bool dimm = false;
unsigned long TempDisp_mtbs = 5000U;
unsigned long TempDisp_lasttime;
unsigned long dimm_mtbs = 15000U;
unsigned long dimm_lasttime;

Supla::Control::VirtualRelay *relay_0 = nullptr;
Supla::Sensor::DS18B20 *DsTemp = nullptr;
Supla::Control::RGBWBase *miDimmToTemp_hist = nullptr;

const uint8_t logo32_glcd_bmp[] PROGMEM = // logo supla 32
    {
        0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00,
        0xF0, 0x70, 0x00, 0x00, 0x30, 0xE0, 0x00, 0x00, 0x38, 0xC0, 0x00, 0x00,
        0x18, 0xC0, 0x01, 0x00, 0x18, 0xC0, 0x01, 0x00, 0x38, 0xC0, 0x00, 0x00,
        0x38, 0xE0, 0x01, 0x00, 0x70, 0xF0, 0x07, 0x00, 0xE0, 0x7F, 0x0E, 0x00,
        0xC0, 0x3F, 0x38, 0x00, 0x00, 0x1F, 0xE0, 0x0F, 0x00, 0x18, 0xC0, 0x1F,
        0x00, 0x18, 0xC0, 0x30, 0x00, 0x18, 0xC0, 0x30, 0x00, 0x30, 0xC0, 0x30,
        0x00, 0x30, 0x80, 0x1F, 0x00, 0x30, 0xC0, 0x0F, 0x00, 0x20, 0x60, 0x00,
        0x00, 0x60, 0x20, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x40, 0x18, 0x00,
        0x00, 0xC0, 0x0D, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x60, 0x04, 0x00,
        0x00, 0x20, 0x0C, 0x00, 0x00, 0x20, 0x0C, 0x00, 0x00, 0x60, 0x06, 0x00,
        0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t logo16_wifi_bmp[] PROGMEM = // logo wifi 16
    {
        0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x38, 0x1C, 0xC4, 0x23, 0x72, 0x4E,
        0x08, 0x10, 0xE4, 0x27, 0x10, 0x0C, 0x90, 0x09, 0x40, 0x02, 0x60, 0x06,
        0x40, 0x02, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00};
const uint8_t logo16_supla_bmp[] PROGMEM = // logo supla 16
    {
        0x30, 0x00, 0x7C, 0x00, 0xC4, 0x00, 0x86, 0x00, 0x84, 0x00, 0xDC, 0x03,
        0x78, 0x36, 0x60, 0x78, 0x40, 0x48, 0x40, 0x38, 0x40, 0x04, 0x80, 0x06,
        0x80, 0x03, 0x40, 0x02, 0xC0, 0x03, 0x00, 0x01};

const uint8_t logo_Power_off[] PROGMEM = // Power off
    {
        0xe0,0xff,0xff,0xff,0x03,0x38,0xfc,0xff,0xff,0x0f,0x0c,0xf0,0xff,0xff,0x3f,0x06,
        0xe0,0xff,0xff,0x3f,0x02,0xc0,0xcf,0x43,0x78,0x03,0xc0,0x33,0x43,0x78,0x01,0xc0,
        0x7b,0x7b,0xff,0x01,0x80,0xfd,0x42,0xf8,0x01,0x80,0xfd,0x42,0xf8,0x01,0x80,0x7b,
        0x7b,0xff,0x03,0xc0,0x33,0x7b,0xff,0x02,0xc0,0xcf,0x7b,0x7f,0x06,0xe0,0xff,0xff,
        0x7f,0x0c,0xf0,0xff,0xff,0x3f,0x18,0xfc,0xff,0xff,0x1f,0xf0,0xff,0xff,0xff,0x07,
};
const uint8_t logo_Power_on[] PROGMEM = // Power on
    {
        0xe0,0xff,0xff,0xff,0x07,0x38,0x00,0x00,0x30,0x0c,0x0c,0x00,0x00,0x18,0x18,0x06,0x00,
        0x00,0x0c,0x30,0x02,0x0e,0x00,0x06,0x60,0x03,0x9f,0x19,0x02,0x40,0x81,0xb1,0x1b,0x03,
        0xc0,0x81,0xa0,0x1a,0x01,0x80,0x81,0xa0,0x1e,0x01,0x80,0x81,0xb1,0x1c,0x01,0xc0,0x03,
        0x9b,0x18,0x03,0x40,0x02,0x8e,0x18,0x02,0x60,0x06,0x00,0x00,0x06,0x20,0x0c,0x00,0x00,
        0x0c,0x38,0x38,0x00,0x00,0x18,0x0c,0xe0,0xff,0xff,0xff,0x07,};
const uint8_t hand16_bmp[] PROGMEM = // logo hand 16
    {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x30, 0x02, 0x08, 0x3F,
        0x04, 0x40, 0x04, 0x7C, 0x02, 0x40, 0x02, 0x7C, 0x02, 0x60, 0x04, 0x3C,
        0x18, 0x10, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00};

class ManualRelay : public Supla::Control::Relay
{
public:
  ManualRelay() : Relay(-1, true, 32) {}
  void onInit()
  {
    pinMode(relay_pin, OUTPUT);
    digitalWrite(relay_pin, !relayOnLevel);
  }
  void turnOn(_supla_int_t duration)
  {
    if (!relay_0->isOn() && Protected)
    {
      digitalWrite(relay_pin, !relayOnLevel);
      channel.setNewValue(false);
    }
    else
    {
      digitalWrite(relay_pin, relayOnLevel);
      channel.setNewValue(true);
      EEPROM.put(400, 1);
      EEPROM.commit();
    }
  }
  void turnOff(_supla_int_t duration)
  {
    digitalWrite(relay_pin, !relayOnLevel);
    channel.setNewValue(false);
    EEPROM.put(400, 0);
    EEPROM.commit();
  }
  bool isOn()
  {
    if (relayOnLevel)
    {
      return digitalRead(relay_pin);
    }
    else
    {
      return !digitalRead(relay_pin);
    }
  }
};
ManualRelay *relay_1 = nullptr;

class TermostatSet : public Supla::Control::Relay
{
public:
  TermostatSet() : Relay(-1, true, 32) {}

  void onInit()
  {
    // do nothing here
  }
  void turnOn(_supla_int_t duration)
  {
    ThermostatTemperature += 0.1;
    if (ThermostatTemperature > 100.0)
      ThermostatTemperature = 100.0;
    channel.setNewValue(false);
    doSaveTermSetTemp = true;
  }
  void turnOff(_supla_int_t duration)
  {
    ThermostatTemperature -= 0.1;
    if (ThermostatTemperature < 0.0)
      ThermostatTemperature = 0.0;
    channel.setNewValue(false);
    doSaveTermSetTemp = true;
  }
  bool isOn()
  {
    return false;
  }
};
TermostatSet *TerSet = nullptr;

class TermostatTemp : public Supla::Sensor::Thermometer
{
public:
  TermostatTemp() {}

  void onInit()
  {
    channel.setNewValue(getValue());
  }
  double getValue()
  {
    return ThermostatTemperature;
  }
  void iterateAlways()
  {
    channel.setNewValue(getValue());
    if (millis() - lastReadTime > 2500)
    {
      lastReadTime = millis();
      actualTemp = DsTemp->getValue();

      if (relay_0->isOn())
      {
        if (((relay_1->isOn()) && (actualTemp >= ThermostatTemperature)) || (actualTemp < -100.0))
        {
          relay_1->turnOff(0);
        }
        else if ((!relay_1->isOn()) && (actualTemp <= (ThermostatTemperature - Term_Hist)))
        {
          relay_1->turnOn(0);
        }
      }
    }
  }
};
TermostatTemp *TerTemp = nullptr;

class TermostatSet_hist : public Supla::Control::Relay
{
public:
  TermostatSet_hist() : Relay(-1, true, 32) {}

  void onInit()
  {
    // do nothing here
  }
  void turnOn(_supla_int_t duration)
  {
    Term_Hist += 0.1;
    if (Term_Hist > 10.0)
      Term_Hist = 10.0;

    channel.setNewValue(false);
    doSafeHistSetTemp = true;
    miDimmToTemp_hist->setRGBW(-1, -1, -1, -1, (Term_Hist * 10));
  }
  void turnOff(_supla_int_t duration)
  {
    Term_Hist -= 0.1;
    if (Term_Hist <= 0.0)
      Term_Hist = 0.0;
    channel.setNewValue(false);
    doSafeHistSetTemp = true;
    miDimmToTemp_hist->setRGBW(-1, -1, -1, -1, (Term_Hist * 10));
  }
  bool isOn()
  {
    return false;
  }
};
TermostatSet_hist *TerSet_hist = nullptr;
class TermostatTemp_hist : public Supla::Sensor::Thermometer
{
public:
  TermostatTemp_hist()
  {
  }

  void onInit()
  {
    channel.setNewValue(getValue());
  }
  double getValue()
  {
    return Term_Hist;
    Term_Hist = Term_Hist;
  }
  void iterateAlways()
  {
    channel.setNewValue(getValue());
  }
};
TermostatTemp_hist *TerTemp_hist = nullptr;

enum addedActions
{
  unDimm
};

class addedActionsClass : public Supla::ActionHandler
{
public:
  addedActionsClass(){};
  void handleAction(int event, int action)
  {
    if (action == unDimm)
    {
      if (dimm)
      {
        dimm = false;
        dimm_lasttime = millis();
        display.setContrast(200, 241, 64);
      }
      else
      {
        dimm_lasttime = millis();
      }
    }
  }
};
addedActionsClass *custAct = new addedActionsClass;

class DimmToTemp_hist : public Supla::Control::DimmerBase
{
public:
  DimmToTemp_hist() {}

  void setRGBWValueOnDevice(uint32_t red,
                            uint32_t green,
                            uint32_t blue,
                            uint32_t colorBrightness,
                            uint32_t brightness)
  {
    float dimmTemp_hist = map(brightness, 0, 1023, 0, 100);
    Term_Hist = dimmTemp_hist * 0.1;
  }
};

void status_func(int status, const char *msg)
{ 
  if (s != status)
  {
    s = status;
    if (s != 10)
    {
      strcpy(Supla_status, msg);
    }
  }
}

void TH_Overlay()
{

  display.clear();
  if (actualTemp > -100)
  {
    // display.setFont(Arimo_Bold_32);
    display.setFont(ArialMT_Plain_24);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(64, 19, String(actualTemp, 1) + "ºC");
  }
  else
  {
    // display.setFont(Arimo_Bold_32);
    display.setFont(ArialMT_Plain_24);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(64, 19, "-----");
  }

  if (relay_0->isOn())
  {
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(38, 48, "T " + String(ThermostatTemperature, 1) + "ºC");
    display.drawString(61, 0, "Auto");
  }
  else
  {
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(38, 48, "T " + String(ThermostatTemperature, 1) + "ºC");
    display.drawXbm(52, 0, 16, 16, hand16_bmp);
  }
  if (TerSet_hist->isOn())
  {
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(105, 48, "H " + String(Term_Hist, 1) + "ºC");
  }
  else
  {
    display.setFont(ArialMT_Plain_10);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.drawString(105, 48, "H " + String(Term_Hist, 1) + "ºC");
  }

  if (WiFiConected)
  {
    display.drawXbm(1, 0, 16, 16, logo16_wifi_bmp); 
    if (s == STATUS_REGISTERED_AND_READY)
    {
      display.drawXbm(22, 0, 16, 16, logo16_supla_bmp); 
    }
    else if (s != 10)
    {
      display.setFont(ArialMT_Plain_16);
      display.drawString(30, 0, String(s));
    }
  }
  if (relay_1->isOn())
  {
    display.drawXbm(86, 0, 40, 16, logo_Power_on); 
  }
  else
  {
    display.drawXbm(86, 0, 40, 16, logo_Power_off); 
  }
  display.display();
  TempDisp_lasttime = millis();
}

void setup()
{
  Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY, 1);
  delay(5);
  EEPROM.begin(1024);
  pinMode(button_pin, INPUT_PULLUP);
  display.init();
  display.flipScreenVertically();
  display.clear();
  display.setFont(ArialMT_Plain_24);
  display.drawString(42, 6, "Supla");
  display.setFont(ArialMT_Plain_16);
  display.drawString(33, 40, "Thermostat");
  display.drawXbm(0, 16, 32, 32, logo32_glcd_bmp);
  display.display();
  delay(10);
  TerSet_hist = new TermostatSet_hist();
  TerSet_hist->getChannel()->setDefault(SUPLA_CHANNELFNC_POWERSWITCH);
  TerSet_hist->disableChannelState();
  TerTemp_hist = new TermostatTemp_hist();
  TerTemp_hist->getChannel()->setDefault(SUPLA_CHANNELFNC_THERMOMETER);
  TerTemp_hist->disableChannelState();
  EEPROM.get(381, ThermostatTemperature);
  if ((ThermostatTemperature > 125.0) || isnan(ThermostatTemperature))
  {
    ThermostatTemperature = 20.0;
    EEPROM.put(381, ThermostatTemperature);
    EEPROM.commit();
  }
  auto buttonCfgRelay =
      new Supla::Control::Button(button_pin, true, true);
  buttonCfgRelay->configureAsConfigButton(&SuplaDevice);
  relay_0 = new Supla::Control::VirtualRelay(32);
  relay_0->getChannel()->setDefault(SUPLA_CHANNELFNC_POWERSWITCH);
  relay_0->setDefaultStateRestore();
  relay_0->disableChannelState();
  relay_1 = new ManualRelay();
  relay_1->getChannel()->setDefault(SUPLA_CHANNELFNC_POWERSWITCH);
  relay_1->setDefaultStateOff();
  relay_1->disableChannelState();
  DsTemp = new Supla::Sensor::DS18B20(ds_pin);
  TerTemp = new TermostatTemp();
  TerTemp->disableChannelState();
  TerSet = new TermostatSet();
  TerSet->getChannel()->setDefault(SUPLA_CHANNELFNC_POWERSWITCH);
  TerSet->disableChannelState();
  miDimmToTemp_hist = new DimmToTemp_hist();
  miDimmToTemp_hist->disableChannelState();

  auto button_1 = new Supla::Control::Button(button_pin, true, true);
  auto button_2 = new Supla::Control::Button(button2_pin, true, true);
  auto button_3 = new Supla::Control::Button(button3_pin, true, true);

  button_1->setMulticlickTime(800, false);
  button_1->addAction(Supla::TOGGLE, relay_0, Supla::ON_CLICK_1);
  if (!Protected)
    button_1->addAction(Supla::TOGGLE, relay_1, Supla::ON_CLICK_2);
  button_1->addAction(unDimm, custAct, Supla::ON_PRESS);
  relay_0->addAction(Supla::TURN_OFF, relay_1, Supla::ON_TURN_OFF);

  button_2->setHoldTime(500);
  button_3->setHoldTime(500);
  button_2->repeatOnHoldEvery(30);
  button_3->repeatOnHoldEvery(30);
  button_2->addAction(unDimm, custAct, Supla::ON_PRESS);
  button_3->addAction(unDimm, custAct, Supla::ON_PRESS);
  button_2->addAction(Supla::TURN_ON, TerSet, Supla::ON_PRESS);
  button_3->addAction(Supla::TURN_OFF, TerSet, Supla::ON_PRESS);
  button_2->addAction(Supla::TURN_ON, TerSet, Supla::ON_HOLD);
  button_3->addAction(Supla::TURN_OFF, TerSet, Supla::ON_HOLD);
  SuplaDevice.setStatusFuncImpl(&status_func);
  SuplaDevice.setSuplaCACert(suplaCACert);
  SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
  SuplaDevice.begin();
  state_auto();    //
  state_relay_1(); //
  EEPROM.get(600, his2);
  delay(10);
  if (his2 > 100 || isnan(his2))
  {
    his2 = 1;
  }
  else
  {
    double his3 = his2 * 0.1;
    Term_Hist = his3;
  }
}
void state_auto()
{
  if (EEPROM.read(420) == 1)
  {
    relay_0->turnOn();
  }
  else
  {
    relay_0->turnOff();
  }
}
void state_relay_1()
{
  if (EEPROM.read(400) == 1)
  {
    relay_1->turnOn(0);
  }
  else
  {
    relay_1->turnOff(0);
  }
}
static bool previousRelayState = false;
void loop()
{
  if (Term_Hist != poprzedniX)
  {
    doSafeHistSetTemp = true;
    poprzedniX = Term_Hist;
  }
  SuplaDevice.iterate();
  delay(5);
  bool currentRelayState = relay_0->isOn();
  if (currentRelayState != previousRelayState)
  {
    previousRelayState = currentRelayState;
    if (currentRelayState == true)
    {
      EEPROM.put(420, 1);
      EEPROM.commit();
    }
    else
    {
      EEPROM.put(420, 0);
      EEPROM.commit();
    }
  }
  if (doSaveTermSetTemp)
  {
    EEPROM.put(381, ThermostatTemperature);
    EEPROM.commit();
    doSaveTermSetTemp = false;
  }
  if (doSafeHistSetTemp == true)
  {
    his = Term_Hist;
    his = Term_Hist * 10;
    EEPROM.put(600, his);
    EEPROM.commit();
    doSafeHistSetTemp = false;
  }
  if ((millis() - TempDisp_lasttime) > TempDisp_mtbs)
  {
    WiFiConected = (WiFi.status() == WL_CONNECTED);
    TempDisp_mtbs = 500;
    TH_Overlay();
  }
  if ((millis() - dimm_lasttime) > dimm_mtbs)
  {
    if (dimm == false)
    {
      display.setContrast(50, 50, 30);
      display.display();
      dimm = true;
    }
    dimm_lasttime = millis();
  }
}
term.jpg
term.jpg (171.57 KiB) Przejrzano 934 razy
AdrianK95
Posty: 20
Rejestracja: sob lis 05, 2022 9:24 am

Witam mam pytanie jak często odczytuje temperature bo mam taki przypadek że mam ustawiona temp na 20.6stopni i przekaznik się co chwilę włącza o wyłącza bo temp skacze raz 20.7st. Raz 20,5st 20,8 i tak skacze :cry:
ODPOWIEDZ

Wróć do „Projekty użytkowników”