web_config.cpp 12.7 KB
Newer Older
1
2
#include "web_config.h"

Eric Duminil's avatar
Eric Duminil committed
3
4
#define STRING_LEN 40 // Should be enough for ip, addresses, passwords...

Eric Duminil's avatar
Eric Duminil committed
5
6
7
8
9
10
11
#if defined(ESP8266)
#  include <ESP8266WebServer.h>
#elif defined(ESP32)
#  include <WebServer.h>
#endif

#include "config.h"
Eric Duminil's avatar
Eric Duminil committed
12
13
14
15
#ifndef MEASUREMENT_TIMESTEP
#  error Missing config.h file. Please copy config.public.h to config.h.
#endif

16
17
18
19
20
// Make sure AMPEL_WIFI is defined and not empty:
#if !defined(AMPEL_WIFI) || (7-AMPEL_WIFI-7 == 14)
#  error config.h has a new structure, please update it from config.public.h (e.g. AMPEL_WIFI should be set to true or false)
#endif

Eric Duminil's avatar
Eric Duminil committed
21
22
#include "util.h"
#include "sensor_console.h"
Eric Duminil's avatar
Eric Duminil committed
23

Eric Duminil's avatar
Eric Duminil committed
24
#include <IotWebConf.h>
Eric Duminil's avatar
Eric Duminil committed
25
#include <IotWebConfTParameter.h>
Eric Duminil's avatar
Eric Duminil committed
26
27
#include <IotWebConfOptionalGroup.h>

28
29
//TODO: Check memory consumption. Disable DEBUG info?
//TODO: Convert all strings to F-strings
Eric Duminil's avatar
Notes    
Eric Duminil committed
30

31
32
33
34
35
36
37
namespace web_config {
#if defined(ESP8266)
  ESP8266WebServer http(80); // Create a webserver object that listens for HTTP request on port 80
#elif defined(ESP32)
  WebServer http(80);
#endif

Eric Duminil's avatar
Eric Duminil committed
38
  DNSServer dnsServer; //TODO: Check if needed
39
40
41

  IotWebConf *iotWebConf;

Eric Duminil's avatar
Eric Duminil committed
42
  const char config_version[IOTWEBCONF_CONFIG_VERSION_LENGTH] = "a09"; // -- Configuration specific key. The value should be modified if config structure was changed.
43
  using namespace iotwebconf;
44

Eric Duminil's avatar
Eric Duminil committed
45
  /**
Eric Duminil's avatar
Eric Duminil committed
46
   * WiFi params
Eric Duminil's avatar
Eric Duminil committed
47
   */
48
49
  CheckboxTParameter ampelWifiParam =
      Builder<CheckboxTParameter>("WiFi").label("WiFi?").defaultValue(AMPEL_WIFI).build();
Eric Duminil's avatar
Eric Duminil committed
50
51
52
  IntTParameter<uint16_t> wifiTimeoutParam =
      Builder<IntTParameter<uint16_t>>("wifi_timeout").label("WiFi timeout").defaultValue(WIFI_TIMEOUT).min(0).placeholder(
          "[s]").build();
Eric Duminil's avatar
Eric Duminil committed
53

Eric Duminil's avatar
Eric Duminil committed
54
  //TODO: Distribute to corresponding classes, possibly with callbacks?
Eric Duminil's avatar
Eric Duminil committed
55
  //TODO: Chainedparameters?
Eric Duminil's avatar
Eric Duminil committed
56
57
58
  /**
   * CO2 sensor
   */
Eric Duminil's avatar
Done    
Eric Duminil committed
59
  ParameterGroup co2Params = ParameterGroup("co2", "CO2 Sensor");
Eric Duminil's avatar
Eric Duminil committed
60

Eric Duminil's avatar
Eric Duminil committed
61
62
  IntTParameter<uint16_t> timestepParam =
      Builder<IntTParameter<uint16_t>>("timestep").label("Measurement timestep").defaultValue(MEASUREMENT_TIMESTEP).min(
Eric Duminil's avatar
Eric Duminil committed
63
          2).max(1800).placeholder("[s]").build();
Eric Duminil's avatar
Eric Duminil committed
64

Eric Duminil's avatar
Eric Duminil committed
65
  FloatTParameter temperatureOffsetParam =
Eric Duminil's avatar
Eric Duminil committed
66
      Builder<FloatTParameter>("temp_offset").label("Temperature offset").defaultValue(TEMPERATURE_OFFSET).placeholder(
Eric Duminil's avatar
Eric Duminil committed
67
          "[K]").step(0.1).build();
Eric Duminil's avatar
Eric Duminil committed
68

Eric Duminil's avatar
Eric Duminil committed
69
  IntTParameter<uint16_t> altitudeParam = Builder<IntTParameter<uint16_t>>("altitude").label("Altitude").defaultValue(
Eric Duminil's avatar
Eric Duminil committed
70
  ALTITUDE_ABOVE_SEA_LEVEL).min(0).step(1).placeholder("[m]").build();
Eric Duminil's avatar
Eric Duminil committed
71

Eric Duminil's avatar
Eric Duminil committed
72
73
  IntTParameter<uint16_t> atmosphericCO2Param = Builder<IntTParameter<uint16_t>>("atmospheric_co2").label(
      "Atmospheric CO2 concentration").defaultValue(
Eric Duminil's avatar
Eric Duminil committed
74
  ATMOSPHERIC_CO2_CONCENTRATION).min(400).max(2000).step(1).placeholder("ppm").build();
Eric Duminil's avatar
Eric Duminil committed
75

Eric Duminil's avatar
Eric Duminil committed
76
  CheckboxTParameter autoCalibrateParam = Builder<CheckboxTParameter>("asc").label("Auto-calibration?").defaultValue(
Eric Duminil's avatar
Eric Duminil committed
77
  AUTO_CALIBRATE_SENSOR).build();
Eric Duminil's avatar
Eric Duminil committed
78

Eric Duminil's avatar
Eric Duminil committed
79
80
81
  /**
   * LED
   */
Eric Duminil's avatar
Eric Duminil committed
82
  //NOTE: Could also be optional : for LED 0 / 1
Eric Duminil's avatar
Eric Duminil committed
83
84
85
86
87
88
89
90
  ParameterGroup ledParams = ParameterGroup("LED", "LED");

  IntTParameter<uint8_t> maxBrightnessParam =
      Builder<IntTParameter<uint8_t>>("max_brightness").label("Max Brightness").defaultValue(MAX_BRIGHTNESS).min(0).max(
          255).build();
  IntTParameter<uint8_t> minBrightnessParam =
      Builder<IntTParameter<uint8_t>>("min_brightness").label("Min Brightness").defaultValue(MIN_BRIGHTNESS).min(0).max(
          255).build();
91
  IntTParameter<uint16_t> ledCountParam = Builder<IntTParameter<uint16_t>>("led_count").label("LED ring").defaultValue(
Eric Duminil's avatar
Eric Duminil committed
92
93
  LED_COUNT).min(12).max(16).step(4).build();

Eric Duminil's avatar
Eric Duminil committed
94
95
96
  /**
   * CSV
   */
97
  OptionalParameterGroup csvParams = OptionalParameterGroup("CSV", "CSV", AMPEL_CSV);
Eric Duminil's avatar
Eric Duminil committed
98

99
100
  IntTParameter<uint16_t> csvIntervalParam =
      Builder<IntTParameter<uint16_t>>("csv_interval").label("CSV interval").defaultValue(CSV_INTERVAL).min(0).step(1).placeholder(
Eric Duminil's avatar
Eric Duminil committed
101
          "[s]").build();
Eric Duminil's avatar
Eric Duminil committed
102
103
104
105

