Main.c for the Hurricane Telemetry Tutorial
/*
* EVALUATION AND USE OF THIS SOFTWARE IS SUBJECT TO THE TERMS AND
* CONDITIONS OF THE CONTROLLING LICENSE AGREEMENT FOUND AT LICENSE.md
* IN THIS SDK. IF YOU DO NOT AGREE TO THE LICENSE TERMS AND CONDITIONS,
* PLEASE RETURN ALL SOURCE FILES TO SILICON LABORATORIES.
* (c) Copyright 2018, Silicon Laboratories Inc. All rights reserved.
*/
#include "gos.h"
#include "example_app_util.h"
#include "hurricane.h"
// Update this value anytime settings.ini changes
// This will cause Gecko OS to reload the settings
#define SETTINGS_MAGIC_NUMBER 0x8
static void start_demo_handler(void *arg);
static void stop_demo_handler(void *arg);
hurricane_demo_t demo_info =
{ .demo_name = "Telemetry", // Demo name used on LCD
.start_demo_callback = start_demo_handler, // Function called when user selects Run
.stop_demo_callback = stop_demo_handler, // Function called when leaving the demo and returning to hurricane setup
.draw_splash_screen_callback = NULL, // NULL = Do not override splash screen display function
.demo_splash_screen_arg = NULL, // Splash screen jpeg file (NULL = text only)
.splash_font_color = HURRICANE_SPLASH_DEFAULT_FONT_COLOR, // Color of the splash screen navigation text
.splash_screen_timeout_ms = 0 // Splash screen timeout (0 = no timeout)
};
/*************************************************************************************************/
void gos_app_init(void)
{
gos_result_t result;
// Load the application settings if necessary
// NOTE: If the 'magic number' is different, then
// 1. The settings.ini is load
// 2. Settings are saved to NVM
// 3. The device is rebooted
//
// Upon reboot the device will automatically bringup the WLAN inteface and open the DMS websocket
if(GOS_FAILED(result, gos_load_app_settings_once("settings.ini", SETTINGS_MAGIC_NUMBER)))
{
GOS_LOG("Failed to load settings, err:%d", result);
}
hurricane_init(&demo_info);
}
/*************************************************************************************************/
static void start_demo_handler(void *arg)
{
GOS_LOG("\r\nDMS Telemetry example starting ...");
hurricane_draw_message_screen("Telemetry and Cloud Demo", GUI_TA_HCENTER | GUI_TA_VCENTER, "", "");
// Initialize the button GPIOs
gos_gpio_init(PLATFORM_BUTTON1, GOS_GPIO_INPUT_HIGH_IMPEDANCE, false);
gos_gpio_init(PLATFORM_BUTTON2, GOS_GPIO_INPUT_HIGH_IMPEDANCE, false);
// Set the connection handler
gos_dms_set_message_stream_state_handler(message_stream_connection_handler);
// Set the telemetry callback
gos_dms_set_telemetry_callback(telemetry_callback);
// Bring up the network if it isn't already
// This also pretty prints an error if no network credentials are set
example_app_util_network_up(GOS_INTERFACE_WLAN, false, NULL);
gos_event_register_periodic(sensor_report_event_handler, 0, 5000, 0);
}
/*************************************************************************************************/
static void stop_demo_handler(void *arg)
{ GOS_LOG("Exiting Hurricane Demo");
}
/*************************************************************************************************/
static gos_result_t telemetry_callback(gos_msgpack_context_t *msgpack, uint32_t *pair_count_ptr)
{
char temp_str[128];
// NOTE: The msgpack already has the root dictionary marker written
// We just need to add to the dictionary
// Add: buttons [
gos_msgpack_write_dict_array(msgpack, "buttons", 2);
// Add: { btn1: <true/false> }
gos_msgpack_write_dict_marker(msgpack, 1);
gos_msgpack_write_dict_bool(msgpack, "btn1", gos_gpio_get(PLATFORM_BUTTON1) == PLATFORM_BUTTON_ACTIVE_STATE);
// Add: { btn2: <true/false> }
gos_msgpack_write_dict_marker(msgpack, 1);
gos_msgpack_write_dict_bool(msgpack, "btn2", gos_gpio_get(PLATFORM_BUTTON2) == PLATFORM_BUTTON_ACTIVE_STATE);
// Add: utc : "<UTC string>"
gos_time_get_current_utc_as_iso8601_str((gos_iso8601_str_t*)temp_str, true);
gos_msgpack_write_dict_str(msgpack, "utc", (const char*)temp_str);
*pair_count_ptr = 2; // we added 2 entries to the root dictionary
GOS_LOG("Posting telemetry to DMS for device: %s", gos_system_get_uuid_str(temp_str));
return GOS_SUCCESS;
}
/*************************************************************************************************/
static void message_stream_connection_handler(bool is_up)
{
if (is_up == true)
{
char buffer[32];
GOS_LOG("DMS connection up");
GOS_LOG("Posting telemetry every %s seconds", gos_settings_get_print_str("dms.telemetry.interval", buffer, sizeof(buffer)));
GOS_LOG("NOTE: You can also issue the command:");
GOS_LOG("> dms_telemetry");
GOS_LOG("To immediately post telemetry to the DMS");
}
else
{
GOS_LOG("DMS connection down");
}
}
/*************************************************************************************************/
static void sensor_report_event_handler(void *arg)
{
gos_result_t result;
char als_float_str[10], prox_float_str[10];
char display_message[128];
float als, prox;
gos_msgpack_context_t *sensor_msgpack = NULL;
const gos_dms_messsage_config_t config =
{
.length = 0,
.is_response = false,
.response.handler = 0,
.response.timeout_ms = 90000 //90 second timeout
};
// Initialize the write context
if(GOS_FAILED(result, gos_dms_message_write_init(&sensor_msgpack, &config)))
{
return;
}
gos_msgpack_write_dict_marker(sensor_msgpack, 3);
gos_msgpack_write_dict_str(sensor_msgpack, "request", "webhook"); // the connector is of type webhook
gos_msgpack_write_dict_str(sensor_msgpack, "code", "DLCTELEMETRY"); // code must match connector setup on DMS
gos_msgpack_write_dict_dict(sensor_msgpack, "data", 2); // container for the data
// Add ambient light data to the msgpack
als = hurricane_sensor_get_ALS();
float_to_str(als, als_float_str, 2);
gos_msgpack_write_dict_dict(sensor_msgpack, "Ambient Light", 5);
gos_msgpack_write_dict_str(sensor_msgpack, "value", als_float_str);
gos_msgpack_write_dict_str(sensor_msgpack, "min", "0");
gos_msgpack_write_dict_str(sensor_msgpack, "max", "500");
gos_msgpack_write_dict_str(sensor_msgpack, "units", "");
gos_msgpack_write_dict_str(sensor_msgpack, "precision", "1");
// Add prox data to the msgpack
prox = hurricane_sensor_get_prox();
float_to_str(prox, prox_float_str, 2);
gos_msgpack_write_dict_dict(sensor_msgpack, "Proximity", 5);
gos_msgpack_write_dict_str(sensor_msgpack, "value", prox_float_str);
gos_msgpack_write_dict_str(sensor_msgpack, "min", "0");
gos_msgpack_write_dict_str(sensor_msgpack, "max", "1000");
gos_msgpack_write_dict_str(sensor_msgpack, "units", "");
gos_msgpack_write_dict_str(sensor_msgpack, "precision", "1");
// Send the message to the DMS
if(GOS_FAILED(result, gos_dms_message_write_flush(sensor_msgpack)))
{
gos_dms_message_context_destroy(sensor_msgpack);
}
GOS_LOG("Posting sensor data to the cloud via a DMS Cloud Connector");
sprintf(display_message, "Telemetry and Could Demo\nALS: %s\nProx: %s", als_float_str, prox_float_str);
hurricane_draw_message_screen(display_message, GUI_TA_HCENTER | GUI_TA_VCENTER, "", "");
}