jestem kompletnie "zielony" w temacie supla-device, ostatnio zachciało mi się trochę wgłębić w temat aby wykorzystać Suple w swoich projektach ale idzie to coś topornie więc proszę o pomoc :p
Słowem wstępu, mam prosty projekt. ESP32 z ekranem OLED SSD1306 które działa mi jako termometr, temperaturę wewnątrz mierzy DHT22 a temperaturę zewnętrzną postanowiłem sobie zasysać z pobliskiego paczkomatu przez API
I teraz do rzeczy, problemów po drodze miałem sporo ale aktualnie nie mogę przeskoczyć poniższych trzech:
- "SSL error: -1, ERROR - Generic error" - nie mogę połączyć się z serwerem supli, gdzieś się na forum doszukałem, że trzeba ustawić certyfikaty za pomocą "setSuplaCACert" oraz "setSupla3rdPartyCACert" ale to nie pomogło
Code: Select all
Supla - starting initialization (platform 0) Main storage not configured Config storage not configured Channel(0) value changed to temp(27.70), humi(38.60) GUID: 9E69D6EB1490454DBD9B8C18806D8382 Device name: SUPLA-ESP32 Device software version: SDK 24.10.05-dev Initializing network layer [Wi-Fi] Network AP/hostname: SUPLA-ESP32-1C6920302C00 Using Supla protocol version 23 Current status: [5] SuplaDevice initialized Enter normal mode WiFi: establishing connection with SSID: "KMA" Indoor Temperature: 27.70°C, Indoor Humidity: 38.60% WiFi Station disconnected E (10100) wifi:sta is connecting, return error Indoor Temperature: 27.70°C, Indoor Humidity: 38.90% Connected BSSID: 24:E4:CE:55:19:84 local IP: 192.168.0.148 subnetMask: 255.255.255.0 gatewayIP: 192.168.0.1 Signal strength (RSSI): -19 dBm Establishing encrypted connection with: svr32.supla.org (port: 2016) SSL error: -1, ERROR - Generic error Connection fail (0). Server: svr32.supla.org Indoor Temperature: 27.70°C, Indoor Humidity: 38.90% Channel(0) value changed to temp(27.70), humi(38.90) Establishing encrypted connection with: svr32.supla.org (port: 2016) SSL error: -1, ERROR - Generic error Current status: [6] Not connected to Supla server Connection fail (0). Server: svr32.supla.org - Odkąd podpiąłem Suple do projektu to pojawiły się problemy z obsługą OLEDa, wywołanie np. display.println(...) i potem display() kończą się tym, że ESP się wywala a następnie leci restart. Musze/Mogę obsługiwać tego OLEDa ale przez jakieś metodki z libki supli zamiast te z libki od Adafruit?
Code: Select all
Device software version: SDK 24.10.05-dev Initializing network layer [Wi-Fi] Network AP/hostname: SUPLA-ESP32-1C6920302C00 Using Supla protocol version 23 Current status: [5] SuplaDevice initialized Enter normal mode WiFi: establishing connection with SSID: "KMA" Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled. Core 1 register dump: PC : 0x4008a514 PS : 0x00060b30 A0 : 0x800db688 A1 : 0x3ffb21d0 A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000400 A5 : 0x00000000 A6 : 0x00000000 A7 : 0x00000040 A8 : 0x00000001 A9 : 0x71eb851e A10 : 0x028f5c28 A11 : 0x00000000 A12 : 0x00002710 A13 : 0x0000e5c0 A14 : 0x3ffc4f94 A15 : 0x3ffc45a0 SAR : 0x00000002 EXCCAUSE: 0x0000001d EXCVADDR: 0x00000000 LBEG : 0x4008a514 LEND : 0x4008a51f LCOUNT : 0x0000003f Backtrace: 0x4008a511:0x3ffb21d0 0x400db685:0x3ffb21e0 0x400d3be3:0x3ffb2200 0x400ed23c:0x3ffb2270 0x40090972:0x3ffb2290 - I ostatnie to pytanie w jaki sposób mogę zrobić sobie w supli kanał z fake termometrem do którego dane będę przekazywać z API zamiast z DHT? Gdzieś na forum widziałem jakiś przykład wirtualnego termometru, który działał na zasadzie klaski, która dziedziczyła chyba z DHT ale miała nadpisane metodki od zwracania danych, nie mogę niestety teraz tego odnaleźć. Dobrze rozumiem, że to jest najprostsze obejście?
Będę wdzięczny za wszystkie porady!
Code: Select all
#include <HTTPClient.h>
#include <Arduino_JSON.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <DHT.h>
#include <config.h>
#include <ArduinoOTA.h>
#include <SuplaDevice.h>
#include <supla/sensor/DHT.h>
#include <supla/network/esp_wifi.h>
#include <supla/device/supla_ca_cert.h>
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASS;
Supla::ESPWifi wifi(ssid, password);
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const String apiUrl = "https://greencity.pl/shipx-point-data/248/KRA186M/air_index_level";
#define DHTPIN 4 // Define the pin connected to the DHT sensor
#define DHTTYPE DHT22 // Define sensor type (DHT22)
DHT dht(DHTPIN, DHTTYPE);
float lastTemperature = -1, lastHumidity = -1, lastPM25Percent = -1, lastPM10Percent = -1, lastPressure = -1;
String lastQuality = "";
float indoorTemperature = -1, indoorHumidity = -1;
unsigned long previousAPIMillis = 0, previousDHTMillis = 0, previousDisplayMillis = 0;
const long apiInterval = 300000; // 5 minutes in milliseconds
const long dhtInterval = 5000; // 5 seconds in milliseconds
const long displayInterval = 5000; // 5 seconds display switch interval
bool displayOutdoor = false; // Toggle display between indoor and outdoor
void setup() {
Serial.begin(115200);
pinMode(DHTPIN, INPUT_PULLUP);
dht.begin();
char GUID[SUPLA_GUID_SIZE] = SUPLA_GUID;
char AUTHKEY[SUPLA_AUTHKEY_SIZE] = SUPLA_KEY;
// CHANNEL0 - DHT22 Sensor
new Supla::Sensor::DHT(DHTPIN, DHTTYPE);
SuplaDevice.setSuplaCACert(suplaCACert);
SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
SuplaDevice.setAutomaticResetOnConnectionProblem(60);
SuplaDevice.begin(GUID, // Global Unique Identifier
"svr32.supla.org ", // SUPLA server address
"[email protected]", // Email address used to login to Supla Cloud
AUTHKEY);
}
bool otaReady = false;
void loop() {
SuplaDevice.iterate();
// moved here from setup, supla should handle WiFi so we just wait, right?
if(WiFi.status() == WL_CONNECTED && !otaReady){
// OTA
ArduinoOTA.setPassword("wifi-temp-ota");
ArduinoOTA
.onStart([]() {
})
.onEnd([]() {
})
.onProgress([](unsigned int progress, unsigned int total) {
})
.onError([](ota_error_t error) {
});
ArduinoOTA.begin();
otaReady = true;
}
if(otaReady){
ArduinoOTA.handle();
}
unsigned long currentMillis = millis();
// Fetch API data every 5 minutes
if (currentMillis - previousAPIMillis >= apiInterval || previousAPIMillis == 0) {
fetchWeatherData();
previousAPIMillis = currentMillis;
}
// Read DHT22 sensor data every 5 seconds
if (currentMillis - previousDHTMillis >= dhtInterval || previousDHTMillis == 0) {
// wait 2s on first run to let the sensor initialize
if (previousDHTMillis == 0) {
}
indoorTemperature = dht.readTemperature();
indoorHumidity = dht.readHumidity();
Serial.print("Indoor Temperature: ");
Serial.print(indoorTemperature);
Serial.print("°C, Indoor Humidity: ");
Serial.print(indoorHumidity);
Serial.println("%");
previousDHTMillis = currentMillis;
}
// Switch display between indoor and outdoor data every 5 seconds
if (currentMillis - previousDisplayMillis >= displayInterval || previousDisplayMillis == 0) {
displayOutdoor = !displayOutdoor;
if (displayOutdoor) {
displayWeatherData("Outdoor", lastTemperature, lastHumidity, lastPM25Percent, lastPM10Percent, lastPressure, lastQuality);
} else {
displayWeatherData("Indoor", indoorTemperature, indoorHumidity, -1, -1, -1, "");
}
previousDisplayMillis = currentMillis;
}
}
void fetchWeatherData() {
// check is wifi connected
if (WiFi.status() != WL_CONNECTED) {
return;
}
// show fetching message on first run
if(previousAPIMillis == 0){
}
HTTPClient http;
http.begin(apiUrl);
http.addHeader("X-Requested-With", "XMLHttpRequest");
int httpResponseCode = http.POST("");
if (httpResponseCode == 200) {
String payload = http.getString();
JSONVar response = JSON.parse(payload);
if (JSON.typeof(response) == "undefined") {
Serial.println("Parsing failed!");
displayError("API parse error");
} else {
lastTemperature = parseSensorValue(response, "TEMPERATURE");
lastHumidity = parseSensorValue(response, "HUMIDITY");
lastPM25Percent = parseSensorPercentage(response, "PM25");
lastPM10Percent = parseSensorPercentage(response, "PM10");
lastPressure = parseSensorValue(response, "PRESSURE");
if (response.hasOwnProperty("air_index_level") && JSON.typeof(response["air_index_level"]) != "null") {
lastQuality = (const char*)response["air_index_level"];
} else {
Serial.println("Air Index Level is not available.");
}
}
} else {
displayError("API request error");
}
http.end();
}
float parseSensorValue(JSONVar response, String sensorName) {
JSONVar sensors = response["air_sensors"];
for (int i = 0; i < sensors.length(); i++) {
String sensorData = sensors[i];
int pos = sensorData.indexOf(":");
String name = sensorData.substring(0, pos);
if (name == sensorName) {
String value = sensorData.substring(pos + 1, sensorData.indexOf(":", pos + 1));
return value.toFloat();
}
}
return -1; // return -1 if sensor not found
}
float parseSensorPercentage(JSONVar response, String sensorName) {
JSONVar sensors = response["air_sensors"];
for (int i = 0; i < sensors.length(); i++) {
String sensorData = sensors[i];
int firstColon = sensorData.indexOf(":");
int secondColon = sensorData.indexOf(":", firstColon + 1);
String name = sensorData.substring(0, firstColon);
if (name == sensorName && secondColon != -1) {
String percentage = sensorData.substring(secondColon + 1);
return percentage.toFloat();
}
}
return -1; // return -1 if sensor not found
}
void displayWeatherData(String source, float temperature, float humidity, float pm25Percent, float pm10Percent, float pressure, String quality) {
}
void displayError(String message) {
}
