A sleep-interval of less than 300s will reduce battery life, consider using 900s
When using the gyro temperature use a sleep-interval that is greater than 300s for accurate readings
(C) Copyright 2021-22 Magnus Persson
\ No newline at end of file
+Beer Gravity Monitor
...
A sleep-interval of less than 300s will reduce battery life, consider using 900s
When using the gyro temperature use a sleep-interval that is greater than 300s for accurate readings
(C) Copyright 2021-22 Magnus Persson
\ No newline at end of file
diff --git a/html/format.htm b/html/format.htm
index ef792b3..04e71fb 100644
--- a/html/format.htm
+++ b/html/format.htm
@@ -131,7 +131,9 @@
// Store the format
$("#format-btn").click(function(e) {
- var obj = 'id=' + $("#id").val() + '&' + $("#push-target").val() + '=' + encodeURIComponent($("#format").val());
+ var s = $("#format").val();
+ s = s.replaceAll("\n", "");
+ var obj = 'id=' + $("#id").val() + '&' + $("#push-target").val() + '=' + encodeURIComponent(s);
console.log(obj);
$.ajax( {
@@ -185,7 +187,11 @@
function selectFormat() {
var s = "#" + $("#push-target").val()
console.log(s);
- $("#format").val(decodeURIComponent($(s).val()));
+ s = decodeURIComponent($(s).val());
+ console.log(s);
+ s = s.replaceAll("|", "|\n");
+ console.log(s);
+ $("#format").val(s);
$("#preview").text("");
}
diff --git a/html/format.min.htm b/html/format.min.htm
index 1c58b45..0840663 100644
--- a/html/format.min.htm
+++ b/html/format.min.htm
@@ -1,2 +1,2 @@
-Beer Gravity Monitor
...
(C) Copyright 2021-22 Magnus Persson
\ No newline at end of file
+Beer Gravity Monitor
...
(C) Copyright 2021-22 Magnus Persson
\ No newline at end of file
diff --git a/html/upload.htm b/html/upload.htm
index ed73a73..a4e416b 100644
--- a/html/upload.htm
+++ b/html/upload.htm
@@ -78,6 +78,10 @@
The listed files below needs to be uploaded to the FileSystem in order for the GUI to work. You can also flash the LittleFS filesystem but in that case you will loose your device settings. An OTA upgrade will automatically download the files if they are found in the same location as the firmware.bin. This page is a fallback option.
Once all the files are confirmed, please reboot the device for normal operation.
index.min.htm
Checking...
device.min.htm
Checking...
config.min.htm
Checking...
calibration.min.htm
Checking...
about.min.htm
Checking...
(C) Copyright 2021-22 Magnus Persson
\ No newline at end of file
+Beer Gravity Monitor
...
The listed files below needs to be uploaded to the FileSystem in order for the GUI to work. You can also flash the LittleFS filesystem but in that case you will loose your device settings. An OTA upgrade will automatically download the files if they are found in the same location as the firmware.bin. This page is a fallback option.
Once all the files are confirmed, please reboot the device for normal operation.
index.min.htm
Checking...
device.min.htm
Checking...
config.min.htm
Checking...
calibration.min.htm
Checking...
format.min.htm
Checking...
about.min.htm
Checking...
(C) Copyright 2021-22 Magnus Persson
\ No newline at end of file
diff --git a/src/config.cpp b/src/config.cpp
index e7c053c..a0b27cf 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -66,6 +66,7 @@ Config::Config() {
_formulaData = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}};
_gyroTemp = false;
_saveNeeded = false;
+ _mqttPort = 1883;
}
//
@@ -87,7 +88,7 @@ void Config::createJson(DynamicJsonDocument& doc) {
doc[PARAM_PUSH_INFLUXDB2_BUCKET] = getInfluxDb2PushBucket();
doc[PARAM_PUSH_INFLUXDB2_AUTH] = getInfluxDb2PushToken();
doc[PARAM_PUSH_MQTT] = getMqttUrl();
- doc[PARAM_PUSH_MQTT_TOPIC] = getMqttTopic();
+ doc[PARAM_PUSH_MQTT_PORT] = getMqttPort();
doc[PARAM_PUSH_MQTT_USER] = getMqttUser();
doc[PARAM_PUSH_MQTT_PASS] = getMqttPass();
doc[PARAM_SLEEP_INTERVAL] = getSleepInterval();
@@ -227,8 +228,8 @@ bool Config::loadFile() {
setInfluxDb2PushToken(doc[PARAM_PUSH_INFLUXDB2_AUTH]);
if (!doc[PARAM_PUSH_MQTT].isNull()) setMqttUrl(doc[PARAM_PUSH_MQTT]);
- if (!doc[PARAM_PUSH_MQTT_TOPIC].isNull())
- setMqttTopic(doc[PARAM_PUSH_MQTT_TOPIC]);
+ if (!doc[PARAM_PUSH_MQTT_PORT].isNull())
+ setMqttPort(doc[PARAM_PUSH_MQTT_PORT].as());
if (!doc[PARAM_PUSH_MQTT_USER].isNull())
setMqttUser(doc[PARAM_PUSH_MQTT_USER]);
if (!doc[PARAM_PUSH_MQTT_PASS].isNull())
diff --git a/src/config.hpp b/src/config.hpp
index f143e3b..3d5de73 100644
--- a/src/config.hpp
+++ b/src/config.hpp
@@ -113,7 +113,7 @@ class Config {
String _influxDb2Token;
String _mqttUrl;
- String _mqttTopic;
+ int _mqttPort;
String _mqttUser;
String _mqttPass;
@@ -217,9 +217,13 @@ class Config {
_mqttUrl = s;
_saveNeeded = true;
}
- const char* getMqttTopic() { return _mqttTopic.c_str(); }
- void setMqttTopic(String s) {
- _mqttTopic = s;
+ int getMqttPort() { return _mqttPort; }
+ void setMqttPort(String s) {
+ _mqttPort = s.toInt();
+ _saveNeeded = true;
+ }
+ void setMqttPort(int i) {
+ _mqttPort = i;
_saveNeeded = true;
}
const char* getMqttUser() { return _mqttUser.c_str(); }
diff --git a/src/helper.cpp b/src/helper.cpp
index fbb1a1b..e2aee6b 100644
--- a/src/helper.cpp
+++ b/src/helper.cpp
@@ -378,5 +378,4 @@ String urldecode(String str) {
return encodedString;
}
-
// EOF
diff --git a/src/pushtarget.cpp b/src/pushtarget.cpp
index cd7cd70..3d3525f 100644
--- a/src/pushtarget.cpp
+++ b/src/pushtarget.cpp
@@ -30,7 +30,6 @@ SOFTWARE.
#include
#include
-#include
#include
#include
@@ -46,8 +45,8 @@ void PushTarget::send(float angle, float gravitySG, float corrGravitySG,
if ((timePassed < interval) && !force) {
#if LOG_LEVEL == 6 && !defined(PUSH_DISABLE_LOGGING)
- Log.verbose(F("PUSH: Timer has not expired %l vs %l." CR), timePassed,
- interval);
+/* Log.verbose(F("PUSH: Timer has not expired %l vs %l." CR), timePassed,
+ interval);*/
#endif
return;
}
@@ -222,8 +221,10 @@ void PushTarget::sendMqtt(TemplatingEngine& engine) {
MQTTClient mqtt(512);
String url = myConfig.getMqttUrl();
String doc = engine.create(TemplatingEngine::TEMPLATE_MQTT);
+ int port = myConfig.getMqttPort();
- if (url.endsWith(":8883")) {
+ //if (url.endsWith(":8883")) {
+ if (port>8000) {
// Allow secure channel, but without certificate validation
myWifi.getWifiClientSecure().setInsecure();
Log.notice(F("PUSH: MQTT, SSL enabled without validation." CR));
@@ -238,16 +239,39 @@ void PushTarget::sendMqtt(TemplatingEngine& engine) {
#if LOG_LEVEL == 6 && !defined(PUSH_DISABLE_LOGGING)
Log.verbose(F("PUSH: url %s." CR), myConfig.getMqttUrl());
- Log.verbose(F("PUSH: json %s." CR), doc.c_str());
+ Log.verbose(F("PUSH: data %s." CR), doc.c_str());
#endif
- // Send MQQT message
+ // Send MQQT message(s)
mqtt.setTimeout(10); // 10 seconds timeout
- if (mqtt.publish(myConfig.getMqttTopic(), doc)) {
- Log.notice(F("PUSH: MQTT publish successful" CR));
- } else {
- Log.error(F("PUSH: MQTT publish failed err=%d, ret=%d" CR),
- mqtt.lastError(), mqtt.returnCode());
+
+ int lines = 1;
+ // Find out how many lines are in the document. Each line is one topic/message. | is used as new line.
+ for (unsigned int i = 0; i:
+ String topic = line.substring(0, line.indexOf(":"));
+ String value = line.substring(line.indexOf(":")+1);
+#if LOG_LEVEL == 6 && !defined(PUSH_DISABLE_LOGGING)
+ Log.verbose(F("PUSH: topic '%s', value '%s'." CR), topic.c_str(), value.c_str());
+#endif
+ if (mqtt.publish(topic, value)) {
+ Log.notice(F("PUSH: MQTT publish successful on %s" CR), topic.c_str());
+ } else {
+ Log.error(F("PUSH: MQTT publish failed err=%d, ret=%d" CR),
+ mqtt.lastError(), mqtt.returnCode());
+ }
+
+ index = next+1;
+ lines--;
}
mqtt.disconnect();
diff --git a/src/resources.hpp b/src/resources.hpp
index 3136f91..9915787 100644
--- a/src/resources.hpp
+++ b/src/resources.hpp
@@ -40,7 +40,7 @@ SOFTWARE.
#define PARAM_PUSH_MQTT "mqtt-push"
#define PARAM_PUSH_MQTT_USER "mqtt-user"
#define PARAM_PUSH_MQTT_PASS "mqtt-pass"
-#define PARAM_PUSH_MQTT_TOPIC "mqtt-topic"
+#define PARAM_PUSH_MQTT_PORT "mqtt-port"
#define PARAM_SLEEP_INTERVAL "sleep-interval"
#define PARAM_TEMPFORMAT "temp-format"
#define PARAM_VOLTAGEFACTOR "voltage-factor"
diff --git a/src/templating.cpp b/src/templating.cpp
index a94a53b..7ee778a 100644
--- a/src/templating.cpp
+++ b/src/templating.cpp
@@ -71,6 +71,15 @@ const char influxDbFormat[] PROGMEM =
"gravity=${gravity},corr-gravity=${corr-gravity},angle=${angle},temp=${temp},battery=${battery},"
"rssi=${rssi}\n";
+const char mqttFormat[] PROGMEM =
+ "ispindel/${mdns}/tilt:${angle}|"
+ "ispindel/${mdns}/temperature:${temp}|"
+ "ispindel/${mdns}/temp_units:${temp-unit}|"
+ "ispindel/${mdns}/battery:${battery}|"
+ "ispindel/${mdns}/gravity:${gravity}|"
+ "ispindel/${mdns}/interval:${sleep-interval}|"
+ "ispindel/${mdns}/RSSI:${rssi}|";
+
//
// Initialize the variables
//
@@ -119,8 +128,8 @@ void TemplatingEngine::initialize(float angle, float gravitySG, float corrGravit
setVal(TPL_GRAVITY_CORR_P, convertToPlato(corrGravitySG), 1);
setVal(TPL_GRAVITY_UNIT, myConfig.getGravityFormat());
-#if LOG_DEBUG == 6
- dumpAll();
+#if LOG_LEVEL == 6
+ // dumpAll();
#endif
}
@@ -133,23 +142,23 @@ const String& TemplatingEngine::create(TemplatingEngine::Templates idx) {
// Load templates from memory
switch (idx) {
case TEMPLATE_HTTP1:
- baseTemplate = iSpindleFormat;
+ baseTemplate = String(iSpindleFormat);
fname = TPL_FNAME_HTTP1;
break;
case TEMPLATE_HTTP2:
- baseTemplate = iSpindleFormat;
+ baseTemplate = String(iSpindleFormat);
fname = TPL_FNAME_HTTP2;
break;
case TEMPLATE_BREWFATHER:
- baseTemplate = brewfatherFormat;
+ baseTemplate = String(brewfatherFormat);
//fname = TPL_FNAME_BREWFATHER;
break;
case TEMPLATE_INFLUX:
- baseTemplate = influxDbFormat;
+ baseTemplate = String(influxDbFormat);
fname = TPL_FNAME_INFLUXDB;
break;
case TEMPLATE_MQTT:
- baseTemplate = iSpindleFormat;
+ baseTemplate = String(mqttFormat);
fname = TPL_FNAME_MQTT;
break;
}
@@ -165,8 +174,17 @@ const String& TemplatingEngine::create(TemplatingEngine::Templates idx) {
Log.notice(F("TPL : Template loaded from disk %s." CR), fname.c_str());
}
+#if LOG_LEVEL == 6
+ //Log.verbose(F("TPL : Base '%s'." CR), baseTemplate.c_str());
+#endif
+
// Insert data into template.
transform(baseTemplate);
+
+#if LOG_LEVEL == 6
+ //Log.verbose(F("TPL : Transformed '%s'." CR), baseTemplate.c_str());
+#endif
+
return baseTemplate;
}
diff --git a/src/templating.hpp b/src/templating.hpp
index 0aee648..2e7b99f 100644
--- a/src/templating.hpp
+++ b/src/templating.hpp
@@ -60,6 +60,7 @@ SOFTWARE.
extern const char iSpindleFormat[] PROGMEM;
extern const char brewfatherFormat[] PROGMEM;
extern const char influxDbFormat[] PROGMEM;
+extern const char mqttFormat[] PROGMEM;
// Classes
class TemplatingEngine {
diff --git a/src/webserver.cpp b/src/webserver.cpp
index 317b39c..6b9acb8 100644
--- a/src/webserver.cpp
+++ b/src/webserver.cpp
@@ -360,7 +360,7 @@ void WebServerHandler::webHandleConfigPush() {
myConfig.setInfluxDb2PushToken(
_server->arg(PARAM_PUSH_INFLUXDB2_AUTH).c_str());
myConfig.setMqttUrl(_server->arg(PARAM_PUSH_MQTT).c_str());
- myConfig.setMqttTopic(_server->arg(PARAM_PUSH_MQTT_TOPIC).c_str());
+ myConfig.setMqttPort(_server->arg(PARAM_PUSH_MQTT_PORT).c_str());
myConfig.setMqttUser(_server->arg(PARAM_PUSH_MQTT_USER).c_str());
myConfig.setMqttPass(_server->arg(PARAM_PUSH_MQTT_PASS).c_str());
myConfig.saveFile();
@@ -685,13 +685,13 @@ void WebServerHandler::webHandleConfigFormatRead() {
if (s.length())
doc[PARAM_FORMAT_HTTP1] = urlencode(s);
else
- doc[PARAM_FORMAT_HTTP1] = urlencode(&iSpindleFormat[0]);
+ doc[PARAM_FORMAT_HTTP1] = urlencode(String(&iSpindleFormat[0]));
s = readFile(TPL_FNAME_HTTP2);
if (s.length())
doc[PARAM_FORMAT_HTTP2] = urlencode(s);
else
- doc[PARAM_FORMAT_HTTP2] = urlencode(&iSpindleFormat[0]);
+ doc[PARAM_FORMAT_HTTP2] = urlencode(String(&iSpindleFormat[0]));
/*s = readFile(TPL_FNAME_BREWFATHER);
if (s.length())
@@ -703,13 +703,13 @@ void WebServerHandler::webHandleConfigFormatRead() {
if (s.length())
doc[PARAM_FORMAT_INFLUXDB] = urlencode(s);
else
- doc[PARAM_FORMAT_INFLUXDB] = urlencode(&influxDbFormat[0]);
+ doc[PARAM_FORMAT_INFLUXDB] = urlencode(String(&influxDbFormat[0]));
s = readFile(TPL_FNAME_MQTT);
if (s.length())
doc[PARAM_FORMAT_MQTT] = urlencode(s);
else
- doc[PARAM_FORMAT_MQTT] = urlencode(&iSpindleFormat[0]);
+ doc[PARAM_FORMAT_MQTT] = urlencode(String(&mqttFormat[0]));
#if LOG_LEVEL == 6 && !defined(WEB_DISABLE_LOGGING)
serializeJson(doc, Serial);
diff --git a/src_docs/source/configuration.rst b/src_docs/source/configuration.rst
index 9157a8b..1ceb599 100644
--- a/src_docs/source/configuration.rst
+++ b/src_docs/source/configuration.rst
@@ -144,11 +144,9 @@ Push Settings
IP or name of server to send data to. Format used :ref:`data-formats-ispindle`
- If you add the suffix `:8883` to the server name, then the device will use SSL when sending data.
+* **MQTT Port:**
-* **MQTT Topic:**
-
- Name of topic to publish sensor readings to, iSpindle format is used.
+ Which port should be used for communication, default is 1883 (standard port). For SSL use 8883 (any port over 8000 is treated as SSL).
* **MQTT user:**
@@ -368,7 +366,7 @@ Other parameters are the same as in the configuration guide.
"influxdb2-bucket": "Qwerty",
"influxdb2-auth": "Qwerty",
"mqtt-push": "192.168.1.50",
- "mqtt-topic": "Qwerty",
+ "mqtt-port": 1883,
"mqtt-user": "Qwerty",
"mqtt-pass": "Qwerty",
"sleep-interval": 30,
@@ -493,7 +491,7 @@ Used to update push settings via an HTTP POST command. Payload is in JSON format
"influxdb2-bucket": "Qwerty",
"influxdb2-auth": "Qwerty"
"mqtt-push": "192.168.1.50",
- "mqtt-topic": "Qwerty",
+ "mqtt-port": 1883,
"mqtt-user": "Qwerty",
"mqtt-pass": "Qwerty",
}
@@ -607,7 +605,7 @@ present or the API call will fail.
"influxdb2-bucket": "",
"influxdb2-auth": "",
"mqtt-push": "192.168.1.50",
- "mqtt-topic": "Qwerty",
+ "mqtt-port": 1883,
"mqtt-user": "Qwerty",
"mqtt-pass": "Qwerty"
}
@@ -739,6 +737,39 @@ This is the format template used to create the json above.
measurement,host=${mdns},device=${id},temp-format=${temp-unit},gravity-format=${gravity-unit} gravity=${gravity},corr-gravity=${corr-gravity},angle=${angle},temp=${temp},battery=${battery},rssi=${rssi}
+MQTT
+====
+
+This is the format used to send data to MQTT. Each of the lines are specific topics
+
+.. code-block::
+
+ ispindel/device_name/tilt 89.96796
+ ispindel/device_name/temperature 21.375
+ ispindel/device_name/temp_units C
+ ispindel/device_name/battery 0.04171
+ ispindel/device_name/gravity 33.54894
+ ispindel/device_name/interval 1
+ ispindel/device_name/RSSI -58
+
+
+This is the format template used to create the json above.
+
+.. tip::
+
+ Each line in the format is treated as one topic. The `|` is used as separator between lines and `:` between topic and value. Each line is formatted as `:`
+
+.. code-block::
+
+ ispindel/${mdns}/tilt:${angle}|
+ ispindel/${mdns}/temperature:${temp}|
+ ispindel/${mdns}/temp_units:${temp-unit}|
+ ispindel/${mdns}/battery:${battery}|
+ ispindel/${mdns}/gravity:${gravity}|
+ ispindel/${mdns}/interval:${sleep-interval}|
+ ispindel/${mdns}/RSSI:${rssi}|
+
+
version.json
============
diff --git a/test/config.json b/test/config.json
index 73b4278..3186747 100644
--- a/test/config.json
+++ b/test/config.json
@@ -11,7 +11,7 @@
"influxdb2-bucket": "spann",
"influxdb2-auth": "OijkU((jhfkh",
"mqtt-push": "192.168.1.10",
- "mqtt-topic": "mytopic",
+ "mqtt-port": 1883,
"mqtt-user": "user",
"mqtt-pass": "pass",
"sleep-interval": 30,
diff --git a/test/format.json b/test/format.json
index 459e80d..e2c7c21 100644
--- a/test/format.json
+++ b/test/format.json
@@ -2,7 +2,6 @@
"id": "7376ef",
"http-1": "%7B%22name%22%20%3A%20%22gravmon%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22gravmon%22%2C%20%22interval%22%3A%20%24%7Bsleep%2Dinterval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp%2Dunits%22%3A%20%22%24%7Btemp%2Dunit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22rssi%22%3A%20%24%7Brssi%7D%2C%20%22corr%2Dgravity%22%3A%20%24%7Bcorr%2Dgravity%7D%2C%20%22gravity%2Dunit%22%3A%20%22%24%7Bgravity%2Dunit%7D%22%2C%20%22run%2Dtime%22%3A%20%24%7Brun%2Dtime%7D%20%7D",
"http-2": "%7B%22name%22%20%3A%20%22gravmon%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22gravmon%22%2C%20%22interval%22%3A%20%24%7Bsleep%2Dinterval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp%2Dunits%22%3A%20%22%24%7Btemp%2Dunit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22rssi%22%3A%20%24%7Brssi%7D%2C%20%22corr%2Dgravity%22%3A%20%24%7Bcorr%2Dgravity%7D%2C%20%22gravity%2Dunit%22%3A%20%22%24%7Bgravity%2Dunit%7D%22%2C%20%22run%2Dtime%22%3A%20%24%7Brun%2Dtime%7D%20%7D",
- "brewfather": "%7B%22name%22%3A%20%22%24%7Bmdns%7D%22%2C%22temp%22%3A%20%24%7Btemp%7D%2C%20%22aux%5Ftemp%22%3A%200%2C%20%22ext%5Ftemp%22%3A%200%2C%20%22temp%5Funit%22%3A%20%22%24%7Btemp%2Dunit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22gravity%5Funit%22%3A%20%22%24%7Bgravity%2Dunit%7D%22%2C%20%22pressure%22%3A%200%2C%20%22pressure%5Funit%22%3A%20%22PSI%22%2C%20%22ph%22%3A%200%2C%20%22bpm%22%3A%200%2C%20%22comment%22%3A%20%22%22%2C%20%22beer%22%3A%20%22%22%2C%20%22battery%22%3A%20%24%7Bbattery%7D%7D",
"influxdb": "measurement%2Chost%3D%24%7Bmdns%7D%2Cdevice%3D%24%7Bid%7D%2Ctemp%2Dformat%3D%24%7Btemp%2Dunit%7D%2Cgravity%2Dformat%3D%24%7Bgravity%2Dunit%7D%20gravity%3D%24%7Bgravity%7D%2Ccorr%2Dgravity%3D%24%7Bcorr%2Dgravity%7D%2Cangle%3D%24%7Bangle%7D%2Ctemp%3D%24%7Btemp%7D%2Cbattery%3D%24%7Bbattery%7D%2Crssi%3D%24%7Brssi%7D%0A",
- "mqtt": "%7B%22name%22%20%3A%20%22gravmon%22%2C%20%22ID%22%3A%20%22%24%7Bid%7D%22%2C%20%22token%22%20%3A%20%22gravmon%22%2C%20%22interval%22%3A%20%24%7Bsleep%2Dinterval%7D%2C%20%22temperature%22%3A%20%24%7Btemp%7D%2C%20%22temp%2Dunits%22%3A%20%22%24%7Btemp%2Dunit%7D%22%2C%20%22gravity%22%3A%20%24%7Bgravity%7D%2C%20%22angle%22%3A%20%24%7Bangle%7D%2C%20%22battery%22%3A%20%24%7Bbattery%7D%2C%20%22rssi%22%3A%20%24%7Brssi%7D%2C%20%22corr%2Dgravity%22%3A%20%24%7Bcorr%2Dgravity%7D%2C%20%22gravity%2Dunit%22%3A%20%22%24%7Bgravity%2Dunit%7D%22%2C%20%22run%2Dtime%22%3A%20%24%7Brun%2Dtime%7D%20%7D"
+ "mqtt": "ispindel%2F%24%7Bmdns%7D%2Ftilt%3A%24%7Bangle%7D%7Cispindel%2F%24%7Bmdns%7D%2Ftemperature%3A%24%7Btemp%7D%7Cispindel%2F%24%7Bmdns%7D%2Ftemp%5Funits%3A%24%7Btemp%2Dunit%7D%7Cispindel%2F%24%7Bmdns%7D%2Fbattery%3A%24%7Bbattery%7D%7Cispindel%2F%24%7Bmdns%7D%2Fgravity%3A%24%7Bgravity%7D%7Cispindel%2F%24%7Bmdns%7D%2Finterval%3A%24%7Bsleep%2Dinterval%7D%7Cispindel%2F%24%7Bmdns%7D%2FRSSI%3A%24%7Brssi%7D%7C"
}
\ No newline at end of file
diff --git a/test/upload.json b/test/upload.json
index 10d8f2b..f2dd325 100644
--- a/test/upload.json
+++ b/test/upload.json
@@ -3,5 +3,6 @@
"device": false,
"config": false,
"calibration": false,
+ "format": false,
"about": true
}
\ No newline at end of file