diff --git a/ActionAccessPointCli.cpp b/ActionAccessPointCli.cpp index 7df67f3..acbfd88 100644 --- a/ActionAccessPointCli.cpp +++ b/ActionAccessPointCli.cpp @@ -42,6 +42,12 @@ static void az_scopeid_command(int argc, char **argv); static void az_deviceid_command(int argc, char **argv); static void az_saskey_command(int argc, char **argv); static void az_iothub_command(int argc, char **argv); +static void mqtt_server_command(int argc, char **argv); +static void mqtt_port_command(int argc, char **argv); +static void mqtt_topic_command(int argc, char **argv); +static void mqtt_client_command(int argc, char **argv); +static void mqtt_user_command(int argc, char **argv); +static void mqtt_password_command(int argc, char **argv); static void apmode_ssid_command(int argc, char **argv); static void apmode_pwd_Command(int argc, char **argv); @@ -59,6 +65,12 @@ static const struct console_command cmds[] = {"set_az_deviceid" , "Set device id of Azure IoT Central" , false, az_deviceid_command }, {"set_az_saskey" , "Set SAS key of Azure IoT Central" , true , az_saskey_command }, {"set_az_iothub" , "Set the connection string of Azure IoT Hub" , true , az_iothub_command }, + {"set_mqtt_server" , "Set the MQTT server address" , false, mqtt_server_command }, + {"set_mqtt_port" , "Set the MQTT port" , false, mqtt_port_command }, + {"set_mqtt_topic" , "Set the MQTT topic" , false, mqtt_topic_command }, + {"set_mqtt_client" , "Set the MQTT client" , false, mqtt_client_command }, + {"set_mqtt_user" , "Set the MQTT user" , false, mqtt_user_command }, + {"set_mqtt_password" , "Set the MQTT port" , true , mqtt_password_command }, {"set_apmodessid" , "Set AP mode SSID" , false, apmode_ssid_command }, {"set_apmodepwd" , "Set AP mode password" , true , apmode_pwd_Command }, }; @@ -263,6 +275,126 @@ static void az_iothub_command(int argc, char **argv) Serial.printf("INFO: Set Azure Iot hub connection string successfully.\r\n"); } +static void mqtt_server_command(int argc, char **argv) +{ + if (argc == 1 || argv[1] == NULL) + { + Serial.printf("Usage: set_mqtt_server . Please provide the server address of the MQTT server.\r\n"); + return; + } + int len = strlen(argv[1]); + if (len == 0 || len > CONFIG_MQTT_SERVER_MAX_LEN) + { + Serial.printf("Invalid MQTT server address.\r\n"); + return; + } + + strncpy(Config.MQTTServer, argv[1], CONFIG_MQTT_SERVER_MAX_LEN + 1); + + ConfigWrite(); + Serial.printf("INFO: Set MQTT Server address successfully.\r\n"); +} + +static void mqtt_port_command(int argc, char **argv) +{ + if (argc == 1 || argv[1] == NULL) + { + Serial.printf("Usage: set_mqtt_port . Please provide the MQTT port.\r\n"); + return; + } + int len = strlen(argv[1]); + if (len == 0 || len > CONFIG_MQTT_PORT_MAX_LEN) + { + Serial.printf("Invalid MQTT port.\r\n"); + return; + } + + strncpy(Config.MQTTPort, argv[1], CONFIG_MQTT_PORT_MAX_LEN + 1); + + ConfigWrite(); + Serial.printf("INFO: Set MQTT port successfully.\r\n"); +} + +static void mqtt_topic_command(int argc, char **argv) +{ + if (argc == 1 || argv[1] == NULL) + { + Serial.printf("Usage: set_mqtt_topic . Please provide the MQTT topic.\r\n"); + return; + } + int len = strlen(argv[1]); + if (len == 0 || len > CONFIG_MQTT_TOPIC_MAX_LEN) + { + Serial.printf("Invalid MQTT topic.\r\n"); + return; + } + + strncpy(Config.MQTTPort, argv[1], CONFIG_MQTT_TOPIC_MAX_LEN + 1); + + ConfigWrite(); + Serial.printf("INFO: Set MQTT topic successfully.\r\n"); +} + +static void mqtt_client_command(int argc, char **argv) +{ + if (argc == 1 || argv[1] == NULL) + { + Serial.printf("Usage: set_mqtt_client . Please provide the MQTT client id.\r\n"); + return; + } + int len = strlen(argv[1]); + if (len == 0 || len > CONFIG_MQTT_CLIENT_MAX_LEN) + { + Serial.printf("Invalid MQTT client id.\r\n"); + return; + } + + strncpy(Config.MQTTPort, argv[1], CONFIG_MQTT_CLIENT_MAX_LEN + 1); + + ConfigWrite(); + Serial.printf("INFO: Set MQTT client id successfully.\r\n"); +} + +static void mqtt_user_command(int argc, char **argv) +{ + if (argc == 1 || argv[1] == NULL) + { + Serial.printf("Usage: set_mqtt_user . Please provide the MQTT username.\r\n"); + return; + } + int len = strlen(argv[1]); + if (len == 0 || len > CONFIG_MQTT_USER_MAX_LEN) + { + Serial.printf("Invalid MQTT username.\r\n"); + return; + } + + strncpy(Config.MQTTPort, argv[1], CONFIG_MQTT_USER_MAX_LEN + 1); + + ConfigWrite(); + Serial.printf("INFO: Set MQTT username successfully.\r\n"); +} + +static void mqtt_password_command(int argc, char **argv) +{ + if (argc == 1 || argv[1] == NULL) + { + Serial.printf("Usage: set_mqtt_password . Please provide the MQTT password.\r\n"); + return; + } + int len = strlen(argv[1]); + if (len == 0 || len > CONFIG_MQTT_PASSWORD_MAX_LEN) + { + Serial.printf("Invalid MQTT password.\r\n"); + return; + } + + strncpy(Config.MQTTPort, argv[1], CONFIG_MQTT_PASSWORD_MAX_LEN + 1); + + ConfigWrite(); + Serial.printf("INFO: Set MQTT password successfully.\r\n"); +} + static void apmode_ssid_command(int argc, char **argv) { if (argc == 1 || argv[1] == NULL) diff --git a/ActionSendMessage.cpp b/ActionSendMessage.cpp index a7be781..eab1c55 100644 --- a/ActionSendMessage.cpp +++ b/ActionSendMessage.cpp @@ -8,6 +8,8 @@ #include #include "ReButtonClient.h" #include +#include "MQTTClient.h" +#include "MQTTNetwork.h" static String stringformat(const char* format, ...) { @@ -151,75 +153,124 @@ bool ActionSendMessage(ACTION_TYPE action) IPAddress ip = WiFi.localIP(); Serial.printf("ActionSendMessage() : IP address is %s.\n", ip.get_address()); - //////////////////// - // Initialize IoTHub client - - ReButtonClient client; - if (!client.Connect(&DeviceTwinUpdateCallbackFunc)) - { - Serial.println("ActionSendMessage() : IoT Hub Connection failed"); - return false; - } - //////////////////// - // Make sure we are connected - - Serial.println("ActionSendMessage() : Wait for connected."); - while (!client.IsConnected()) - { - client.DoWork(); - wait_ms(100); + // Check if IoTHub parameters are set + if (strlen(Config.IoTHubConnectionString) > 0 || (strlen(Config.ScopeId) >= 1 && strlen(Config.DeviceId) >= 1 && strlen(Config.SasKey) >= 1)){ + + //////////////////// + // Initialize IoTHub client + + ReButtonClient client; + if (!client.Connect(&DeviceTwinUpdateCallbackFunc)) + { + Serial.println("ActionSendMessage() : IoT Hub Connection failed"); + return false; + } + + //////////////////// + // Make sure we are connected + + Serial.println("ActionSendMessage() : Wait for connected."); + while (!client.IsConnected()) + { + client.DoWork(); + wait_ms(100); + } + + //////////////////// + // Make sure we are received Twin Update + + Serial.println("ActionSendMessage() : Wait for DeviceTwin received."); + while (!DeviceTwinReceived) + { + client.DoWork(); + wait_ms(100); + } + + //////////////////// + // Send message + + String payload = MakeMessageJsonString(action); + if (!client.SendMessageAsync(payload.c_str())) + { + Serial.println("ActionSendMessage() : SendEventAsync failed"); + return false; + } + + while (!client.IsMessageSent()) + { + client.DoWork(); + wait_ms(100); + } + + while (!client.IsAllEventsSent()) + { + client.DoWork(); + wait_ms(100); + } + + //////////////////// + // Report status + + client.DeviceTwinReport(MakeReportJsonString().c_str()); + + while (!client.IsDeviceTwinReported()) + { + client.DoWork(); + wait_ms(100); + } + + //////////////////// + // Disconnect IoTHub + + client.Disconnect(); } //////////////////// - // Make sure we are received Twin Update - - Serial.println("ActionSendMessage() : Wait for DeviceTwin received."); - while (!DeviceTwinReceived) - { - client.DoWork(); - wait_ms(100); + // Check if MQTT Parameters are set + if (strlen(Config.MQTTServer) >= 1 && strlen(Config.MQTTPort) >= 1 && strlen(Config.MQTTTopic) >= 1 && strlen(Config.MQTTClient) >= 1){ + + //////////////////// + // Publish MQTT Topic + MQTTNetwork mqttNetwork; + MQTT::Client mqttClient = MQTT::Client(mqttNetwork); + + Serial.printf("Connecting to MQTT server %s:%s", Config.MQTTServer, Config.MQTTPort); + + int rc = mqttNetwork.connect(Config.MQTTServer, atoi(Config.MQTTPort)); + if (rc != 0) { + Serial.println("Connected to MQTT server failed"); + } else { + Serial.println("Connected to MQTT server successfully"); + } + + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.MQTTVersion = 3; + data.clientID.cstring = Config.MQTTClient; + data.username.cstring = Config.MQTTUser; + data.password.cstring = Config.MQTTPassword; + if ((rc = mqttClient.connect(data)) != 0) { + Serial.println("MQTT client connect to server failed"); + } + + MQTT::Message message; + + // QoS 0 + char buf[256]; + String payload = MakeMessageJsonString(action); + sprintf(buf, payload.c_str()); + message.qos = MQTT::QOS0; + message.retained = false; + message.dup = false; + message.payload = (void*)buf; + message.payloadlen = strlen(buf); + rc = mqttClient.publish(Config.MQTTTopic, message); + + if ((rc = mqttClient.disconnect()) != 0) { + Serial.println("MQTT client disconnect from server failed"); + } } - - //////////////////// - // Send message - - String payload = MakeMessageJsonString(action); - if (!client.SendMessageAsync(payload.c_str())) - { - Serial.println("ActionSendMessage() : SendEventAsync failed"); - return false; - } - - while (!client.IsMessageSent()) - { - client.DoWork(); - wait_ms(100); - } - - while (!client.IsAllEventsSent()) - { - client.DoWork(); - wait_ms(100); - } - - //////////////////// - // Report status - - client.DeviceTwinReport(MakeReportJsonString().c_str()); - - while (!client.IsDeviceTwinReported()) - { - client.DoWork(); - wait_ms(100); - } - - //////////////////// - // Disconnect IoTHub - - client.Disconnect(); - - + Serial.println("Complete"); return true; diff --git a/Config.cpp b/Config.cpp index 6d79c65..5fc252f 100644 --- a/Config.cpp +++ b/Config.cpp @@ -67,6 +67,13 @@ void ConfigResetFactorySettings() strncpy_w_zero(Config.IoTHubConnectionString, "", sizeof(Config.IoTHubConnectionString)); + strncpy_w_zero(Config.MQTTServer, "", sizeof(Config.MQTTServer)); + strncpy_w_zero(Config.MQTTPort, "", sizeof(Config.MQTTPort)); + strncpy_w_zero(Config.MQTTTopic, "", sizeof(Config.MQTTTopic)); + strncpy_w_zero(Config.MQTTClient, "", sizeof(Config.MQTTClient)); + strncpy_w_zero(Config.MQTTUser, "", sizeof(Config.MQTTUser)); + strncpy_w_zero(Config.MQTTPassword, "", sizeof(Config.MQTTPassword)); + strncpy_w_zero(Config.APmodeSSID, ssid, sizeof(Config.APmodeSSID)); strncpy_w_zero(Config.APmodePassword, "", sizeof(Config.APmodePassword)); } @@ -106,7 +113,7 @@ void ConfigPrint() Serial.printf("WiFiSSID = %s\n", Config.WiFiSSID); //Serial.printf("WiFiPassword = %s\n", Config.WiFiPassword); Serial.printf("TimeServer = %s\n", Config.TimeServer); - Serial.printf("IoTHubConnectionString = %s\n", Config.IoTHubConnectionString); + //Serial.printf("IoTHubConnectionString = %s\n", Config.IoTHubConnectionString); Serial.printf("APmodeSSID = %s\n", Config.APmodeSSID); //Serial.printf("APmodePassword = %s\n", Config.APmodePassword); } diff --git a/Config.h b/Config.h index bcd0d43..13bf3e6 100644 --- a/Config.h +++ b/Config.h @@ -17,6 +17,12 @@ extern const char* CONFIG_FIRMWARE_VERSION; #define CONFIG_DEVICE_ID_MAX_LEN (128) #define CONFIG_SAS_KEY_MAX_LEN (128) #define CONFIG_IOTHUB_CONNECTION_STRING_MAX_LEN (512) +#define CONFIG_MQTT_SERVER_MAX_LEN (128) +#define CONFIG_MQTT_PORT_MAX_LEN (10) +#define CONFIG_MQTT_TOPIC_MAX_LEN (64) +#define CONFIG_MQTT_CLIENT_MAX_LEN (32) +#define CONFIG_MQTT_USER_MAX_LEN (32) +#define CONFIG_MQTT_PASSWORD_MAX_LEN (64) #define CONFIG_APMODE_SSID_MAX_LEN (32) #define CONFIG_APMODE_PASSWORD_MAX_LEN (64) @@ -49,6 +55,13 @@ struct CONFIG_TYPE char IoTHubConnectionString[CONFIG_IOTHUB_CONNECTION_STRING_MAX_LEN + 1]; + char MQTTServer[CONFIG_MQTT_SERVER_MAX_LEN + 1]; + char MQTTPort[CONFIG_MQTT_PORT_MAX_LEN + 1]; + char MQTTTopic[CONFIG_MQTT_TOPIC_MAX_LEN + 1]; + char MQTTClient[CONFIG_MQTT_CLIENT_MAX_LEN + 1]; + char MQTTUser[CONFIG_MQTT_USER_MAX_LEN + 1]; + char MQTTPassword[CONFIG_MQTT_PASSWORD_MAX_LEN + 1]; + char APmodeSSID[CONFIG_APMODE_SSID_MAX_LEN + 1]; char APmodePassword[CONFIG_APMODE_PASSWORD_MAX_LEN + 1]; diff --git a/HttpServer.cpp b/HttpServer.cpp index 03d1e9c..c272edf 100644 --- a/HttpServer.cpp +++ b/HttpServer.cpp @@ -95,6 +95,7 @@ static const char* HTML_INDEX = \ "

Wi-Fi

" \ "

Azure IoT Central

" \ "

Azure IoT Hub

" \ + "

MQTT Server

" \ "

Device to Cloud (D2C) Message

" \ "

Firmware Update

" \ "" \ @@ -262,6 +263,73 @@ static const char* HTML_IOTHUB2_SUCCESS = \ "" \ ""; +static const char* HTML_MQTT = \ + "%s " \ + "
" \ + "

ReButton - MQTT Server

" \ + "
" \ + "
" \ + "
" \ + "
" \ + "
" \ + "

Connect ReButton to MQTT Server

" \ + "

Enable publishing message to a MQTT server.

" \ + "

This can be used with or without an Azure IoT Hub or IoT Central connection.

" \ + "
" \ + "
" \ + "" \ + " " \ + "
" \ + "
" \ + "" \ + " " \ + "
" \ + "
" \ + "" \ + " " \ + "
" \ + "
" \ + "" \ + " " \ + "
" \ + "
" \ + "" \ + " " \ + "
" \ + "
" \ + "" \ + " " \ + "
" \ + "
" \ + " " \ + "" \ + "" \ + "
" \ + "
" \ + "
" \ + "
" \ + "" \ + ""; + +static const char* HTML_MQTT2_SUCCESS = \ + "%s " \ + "
" \ + "

ReButton - MQTT Server

" \ + "
" \ + "
" \ + "
" \ + "
" \ + "

MQTT Server saved.

" \ + "
" \ + "
" \ + "" \ + "" \ + "
" \ + "
" \ + "
" \ + "" \ + ""; + static const char* HTML_MESSAGE = \ "%s " \ "
" \ @@ -611,6 +679,59 @@ static int HtmlIoTHub2PostHandler(httpd_request_t *req) return kNoErr; } +static int HtmlMQTTGetHandler(httpd_request_t* req) +{ + AutoShutdownUpdateStartTime(); + + OSStatus err; + + String html = stringformat(strlen(HTML_MQTT) + strlen(HTML_HEADER) + strlen(Config.MQTTServer) + strlen(Config.MQTTPort) + strlen(Config.MQTTTopic) + strlen(Config.MQTTClient) + strlen(Config.MQTTUser) + strlen(Config.MQTTPassword), HTML_MQTT, HTML_HEADER, Config.MQTTServer, Config.MQTTPort, Config.MQTTTopic, Config.MQTTClient, Config.MQTTUser, Config.MQTTPassword); + if ((err = HttpdSend(req, html.c_str())) != kNoErr) return err; + + return kNoErr; +} + +static int HtmlMQTT2PostHandler(httpd_request_t *req) +{ + AutoShutdownUpdateStartTime(); + + OSStatus err; + + std::vector buf(1000); + + if ((err = httpd_get_data(req, &buf[0], buf.size())) != kNoErr) return err; + if (strstr(req->content_type, "multipart/form-data") == NULL) return kGeneralErr; + char* boundary = strstr(req->content_type, "boundary="); + boundary += 9; + + char mqttServer[CONFIG_MQTT_SERVER_MAX_LEN + 1]; + char mqttPort[CONFIG_MQTT_PORT_MAX_LEN + 1]; + char mqttTopic[CONFIG_MQTT_TOPIC_MAX_LEN + 1]; + char mqttClient[CONFIG_MQTT_CLIENT_MAX_LEN + 1]; + char mqttUser[CONFIG_MQTT_USER_MAX_LEN + 1]; + char mqttPassword[CONFIG_MQTT_PASSWORD_MAX_LEN + 1]; + + if ((err = httpd_get_tag_from_multipart_form(&buf[0], boundary, "MQTTServer", mqttServer, CONFIG_MQTT_SERVER_MAX_LEN)) != kNoErr) return err; + if ((err = httpd_get_tag_from_multipart_form(&buf[0], boundary, "MQTTPort", mqttPort, CONFIG_MQTT_PORT_MAX_LEN)) != kNoErr) return err; + if ((err = httpd_get_tag_from_multipart_form(&buf[0], boundary, "MQTTTopic", mqttTopic, CONFIG_MQTT_TOPIC_MAX_LEN)) != kNoErr) return err; + if ((err = httpd_get_tag_from_multipart_form(&buf[0], boundary, "MQTTClient", mqttClient, CONFIG_MQTT_CLIENT_MAX_LEN)) != kNoErr) return err; + if ((err = httpd_get_tag_from_multipart_form(&buf[0], boundary, "MQTTUser", mqttUser, CONFIG_MQTT_USER_MAX_LEN)) != kNoErr) return err; + if ((err = httpd_get_tag_from_multipart_form(&buf[0], boundary, "MQTTPassword", mqttPassword, CONFIG_MQTT_PASSWORD_MAX_LEN)) != kNoErr) return err; + + strncpy(Config.MQTTServer, mqttServer, sizeof(Config.MQTTServer)); + strncpy(Config.MQTTPort, mqttPort, sizeof(Config.MQTTPort)); + strncpy(Config.MQTTTopic, mqttTopic, sizeof(Config.MQTTTopic)); + strncpy(Config.MQTTClient, mqttClient, sizeof(Config.MQTTClient)); + strncpy(Config.MQTTUser, mqttUser, sizeof(Config.MQTTUser)); + strncpy(Config.MQTTPassword, mqttPassword, sizeof(Config.MQTTPassword)); + ConfigWrite(); + + String html = stringformat(strlen(HTML_MQTT2_SUCCESS) + strlen(HTML_HEADER), HTML_MQTT2_SUCCESS, HTML_HEADER); + if ((err = HttpdSend(req, html.c_str())) != kNoErr) return err; + + return kNoErr; +} + static int HtmlMessageGetHandler(httpd_request_t* req) { AutoShutdownUpdateStartTime(); @@ -1211,6 +1332,8 @@ static struct httpd_wsgi_call g_app_handlers[] = { "/iotcentral2" , HTTPD_HDR_DEFORT, 0, NULL , HtmlIoTCentral2PostHandler , NULL, NULL }, { "/iothub" , HTTPD_HDR_DEFORT, 0, HtmlIoTHubGetHandler , NULL , NULL, NULL }, { "/iothub2" , HTTPD_HDR_DEFORT, 0, NULL , HtmlIoTHub2PostHandler , NULL, NULL }, + { "/mqtt" , HTTPD_HDR_DEFORT, 0, HtmlMQTTGetHandler , NULL , NULL, NULL }, + { "/mqtt2" , HTTPD_HDR_DEFORT, 0, NULL , HtmlMQTT2PostHandler , NULL, NULL }, { "/message" , HTTPD_HDR_DEFORT, 0, HtmlMessageGetHandler , NULL , NULL, NULL }, { "/message2" , HTTPD_HDR_DEFORT, 0, NULL , HtmlMessage2PostHandler , NULL, NULL }, { "/firmware" , HTTPD_HDR_DEFORT, 0, HtmlFirmwareUpdateGetHandler, NULL , NULL, NULL }, diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c8d9c2d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Seeed K.K. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ReButtonApp.ino b/ReButtonApp.ino index 3cdd171..494d9af 100644 --- a/ReButtonApp.ino +++ b/ReButtonApp.ino @@ -1,139 +1,139 @@ -#include -#include "Config.h" - -#include -#include "AutoShutdown.h" -#include "Display.h" -#include "Input.h" -#include "Action.h" - -#define LOOP_WAIT_TIME (10) // [msec.] -#define POWER_OFF_TIME (1000) // [msec.] - -void setup() -{ - //////////////////// - // Setup auto shutdown - - AutoShutdownBegin(CONFIG_AUTO_SHUTDOWN_TIMEOUT); - DisplayBegin(); - - //////////////////// - // Read CONFIG - - ConfigRead(); - - Serial.printf("Firmware version is %s.\n", CONFIG_FIRMWARE_VERSION); - - Serial.println("Parameters:"); - Serial.println("-----"); - ConfigPrint(); - Serial.println("-----"); - - if (!ReButton::IsButtonPressed() && ReButton::IsJumperShort()) - { - Serial.println("Force factory reset."); - ConfigResetFactorySettings(); - ConfigWrite(); - return; - } - - //////////////////// - // INPUT - - InputBegin(); - for (;;) - { - InputTask(); - if (!InputIsCapturing()) break; - DisplayColor(InputToDisplayColor(InputGetCurrentValue())); - delay(LOOP_WAIT_TIME); - } - INPUT_TYPE input = InputGetConfirmValue(); - Serial.printf("Button is %s.\n", InputGetInputString(input)); - - //////////////////// - // FLASH - - DisplayStartAction(InputToDisplayColor(input)); - - //////////////////// - // ACTION - - ACTION_TYPE action = InputToAction(input); - Serial.printf("Action is %s.\n", ActionGetActionString(action)); - - if (!ActionTaskBlocking(action)) return; - - //////////////////// - // FINISH - - Serial.println("Finish."); - - DisplayStartFinish(InputToDisplayColor(input)); - delay(1500); - - //////////////////// - // Power off - - ReButton::PowerSupplyEnable(false); - delay(POWER_OFF_TIME); -} - -void loop() -{ - //////////////////// - // FINISH (Error) - - for (int i = 0; i < 3; i++) - { - DisplayColor(DISPLAY_ERROR); - delay(200); - DisplayColor(DISPLAY_OFF); - delay(200); - } - ReButton::PowerSupplyEnable(false); - delay(POWER_OFF_TIME); -} - -static DISPLAY_COLOR_TYPE InputToDisplayColor(INPUT_TYPE value) -{ - switch (value) - { - case INPUT_SINGLE_CLICK: - return Config.DisplayColorSingleClick; - case INPUT_DOUBLE_CLICK: - return Config.DisplayColorDoubleClick; - case INPUT_TRIPLE_CLICK: - return Config.DisplayColorTripleClick; - case INPUT_LONG_PRESS: - return Config.DisplayColorLongPress; - case INPUT_SUPER_LONG_PRESS: - return Config.DisplayColorSuperLongPress; - case INPUT_ULTRA_LONG_PRESS: - return Config.DisplayColorUltraLongPress; - default: - return DISPLAY_ERROR; - } -} - -static ACTION_TYPE InputToAction(INPUT_TYPE value) -{ - switch (value) - { - case INPUT_SINGLE_CLICK: - return ACTION_1; - case INPUT_DOUBLE_CLICK: - return ACTION_2; - case INPUT_TRIPLE_CLICK: - return ACTION_3; - case INPUT_LONG_PRESS: - return ACTION_10; - case INPUT_SUPER_LONG_PRESS: - return ACTION_11; - case INPUT_ULTRA_LONG_PRESS: - return ACTION_AP; - default: - return ACTION_NONE; - } -} +#include +#include "Config.h" + +#include +#include "AutoShutdown.h" +#include "Display.h" +#include "Input.h" +#include "Action.h" + +#define LOOP_WAIT_TIME (10) // [msec.] +#define POWER_OFF_TIME (1000) // [msec.] + +void setup() +{ + //////////////////// + // Setup auto shutdown + + AutoShutdownBegin(CONFIG_AUTO_SHUTDOWN_TIMEOUT); + DisplayBegin(); + + //////////////////// + // Read CONFIG + + ConfigRead(); + + Serial.printf("Firmware version is %s.\n", CONFIG_FIRMWARE_VERSION); + + Serial.println("Parameters:"); + Serial.println("-----"); + ConfigPrint(); + Serial.println("-----"); + + if (!ReButton::IsButtonPressed() && ReButton::IsJumperShort()) + { + Serial.println("Force factory reset."); + ConfigResetFactorySettings(); + ConfigWrite(); + return; + } + + //////////////////// + // INPUT + + InputBegin(); + for (;;) + { + InputTask(); + if (!InputIsCapturing()) break; + DisplayColor(InputToDisplayColor(InputGetCurrentValue())); + delay(LOOP_WAIT_TIME); + } + INPUT_TYPE input = InputGetConfirmValue(); + Serial.printf("Button is %s.\n", InputGetInputString(input)); + + //////////////////// + // FLASH + + DisplayStartAction(InputToDisplayColor(input)); + + //////////////////// + // ACTION + + ACTION_TYPE action = InputToAction(input); + Serial.printf("Action is %s.\n", ActionGetActionString(action)); + + if (!ActionTaskBlocking(action)) return; + + //////////////////// + // FINISH + + Serial.println("Finish."); + + DisplayStartFinish(InputToDisplayColor(input)); + delay(1500); + + //////////////////// + // Power off + + ReButton::PowerSupplyEnable(false); + delay(POWER_OFF_TIME); +} + +void loop() +{ + //////////////////// + // FINISH (Error) + + for (int i = 0; i < 3; i++) + { + DisplayColor(DISPLAY_ERROR); + delay(200); + DisplayColor(DISPLAY_OFF); + delay(200); + } + ReButton::PowerSupplyEnable(false); + delay(POWER_OFF_TIME); +} + +static DISPLAY_COLOR_TYPE InputToDisplayColor(INPUT_TYPE value) +{ + switch (value) + { + case INPUT_SINGLE_CLICK: + return Config.DisplayColorSingleClick; + case INPUT_DOUBLE_CLICK: + return Config.DisplayColorDoubleClick; + case INPUT_TRIPLE_CLICK: + return Config.DisplayColorTripleClick; + case INPUT_LONG_PRESS: + return Config.DisplayColorLongPress; + case INPUT_SUPER_LONG_PRESS: + return Config.DisplayColorSuperLongPress; + case INPUT_ULTRA_LONG_PRESS: + return Config.DisplayColorUltraLongPress; + default: + return DISPLAY_ERROR; + } +} + +static ACTION_TYPE InputToAction(INPUT_TYPE value) +{ + switch (value) + { + case INPUT_SINGLE_CLICK: + return ACTION_1; + case INPUT_DOUBLE_CLICK: + return ACTION_2; + case INPUT_TRIPLE_CLICK: + return ACTION_3; + case INPUT_LONG_PRESS: + return ACTION_10; + case INPUT_SUPER_LONG_PRESS: + return ACTION_11; + case INPUT_ULTRA_LONG_PRESS: + return ACTION_AP; + default: + return ACTION_NONE; + } +} diff --git a/readme.md b/readme.md index 9489ed8..10bdbbe 100644 --- a/readme.md +++ b/readme.md @@ -1,2 +1,2 @@ # ReButtonApp - +This version of ReButtonApp supports MQTT communication.