Zdař, pokud by měl někdo zájem zde jsem vyvinul program pro Raspberry pi pico W a stahování dat z OTE.cz.
Můžete si upravit k obrazu svému. Já to budu ještě upravovat a přidávat si relátka a diody. Programováno přes Arduino IDE.
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
String payload = "";
HTTPClient http;
long countErr = 0;
long countAll = 0;
int quarterHour = 0;
int previousQuarterHour = -1;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0; // Přidáno pro řízení blikání Wi-Fi LED
unsigned long previousMillis3 = 0; // Přidáno pro řízení blikání LED při stahování dat
float price_threshold = 10.0;
float weighted_avg_threshold = 10.0;
String Stav = "";
int loopCounter = 0;
bool twoValueDiffNul = false;
const int ledPin = 0; // signalizace, že cena není pod 10 EUR
const int ledPin1 = 1; // signalizace, že se data stahují
const int ledPin2 = 2; // signalizace Wi-Fi připojení
const int ledPin3 = 3; // signalizace načtení dat OK / NOK
const char* ssid = "Vaš název Wifi Sítě";
const char* password = "Vaše heslo na Wifi Síť";
const char* serverUrl = "
https://www.ote-cr.cz/en/short-term-mar ... tion=PT15M";
const int maxDataSize = 400;
struct DataPoint {
String time;
float value;
};
DataPoint dataArray[maxDataSize];
int dataCount = 0;
WiFiUDP udp;
NTPClient timeClient(udp, "pool.ntp.org", 3600, 1000);
void setup() {
Serial.begin(115200);
delay(100);
pinMode(ledPin, OUTPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT); // Inicializace 4. LED pro signalizaci načtení dat
// Připojení k Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis2 >= 500) {
previousMillis2 = currentMillis;
digitalWrite(ledPin2, !digitalRead(ledPin2)); // Blikání LED při pokusu o připojení k Wi-Fi
}
}
digitalWrite(ledPin2, HIGH); // LED svítí, když je Wi-Fi připojeno
Serial.println("Připojeno k Wi-Fi");
timeClient.begin();
}
// Funkce pro aktualizaci dat
void updateData() {
twoValueDiffNul = false;
++countAll;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis3 >= 500) {
previousMillis3 = currentMillis;
digitalWrite(ledPin1, !digitalRead(ledPin1)); // Blikání LED při stahování dat
}
http.begin(serverUrl);
http.setInsecure(); // Nepoužíváme bezpečnou HTTPS komunikaci
int httpCode = http.GET();
if (httpCode == 200) { // Pokud je HTTP odpověď 200 (OK)
payload = http.getString();
delay(1000);
// Nastavení kapacity pro JSON dokument
const size_t capacity = JSON_ARRAY_SIZE(500) + 500 * JSON_OBJECT_SIZE(2);
StaticJsonDocument<capacity> doc;
DeserializationError error = deserializeJson(doc, payload);
// Kontrola chyb při deserializaci
if (error) {
++countErr;
Serial.print("Chyba při deserializaci: ");
Serial.println(error.f_str());
if (countErr < 3) { // Maximálně 3 pokusy
Serial.println("Zkouším znovu získat data...");
delay(500);
quarterHour = 0;
clearDataArray();
delay(2500);
digitalWrite(ledPin3, LOW); // Pokud je problém s daty, LED3 je vypnuta (NOK)
return;
} else {
Serial.println("Po 3 pokusech stále není možné deserializovat data.");
digitalWrite(ledPin1, LOW); // LED přestane blikat po 3 pokusech
digitalWrite(ledPin3, LOW); // Pokud stále není možné deserializovat, LED3 je vypnuta (NOK)
return;
}
}
// Získání pole dat z JSON
JsonArray dataLine = doc["data"]["dataLine"].as<JsonArray>();
if (dataLine.isNull()) {
Serial.println("DataLine je prázdné nebo neexistuje.");
++countErr;
digitalWrite(ledPin3, LOW); // Pokud dataLine neexistují, LED3 je vypnuta (NOK)
return;
}
// Zpracování jednotlivých bodů dat
for (JsonObject obj : dataLine) {
String title = obj["title"].as<String>();
Serial.println("Title: " + title);
JsonArray points = obj["point"].as<JsonArray>();
for (JsonObject point : points) {
String x = point["x"].as<String>();
float y = point["y"].as<float>();
if (dataCount < maxDataSize) {
dataArray[dataCount].time = x;
dataArray[dataCount].value = y;
dataCount++;
}
Serial.print("X: ");
Serial.print(x);
Serial.print(", Y: ");
Serial.println(y);
}
}
digitalWrite(ledPin3, HIGH); // Pokud data byla úspěšně načtena, LED3 svítí (OK)
} else { // Pokud odpověď není OK
Serial.print("Chyba při stahování dat: ");
Serial.println(httpCode);
++countErr;
digitalWrite(ledPin3, LOW); // Pokud data nejsou správně načtena, LED3 je vypnuta (NOK)
delay(5000); // Po chybě HTTP čekáme 5 sekund před dalším pokusem
}
digitalWrite(ledPin1, LOW); // Data úspěšně stažena, LED přestane blikat
http.end();
}
// Funkce pro aktualizaci času
void updateTime() {
timeClient.update();
String currentTime = timeClient.getFormattedTime();
int hours = timeClient.getHours();
int minutes = timeClient.getMinutes();
int seconds = timeClient.getSeconds();
int totalSeconds = hours * 3600 + minutes * 60 + seconds;
int newQuarterHour = totalSeconds / 900;
Serial.print(currentTime + " | ");
Serial.print(quarterHour + " | ");
Serial.print(dataArray[quarterHour].value);
Serial.print(" | ");
Serial.print(dataArray[quarterHour + 96].value);
Serial.print(" | ");
Serial.print(dataArray[quarterHour + 192].value);
Serial.print(" | ");
Serial.print(dataArray[quarterHour + 288].value);
Serial.print(" | ");
Serial.print("CounterErr: | " + countErr);
Serial.print(" | ");
Serial.print("CounterAll: | " + countAll);
// Přidání stavu LED diod
Serial.print(" | LED1 (Ceny nad 10 EUR): ");
Serial.print(digitalRead(ledPin) == HIGH ? "ON" : "OFF"); // Stav LED1 (signalizace ceny pod 10 EUR)
Serial.print(" | LED2 (Stahování dat): ");
Serial.print(digitalRead(ledPin1) == HIGH ? "ON" : "OFF"); // Stav LED2 (signalizace stahování dat)
Serial.print(" | LED3 (Wi-Fi připojení): ");
Serial.print(digitalRead(ledPin2) == HIGH ? "ON" : "OFF"); // Stav LED3 (signalizace Wi-Fi připojení)
Serial.print(" | LED4 (Data načtena OK/NOK): ");
Serial.println(digitalRead(ledPin3) == HIGH ? "OK" : "NOK"); // Stav LED4 (signalizace načtení dat)
// Kontrola změny čtvrtiny hodiny
if (newQuarterHour != quarterHour) {
quarterHour = newQuarterHour;
if (dataArray[quarterHour].value == 0.0 && dataArray[quarterHour + 96].value == 0.0 && dataArray[quarterHour + 192].value == 0.0 && dataArray[quarterHour + 288].value == 0.0) {
Serial.println("Data jsou stále 0.0, opakuji pokus o načtení...");
unsigned long startMillis = millis();
int retryCount = 0;
while (millis() - startMillis < 30000 && retryCount < 3) {
updateData();
int nonZeroCount = 0;
if (dataArray[quarterHour].value != 0.0) nonZeroCount++;
if (dataArray[quarterHour + 96].value != 0.0) nonZeroCount++;
if (dataArray[quarterHour + 192].value != 0.0) nonZeroCount++;
if (dataArray[quarterHour + 288].value != 0.0) nonZeroCount++;
if (nonZeroCount >= 2) {
Serial.println("Alespoň 2 hodnoty jsou nyní různé od 0.0.");
twoValueDiffNul = true;
break;
}
delay(3000);
retryCount++;
}
if (retryCount >= 3) {
Serial.println("Po 3 pokusech se nepodařilo získat data.");
quarterHour = 0;
clearDataArray();
delay(5000);
return;
}
}
}
}
// Funkce pro vyčištění datového pole
void clearDataArray() {
for (int i = 0; i < maxDataSize; i++) {
dataArray
.time = "";
dataArray.value = 0.0;
}
dataCount = 0;
}
void loop() {
// Kontrola připojení k Wi-Fi
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Wi-Fi není připojeno. Pokouším se připojit...");
WiFi.begin(ssid, password);
unsigned long startMillis2 = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startMillis2 < 5000) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis2 >= 500) {
previousMillis2 = currentMillis;
digitalWrite(ledPin2, !digitalRead(ledPin2)); // Blikání LED při pokusu o připojení k Wi-Fi
}
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nPřipojeno k Wi-Fi.");
} else {
Serial.println("\nNepodařilo se připojit k Wi-Fi.");
digitalWrite(ledPin2, LOW); // Pokud Wi-Fi připojení selže, LED zhasne
}
}
// Aktualizace času každých 5 sekund
unsigned long currentMillis = millis();
if (currentMillis - previousMillis1 >= 5000) {
previousMillis1 = currentMillis;
updateTime();
loopCounter++;
}
// Nastavení stavu na základě hodnoty
Stav = (twoValueDiffNul && (dataArray[quarterHour + 288].value < price_threshold || dataArray[quarterHour + 96].value < weighted_avg_threshold)) ? "vypnuto" : "zapnuto";
// Řízení LED na základě stavu
if (loopCounter >= 10) {
loopCounter = 0;
digitalWrite(ledPin, (Stav == "zapnuto" && twoValueDiffNul == true) ? HIGH : LOW);
}
}