Termostat
-
Duch__
- Posts: 2199
- Joined: Wed Aug 24, 2016 7:26 pm
- Location: Opole
- Been thanked: 6 times
Czy to normalne że po kilkukrotnym odłączeniu napięcia układ z termostatem stracił dane do wifi, adres serwa i email? Musiałem go na nowo zarejestrować i skonfigurować wszystko od nowa.
. Wykresy poszły się...
You do not have the required permissions to view the files attached to this post.
-
Duch__
- Posts: 2199
- Joined: Wed Aug 24, 2016 7:26 pm
- Location: Opole
- Been thanked: 6 times
Mam nazwijmy to nadrzędny przekaźnik 230V którym odcinam globalnie zasilanie od wszystkiego co steruje ogrzewaniem. Robiłem taki "wieloklik" co parenaście sekund i po którymś razie zauważyłem ten bubel. Dodam że pomiędzy klikaniami zmieniałem wartości temperatur na termostacie i nagle zrobił się offline. Ale o tym że na każdym z kanałów ma być nastawa górna to pamiętał, mimo że nie mam tego na sztywno w sofcie zadeklarowanego.
Mój program:
Mój program:
Code: Select all
/*
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.
*/
#define MAX_SLEEP_TIME_SEC 240
#ifdef ARDUINO_ARCH_AVR
#error "This example is not supported on Arduino AVR"
#endif
#include <SuplaDevice.h>
#include <supla/storage/eeprom.h>
#include <supla/network/esp_wifi.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/control/hvac_base.h>
#include <supla/clock/clock.h>
#include <supla/network/html/time_parameters.h>
#include <supla/network/html/hvac_parameters.h>
#include <supla/control/internal_pin_output.h>
#include <supla/events.h>
#include <supla/actions.h>
#include <supla/sensor/virtual_thermometer.h>
#include <supla/control/button.h>
#include <supla/sensor/general_purpose_measurement.h>
#include <HTTPUpdateServer.h>
#include <ArduinoJson.h> //by Benoit Blanchon 6.17.0
#include <WiFiUdp.h>
String udp_msg;
#define udpPort 4210
char incomingPacket[255]; // buffer for incoming packets
WiFiUDP udp;
String msg;
word wykonaj_raz;
float temp_aktualna[17];
String channel_name[17];
byte grzanie[17];
unsigned long temp_aktualna_unsigned_long;
word temp_aktualna_word[17];
word timeout;
bool pierwsza_transmisja_UDP;
int state_output_[17];
int state_output_old_[17];
bool nowe_dane_udp_do_wyslania;
byte sekundy_od_ostatniej_transmisji_UDP_TX;
byte numer_kanalu_do_wyslania_przez_UDP;
unsigned long previousMillis_UDP;
unsigned long previousMillis_UDP_time;
byte Liczba_grzejacych;
float kondensacja;
word aktualne_pwm_odebrane_z_pompy;
word licz_sekundy_od_ostatniego_stanu_pompy;
/*
This example requires Dallas Temperature Control library installed.
https://github.com/milesburton/Arduino-Temperature-Control-Library
*/
// Add include to DS sensor
#include <supla/sensor/DS18B20.h>
#define CFG_BUTTON_GPIO 0
#define STATUS_LED_GPIO 2
//#define LED_RED_GPIO 13
//#define LED_BLUE_GPIO 12
#define OUTPUT_GPIO_1 5
#define OUTPUT_GPIO_2 13
#define OUTPUT_GPIO_3 14
#define OUTPUT_GPIO_4 27
#define OUTPUT_GPIO_5 25
#define wysylaj_przez_udp 1 //Zezwalaj na wysylanie danych przez UDP
String last_message[18];
Supla::ESPWifi wifi;
Supla::Eeprom eeprom;
Supla::LittleFsConfig configSupla;
Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); // inverted state
Supla::EspWebServer suplaServer;
auto termometr_1 = new Supla::Sensor::VirtualThermometer;
auto termometr_2 = new Supla::Sensor::VirtualThermometer;
auto termometr_3 = new Supla::Sensor::VirtualThermometer;
auto termometr_4 = new Supla::Sensor::VirtualThermometer;
auto termometr_5 = new Supla::Sensor::VirtualThermometer;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_0 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_1 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_2 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_3 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_4 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_5 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_6 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *gpm_channel_7 = nullptr;
HTTPUpdateServer httpUpdater;
void setup() {
Serial.begin(115200);
gpm_channel_0 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_1 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_2 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_3 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_4 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_5 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_6 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_7 = new Supla::Sensor::GeneralPurposeMeasurement();
gpm_channel_0->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_1->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_2->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_3->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_4->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_5->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_6->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_7->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
gpm_channel_0->setDefaultUnitBeforeValue(""); gpm_channel_0->setDefaultUnitAfterValue(""); gpm_channel_0->setDefaultValuePrecision(0); gpm_channel_0->setInitialCaption("Grzanie piec");
gpm_channel_1->setDefaultUnitBeforeValue(""); gpm_channel_1->setDefaultUnitAfterValue(""); gpm_channel_1->setDefaultValuePrecision(0); gpm_channel_1->setInitialCaption("PWM Pompa");
gpm_channel_2->setDefaultUnitBeforeValue(""); gpm_channel_2->setDefaultUnitAfterValue(""); gpm_channel_2->setDefaultValuePrecision(0); gpm_channel_2->setInitialCaption("Kondensacja");
gpm_channel_3->setDefaultUnitBeforeValue(""); gpm_channel_3->setDefaultUnitAfterValue(""); gpm_channel_3->setDefaultValuePrecision(0); gpm_channel_3->setInitialCaption("Grzanie Salon");
gpm_channel_4->setDefaultUnitBeforeValue(""); gpm_channel_4->setDefaultUnitAfterValue(""); gpm_channel_4->setDefaultValuePrecision(0); gpm_channel_4->setInitialCaption("Grzanie Sypialnia");
gpm_channel_5->setDefaultUnitBeforeValue(""); gpm_channel_5->setDefaultUnitAfterValue(""); gpm_channel_5->setDefaultValuePrecision(0); gpm_channel_5->setInitialCaption("Grzanie Pok. Zielony");
gpm_channel_6->setDefaultUnitBeforeValue(""); gpm_channel_6->setDefaultUnitAfterValue(""); gpm_channel_6->setDefaultValuePrecision(0); gpm_channel_6->setInitialCaption("Grzanie Pok. Niebieski");
gpm_channel_7->setDefaultUnitBeforeValue(""); gpm_channel_7->setDefaultUnitAfterValue(""); gpm_channel_7->setDefaultValuePrecision(0); gpm_channel_7->setInitialCaption("Grzanie Łazienka");
// WARNING: using default Clock class. It works only when there is connection
// with Supla server. In real thermostat application, use RTC HW clock,
// which will keep time after ESP power reset
new Supla::Clock;
// HTML www component (they appear in sections according to creation
// sequence)
new Supla::Html::DeviceInfo(&SuplaDevice);
new Supla::Html::WifiParameters;
new Supla::Html::ProtocolParameters;
new Supla::Html::StatusLedParameters;
new Supla::Html::TimeParameters(&SuplaDevice);
new Supla::Device::StatusLed(STATUS_LED_GPIO, true);
eeprom.setStateSavePeriod(5000);
auto output_1 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_1,false);
auto output_2 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_2,false);
auto output_3 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_3,false);
auto output_4 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_4,false);
auto output_5 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_5,false);
auto hvac_1 = new Supla::Control::HvacBase(output_1);
auto hvac_2 = new Supla::Control::HvacBase(output_2);
auto hvac_3 = new Supla::Control::HvacBase(output_3);
auto hvac_4 = new Supla::Control::HvacBase(output_4);
auto hvac_5 = new Supla::Control::HvacBase(output_5);
// Html page for HVAC
new Supla::Html::HvacParameters(hvac_1);
new Supla::Html::HvacParameters(hvac_2);
new Supla::Html::HvacParameters(hvac_3);
new Supla::Html::HvacParameters(hvac_4);
new Supla::Html::HvacParameters(hvac_5);
termometr_1->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_2->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_3->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_4->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_5->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
// Configure thermostat parameters
hvac_1->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_1->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_1->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_1->setTemperatureHisteresisMax(1000); // 10 degree
hvac_1->setTemperatureHisteresis(20);
hvac_2->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_2->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_2->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_2->setTemperatureHisteresisMax(1000); // 10 degree
hvac_2->setTemperatureHisteresis(20);
hvac_3->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_3->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_3->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_3->setTemperatureHisteresisMax(1000); // 10 degree
hvac_3->setTemperatureHisteresis(20);
hvac_4->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_4->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_4->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_4->setTemperatureHisteresisMax(1000); // 10 degree
hvac_4->setTemperatureHisteresis(20);
hvac_5->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_5->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_5->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_5->setTemperatureHisteresisMax(1000); // 10 degree
hvac_5->setTemperatureHisteresis(20);
auto cfgButton = new Supla::Control::Button(CFG_BUTTON_GPIO, true, true);
cfgButton->configureAsConfigButton(&SuplaDevice);
// configure defualt Supla CA certificate
SuplaDevice.setSuplaCACert(suplaCACert);
SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
SuplaDevice.setName("Termostat ESP32");
httpUpdater.setup(suplaServer.getServerPtr(), "/update");
SuplaDevice.begin(21); // Thermostat requires proto version >= 21
}
void loop() {
if(timeout == 0){
SuplaDevice.iterate();
if(pierwsza_transmisja_UDP == 1){
termometr_1->setValue(temp_aktualna[2]);
termometr_2->setValue(temp_aktualna[4]);
termometr_3->setValue(temp_aktualna[5]);
termometr_4->setValue(temp_aktualna[6]);
termometr_5->setValue(temp_aktualna[15]);
}
gpm_channel_0->setValue(Liczba_grzejacych);
if(licz_sekundy_od_ostatniego_stanu_pompy < 120){
gpm_channel_1->setValue(aktualne_pwm_odebrane_z_pompy);
}
if(licz_sekundy_od_ostatniego_stanu_pompy >= 120){
gpm_channel_1->setValue(-1);
}
gpm_channel_2->setValue(kondensacja);
gpm_channel_3->setValue(grzanie[2]);
gpm_channel_4->setValue(grzanie[4]);
gpm_channel_5->setValue(grzanie[5]);
gpm_channel_6->setValue(grzanie[6]);
gpm_channel_7->setValue(grzanie[15]);
}
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_NORMAL) {
if (WiFi.status() == WL_CONNECTED) {
if(wykonaj_raz < 10000){
++wykonaj_raz;
}
if(wykonaj_raz == 10000){
wykonaj_raz = 10001;
Serial.println("UDP begin");
delay(1000);
udp.begin(udpPort);
}
}
Odczytaj_UDP();
Wyslij_UDP();
}
if (Supla::Network::IsReady()) {
SuplaDevice.handleAction(0, Supla::START_LOCAL_WEB_SERVER);
}
/*
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_CONFIG) {
// CONFIG MODE
}
if(wykonaj_raz == 10001){
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_NORMAL) {
}
}
*/
if(timeout > 0){
if(timeout == 1){
Serial.println("timeout");
}
--timeout;
}
Odczytaj_stan_wyjsc_hvac();
}
void Odczytaj_stan_wyjsc_hvac(){
int state_pomocniczy;
int state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_1); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[2] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_2); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[4] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_3); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[5] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_4); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[6] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_5); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[15] = state_pomocniczy_2;
//Serial.println(hvac_1->isOn());
for (byte licz = 1; licz <= 16; licz++) {
if(state_output_old_[licz] != state_output_[licz]){
state_output_old_[licz] = state_output_[licz];
nowe_dane_udp_do_wyslania = 1;
if(state_output_[licz] == 1){grzanie[licz] = 1;}else{grzanie[licz] = 0;}
if(licz == 2) {Serial.println("Status hvac 1 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 4) {Serial.println("Status hvac 2 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 5) {Serial.println("Status hvac 3 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 6) {Serial.println("Status hvac 4 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 15){Serial.println("Status hvac 5 = " + channel_name[licz] + " " + String(grzanie[licz]));}
}
}
Liczba_grzejacych = 0;
for (byte licz = 1; licz <= 16; licz++) {
if(grzanie[licz] == 1){
++Liczba_grzejacych;
}
}
kondensacja = temp_aktualna[9] - temp_aktualna[10];
}
void Wyslij_UDP(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis_UDP_time >= 1000UL){
previousMillis_UDP_time = currentMillis;
++sekundy_od_ostatniej_transmisji_UDP_TX;
++licz_sekundy_od_ostatniego_stanu_pompy;
if(licz_sekundy_od_ostatniego_stanu_pompy >= 120){
licz_sekundy_od_ostatniego_stanu_pompy = 120;
}
}
if(sekundy_od_ostatniej_transmisji_UDP_TX > 10){
sekundy_od_ostatniej_transmisji_UDP_TX = 0;
nowe_dane_udp_do_wyslania = 1;
}
if(nowe_dane_udp_do_wyslania > 0){
String text_UDP;
if(nowe_dane_udp_do_wyslania >= 1){
sekundy_od_ostatniej_transmisji_UDP_TX = 0;
nowe_dane_udp_do_wyslania = 1; //ograniczam żeby wysyłanie nie trwało w nieskończonośc
}
if(currentMillis - previousMillis_UDP >= 60UL){
previousMillis_UDP = currentMillis;
++numer_kanalu_do_wyslania_przez_UDP;
String text_UDP;
if(numer_kanalu_do_wyslania_przez_UDP < 17){
text_UDP = "{";
text_UDP += "\"ID\":\"" + String(numer_kanalu_do_wyslania_przez_UDP) + "\", ";
text_UDP += "\"Name\":\"" + channel_name[numer_kanalu_do_wyslania_przez_UDP] + "\", "; // <---Dodatkowe znaki cudzyslowia, przesylamy wartosc jako tekst, nie jako liczbę
text_UDP += "\"Temp\":\"" + String(temp_aktualna[numer_kanalu_do_wyslania_przez_UDP]) + "\", ";
text_UDP += "\"Heat\":\"" + String(grzanie[numer_kanalu_do_wyslania_przez_UDP]) + "\"} ";
if(wysylaj_przez_udp == 1){
udp.beginPacket("192.168.2.255", udpPort); udp.print(text_UDP); udp.endPacket();yield();
}else{
Serial.print("UDP TX: ");
Serial.println(text_UDP);
}
}
if(numer_kanalu_do_wyslania_przez_UDP == 17){
word PWM_dla_pompy = 0;
for (byte licz = 1; licz <= 16; licz++) {
if(grzanie[licz] == 1){
if(licz == 2){
PWM_dla_pompy = PWM_dla_pompy + 1000; //Dla salonu daj 1000
}else{
PWM_dla_pompy = PWM_dla_pompy + 250; //Dla pozostałych pomieszczen daj 250
}
}
}
if(PWM_dla_pompy > 1000){
PWM_dla_pompy = 1000;
}
word randNumber1 = random(1024);
word randNumber2 = random(1024);
word randNumber3 = random(1024);
word randNumber4 = random(1024);
word PUMP_CRC = 0;
PUMP_CRC = PUMP_CRC + randNumber1;
PUMP_CRC = PUMP_CRC + randNumber2;
PUMP_CRC = PUMP_CRC + randNumber3;
PUMP_CRC = PUMP_CRC + randNumber4;
PUMP_CRC = PUMP_CRC + PWM_dla_pompy;
text_UDP = "{";
text_UDP += "\"ID\":\"Pompa_1\", ";
text_UDP += "\"Name\":\"Pompa_PWM\", "; // <---Dodatkowe znaki cudzyslowia, przesylamy wartosc jako tekst, nie jako liczbę
text_UDP += "\"PWM_1\":\"" + String(randNumber1) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_2\":\"" + String(randNumber2) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_3\":\"" + String(randNumber3) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_4\":\"" + String(randNumber4) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_5\":\"" + String(PWM_dla_pompy) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"Pompa_CRC\":\"" + String(PUMP_CRC) + "\"} ";
if(wysylaj_przez_udp == 1){
udp.beginPacket("192.168.2.255", udpPort); udp.print(text_UDP); udp.endPacket();yield();
}else{
Serial.print("UDP TX: ");
Serial.println(text_UDP);
}
}
}
if(numer_kanalu_do_wyslania_przez_UDP >= 17){
numer_kanalu_do_wyslania_przez_UDP = 0;
nowe_dane_udp_do_wyslania = 0;
sekundy_od_ostatniej_transmisji_UDP_TX = 0;
}
}
}
void Odczytaj_UDP(){
int packetSize = udp.parsePacket();
if (packetSize)
{
digitalWrite(STATUS_LED_GPIO,HIGH);
delay(30);
// receive incoming UDP packets
//Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
}
udp_msg = String(incomingPacket);
if (udp_msg.substring(2,9) == "CzID255") {
Dekoduj_json_udp();
}
if (udp_msg.substring(7,14) == "Pompa_1") {
Dekoduj_json_udp();
}
udp_msg = "";
digitalWrite(STATUS_LED_GPIO,LOW);
}
}
void Dekoduj_json_udp(){
byte ID_val = 0;
//Serial.println(msg);
//Kod wygenerowany przy pomocy strony https://arduinojson.org/v6/assistant/
DynamicJsonDocument doc(1024);
DeserializationError err = deserializeJson(doc, udp_msg);
if (err) {
Serial.println(F("Blad dokodowania JSON"));
return;
}
deserializeJson(doc, udp_msg);
String ID_string = doc["CzID255"];
String Name_string = doc["CzN255"];
String Temp_string = doc["CzT255"];
String Pompa_string = doc["ID"];
String Pompa_status_string = doc["STATUS"];
String Pompa_DATA_1 = doc["DATA_1"];
String Pompa_DATA_2 = doc["DATA_2"];
String Pompa_DATA_3 = doc["DATA_3"];
String Pompa_DATA_4 = doc["DATA_4"];
String Pompa_DATA_5 = doc["DATA_5"];
String Pompa_DATA_CRC = doc["DATA_CRC"];
String Start_string = doc["255_START"];
String End_string = doc["255_END"];
//Serial.println(msg.substring(2,9));
//Serial.println(udp_msg);
if (udp_msg.substring(7,14) == "Pompa_1") {
if(Pompa_string == "Pompa_1" && Pompa_status_string == "OK"){
int Pompa_DATA_1_int = Pompa_DATA_1.toInt();
int Pompa_DATA_2_int = Pompa_DATA_2.toInt();
int Pompa_DATA_3_int = Pompa_DATA_3.toInt();
int Pompa_DATA_4_int = Pompa_DATA_4.toInt();
int Pompa_DATA_5_int = Pompa_DATA_5.toInt();
int Pompa_DATA_CRC_int = Pompa_DATA_CRC.toInt();
word licz_crc = 0;
licz_crc = licz_crc + Pompa_DATA_1_int;
licz_crc = licz_crc + Pompa_DATA_2_int;
licz_crc = licz_crc + Pompa_DATA_3_int;
licz_crc = licz_crc + Pompa_DATA_4_int;
licz_crc = licz_crc + Pompa_DATA_5_int;
if(licz_crc == Pompa_DATA_CRC_int){
aktualne_pwm_odebrane_z_pompy = Pompa_DATA_5_int;
licz_sekundy_od_ostatniego_stanu_pompy = 0;
}
}
}
if (udp_msg.substring(2,9) == "CzID255") {
//Serial.println(udp_msg);
ID_val = ID_string.toInt();
last_message[ID_val] = udp_msg;
channel_name[ID_val] = Name_string;
if(ID_val == 0){
temp_aktualna_unsigned_long = Temp_string.toInt();
timeout = 50000;
}else{
temp_aktualna_word[ID_val] = Temp_string.toInt();
timeout = 50000;
}
if(ID_val == 16){
timeout = 0;
//Kalkulacja CRC
unsigned long CRC = 0;
for (byte licz = 1; licz <= 16; licz++) {
CRC = CRC + temp_aktualna_word[licz];
}
if(CRC == temp_aktualna_unsigned_long){ //Jesli otrzymalismy prawidlowe CRC;
float temp_aktualna_float = 0;
for (byte licz = 1; licz <= 16; licz++) {
temp_aktualna_float = temp_aktualna_word[licz] - 12721; //Deszyfrujemy dane
temp_aktualna[licz] = temp_aktualna_float;
temp_aktualna[licz] = temp_aktualna[licz] / 100;
}
pierwsza_transmisja_UDP = 1;
kasuj_wszystkie_msg();
}else{
if(temp_aktualna_unsigned_long == 0){
Serial.println(F("CRC blędne, nieodebrano calej ramki danych"));
korekcja_bledow();
kasuj_wszystkie_msg();
}else{
Serial.print(F("CRC blędne, oczekiwano: "));
Serial.print(String(temp_aktualna_unsigned_long));
Serial.print(F(" jest: "));
Serial.println(String(CRC));
korekcja_bledow();
kasuj_wszystkie_msg();
}
}
temp_aktualna_unsigned_long = random(30000); //Usuwamy dane zapisujac ja dowolnymi danymi
for (byte licz = 1; licz <= 16; licz++) {
temp_aktualna_word[licz] = random(30000); //Usuwamy dane zapisujac ja dowolnymi danymi
}
}
}
}
void korekcja_bledow(){
byte liczba_brakujacych_transmisji;
byte zapamietaj_numer_brakujacej_transmisji;
unsigned long suma;
unsigned long roznica;
for (byte licz = 0; licz <= 16; licz++) {
if(last_message[licz] == ""){
++liczba_brakujacych_transmisji;
zapamietaj_numer_brakujacej_transmisji = licz;
}
}
if(liczba_brakujacych_transmisji > 0){
Serial.print("Liczba brakujacych transmisji: ");
Serial.println(liczba_brakujacych_transmisji);
if(liczba_brakujacych_transmisji == 1){
//Serial.print("Numer brakujacej transmisji: ");
//Serial.println(zapamietaj_numer_brakujacej_transmisji);
if(zapamietaj_numer_brakujacej_transmisji != 0){
suma = 0;
for (byte licz = 1; licz <= 16; licz++) {
if(licz != zapamietaj_numer_brakujacej_transmisji){
suma = suma + temp_aktualna_word[licz];
}
}
//Serial.print("Suma: ");
//Serial.println(suma);
roznica = temp_aktualna_unsigned_long - suma;
//Serial.print("Różnica: ");
//Serial.println(roznica);
if(roznica < 100000){
temp_aktualna_word[zapamietaj_numer_brakujacej_transmisji] = roznica;
float temp_aktualna_float = 0;
for (byte licz = 1; licz <= 16; licz++) {
temp_aktualna_float = temp_aktualna_word[licz] - 12721; //Deszyfrujemy dane
temp_aktualna[licz] = temp_aktualna_float;
temp_aktualna[licz] = temp_aktualna[licz] / 100;
}
Serial.print("Naprawiono blad transmisji nr: ");
Serial.print(zapamietaj_numer_brakujacej_transmisji);
Serial.print(" Wartosc: ");
Serial.print(roznica);
Serial.print(" --> ");
Serial.print(String(temp_aktualna[zapamietaj_numer_brakujacej_transmisji],1));
Serial.println("*C");
}else{
Serial.println("Nienaprawialne, roznica wieksza / rowna 100000");
}
}else{
Serial.println("Nienaprawialne, brakuje transmisji 0");
}
}else{
Serial.println("Nienaprawialne, za duzo brakuje");
}
}
}
void kasuj_wszystkie_msg(){
for (byte licz = 0; licz <= 16; licz++) {
last_message[licz] = "";
}
}potwierdzam,
nie jednokrotnie tez tak miałem,
przeważnie podczas eksperymentów/testów zabawy z podłączaniem/odłączaniem szybkim itp.
ale jak już uruchomiony skonfigurowany i działa przez jakiś czas godziny/dni tygodnie to jest ok
być może podczas takich eksperymentów z pamięcią się coś dzieje, może nie nadąża zapisać/odczytać itp. tak tylko podejrzewam
nie jednokrotnie tez tak miałem,
przeważnie podczas eksperymentów/testów zabawy z podłączaniem/odłączaniem szybkim itp.
ale jak już uruchomiony skonfigurowany i działa przez jakiś czas godziny/dni tygodnie to jest ok
być może podczas takich eksperymentów z pamięcią się coś dzieje, może nie nadąża zapisać/odczytać itp. tak tylko podejrzewam
-
Duch__
- Posts: 2199
- Joined: Wed Aug 24, 2016 7:26 pm
- Location: Opole
- Been thanked: 6 times
Nie jest to bezpieczne. Można sobie zdalnie rozsypać configa będąc daleko poza domem. Powinna być jakaś programowa alternatywa że skoro nie umie się podłączyć przez konfiga to jakoś zapasowym łączem / ustawieniami.
Nie rozumiem też czemu przy każdym czyszczeniu procesora generuje nowy guid
Nie rozumiem też czemu przy każdym czyszczeniu procesora generuje nowy guid
-
lukfud
- Posts: 2480
- Joined: Thu Nov 23, 2017 11:33 pm
- Location: Warszawa
- Has thanked: 13 times
- Been thanked: 11 times
"czyszczeniu procesora"? masz na myśli kasowaniu flash'a?
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
-
Duch__
- Posts: 2199
- Joined: Wed Aug 24, 2016 7:26 pm
- Location: Opole
- Been thanked: 6 times
Jest w Arduino opcja erase flash. Domyślnie mam ją jako disable. Ale jak załącze to wiadomo kasuje wszystko. Na podstawie czego guid jest generowany? MAC adres + ilość funkcji + data kompilacji + nazwa pliku ino?
Najchętniej to to na sztywno ustawie. Wolę mieć channel conflikt niż ciągle wszystko ustawiać od zera przy modyfikacjach softu. Jest to męczące. Z ustawieniami od zera najbardziej męczyłem się przy esp32 który ma 80 kanałów. To była masakra. Ustawiłem guidy, email i wifi na sztywno i jakoś to pracuje.
Najchętniej to to na sztywno ustawie. Wolę mieć channel conflikt niż ciągle wszystko ustawiać od zera przy modyfikacjach softu. Jest to męczące. Z ustawieniami od zera najbardziej męczyłem się przy esp32 który ma 80 kanałów. To była masakra. Ustawiłem guidy, email i wifi na sztywno i jakoś to pracuje.
Dołączam się do pytania. A co do niespodziewanego skasowanie flash to faktycznie jest problemowe. Też z tym walczyłem nie dawno, wyszło przy eksperymentowaniu jak to ujął @radzik_r. Dodałem argument dla klasy Supla::LittleFsConfig configSupla(3000); i zrobiłem offset dla eeprom. Wydawało się że pomogło. Układ w normalnych warunkach działał bez jakichkolwiek problemów ok. 3 miesiące. Tydzień temu, przy wyłączeniu i włączeniu zasilania trach i flash czysty. To się dzieje w trakcie startowania modułu. Część mojego kodu wtedy @klew widział i "rzucił" wzmiankę że nie widzi żadnych zabezpieczeń w kodzie. Zdaje się że chodziło o jakieś zabezpieczenie właśnie flash przed skasowaniem. Nie wnikałem bo myślałem że problem się rozwiązał. Osobiście nie wiem jak takie zabezpieczenie zrobić i gdyby @klew czy ktokolwiek kto wie napisał jak to zrobić, osobiście byłbym wdzięczny.Duch__ wrote: Wed Nov 13, 2024 11:56 am Jest w Arduino opcja erase flash. Domyślnie mam ją jako disable. Ale jak załącze to wiadomo kasuje wszystko. Na podstawie czego guid jest generowany? MAC adres + ilość funkcji + data kompilacji + nazwa pliku ino?
-
Duch__
- Posts: 2199
- Joined: Wed Aug 24, 2016 7:26 pm
- Location: Opole
- Been thanked: 6 times
Pół biedy jak wyleci ssid czy dane do konta. Jak szlak trafi temp setpoint i wkradnie się tam wartość np 0 stopni albo 28 to będąc na urlopie albo zastaniemy potrzaskane od zimna instalacje albo tropiki. W obu przypadkach zbędne koszty.
Możliwość zmiany wszystkich strategicznych parametrów powinna być potwierdzona chociażby nawet głupim kodem typu 1234 czy flagą zezwalającą, tak że procesor nie otrzymując tego kodu / flagi nie ma prawa dokonać żadnych zmian we flashu. Coś na wzór wpisania komendy potwierdzającej reset licznika energii. Sam przycisk "zapisz" to za mało
Możliwość zmiany wszystkich strategicznych parametrów powinna być potwierdzona chociażby nawet głupim kodem typu 1234 czy flagą zezwalającą, tak że procesor nie otrzymując tego kodu / flagi nie ma prawa dokonać żadnych zmian we flashu. Coś na wzór wpisania komendy potwierdzającej reset licznika energii. Sam przycisk "zapisz" to za mało
-
Duch__
- Posts: 2199
- Joined: Wed Aug 24, 2016 7:26 pm
- Location: Opole
- Been thanked: 6 times
Czemu te procedury:
ustawione w nie działają?
Chciałbym żeby na dzień dobry ustawiło mi te wartości bym nie musiał ich na nowo ustawiać przy każdej nowej, testowej rejestracji termostatu.
Code: Select all
hvac_1->setUsedAlgorithm(SUPLA_HVAC_ALGORITHM_ON_OFF_SETPOINT_AT_MOST);
hvac_1->setMinOnTimeS(120);
hvac_1->setMinOffTimeS(180);
hvac_1->setTemperatureFreezeProtection(1100);
hvac_1->setTemperatureHeatProtection(2700);
hvac_1->setTemperatureEco(2200);
hvac_1->setTemperatureComfort(2300);
hvac_1->setTemperatureAboveAlarm(2750);
hvac_1->setTemperatureBelowAlarm(1050);Code: Select all
void setup() {}Chciałbym żeby na dzień dobry ustawiło mi te wartości bym nie musiał ich na nowo ustawiać przy każdej nowej, testowej rejestracji termostatu.
