Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

local WLAN http-pages, influx-db integration and translation system #453

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Actual_values.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Config_Influx.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Loginfo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 71 additions & 0 deletions README_FORK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Fork of MultiGeiger
# Adoptions in this fork:
this fork is based on the master branch of the original MultiGeiger software (https://github.com/ecocurious2/MultiGeiger.git) as of 08.04.2022 (Firmware V1.17.0-dev)

# Motivation:
Having a Air Quality sensor from the Luftdaten project (sensor.community) installed, I know about problems with dropping Wifi connections, memory leaks,
interrupted data transfer to the internet portals, etc.
And I also know, without being able to monitor my sensor outside at its final installation position, I would have been lost.

E.g. to search a good installation position outside, I use a power bank for the sensor and my cellphone to display the 'Actual Values' page, and I directly see the Wifi quality.

Then you install it there in a provisional manner and watch the values from inside via Wifi for a couple of days.

If sending to the portals fails, you can see the http return code on the log page.

You can actually monitor all values which are normally sent to the serial port via the log info page via WiFi now,
no need to connect a laptop anymore via USB (which would imply a restart, resetting the sensor, which could solve/hide an actual problem ) ...

As long as you have WiFi, you can monitor your Sensor, even if your Internet connection is broken down.

I have an Influx-DB running here on a raspberry, where I log all my weather data locally. Of course I wanted to include this sensor as well.

This fork bascically ports some functionality from the 'Luftdaten-Sensor' (sensor.community) to the MultiGeiger,
with some simplifications and enhancements in the code ...

It does NOT touch the original code concerning gathering the data from the tube, etc. This is all untouched !

Nicola from the ecocurious team was so nice to share the ecocurious logo for this fork.

# This implementation adds :
* local html pages which are accessible via WiFi. Just connect to the sensor in your WLAN and you're on the first page ...

* first page is showing actual sensor values (Dose rate, cps, HV pulses), Wifi-Data (Signal/Quality), free Memory, Firmware Version & Date …

![Alt text](./Actual_values.png)

* if BME280/680 is available, it also shows temperature, humidity & pressure

* the page refreshes automatically every 10s

* second page shows log infos which are normally only available through serial connection

![Alt text](./Loginfo.png)

* the loginfo is updated automatically in the central frame and can be scrolled

* The loglevel can be changed temporarily (runtime, not saved)

* a configurable http connection to a influx database included in the original configuration page

![Alt text](./Config_Influx.png)

* (extendable) translation system for the texts displayed on the local WLAN pages.

* Languages DE, EN and IT are available already.

* Preferred language to be set on compile time

* in the configuration page where Text attributes were showing only '?????' upon first run.

# Compilation :

I use 'VS code' and platformio for compilation, upload and monitoring (I'm working under Fedora).
* You can copy the platformio-example.ini to platformio.ini, compile one of the (currently) 3 language options, and upload it.
* The only thing to be adopted in platformio.ini is probably upload_port & monitor_port
* Necessary libraries should be pulled in automatically.
* Furthermore you have to copy userdefines-example.h to userdefines.h and adopt the content before compilation.

I have only experience with the WiFi version of this sensor, so the pages will not be visible on the LoRaWan sensor option due to missing WiFi (I guess).


5 changes: 3 additions & 2 deletions multigeiger/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ static const char *status_chars[STATUS_MAX] = {
".t3T?", // ST_TTN_OFF, ST_TTN_IDLE, ST_TTN_ERROR, ST_TTN_SENDING, ST_TTN_INIT
// group BlueTooth
".B4b?", // ST_BLE_OFF, ST_BLE_CONNECTED, ST_BLE_ERROR, ST_BLE_CONNECTABLE, ST_BLE_INIT
// group InfluxDB
".i5I?", // ST_INFLUX_OFF, ST_INFLUX_IDLE, ST_INFLUX_ERROR, ST_INFLUX_SENDING,ST_INFLUX_INIT
// group other
".", // ST_NODISPLAY
".", // ST_NODISPLAY
".", // ST_NODISPLAY
".H7", // ST_NODISPLAY, ST_HV_OK, ST_HV_ERROR
};

Expand Down
6 changes: 6 additions & 0 deletions multigeiger/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ void display_statusline(String txt);
#define ST_BLE_INIT 4

// status index 5 is still free
#define STATUS_INFLUX 5
#define ST_INFLUX_OFF 0
#define ST_INFLUX_IDLE 1
#define ST_INFLUX_ERROR 2
#define ST_INFLUX_SENDING 3
#define ST_INFLUX_INIT 4

// status index 6 is still free

Expand Down
19 changes: 13 additions & 6 deletions multigeiger/log.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// low level log() call - outputs to serial/usb

#include <Arduino.h>

#include "string.h"
#include "log.h"
#include "clock.h"
#include "utils.h"

// the GEIGER: prefix is is to easily differentiate our output from other esp32 output (e.g. wifi messages)
#define LOG_PREFIX_FORMAT "GEIGER: %s "
#define LOG_PREFIX_LEN (7+1+19+1) // chars, without the terminating \0

static int log_level = NOLOG; // messages at level >= log_level will be output
int log_level = NOLOG; // messages at level >= log_level will be output

void log(int level, const char *format, ...) {
if (level < log_level)
if (level > log_level)
return;

va_list args;
Expand All @@ -21,12 +22,18 @@ void log(int level, const char *format, ...) {
sprintf(buf, LOG_PREFIX_FORMAT, utctime());
vsprintf(buf + LOG_PREFIX_LEN, format, args);
va_end(args);
Serial.println(buf);
Debug.println(buf);
}

void setup_log(int level) {
Serial.begin(115200);
while (!Serial) {};
Debug.begin(115200); // Output to Serial at 115200 baud
while (!Debug) {};
log(NOLOG, "Logging initialized at level %d.", level); // this will always be output
log_level = level;
}
int getloglevel(void){
return log_level;
}
void setloglevel(int level){
log_level=level;
}
32 changes: 25 additions & 7 deletions multigeiger/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,32 @@
#define _LOG_H_

// log levels
#define DEBUG 0
#define INFO 1
#define WARNING 2
#define ERROR 3
#define CRITICAL 4
#define NOLOG 999 // only to set log_level, so log() never creates output
// reverted the numbers to meet logic in log_data.h (see #define Serial_None 0 ...)
// DEBUG is max info, reducing output step by step till NOLOG
/* TR, 20.04.2022 :
1) there's no CRITICAL and no WARNING . remove both and use numbers for Serial_Print_Mode?
and NOLOG really logs nothing then ...
2) Serial_Print_Mode should be included in this sequence (--> settable through the loglevel!).
It's not clear to me, why Serial_Print_Mode is set fix at compilation time ?!?
Org:
#define DEBUG 5
#define INFO 4
#define WARNING 3 // there is nothing with WARNING ...
#define ERROR 2
#define CRITICAL 1 // there is nothing with CRITICAL ...
#define NOLOG 0 // minimum info, only display alarms
*/

#define DEBUG 5
#define INFO 4
#define MED_INFO 3
#define MIN_INFO 2
#define ERROR 1
#define NOLOG 0


void log(int level, const char *format, ...);
void setup_log(int level);

int getloglevel(void);
void setloglevel(int level);
#endif // _LOG_H_
43 changes: 23 additions & 20 deletions multigeiger/log_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ int Serial_Print_Mode;

static const char *Serial_Logging_Name = "Simple Multi-Geiger";
static const char *dashes = "------------------------------------------------------------------------------------------------------------------------";

static const char *Serial_Logging_Header = " %10s %15s %10s %9s %9s %8s %9s %9s %9s %5s %5s %6s";
static const char *Serial_Logging_Body = "DATA %10d %15d %10f %9f %9d %8d %9d %9f %9f %5.1f %5.1f %6.0f";
static const char *Serial_One_Minute_Log_Header = " %4s %10s %29s";
Expand All @@ -20,48 +19,52 @@ void setup_log_data(int mode) {
// Write Header of Table, depending on the logging mode:
bool data_log_enabled = (Serial_Print_Mode == Serial_Logging) || (Serial_Print_Mode == Serial_One_Minute_Log) || (Serial_Print_Mode == Serial_Statistics_Log);
if (data_log_enabled) {
log(INFO, dashes);
log(INFO, "%s, Version %s", Serial_Logging_Name, VERSION_STR);
log(INFO, dashes);
log(Serial_Print_Mode, dashes);
log(Serial_Print_Mode, "%s, Version %s", Serial_Logging_Name, VERSION_STR);
log(Serial_Print_Mode, dashes);
}
}

//Serial_Logging
void log_data(int GMC_counts, int time_difference, float Count_Rate, float Dose_Rate, int HV_pulse_count,
int accumulated_GMC_counts, int accumulated_time, float accumulated_Count_Rate, float accumulated_Dose_Rate,
float t, float h, float p) {
static int counter = 0;
if (counter++ % 20 == 0) { // output the header now and then, so table is better readable
log(INFO, Serial_Logging_Header,
"GMC_counts", "Time_difference", "Count_Rate", "Dose_Rate", "HV Pulses", "Accu_GMC", "Accu_Time", "Accu_Rate", "Accu_Dose", "Temp", "Humi", "Press");
log(INFO, Serial_Logging_Header,
"[Counts]", "[ms]", "[cps]", "[uSv/h]", "[-]", "[Counts]", "[ms]", "[cps]", "[uSv/h]", "[C]", "[%]", "[hPa]");
log(INFO, dashes);
write_log_header();
}
log(INFO, Serial_Logging_Body,
GMC_counts, time_difference, Count_Rate, Dose_Rate, HV_pulse_count,
accumulated_GMC_counts, accumulated_time, accumulated_Count_Rate, accumulated_Dose_Rate,
t, h, p);
}

//Serial_One_Minute_Log
void log_data_one_minute(int time_s, int cpm, int counts) {
static int counter = 0;
if (counter++ % 20 == 0) { // output the header now and then, so table is better readable
log(INFO, Serial_One_Minute_Log_Header,
log(MED_INFO, Serial_One_Minute_Log_Header,
"Time", "Count_Rate", "Counts");
log(INFO, Serial_One_Minute_Log_Header,
log(MED_INFO, Serial_One_Minute_Log_Header,
"[s]", "[cpm]", "[Counts per last measurement]");
log(INFO, dashes);
log(MED_INFO, dashes);
}
log(INFO, Serial_One_Minute_Log_Body,
log(MED_INFO, Serial_One_Minute_Log_Body,
time_s, cpm, counts);
}

// Serial_Statistics_Log
void log_data_statistics(int count_time_between) {
static int counter = 0;
if (counter++ % 20 == 0) { // output the header now and then, so table is better readable
log(INFO, "Time between two impacts");
log(INFO, "[usec]");
log(INFO, dashes);
log(MIN_INFO, "Time between two impacts");
log(MIN_INFO, "[usec]");
log(MIN_INFO, dashes);
}
log(INFO, "%d", count_time_between);
log(MIN_INFO, "%d", count_time_between);
}
//Header for Serial_Logging
void write_log_header(){
log(INFO, Serial_Logging_Header,
"GMC_counts", "Time_difference", "Count_Rate", "Dose_Rate", "HV Pulses", "Accu_GMC", "Accu_Time", "Accu_Rate", "Accu_Dose", "Temp", "Humi", "Press");
log(INFO, Serial_Logging_Header,
"[Counts]", "[ms]", "[cps]", "[uSv/h]", "[-]", "[Counts]", "[ms]", "[cps]", "[uSv/h]", "[C]", "[%]", "[hPa]");
log(INFO, dashes);
}
27 changes: 23 additions & 4 deletions multigeiger/log_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,30 @@
#define _LOG_DATA_H_

// Values for Serial_Print_Mode to configure Serial (USB) output mode.
/* TR, 20.04.2022 :
Serial_Print_Mode should be included in NOLOG...DEBUG sequence (--> settable through the loglevel!).
It's not clear to me, why Serial_Print_Mode is set fix at compilation time ...
Current settings are :
Serial_None 0 // No Serial output
Serial_Debug 1 // Only debug and error messages
Serial_Logging 2 // Log measurements as a table (default)
Serial_One_Minute_Log 3 // One Minute logging
Serial_Statistics_Log 4 // Logs time [us] between two events, 1/s

Proposal:
rename standard log levels and include Serial_xxx :
NOLOG 0 --> incl. Serial_None, display ALARMS, else turn off logging
ERROR 1 --> incl. 0
MIN_INFO 2 --> incl. Serial_Statistics_Log + 0 + 1
MED_INFO 3 --> incl. Serial_One_Minute_Log + 0 + 1
MAX_INFO 4 --> incl. Serial_Logging + 0 + 1
DEBUG 5 --> incl. Serial_Debug + 0 + 1 + 4
*/
#define Serial_None 0 // No Serial output
#define Serial_Debug 1 // Only debug and error messages
#define Serial_Logging 2 // Log measurements as a table
#define Serial_Debug 5 // Only debug and error messages
#define Serial_Logging 4 // Log measurements as a table
#define Serial_One_Minute_Log 3 // One Minute logging
#define Serial_Statistics_Log 4 // Logs time [us] between two events
#define Serial_Statistics_Log 2 // Logs time [us] between two events

extern int Serial_Print_Mode;

Expand All @@ -18,5 +37,5 @@ void log_data(int GMC_counts, int time_difference, float Count_Rate, float Dose_
float t, float h, float p);
void log_data_one_minute(int time_s, int cpm, int counts);
void log_data_statistics(int count_time_between);

void write_log_header(void);
#endif // _LOG_DATA_H_
Loading