Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set configuration options and settings via MQTT (Telnet-MQTT-proxy?) ? #1505

Closed
schweini opened this issue Jan 23, 2019 · 12 comments
Closed
Labels
Milestone

Comments

@schweini
Copy link

I have a couple of espurna-powered Sonoff POWs deployed 'in the wild'. They are behind different types of NATs and firewalls, and usually impossible to access 'from the outside'. When I set them up, I just make sure that they can connect to my MQTT server, and let them be.

Is there some way to set (and save) configuration parameters (secondary wifi network, sensor configuration, etc.) via MQTT messages? This would be a very useful feature, since MQTT bypasses the whole NAT issue.

Maybe a MQTT-telnet-proxy topic I could send telnet commands to, and get telnet responses back? IIRC, everything can be done over telnet, so that would allow everything to be set via MQTT, too?

@schweini schweini changed the title set configuration options ans settings via MQTT? set configuration options and settings via MQTT (Telnet-MQTT-proxy?) ? Jan 23, 2019
@mcspr
Copy link
Collaborator

mcspr commented Jan 26, 2019

Maybe not directly terminal commands, but tbh that would be interesting thing to have. Currently this is what I am trying with Home Assistant, discovery mechanism replaced bunch of manual config entries. Two problems though:

  • right now espurna ignores messages that are retained (or sent immediately on connection by some luck), which would be the most useful thing for this to have config immediately, even share it with multiple devices using common naming scheme.
  • these settings most preferably should go inside single topic+message instead of multiple ones and should be packed and unpacked using json / msgpack / something else (see domoticz, homeassistant light.mqtt and others)

@mcspr mcspr mentioned this issue Mar 17, 2019
@stale
Copy link

stale bot commented Mar 27, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Mar 27, 2019
@schweini
Copy link
Author

schweini commented Mar 27, 2019 via email

@stale stale bot removed the stale label Mar 27, 2019
@mcspr
Copy link
Collaborator

mcspr commented Mar 28, 2019

Also depends on #1234, because we may need to buffer incoming messages (e.g. we send whole config)
Basic idea is still the same - subscribe to a specific topic and apply all kv pairs as settings?

@schweini
Copy link
Author

schweini commented Mar 28, 2019 via email

@schweini
Copy link
Author

schweini commented Apr 5, 2019

Huh.
I just searched around the code, and two interesting things popped up:
uartmqtt.ino seems to be a MQTT-UART-gateway. Maybe this could be used to send "telnet" commands to the serial port?

mqtt.ino
subscribes to the MQTT topic 'actions', and if it received 'reboot', it does just that.
It shouldn't be that hard to find the espurna call for "set configuration key X to Y" and the call for "save config" and add it there.

I'll tryo too find that part some other day, but if someone knows the relevant calls, we could implement this relatively quickly via the /action topic, i think?

@schweini
Copy link
Author

schweini commented Apr 5, 2019

Sorry to use this issue as a notepad of sorts, but:
in telnet.ino, all that seems to be done is to call terminalInject(data, len); with the received line.
So maybe, just maybe, adding terminalInject(data, len); in mqtt.ino could to the whole terminal-MQTT thing. hmm.

@mcspr
Copy link
Collaborator

mcspr commented Apr 22, 2019

Sorry, I was a bit carried away with this.

Yes, that is the way. Action needs to be subtopic though? <root>/action/dbgcmd or something like that.

@stale
Copy link

stale bot commented Jun 21, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@mcspr
Copy link
Collaborator

mcspr commented May 20, 2020

Long overdue... See #2247
ATM with HTTP API enabled, it is possible to call some of the commands (since we need to rewrite all of them to use a different output). Right now only get, set, del, keys, help and eeprom.dump are changed. EEPROM dump is used as a reference, since we output ~16KB of data.

There is a weird distinction between PUT and GET parameter list, as I was only been able to call the device with apiRestFul 0 via curl 'http://10.1.1.2/cmd?apikey=12345&line=eeprom.dump. Something WIP

MQTT is not yet implemented. We need to either patch Async Mqtt Client lib to support streaming payloads or somehow hint about the limit of TCP_MSS (536 or 1460 bytes plain text, minus MQTT header overhead, minus SSL overhead (when used)). One possible option is marvinroger/async-mqtt-client#184
e.g. <root>/cmd dumps output, <root>/cmd/set accepts command line. (with or without the line break)

@mcspr
Copy link
Collaborator

mcspr commented May 20, 2020

Also, for future reference, pubsubclient is the only client atm. that can stream data the same way:
https://github.com/knolleary/pubsubclient/blob/master/examples/mqtt_large_message/mqtt_large_message.ino
edit: But, unlike chunked-encoded HTTP stream, we would need to know the message lengths before sending. Bummer :(

To send really large payploads, this is also is seemingly depends on WiFiClient being in 'sync' mode so that we flush the data periodically without switching out of the Print loop, which is set by the WiFiClient::setDefaultSync(true) (for every client) or _wifi.setSync(true) (instance). It may be very slow though, so we might want to do not use it and add the something similar to the AsyncWebPrint (web.cpp, PR) and AsyncBufferedClient (telnet.cpp, dev) and manage client's Print API, periodically calling yield() / flush() / something that will send the data

arduino-mqtt library has an issue for this specific use case 256dpi/arduino-mqtt#145 (which is still pending)

edit: TODO: check out WriteBufferingStream from https://github.com/bblanchon/ArduinoStreamUtils/ as a possible workaround. It does implement the flush()'ing part

@mcspr
Copy link
Collaborator

mcspr commented May 25, 2020

Experimenting via #2247
TERMINAL_MQTT_SUPPORT=1 will subscribe to the <root>/cmd/set and will try to handle each terminal command, including set / get / del. Sometimes, there will be output to the <root>/cmd, but not always (I also wonder how much this will break...)

Only a single command accepted right now. Batching through \r\n / \n can be easily 'stolen' from the shared terminal loop implementation.

@mcspr mcspr closed this as completed May 25, 2020
@mcspr mcspr added this to the 1.14.2 milestone May 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants