A Telegram BOT for this awesome all-in-one board.
Dependencies: BSP_B-L475E-IOT01 mbed es_wifi jsmn
Telegram Bot for DISCO_L475VG_IOT01
This application embeds aTelegram chatbot into the DISCO_L475VG_IOT01 board.
The Bot answers to the users queries about:
- Real time environmental data taken from the on board sensors.
- Environmental data history of the latest 24 hours stored on board.
- Camera images taken from the Arducam-mini-2mp (optional).
This software uses:
- A modified version of the wifi library provided by ST in order to enable the TCP-SSL connection.
- An open source json parser jsmn (https://github.com/zserge/jsmn).
- A web service (http://now.http.org) to initialize the RTC.
- A web service (https://image-charts.com) to publish temperature,humidity and pressure charts.
- A modified version of the Arducam driver (https://os.mbed.com/users/dflet/)
Compilation
Import in your compiler and modify the following defines:
- WIFI_SSID
- WIFI_PASSWORD
- TELEGRAM_BOT_APIKEY
Please follow the Telegram bots documentation (https://core.telegram.org/bots) to better understand how the Telegram API works and how to create your bot.
In order to support the Arducam-Mini-2MP set WITH_ARDUCAM_2640 #define to 1.
Screenshots
Security
The Inventek wifi module creates the ssl connection but does not authenticate the server's certificate ( AT cmd P9=0 ).
For more details http://www.inventeksys.com/IWIN/programming-certificates-tcp-ssltls/
Diff: main.cpp
- Revision:
- 7:2b389a2e83c4
- Parent:
- 6:94fc61e1cf40
- Child:
- 8:89fe332bc412
--- a/main.cpp Fri Jan 26 15:27:26 2018 +0000 +++ b/main.cpp Tue Jan 30 10:23:41 2018 +0000 @@ -15,7 +15,7 @@ #define WIFI_WRITE_TIMEOUT 10000 -#define WIFI_READ_TIMEOUT 10000 +#define WIFI_READ_TIMEOUT 25000 #define CONNECTION_TRIAL_MAX 10 @@ -36,9 +36,9 @@ char g_json_io_buffer[TBOT_JSON_BUFFER_SIZE]; // telegram REST API -const char TELEGRAM_GETUPDATES[] = "GET /bot" TELEGRAM_BOT_APIKEY "/getUpdates?offset=%d&timeout=5&limit=1 HTTP/1.1\r\nHost: api.telegram.org\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\n\r\n"; +const char TELEGRAM_GETUPDATES[] = "GET /bot" TELEGRAM_BOT_APIKEY "/getUpdates?offset=%d&timeout=20&limit=1 HTTP/1.1\r\nHost: api.telegram.org\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\n\r\n"; const char TELEGRAM_SENDMESSAGE[] = "GET /bot" TELEGRAM_BOT_APIKEY "/sendMessage HTTP/1.1\r\nHost: api.telegram.org\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n"; -const char TELEGRAM_CUSTOM_KEYBOARD[] = "{\"keyboard\": [[\"Temperature\"],[\"Humidity\"],[\"Pressure\"],[\"RTC\"]],\"one_time_keyboard\": true}"; +const char TELEGRAM_CUSTOM_KEYBOARD[] = "{\"keyboard\": [[\"Temperature\",\"Humidity\",\"Pressure\"],[\"Daily\",\"RTC\"]],\"one_time_keyboard\": true}"; bool telegram_get_update(int32_t update_id); bool telegram_send_message(); #define TELEGRAM_BOT_INCOMING_CMD_SIZE 80 @@ -59,6 +59,16 @@ jsmntok_t g_json_tokens[JSON_MAX_TOKENS]; bool jsoneq(const char *json, jsmntok_t *tok, const char *s,jsmntype_t type); +// Data history +float g_daily_data_history_temp[24][60]; +float g_daily_data_history_pres[24][60]; +float g_daily_data_history_humi[24][60]; +void daily_history_update(int hour, int min,float t, float p, float h); +int32_t daily_humidity_history_chart(char *report_buffer, uint32_t buffer_len); +int32_t daily_temperature_history_chart(char *report_buffer, uint32_t buffer_len); +int32_t daily_pressure_history_chart(char *report_buffer, uint32_t buffer_len); + + int main() { @@ -75,12 +85,23 @@ telegram_bot(); } + + + + + + + void telegram_bot(void) { int32_t update_id = 0; int32_t chat_id = 0; int json_results; bool well_done = false; + time_t timestamp; + struct tm *timestamp_tm; + float temp,pres,humi; + /* wifi connect */ if(wifi_connect()) @@ -95,13 +116,33 @@ /* set RTC */ set_rtc_from_network(); - + + /* init data history */ + for(int i=0; i<24; i++) + { + for(int ii=0; ii<60; ii++) + { + g_daily_data_history_temp[i][ii]=0.0F; + g_daily_data_history_pres[i][ii]=0.0F; + g_daily_data_history_humi[i][ii]=0.0F; + } + } + /* main loop */ while (1) { g_alivenessLED = !g_alivenessLED; + /* history update */ + timestamp = time(NULL); + timestamp_tm = localtime(×tamp); + temp = BSP_TSENSOR_ReadTemp(); + pres = BSP_PSENSOR_ReadPressure(); + humi = BSP_HSENSOR_ReadHumidity(); + daily_history_update( timestamp_tm->tm_hour, timestamp_tm->tm_min, temp, pres, humi ); + + // Get updates -- API method getUpdates printf("> Get updates\r\n"); g_json_io_buffer[0]=0; @@ -182,23 +223,48 @@ if( strstr(g_incoming_msg,"Temperature") != NULL) { snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Temperature %.2f degC\",\"reply_markup\":%s}", - chat_id,BSP_TSENSOR_ReadTemp(),TELEGRAM_CUSTOM_KEYBOARD); + chat_id,temp,TELEGRAM_CUSTOM_KEYBOARD); } else if( strstr(g_incoming_msg,"Humidity") != NULL) { snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Humidity %.2f %%\",\"reply_markup\":%s}", - chat_id,BSP_HSENSOR_ReadHumidity(),TELEGRAM_CUSTOM_KEYBOARD); + chat_id,humi,TELEGRAM_CUSTOM_KEYBOARD); } else if( strstr(g_incoming_msg,"Pressure") != NULL) { snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"Pressure %.2f mBar\",\"reply_markup\":%s}", - chat_id,BSP_PSENSOR_ReadPressure(),TELEGRAM_CUSTOM_KEYBOARD); + chat_id,pres,TELEGRAM_CUSTOM_KEYBOARD); } else if( strstr(g_incoming_msg,"RTC") != NULL) { - time_t seconds = time(NULL); snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"%s UTC\",\"reply_markup\":%s}", - chat_id,ctime(&seconds),TELEGRAM_CUSTOM_KEYBOARD); + chat_id,ctime(×tamp),TELEGRAM_CUSTOM_KEYBOARD); + } + else if( strstr(g_incoming_msg,"Daily") != NULL) + { + int pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); + pivot += daily_temperature_history_chart( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot ); + snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\"}"); + if( telegram_send_message() == false) + { + printf("> ERROR telegram_send_message\r\n"); + continue; + } + + pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); + pivot += daily_humidity_history_chart( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot ); + snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\"}"); + if( telegram_send_message() == false) + { + printf("> ERROR telegram_send_message\r\n"); + continue; + } + + pivot = snprintf(g_json_io_buffer,TBOT_JSON_BUFFER_SIZE,"{\"chat_id\":%d,\"text\":\"", chat_id); + pivot += daily_pressure_history_chart( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot ); + snprintf( g_json_io_buffer + pivot, TBOT_JSON_BUFFER_SIZE - pivot, "\",\"reply_markup\":%s}",TELEGRAM_CUSTOM_KEYBOARD); + + } else { @@ -227,8 +293,109 @@ } } +/***************************************************************************************** +* +* +* Daily history update +* +* +******************************************************************************************/ +void daily_history_update( int hour, int min, float t, float p, float h ) +{ + g_daily_data_history_temp[hour][min] = t; + g_daily_data_history_pres[hour][min] = p; + g_daily_data_history_humi[hour][min] = h; +} +int32_t daily_temperature_history_chart(char *report_buffer, uint32_t buffer_len) +{ + float sum; + uint32_t num; + int32_t pivot = 0; + + // temperature chart + pivot = snprintf(report_buffer,buffer_len,"Daily temperature chart\n\nhttps://image-charts.com/chart?chxt=x,y&chxr=1,0,%d&cht=lc&chd=t:",50); + for(int i=0;i<24;i++) + { + sum = 0.0F; + num = 0; + for(int ii=0;ii<60;ii++) + { + if(g_daily_data_history_temp[i][ii] > 0.0F) + { + num++; + sum += g_daily_data_history_temp[i][ii]; + } + } + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%d,",(num>0)?(int32_t)sum/num:0); + } + pivot--; + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%s","&chco=76A4FB&chls=2.0&chs=600x300&chg=10,10"); + + report_buffer[pivot]=0; + return pivot; +} + +int32_t daily_humidity_history_chart(char *report_buffer, uint32_t buffer_len) +{ + float sum; + uint32_t num; + int32_t pivot = 0; + + // humidity chart + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"Daily humidity chart\n\nhttps://image-charts.com/chart?chxt=x,y&chxr=1,0,%d&cht=lc&chd=t:",100); + for(int i=0;i<24;i++) + { + sum = 0.0F; + num = 0; + for(int ii=0;ii<60;ii++) + { + if(g_daily_data_history_humi[i][ii] > 0.0F) + { + num++; + sum += g_daily_data_history_humi[i][ii]; + } + } + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%d,",(num>0)?(int32_t)sum/num:0); + } + pivot--; + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%s","&chco=76A4FB&chls=2.0&chs=600x300&chg=10,10\n\n"); + + report_buffer[pivot]=0; + return pivot; +} + + +int32_t daily_pressure_history_chart(char *report_buffer, uint32_t buffer_len) +{ + float sum; + uint32_t num; + int32_t pivot = 0; + + // pressure chart + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"Daily pressure chart\n\nhttps://image-charts.com/chart?chxt=x,y&chxr=1,%d,%d&cht=lc&chd=t:",900,1100); + for(int i=0;i<24;i++) + { + sum = 0.0F; + num = 0; + for(int ii=0;ii<60;ii++) + { + if(g_daily_data_history_pres[i][ii] > 0.0F) + { + num++; + sum += g_daily_data_history_pres[i][ii]; + } + } + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%d,",(num>0)?(int32_t)sum/num:0); + } + pivot--; + pivot += snprintf(report_buffer+pivot,buffer_len-pivot,"%s","&chco=76A4FB&chls=2.0&chs=600x300&chg=10,10&chds=a"); + + report_buffer[pivot]=0; + return pivot; +} + /***************************************************************************************** * *