mqtt_sav2
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <StackArray.h>
//#include <b64.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ESP8266HTTPClient.h>
//#include <ArduinoJson.h>
//if (client.connect(" ESP8266Client_Rom55", - измененнй Client
//Бегущая строка
//Time intervals for tasks
const uint32_t draw_topics_interval = 1000;
const uint32_t count_seconds = 30000;
unsigned long yandex_api_call_interval = 43200; // in seconds
//process timers
uint32_t current_time_process_1 = 0;
uint32_t current_time_process_2 = 0;
unsigned long epoch_time = 0;
unsigned long now_epoch_time = yandex_api_call_interval;
// WiFi credentials and MQTT broker information
const char* ssid = "Keenetic-6391";
const char* password = "U7Y6hMeB";
const char* mqtt_server = "192.168.1.75";
const char* mqtt_username = "mqtt"; // если требуется
const char* mqtt_password = "mq485127sav"; // если требуется
// MQTT topics
const char* air_temperature_topic = "air_temperature";
const char* water_temperature_topic = "water_temperature";
const char* humidity_topic = "humidity";
//Добавка от 5.01.2025 навес
const char* air_temp_naves_topic = "air_temp_naves";
const char* humedity_naves_topic = "humedity_naves";
const char* P_naves_topic = "P_naves";
const char* water_level_topic = "water_level";
// Yandex.Weather API information
const char* api_key = "141eea13-8ecd-4900-b928-048976a66f68";
const char* location = "shakhty";
const char* lang = "ru_RU";
bool start_draw = false;
// Matrix dimensions and pins
const int matrix_width = 4; // количество светодиодов в матрице
const int matrix_height = 1; // количество строк светодиодов в матрице
//const int matrix_cs_pin = D8; // пин выбора MAX7219
const int matrix_cs_pin = 15; // пин выбора MAX7219 io15
//const int matrix_clk_pin = D5; // пин тактового сигнала MAX7219
const int matrix_clk_pin = 14; // пин тактового сигнала MAX7219 io14
//const int matrix_data_pin = D7; // пин данных MAX7219
const int matrix_data_pin = 13; // пин данных MAX7219 io13
const int matrix_num_devices = 4; // количество устройств MAX7219 в цепи
Max72xxPanel matrix = Max72xxPanel(matrix_cs_pin, matrix_height, matrix_width);
// MQTT client and WiFi client
WiFiClient espClient;
WiFiClientSecure espClientDouble;
PubSubClient client(espClient);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
// переменные для хранения показаний датчиков
float air_temperature = 0;
float water_temperature = 0;
float humidity = 0;
//Добавка топиков от навеса от 7.01.2025
float air_temp_naves = 0;
float P_naves = 0;
float humedity_naves = 0;
String water_level = "";
// переменные для хранения данных с Yandex
String y_temperature;
String y_condition;
String y_description;
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
Serial.print(WiFi.status());
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
char msg[length + 1];
for (int i = 0; i < length; i++) {
msg[i] = (char)payload[i];
}
msg[length] = '\0';
Serial.println(msg);
if (strcmp(topic, air_temperature_topic) == 0) {
Serial.print("air temperature: ");
air_temperature = atof(msg);
Serial.println(air_temperature);
} else if (strcmp(topic, water_temperature_topic) == 0) {
Serial.print("water temperature: ");
water_temperature = atof(msg);
Serial.println(water_temperature);
} else if (strcmp(topic, humidity_topic) == 0) {
Serial.print("humidity: ");
humidity = atof(msg);
Serial.println(humidity);
} else if (strcmp(topic, water_level_topic) == 0) {
Serial.print("water_level: ");
water_level = "";
water_level = msg;
Serial.println(water_level);
//Добавка топиков от навеса от 7.01.2025
} else if (strcmp(topic, air_temp_naves_topic) == 0) {
Serial.print("air_temp_naves: ");
air_temp_naves = atof(msg);
Serial.println(air_temp_naves);
} else if (strcmp(topic, humedity_naves_topic) == 0) {
Serial.print("humedity_naves: ");
humedity_naves = atof(msg);
Serial.println(humedity_naves);
} else if (strcmp(topic,P_naves_topic) == 0) {
Serial.print("P_naves: ");
P_naves = atof(msg);
Serial.println(P_naves);
//Конец добавки
}
Serial.println("END void callback");
}
void setup() {
Serial.begin(9600);
SPI.begin();
matrix.setIntensity(5);
matrix.fillScreen(LOW);
matrix.setRotation(1);
matrix.write();
setup_wifi();
timeClient.begin();
// Set offset time in seconds to adjust for your timezone, for example:
// GMT +1 = 3600
// GMT +3 = 10800
// GMT +8 = 28800
// GMT -1 = -3600
// GMT 0 = 0
timeClient.setTimeOffset(10800);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
DynamicJsonDocument doc(2048);
// Предположим, что response - это ваша строка JSON
String response = "{\"hello\":\"world\"}";
// Разбираем объект JSON в строке
DeserializationError error = deserializeJson(doc, response);
// Проверяем, удалось ли разбор.
if (error) {
Serial.print(F("deserializeJson() не удалось: "));
Serial.println(error.f_str());
return;
}
// Получаем корневой объект JSON
JsonObject root = doc.as<JsonObject>();
// Теперь вы можете использовать root для доступа к элементам в JSON
const char* hello = root["hello"]; // "world"
Serial.println("End setup");
}
void drawString(const String &str, int16_t x, int16_t y) {
Serial.println("START-drawString");
int spacer = 1;
int width = 5 + spacer;
for (int i = 0; i < width * str.length() + matrix.width() - 1 - spacer; i++) {
matrix.fillScreen(LOW);
int letter = i / width;
int x = (matrix.width() - 1) - i % width;
int y = (matrix.height() - 8) / 2; // центровка по вертикали
while (x + width - spacer >= 0 && letter >= 0) {
if (letter < str.length()) {
matrix.drawChar(x, y, str[letter], HIGH, LOW, 1);
}
letter--;
x -= width;
}
matrix.write();
delay(50);
client.loop();
}
Serial.println("ENDSTART-drawString");
}
const String get_reduced_json(WiFiClient* stream_ptr) {
StackArray<char> brackets_stack;
const int max_sizeof_buff = (int)(ESP.getFreeHeap() * 0.2);
String res("");
bool begin_search = false;
bool fact_match = false;
bool one_bracket_found = false;
int i = 0;
char* fact_keyword = "fact";
while (stream_ptr->available()) {
fact_match = true;
char c = stream_ptr->read();
if (c != fact_keyword[i]) {
fact_match = false;
i = 0;
} else {
if (fact_match && i == 3) {
begin_search = true;
i = 0;
}
i++;
}
if (begin_search) {
if (c == '{') {
brackets_stack.push(c);
} else if (c == '}') {
brackets_stack.pop();
one_bracket_found = true;
}
if (brackets_stack.isEmpty() && one_bracket_found) {
res += c;
res += '}';
return res;
}
}
res += c;
}
return "";
}
void get_yandex_info() {
Serial.println("Updating Yandex data");
HTTPClient http; // Declare HTTPClient here
const String url = "https://api.weather.yandex.ru/v2/forecast/?lat=47.709236&lon=40.215405&lang=ru_RU";
espClientDouble.setInsecure();
http.begin(espClientDouble, url);
// http.begin(url);
http.addHeader("X-Yandex-API-Key", api_key);
int httpCode = http.GET();
Serial.println("httpCode: ");
Serial.println(httpCode);
if (httpCode > 0) {
WiFiClient* stream = http.getStreamPtr();
const String response = get_reduced_json(stream);
Serial.println(response);
//ArduinoJson::StaticJsonBuffer<2048> jsonBuffer; // Use StaticJsonBuffer for ArduinoJson 5
DynamicJsonDocument doc(8128);
DeserializationError error = deserializeJson(doc, response);
if (error) {
Serial.print(F("deserializeJson() не удалось: "));
Serial.println(error.f_str());
return;
}
//ArduinoJson::JsonObject& root = jsonBuffer.parseObject(response);
JsonObject root = doc.as<JsonObject>();
String temperature = root["fact"]["temp"];
String condition = root["fact"]["condition"];
String description = root["fact"]["condition"];
Serial.print("Temperature: ");
Serial.println(temperature);
Serial.print("Condition: ");
Serial.println(condition);
Serial.print("Description: ");
Serial.println(description);
y_temperature = temperature;
y_condition = condition;
y_description = description;
} else {
Serial.println("response <= 0");
}
http.end(); // Properly end the HTTPClient
}
void drawWeather() {
String weather = "Temp " + y_temperature + "C " + y_condition + " " + y_description;
drawString(weather.c_str(), matrix_width, 0);
matrix.fillScreen(LOW);
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
//if (client.connect(" ESP8266ClientRom", mqtt_username, mqtt_password)) {
if (client.connect(" ESP8266ClientRom55")) {
Serial.println("connected");
client.subscribe(air_temperature_topic);
client.subscribe(water_temperature_topic);
client.subscribe(humidity_topic);
client.subscribe(water_level_topic);
//добавка от 7.01.2025 навес
client.subscribe(air_temp_naves_topic);
client.subscribe(humedity_naves_topic);
client.subscribe(P_naves_topic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds");
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (now_epoch_time - epoch_time >= yandex_api_call_interval) {
get_yandex_info();
epoch_time = now_epoch_time;
}
// if (millis() - current_time_process_1 >= count_seconds) {
// now_epoch_time += 30;
// Serial.println("Seconds counted");
// current_time_process_1 = millis();
// }
if (millis() - current_time_process_2 >= draw_topics_interval) {
timeClient.update();
now_epoch_time = timeClient.getEpochTime();
Serial.println("elapsed: ");
Serial.println(now_epoch_time - epoch_time);
String formatted_time = timeClient.getFormattedTime();
struct tm * ptm;
time_t rawtime = timeClient.getEpochTime();
ptm = localtime (&rawtime);
int month_day = ptm->tm_mday;
int current_month = ptm->tm_mon+1;
int current_year = ptm->tm_year+1900;
String current_date = String(current_year) + "-" + String(current_month) + "-" + String(month_day);
matrix.fillScreen(LOW);
String topics = current_date + " " + formatted_time + " Air temp " + String(air_temperature, 1) + "C " + "water temp " + String(water_temperature, 1) + "C " + "humidity " + String(humidity, 1) + "% " + "water level " + water_level + "";
drawString(topics.c_str(), matrix_width, 0);
drawString("Forecast: ", matrix_width, 0);
drawWeather();
current_time_process_2 = millis();
}
}