2020-06-18 23:43:06 +02:00
# include "Global.h"
2020-06-17 23:30:48 +03:00
2020-06-21 03:43:15 +03:00
//
# include <LittleFS.h>
2020-06-22 14:01:12 +03:00
static const char * MODULE = " Mqtt " ;
2020-06-20 14:27:58 +03:00
// Errors
int wifi_lost_error = 0 ;
int mqtt_lost_error = 0 ;
2020-06-19 22:14:50 +02:00
2020-06-22 14:01:12 +03:00
// Session params
String mqttPrefix ;
2020-06-22 17:40:29 +03:00
String mqttRootDevice ;
2020-06-22 14:01:12 +03:00
void handleSubscribedUpdates ( char * topic , uint8_t * payload , size_t length ) ;
const String getMqttStateStr ( ) ;
2020-06-18 23:43:06 +02:00
void sendAllData ( ) ;
void sendAllWigets ( ) ;
2020-06-22 17:40:29 +03:00
boolean publicStatus ( String topic , String state ) ;
2020-06-18 23:43:06 +02:00
void outcoming_date ( ) ;
2020-06-17 23:30:48 +03:00
2020-06-22 14:01:12 +03:00
void initMQTT ( ) {
mqtt . setCallback ( handleSubscribedUpdates ) ;
2020-06-20 14:27:58 +03:00
ts . add (
2020-06-22 14:01:12 +03:00
WIFI_MQTT_CONNECTION_CHECK , MQTT_RECONNECT_INTERVAL ,
[ & ] ( void * ) {
if ( isNetworkActive ( ) ) {
if ( mqtt . connected ( ) ) {
pm . info ( " OK " ) ;
2020-06-22 03:11:02 +03:00
setLedStatus ( LED_OFF ) ;
2020-06-20 14:27:58 +03:00
} else {
2020-06-22 14:01:12 +03:00
connectMQTT ( ) ;
2020-06-20 14:27:58 +03:00
if ( ! just_load ) mqtt_lost_error + + ;
}
} else {
2020-06-22 14:01:12 +03:00
pm . error ( " WiFi connection lost " ) ;
2020-06-20 14:27:58 +03:00
ts . remove ( WIFI_MQTT_CONNECTION_CHECK ) ;
2020-06-22 14:01:12 +03:00
wifi_lost_error + + ;
2020-06-22 03:11:02 +03:00
startAPMode ( ) ;
2020-06-20 14:27:58 +03:00
}
} ,
nullptr , true ) ;
2020-06-17 23:30:48 +03:00
}
2020-06-22 17:40:29 +03:00
void reconnectMQTT ( ) {
2020-06-22 14:01:12 +03:00
if ( mqttParamsChanged ) {
mqtt . disconnect ( ) ;
connectMQTT ( ) ;
mqttParamsChanged = false ;
2020-06-20 14:27:58 +03:00
}
2020-06-17 23:30:48 +03:00
}
2020-06-22 14:01:12 +03:00
void loopMQTT ( ) {
if ( ! isNetworkActive ( ) | | ! mqtt . connected ( ) ) {
return ;
2020-06-17 23:30:48 +03:00
}
2020-06-22 14:01:12 +03:00
mqtt . loop ( ) ;
}
void subscribe ( ) {
pm . info ( " Subscribe " ) ;
// Для приема получения HELLOW и подтверждения связи
// Подписываемся на топики control
// Подписываемся на топики order
2020-06-22 17:40:29 +03:00
mqtt . subscribe ( mqttPrefix . c_str ( ) ) ;
mqtt . subscribe ( ( mqttRootDevice + " /+/control " ) . c_str ( ) ) ;
mqtt . subscribe ( ( mqttRootDevice + " /order " ) . c_str ( ) ) ;
mqtt . subscribe ( ( mqttRootDevice + " /update " ) . c_str ( ) ) ;
mqtt . subscribe ( ( mqttRootDevice + " /devc " ) . c_str ( ) ) ;
mqtt . subscribe ( ( mqttRootDevice + " /devs " ) . c_str ( ) ) ;
2020-06-17 23:30:48 +03:00
}
2020-06-22 14:01:12 +03:00
boolean connectMQTT ( ) {
if ( ! isNetworkActive ( ) ) {
return false ;
}
String addr = jsonReadStr ( configSetupJson , " mqttServer " ) ;
2020-06-22 17:40:29 +03:00
if ( ! addr ) {
pm . error ( " no broker address " ) ;
return false ;
}
2020-06-22 14:01:12 +03:00
int port = jsonReadInt ( configSetupJson , " mqttPort " ) ;
String user = jsonReadStr ( configSetupJson , " mqttUser " ) ;
String pass = jsonReadStr ( configSetupJson , " mqttPass " ) ;
2020-06-22 17:40:29 +03:00
//Session params
2020-06-22 14:01:12 +03:00
mqttPrefix = jsonReadStr ( configSetupJson , " mqttPrefix " ) ;
2020-06-22 17:40:29 +03:00
mqttRootDevice = mqttPrefix + " / " + chipId ;
2020-06-22 14:01:12 +03:00
pm . info ( " broker " + addr + " : " + String ( port , DEC ) ) ;
setLedStatus ( LED_FAST ) ;
mqtt . setServer ( addr . c_str ( ) , port ) ;
2020-06-17 23:30:48 +03:00
bool res = false ;
2020-06-22 14:01:12 +03:00
if ( ! mqtt . connected ( ) ) {
if ( mqtt . connect ( chipId . c_str ( ) , user . c_str ( ) , pass . c_str ( ) ) ) {
pm . info ( " connected " ) ;
setLedStatus ( LED_OFF ) ;
subscribe ( ) ;
res = true ;
} else {
pm . error ( " could't connect, retry in " + String ( MQTT_RECONNECT_INTERVAL / 1000 ) + " s " ) ;
setLedStatus ( LED_FAST ) ;
2020-06-17 23:30:48 +03:00
}
}
return res ;
}
2020-06-22 14:01:12 +03:00
void handleSubscribedUpdates ( char * topic , uint8_t * payload , size_t length ) {
String topicStr = String ( topic ) ;
pm . info ( topicStr ) ;
2020-06-20 14:27:58 +03:00
2020-06-22 14:01:12 +03:00
String payloadStr ;
payloadStr . reserve ( length + 1 ) ;
2020-06-20 14:27:58 +03:00
for ( size_t i = 0 ; i < length ; i + + ) {
2020-06-22 14:01:12 +03:00
payloadStr + = ( char ) payload [ i ] ;
2020-06-20 14:27:58 +03:00
}
2020-06-22 14:01:12 +03:00
pm . info ( payloadStr ) ;
2020-06-20 14:27:58 +03:00
2020-06-22 14:01:12 +03:00
if ( payloadStr = = " HELLO " ) {
//данные которые отправляем при подключении или отбновлении страницы
pm . info ( " Send web page updates " ) ;
sendAllWigets ( ) ;
sendAllData ( ) ;
# ifdef LOGGING_ENABLED
choose_log_date_and_send ( ) ;
# endif
} else if ( topicStr . indexOf ( " control " ) ) {
// название топика - команда,
// значение - параметр
//IoTmanager/800324-1458415/button99/control 1
String topic = selectFromMarkerToMarker ( topicStr , " / " , 3 ) ;
topic = add_set ( topic ) ;
String number = selectToMarkerLast ( topic , " Set " ) ;
topic . replace ( number , " " ) ;
2020-06-20 14:27:58 +03:00
2020-06-22 14:01:12 +03:00
order_loop + = topic ;
order_loop + = " " ;
order_loop + = number ;
order_loop + = " " ;
order_loop + = payloadStr ;
order_loop + = " , " ;
} else if ( topicStr . indexOf ( " order " ) ) {
payloadStr . replace ( " _ " , " " ) ;
order_loop + = payloadStr ;
order_loop + = " , " ;
} else if ( topicStr . indexOf ( " update " ) ) {
if ( payloadStr = = " 1 " ) {
2020-06-20 14:27:58 +03:00
upgrade = true ;
}
2020-06-22 14:01:12 +03:00
} else if ( topicStr . indexOf ( " devc " ) ) {
writeFile ( " firmware.c.txt " , payloadStr ) ;
2020-06-20 14:27:58 +03:00
Device_init ( ) ;
2020-06-22 14:01:12 +03:00
} else if ( topicStr . indexOf ( " devs " ) ) {
writeFile ( " firmware.s.txt " , payloadStr ) ;
2020-06-20 14:27:58 +03:00
Scenario_init ( ) ;
2020-06-17 23:30:48 +03:00
}
}
2020-06-22 14:01:12 +03:00
boolean publish ( const String & topic , const String & data ) {
if ( mqtt . beginPublish ( topic . c_str ( ) , data . length ( ) , false ) ) {
mqtt . print ( data ) ;
return mqtt . endPublish ( ) ;
}
return false ;
}
2020-06-17 23:30:48 +03:00
2020-06-22 14:01:12 +03:00
boolean publishData ( const String & topic , const String & data ) {
2020-06-22 17:40:29 +03:00
String path = mqttRootDevice + " / " + topic ;
2020-06-22 14:01:12 +03:00
if ( ! publish ( path , data ) ) {
pm . error ( " on publish data " ) ;
return false ;
}
return true ;
2020-06-17 23:30:48 +03:00
}
2020-06-22 14:01:12 +03:00
boolean publishChart ( const String & topic , const String & data ) {
2020-06-22 17:40:29 +03:00
String path = mqttRootDevice + " / " + topic + " /status " ;
2020-06-22 14:01:12 +03:00
if ( ! publish ( path , data ) ) {
pm . error ( " on publish chart " ) ;
return false ;
}
return true ;
2020-06-17 23:30:48 +03:00
}
2020-06-22 14:01:12 +03:00
boolean publishControl ( String id , String topic , String state ) {
String path = mqttPrefix + " / " + id + " / " + topic + " /control " ;
return mqtt . publish ( path . c_str ( ) , state . c_str ( ) , false ) ;
2020-06-17 23:30:48 +03:00
}
2020-06-22 14:01:12 +03:00
boolean sendCHART_test ( String topic , String data ) {
2020-06-22 17:40:29 +03:00
topic = mqttRootDevice + " / " + topic + " /status " ;
2020-06-22 14:01:12 +03:00
return mqtt . publish ( topic . c_str ( ) , data . c_str ( ) , false ) ;
2020-06-19 22:14:50 +02:00
}
2020-06-22 17:40:29 +03:00
boolean publishStatus ( const String & topic , const String & data ) {
String path = mqttRootDevice + " / " + topic + " /status " ;
String json = " {} " ;
jsonWriteStr ( json , " status " , data ) ;
return mqtt . publish ( topic . c_str ( ) , json . c_str ( ) , false ) ;
2020-06-17 23:30:48 +03:00
}
//=====================================================ОТПРАВЛЯЕМ ВИДЖЕТЫ========================================================
2020-06-21 03:43:15 +03:00
# ifdef LAYOUT_IN_RAM
2020-06-17 23:30:48 +03:00
void sendAllWigets ( ) {
2020-06-20 14:27:58 +03:00
if ( all_widgets ! = " " ) {
int counter = 0 ;
String line ;
int psn_1 = 0 ;
int psn_2 ;
do {
psn_2 = all_widgets . indexOf ( " \r \n " , psn_1 ) ; //\r\n
line = all_widgets . substring ( psn_1 , psn_2 ) ;
line . replace ( " \n " , " " ) ;
line . replace ( " \r \n " , " " ) ;
//jsonWriteStr(line, "id", String(counter));
//jsonWriteStr(line, "pageId", String(counter));
counter + + ;
sendMQTT ( " config " , line ) ;
Serial . println ( " [V] " + line ) ;
psn_1 = psn_2 + 1 ;
} while ( psn_2 + 2 < all_widgets . length ( ) ) ;
2020-06-20 22:51:14 +03:00
getMemoryLoad ( " [I] after send all widgets " ) ;
2020-06-20 14:27:58 +03:00
}
2020-06-17 23:30:48 +03:00
}
# endif
2020-06-21 03:43:15 +03:00
# ifndef LAYOUT_IN_RAM
2020-06-17 23:30:48 +03:00
void sendAllWigets ( ) {
2020-06-21 03:43:15 +03:00
auto file = seekFile ( " /layout.txt " ) ;
2020-06-20 22:51:14 +03:00
if ( ! file ) {
2020-06-20 14:27:58 +03:00
return ;
}
2020-06-20 22:51:14 +03:00
while ( file . position ( ) ! = file . size ( ) ) {
2020-06-21 03:43:15 +03:00
String payload = file . readStringUntil ( ' \n ' ) ;
2020-06-22 14:01:12 +03:00
pm . info ( " publish: " + payload ) ;
publishData ( " config " , payload ) ;
2020-06-20 14:27:58 +03:00
}
2020-06-21 03:43:15 +03:00
file . close ( ) ;
2020-06-17 23:30:48 +03:00
}
# endif
2020-06-21 03:43:15 +03:00
2020-06-17 23:30:48 +03:00
//=====================================================ОТПРАВЛЯЕМ ДАННЫЕ В ВИДЖЕТЫ ПРИ ОБНОВЛЕНИИ СТРАНИЦЫ========================================================
2020-06-20 14:27:58 +03:00
2020-06-22 17:40:29 +03:00
void sendAllData ( ) {
// берет строку json и ключи превращает в топики а значения колючей в них посылает
// {"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"}
// "name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"
// "name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1",
String current_config = configLiveJson ;
2020-06-21 03:43:15 +03:00
printMemoryStatus ( " [I] after send all date " ) ;
2020-06-20 14:27:58 +03:00
current_config . replace ( " { " , " " ) ;
2020-06-22 17:40:29 +03:00
current_config . replace ( " } " , " " ) ;
current_config + = " , " ;
2020-06-20 14:27:58 +03:00
2020-06-22 17:40:29 +03:00
while ( current_config . length ( ) ) {
2020-06-20 14:27:58 +03:00
String tmp = selectToMarker ( current_config , " , " ) ;
2020-06-22 17:40:29 +03:00
2020-06-20 14:27:58 +03:00
String topic = selectToMarker ( tmp , " : " ) ;
topic . replace ( " \" " , " " ) ;
2020-06-22 17:40:29 +03:00
2020-06-20 14:27:58 +03:00
String state = selectToMarkerLast ( tmp , " : " ) ;
state . replace ( " \" " , " " ) ;
2020-06-22 17:40:29 +03:00
2020-06-20 14:27:58 +03:00
if ( topic ! = " name " & & topic ! = " lang " & & topic ! = " ip " & & topic . indexOf ( " _in " ) < 0 ) {
2020-06-22 17:40:29 +03:00
publishStatus ( topic , state ) ;
2020-06-20 14:27:58 +03:00
}
current_config = deleteBeforeDelimiter ( current_config , " , " ) ;
2020-06-17 23:30:48 +03:00
}
}
2020-06-22 14:01:12 +03:00
const String getMqttStateStr ( ) {
switch ( mqtt . state ( ) ) {
2020-06-17 23:30:48 +03:00
case - 4 :
2020-06-22 14:01:12 +03:00
return F ( " no respond " ) ;
2020-06-17 23:30:48 +03:00
break ;
case - 3 :
2020-06-22 14:01:12 +03:00
return F ( " connection was broken " ) ;
2020-06-17 23:30:48 +03:00
break ;
case - 2 :
2020-06-22 14:01:12 +03:00
return F ( " connection failed " ) ;
2020-06-17 23:30:48 +03:00
break ;
case - 1 :
2020-06-22 14:01:12 +03:00
return F ( " client disconnected " ) ;
2020-06-17 23:30:48 +03:00
break ;
case 0 :
2020-06-22 14:01:12 +03:00
return F ( " client connected " ) ;
2020-06-17 23:30:48 +03:00
break ;
case 1 :
2020-06-22 14:01:12 +03:00
return F ( " doesn't support the requested version " ) ;
2020-06-17 23:30:48 +03:00
break ;
case 2 :
2020-06-22 14:01:12 +03:00
return F ( " rejected the client identifier " ) ;
2020-06-17 23:30:48 +03:00
break ;
case 3 :
2020-06-22 14:01:12 +03:00
return F ( " unable to accept the connection " ) ;
2020-06-17 23:30:48 +03:00
break ;
case 4 :
2020-06-22 14:01:12 +03:00
return F ( " wrong username/password " ) ;
2020-06-17 23:30:48 +03:00
break ;
case 5 :
2020-06-22 14:01:12 +03:00
return F ( " not authorized to connect " ) ;
2020-06-17 23:30:48 +03:00
break ;
default :
2020-06-22 14:01:12 +03:00
return F ( " unspecified " ) ;
2020-06-17 23:30:48 +03:00
break ;
}
}