1- #define MQTT_MAX_PACKET_SIZE 1024
1+ #pragma once
2+
23#if defined(ESP8266)
3- #include < ESP8266WiFi.h>
4+ #include < ESP8266WiFi.h>
45#elif defined(ESP32)
5- #include < WiFi.h>
6+ #include < WiFi.h>
67#endif
8+
9+ #include < stdint.h>
10+ #include < string.h>
11+
712#include " PubSubClient/PubSubClient.h"
813#include " ArduinoJson.h"
914
10- String HandleResponse (String query);
15+ #include " thingesp/Logger.cpp"
16+ #include " thingesp/Device.cpp"
17+ #include " thingesp/RateLimiter.cpp"
1118
12- class ThingESP32
19+ String HandleResponse (String query) __attribute__((weak));
20+
21+ class ThingESP32 : public DeviceData , public RateLimiter
1322{
1423public:
15- ThingESP32 (String username, String deviceName, String password) : g_client(espClient)
16- {
17- this ->Username = username;
18- this ->DeviceName = deviceName;
19- this ->Password = password;
20- };
21-
22- void SetWiFi (const char *ssID, const char *ssID_password)
23- {
24- this ->ssid = ssID;
25- this ->ssid_password = ssID_password;
26- }
27-
28- void initDevice ()
29- {
30- this ->topic = this ->DeviceName + " /" + this ->Username ;
31- this ->outname = this ->DeviceName + " @" + this ->Username ;
32-
33- this ->char_DeviceName = this ->DeviceName .c_str ();
34- this ->char_Password = this ->Password .c_str ();
35- this ->char_outname = this ->outname .c_str ();
36- this ->char_topic = this ->topic .c_str ();
37- this ->initiated = true ;
38-
39- Serial.println ();
40- Serial.print (" Connecting to " );
41- Serial.println (ssid);
42- Serial.println (mqttServer);
43-
44- WiFi.begin (ssid, ssid_password);
45-
46- while (WiFi.status () != WL_CONNECTED)
24+ ThingESP32 (const char * _username, const char * _projectName, const char * _credentials) : client(espClient)
4725 {
48- delay ( 500 ) ;
49- Serial. print ( " . " ) ;
50- }
26+ username = _username ;
27+ projectName = _projectName ;
28+ credentials = _credentials;
5129
52- randomSeed (micros ());
30+ genMetaData ();
31+ };
5332
54- Serial.println (" " );
55- Serial.println (" WiFi connected" );
56- Serial.println (" IP address: " );
57- Serial.println (WiFi.localIP ());
5833
59- g_client.setServer (this ->mqttServer , this ->mqttPort );
60- g_client.setCallback ([this ](char *topic, byte *payload, unsigned int length) {
61- callback (topic, payload, length);
62- });
63- }
34+ void sendMsg (String number, String msg)
35+ {
36+ if (is_rate_limited ()) return ;
37+
38+ DynamicJsonDocument data_out (1024 );
39+ data_out[" action" ] = " device_call" ;
40+ data_out[" to_number" ] = number;
41+ data_out[" msg" ] = msg;
42+ String outdata;
43+ serializeJson (data_out, outdata);
44+ publishMSG (outdata.c_str ());
45+ }
6446
65- void Handle ()
66- {
67- if (!g_client.connected ())
47+ void initDevice ()
6848 {
69- while (!g_client.connected ())
70- {
71- delay (10 );
72- Serial.print (" Attempting connection..." );
73- if (g_client.connect (this ->char_outname , this ->char_outname , this ->char_Password ))
74- {
75- Serial.println (" connected" );
76- g_client.subscribe (this ->char_topic );
49+ if (wifi_configured) {
50+
51+ LOG_VALUE (" WiFi" , " Connecting to: " , ssid)
52+
53+ WiFi.begin (ssid, ssid_password);
54+
55+ while (WiFi.status () != WL_CONNECTED) {
56+ delay (500 );
57+ }
58+
59+ LOG (" WiFi" , " Connected successfully" );
60+ LOG_VALUE (" WiFi" ," IP address: " , WiFi.localIP ());
61+
62+
7763 }
78- else
64+
65+ randomSeed (micros ());
66+
67+ client.setServer (MQTT_SERVER, MQTT_PORT);
68+ client.setCallback ([this ](char *topic, byte *payload, unsigned int length) {
69+ callback (topic, payload, length);
70+ });
71+ }
72+
73+ void Handle ()
74+ {
75+ if (!client.connected ())
7976 {
80- Serial.print (" failed, rc=" );
81- Serial.print (g_client.state ());
82- Serial.println (" try again in 5 seconds" );
83- delay (5000 );
77+ while (!client.connected ())
78+ {
79+ LOG (" SOCKET" , " Attempting connection to ThingESP" )
80+
81+ if (client.connect (outName.c_str (), outName.c_str (), credentials))
82+ {
83+ LOG (" SOCKET" , " Connected to ThingESP successfully" )
84+ client.subscribe (topic.c_str ());
85+ publishMSG (get_rate_limits_msg ());
86+ }
87+ else
88+ {
89+ LOG_VALUE (" SOCKET" , " Error connecting to ThingESP! Error code: " , client.state ());
90+ if (client.state () == 5 )
91+ LOG (" SOCKET" ," Please check your username, project name or credentials! " )
92+ LOG (" SOCKET" , " Trying again in 10 seconds.." );
93+ delay (10000 );
94+ }
95+ }
8496 }
85- }
97+ client.loop ();
98+ }
99+
100+
101+ void setCallback ( String(*clbk)(String) ){
102+ this ->callbackFunction = clbk;
86103 }
87- g_client.loop ();
88- }
89-
90- void sendMsg (String number, String msg)
91- {
92- DynamicJsonDocument data_out (1024 );
93- data_out[" action" ] = " device_call" ;
94- data_out[" to_number" ] = number;
95- data_out[" msg" ] = msg;
96- String outdata;
97- serializeJson (data_out, outdata);
98- publishMSG (outdata.c_str ());
99- }
100104
101105private:
102- String Username;
103- String DeviceName;
104- String Password;
105106
106- bool initiated = false ;
107+ /*
108+ * the callback function
109+ */
110+ String (*callbackFunction)(String);
107111
108- const char *ssid;
109- const char *ssid_password;
110112
111- const char *mqttServer = " thingesp.siddhesh.me" ;
113+ /*
114+ * the WiFi Client
115+ */
116+ WiFiClient espClient;
112117
113- int mqttPort = 1893 ;
114118
115- String topic;
116- String outname;
117119
118- const char *char_DeviceName;
119- const char *char_Password;
120- const char *char_outname;
121- const char *char_topic ;
120+ /*
121+ * PubSubClient for MQTT
122+ */
123+ PubSubClient client ;
122124
123- WiFiClient espClient;
124- PubSubClient g_client;
125125
126- void callback (char *topic, byte *payload, unsigned int length)
127- {
128- String srr;
129- Serial.println ();
130- Serial.print (" Message arrived [" );
131- Serial.print (topic);
132- Serial.print (" ] " );
133- Serial.println ();
134- for (int i = 0 ; i < length; i++)
126+ void publishMSG (const char * _msg)
135127 {
136- srr. concat (( char )payload[i] );
128+ client. publish (topic. c_str (), _msg );
137129 }
138- Serial.print (srr);
139- onMessage (srr);
140- }
141-
142- void onMessage (String data)
143- {
144- DynamicJsonDocument data_in (1024 );
145- DynamicJsonDocument data_out (1024 );
146- deserializeJson (data_in, data);
147130
148- if (data_in[ " action " ] == " query " )
131+ void callback ( char *topic, byte *payload, unsigned int length )
149132 {
150- data_out[" msg_id" ] = data_in[" msg_id" ];
151- data_out[" action" ] = " returned_api_response" ;
152- String query = data_in[" query" ];
153- query.toLowerCase ();
154- data_out[" returned_api_response" ] = HandleResponse (query);
155- String outdata;
156- serializeJson (data_out, outdata);
157- publishMSG (outdata.c_str ());
133+ String msg;
134+
135+ for (int i = 0 ; i < length; i++)
136+ msg.concat ((char )payload[i]);
137+
138+ onMessage (msg);
158139 }
159- }
160140
161- void publishMSG (const char *info)
162- {
163- g_client.publish (this ->char_topic , info);
164- }
165- };
141+
142+ void onMessage (String& data)
143+ {
144+
145+ DynamicJsonDocument data_in (1024 );
146+ DynamicJsonDocument data_out (1024 );
147+ deserializeJson (data_in, data);
148+
149+ String incoming_action = data_in[" action" ];
150+
151+ if (incoming_action == " query" )
152+ {
153+ data_out[" msg_id" ] = data_in[" msg_id" ];
154+ data_out[" action" ] = " returned_api_response" ;
155+ String query = data_in[" query" ];
156+
157+ #ifndef _DISABLE_LOWER_CASE_
158+ query.toLowerCase ();
159+ #endif
160+
161+ LOG_VALUE (" MSG" , " Query: " , query);
162+
163+ String resp = !!HandleResponse ? HandleResponse (query) : this ->callbackFunction (query);
164+
165+ LOG_VALUE (" MSG" , " Response: " , resp);
166+
167+ data_out[" returned_api_response" ] = resp;
168+
169+ String out_msg;
170+ serializeJson (data_out, out_msg);
171+ publishMSG (out_msg.c_str ());
172+
173+ }
174+ else if (incoming_action == " RATE_LIMITS_INFO" ){
175+ set_rate_limit ((unsigned int )data_in[" delay" ]);
176+ }
177+ };
178+
179+ };
0 commit comments