  /**
   * MQTT
   */
106
  OptionalParameterGroup mqttParams = OptionalParameterGroup("MQTT", "MQTT", AMPEL_MQTT);
Eric Duminil's avatar
Eric Duminil committed
107

108
109
  IntTParameter<uint16_t> mqttIntervalParam =
      Builder<IntTParameter<uint16_t>>("mqtt_interval").label("MQTT interval").defaultValue(
Eric Duminil's avatar
Eric Duminil committed
110
      MQTT_SENDING_INTERVAL).min(0).step(1).defaultValue(300).placeholder("[s]").build();
Eric Duminil's avatar
Eric Duminil committed
111

Eric Duminil's avatar
Eric Duminil committed
112
113
114
  CheckboxTParameter mqttEncryptionParam =
      Builder<CheckboxTParameter>("mqtt_encryption").label("Encrypt MQTT?").defaultValue(MQTT_ENCRYPTED).build();

Eric Duminil's avatar
Eric Duminil committed
115
  CheckboxTParameter mqttCommandsParam =
Eric Duminil's avatar
Eric Duminil committed
116
      Builder<CheckboxTParameter>("mqtt_commands").label("Allow MQTT commands?").defaultValue(ALLOW_MQTT_COMMANDS).build();
Eric Duminil's avatar
Eric Duminil committed
117

Eric Duminil's avatar
Eric Duminil committed
118
119
  TextTParameter<STRING_LEN> mqttServerParam =
      Builder<TextTParameter<STRING_LEN>>("mqtt_server").label("MQTT Server").defaultValue(MQTT_SERVER).build();
Eric Duminil's avatar
Eric Duminil committed
120

Eric Duminil's avatar
Eric Duminil committed
121
122
  IntTParameter<uint16_t> mqttPortParam = Builder<IntTParameter<uint16_t>>("mqtt_port").label("MQTT Port").defaultValue(
  MQTT_PORT).build();
Eric Duminil's avatar
Eric Duminil committed
123

Eric Duminil's avatar
Eric Duminil committed
124
125
  TextTParameter<STRING_LEN> mqttUserParam =
      Builder<TextTParameter<STRING_LEN>>("mqtt_user").label("MQTT User").defaultValue(MQTT_USER).build();
Eric Duminil's avatar
Eric Duminil committed
126

Eric Duminil's avatar
TODO    
Eric Duminil committed
127
  //TODO: Show the number of * for password?
Eric Duminil's avatar
Eric Duminil committed
128
  PasswordTParameter<STRING_LEN> mqttPasswordParam = Builder<PasswordTParameter<STRING_LEN>>("mqtt_password").label(
Eric Duminil's avatar
Eric Duminil committed
129
      "MQTT password").defaultValue(MQTT_PASSWORD).build();
Eric Duminil's avatar
Eric Duminil committed
130

Eric Duminil's avatar
Eric Duminil committed
131
132
133
  /**
   * NTP Time
   */
Eric Duminil's avatar
Eric Duminil committed
134

Eric Duminil's avatar
Eric Duminil committed
135
  ParameterGroup timeParams = ParameterGroup("NTP", "Time server");
Eric Duminil's avatar
Eric Duminil committed
136
  TextTParameter<STRING_LEN> ntpServerParam =
Eric Duminil's avatar
Eric Duminil committed
137
      Builder<TextTParameter<STRING_LEN>>("ntp_server").label("NTP Server").defaultValue(NTP_SERVER).build();
Eric Duminil's avatar
Eric Duminil committed
138
  IntTParameter<int16_t> timeOffsetParam = Builder<IntTParameter<int16_t>>("timezone").label("Timezone").defaultValue(
Eric Duminil's avatar
Eric Duminil committed
139
      (UTC_OFFSET_IN_SECONDS) / 3600).min(-23).max(23).step(1).placeholder("[h]").build();
Eric Duminil's avatar
Eric Duminil committed
140
  CheckboxTParameter dstParam =
Eric Duminil's avatar
Eric Duminil committed
141
      Builder<CheckboxTParameter>("dst").label("Daylight Saving Time?").defaultValue(false).build();
142

Eric Duminil's avatar
Eric Duminil committed
143
  /**
Eric Duminil's avatar
TODO    
Eric Duminil committed
144
   * LoRaWAN
Eric Duminil's avatar
Eric Duminil committed
145
   */
Eric Duminil's avatar
Eric Duminil committed
146
#if defined(ESP32)
147
  OptionalParameterGroup loraParams = OptionalParameterGroup("LoRaWan", "LoRaWan", AMPEL_LORAWAN);
148
149
  IntTParameter<uint16_t> loraIntervalParam =
      Builder<IntTParameter<uint16_t>>("lora_interval").label("LoRa interval").defaultValue(
Eric Duminil's avatar
Eric Duminil committed
150
151
      LORAWAN_SENDING_INTERVAL).min(0).step(1).defaultValue(300).placeholder("[s]").build();

152
153
154
155
156
157
158
  TextTParameter<17> deviceEUIParam = Builder<TextTParameter<17>>("device_eui").label("Device EUI (MSB)").defaultValue(
  LORAWAN_DEVICE_EUI).build();
  TextTParameter<17> appEUIParam = Builder<TextTParameter<17>>("app_eui").label("App EUI (MSB)").defaultValue(
  LORAWAN_APPLICATION_EUI).build();
  TextTParameter<33> appKeyParam = Builder<TextTParameter<33>>("app_key").label("App key (MSB)").defaultValue(
  LORAWAN_APPLICATION_KEY).build();

Eric Duminil's avatar
Eric Duminil committed
159
#endif
160

Eric Duminil's avatar
Eric Duminil committed
161
  OptionalGroupHtmlFormatProvider optionalGroupHtmlFormatProvider;
162
163
164
165
166

  void update() {
    iotWebConf->doLoop(); // Listen for HTTP requests from clients
  }

Eric Duminil's avatar
Eric Duminil committed
167
168
  void setWifiConnectionCallback(void (*success_function)()) {
    iotWebConf->setWifiConnectionCallback(success_function);
Eric Duminil's avatar
Eric Duminil committed
169
170
  }

Eric Duminil's avatar
Eric Duminil committed
171
172
173
  void setWifiFailCallback(void (*fail_function)()) {
    std::function<WifiAuthInfo* ()> fail_and_return_null = [fail_function]() {
      fail_function();
Eric Duminil's avatar
Eric Duminil committed
174
      iotWebConf->forceApMode(true); // Will stay in AP.
Eric Duminil's avatar
Eric Duminil committed
175
176
177
      return nullptr;
    };
    iotWebConf->setWifiConnectionFailedHandler(fail_and_return_null);
Eric Duminil's avatar
Eric Duminil committed
178
179
  }

180
  void initialize() {
181
    iotWebConf = new IotWebConf(ampel.sensorId, &dnsServer, &http, AMPEL_PASSWORD, config_version);
182

183
184
185
    iotWebConf->setHtmlFormatProvider(&optionalGroupHtmlFormatProvider);

    iotWebConf->addSystemParameter(&ampelWifiParam);
Eric Duminil's avatar
Eric Duminil committed
186
    iotWebConf->addSystemParameter(&wifiTimeoutParam);
Eric Duminil's avatar
Eric Duminil committed
187

Eric Duminil's avatar
Eric Duminil committed
188
189
190
    iotWebConf->getThingNameParameter()->label = "Ampel name";
    iotWebConf->getApPasswordParameter()->label = "Ampel password (user : 'admin')";

Eric Duminil's avatar
Eric Duminil committed
191
192
    co2Params.addItem(&timestepParam);
    co2Params.addItem(&temperatureOffsetParam);
Eric Duminil's avatar
Eric Duminil committed
193
194
195
    co2Params.addItem(&altitudeParam);
    co2Params.addItem(&atmosphericCO2Param);
    co2Params.addItem(&autoCalibrateParam);
Eric Duminil's avatar
Eric Duminil committed
196

Eric Duminil's avatar
Eric Duminil committed
197
    ledParams.addItem(&minBrightnessParam);
Eric Duminil's avatar
Eric Duminil committed
198
    ledParams.addItem(&maxBrightnessParam);
Eric Duminil's avatar
Eric Duminil committed
199
200
    ledParams.addItem(&ledCountParam);

Eric Duminil's avatar
Eric Duminil committed
201
    timeParams.addItem(&ntpServerParam);
202
203
204
    timeParams.addItem(&timeOffsetParam);
    timeParams.addItem(&dstParam);

205
    csvParams.addItem(&csvIntervalParam);
Eric Duminil's avatar
Eric Duminil committed
206

207
    mqttParams.addItem(&mqttIntervalParam);
Eric Duminil's avatar
Eric Duminil committed
208
209
210
211
    mqttParams.addItem(&mqttServerParam);
    mqttParams.addItem(&mqttPortParam);
    mqttParams.addItem(&mqttUserParam);
    mqttParams.addItem(&mqttPasswordParam);
Eric Duminil's avatar
Eric Duminil committed
212
213
    mqttParams.addItem(&mqttEncryptionParam);
    mqttParams.addItem(&mqttCommandsParam);
Eric Duminil's avatar
Eric Duminil committed
214

Eric Duminil's avatar
Eric Duminil committed
215
#if defined(ESP32)
216
    loraParams.addItem(&loraIntervalParam);
Eric Duminil's avatar
Eric Duminil committed
217
218
219
    loraParams.addItem(&deviceEUIParam);
    loraParams.addItem(&appEUIParam);
    loraParams.addItem(&appKeyParam);
Eric Duminil's avatar
Eric Duminil committed
220
#endif
221

Eric Duminil's avatar
Eric Duminil committed
222
    iotWebConf->addParameterGroup(&co2Params);
Eric Duminil's avatar
Eric Duminil committed
223
    iotWebConf->addParameterGroup(&ledParams);
224
    iotWebConf->addParameterGroup(&timeParams);
Eric Duminil's avatar
Eric Duminil committed
225
226
    iotWebConf->addParameterGroup(&csvParams);
    iotWebConf->addParameterGroup(&mqttParams);
Eric Duminil's avatar
Eric Duminil committed
227
#if defined(ESP32)
228
    iotWebConf->addParameterGroup(&loraParams);
Eric Duminil's avatar
Eric Duminil committed
229
#endif
Eric Duminil's avatar
Eric Duminil committed
230

Eric Duminil's avatar
Eric Duminil committed
231
    //TODO: Add "ap" command?
Eric Duminil's avatar
Could    
Eric Duminil committed
232
233
    //TODO: Add "wifi_ssid" command?
    //TODO: Add "wifi_password" command?
Eric Duminil's avatar
Eric Duminil committed
234
235
    sensor_console::defineCommand("reset_config", []() {
      Serial.println(F("Resetting config..."));
Eric Duminil's avatar
Eric Duminil committed
236
      iotWebConf->getRootParameterGroup()->applyDefaultValue();
Eric Duminil's avatar
Eric Duminil committed
237
238
239
240
      iotWebConf->saveConfig();
      Serial.println(F("Done!"));
    }, F("(resets the complete IotWeb config)"));

Eric Duminil's avatar
Eric Duminil committed
241
    sensor_console::defineIntCommand("wifi", [](int32_t onOff) {
Eric Duminil's avatar
Eric Duminil committed
242
      config::is_wifi_on = onOff;
Eric Duminil's avatar
Eric Duminil committed
243
244
245
      iotWebConf->saveConfig();
      Serial.print(F("WiFi - "));
      Serial.println(onOff ? F("On!") : F("Off!"));
Eric Duminil's avatar
Doc    
Eric Duminil committed
246
    }, F("0/1 (Turns Wifi on/off)."));
Eric Duminil's avatar
Eric Duminil committed
247

Eric Duminil's avatar
Eric Duminil committed
248
    iotWebConf->loadConfig();
Eric Duminil's avatar
Eric Duminil committed
249

Eric Duminil's avatar
Eric Duminil committed
250
    if (!config::is_wifi_on) {
Eric Duminil's avatar
Eric Duminil committed
251
252
253
      Serial.println(F("Wifi is off : no access point or connection. Use 'wifi 1' to turn on again!"));
      return;
    }
Eric Duminil's avatar
Eric Duminil committed
254

255
256
257
258
259
260
    const int ONBOARD_LED_PIN = 2;
# ifdef ESP8266
    iotWebConf->setStatusPin(ONBOARD_LED_PIN, LOW);
# else
    iotWebConf->setStatusPin(ONBOARD_LED_PIN, HIGH);
# endif
Eric Duminil's avatar
Eric Duminil committed
261
262

    iotWebConf->setWifiConnectionTimeoutMs(1000UL * config::wifi_timeout);
263
264
265
266
267
268
269
270

    iotWebConf->skipApStartup();
    //TODO: Add callbacks
    //TODO: Add default values for SSID/password
    //TODO: Save LoRaWAN key if possible?

    iotWebConf->init();

Eric Duminil's avatar
Eric Duminil committed
271
272
    //TODO: Authenticate only if required?
    //TODO: / captive fast return?
273
274
275
276

    http.on("/config", [] {
      iotWebConf->handleConfig();
    });
Eric Duminil's avatar
Eric Duminil committed
277

278
279
280
281
282
    http.onNotFound([]() {
      iotWebConf->handleNotFound();
    });
  }
}
Eric Duminil's avatar
Eric Duminil committed
283

Eric Duminil's avatar
Eric Duminil committed
284
285
286
/***
 * Define all the corresponding config values as reference, so that they can be updated.
 */
Eric Duminil's avatar
Eric Duminil committed
287
namespace config {
Eric Duminil's avatar
Eric Duminil committed
288

Eric Duminil's avatar
Eric Duminil committed
289
290
291
292
  char* ampel_name() {
    return web_config::iotWebConf->getThingName();
  }

Eric Duminil's avatar
Rename    
Eric Duminil committed
293
  char* selected_ssid() {
Eric Duminil's avatar
Eric Duminil committed
294
295
296
    return web_config::iotWebConf->getWifiSsidParameter()->valueBuffer;
  }

Eric Duminil's avatar
Eric Duminil committed
297
  char* ampel_password() {
Eric Duminil's avatar
Eric Duminil committed
298
299
300
    return web_config::iotWebConf->getApPasswordParameter()->valueBuffer;
  }

Eric Duminil's avatar
Eric Duminil committed
301
  // Sensor
302
303
304
305
306
307
  uint16_t &measurement_timestep = web_config::timestepParam.value(); // [s] Value between 2 and 1800 (range for SCD30 sensor).
  uint16_t &altitude_above_sea_level = web_config::altitudeParam.value(); // [m]
  uint16_t &co2_calibration_level = web_config::atmosphericCO2Param.value(); // [ppm]
  bool &auto_calibrate_sensor = web_config::autoCalibrateParam.value(); // [true / false]
  float &temperature_offset = web_config::temperatureOffsetParam.value(); // [K] Sign isn't relevant.

Eric Duminil's avatar
Eric Duminil committed
308
  bool &is_wifi_on = web_config::ampelWifiParam.value();
Eric Duminil's avatar
Eric Duminil committed
309
  uint16_t &wifi_timeout = web_config::wifiTimeoutParam.value();
Eric Duminil's avatar
Eric Duminil committed
310
311
312
  void save() {
    web_config::iotWebConf->saveConfig();
  }
Eric Duminil's avatar
Eric Duminil committed
313

Eric Duminil's avatar
Eric Duminil committed
314
  // LEDs
315
316
317
  uint8_t &max_brightness = web_config::maxBrightnessParam.value();
  uint8_t &min_brightness = web_config::minBrightnessParam.value();
  uint16_t &led_count = web_config::ledCountParam.value();
Eric Duminil's avatar
Eric Duminil committed
318

Eric Duminil's avatar
Eric Duminil committed
319
320
  // Time server
  char *ntp_server = web_config::ntpServerParam.value();
Eric Duminil's avatar
Eric Duminil committed
321
  int16_t &time_zone = web_config::timeOffsetParam.value();
Eric Duminil's avatar
Eric Duminil committed
322
323
  bool &daylight_saving_time = web_config::dstParam.value();

Eric Duminil's avatar
Eric Duminil committed
324
  // CSV
Eric Duminil's avatar
Eric Duminil committed
325
  bool is_csv_active() {
326
327
    return web_config::csvParams.isActive();
  }
328
  uint16_t &csv_interval = web_config::csvIntervalParam.value();
Eric Duminil's avatar
Eric Duminil committed
329

330
  // MQTT
Eric Duminil's avatar
Eric Duminil committed
331
  bool is_mqtt_active() {
Eric Duminil's avatar
Eric Duminil committed
332
333
    return web_config::mqttParams.isActive();
  }
Eric Duminil's avatar
Eric Duminil committed
334
335
336
337
  char *mqtt_server = web_config::mqttServerParam.value();
  char *mqtt_user = web_config::mqttUserParam.value();
  char *mqtt_password = web_config::mqttPasswordParam.value();
  uint16_t &mqtt_port = web_config::mqttPortParam.value();
338
  uint16_t &mqtt_sending_interval = web_config::mqttIntervalParam.value();
Eric Duminil's avatar
Eric Duminil committed
339
  bool &mqtt_encryption = web_config::mqttEncryptionParam.value();
Eric Duminil's avatar
Eric Duminil committed
340
  bool &allow_mqtt_commands = web_config::mqttCommandsParam.value();
Eric Duminil's avatar
Eric Duminil committed
341

342
// LORAWAN
Eric Duminil's avatar
Eric Duminil committed
343
#if defined(ESP32)
Eric Duminil's avatar
Eric Duminil committed
344
  bool is_lorawan_active() {
Eric Duminil's avatar
Eric Duminil committed
345
346
    return web_config::loraParams.isActive();
  }
347
  uint16_t &lorawan_sending_interval = web_config::loraIntervalParam.value();
Eric Duminil's avatar
Eric Duminil committed
348
349
350
  char *lorawan_device_eui = web_config::deviceEUIParam.value();
  char *lorawan_app_key = web_config::appKeyParam.value();
  char *lorawan_app_eui = web_config::appEUIParam.value();
Eric Duminil's avatar
Eric Duminil committed
351
#endif
Eric Duminil's avatar
Eric Duminil committed
352
}