Compare commits

...

4 Commits
0.5.0 ... 0.5.1

Author SHA1 Message Date
hsaturn
f122d5e902 relase 0.5.1 2021-03-25 01:26:27 +01:00
hsaturn
d63793cf77 Avoid to use message member, minor changes 2021-03-25 01:26:03 +01:00
hsaturn
8386779e92 tinytest great enhancements 2021-03-25 01:24:46 +01:00
hsaturn
1b988a06a2 Relase 0.5.0 2021-03-24 21:21:46 +01:00
6 changed files with 164 additions and 42 deletions

View File

@@ -2,10 +2,33 @@
Exemple of commands that can be sent via the serial monitor to tinymqtt-test Exemple of commands that can be sent via the serial monitor to tinymqtt-test
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Commands can usually be abbreviated to their first letters.
ex: cl for client, a / a.con / a.sub / a.p for publish.
set name value set variable name to value (later replaced)
set name if no value, then var is erased
set view all vars
reserved keywords are forbidden
client a starts a client (not connected no internal broker) client a starts a client (not connected no internal broker)
a.connect [server][port][alive] connects the client, default port=1883 a.connect [server][port][alive] connects the client, default port=1883
a.publish topic [payload] send a topic with a payload a.publish topic [payload] send a topic with a payload
a.subscribe topic subscribes to a topic a.subscribe topic subscribes to a topic
delete a destroy the client delete a destroy the client
----------------------------------------------------
example:
client c
c.connect broker.emqx.io
set topic sensor/temperature
c.subscribe topic
c.publish topic 15
c.publish topic 20
macro exansion example
set temp publish sensor/temperature
c.temp 20 -> c.publish sensor/temperature 20

View File

@@ -78,6 +78,71 @@ std::string getword(std::string& str, const char* if_empty=nullptr, char sep=' '
return sword; return sword;
} }
std::map<std::string, std::string> vars;
std::set<std::string> commands = {
"auto", "broker", "client", "connect",
"create", "delete", "help", "interval",
"ls", "ip", "off", "on", "set",
"publish", "reset", "subscribe", "view"
};
void getCommand(std::string& search)
{
while(search[0]==' ') search.erase(0,1);
if (search.length()==0) return;
std::string matches;
int count=0;
for(std::string cmd: commands)
{
if (cmd.substr(0, search.length()) == search)
{
if (count) matches +=", ";
count++;
matches += cmd;
}
}
if (count==1)
search = matches;
else if (count>1)
{
Serial << "Ambiguous command: " << matches << endl;
search="";
}
}
void replace(const char* d, std::string& str, std::string srch, std::string to)
{
if (d[0] && d[1])
{
srch=d[0]+srch+d[1];
to=d[0]+to+d[1];
size_t pos = 0;
while((pos=str.find(srch, pos)) != std::string::npos)
{
str.erase(pos, srch.length());
str.insert(pos, to);
pos += to.length();
}
}
}
void replaceVars(std::string& cmd)
{
cmd = ' '+cmd+' ';
for(auto it: vars)
{
replace("..", cmd, it.first, it.second);
replace(". ", cmd, it.first, it.second);
replace(" .", cmd, it.first, it.second);
replace(" ", cmd, it.first, it.second);
}
cmd.erase(0, cmd.find_first_not_of(" "));
cmd.erase(cmd.find_last_not_of(" ")+1);
}
// publish at regular interval // publish at regular interval
class automatic class automatic
{ {
@@ -180,6 +245,7 @@ class automatic
{ {
Serial << " auto [$id] on/off" << endl; Serial << " auto [$id] on/off" << endl;
Serial << " auto [$id] view" << endl; Serial << " auto [$id] view" << endl;
Serial << " auto [$id] interval [s]" << endl;
Serial << " auto [$id] create [millis] [topic]" << endl; Serial << " auto [$id] create [millis] [topic]" << endl;
} }
@@ -219,12 +285,16 @@ void loop()
if (c==10 or c==14) if (c==10 or c==14)
{ {
Serial << "----------------[ " << cmd.c_str() << " ]--------------" << endl; Serial << "----------------[ " << cmd.c_str() << " ]--------------" << endl;
static std::string last_cmd; static std::string last_cmd;
if (cmd=="!") if (cmd=="!")
cmd=last_cmd; cmd=last_cmd;
else else
last_cmd=cmd; last_cmd=cmd;
replaceVars(cmd);
Serial << "---------------@[ " << cmd.c_str() << " ]--------------" << endl;
while(cmd.length()) while(cmd.length())
{ {
MqttError retval = MqttOk; MqttError retval = MqttOk;
@@ -235,27 +305,34 @@ void loop()
// client.function notation // client.function notation
// ("a.fun " becomes "fun a ") // ("a.fun " becomes "fun a ")
if (cmd.find('.') != std::string::npos) if (cmd.find('.') != std::string::npos &&
cmd.find('.') < cmd.find(' '))
{ {
s=getword(cmd, nullptr, '.'); s=getword(cmd, nullptr, '.');
if (clients.find(s) != clients.end()) if (s.length())
{ {
client = clients[s]; if (clients.find(s) != clients.end())
} {
else if (brokers.find(s) != brokers.end()) client = clients[s];
{ }
broker = brokers[s]; else if (brokers.find(s) != brokers.end())
} {
else broker = brokers[s];
{ }
Serial << "Unknown class (" << s.c_str() << ")" << endl; else
cmd=""; {
Serial << "Unknown class (" << s.c_str() << ")" << endl;
cmd="";
}
} }
} }
s = getword(cmd); s = getword(cmd);
if (compare(s, "delete")) if (s.length()) getCommand(s);
if (s.length()==0)
{}
else if (compare(s, "delete"))
{ {
if (client==nullptr && broker==nullptr) if (client==nullptr && broker==nullptr)
{ {
@@ -384,6 +461,32 @@ void loop()
Serial << "Missing or existing client name" << endl; Serial << "Missing or existing client name" << endl;
cmd+=" ls"; cmd+=" ls";
} }
else if (compare(s, "set"))
{
std::string name(getword(cmd));
if (name.length()==0)
{
for(auto it: vars)
{
Serial << " " << it.first << " -> " << it.second << endl;
}
}
else if (commands.find(name) != commands.end())
{
Serial << "Reserved keyword (" << name << ")" << endl;
cmd.clear();
}
else
{
if (cmd.length())
{
vars[name] = cmd;
cmd.clear();
}
else if (vars.find(name) != vars.end())
vars.erase(vars.find(name));
}
}
else if (compare(s, "ls") or compare(s, "view")) else if (compare(s, "ls") or compare(s, "view"))
{ {
Serial << "--< " << clients.size() << " client/s. >--" << endl; Serial << "--< " << clients.size() << " client/s. >--" << endl;
@@ -421,6 +524,7 @@ void loop()
Serial << endl; Serial << endl;
Serial << " help" << endl; Serial << " help" << endl;
Serial << " ls / ip / reset" << endl; Serial << " ls / ip / reset" << endl;
Serial << " set [name][value]" << endl;
Serial << " ! repeat last command" << endl; Serial << " ! repeat last command" << endl;
Serial << endl; Serial << endl;
Serial << " $id : name of the client." << endl; Serial << " $id : name of the client." << endl;

View File

@@ -6,7 +6,7 @@
"type": "git", "type": "git",
"url": "https://github.com/hsaturn/TinyMqtt.git" "url": "https://github.com/hsaturn/TinyMqtt.git"
}, },
"version": "0.4.0", "version": "0.5.1",
"exclude": "", "exclude": "",
"examples": "examples/*/*.ino", "examples": "examples/*/*.ino",
"frameworks": "arduino", "frameworks": "arduino",

View File

@@ -1,5 +1,5 @@
name=TinyMqtt name=TinyMqtt
version=0.4.0 version=0.5.1
author=Francois BIOT, HSaturn, <hsaturn@gmail.com> author=Francois BIOT, HSaturn, <hsaturn@gmail.com>
maintainer=Francois BIOT, HSaturn, <hsaturn@gmail.com> maintainer=Francois BIOT, HSaturn, <hsaturn@gmail.com>
sentence=A tiny broker and client library for MQTT messaging. sentence=A tiny broker and client library for MQTT messaging.

View File

@@ -69,18 +69,18 @@ void MqttClient::connect(std::string broker, uint16_t port, uint16_t ka)
if (client->connect(broker.c_str(), port)) if (client->connect(broker.c_str(), port))
{ {
debug("cnx: connecting"); debug("cnx: connecting");
message.create(MqttMessage::Type::Connect); MqttMessage msg(MqttMessage::Type::Connect);
message.add("MQTT",4); msg.add("MQTT",4);
message.add(0x4); // Mqtt protocol version 3.1.1 msg.add(0x4); // Mqtt protocol version 3.1.1
message.add(0x0); // Connect flags TODO user / name msg.add(0x0); // Connect flags TODO user / name
keep_alive = ka; // TODO not configurable keep_alive = ka;
message.add(0x00); // keep_alive msg.add(0x00); // keep_alive
message.add((char)keep_alive); msg.add((char)keep_alive);
message.add(clientId); msg.add(clientId);
debug("cnx: mqtt connecting"); debug("cnx: mqtt connecting");
message.sendTo(this); msg.sendTo(this);
message.reset(); msg.reset();
debug("cnx: mqtt sent " << (int32_t)parent); debug("cnx: mqtt sent " << (int32_t)parent);
clientAlive(0); clientAlive(0);
@@ -339,21 +339,22 @@ if (message.type() != MqttMessage::Type::PingReq && message.type() != MqttMessag
Serial << "Connected client:" << clientId.c_str() << ", keep alive=" << keep_alive << '.' << endl; Serial << "Connected client:" << clientId.c_str() << ", keep alive=" << keep_alive << '.' << endl;
bclose = false; bclose = false;
mqtt_connected=true; mqtt_connected=true;
// Reuse received msg {
message.create(MqttMessage::Type::Connack); MqttMessage msg(MqttMessage::Type::ConnAck);
message.add(0); // Session present (not implemented) msg.add(0); // Session present (not implemented)
message.add(0); // Connection accepted msg.add(0); // Connection accepted
message.sendTo(this); msg.sendTo(this);
}
break; break;
case MqttMessage::Type::Connack: case MqttMessage::Type::ConnAck:
// TODO what more on connack ? // TODO what more on connack ?
mqtt_connected = true; mqtt_connected = true;
bclose = false; bclose = false;
break; break;
case MqttMessage::Type::Suback: case MqttMessage::Type::SubAck:
case MqttMessage::Type::Puback: case MqttMessage::Type::PubAck:
if (!mqtt_connected) break; if (!mqtt_connected) break;
// Ignore acks // Ignore acks
bclose = false; bclose = false;
@@ -429,11 +430,6 @@ if (message.type() != MqttMessage::Type::PingReq && message.type() != MqttMessag
} }
break; break;
case MqttMessage::Type::PubAck:
if (!mqtt_connected) break;
bclose = false;
break;
default: default:
bclose=true; bclose=true;
break; break;
@@ -462,8 +458,7 @@ bool Topic::matches(const Topic& topic) const
// publish from local client // publish from local client
MqttError MqttClient::publish(const Topic& topic, const char* payload, size_t pay_length) MqttError MqttClient::publish(const Topic& topic, const char* payload, size_t pay_length)
{ {
MqttMessage msg; MqttMessage msg(MqttMessage::Publish);
msg.create(MqttMessage::Publish);
msg.add(topic); msg.add(topic);
msg.add(payload, pay_length, false); msg.add(payload, pay_length, false);
if (parent) if (parent)

View File

@@ -41,11 +41,11 @@ class MqttMessage
{ {
Unknown = 0, Unknown = 0,
Connect = 0x10, Connect = 0x10,
Connack = 0x20, ConnAck = 0x20,
Publish = 0x30, Publish = 0x30,
PubAck = 0x40, PubAck = 0x40,
Subscribe = 0x80, Subscribe = 0x80,
Suback = 0x90, SubAck = 0x90,
PingReq = 0xC0, PingReq = 0xC0,
PingResp = 0xD0, PingResp = 0xD0,
}; };