11#include <HDC1080JS.h>
22#include <BH1750.h>
33#include "Wire.h"
4+ #include <WiFiClientSecure.h>
5+ #include <HTTPClient.h>
46
57// external sensors
68#include <Adafruit_AHTX0.h>
79#include <SensirionI2cScd4x.h>
810#include <ccs811.h>
911
10-
11- #define BUZZER_CHANNEL 0 // LEDC channel (0–15)
12- #define BUZZER_FREQ 4000 // Frequency in Hz (2kHz tone)
13- #define BUZZER_RES 8 // Resolution in bits (8 bits = 0–255)
14- #define DUTY_CYCLE 128 // 50% duty cycle (128/255)
15-
12+ #define BUZZER_CHANNEL 0 // LEDC channel (0–15)
13+ #define BUZZER_FREQ 4000 // Frequency in Hz (2kHz tone)
14+ #define BUZZER_RES 8 // Resolution in bits (8 bits = 0–255)
15+ #define DUTY_CYCLE 128 // 50% duty cycle (128/255)
1616
1717HDC1080JS hdc ;
1818BH1750 lightMeter ;
@@ -34,11 +34,9 @@ unsigned long tuneDuration(int tune) {
3434 return 0 ;
3535}
3636
37-
3837// declare it here for the compiler
3938void mqttHaPublish (const char * topic , const char * payload , bool retain = true);
4039
41-
4240void playback (int * melody , int * duration , int length ) {
4341 for (int i = 0 ; i < length ; i ++ ) {
4442 ledcWriteTone (BUZZER_CHANNEL , melody [i ]);
@@ -49,39 +47,37 @@ void playback(int* melody, int* duration, int length) {
4947 }
5048}
5149
52-
5350void playTune (int tune ) {
54-
5551 // 0 = none, 1 = beep, 2 = alarm, 3 = melody, 99 = startup
5652 if (tune == 1 ) {
5753 // beep
5854 logger ("Playing beep tune" , "Device" );
5955
60- int melody [] = { 880 , 880 };
61- int duration [] = { 250 , 250 };
56+ int melody [] = {880 , 880 };
57+ int duration [] = {250 , 250 };
6258 playback (melody , duration , 2 );
6359
6460 } else if (tune == 2 ) {
6561 // alarm
6662 logger ("Playing alarm tune" , "Device" );
6763
6864 // A5, F5, C5
69- int melody [] = { 880 , 698 , 523 };
70- int duration [] = { 150 , 150 , 300 };
65+ int melody [] = {880 , 698 , 523 };
66+ int duration [] = {150 , 150 , 300 };
7167 playback (melody , duration , 3 );
7268
7369 } else if (tune == 3 ) {
7470 // melody
7571 logger ("Playing melody tune" , "Device" );
7672
77- int melody [] = { 659 , 698 , 784 , 0 , 784 , 880 , 988 , 0 , 988 , 1046 , 1175 , 0 , 1318 , 1175 , 1046 , 0 , 988 , 784 , 880 , 0 , 659 , 784 , 523 };
78- int duration [] = { 150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 400 , 200 , 600 };
73+ int melody [] = {659 , 698 , 784 , 0 , 784 , 880 , 988 , 0 , 988 , 1046 , 1175 , 0 , 1318 , 1175 , 1046 , 0 , 988 , 784 , 880 , 0 , 659 , 784 , 523 };
74+ int duration [] = {150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 150 , 150 , 300 , 100 , 400 , 200 , 600 };
7975 playback (melody , duration , 23 );
8076
81- } else if (tune == 99 ) {
77+ } else if (tune == 99 ) {
8278 // C5, E5, G5, C6
83- int melody [] = { 523 , 659 , 783 , 1046 };
84- int duration [] = { 200 , 200 , 200 , 400 };
79+ int melody [] = {523 , 659 , 783 , 1046 };
80+ int duration [] = {200 , 200 , 200 , 400 };
8581 playback (melody , duration , 4 );
8682
8783 } else {
@@ -90,9 +86,7 @@ void playTune(int tune) {
9086 }
9187}
9288
93-
9489void setupBuzzer () {
95-
9690 ledcSetup (BUZZER_CHANNEL , BUZZER_FREQ , BUZZER_RES );
9791 ledcAttachPin (BUZZER_PIN , BUZZER_CHANNEL );
9892
@@ -122,9 +116,7 @@ void buzzerLoop() {
122116 }
123117}
124118
125-
126119void setupSensors () {
127-
128120 Wire .begin (I2C_SDA , I2C_SCL );
129121 Wire .setClock (400000 );
130122 delay (200 );
@@ -134,39 +126,36 @@ void setupSensors() {
134126
135127 lightMeter .begin ();
136128
137-
138- if (appConfig .externalSensorSet ) {
139- if (appConfig .externalSensor == 1 ) {
129+ if (appConfig .externalSensorSet ) {
130+ if (appConfig .externalSensor == 1 ) {
140131 // AHT10
141132 aht .begin ();
142133
143- } else if (appConfig .externalSensor == 2 ) {
134+ } else if (appConfig .externalSensor == 2 ) {
144135 // SCD40
145136 scd4x .begin (Wire , SCD40_I2C_ADDR_62 );
146137 scd4x .wakeUp ();
147138 scd4x .stopPeriodicMeasurement ();
148139 scd4x .reinit ();
149140 scd4x .startPeriodicMeasurement ();
150141
151- } else if (appConfig .externalSensor == 3 ) {
142+ } else if (appConfig .externalSensor == 3 ) {
152143 // SCD41
153144 scd4x .begin (Wire , SCD41_I2C_ADDR_62 );
154145 scd4x .wakeUp ();
155146 scd4x .stopPeriodicMeasurement ();
156147 scd4x .reinit ();
157148 scd4x .startPeriodicMeasurement ();
158149
159- } else if (appConfig .externalSensor == 4 ) {
150+ } else if (appConfig .externalSensor == 4 ) {
160151 // CCS811
161152 ccs811 .begin ();
162153 ccs811 .start (CCS811_MODE_1SEC );
163154 }
164155 }
165156}
166157
167-
168158void sensorLoop () {
169-
170159 unsigned long currentTime = millis ();
171160
172161 if (currentTime - lastSensorReadTime >= appConfig .sensorUpdateInterval ) {
@@ -179,18 +168,17 @@ void sensorLoop() {
179168 float humid = hdc .getRelativeHumidity ();
180169
181170 // convert to fahrenheit if set so
182- if (!isCelsius ) {
171+ if (!isCelsius ) {
183172 temp = (temp * 9.0 / 5.0 ) + 32.0 ;
184173 }
185174
186175 float lux = 0 ;
187- //float lux = lightMeter.readLightLevel();
176+ // float lux = lightMeter.readLightLevel();
188177
189178 bool tempChanged = fabs (temp - appConfig .temperature ) >= appConfig .tempThreshold ;
190179 bool humidityChanged = fabs (humid - appConfig .humidity ) >= appConfig .humThreshold ;
191180 bool luxChanged = fabs (lux - appConfig .lux ) >= appConfig .luxThreshold ;
192181
193-
194182 // check if any sensor value changed
195183 if (tempChanged ) {
196184 appConfig .temperature = temp ;
@@ -249,48 +237,78 @@ void sensorLoop() {
249237 events .send (response .c_str (), "door" , millis ());
250238 }
251239
252-
253240 // external sensors
254- if (appConfig .externalSensorSet ) {
255- if (appConfig .externalSensor == 1 ) {
241+ if (appConfig .externalSensorSet ) {
242+ if (appConfig .externalSensor == 1 ) {
256243 // AHT10
257244 sensors_event_t humidity , temperature ;
258245 aht .getEvent (& humidity , & temperature );
259-
260- if (!isCelsius ) {
246+
247+ if (!isCelsius ) {
261248 temperature .temperature = (temperature .temperature * 9.0 / 5.0 ) + 32.0 ;
262249 }
263250
264251 // convert sensor data to JSON string
265252 appConfig .extSensorData = "{\"temperature\":" + String (temperature .temperature , 2 ) +
266- ",\"humidity\":" + String (humidity .relative_humidity , 2 ) + "}" ;
253+ ",\"humidity\":" + String (humidity .relative_humidity , 2 ) + "}" ;
267254
268- } else if (appConfig .externalSensor == 2 || appConfig .externalSensor == 3 ) {
255+ } else if (appConfig .externalSensor == 2 || appConfig .externalSensor == 3 ) {
269256 // SCD40 or SCD41
270257 uint16_t co2 ;
271258 float temperature , humidity ;
272259 scd4x .readMeasurement (co2 , temperature , humidity );
273-
274- if (!isCelsius ) {
260+
261+ if (!isCelsius ) {
275262 temperature = (temperature * 9.0 / 5.0 ) + 32.0 ;
276263 }
277264
278265 // convert sensor data to JSON string
279266 appConfig .extSensorData = "{\"co2\":" + String (co2 ) +
280- ",\"temperature\":" + String (temperature , 2 ) +
281- ",\"humidity\":" + String (humidity , 2 ) + "}" ;
267+ ",\"temperature\":" + String (temperature , 2 ) +
268+ ",\"humidity\":" + String (humidity , 2 ) + "}" ;
282269
283- } else if (appConfig .externalSensor == 4 ) {
270+ } else if (appConfig .externalSensor == 4 ) {
284271 // CCS811
285272 uint16_t eco2 , etvoc , errstat , raw ;
286273 ccs811 .read (& eco2 , & etvoc , & errstat , & raw );
287-
274+
288275 // convert sensor data to JSON string
289276 appConfig .extSensorData = "{\"eco2\":" + String (eco2 ) +
290- ",\"etvoc\":" + String (etvoc ) +
291- ",\"errstat\":" + String (errstat ) +
292- ",\"raw\":" + String (raw ) + "}" ;
277+ ",\"etvoc\":" + String (etvoc ) +
278+ ",\"errstat\":" + String (errstat ) +
279+ ",\"raw\":" + String (raw ) + "}" ;
293280 }
294281 }
295282 }
283+ }
284+
285+ bool checkForFirmwareUpdate () {
286+ WiFiClientSecure client ;
287+ client .setInsecure ();
288+
289+ String url = "https://api.github.com/repos/derDeno/PandaGarage/releases/latest" ;
290+
291+ HTTPClient https ;
292+ https .begin (client , url );
293+ https .addHeader ("User-Agent" , "PandaGarage" );
294+
295+ int httpCode = https .GET ();
296+ if (httpCode == HTTP_CODE_OK ) {
297+ String payload = https .getString ();
298+ https .end ();
299+
300+ JsonDocument doc ;
301+ auto err = deserializeJson (doc , payload );
302+ if (err ) {
303+ Serial .printf ("JSON parse failed: %s\n" , err .c_str ());
304+ return false;
305+ }
306+
307+ const char * latestTag = doc ["tag_name" ];
308+ return (strcmp (latestTag , VERSION ) != 0 );
309+
310+ } else {
311+ https .end ();
312+ return false;
313+ }
296314}
0 commit comments