@ -10,7 +10,7 @@
# include "config_user.h"
# ifndef DISABLE_WIFIMANAGER
# include <WiFiManager.h> // WiFiManager from bib manager
# include <WiFiManager.h> // WiFiManager from bib manager
# endif
# ifdef HTTP_CALL_ON_WINDSPEED_EXCEED
@ -19,6 +19,7 @@
# ifdef HTTP_CALL_SEND_JSON_DATA
# include <ESP8266HTTPClient.h>
# include <UrlEncode.h>
# endif
//*************************************************************************//
@ -33,15 +34,16 @@
//*************************************************************************//
// constant variables
const uint8_t VALUES = 8 ; // see constants.h file - count of number of SENSOR_ defines
const uint8_t VALUES = 8 ; // see constants.h file - count of number of SENSOR_ defines
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 " ) } ;
uint32_t update_sensor_cnt = 0 ;
uint32_t update_webserver_cnt = 0 ;
uint32_t update_sensor_cnt = 0 ;
uint32_t update_webserver_cnt = 0 ;
uint32_t update_windspeed_exceed_cnt = 0 ;
uint32_t wifi_check_interval_counter = 0 ;
uint32_t http_call_send_json_data_cnt = 0 ;
# ifndef DISABLE_WIFIMANAGER
const String wifiName = " oko-weather- " + DEVICE_NAME ;
@ -61,8 +63,7 @@ uint32_t wifi_reconnect_cnt = 0;
//*************************************************************************//
void debug ( String x )
{
void debug ( String x ) {
# ifdef DEBUG
Serial . println ( x ) ;
# endif
@ -74,19 +75,18 @@ void debug(String x)
//*************************************************************************//
void setup ( )
{
void setup ( ) {
# if defined(DEBUG) || defined(SERIAL_FEATURE)
Serial . begin ( SERIAL_BAUD_RATE ) ;
# 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 ) ;
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 , HIGH ) ;
@ -129,21 +129,19 @@ void setup()
ESP . deepSleep ( POWERSAVING_SLEEP_S * 1000000 , WAKE_RF_DEFAULT ) ;
delay ( 100 ) ;
# else // not in battery mode
# else // not in battery mode
# ifdef ENABLE_WATCHDOG
// Enable the internal watchdog
ESP . wdtEnable ( WATCHDOG_TIMEOUT_MS ) ;
# endif
# endif
}
//*************************************************************************//
void initWifiBasedSW ( )
{
void initWifiBasedSW ( ) {
# ifdef INFLUXDB_FEATURE
influxdb_begin ( ) ;
# endif
@ -153,13 +151,11 @@ void initWifiBasedSW()
setupWebUpdater ( DEVICE_NAME , WiFi . localIP ( ) . toString ( ) ) ;
# endif
# endif
}
//*************************************************************************//
void initSensors ( )
{
void initSensors ( ) {
// Initialize and configure the sensors
# ifdef SENSOR_APDS9930
if ( sensor_apds9930_begin ( ) ;
@ -182,13 +178,11 @@ void initSensors()
//*************************************************************************//
float readSensors ( uint8_t s )
{
float readSensors ( uint8_t s ) {
float ret = nan ( " no value " ) ;
switch ( s )
{
case SENSOR_LIGHT : // Initialize and configure the sensors
switch ( s ) {
case SENSOR_LIGHT : // Initialize and configure the sensors
# ifdef SENSOR_APDS9930
ret = apds9930_light ( ) ;
# endif
@ -223,8 +217,7 @@ float readSensors(uint8_t s)
case SENSOR_WINDSPEED :
# ifdef SENSOR_WIND
if ( do_not_read_windsensor = = false )
{
if ( do_not_read_windsensor = = false ) {
ret = wind_speed ( ) ;
}
# endif
@ -257,19 +250,16 @@ float readSensors(uint8_t s)
//*************************************************************************//
void wifiConnectionCheck ( )
{
void wifiConnectionCheck ( ) {
if ( ( wifi_check_interval_counter + WIFI_CHECK_INTERVAL_MS ) > millis ( ) )
{
if ( ( wifi_check_interval_counter + WIFI_CHECK_INTERVAL_MS ) > millis ( ) ) {
// if check interval is not exceeded abort check
return ;
}
wifi_check_interval_counter = millis ( ) ;
if ( WiFi . status ( ) = = WL_CONNECTED )
{
if ( WiFi . status ( ) = = WL_CONNECTED ) {
// if we are connected
return ;
}
@ -286,23 +276,20 @@ void wifiConnectionCheck()
setWifiReconnectCnt ( wifi_reconnect_cnt ) ;
# endif
if ( wifi_reconnect_cnt > = 5 )
{
debug ( " \n Reboot " ) ;
ESP . restart ( ) ;
if ( wifi_reconnect_cnt > = 5 ) {
debug ( " \n Reboot " ) ;
ESP . restart ( ) ;
} else {
wifiConnect ( ) ;
wifiConnect ( ) ;
//initWifiBasedSW();
//initWifiBasedSW();
}
}
//*************************************************************************//
void wifiConnect ( )
{
void wifiConnect ( ) {
// Establish WiFi connection if not already applied
@ -314,8 +301,7 @@ void wifiConnect()
// the time in seconds to wait for the user to configure the device
wifiManager . setTimeout ( WIFI_CONFIG_PORTAL_TIMEOUT_S ) ;
while ( ! wifiManager . autoConnect ( wifiName . c_str ( ) , " DEADBEEF " ) )
{
while ( ! wifiManager . autoConnect ( wifiName . c_str ( ) , " DEADBEEF " ) ) {
# ifdef SLEEP_IF_NO_WLAN_CONNECTION
// If autoconnect to WLAN failed and no client connected, go to deep sleep
@ -328,13 +314,11 @@ void wifiConnect()
debug ( " WiFi connection failed, try again in 5 seconds... " ) ;
delay ( 5000 ) ;
# endif
}
# else // DISABLE_WIFIMANAGER
# else // DISABLE_WIFIMANAGER
if ( ! WiFi . config ( local_IP , gateway , subnet ) )
{
if ( ! WiFi . config ( local_IP , gateway , subnet ) ) {
debug ( " Failed to set IP configuration " ) ;
} else {
debug ( " Successful set IP configuration " ) ;
@ -344,27 +328,23 @@ void wifiConnect()
debug ( " Connecting to WLAN " ) ;
while ( WiFi . status ( ) ! = WL_CONNECTED )
{
while ( WiFi . status ( ) ! = WL_CONNECTED ) {
delay ( 100 ) ;
}
# endif // DISABLE_WIFIMANAGER
# endif // DISABLE_WIFIMANAGER
}
//*************************************************************************//
# ifdef BATTERY_POWERED
void criticalBatCheck ( )
{
void criticalBatCheck ( ) {
float volt = battery_voltage ( ) ;
if ( volt < = BAT_EMERGENCY_DEEPSLEEP_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 * 1000000u ) ; // battery low, shutting down
ESP . deepSleep ( 1U * EMERGENCY_SLEEP_S * 1000000u ) ; // battery low, shutting down
delay ( 100 ) ;
}
}
@ -372,8 +352,7 @@ void criticalBatCheck()
//*************************************************************************//
void loop ( )
{
void loop ( ) {
# ifdef ENABLE_WATCHDOG
ESP . wdtFeed ( ) ;
@ -392,33 +371,38 @@ void loop()
delay ( DELAY_LOOP_MS ) ;
# endif
}
//*************************************************************************//
# ifndef BATTERY_POWERED
void _fsm_loop ( )
{
void _fsm_loop ( ) {
# ifdef WEBUPDATER_FEATURE
if ( ( update_webserver_cnt + ( UPDATE_WEBSERVER_INTVERVAL_MS ) ) < = millis ( ) )
{
if ( ( update_webserver_cnt + ( UPDATE_WEBSERVER_INTVERVAL_MS ) ) < = millis ( ) ) {
//debug("web updater call");
update_webserver_cnt = millis ( ) ;
doWebUpdater ( ) ;
}
# endif
switch ( fsm_state )
# ifdef HTTP_CALL_SEND_JSON_DATA
if ( ( http_call_send_json_data_cnt + ( HTTP_CALL_SEND_JSON_DATA_INTERVAL_S * 1000 ) ) < = millis ( ) and validData = = true )
{
// send the data to the server
debug ( " Sending weather json data to http webserver " ) ;
http_call_send_json_data_cnt = millis ( ) ;
http_call_send_json_data ( ) ;
}
# endif
switch ( fsm_state ) {
/* -------------------------------------------------------------------------------- */
case FSM_STATE_1 :
//debug("wind speed exceeded check if required");
# ifdef HTTP_CALL_ON_WINDSPEED_EXCEED
if ( ( update_windspeed_exceed_cnt + ( HTTP_CALL_ON_WINDSPEED_INTERVAL_S * 1000 ) ) < = millis ( ) )
{
if ( ( update_windspeed_exceed_cnt + ( HTTP_CALL_ON_WINDSPEED_INTERVAL_S * 1000 ) ) < = millis ( ) ) {
debug ( " reading wind sensor exceed " ) ;
// reset the wait timer to get a value every HTTP_CALL_ON_WINDSPEED_INTERVAL_S independently to the runtime of the measurement
@ -427,9 +411,8 @@ void _fsm_loop()
// start measurement of wind speed
start_measure_wind ( ) ;
fsm_state = FSM_STATE_11 ; // wait untile the wind meas time exceeded
break ; // abort case here to prevent read of next sensor in list
fsm_state = FSM_STATE_11 ; // wait untile the wind meas time exceeded
break ; // abort case here to prevent read of next sensor in list
}
# endif
fsm_state = FSM_STATE_2 ;
@ -440,8 +423,7 @@ void _fsm_loop()
//debug("reset time check if required");
# ifdef RESET_ESP_TIME_INTERVAL
// if millis() reached interval restart ESP
if ( RESET_ESP_TIME_INTERVAL_MS < = millis ( ) )
{
if ( RESET_ESP_TIME_INTERVAL_MS < = millis ( ) ) {
debug ( " resetting firmware intentionally " ) ;
// Push reset button after flashing once or do a manual power cycle to get the functionality working.
ESP . restart ( ) ;
@ -460,8 +442,7 @@ void _fsm_loop()
case FSM_STATE_4 :
//debug("disable measure of wind speed if required");
# ifdef defined(BATTERY_POWERED) && defined(SENSOR_WIND)
if ( energySavingMode ( ) = = 1 )
{
if ( energySavingMode ( ) = = 1 ) {
// Disable expensive tasks
//sensors[SENSOR_WINDSPEED] = 0;
//debug("read of wind sensor because of low battery disabled");
@ -480,39 +461,36 @@ void _fsm_loop()
/* -------------------------------------------------------------------------------- */
case FSM_STATE_5 :
//debug("read sensor data check");
if ( ( update_sensor_cnt + ( UPDATE_SENSOR_INTERVAL_S * 1000 ) ) < = millis ( ) or validData = = false )
{
if ( ( update_sensor_cnt + ( UPDATE_SENSOR_INTERVAL_S * 1000 ) ) < = millis ( ) or validData = = false ) {
debug ( " read sensor data " + String ( sensor_cnt ) ) ;
if ( sensor_cnt ! = SENSOR_WINDSPEED )
{
if ( sensor_cnt ! = SENSOR_WINDSPEED ) {
// read data from sensor
currentSensorData [ sensor_cnt ] = readSensors ( sensor_cnt ) ;
//debug(String(sensor_cnt) + "=" + String(currentSensorData[sensor_cnt]));
} else {
start_measure_wind ( ) ; // start measurement of wind speed
fsm_state = FSM_STATE_9 ; // wait untile the wind meas time exceeded
break ; // abort case here to prevent read of next sensor in list
start_measure_wind ( ) ; // start measurement of wind speed
fsm_state = FSM_STATE_9 ; // wait untile the wind meas time exceeded
break ; // abort case here to prevent read of next sensor in list
}
if ( sensor_cnt < VALUES - 1 )
{
if ( sensor_cnt < VALUES - 1 ) {
sensor_cnt + + ;
fsm_state = FSM_STATE_5 ; // jump to same state again, more sensors to read
fsm_state = FSM_STATE_5 ; // jump to same state again, more sensors to read
} else {
update_sensor_cnt = millis ( ) ; // reset the update interval counter
update_sensor_cnt = millis ( ) ; // reset the update interval counter
sensor_cnt = 0 ;
fsm_state = FSM_STATE_6 ; // next state
fsm_state = FSM_STATE_6 ; // next state
}
} else {
//debug("skip read sensor data");
fsm_state = FSM_STATE_1 ; // no new data, reset FSM
fsm_state = FSM_STATE_1 ; // no new data, reset FSM
}
break ;
@ -529,16 +507,13 @@ void _fsm_loop()
case FSM_STATE_7 :
//debug("send data to influxdb if required");
# ifdef INFLUXDB_FEATURE
for ( uint8_t i = 0 ; i < 5 and validData = = false ; i + + )
{ // only check sensor data 0 to 4 -> SENSOR_TEMPERATURE, SENSOR_HUMIDITY, SENSOR_LIGHT, SENSOR_WINDSPEED, SENSOR_PRESSURE
if ( currentSensorData [ i ] ! = 0 and currentSensorData [ i ] ! = nanf ( " no value " ) and ( not isnan ( currentSensorData [ i ] ) ) )
{
for ( uint8_t i = 0 ; i < 5 and validData = = false ; i + + ) { // only check sensor data 0 to 4 -> SENSOR_TEMPERATURE, SENSOR_HUMIDITY, SENSOR_LIGHT, SENSOR_WINDSPEED, SENSOR_PRESSURE
if ( currentSensorData [ i ] ! = 0 and currentSensorData [ i ] ! = nanf ( " no value " ) and ( not isnan ( currentSensorData [ i ] ) ) ) {
validData = true ;
}
}
if ( validData = = true )
{
if ( validData = = true ) {
// send data only if valid data is available
pushToInfluxDB ( DEVICE_NAME , currentSensorData ) ;
}
@ -552,16 +527,16 @@ void _fsm_loop()
# ifdef WEBUPDATER_FEATURE
setSensorData ( currentSensorData ) ;
# endif
fsm_state = FSM_STATE_1 ;
break ;
/* -------------------------------------------------------------------------------- */
case FSM_STATE_9 :
# ifdef SENSOR_WIND
if ( check_measure_wind_done ( ) = = false )
{
if ( check_measure_wind_done ( ) = = false ) {
//debug("wait for wind sensor finish");
fsm_state = FSM_STATE_9 ; // stay here until the wind measurement is done
fsm_state = FSM_STATE_9 ; // stay here until the wind measurement is done
} else {
//debug("wind sensor read finish");
fsm_state = FSM_STATE_10 ;
@ -587,10 +562,9 @@ void _fsm_loop()
/* -------------------------------------------------------------------------------- */
case FSM_STATE_11 :
# ifdef SENSOR_WIND
if ( check_measure_wind_done ( ) = = false )
{
if ( check_measure_wind_done ( ) = = false ) {
//debug("wait for wind sensor finish");
fsm_state = FSM_STATE_11 ; // stay here until the wind measurement is done
fsm_state = FSM_STATE_11 ; // stay here until the wind measurement is done
} else {
//debug("wind sensor read finish");
fsm_state = FSM_STATE_12 ;
@ -608,26 +582,24 @@ void _fsm_loop()
currentSensorData [ sensor_cnt ] = measure_wind_result ( ) ;
debug ( " wind sensor value " + String ( currentSensorData [ sensor_cnt ] ) ) ;
if ( currentSensorData [ SENSOR_WINDSPEED ] > = HTTP_CALL_ON_WINDSPEED_EXCEED_MPS )
{
if ( currentSensorData [ SENSOR_WINDSPEED ] > = HTTP_CALL_ON_WINDSPEED_EXCEED_MPS ) {
// windspeed exceeded send http call
digitalWrite ( STATUS_LED_PIN , LOW ) ;
// call the url HTTP_CALL_ON_WINDSPEED_URL
WiFiClient client ;
HTTPClient http ;
http . begin ( client , String ( HTTP_CALL_ON_WINDSPEED_URL ) . c_str ( ) ) ;
// Send HTTP GET request
int httpResponseCode = http . GET ( ) ;
if ( httpResponseCode > 0 )
{
if ( httpResponseCode > 0 ) {
String response = http . getString ( ) ;
debug ( " http response code: " + String ( httpResponseCode ) + " = " + response ) ;
// TODO handle response
}
http . end ( ) ;
debug ( " Called windspeed exceed callout " ) ;
digitalWrite ( STATUS_LED_PIN , HIGH ) ;
@ -647,7 +619,7 @@ void _fsm_loop()
fsm_state = FSM_STATE_1 ;
break ;
} // close of switch
} // close of switch
//debug("FSM state = " + String(fsm_state));
/*if (fsm_state == FSM_STATE_1)
@ -659,11 +631,9 @@ void _fsm_loop()
//*************************************************************************//
void _battery_mode_main ( )
{
void _battery_mode_main ( ) {
if ( energySavingMode ( ) = = 1 )
{
if ( energySavingMode ( ) = = 1 ) {
// Disable expensive tasks
//debug("read of wind sensor because of low battery disabled");
do_not_read_windsensor = true ;
@ -673,8 +643,7 @@ void _battery_mode_main()
do_not_read_windsensor = false ;
}
for ( uint8_t i = 0 ; i < VALUES ; i + + )
{
for ( uint8_t i = 0 ; i < VALUES ; i + + ) {
currentSensorData [ i ] = readSensors ( i ) ;
}
@ -694,8 +663,7 @@ void _battery_mode_main()
//*************************************************************************//
# ifdef SERIAL_FEATURE
void logToSerial ( float sensorValues [ ] )
{
void logToSerial ( float sensorValues [ ] ) {
Serial . println ( " " ) ;
Serial . println ( " Current readings: " ) ;
Serial . println ( " Temperature: " + String ( sensorValues [ SENSOR_TEMPERATURE ] ) + " °C " ) ;
@ -710,3 +678,66 @@ void logToSerial(float sensorValues[])
# endif
//*************************************************************************//
# ifdef HTTP_CALL_SEND_JSON_DATA
String getJsonData ( )
{
String msg = hb_ws_msg_start +
hb_ws_msg_temp +
String ( currentSensorData [ SENSOR_TEMPERATURE ] , 2 ) +
" , " +
hb_ws_msg_humi +
String ( currentSensorData [ SENSOR_HUMIDITY ] , 2 ) +
" , " +
hb_ws_msg_light +
String ( currentSensorData [ SENSOR_LIGHT ] , 0 ) + // The light level for the homebridge-http-lux2 plugin is only able to parse integer values
" , " +
hb_ws_msg_windspeed +
String ( currentSensorData [ SENSOR_WINDSPEED ] , 2 ) +
" , " +
hb_ws_msg_pressure +
String ( currentSensorData [ SENSOR_PRESSURE ] , 2 ) +
" , " +
hb_ws_msg_timestamp +
String ( millis ( ) ) +
" , " +
hb_ws_msg_valid +
String ( validData ) +
hb_ws_msg_end ;
return msg ;
}
void http_call_send_json_data ( )
{
currentSensorData [ sensor_cnt ] = measure_wind_result ( ) ;
debug ( " http call to " + String ( currentSensorData [ sensor_cnt ] ) ) ;
// windspeed exceeded send http call
digitalWrite ( STATUS_LED_PIN , LOW ) ;
// call the url HTTP_CALL_SEND_JSON_DATA_URL
WiFiClient client ;
HTTPClient http ;
String tmp_str = HTTP_CALL_SEND_JSON_DATA_URL + urlEncode ( getJsonData ( ) ) ;
debug ( " send: " + tmp_str ) ;
http . begin ( client , String ( tmp_str ) . c_str ( ) ) ;
// Send HTTP GET request
int httpResponseCode = http . GET ( ) ;
if ( httpResponseCode > 0 ) {
String response = http . getString ( ) ;
debug ( " http response code: " + String ( httpResponseCode ) + " = " + response ) ;
// TODO handle response
}
http . end ( ) ;
digitalWrite ( STATUS_LED_PIN , HIGH ) ;
}
# endif