diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/debian/changelog indi-duino-1.2~202004081446~ubuntu19.04.1/debian/changelog --- indi-duino-1.1~202004070720~ubuntu19.04.1/debian/changelog 2020-04-07 07:20:31.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/debian/changelog 2020-04-08 14:46:30.000000000 +0000 @@ -1,8 +1,18 @@ -indi-duino (1.1~202004070720~ubuntu19.04.1) disco; urgency=low +indi-duino (1.2~202004081446~ubuntu19.04.1) disco; urgency=low * Auto build. - -- Jasem Mutlaq Tue, 07 Apr 2020 07:20:31 +0000 + -- Jasem Mutlaq Wed, 08 Apr 2020 14:46:30 +0000 + +indi-duino (1.2) buster; urgency=medium + + * Changing WiFi credentials added + * Refreshing firmware info + * Memory information added to configuration info + * Connect / disconnect to WiFi + * Reset function added for ESP8266 + + -- Wolfgang Reissenberger Tue, 07 Apr 2020 21:59:35 +0200 indi-duino (1.1) buster; urgency=medium diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/debian/git-build-recipe.manifest indi-duino-1.2~202004081446~ubuntu19.04.1/debian/git-build-recipe.manifest --- indi-duino-1.1~202004070720~ubuntu19.04.1/debian/git-build-recipe.manifest 2020-04-07 07:20:31.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/debian/git-build-recipe.manifest 2020-04-08 14:46:30.000000000 +0000 @@ -1,5 +1,5 @@ -# git-build-recipe format 0.4 deb-version {debupstream}~202004070720 +# git-build-recipe format 0.4 deb-version {debupstream}~202004081446 lp:~mutlaqja/+git/dummy git-commit:9a182f35d7f48b02de1170889c0798f3ab639afb -nest-part src lp:~mutlaqja/libindi/+git/trunk indi-duino indi-duino git-commit:631d7e6eaf27b675f018211b7aa55d6fc3395691 -nest-part cmake lp:~mutlaqja/libindi/+git/trunk cmake_modules indi-duino/cmake_modules git-commit:631d7e6eaf27b675f018211b7aa55d6fc3395691 -nest-part pack lp:~mutlaqja/libindi/+git/trunk debian/indi-duino debian git-commit:631d7e6eaf27b675f018211b7aa55d6fc3395691 +nest-part src lp:~mutlaqja/libindi/+git/trunk indi-duino indi-duino git-commit:30df2c9f812333f499b3ee73020ba44e9d2e1f45 +nest-part cmake lp:~mutlaqja/libindi/+git/trunk cmake_modules indi-duino/cmake_modules git-commit:30df2c9f812333f499b3ee73020ba44e9d2e1f45 +nest-part pack lp:~mutlaqja/libindi/+git/trunk debian/indi-duino debian git-commit:30df2c9f812333f499b3ee73020ba44e9d2e1f45 diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/CMakeLists.txt indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/CMakeLists.txt --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/CMakeLists.txt 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/CMakeLists.txt 2020-04-08 14:46:24.000000000 +0000 @@ -10,7 +10,7 @@ set (DUINO_VERSION_MINOR 6) set (WEATHERRADIO_VERSION_MAJOR 1) -set (WEATHERRADIO_VERSION_MINOR 1) +set (WEATHERRADIO_VERSION_MINOR 2) find_package(INDI REQUIRED) diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/esp8266.h indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/esp8266.h --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/esp8266.h 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/esp8266.h 2020-04-08 14:46:24.000000000 +0000 @@ -12,22 +12,26 @@ #include #include #include +#include "memory.h" #define WIFI_TIMEOUT 20 // try 20 secs to connect until giving up -const char* ssid = WIFI_SSID; -const char* password = WIFI_PWD; - struct { bool status; unsigned long lastRetry; // Last time the frequency had been measured -} esp8266Data {false, 0}; + String ssid; + String password; +} esp8266Data {false, 0, WIFI_SSID, WIFI_PWD}; ESP8266WebServer server(80); +void reset() { + ESP.restart(); +} + void initWiFi() { WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); + WiFi.begin(esp8266Data.ssid.c_str(), esp8266Data.password.c_str()); int count = 0; // Wait for connection @@ -38,13 +42,29 @@ } } +void disconnectWiFi() { + if (WiFi.status() == WL_CONNECTED) { + WiFi.disconnect(); + esp8266Data.status = (WiFi.status() == WL_CONNECTED); + + int count = 0; + // Wait for connection + while (WiFi.status() != WL_CONNECTED && count++ < WIFI_TIMEOUT) { + esp8266Data.lastRetry = millis(); + delay(1000); + esp8266Data.status = (WiFi.status() == WL_CONNECTED); + } + } +} + + void wifiServerLoop() { // retry a connect if (esp8266Data.status == false && WiFi.status() != WL_CONNECTED) { volatile unsigned long now = millis(); if (now - esp8266Data.lastRetry > 1000) { - WiFi.begin(); + WiFi.begin(esp8266Data.ssid, esp8266Data.password); esp8266Data.lastRetry = now; if (WiFi.status() == WL_CONNECTED) esp8266Data.status = true; } @@ -53,4 +73,38 @@ // handle requests to the WiFi server server.handleClient(); } + +// Parse ssid and passphrase from input +// example input = +void parseCredentials(String input) { + int begin = 0; + int end = input.indexOf('=', begin); + int next = 0; + + String name; + String value; + + while (end > begin) { + name = input.substring(begin, end); + next = input.indexOf('&', end + 1); + + if (next == -1) { + // last parameter + value = input.substring(end + 1); + + // finish + end = -1; + } else { + value = input.substring(end + 1, next); + + // next cycle + begin = next + 1; + end = input.indexOf('=', begin); + } + + if (name == String("ssid")) esp8266Data.ssid = value; + if (name == String("password")) esp8266Data.password = value; + } +} + #endif diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/memory.h indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/memory.h --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/memory.h 1970-01-01 00:00:00.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/memory.h 2020-04-08 14:46:24.000000000 +0000 @@ -0,0 +1,18 @@ +/* Memory information for Ardiono. + + Copyright (C) 2020 Wolfgang Reissenberger + + This application is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. +*/ + +// memory information for ESP8266 +extern "C" { +#include "user_interface.h" +} + +uint32_t freeMemory() { + return system_get_free_heap_size(); +} diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/version.h indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/version.h --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/version.h 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/version.h 2020-04-08 14:46:24.000000000 +0000 @@ -1 +1 @@ -#define METEORADIO_VERSION "1.1"; +#define METEORADIO_VERSION "1.2"; diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/weatherradio.ino indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/weatherradio.ino --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/weatherradio.ino 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/devices/Firmwares/weatherradio/weatherradio.ino 2020-04-08 14:46:24.000000000 +0000 @@ -87,13 +87,23 @@ return result; } + // translate the sensor configurations to a JSON document String getCurrentConfig() { - const int docSize = JSON_OBJECT_SIZE(3) + // max 3 configurations + const int docSize = JSON_OBJECT_SIZE(4) + // max 4 configurations JSON_OBJECT_SIZE(2) + // DHT sensors JSON_OBJECT_SIZE(3) + // Davis Anemometer - JSON_OBJECT_SIZE(4); // WiFi parameters + JSON_OBJECT_SIZE(3) + // WiFi parameters + JSON_OBJECT_SIZE(1) + // Arduino + JSON_OBJECT_SIZE(2); // buffer StaticJsonDocument doc; + +#ifdef USE_WIFI + // currently, we have memory info only available for ESP8266 + JsonObject arduinodata = doc.createNestedObject("Arduino"); + arduinodata["free memory"] = freeMemory(); +#endif + #ifdef USE_DHT_SENSOR JsonObject dhtdata = doc.createNestedObject("DHT"); dhtdata["pin"] = DHTPIN; @@ -109,12 +119,12 @@ #ifdef USE_WIFI JsonObject wifidata = doc.createNestedObject("WiFi"); + wifidata["SSID"] = esp8266Data.ssid; + wifidata["connected"] = WiFi.status() == WL_CONNECTED; if (WiFi.status() == WL_CONNECTED) wifidata["IP"] = WiFi.localIP().toString(); else - wifidata["connected"] = WiFi.status() == WL_CONNECTED; - - wifidata["SSID"] = WIFI_SSID; + wifidata["IP"] = ""; #endif if (doc.isNull()) @@ -140,7 +150,6 @@ initTSL237(); #endif //USE_TSL237_SENSOR - #ifdef USE_WIFI initWiFi(); @@ -170,6 +179,7 @@ }); server.begin(); + } #endif } @@ -198,6 +208,20 @@ case 'p': Serial.println(getSensorData(true, "")); break; +#ifdef USE_WIFI + case 's': + if (input.length() > 2 && input.charAt(1) == '?') + parseCredentials(input.substring(2)); + disconnectWiFi(); + initWiFi(); + break; + case 'd': + disconnectWiFi(); + break; + case 'r': + reset(); + break; +#endif } } diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/doc/Readme-WeatherRadio.md indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/doc/Readme-WeatherRadio.md --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/doc/Readme-WeatherRadio.md 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/doc/Readme-WeatherRadio.md 2020-04-08 14:46:24.000000000 +0000 @@ -64,10 +64,12 @@ ![Serial Monitor](weatherradio/img/serial_monitor.png) The following commands are supported: -* **v** to show the firmware version -* **w** to show the current sensor values (one line version) -* **p** to show the current sensor values (pretty printing version) -* **c** to show the firmware configuration +* **v** show the firmware version +* **w** show the current sensor values (one line version) +* **p** show the current sensor values (pretty printing version) +* **c** show the firmware configuration +* **s** (re)connect WiFi. If issued as `s?ssid=&password=`, it connects with the given parameters. +* **d** disconnect from WiFi If everything is shown as expected, your hardware is ready! Binary files /tmp/tmp6w3WfP/952QXCRmEk/indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/doc/weatherradio/sensorcalibration.xlsx and /tmp/tmp6w3WfP/Uczkqq_wcO/indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/doc/weatherradio/sensorcalibration.xlsx differ diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/weathercalculator.h indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/weathercalculator.h --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/weathercalculator.h 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/weathercalculator.h 2020-04-08 14:46:24.000000000 +0000 @@ -29,10 +29,6 @@ class WeatherCalculator { public: - //Clear sky corrected temperature (temp below means 0% clouds) - #define CLOUD_TEMP_CLEAR -8 - //Totally cover sky corrected temperature (temp above means 100% clouds) - #define CLOUD_TEMP_OVERCAST 0 WeatherCalculator() = default; ~WeatherCalculator() = default; @@ -48,10 +44,10 @@ { double correctedTemperature = skyTemperatureCorr(ambientTemperature, skyTemperature); - if (correctedTemperature < CLOUD_TEMP_CLEAR) correctedTemperature = CLOUD_TEMP_CLEAR; - if (correctedTemperature > CLOUD_TEMP_OVERCAST) correctedTemperature = CLOUD_TEMP_OVERCAST; + if (correctedTemperature < skyTemperatureCoefficients.t_clear) correctedTemperature = skyTemperatureCoefficients.t_clear; + if (correctedTemperature > skyTemperatureCoefficients.t_overcast) correctedTemperature = skyTemperatureCoefficients.t_overcast; - return (correctedTemperature - CLOUD_TEMP_CLEAR) * 100 / (CLOUD_TEMP_OVERCAST - CLOUD_TEMP_CLEAR); + return (correctedTemperature - skyTemperatureCoefficients.t_clear) * 100 / (skyTemperatureCoefficients.t_overcast - skyTemperatureCoefficients.t_clear); } @@ -103,6 +99,9 @@ // Calibration coefficients for cloud coverage calculation struct { double k1 = 33.0, k2 = 0.0, k3 = 4.0, k4 = 100.0, k5 = 100.0; + //Clear sky corrected temperature (temp below means 0% clouds) + //Totally cover sky corrected temperature (temp above means 100% clouds) + double t_clear = -8, t_overcast = 0; } skyTemperatureCoefficients; diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/weatherradio.cpp indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/weatherradio.cpp --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/weatherradio.cpp 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/weatherradio.cpp 2020-04-08 14:46:24.000000000 +0000 @@ -46,6 +46,8 @@ #define MAX_WEATHERBUFFER 512 +#define WIFI_DEVICE "WiFi" + #define WEATHER_TEMPERATURE "WEATHER_TEMPERATURE" #define WEATHER_PRESSURE "WEATHER_PRESSURE" #define WEATHER_HUMIDITY "WEATHER_HUMIDITY" @@ -127,16 +129,32 @@ IUFillNumber(&ttyTimeoutN[0], "TIMEOUT", "Timeout (s)", "%.f", 0, 60, 1, getTTYTimeout()); IUFillNumberVector(&ttyTimeoutNP, ttyTimeoutN, 1, getDeviceName(), "TTY_TIMEOUT", "TTY timeout", CONNECTION_TAB, IP_RW, 0, IPS_OK); + // Firmware version IUFillText(&FirmwareInfoT[0], "FIRMWARE_INFO", "Firmware Version", ""); IUFillTextVector(&FirmwareInfoTP, FirmwareInfoT, 1, getDeviceName(), "FIRMWARE", "Firmware", INFO_TAB, IP_RO, 60, IPS_OK); + // Reset Arduino + IUFillSwitch(&resetArduinoS[0], "RESET", "Reset", ISS_OFF); + IUFillSwitchVector(&resetArduinoSP, resetArduinoS, 1, getDeviceName(), "RESET_ARDUINO", "Arduino", INFO_TAB, IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + + // refresh firmware configuration + IUFillSwitch(&refreshConfigS[0], "REFRESH", "Refresh", ISS_OFF); + IUFillSwitchVector(&refreshConfigSP, refreshConfigS, 1, getDeviceName(), "REFRESH_CONFIG", "Refresh", INFO_TAB, IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + + // connect/disconnect WiFi + IUFillSwitch(&wifiConnectionS[0], "DISCONNECT", "Disconnect", ISS_OFF); + IUFillSwitch(&wifiConnectionS[1], "CONNECT", "Connect", ISS_OFF); + IUFillSwitchVector(&wifiConnectionSP, wifiConnectionS, 2, getDeviceName(), "WIFI", "WiFi", INFO_TAB, IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + // calibration parameters - IUFillNumber(&skyTemperatureCalibrationN[0], "K1", "K1", "%.3f", 0, 100, 1, weatherCalculator->skyTemperatureCoefficients.k1); - IUFillNumber(&skyTemperatureCalibrationN[1], "K2", "K2", "%.3f", -50, 50, 1, weatherCalculator->skyTemperatureCoefficients.k2); - IUFillNumber(&skyTemperatureCalibrationN[2], "K3", "K3", "%.3f", -50, 50, 1, weatherCalculator->skyTemperatureCoefficients.k3); - IUFillNumber(&skyTemperatureCalibrationN[3], "K4", "K4", "%.3f", -100, 200, 1, weatherCalculator->skyTemperatureCoefficients.k4); - IUFillNumber(&skyTemperatureCalibrationN[4], "K5", "K5", "%.3f", -100, 200, 1, weatherCalculator->skyTemperatureCoefficients.k5); - IUFillNumberVector(&skyTemperatureCalibrationNP, skyTemperatureCalibrationN, 5, getDeviceName(), "SKY_TEMP_CALIBRATION", "Sky Temp calibr.", CALIBRATION_TAB, IP_RW, 0, IPS_OK); + IUFillNumber(&skyTemperatureCalibrationN[0], "K1", "K1", "%.2f", 0, 100, 1, weatherCalculator->skyTemperatureCoefficients.k1); + IUFillNumber(&skyTemperatureCalibrationN[1], "K2", "K2", "%.2f", -50, 50, 1, weatherCalculator->skyTemperatureCoefficients.k2); + IUFillNumber(&skyTemperatureCalibrationN[2], "K3", "K3", "%.2f", 0, 100, 1, weatherCalculator->skyTemperatureCoefficients.k3); + IUFillNumber(&skyTemperatureCalibrationN[3], "K4", "K4", "%.2f", 0, 100, 1, weatherCalculator->skyTemperatureCoefficients.k4); + IUFillNumber(&skyTemperatureCalibrationN[4], "K5", "K5", "%.2f", 0, 100, 1, weatherCalculator->skyTemperatureCoefficients.k5); + IUFillNumber(&skyTemperatureCalibrationN[5], "T_CLEAR", "clear sky (°C)", "%.2f", -20, 20, 1, weatherCalculator->skyTemperatureCoefficients.t_clear); + IUFillNumber(&skyTemperatureCalibrationN[6], "T_OVERCAST", "overcast sky (°C)", "%.2f", -20, 20, 1, weatherCalculator->skyTemperatureCoefficients.t_overcast); + IUFillNumberVector(&skyTemperatureCalibrationNP, skyTemperatureCalibrationN, 7, getDeviceName(), "SKY_TEMP_CALIBRATION", "Sky Temp calibr.", CALIBRATION_TAB, IP_RW, 0, IPS_OK); // calibration parameters IUFillNumber(&humidityCalibrationN[0], "FACTOR", "Factor", "%.3f", 0, 10, 0.1, 1.0); @@ -262,6 +280,8 @@ // Load the configuration if everything was fine if (result == true) loadConfig(); + + defineSwitch(&resetArduinoSP); } else { @@ -269,6 +289,7 @@ for (size_t i = 0; i < rawDevices.size(); i++) deleteProperty(rawDevices[i].name); + deleteProperty(resetArduinoSP.name); deleteProperty(windDirectionCalibrationNP.name); deleteProperty(sqmCalibrationNP.name); deleteProperty(temperatureCalibrationNP.name); @@ -284,6 +305,8 @@ deleteProperty(windGustSensorSP.name); deleteProperty(windSpeedSensorSP.name); deleteProperty(windDirectionSensorSP.name); + deleteProperty(refreshConfigSP.name); + deleteProperty(wifiConnectionSP.name); deleteProperty(FirmwareInfoTP.name); deleteProperty(FirmwareConfigTP.name); @@ -325,22 +348,52 @@ defineText(&FirmwareInfoTP); IDSetText(&FirmwareInfoTP, nullptr); - configuration config; + FirmwareConfig config; readFirmwareConfig(&config); - IText *configSettings = new IText[config.size()]; + FirmwareConfigT = new IText[config.size()]; std::map::iterator it; size_t pos = 0; for (it = config.begin(); it != config.end(); ++it) { - configSettings[pos].text = nullptr; // seems like a bug in IUFillText that this is necessary - IUFillText(&configSettings[pos++], it->first.c_str(), it->first.c_str(), it->second.c_str()); + FirmwareConfigT[pos].text = nullptr; // seems like a bug in IUFillText that this is necessary + IUFillText(&FirmwareConfigT[pos++], it->first.c_str(), it->first.c_str(), it->second.c_str()); } - IUFillTextVector(&FirmwareConfigTP, configSettings, static_cast(config.size()), getDeviceName(), "FIRMWARE_CONFIGS", "Firmware config", INFO_TAB, IP_RO, 60, IPS_OK); + IUFillTextVector(&FirmwareConfigTP, FirmwareConfigT, static_cast(config.size()), getDeviceName(), "FIRMWARE_CONFIGS", "Firmware config", INFO_TAB, IP_RO, 60, IPS_OK); defineText(&FirmwareConfigTP); + // refresh button + defineSwitch(&refreshConfigSP); + + if (hasWiFi) + defineSwitch(&wifiConnectionSP); +} + +/************************************************************************************** +** Update firmware configuration data +***************************************************************************************/ +void WeatherRadio::updateConfigData() +{ + FirmwareInfoTP.s = getFirmwareVersion(FirmwareInfoT[0].text); + if (FirmwareInfoTP.s != IPS_OK) + LOG_ERROR("Failed to get firmware from device."); + + FirmwareConfig config; + readFirmwareConfig(&config); + std::map::iterator it; + + for (it = config.begin(); it != config.end(); ++it) + { + // find the matching text property + for (int i = 0; i < FirmwareConfigTP.ntp; i++) + if (strcmp(FirmwareConfigT[i].name, it->first.c_str()) == 0) + IUSaveText(&FirmwareConfigT[i], it->second.c_str()); + } + FirmwareConfigTP.s = IPS_OK; + IDSetText(&FirmwareInfoTP, nullptr); + IDSetText(&FirmwareConfigTP, nullptr); } /************************************************************************************** @@ -382,7 +435,7 @@ /************************************************************************************** ** Read the configuration parameters from the firmware ***************************************************************************************/ -IPState WeatherRadio::readFirmwareConfig(configuration *config) +IPState WeatherRadio::readFirmwareConfig(FirmwareConfig *config) { char data[MAX_WEATHERBUFFER] = {0}; int n_bytes = 0; @@ -390,6 +443,7 @@ if (result) { + // LOGF_DEBUG("Firmware configuration response: %s", data); char *source = data; char *endptr; JsonValue value; @@ -407,6 +461,9 @@ char *device {new char[strlen(deviceIter->key)+1] {0}}; strncpy(device, deviceIter->key, static_cast(strlen(deviceIter->key))); + if (strcmp(device, WIFI_DEVICE) == 0) + hasWiFi = true; + JsonIterator configIter; // read settings for the single device @@ -434,15 +491,25 @@ value = "false"; break; default: - value = configIter->value.toString(); + value = strdup(configIter->value.toString()); break; } // add it to the configuration - (*config)[std::string(device) + ": " + std::string(name)] = std::string(value); + (*config)[std::string(device) + "::" + std::string(name)] = value; } } + // update WiFi status + if (hasWiFi) + { + FirmwareConfig::iterator configIt = config->find(std::string(WIFI_DEVICE) + "::" + "connected"); + bool connected = (configIt != config->end() && strcmp(configIt->second.c_str(), "true") == 0); + + updateWiFiStatus(connected); + } + return IPS_OK; + } else { @@ -451,6 +518,38 @@ } } +/************************************************************************************** +** Connect / disconnect the Arduino to WiFi. +***************************************************************************************/ +bool WeatherRadio::connectWiFi(bool connect) +{ + bool result; + if (connect) + result = transmit("s\n"); + else + result = transmit("d\n"); + return result; +} + +void WeatherRadio::updateWiFiStatus(bool connected) +{ + wifiConnectionS[0].s = connected ? ISS_OFF : ISS_ON; + wifiConnectionS[1].s = connected ? ISS_ON : ISS_OFF; + wifiConnectionSP.s = IPS_OK; + + IDSetSwitch(&wifiConnectionSP, nullptr); + LOGF_INFO("WiFi %s.", connected ? "connected" : "disconnected"); +} + +/************************************************************************************** +** Reset the Arduino. +***************************************************************************************/ +bool WeatherRadio::resetArduino() +{ + bool result = transmit("r\n"); + return result; +} + /************************************************************************************** ** Create a selection of sensors for a certain weather property. @@ -504,13 +603,16 @@ else if (strcmp(name, skyTemperatureCalibrationNP.name) == 0) { IUUpdateNumber(&skyTemperatureCalibrationNP, values, names, n); - weatherCalculator->skyTemperatureCoefficients.k1 = values[0]; - weatherCalculator->skyTemperatureCoefficients.k2 = values[1]; - weatherCalculator->skyTemperatureCoefficients.k3 = values[2]; - weatherCalculator->skyTemperatureCoefficients.k4 = values[3]; - weatherCalculator->skyTemperatureCoefficients.k5 = values[4]; + if (n > 0) weatherCalculator->skyTemperatureCoefficients.k1 = values[0]; + if (n > 1) weatherCalculator->skyTemperatureCoefficients.k2 = values[1]; + if (n > 2) weatherCalculator->skyTemperatureCoefficients.k3 = values[2]; + if (n > 3) weatherCalculator->skyTemperatureCoefficients.k4 = values[3]; + if (n > 4) weatherCalculator->skyTemperatureCoefficients.k5 = values[4]; + if (n > 5) weatherCalculator->skyTemperatureCoefficients.t_clear = values[5]; + if (n > 6) weatherCalculator->skyTemperatureCoefficients.t_overcast = values[6]; skyTemperatureCalibrationNP.s = IPS_OK; IDSetNumber(&skyTemperatureCalibrationNP, nullptr); + LOG_DEBUG("Cloud coverage value calibration updated."); return skyTemperatureCalibrationNP.s; } else if (strcmp(name, humidityCalibrationNP.name) == 0) @@ -520,6 +622,7 @@ weatherCalculator->humidityCalibration.shift = values[1]; humidityCalibrationNP.s = IPS_OK; IDSetNumber(&humidityCalibrationNP, nullptr); + LOG_DEBUG("Humidity value calibration updated."); return humidityCalibrationNP.s; } else if (strcmp(name, temperatureCalibrationNP.name) == 0) @@ -529,6 +632,7 @@ weatherCalculator->temperatureCalibration.shift = values[1]; temperatureCalibrationNP.s = IPS_OK; IDSetNumber(&temperatureCalibrationNP, nullptr); + LOG_DEBUG("Temperature value calibration updated."); return temperatureCalibrationNP.s; } else if (strcmp(name, sqmCalibrationNP.name) == 0) @@ -539,6 +643,7 @@ sqmCalibrationNP.s = IPS_OK; IDSetNumber(&sqmCalibrationNP, nullptr); return sqmCalibrationNP.s; + LOG_DEBUG("SQM value calibration updated."); } else if (strcmp(name, windDirectionCalibrationNP.name) == 0) { @@ -547,6 +652,7 @@ windDirectionCalibrationNP.s = IPS_OK; IDSetNumber(&windDirectionCalibrationNP, nullptr); return windDirectionCalibrationNP.s; + LOG_DEBUG("Wind direction value calibration updated."); } } return INDI::Weather::ISNewNumber(dev, name, values, names, n); @@ -560,7 +666,47 @@ if (dev != nullptr && strcmp(dev, getDeviceName()) == 0) { - if (strcmp(name, temperatureSensorSP.name) == 0) + if (strcmp(name, refreshConfigSP.name) == 0) + { + // refresh config button pressed + IUUpdateSwitch(&refreshConfigSP, states, names, n); + updateConfigData(); + + refreshConfigSP.s = IPS_OK; + refreshConfigS[0].s = ISS_OFF; + IDSetSwitch(&refreshConfigSP, nullptr); + + LOG_INFO("Firmware configuration data updated."); + return (refreshConfigSP.s == IPS_OK); + } + else if (strcmp(name, wifiConnectionSP.name) == 0) + { + // reconnect config button pressed + IUUpdateSwitch(&wifiConnectionSP, states, names, n); + int pressed = IUFindOnSwitchIndex(&wifiConnectionSP); + + wifiConnectionSP.s = connectWiFi(pressed == 1) ? IPS_OK : IPS_ALERT; + IDSetSwitch(&wifiConnectionSP, nullptr); + + LOGF_INFO("%s WiFi. Press \"Refresh\" to update the status.", pressed == 1? "Connecting" :"Disconnecting"); + return (wifiConnectionSP.s == IPS_OK); + } + else if (strcmp(name, resetArduinoSP.name) == 0) + { + // reset Arduino button pressed + IUUpdateSwitch(&resetArduinoSP, states, names, n); + + if (resetArduino()) + resetArduinoSP.s = IPS_OK; + else + resetArduinoSP.s = IPS_ALERT; + resetArduinoS->s = ISS_OFF; + IDSetSwitch(&resetArduinoSP, nullptr); + + LOG_INFO("Resetting Arduino. Press \"Refresh\" to update the status"); + return (resetArduinoSP.s == IPS_OK); + } + else if (strcmp(name, temperatureSensorSP.name) == 0) { // temperature sensor selected IUUpdateSwitch(&temperatureSensorSP, states, names, n); @@ -569,6 +715,7 @@ sensor_name sensor = updateSensorSelection(&temperatureSensorSP, selected); currentSensors.temperature = sensor; + LOGF_DEBUG("Temperature sensor selected: %s", selected); return (temperatureSensorSP.s == IPS_OK); } else if (strcmp(name, pressureSensorSP.name) == 0) @@ -580,6 +727,7 @@ sensor_name sensor = updateSensorSelection(&pressureSensorSP, selected); currentSensors.pressure = sensor; + LOGF_DEBUG("Pressure sensor selected: %s", selected); return (pressureSensorSP.s == IPS_OK); } else if (strcmp(name, humiditySensorSP.name) == 0) @@ -591,6 +739,7 @@ sensor_name sensor = updateSensorSelection(&humiditySensorSP, selected); currentSensors.humidity = sensor; + LOGF_DEBUG("Humidity sensor selected: %s", selected); return (humiditySensorSP.s == IPS_OK); } else if (strcmp(name, luminositySensorSP.name) == 0) @@ -602,6 +751,7 @@ sensor_name sensor = updateSensorSelection(&luminositySensorSP, selected); currentSensors.luminosity = sensor; + LOGF_DEBUG("Luminosity sensor selected: %s", selected); return (luminositySensorSP.s == IPS_OK); } else if (strcmp(name, sqmSensorSP.name) == 0) @@ -613,6 +763,7 @@ sensor_name sensor = updateSensorSelection(&sqmSensorSP, selected); currentSensors.sqm = sensor; + LOGF_DEBUG("SQM sensor selected: %s", selected); return (sqmSensorSP.s == IPS_OK); } else if (strcmp(name, ambientTemperatureSensorSP.name) == 0) @@ -624,6 +775,7 @@ sensor_name sensor = updateSensorSelection(&ambientTemperatureSensorSP, selected); currentSensors.temp_ambient = sensor; + LOGF_DEBUG("Ambient temperature sensor selected: %s", selected); return (ambientTemperatureSensorSP.s == IPS_OK); } else if (strcmp(name, objectTemperatureSensorSP.name) == 0) @@ -635,6 +787,7 @@ sensor_name sensor = updateSensorSelection(&objectTemperatureSensorSP, selected); currentSensors.temp_object = sensor; + LOGF_DEBUG("Object temperature sensor selected: %s", selected); return (objectTemperatureSensorSP.s == IPS_OK); } else if (strcmp(name, windGustSensorSP.name) == 0) @@ -646,6 +799,7 @@ sensor_name sensor = updateSensorSelection(&windGustSensorSP, selected); currentSensors.wind_gust = sensor; + LOGF_DEBUG("Wind gust sensor selected: %s", selected); return (windGustSensorSP.s == IPS_OK); } else if (strcmp(name, windSpeedSensorSP.name) == 0) @@ -657,6 +811,7 @@ sensor_name sensor = updateSensorSelection(&windSpeedSensorSP, selected); currentSensors.wind_speed = sensor; + LOGF_DEBUG("Wind speed sensor selected: %s", selected); return (windSpeedSensorSP.s == IPS_OK); } else if (strcmp(name, windDirectionSensorSP.name) == 0) @@ -668,6 +823,7 @@ sensor_name sensor = updateSensorSelection(&windDirectionSensorSP, selected); currentSensors.wind_direction = sensor; + LOGF_DEBUG("Wind direction sensor selected: %s", selected); return (windDirectionSensorSP.s == IPS_OK); } } @@ -705,6 +861,7 @@ char cmd[20] = {0}; sprintf(cmd, "w#%d\n", id); bool result = sendQuery(cmd, data, &n_bytes); + // LOGF_DEBUG("Weather data received: %s", data); if (result == false) return IPS_ALERT; diff -Nru indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/weatherradio.h indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/weatherradio.h --- indi-duino-1.1~202004070720~ubuntu19.04.1/indi-duino/weatherradio.h 2020-04-07 07:19:45.000000000 +0000 +++ indi-duino-1.2~202004081446~ubuntu19.04.1/indi-duino/weatherradio.h 2020-04-08 14:46:24.000000000 +0000 @@ -57,6 +57,9 @@ // Initial function to get data after connection is successful void getBasicData(); + // Read the firmware configuration + void updateConfigData(); + ISwitchVectorProperty temperatureSensorSP, ambientTemperatureSensorSP, objectTemperatureSensorSP, pressureSensorSP, humiditySensorSP, luminositySensorSP, sqmSensorSP, windSpeedSensorSP, windGustSensorSP, windDirectionSensorSP; @@ -68,6 +71,7 @@ ITextVectorProperty FirmwareInfoTP; IText FirmwareInfoT[1] = {}; // firmware configuration (dynamically created) + IText *FirmwareConfigT; ITextVectorProperty FirmwareConfigTP; /** @@ -93,7 +97,7 @@ double steps; }; - typedef std::map configuration; + typedef std::map FirmwareConfig; typedef std::map sensorsConfigType; typedef std::map deviceConfigType; @@ -137,9 +141,19 @@ INumber ttyTimeoutN[1] = {}; INumberVectorProperty ttyTimeoutNP; + ISwitch refreshConfigS[1] = {}; + ISwitchVectorProperty refreshConfigSP; + + ISwitch wifiConnectionS[2] = {}; + ISwitchVectorProperty wifiConnectionSP; + bool hasWiFi = false; + + ISwitch resetArduinoS[1] = {}; + ISwitchVectorProperty resetArduinoSP; + // calibration parameters to calculate the corrected sky temperature INumberVectorProperty skyTemperatureCalibrationNP; - INumber skyTemperatureCalibrationN[5]; + INumber skyTemperatureCalibrationN[7]; // calibration parameters for the humidity INumberVectorProperty humidityCalibrationNP; @@ -225,8 +239,25 @@ * @brief Read the firmware configuration * @param config configuration to be updated */ - IPState readFirmwareConfig(configuration *config); + IPState readFirmwareConfig(FirmwareConfig *config); + + /** + * @brief Connect to WiFi + * @param connect true iff connect, false iff disconnect + */ + bool connectWiFi(bool connect); + + /** + * @brief updateWiFiStatus + * @param connected true iff WiFi is connected + */ + void updateWiFiStatus(bool connected); + /** + * @brief Send the Arduino a reset command + * @return true iff successful + */ + bool resetArduino(); // helper functions bool receive(char* buffer, int* bytes, char end, int wait);