supla-device
Loading...
Searching...
No Matches
aqi.eco.h
1/*
2 * Copyright (C) malarz
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19// Dependencies:
20// https://github.com/arduino-libraries/Arduino_JSON
21
22// It use ca. 20kB RAM, so ESP32 is highly recomended
23
24#ifndef SRC_SUPLA_PROTOCOL_AQI_ECO_H_
25#define SRC_SUPLA_PROTOCOL_AQI_ECO_H_
26
27#include <supla/version.h>
28#include <ArduinoJson.h>
29#include <WiFiClientSecure.h>
30#include <supla/protocol/weathersender.h>
31
32namespace Supla {
33namespace Protocol {
34class AQIECO : public Supla::Protocol::WeatherSender {
35 public:
36 explicit AQIECO(Supla::Network* _network, char token[], int refresh = 180,
37 char server[] = "api.aqi.eco", int id = 0)
39 // serverAddress
40 strncpy(serverAddress, server, 32);
41 serverAddress[32] = 0;
42
43 // apiToken
44 if (strlen(token) == 32) {
45 strncpy(apiToken, token, 32);
46 apiToken[32] = 0;
47 } else {
48 apiToken[0] = 0;
49 }
50 SUPLA_LOG_DEBUG("aqi.eco: token: %s", apiToken);
51
52 // refreshTime
53 if (refresh < 120) {
54 refreshTime = 120;
55 } else {
56 refreshTime = refresh;
57 }
58 SUPLA_LOG_DEBUG("aqi.eco: refresh time: %d", refreshTime);
59
60 // sensorId
61 if (id == 0) {
62 uint8_t mac[6] = {};
63 _network->getMacAddr(mac);
64 sensorId = ((mac[2]*256+mac[3])*256+mac[4])*256+mac[5];
65 } else {
66 sensorId = id;
67 }
68 }
69
70 bool sendData() override {
71 if (strlen(apiToken) != 32) {
72 SUPLA_LOG_DEBUG("aqi.eco: wrong token length: %s", apiToken);
73 return false;
74 }
75
76 StaticJsonDocument<768> jsonBuffer;
77 JsonObject json = jsonBuffer.to<JsonObject>();
78
79 json["esp8266id"] = sensorId;
80 json["software_version"] = "Supla_" SUPLA_SHORT_VERSION;
81 JsonArray sensordatavalues = json.createNestedArray("sensordatavalues");
82
83 for (int i=0; i < MAXSENSORS; i++) {
84 if (sensors[i]) {
85 double value = getSensorValue(i);
86 String type = "unknown";
87 switch (i) {
88 case Supla::SenorType::PM1:
89 type = "SPS30_P0";
90 break;
91 case Supla::SenorType::PM2_5:
92 type = "SPS30_P2";
93 break;
94 case Supla::SenorType::PM4:
95 type = "SPS30_P4";
96 break;
97 case Supla::SenorType::PM10:
98 type = "SPS30_P1";
99 break;
100 case Supla::SenorType::TEMP:
101 type = "BME280_temperature";
102 break;
103 case Supla::SenorType::HUMI:
104 type = "BME280_humidity";
105 break;
106 case Supla::SenorType::PRESS:
107 type = "BME280_pressure";
108 value *= 100;
109 break;
110 case Supla::SenorType::LIGHT:
111 type = "ambient_light";
112 break;
113 case Supla::SenorType::WIND:
114 type = "wind_speed";
115 break;
116 case Supla::SenorType::RAIN:
117 type = "rainfall";
118 break;
119 case Supla::SenorType::CO2:
120 type = "conc_co2_ppm";
121 break;
122 }
123
124 if (!isnan(value)) {
125 JsonObject jo = sensordatavalues.createNestedObject();
126 jo["value_type"] = type;
127 jo["value"] = value;
128 } else {
129 return false;
130 }
131 }
132 }
133 char output[768];
134 serializeJson(json, output, 768);
135 SUPLA_LOG_DEBUG("aqi.eco: JSON: %s", output);
136
137 WiFiClientSecure client;
138 client.setInsecure();
139 if (client.connect(serverAddress, 443)) {
140 client.print("POST /update/");
141 client.print(apiToken);
142 client.println(" HTTP/1.1");
143 client.print("Host: ");
144 client.println(serverAddress);
145 client.println("Content-Type: application/json");
146 client.print("Content-Length: ");
147 client.println(strlen(output));
148 client.println();
149 client.println(output);
150
151 SUPLA_LOG_DEBUG("aqi.eco: sended %d bytes to %s/update/%s",
152 strlen(output), serverAddress, apiToken);
153
154 // waiting for response
155 delay(100);
156 if (!client.available()) {
157 SUPLA_LOG_DEBUG("aqi.eco: no bytes to read from %s", serverAddress);
158 return false;
159 }
160 SUPLA_LOG_DEBUG("aqi.eco: reading from %s: %d bytes",
161 serverAddress, client.available());
162
163 output[client.available()] = 0;
164 for (int i=0; client.available(); i++) {
165 output[i] = client.read();
166 if (output[i] == '\n') {
167 output[i] = 0;
168 }
169 }
170 SUPLA_LOG_DEBUG("aqi.eco: response from %s: %s", serverAddress, output);
171 return true;
172 }
173 return false;
174 }
175
176 private:
177 char apiToken[33];
178 char serverAddress[33];
179 uint32_t sensorId = 0;
180};
181} // namespace Protocol
182} // namespace Supla
183
184#endif // SRC_SUPLA_PROTOCOL_AQI_ECO_H_
Definition network.h:36
Definition weathersender.h:45