feature/InfluxDB-Connection-Update #1

Merged
klaute merged 39 commits from feature/InfluxDB-Connection-Update into master 2022-05-23 17:36:59 +02:00
16 changed files with 406 additions and 407 deletions

5
.gitignore vendored Normal file → Executable file
View 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

View file

@ -1,2 +0,0 @@
sudo docker-compose exec esphome esphome run /config/weatherstation.yml

View file

@ -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:

View file

@ -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
View file

32
firmware/config.h Executable file → Normal file
View 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
#endif
#endif

51
firmware/config_user.h.example Normal file → Executable file
View 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";
// 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
View 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

151
firmware/firmware.ino Executable file → Normal file
View 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
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[]) {
@ -238,4 +313,4 @@ void logToSerial(float sensorValues[]) {
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]));
}
}

View file

@ -1,3 +1,8 @@
#include "config_user.h"
#if INFLUXDB_VERSION == 1
#include <ESP8266Influxdb.h> // https://github.com/hwwong/ESP8266Influxdb
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

2
firmware/sensor_apds9930.ino Executable file → Normal file
View file

@ -20,4 +20,4 @@ float apds9930_light() {
} else {
return 0;
}
}
}

2
firmware/sensor_battery.ino Executable file → Normal file
View file

@ -48,4 +48,4 @@ int energySavingMode() {
float isEnergySavingMode() {
return _sensor_battery_saveMode;
}
}

4
firmware/sensor_bme280.ino Executable file → Normal file
View file

@ -14,11 +14,11 @@ 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;
}
float bme280_humidity() {
return _sensor_bme280.readHumidity() * HUMIDITY_FACTOR;
}
}

View file

@ -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;
}

View file

@ -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
Review

Ein Prometheus Endpunkt wäre noch der Oberhammer :)
Ich denke das bau ich dann ein, wenn der PR gemerged ist.

Ein Prometheus Endpunkt wäre noch der Oberhammer :) Ich denke das bau ich dann ein, wenn der PR gemerged ist.
Review

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();
}

View file