// Standard ESP8266 libs from project folder #include #include #include #include #include #include // WiFiClient #include // WiFiManager from bib manager // Project includes #include "config.h" #include "config_user.h" //*************************************************************************// const uint8_t VALUES = 8; float currentSensorData[VALUES] = {nanf("no value"), nanf("no value"), nanf("no value"), nanf("no value"), nanf("no value"), nanf("no value"), nanf("no value"), nanf("no value")}; float (*sensors[VALUES])() = {}; uint16_t update_sensor_cnt = 0; uint16_t update_webserver_cnt = 0; WiFiManager wifiManager; //*************************************************************************// void debug(String x) { #ifdef DEBUG Serial.println(x); #endif } void setup() { #if defined(DEBUG) || defined(SERIAL_FEATURE) Serial.begin(115200); #endif // Pin settings pinMode(BAT_CHARGED_PIN, INPUT); pinMode(BAT_CHARGING_PIN, INPUT); pinMode(STATUS_LED_PIN, OUTPUT); pinMode(ANEMOMETER_PIN, INPUT_PULLUP); pinMode(A0, INPUT); digitalWrite(STATUS_LED_PIN, LOW); #ifndef BAT_PINS_D34 debug("D5 D6 used as battery pins"); #else debug("D3 D4 used as battery pins"); #endif #ifdef BATTERY_POWERED criticalBatCheck(); #endif // Establish WiFi connection String wifiName = "oko-weather-" + DEVICE_NAME; wifiManager.setMinimumSignalQuality(WIFI_MINIMUM_SIGNAL_QUALITY); // the time in seconds to wait for the known wifi connection wifiManager.setConnectTimeout(WIFI_AUTOCONNECT_TIMEOUT_S); // the time in seconds to wait for the user to configure the device wifiManager.setTimeout(WIFI_CONFIG_PORTAL_TIMEOUT_S); #ifdef SLEEP_IF_NO_WLAN_CONNECTION while #endif #ifndef SLEEP_IF_NO_WLAN_CONNECTION if #endif (!wifiManager.autoConnect(wifiName.c_str(), "DEADBEEF")) { debug("WiFi connection failed, try again in 5 seconds..."); // If autoconnect to WLAN failed and no client connected, go to deep sleep #ifdef SLEEP_IF_NO_WLAN_CONNECTION ESP.deepSleep(POWERSAVING_SLEEP_S * 1000000, WAKE_RF_DEFAULT); delay(100); #endif #ifndef SLEEP_IF_NO_WLAN_CONNECTION delay(5000); #endif } debug("Connected!"); #ifdef INFLUXDB_FEATURE influxdb_begin(); #endif // Initialize and configure the sensors #ifdef SENSOR_APDS9930 if (sensor_apds9930_begin()) { sensors[SENSOR_LIGHT] = &apds9930_light; } #endif #ifdef SENSOR_APDS9960 if (sensor_apds9960_begin()) { sensors[SENSOR_LIGHT] = &apds9960_light; } #endif #ifdef SENSOR_BME280 //Temperature + pressure if (sensor_bme280_begin(BME_ADDRESS)) { sensors[SENSOR_TEMPERATURE] = &bme280_temperature; sensors[SENSOR_HUMIDITY] = &bme280_humidity; sensors[SENSOR_PRESSURE] = &bme280_pressure; } #endif #ifdef SENSOR_WIND sensors[SENSOR_WINDSPEED] = &wind_speed; #endif #ifdef SENSOR_BATTERY sensors[SENSOR_BAT_VOLTAGE] = &battery_voltage; sensors[SENSOR_BATCHARGESTATE] = &battery_charging; sensors[SENSOR_ESAVEMODE] = &isEnergySavingMode; #endif #ifdef WEBUPDATER_FEATURE #ifndef BATTERY_POWERED setupWebUpdater(DEVICE_NAME, WiFi.localIP().toString()); #endif #endif #ifdef HOMEBRIDGE_WEBSTAT #ifndef BATTERY_POWERED hb_webstat_server_setup(); #endif #endif //It's magic! leave in delay(100); #ifdef RESET_ESP_TIMEINTERVAL // if millis() reached interval (1h) restart ESP if (millis() >= RESET_ESP_TIME_INTERVAL_MS) { // TODO test ESP.restart(); } #endif #ifdef BATTERY_POWERED debug("battery powered"); _loop(); digitalWrite(STATUS_LED_PIN, LOW); criticalBatCheck(); WiFi.mode(WIFI_OFF); WiFi.forceSleepBegin(); debug("deep sleep"); // the ESP.deepSleep requires microseconds as input, after the sleep the system will run into the setup routine ESP.deepSleep(POWERSAVING_SLEEP_S * 1000000, WAKE_RF_DEFAULT); delay(100); #endif } //*************************************************************************// #ifdef BATTERY_POWERED void criticalBatCheck() { float volt = battery_voltage(); if (volt <= BAT_EMERGENCY_DEEPSLEEP_VOLTAGE) { debug("Bat Voltage: " + String(volt) + " V"); debug("Low battery, going into deep sleep."); // Casting to an unsigned int, so it fits into the integer range ESP.deepSleep(1U * EMERGENCY_SLEEP_S * 1000000); // battery low, shutting down delay(100); } } #endif void loop() { #ifdef BATTERY_POWERED delay(50); return; #endif #ifdef WEBUPDATER_FEATURE if (UPDATE_WEBSERVER_INTVERVAL_S * 1000 / DELAY_LOOP_MS <= update_webserver_cnt) { update_webserver_cnt = 0; doWebUpdater(); } #endif _loop(); //Needed to give WIFI time to function properly delay(DELAY_LOOP_MS); update_sensor_cnt++; #ifdef WEBUPDATER_FEATURE update_webserver_cnt++; #endif } void _loop() { #ifndef BATTERY_POWERED if (UPDATE_SENSOR_INTERVAL_S * 1000 / DELAY_LOOP_MS > update_sensor_cnt) { return; } #endif #ifdef defined(BATTERY_POWERED) && defined(SENSOR_WIND) if (energySavingMode() == 1) { // Disable expensive tasks sensors[SENSOR_WINDSPEED] = 0; } else { sensors[SENSOR_WINDSPEED] = &wind_speed; } #endif update_sensor_cnt = 0; for (uint8_t i = 0; i < VALUES; i++) { if (sensors[i]) { currentSensorData[i] = sensors[i](); } else { currentSensorData[i] = nan("no value"); } } #ifdef SERIAL_FEATURE logToSerial(currentSensorData); #endif delay(100); #ifdef INFLUXDB_FEATURE pushToInfluxDB(DEVICE_NAME, currentSensorData); #endif #ifdef WEBUPDATER_FEATURE setSensorData(currentSensorData); #endif #ifdef HOMEBRIDGE_WEBSTAT hb_webstat_loop(currentSensorData); #endif } void logToSerial(float sensorValues[]) { Serial.println(""); Serial.println("Current readings:"); Serial.println("Temperature: " + String(sensorValues[SENSOR_TEMPERATURE]) + " °C"); Serial.println("Humidity: " + String(sensorValues[SENSOR_HUMIDITY]) + " %"); Serial.println("Light: " + String(sensorValues[SENSOR_LIGHT]) + " Lux"); Serial.println("Windspeed: " + String(sensorValues[SENSOR_WINDSPEED]) + " km/h"); Serial.println("Pressure: " + String(sensorValues[SENSOR_PRESSURE]) + " hPa"); Serial.println("Bat Voltage: " + String(sensorValues[SENSOR_BAT_VOLTAGE]) + " V"); Serial.println("Bat charge state: " + String(sensorValues[SENSOR_BATCHARGESTATE])); Serial.println("Energy saving: " + String(sensorValues[SENSOR_ESAVEMODE])); }