feature/InfluxDB-Connection-Update #1
16 changed files with 406 additions and 407 deletions
5
.gitignore
vendored
Normal file → Executable file
5
.gitignore
vendored
Normal file → Executable file
|
@ -1 +1,6 @@
|
|||
firmware/config_user.h
|
||||
firmware/.DS_Store
|
||||
.DS_Store
|
||||
schematics/#auto_saved_files#
|
||||
schematics/_autosave-oko-weatherstation.sch
|
||||
firmware.ino.bin
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
sudo docker-compose exec esphome esphome run /config/weatherstation.yml
|
|
@ -1,179 +0,0 @@
|
|||
esphome:
|
||||
name: weatherstation
|
||||
platform: ESP8266
|
||||
board: d1_mini
|
||||
|
||||
i2c:
|
||||
- id: bus_a
|
||||
sda: 4 # D2
|
||||
scl: 5 # D1
|
||||
scan: true
|
||||
|
||||
apds9960:
|
||||
address: 0x39
|
||||
update_interval: 300s
|
||||
|
||||
sensor:
|
||||
#
|
||||
#################### wind sensor
|
||||
- platform: pulse_counter
|
||||
pin:
|
||||
# pin D8
|
||||
number: GPIO15
|
||||
mode: INPUT # TODO check if required
|
||||
unit_of_measurement: 'm/s' ##change to m/s if metric
|
||||
name: 'wind_speed'
|
||||
icon: 'mdi:weather-windy'
|
||||
id: my_wind
|
||||
count_mode:
|
||||
rising_edge: DISABLE
|
||||
falling_edge: INCREMENT
|
||||
internal_filter: 50us
|
||||
update_interval: 60s
|
||||
#rotations_per_sec = pulses/2/60
|
||||
#circ_m=0.09*2*3.14 = 0.5652
|
||||
#mps = 1.18*circ_m*rotations_per_sec
|
||||
#mps = 1.18*0.5652/2/60 =0,0055578
|
||||
filters:
|
||||
- multiply: 0.0055578 #use for m/s
|
||||
# - multiply: 2.237 #m/s to mph
|
||||
# - sliding_window_moving_average:
|
||||
# window_size: 4
|
||||
# send_every: 1
|
||||
#- multiply: 0.04973 #1.492mph switch to close 1/sec per spec, pulse/sec (/60/2)*1.492
|
||||
#- multiply: 0.0124327986 #m/s * mph conversion
|
||||
|
||||
#################### apds9960 sensor i2c
|
||||
- platform: apds9960
|
||||
type: CLEAR
|
||||
name: "APDS9960_clear_channel"
|
||||
- platform: apds9960
|
||||
type: RED
|
||||
name: "APDS9960_red_channel"
|
||||
id: apds9960_red
|
||||
- platform: apds9960
|
||||
type: GREEN
|
||||
name: "APDS9960_green_channel"
|
||||
id: apds9960_green
|
||||
- platform: apds9960
|
||||
type: BLUE
|
||||
name: "APDS9960_blue_channel"
|
||||
id: apds9960_blue
|
||||
# TODO fix calculation to get lux instead of a percentual value
|
||||
#
|
||||
# Code from Adafruit_APDS9960 lib:
|
||||
# illuminance = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
|
||||
#
|
||||
# Code from: https://esphome.io/api/apds9960_8cpp_source.html
|
||||
# 180: float red_perc = (uint_red / float(UINT16_MAX)) * 100.0f;
|
||||
# 181: float green_perc = (uint_green / float(UINT16_MAX)) * 100.0f;
|
||||
# 182: float blue_perc = (uint_blue / float(UINT16_MAX)) * 100.0f;
|
||||
- platform: template
|
||||
name: "light"
|
||||
lambda: |-
|
||||
const float perc_to_raw = 65535.0 / 100.0;
|
||||
const float red_to_lux = -0.32466;
|
||||
const float green_to_lux = 1.57837;
|
||||
const float blue_to_lux = -0.73191;
|
||||
return ((red_to_lux * id(apds9960_red).raw_state) + (green_to_lux * id(apds9960_green).raw_state) + (blue_to_lux * id(apds9960_blue).raw_state)) * perc_to_raw;
|
||||
update_interval: 300s
|
||||
accuracy_decimals: 2
|
||||
unit_of_measurement: 'lux'
|
||||
|
||||
#################### bme280 sensor i2c
|
||||
- platform: bme280
|
||||
temperature:
|
||||
name: "BME280_temperature"
|
||||
id: bme280_temperature
|
||||
pressure:
|
||||
name: "BME280_ressure"
|
||||
id: bme280_pressure
|
||||
humidity:
|
||||
name: "BME280 Relative Humidity"
|
||||
id: bme280_humidity
|
||||
address: 0x76
|
||||
update_interval: 300s
|
||||
|
||||
- platform: template
|
||||
name: "altitude"
|
||||
lambda: |-
|
||||
const float STANDARD_SEA_LEVEL_PRESSURE = 1013.25; //in hPa, see note
|
||||
return ((id(bme280_temperature).state + 273.15) / 0.0065) *
|
||||
(powf((STANDARD_SEA_LEVEL_PRESSURE / id(bme280_pressure).state), 0.190234) - 1); // in meter
|
||||
update_interval: 300s
|
||||
icon: 'mdi:signal'
|
||||
unit_of_measurement: 'm'
|
||||
|
||||
- platform: template
|
||||
name: "absolute_humidity"
|
||||
lambda: |-
|
||||
const float mw = 18.01534; // molar mass of water g/mol
|
||||
const float r = 8.31447215; // Universal gas constant J/mol/K
|
||||
return (6.112 * powf(2.718281828, (17.67 * id(bme280_temperature).state) /
|
||||
(id(bme280_temperature).state + 243.5)) * id(bme280_humidity).state * mw) /
|
||||
((273.15 + id(bme280_temperature).state) * r); // in grams/m^3
|
||||
accuracy_decimals: 2
|
||||
update_interval: 300s
|
||||
icon: 'mdi:water'
|
||||
unit_of_measurement: 'g/m³'
|
||||
|
||||
- platform: template
|
||||
name: "dew_point"
|
||||
lambda: |-
|
||||
return (243.5*(log(id(bme280_humidity).state/100)+((17.67*id(bme280_temperature).state)/
|
||||
(243.5+id(bme280_temperature).state)))/(17.67-log(id(bme280_humidity).state/100)-
|
||||
((17.67*id(bme280_temperature).state)/(243.5+id(bme280_temperature).state))));
|
||||
unit_of_measurement: °C
|
||||
update_interval: 300s
|
||||
icon: 'mdi:thermometer-alert'
|
||||
|
||||
# battery power adc
|
||||
- platform: adc
|
||||
pin: A0
|
||||
name: "battery_power"
|
||||
update_interval: 300s
|
||||
|
||||
binary_sensor:
|
||||
# battery charged pin
|
||||
- platform: gpio
|
||||
pin:
|
||||
number: 12 # D6
|
||||
mode:
|
||||
input: true
|
||||
pullup: false
|
||||
name: "battery_charged"
|
||||
|
||||
# battery charging pin
|
||||
- platform: gpio
|
||||
pin:
|
||||
number: 14 # D5
|
||||
mode:
|
||||
input: true
|
||||
pullup: false
|
||||
name: "battery_charging"
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: my_time
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
ota:
|
||||
password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
||||
wifi:
|
||||
ssid: UPC4556888
|
||||
password: emmydhvZ4faw
|
||||
manual_ip:
|
||||
# Set this to the IP of the ESP
|
||||
static_ip: 192.168.0.91
|
||||
# Set this to the IP address of the router. Often ends with .1
|
||||
gateway: 192.168.0.1
|
||||
# The subnet of the network. 255.255.255.0 works for most home networks.
|
||||
subnet: 255.255.255.0
|
||||
|
||||
captive_portal:
|
|
@ -1,146 +0,0 @@
|
|||
esphome:
|
||||
name: weatherstation
|
||||
platform: ESP8266
|
||||
board: d1_mini
|
||||
|
||||
i2c:
|
||||
- id: bus_a
|
||||
sda: 4 # D2
|
||||
scl: 5 # D1
|
||||
scan: true
|
||||
|
||||
apds9960:
|
||||
address: 0x39
|
||||
update_interval: 300s
|
||||
|
||||
sensor:
|
||||
#
|
||||
#################### wind sensor
|
||||
- platform: pulse_counter
|
||||
pin:
|
||||
# pin D8
|
||||
number: GPIO15
|
||||
mode: INPUT_PULLUP # TODO check if required
|
||||
unit_of_measurement: 'm/s' ##change to m/s if metric
|
||||
name: 'wind_speed'
|
||||
icon: 'mdi:weather-windy'
|
||||
id: my_wind
|
||||
count_mode:
|
||||
rising_edge: DISABLE
|
||||
falling_edge: INCREMENT
|
||||
internal_filter: 50us
|
||||
update_interval: 300s
|
||||
#rotations_per_sec = pulses/2/60
|
||||
#circ_m=0.09*2*3.14 = 0.5652
|
||||
#mps = 1.18*circ_m*rotations_per_sec
|
||||
#mps = 1.18*0.5652/2/60 =0,0055578
|
||||
filters:
|
||||
- multiply: 0.0055578 #use for m/s
|
||||
# - multiply: 2.237 #m/s to mph
|
||||
# - sliding_window_moving_average:
|
||||
# window_size: 4
|
||||
# send_every: 1
|
||||
#- multiply: 0.04973 #1.492mph switch to close 1/sec per spec, pulse/sec (/60/2)*1.492
|
||||
#- multiply: 0.0124327986 #m/s * mph conversion
|
||||
|
||||
#################### apds9960 sensor i2c
|
||||
- platform: apds9960
|
||||
type: CLEAR
|
||||
name: "APDS9960_clear_channel"
|
||||
|
||||
- platform: bme280
|
||||
temperature:
|
||||
name: "BME280_temperature"
|
||||
id: bme280_temperature
|
||||
pressure:
|
||||
name: "BME280_ressure"
|
||||
id: bme280_pressure
|
||||
humidity:
|
||||
name: "BME280 Relative Humidity"
|
||||
id: bme280_humidity
|
||||
address: 0x76
|
||||
update_interval: 300s
|
||||
|
||||
- platform: template
|
||||
name: "altitude"
|
||||
lambda: |-
|
||||
const float STANDARD_SEA_LEVEL_PRESSURE = 1013.25; //in hPa, see note
|
||||
return ((id(bme280_temperature).state + 273.15) / 0.0065) *
|
||||
(powf((STANDARD_SEA_LEVEL_PRESSURE / id(bme280_pressure).state), 0.190234) - 1); // in meter
|
||||
update_interval: 300s
|
||||
icon: 'mdi:signal'
|
||||
unit_of_measurement: 'm'
|
||||
|
||||
- platform: template
|
||||
name: "absolute_humidity"
|
||||
lambda: |-
|
||||
const float mw = 18.01534; // molar mass of water g/mol
|
||||
const float r = 8.31447215; // Universal gas constant J/mol/K
|
||||
return (6.112 * powf(2.718281828, (17.67 * id(bme280_temperature).state) /
|
||||
(id(bme280_temperature).state + 243.5)) * id(bme280_humidity).state * mw) /
|
||||
((273.15 + id(bme280_temperature).state) * r); // in grams/m^3
|
||||
accuracy_decimals: 2
|
||||
update_interval: 300s
|
||||
icon: 'mdi:water'
|
||||
unit_of_measurement: 'g/m³'
|
||||
|
||||
- platform: template
|
||||
name: "dew_point"
|
||||
lambda: |-
|
||||
return (243.5*(log(id(bme280_humidity).state/100)+((17.67*id(bme280_temperature).state)/
|
||||
(243.5+id(bme280_temperature).state)))/(17.67-log(id(bme280_humidity).state/100)-
|
||||
((17.67*id(bme280_temperature).state)/(243.5+id(bme280_temperature).state))));
|
||||
unit_of_measurement: °C
|
||||
update_interval: 300s
|
||||
icon: 'mdi:thermometer-alert'
|
||||
|
||||
# battery power adc
|
||||
- platform: adc
|
||||
pin: A0
|
||||
name: "battery_power"
|
||||
update_interval: 300s
|
||||
|
||||
binary_sensor:
|
||||
# battery charged pin
|
||||
- platform: gpio
|
||||
pin:
|
||||
number: 12 # D6
|
||||
mode:
|
||||
input: true
|
||||
pullup: false
|
||||
name: "battery_charged"
|
||||
|
||||
# battery charging pin
|
||||
- platform: gpio
|
||||
pin:
|
||||
number: 14 # D5
|
||||
mode:
|
||||
input: true
|
||||
pullup: false
|
||||
name: "battery_charging"
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: my_time
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
ota:
|
||||
password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
|
||||
wifi:
|
||||
ssid: UPC4556888
|
||||
password: emmydhvZ4faw
|
||||
manual_ip:
|
||||
# Set this to the IP of the ESP
|
||||
static_ip: 192.168.0.91
|
||||
# Set this to the IP address of the router. Often ends with .1
|
||||
gateway: 192.168.0.1
|
||||
# The subnet of the network. 255.255.255.0 works for most home networks.
|
||||
subnet: 255.255.255.0
|
||||
|
||||
captive_portal:
|
0
firmware/README.md
Normal file → Executable file
0
firmware/README.md
Normal file → Executable file
30
firmware/config.h
Executable file → Normal file
30
firmware/config.h
Executable file → Normal file
|
@ -1,29 +1,21 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
#define SENSOR_TEMPERATURE 0
|
||||
#define SENSOR_HUMIDITY 1
|
||||
#define SENSOR_LIGHT 2
|
||||
#define SENSOR_WINDSPEED 3
|
||||
#define SENSOR_PRESSURE 4
|
||||
#define SENSOR_BAT_VOLTAGE 5
|
||||
#define SENSOR_ESAVEMODE 6
|
||||
#define SENSOR_BATCHARGESTATE 7
|
||||
// config general setting and behavior of the weatherstation
|
||||
|
||||
#define BAT_CHARGE_STATE_CHARGED 2.0
|
||||
#define BAT_CHARGE_STATE_CHARGING 1.0
|
||||
#define BAT_CHARGE_STATE_NOTCHARGING 0.0
|
||||
#define ENERGY_SAVE_MODE_ENABLED 1.0
|
||||
#define ENERGY_SAVE_MODE_DISABLED 0.0
|
||||
|
||||
#define WIFI_AUTOCONNECT_TIMEOUT_S 120
|
||||
#define WIFI_CONFIG_PORTAL_TIMEOUT_S 120
|
||||
#define UPDATE_SENSOR_INTERVAL_S 10
|
||||
#define UPDATE_WEBSERVER_INTVERVAL_S 1
|
||||
#define WIFI_AUTOCONNECT_TIMEOUT_S 120
|
||||
#define WIFI_CONFIG_PORTAL_TIMEOUT_S 120
|
||||
#define UPDATE_SENSOR_INTERVAL_S 300
|
||||
#define UPDATE_WEBSERVER_INTVERVAL_S 1 // Do not change, bigger values will prevent using webupdater webinterface
|
||||
#define DELAY_LOOP_MS 50
|
||||
#define POWERSAVING_SLEEP_S 600
|
||||
#define EMERGENCY_SLEEP_S 172800 // Sleep for 2 days to recover
|
||||
#define RESET_ESP_TIME_INTERVAL_MS 3600000
|
||||
#define WIND_SENSOR_MEAS_TIME_S 15
|
||||
#define INITIAL_WEBSERVER_TIME 20
|
||||
|
||||
#define ENERGY_SAVING_ITERATIONS 30
|
||||
#define WIFI_MINIMUM_SIGNAL_QUALITY 10 // percent
|
||||
|
||||
#define BAT_LOW_VOLTAGE 3.6
|
||||
#define BAT_EMERGENCY_DEEPSLEEP_VOLTAGE 3.5
|
||||
|
@ -47,6 +39,6 @@
|
|||
#define BME_CS 10
|
||||
#define BME_ADDRESS 0x76
|
||||
|
||||
#define INITIAL_WEBSERVER_TIME 20
|
||||
#define WEB_UPDATER_HTTP_PORT 8080
|
||||
klaute marked this conversation as resolved
Outdated
|
||||
|
||||
#endif
|
||||
|
|
51
firmware/config_user.h.example
Normal file → Executable file
51
firmware/config_user.h.example
Normal file → Executable file
|
@ -7,20 +7,34 @@
|
|||
// Debug output on the serial console
|
||||
#define DEBUG
|
||||
|
||||
// Device name
|
||||
// WARNING: Keep the name short! If your access point did not show up, you
|
||||
// maybe have a TOO LONG SSID!
|
||||
String DEVICE_NAME = "weatherstation";
|
||||
|
||||
// Enable/Disable features
|
||||
//#define WEBUPDATER_FEATURE
|
||||
#define INFLUXDB_FEATURE
|
||||
#define INFLUXDB_VERSION 1 // 1 or 2
|
||||
#define SERIAL_FEATURE
|
||||
#define BATTERY_POWERED
|
||||
#define SENSOR_WIND
|
||||
//#define BATTERY_POWERED
|
||||
//#define SENSOR_WIND
|
||||
#define SENSOR_APDS9960
|
||||
//#define SENSOR_APDS9930
|
||||
#define SENSOR_BME280
|
||||
#define SENSOR_BATTERY
|
||||
//#define BAT_PINS_D34
|
||||
// Homebridge Webstat is only possible if webupdater is also enabled
|
||||
//#define HOMEBRIDGE_WEBSTAT
|
||||
// retries to connect after 5 seconds or starts the wifimanager
|
||||
#define SLEEP_IF_NO_WLAN_CONNECTION
|
||||
// Restarts the firmware every n seconds
|
||||
//#define RESET_ESP_TIMEINTERVAL // BETA STATUS
|
||||
//#define HTTP_CALL_ON_WINDSPEED_EXCEED // BETA STATUS
|
||||
|
||||
const float HUMIDITY_FACTOR = 1.0;
|
||||
const float LIGHT_FACTOR = 1.0;
|
||||
const float TEMP_FACTOR = 1.0;
|
||||
|
||||
// InfluxDB credentials
|
||||
const char *INFLUXDB_HOST = "hostname";
|
||||
|
@ -29,9 +43,34 @@ const char *INFLUXDB_DB = "database";
|
|||
const char *INFLUXDB_USER = "user";
|
||||
const char *INFLUXDB_PASS = "password";
|
||||
klaute marked this conversation as resolved
Outdated
f
commented
" fehlt. " fehlt.
klaute
commented
Erledigt Erledigt
|
||||
|
||||
klaute marked this conversation as resolved
Outdated
|
||||
// Device name
|
||||
// WARNING: Keep the name short! If your access point did not show up, you
|
||||
// maybe have a TOO LONG SSID!
|
||||
String DEVICE_NAME = "devicename";
|
||||
// InfluxDB2 credentials
|
||||
/*
|
||||
const char *INFLUXDB_URL = "http://192.168.0.123:3124";
|
||||
const char *INFLUXDB_ORG = "home_org";
|
||||
const char *INFLUXDB_BUCKET = "mybucket";
|
||||
const char *INFLUXDB_TOKEN = "your api token";
|
||||
*/
|
||||
|
||||
// enable HTTP_CALL_ON_WINDSPEED_EXCEED to enable this feature
|
||||
#define HTTP_CALL_ON_WINDSPEED_EXCEED_MPS 5.0 // 5.0 m/s == 18 km/h
|
||||
#define HTTP_CALL_ON_WINDSPEED_INTERVAL_S 60 // it's required to be bigger than WIND_SENSOR_MEAS_TIME_S
|
||||
#define HTTP_CALL_ON_WINDSPEED_URL "http://192.168.178.100:3001/button-windspeedexceed?event=click"
|
||||
|
||||
// anemometer settings, to use enable SENSOR_WIND
|
||||
// thingiverse anemometer settings: https://www.thingiverse.com/thing:2559929/files
|
||||
#define ROTOR_LENGTH_CM 8.25
|
||||
#define ROTOR_LENGTH_M (ROTOR_LENGTH_CM / 100.0)
|
||||
//#define ROTOR_LENGTH_KM (ROTOR_LENGTH_M / 1000.0) // configuration example for generalization
|
||||
//#define SEC_TO_HOUR_FACTOR (60.0 * 60.0) // configuration example for generalization
|
||||
#define MPS_CORRECT_FACT 9.28
|
||||
//#define COUNT_TO_KMH ((TWO_PI * ROTOR_LENGTH_KM / WIND_SENSOR_MEAS_TIME_S) * SEC_TO_HOUR_FACTOR) // configuration exampe for generalization
|
||||
#define COUNT_TO_MPS (TWO_PI * ROTOR_LENGTH_M / WIND_SENSOR_MEAS_TIME_S)
|
||||
// only this define is used for calculation, all other before are only used to describe the math v_wind = correction_factor * rotations * 2 * pi * radius / time_of_measurement_in_sec
|
||||
// and if required the result has t be multiplied by another factor to convert it from m/s
|
||||
#define WINDSPEED_FACTOR (COUNT_TO_MPS * MPS_CORRECT_FACT)
|
||||
|
||||
// china aliexpress anemometer settings (calculation unknown) <add link here>
|
||||
//#define WINDSPEED_FACTOR 2.4
|
||||
|
||||
#endif
|
||||
|
||||
|
|
20
firmware/constants.h
Normal file
20
firmware/constants.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef __CONSTANTS_H__
|
||||
#define __CONSTANTS_H__
|
||||
|
||||
#define SENSOR_TEMPERATURE 0
|
||||
#define SENSOR_HUMIDITY 1
|
||||
#define SENSOR_LIGHT 2
|
||||
#define SENSOR_WINDSPEED 3
|
||||
#define SENSOR_PRESSURE 4
|
||||
#define SENSOR_BAT_VOLTAGE 5
|
||||
#define SENSOR_ESAVEMODE 6
|
||||
#define SENSOR_BATCHARGESTATE 7
|
||||
|
||||
#define BAT_CHARGE_STATE_CHARGED 2.0
|
||||
#define BAT_CHARGE_STATE_CHARGING 1.0
|
||||
#define BAT_CHARGE_STATE_NOTCHARGING 0.0
|
||||
#define ENERGY_SAVE_MODE_ENABLED 1.0
|
||||
#define ENERGY_SAVE_MODE_DISABLED 0.0
|
||||
|
||||
#endif
|
149
firmware/firmware.ino
Executable file → Normal file
149
firmware/firmware.ino
Executable file → Normal file
|
@ -1,55 +1,63 @@
|
|||
// Standard ESP8266 libs
|
||||
// Standard ESP8266 libs from project folder
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <ESP8266HTTPUpdateServer.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <DNSServer.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
#include <WiFiClient.h> // WiFiClient
|
||||
#include <WiFiManager.h> // WiFiManager
|
||||
#include <WiFiClient.h> // WiFiClient
|
||||
#include <WiFiManager.h> // WiFiManager from bib manager
|
||||
|
||||
// Project includes
|
||||
#include "constants.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "config_user.h"
|
||||
|
||||
//*************************************************************************//
|
||||
// check if some settings are correct
|
||||
|
||||
#ifdef HTTP_CALL_ON_WINDSPEED_EXCEED
|
||||
#if (HTTP_CALL_ON_WINDSPEED_INTERVAL_S < WIND_SENSOR_MEAS_TIME_S)
|
||||
#error "HTTP_CALL_ON_WINDSPEED_INTERVAL_S < WIND_SENSOR_MEAS_TIME_S"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//*************************************************************************//
|
||||
// constant variables
|
||||
|
||||
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;
|
||||
uint16_t update_sensor_cnt = 0;
|
||||
uint16_t update_webserver_cnt = 0;
|
||||
uint16_t update_windspeed_exceed_cnt = 0;
|
||||
|
||||
WiFiManager wifiManager;
|
||||
|
||||
//*************************************************************************//
|
||||
|
||||
void debug(String x) {
|
||||
void debug(String x)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Serial.println(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
// Erase WiFi Credentials (maybe this will work ...)
|
||||
//WiFi.disconnect(true);
|
||||
//delay(2000);
|
||||
//ESP.reset();
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -62,18 +70,28 @@ void setup() {
|
|||
#ifdef BATTERY_POWERED
|
||||
criticalBatCheck();
|
||||
#endif
|
||||
|
||||
// Establish WiFi connection
|
||||
String wifiName = "oko-weather-" + DEVICE_NAME;
|
||||
|
||||
wifiManager.setMinimumSignalQuality(16);
|
||||
wifiManager.setConnectTimeout(WIFI_AUTOCONNECT_TIMEOUT_S); // the time in seconds to wait for the known wifi connection
|
||||
wifiManager.setTimeout(WIFI_CONFIG_PORTAL_TIMEOUT_S); // the time in seconds to wait for the user to configure the device
|
||||
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
|
||||
klaute marked this conversation as resolved
Outdated
f
commented
Das ist ziemlich dirty gelöst und meine Arduino-IDE weigert sich sogar, das zu compilieren. Auch wenn es ein paar bytes verschenkt ist, wäre es schöner, einfach immer was Das ist ziemlich dirty gelöst und meine Arduino-IDE weigert sich sogar, das zu compilieren. Auch wenn es ein paar bytes verschenkt ist, wäre es schöner, einfach immer was ```while``` stehen zu lassen und dann ein ```#ifdef`` in der schleife rein.
|
||||
wifiManager.setTimeout(WIFI_CONFIG_PORTAL_TIMEOUT_S);
|
||||
|
||||
if (!wifiManager.autoConnect(wifiName.c_str(), "DEADBEEF")) {
|
||||
debug("WiFi connection failed, going into deep sleep ...");
|
||||
while (!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
|
||||
// sleep a few seconds and go on trying to connect
|
||||
delay(5000);
|
||||
#endif
|
||||
}
|
||||
|
||||
debug("Connected!");
|
||||
|
@ -123,6 +141,16 @@ void setup() {
|
|||
//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)
|
||||
{
|
||||
debug("Resetting firmware intentionally");
|
||||
// Push reset button after flashing once or do a manual power cycle to get the functionality working.
|
||||
ESP.restart();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BATTERY_POWERED
|
||||
debug("battery powered");
|
||||
_loop();
|
||||
|
@ -145,7 +173,8 @@ void setup() {
|
|||
//*************************************************************************//
|
||||
|
||||
#ifdef BATTERY_POWERED
|
||||
void criticalBatCheck() {
|
||||
void criticalBatCheck()
|
||||
{
|
||||
float volt = battery_voltage();
|
||||
if (volt <= BAT_EMERGENCY_DEEPSLEEP_VOLTAGE) {
|
||||
debug("Bat Voltage: " + String(volt) + " V");
|
||||
|
@ -157,21 +186,14 @@ void criticalBatCheck() {
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
void loop() {
|
||||
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
|
||||
|
||||
|
||||
// call sub loop function
|
||||
_loop();
|
||||
|
||||
//Needed to give WIFI time to function properly
|
||||
|
@ -182,17 +204,70 @@ void loop() {
|
|||
#ifdef WEBUPDATER_FEATURE
|
||||
update_webserver_cnt++;
|
||||
#endif
|
||||
|
||||
#ifdef HTTP_CALL_ON_WINDSPEED_EXCEED
|
||||
update_windspeed_exceed_cnt++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void _loop() {
|
||||
|
||||
#ifdef WEBUPDATER_FEATURE
|
||||
if (UPDATE_WEBSERVER_INTVERVAL_S * 1000 / DELAY_LOOP_MS <= update_webserver_cnt)
|
||||
{
|
||||
update_webserver_cnt = 0;
|
||||
doWebUpdater();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HTTP_CALL_ON_WINDSPEED_EXCEED
|
||||
if (HTTP_CALL_ON_WINDSPEED_INTERVAL_S * 1000 / DELAY_LOOP_MS <= update_windspeed_exceed_cnt)
|
||||
{
|
||||
debug("Reading wind sensor because of exceed call functionality");
|
||||
if (sensors[SENSOR_WINDSPEED])
|
||||
{
|
||||
// read from windspeed sensorSTATUS_LED_PIN
|
||||
digitalWrite(STATUS_LED_PIN, HIGH);
|
||||
currentSensorData[SENSOR_WINDSPEED] = sensors[SENSOR_WINDSPEED]();
|
||||
digitalWrite(STATUS_LED_PIN, LOW);
|
||||
|
||||
if (currentSensorData[SENSOR_WINDSPEED] >= HTTP_CALL_ON_WINDSPEED_EXCEED_MPS)
|
||||
{
|
||||
digitalWrite(STATUS_LED_PIN, HIGH);
|
||||
|
||||
// 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) {
|
||||
String response = http.getString();
|
||||
#ifdef DEBUG
|
||||
Serial.println("http response code: " + String(httpResponseCode) + " = " + response);
|
||||
#endif
|
||||
// TODO handle response
|
||||
}
|
||||
|
||||
http.end();
|
||||
debug("Called windspeed exceed callout");
|
||||
digitalWrite(STATUS_LED_PIN, LOW);
|
||||
}
|
||||
} else {
|
||||
currentSensorData[SENSOR_WINDSPEED] = nan("no value");
|
||||
}
|
||||
update_windspeed_exceed_cnt = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
@ -203,7 +278,6 @@ void _loop() {
|
|||
#endif
|
||||
|
||||
update_sensor_cnt = 0;
|
||||
|
||||
for (uint8_t i = 0; i < VALUES; i++) {
|
||||
if (sensors[i]) {
|
||||
currentSensorData[i] = sensors[i]();
|
||||
|
@ -225,6 +299,7 @@ void _loop() {
|
|||
#ifdef WEBUPDATER_FEATURE
|
||||
setSensorData(currentSensorData);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void logToSerial(float sensorValues[]) {
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
|
||||
#include "config_user.h"
|
||||
|
||||
#if INFLUXDB_VERSION == 1
|
||||
|
||||
#include <ESP8266Influxdb.h> // https://github.com/hwwong/ESP8266Influxdb
|
||||
klaute marked this conversation as resolved
Outdated
f
commented
Die wird für version 1 gebraucht. Die wird für version 1 gebraucht.
klaute
commented
Erledigt Erledigt
|
||||
|
||||
Influxdb _influxdb(INFLUXDB_HOST, INFLUXDB_PORT);
|
||||
|
@ -74,3 +79,111 @@ void pushToInfluxDB(String device, float sensorValues[]) {
|
|||
_influxdb.write(msg);
|
||||
} while (_influxdb.response() != DB_SUCCESS and tries < 5);
|
||||
}
|
||||
|
||||
#elif INFLUXDB_VERSION == 2
|
||||
|
||||
#include <InfluxDbClient.h> // from bib manager
|
||||
|
||||
// Data point
|
||||
Point sensor(DEVICE_NAME);
|
||||
|
||||
// Init variables to influxdb config - doesn't talk to database
|
||||
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN);
|
||||
|
||||
void influxdb_begin() {
|
||||
|
||||
// Check server connection
|
||||
if (client.validateConnection()) {
|
||||
// success
|
||||
#ifdef DEBUG
|
||||
Serial.print("InfluxDB connect success\n");
|
||||
#endif
|
||||
} else {
|
||||
// fail
|
||||
#ifdef DEBUG
|
||||
Serial.print("InfluxDB connect failed\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void pushToInfluxDB(String device, float sensorValues[]) {
|
||||
|
||||
if (!(isnan(sensorValues[SENSOR_TEMPERATURE])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("temperature", sensorValues[SENSOR_TEMPERATURE]);
|
||||
_writePoint();
|
||||
}
|
||||
if (!(isnan(sensorValues[SENSOR_HUMIDITY])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("humidity", sensorValues[SENSOR_HUMIDITY]);
|
||||
_writePoint();
|
||||
}
|
||||
if (!(isnan(sensorValues[SENSOR_LIGHT])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("light", sensorValues[SENSOR_LIGHT]);
|
||||
_writePoint();
|
||||
}
|
||||
if (!(isnan(sensorValues[SENSOR_WINDSPEED])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("windspeed", sensorValues[SENSOR_WINDSPEED]);
|
||||
_writePoint();
|
||||
}
|
||||
if (!(isnan(sensorValues[SENSOR_PRESSURE])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("pressure", sensorValues[SENSOR_PRESSURE]);
|
||||
_writePoint();
|
||||
}
|
||||
if (!(isnan(sensorValues[SENSOR_BAT_VOLTAGE])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("batvoltage", sensorValues[SENSOR_BAT_VOLTAGE]);
|
||||
_writePoint();
|
||||
}
|
||||
if (!(isnan(sensorValues[SENSOR_ESAVEMODE])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("esavemode", sensorValues[SENSOR_ESAVEMODE]);
|
||||
_writePoint();
|
||||
}
|
||||
if (!(isnan(sensorValues[SENSOR_BATCHARGESTATE])))
|
||||
{
|
||||
sensor.clearFields();
|
||||
sensor.addField("batchargestate", sensorValues[SENSOR_BATCHARGESTATE]);
|
||||
_writePoint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _writePoint() {
|
||||
|
||||
// wait unitl ready
|
||||
do {
|
||||
#ifdef DEBUG
|
||||
Serial.print("InfluxDB: waiting for write ready\n");
|
||||
#endif
|
||||
} while (client.canSendRequest() == false);
|
||||
|
||||
// Write point
|
||||
if (!client.writePoint(sensor)) {
|
||||
#ifdef DEBUG
|
||||
Serial.print("InfluxDB write failed: ");
|
||||
Serial.println(client.getLastErrorMessage());
|
||||
Serial.print("\nErrorcode: ");
|
||||
Serial.println(client.getLastStatusCode());
|
||||
Serial.print("\n");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Serial.print("InfluxDB write done\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // influxdb version 2 check
|
||||
|
|
0
firmware/sensor_apds9930.ino
Executable file → Normal file
0
firmware/sensor_apds9930.ino
Executable file → Normal file
0
firmware/sensor_battery.ino
Executable file → Normal file
0
firmware/sensor_battery.ino
Executable file → Normal file
2
firmware/sensor_bme280.ino
Executable file → Normal file
2
firmware/sensor_bme280.ino
Executable file → Normal file
|
@ -14,7 +14,7 @@ bool sensor_bme280_begin(uint8_t addr) {
|
|||
}
|
||||
|
||||
float bme280_temperature() {
|
||||
return _sensor_bme280.readTemperature();
|
||||
return _sensor_bme280.readTemperature() * TEMP_FACTOR;
|
||||
}
|
||||
float bme280_pressure() {
|
||||
return _sensor_bme280.readPressure() / 100.0F;
|
||||
|
|
|
@ -1,23 +1,34 @@
|
|||
|
||||
#include "config_user.h"
|
||||
#include "config.h"
|
||||
|
||||
int anemometerRotations = 0;
|
||||
unsigned long currentTime = 0;
|
||||
unsigned int anemometerRotations = 0;
|
||||
|
||||
ICACHE_RAM_ATTR void _anemometerInterrupt() {
|
||||
ICACHE_RAM_ATTR void _anemometerInterrupt()
|
||||
{
|
||||
anemometerRotations++;
|
||||
#ifdef DEBUG
|
||||
Serial.print("*");
|
||||
#endif
|
||||
}
|
||||
|
||||
float wind_speed() {
|
||||
float wind_speed()
|
||||
{
|
||||
anemometerRotations = 0;
|
||||
currentTime = millis();
|
||||
|
||||
int interruptNumber = digitalPinToInterrupt(ANEMOMETER_PIN);
|
||||
|
||||
attachInterrupt(interruptNumber, _anemometerInterrupt, RISING);
|
||||
delay(1000 * 5);
|
||||
delay(1000 * WIND_SENSOR_MEAS_TIME_S); // time to measure
|
||||
detachInterrupt(interruptNumber);
|
||||
|
||||
return (float)anemometerRotations / 5.0 * 2.4;
|
||||
// calculate the speed as km/h
|
||||
float tmp_speed = (float)anemometerRotations * WINDSPEED_FACTOR;
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print("Windspeed: " + String(tmp_speed));
|
||||
#endif
|
||||
|
||||
return tmp_speed;
|
||||
|
||||
}
|
||||
|
|
|
@ -11,13 +11,26 @@
|
|||
#include <ESP8266HTTPUpdateServer.h>
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include <WiFiManager.h> // WiFiManager from bib manager
|
||||
|
||||
ESP8266WebServer httpServer(8080);
|
||||
#include "config.h"
|
||||
#include "config_user.h"
|
||||
|
||||
ESP8266WebServer httpServer(WEB_UPDATER_HTTP_PORT);
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
|
||||
String _webUpdater_ip = "127.0.0.1";
|
||||
String _webUpdater_dev = "unknown";
|
||||
float _webUpdater_sensValues[VALUES];
|
||||
float _webUpdater_sensValues[VALUES];
|
||||
|
||||
String hb_ws_msg_start = "{";
|
||||
String hb_ws_msg_temp = "\"temperature\": ";
|
||||
String hb_ws_msg_humi = "\"humidity\": ";
|
||||
String hb_ws_msg_light = "\"lightlevel\": ";
|
||||
String hb_ws_msg_windspeed = "\"windspeed\": ";
|
||||
String hb_ws_msg_pressure = "\"pressure\": ";
|
||||
String hb_ws_msg_timestamp = "\"timestamp\": ";
|
||||
String hb_ws_msg_end = "}";
|
||||
|
||||
void setupWebUpdater(String device, String ip)
|
||||
{
|
||||
|
@ -27,7 +40,11 @@ void setupWebUpdater(String device, String ip)
|
|||
|
||||
httpUpdater.setup(&httpServer);
|
||||
|
||||
httpServer.on("/", showHTMLMain); // oko specific site
|
||||
httpServer.on("/", showHTMLMain);
|
||||
httpServer.on("/resetWifiManager", resetWifiManager);
|
||||
#ifdef HOMEBRIDGE_WEBSTAT
|
||||
httpServer.on("/hbWebstat", hb_webstat_send);
|
||||
klaute marked this conversation as resolved
f
commented
Ein Prometheus Endpunkt wäre noch der Oberhammer :) Ein Prometheus Endpunkt wäre noch der Oberhammer :)
Ich denke das bau ich dann ein, wenn der PR gemerged ist.
klaute
commented
Das wäre super wenn wir noch mehrere andere Plattformen unterstützen könnten! Das wäre super wenn wir noch mehrere andere Plattformen unterstützen könnten!
|
||||
#endif
|
||||
|
||||
httpServer.begin();
|
||||
|
||||
|
@ -40,13 +57,15 @@ void doWebUpdater(void)
|
|||
httpServer.handleClient();
|
||||
}
|
||||
|
||||
void setSensorData(float sensorValues[]) {
|
||||
void setSensorData(float sensorValues[])
|
||||
{
|
||||
for (uint8_t i = 0; i < VALUES; i++) {
|
||||
_webUpdater_sensValues[i] = sensorValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
void showHTMLMain(void) {
|
||||
void showHTMLMain(void)
|
||||
{
|
||||
String message = "<html><head><title>OKO Weatherstation - " + String(_webUpdater_dev) + "</title>"
|
||||
"<meta http-equiv=\"refresh\" content=\"20\">"
|
||||
"</head><body>"
|
||||
|
@ -63,3 +82,55 @@ void showHTMLMain(void) {
|
|||
|
||||
httpServer.send(200, "text/html", message);
|
||||
}
|
||||
|
||||
void hb_webstat_send(void)
|
||||
{
|
||||
unsigned int timestamp = 0;
|
||||
for (int i = 0; i < VALUES; i++)
|
||||
{
|
||||
timestamp += int(_webUpdater_sensValues[i]) + millis();
|
||||
}
|
||||
String msg = hb_ws_msg_start +
|
||||
hb_ws_msg_temp +
|
||||
String(_webUpdater_sensValues[SENSOR_TEMPERATURE], 2) +
|
||||
", " +
|
||||
hb_ws_msg_humi +
|
||||
String(_webUpdater_sensValues[SENSOR_HUMIDITY], 2) +
|
||||
", " +
|
||||
hb_ws_msg_light +
|
||||
String(_webUpdater_sensValues[SENSOR_LIGHT], 0) + // The light level for the homebridge-http-lux2 plugin is only able to parse integer values
|
||||
", " +
|
||||
hb_ws_msg_windspeed +
|
||||
String(_webUpdater_sensValues[SENSOR_WINDSPEED], 2) +
|
||||
", " +
|
||||
hb_ws_msg_pressure +
|
||||
String(_webUpdater_sensValues[SENSOR_PRESSURE], 2) +
|
||||
", " +
|
||||
hb_ws_msg_timestamp +
|
||||
String(timestamp) +
|
||||
hb_ws_msg_end;
|
||||
|
||||
httpServer.send(200, "text/html", msg);
|
||||
}
|
||||
|
||||
void resetWifiManager()
|
||||
{
|
||||
|
||||
String message = "<html><head><title>OKO Weatherstation - " + String(_webUpdater_dev) + "</title>"
|
||||
"<meta http-equiv=\"refresh\" content=\"20\">"
|
||||
"</head><body>"
|
||||
"Reset WifiManager config.<br>"
|
||||
"Rebooting...<br>"
|
||||
"</body></html>";
|
||||
|
||||
httpServer.send(200, "text/html", message);
|
||||
|
||||
// Erase WiFi Credentials, enable, compile, flash, disable and reflash.
|
||||
WiFiManager wifiManager;
|
||||
wifiManager.resetSettings();
|
||||
|
||||
delay(5000);
|
||||
|
||||
// manual reset after restart is required
|
||||
ESP.restart();
|
||||
}
|
||||
|
|
0
influxdb-lib/examples/influxdb_write/influxdb_write.ino
Normal file → Executable file
0
influxdb-lib/examples/influxdb_write/influxdb_write.ino
Normal file → Executable file
Loading…
Reference in a new issue
Ist das die Callback-URL, wenn der Wind zu stark weht?
Es wäre gut, wenn man das Feature an/ausschalten könnte, da es schon sehr spezifisch auf deinen Anwendungsfall gestrickt ist.