diff --git a/include/hasp_conf.h b/include/hasp_conf.h
index 32eba200..1532c1f5 100644
--- a/include/hasp_conf.h
+++ b/include/hasp_conf.h
@@ -2,8 +2,8 @@
#define HASP_CONF_H
#define HASP_VERSION_MAJOR 0
-#define HASP_VERSION_MINOR 1
-#define HASP_VERSION_REVISION 0
+#define HASP_VERSION_MINOR 2
+#define HASP_VERSION_REVISION 1014
#define HASP_USE_APP 1
@@ -35,7 +35,7 @@
#endif
#ifndef HASP_USE_SYSLOG
-#define HASP_USE_SYSLOG 0
+#define HASP_USE_SYSLOG 1
#endif
#ifndef HASP_USE_TELNET
diff --git a/platformio.ini b/platformio.ini
index 51a553a0..45fe4f22 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -157,8 +157,8 @@ build_flags =
[env:d1mini-lolintft24]
platform = espressif8266@^2.4.0 ;@2.3.2
board = d1_mini
-upload_port = COM7 ; To change the port, use platform_override.ini
-monitor_port = COM7 ; To change the port, use platform_override.ini
+;upload_port = To change the port, use platform_override.ini
+;monitor_port = To change the port, use platform_override.ini
board_build.f_flash = 40000000L
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs
diff --git a/src/hasp.cpp b/src/hasp.cpp
index 8e8fef7e..45d29b80 100644
--- a/src/hasp.cpp
+++ b/src/hasp.cpp
@@ -682,8 +682,8 @@ void haspClearPage(uint16_t pageid)
lv_obj_t * page = get_page(pageid);
if(!page) {
Log.warning(F("HASP: Page ID %u not defined"), pageid);
- } else if(page == lv_layer_sys() || page == lv_layer_top()) {
- Log.warning(F("HASP: Cannot clear a layer"));
+ } else if(page == lv_layer_sys() /*|| page == lv_layer_top()*/) {
+ Log.warning(F("HASP: Cannot clear system layer"));
} else {
Log.notice(F("HASP: Clearing page %u"), pageid);
lv_obj_clean(pages[pageid]);
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index 98ae27e7..ff5f291e 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -19,6 +19,7 @@
#include "hasp_mqtt.h"
#endif
+#include "hasp_conf.h"
#include "hasp_debug.h"
#include "hasp_config.h"
#include "hasp_dispatch.h"
@@ -37,6 +38,7 @@
#if HASP_USE_SYSLOG > 0
#include "Syslog.h"
+#include
#ifndef SYSLOG_SERVER
#define SYSLOG_SERVER ""
@@ -280,6 +282,9 @@ static void debugPrintLvglMemory(int level, Print * _logOutput)
static void debugPrintPriority(int level, Print * _logOutput)
{
+ if(_logOutput == &syslogClient) {
+ }
+
switch(level) {
case LOG_LEVEL_FATAL:
case LOG_LEVEL_ERROR:
diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp
index 17e1ab12..9f5c0f69 100644
--- a/src/hasp_dispatch.cpp
+++ b/src/hasp_dispatch.cpp
@@ -7,6 +7,7 @@
#include "hasp_config.h"
#include "hasp_debug.h"
#include "hasp_gui.h"
+#include "hasp_oobe.h"
#include "hasp_hal.h"
#include "hasp.h"
@@ -119,7 +120,7 @@ void dispatchAttribute(String strTopic, const char * payload)
dispatchWebUpdate(payload);
} else if(strTopic == F("setupap")) {
- // haspDisplayAP(String(F("HASP-ABC123")).c_str(), String(F("haspadmin")).c_str());
+ oobeFakeSetup();
} else if(strTopic.length() == 7 && strTopic.startsWith(F("output"))) {
dispatchOutput(strTopic, payload);
diff --git a/src/hasp_http.cpp b/src/hasp_http.cpp
index edb856f4..0a218e91 100644
--- a/src/hasp_http.cpp
+++ b/src/hasp_http.cpp
@@ -375,10 +375,14 @@ void webHandleAbout()
F("ArduinoLog
Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, "
"dhylands, Josha blemasle, mfalkvidd");
httpMessage += FPSTR(MIT_LICENSE);
+#if HASP_USE_SYSLOG > 0
httpMessage += F("Syslog
Copyright© 2016 Martin Sloup");
httpMessage += FPSTR(MIT_LICENSE);
+#endif
+#if HASP_USE_QRCODE > 0
httpMessage += F("QR Code generator
Copyright© Project Nayuki");
httpMessage += FPSTR(MIT_LICENSE);
+#endif
httpMessage += F("AceButton
Copyright© 2018 Brian T. Park");
httpMessage += FPSTR(MIT_LICENSE);
@@ -1220,6 +1224,7 @@ void webHandleDebugConfig()
httpMessage += settings[FPSTR(F_DEBUG_TELEPERIOD)].as();
httpMessage += F("'>
");
+#if HASP_USE_SYSLOG > 0
httpMessage += F("Syslog Hostame (optional)() == 1) httpMessage += F(" checked");
httpMessage += F(">BSD (RFC 3164)");
+#endif
httpMessage += F("");
diff --git a/src/hasp_oobe.cpp b/src/hasp_oobe.cpp
index e63d27fe..6c633ffe 100644
--- a/src/hasp_oobe.cpp
+++ b/src/hasp_oobe.cpp
@@ -33,6 +33,7 @@ void oobeSetAutoCalibrate(bool cal)
static inline void oobeSetPage(uint8_t pageid)
{
lv_scr_load(oobepage[pageid]);
+ lv_obj_invalidate(lv_disp_get_layer_sys(NULL));
}
void gotoPage1_cb(lv_obj_t * event_kb, lv_event_t event)
@@ -293,27 +294,51 @@ static void oobe_calibrate_cb(lv_obj_t * ta, lv_event_t event)
}
}
-void oobeSetup()
+bool oobeSetup()
{
+#if HASP_USE_WIFI > 0
char ssid[32];
char pass[32];
-#if HASP_USE_WIFI>0
if(wifiShowAP(ssid, pass)) {
guiSetDim(100);
oobeSetupQR(ssid, pass);
oobeSetupSsid();
- oobeSetPage(0);
- lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
- lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), gotoPage1_cb);
if(oobeAutoCalibrate) {
lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), oobe_calibrate_cb);
Log.verbose(F("OOBE: Enabled Auto Calibrate on touch"));
} else {
+ lv_obj_set_click(lv_disp_get_layer_sys(NULL), false);
+ lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), gotoPage1_cb);
Log.verbose(F("OOBE: Already calibrated"));
}
+ oobeSetPage(0);
+ return true;
+ } else {
+ return false;
}
#endif
+}
+
+void oobeFakeSetup()
+{
+ char ssid[32] = "HASP-ABCDEF";
+ char pass[32] = "haspadmin";
+
+ guiSetDim(100);
+ oobeSetupQR(ssid, pass);
+ oobeSetupSsid();
+ oobeSetPage(0);
+ lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
+ lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), gotoPage1_cb);
+
+ if(oobeAutoCalibrate) {
+ lv_obj_set_click(lv_disp_get_layer_sys(NULL), true);
+ lv_obj_set_event_cb(lv_disp_get_layer_sys(NULL), oobe_calibrate_cb);
+ Log.verbose(F("OOBE: Enabled Auto Calibrate on touch"));
+ } else {
+ Log.verbose(F("OOBE: Already calibrated"));
+ }
}
\ No newline at end of file
diff --git a/src/hasp_oobe.h b/src/hasp_oobe.h
index a602358e..ed675a95 100644
--- a/src/hasp_oobe.h
+++ b/src/hasp_oobe.h
@@ -1,2 +1,3 @@
void oobeSetAutoCalibrate(bool cal);
-void oobeSetup();
\ No newline at end of file
+bool oobeSetup();
+void oobeFakeSetup();
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index e03e3c21..7feb8331 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -21,15 +21,15 @@ void setup()
***************************/
/* Init Storage */
-#if HASP_USE_EEPROM>0
+#if HASP_USE_EEPROM > 0
eepromSetup(); // Don't start at boot, only at write
#endif
-#if HASP_USE_SPIFFS>0
+#if HASP_USE_SPIFFS > 0
spiffsSetup();
#endif
-#if HASP_USE_SDCARD>0
+#if HASP_USE_SDCARD > 0
sdcardSetup();
#endif
@@ -43,23 +43,24 @@ void setup()
***************************/
debugSetup();
-#if HASP_USE_GPIO>0
+#if HASP_USE_GPIO > 0
gpioSetup();
#endif
-#if HASP_USE_WIFI>0
+#if HASP_USE_WIFI > 0
wifiSetup();
#endif
guiSetup();
- oobeSetup();
- haspSetup();
+ if(!oobeSetup()) {
+ haspSetup();
+ }
-#if HASP_USE_MDNS>0
+#if HASP_USE_MDNS > 0
mdnsSetup();
#endif
-#if HASP_USE_OTA>0
+#if HASP_USE_OTA > 0
otaSetup();
#endif
@@ -67,11 +68,11 @@ void setup()
ethernetSetup();
#endif
-#if HASP_USE_MQTT>0
+#if HASP_USE_MQTT > 0
mqttSetup();
#endif
-#if HASP_USE_HTTP>0
+#if HASP_USE_HTTP > 0
httpSetup();
#endif
@@ -79,7 +80,7 @@ void setup()
telnetSetup();
#endif
-#if HASP_USE_TASMOTA_SLAVE>0
+#if HASP_USE_TASMOTA_SLAVE > 0
slaveSetup();
#endif
@@ -112,7 +113,7 @@ void loop()
// haspLoop();
debugLoop();
-#if HASP_USE_GPIO>0
+#if HASP_USE_GPIO > 0
gpioLoop();
#endif
@@ -121,19 +122,19 @@ void loop()
ethernetLoop();
#endif
-#if HASP_USE_MQTT>0
+#if HASP_USE_MQTT > 0
mqttLoop();
#endif // MQTT
-#if HASP_USE_HTTP>0
+#if HASP_USE_HTTP > 0
httpLoop();
#endif // HTTP
-#if HASP_USE_MDNS>0
+#if HASP_USE_MDNS > 0
mdnsLoop();
#endif // MDNS
-#if HASP_USE_OTA>0
+#if HASP_USE_OTA > 0
otaLoop();
#endif // OTA
@@ -141,7 +142,7 @@ void loop()
telnetLoop();
#endif // TELNET
-#if HASP_USE_TASMOTA_SLAVE>0
+#if HASP_USE_TASMOTA_SLAVE > 0
slaveLoop();
#endif // TASMOTASLAVE
@@ -150,7 +151,7 @@ void loop()
/* Timer Loop */
if(millis() - mainLastLoopTime >= 1000) {
/* Run Every Second */
-#if HASP_USE_OTA>0
+#if HASP_USE_OTA > 0
otaEverySecond();
#endif
debugEverySecond();
diff --git a/test/connect.robot b/test/connect.robot
new file mode 100644
index 00000000..e1db3eac
--- /dev/null
+++ b/test/connect.robot
@@ -0,0 +1,28 @@
+*** Settings ***
+| Library | String
+| Library | MQTTLibrary
+| Test Timeout | 30 seconds
+
+
+*** Variables ***
+| ${broker.uri} | 10.4.0.5
+| ${broker.port} | 1883
+| ${client.id} | test.client
+
+
+| *Test Cases*
+| Connect to a broker with default port and client id
+| | ${mqttc} | Connect | ${broker.uri}
+| | ${client_id} = | Decode Bytes To String | ${mqttc._client_id} | UTF-8
+| | Should Be Empty | ${client_id} |
+| | [Teardown] | Disconnect
+
+| Connect to a broker with default port and specified client id
+| | ${mqttc} | Connect | ${broker.uri} | client_id=${client.id}
+| | Should be equal as strings | ${mqttc._client_id} | ${client.id}
+| | [Teardown] | Disconnect
+
+| Connect to a broker with specified port and client id
+| | ${mqttc} | Connect | ${broker.uri} | ${broker.port} | ${client.id}
+| | Should be equal as strings | ${mqttc._client_id} | ${client.id}
+| | [Teardown] | Disconnect
\ No newline at end of file
diff --git a/test/hasp-lvgl.robot b/test/hasp-lvgl.robot
new file mode 100644
index 00000000..143e7e59
--- /dev/null
+++ b/test/hasp-lvgl.robot
@@ -0,0 +1,165 @@
+| *Settings* | *Value*
+| Resource | keywords.robot
+| Test Timeout | 240 seconds
+
+| *Keywords*
+| Test Property
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
+| | ... | ${property}=${property} | ${data}=${data}
+| | ${time} | Get Time | epoch
+| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
+| | ${topic} | Set Variable | hasp/plate35/command
+| | ${restopic} | Set Variable | hasp/plate35/state/json
+| | ${qos} | Set Variable | 1
+| | ${message} | Set Variable | ${property}=${data}
+| | ${result} | Set Variable | {"${property}":"${data}"}
+| | Sleep | .01s
+| | Subscribe Async | client.id=${client} | topic=${restopic}
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
+| | Publish | ${topic} | ${message} | 1
+| | Publish | ${topic} | ${property} | 1
+| | log to console | ${result}
+| | @{messages} | Listen and Get Messages | topic=${restopic} | limit=1 | timeout=1.5
+| | LOG | ${messages}
+| | Length Should Be | ${messages} | 1
+| | Should Be Equal As Strings | ${messages}[0] | ${result}
+
+| Test Page
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
+| | ... | ${property}=${property} | ${data}=${data}
+| | ${time} | Get Time | epoch
+| | ${client} | Catenate | SEPARATOR=. | robot.mqtt | ${time}
+| | ${topic} | Set Variable | hasp/plate35/command
+| | ${restopic} | Set Variable | hasp/plate35/state/page
+| | ${qos} | Set Variable | 1
+| | ${message} | Set Variable | ${property}=${data}
+| | Subscribe Async | client.id=${client} | topic=${restopic}
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
+| | Publish | ${topic} | ${message} | 1
+| | Publish | ${topic} | ${property} | 1
+| | @{messages} | Listen and Get Messages | topic=${restopic} | limit=1 | timeout=1
+| | LOG | ${messages}
+| | Length Should Be | ${messages} | 1
+| | Should Be Equal As Strings | ${messages}[0] | ${data}
+
+
+| *Test Cases*
+
+| Test Color Picker\n
+| | ${obj} | Set Variable | p[1].b[4]
+| | Test Page | property=page | data=1
+#| | Test Property | property=${obj}.txt | data=ABC
+#| | Test Property | property=${obj}.txt | data=1234
+| | Test Property | property=${obj}.x | data=50
+| | Test Property | property=${obj}.x | data=60
+| | Test Property | property=${obj}.y | data=70
+| | Test Property | property=${obj}.y | data=80
+| | Test Property | property=${obj}.w | data=80
+| | Test Property | property=${obj}.w | data=100
+| | Test Property | property=${obj}.h | data=80
+| | Test Property | property=${obj}.h | data=100
+| | Test Property | property=${obj}.hidden | data=1
+| | Test Property | property=${obj}.hidden | data=0
+| | Test Property | property=${obj}.vis | data=0
+| | Test Property | property=${obj}.vis | data=1
+| | Test Property | property=${obj}.enabled | data=0
+| | Test Property | property=${obj}.enabled | data=1
+| | Test Property | property=${obj}.opacity | data=0
+| | Test Property | property=${obj}.opacity | data=64
+| | Test Property | property=${obj}.opacity | data=192
+| | Test Property | property=${obj}.opacity | data=255
+#| | Test Property | property=${obj}.rect | data=1
+#| | Test Property | property=${obj}.rect | data=0
+| | Test Property | property=${obj}.val | data=50
+| | Test Property | property=${obj}.val | data=60
+| | Test Property | property=${obj}.val | data=70
+| | Test Property | property=${obj}.val | data=80
+
+| Test Text Field\n
+| | ${obj} | Set Variable | p[1].b[1]
+| | Test Page | property=page | data=1
+| | Test Property | property=${obj}.txt | data=ABC
+| | Test Property | property=${obj}.txt | data=123
+| | Test Property | property=${obj}.x | data=20
+| | Test Property | property=${obj}.x | data=10
+| | Test Property | property=${obj}.y | data=20
+| | Test Property | property=${obj}.y | data=10
+#| | Test Property | property=${obj}.w | data=80
+#| | Test Property | property=${obj}.w | data=75
+#| | Test Property | property=${obj}.h | data=36
+#| | Test Property | property=${obj}.h | data=18
+| | Test Property | property=${obj}.hidden | data=1
+| | Test Property | property=${obj}.hidden | data=0
+| | Test Property | property=${obj}.vis | data=0
+| | Test Property | property=${obj}.vis | data=1
+| | Test Property | property=${obj}.enabled | data=0
+| | Test Property | property=${obj}.enabled | data=1
+| | Test Property | property=${obj}.opacity | data=0
+| | Test Property | property=${obj}.opacity | data=64
+| | Test Property | property=${obj}.opacity | data=192
+| | Test Property | property=${obj}.opacity | data=255
+
+
+| Test Button\n
+| | ${obj} | Set Variable | p[0].b[1]
+| | Test Page | property=page | data=0
+#| | Test Property | property=${obj}.txt | data=ABC
+#| | Test Property | property=${obj}.txt | data=1234
+| | Test Property | property=${obj}.x | data=20
+| | Test Property | property=${obj}.x | data=10
+| | Test Property | property=${obj}.y | data=20
+| | Test Property | property=${obj}.y | data=10
+| | Test Property | property=${obj}.w | data=80
+| | Test Property | property=${obj}.w | data=75
+| | Test Property | property=${obj}.h | data=36
+| | Test Property | property=${obj}.h | data=18
+| | Test Property | property=${obj}.hidden | data=1
+| | Test Property | property=${obj}.hidden | data=0
+| | Test Property | property=${obj}.vis | data=0
+| | Test Property | property=${obj}.vis | data=1
+| | Test Property | property=${obj}.enabled | data=0
+| | Test Property | property=${obj}.enabled | data=1
+| | Test Property | property=${obj}.opacity | data=0
+| | Test Property | property=${obj}.opacity | data=64
+| | Test Property | property=${obj}.opacity | data=192
+| | Test Property | property=${obj}.opacity | data=255
+| | Test Property | property=${obj}.toggle | data=0
+| | Test Property | property=${obj}.toggle | data=1
+| | Test Property | property=${obj}.val | data=0
+| | Test Property | property=${obj}.val | data=1
+| | Test Property | property=${obj}.val | data=2
+| | Test Property | property=${obj}.val | data=3
+
+| Test Slider\n
+| | ${obj} | Set Variable | p[1].b[3]
+| | Test Page | property=page | data=1
+#| | Test Property | property=${obj}.txt | data=ABC
+#| | Test Property | property=${obj}.txt | data=1234
+| | Test Property | property=${obj}.x | data=20
+| | Test Property | property=${obj}.x | data=10
+| | Test Property | property=${obj}.y | data=20
+| | Test Property | property=${obj}.y | data=10
+| | Test Property | property=${obj}.w | data=80
+| | Test Property | property=${obj}.w | data=75
+| | Test Property | property=${obj}.h | data=36
+| | Test Property | property=${obj}.h | data=18
+| | Test Property | property=${obj}.hidden | data=1
+| | Test Property | property=${obj}.hidden | data=0
+| | Test Property | property=${obj}.vis | data=0
+| | Test Property | property=${obj}.vis | data=1
+| | Test Property | property=${obj}.enabled | data=0
+| | Test Property | property=${obj}.enabled | data=1
+| | Test Property | property=${obj}.opacity | data=0
+| | Test Property | property=${obj}.opacity | data=64
+| | Test Property | property=${obj}.opacity | data=192
+| | Test Property | property=${obj}.opacity | data=255
+| | Test Property | property=${obj}.max | data=200
+| | Test Property | property=${obj}.min | data=100
+| | Test Property | property=${obj}.min | data=50
+| | Test Property | property=${obj}.max | data=150
+| | Test Property | property=${obj}.val | data=50
+| | Test Property | property=${obj}.val | data=60
+| | Test Property | property=${obj}.val | data=70
+| | Test Property | property=${obj}.val | data=80
diff --git a/test/keywords.robot b/test/keywords.robot
new file mode 100644
index 00000000..c29c54c9
--- /dev/null
+++ b/test/keywords.robot
@@ -0,0 +1,91 @@
+| *Settings* | *Value*
+| Library | MQTTLibrary
+| Library | BuiltIn
+
+| *Variables* | *Value*
+#| ${broker.uri} | mqtt.eclipse.org
+| ${broker.uri} | 10.4.0.5
+| ${broker.port} | 1883
+| ${client.id} | mqtt.test.client
+| ${topic} | test/mqtt_test
+| ${sub.topic} | test/mqtt_test_sub
+
+| *Keywords* |
+| Easy Connect
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
+
+| Publish to MQTT Broker
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
+| | ... | ${topic}=${topic} | ${message}=${EMPTY}
+| | ... | ${qos}=0 | ${retention}=${false}
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
+| | Publish | ${topic} | ${message} | ${qos} | ${retention}
+
+| Publish to MQTT Broker and Disconnect
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${clean_session}=${true}
+| | ... | ${topic}=${topic} | ${message}=${EMPTY}
+| | ... | ${qos}=0 | ${retention}=${false}
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${clean_session}
+| | Publish | ${topic} | ${message} | ${qos} | ${retention}
+| | [Teardown] | Disconnect
+
+| Subscribe to MQTT Broker and Validate
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${topic}=${topic}
+| | ... | ${message}=${EMPTY} | ${qos}=1
+| | ... | ${timeout}=1s
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
+| | Subscribe and Validate
+| | ... | ${topic} | ${qos} | ${message} | ${timeout}
+| | [Teardown] | Disconnect
+
+| Subscribe and Get Messages
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${topic}=${topic}
+| | ... | ${qos}=1 | ${timeout}=1s
+| | ... | ${limit}=1
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
+| | @{messages} | Subscribe | ${topic} | ${qos} | ${timeout} | ${limit}
+| | [Teardown] | Disconnect
+| | [Return] | @{messages}
+
+| Subscribe Async
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${topic}=${topic}
+| | ... | ${qos}=1 | ${timeout}=0s
+| | ... | ${limit}=1
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
+| | Subscribe | ${topic} | ${qos} | ${timeout} | ${limit}
+
+| Unsubscribe and Disconnect
+| | [Arguments] | ${topic}=${topic}
+| | Unsubscribe | ${topic}
+| | [Teardown] | Disconnect
+
+| Unsubscribe Multiple and Disconnect
+| | [Arguments] | @{topics}
+| | FOR | ${topic} | IN | @{topics}
+| | | Unsubscribe | ${topic}
+| | END
+| | [Teardown] | Disconnect
+
+| Subscribe and Unsubscribe
+| | [Arguments] | ${broker.uri}=${broker.uri} | ${port}=${broker.port}
+| | ... | ${client.id}=${client.id} | ${topic}=${topic}
+| | ... | ${qos}=1 | ${timeout}=1s
+| | ... | ${limit}=1
+| | Connect | ${broker.uri} | ${port} | ${client.id} | ${false}
+| | @{messages} | Subscribe | ${topic} | ${qos} | ${timeout} | ${limit}
+| | Unsubscribe | ${topic}
+| | [Teardown] | Disconnect
+| | [Return] | @{messages}
+
+| Listen and Get Messages
+| | [Arguments] | ${topic}=${topic} | ${timeout}=1s
+| | ... | ${limit}=1
+| | @{messages} | Listen | ${topic} | ${timeout} | ${limit}
+| | [Return] | @{messages}
\ No newline at end of file