Intro
I’ve been trying out various technologies for my temperature monitoring project, but all of them have been more or less unstable. The python solution is by far the most robust, but can lose connection to the MQTT broker, and stubbornly refuse to reconnect by itself. The Node-RED solution is, while fast to write, notoriously unstable regarding MQTT connections. Connections sit “idle” showing a connected state, while in fact they are disconnected, and there is no obvious way of reconnecting it - apart from restarting the docker container.
The solution
At my day job we use Apache Camel for integrations, so i figured I’d eat my own dog food for once, and try to set it up. Normally i tend to avoid using anything Java based at home, since Java carries a heavy price tag once you start using the more “enterprise” features like Hibernate.
I based my app on Spring Boot for easy access to Jolokia and Hawt.io for monitoring.
My first problem was that Hibernate doesn’t support SQLite “out of the box”, and after searching around i settled on the H2 embedded database.
After much trial and error, i finally had a complete basic setup.
For a basic idea on how Camel looks, here’s my main route that listens on a MQTT topic, and implements a content based router, that routes the parsed message to the next processing step
@Component
public class SurveillanceTopicRoute extends SpringRouteBuilder {
@Autowired
String mqttHost;
@Override
public void configure() throws Exception {
from("mqtt://temperature?host=tcp://"+mqttHost+"&subscribeTopicNames=/surveillance/temperature/#")
.routeId("SurveillanceTopicRoute")
.setExchangePattern(ExchangePattern.InOnly)
.unmarshal().json(JsonLibrary.Gson, Map.class)
.process(new NotificationParserProcessor())
.choice()
.when(exchangeProperty("operationType").isEqualTo("reading"))
.to("direct:registerReading")
.when(exchangeProperty("operationType").isEqualTo("register_sensor"))
.to("direct:registerSensor")
.otherwise()
.throwException(new RuntimeException("Unknown object type ${exchange[operationType]}"))
.end();
}
}
Hawt.IO
Now with Hawt.IO i can monitor how things are going
And even get a graphical representation of how my route looks
Hawt.IO also allows me to monitor system performance, though i prefer regular UNIX tools for that.
Conclusion
I’ve been running the Apache Camel solution alongside both the Python and Node-RED solutions, and so far the Camel solution is the only solution that hasn’t required any restarts.
It is also the most resource expensive solution. Camel requires roughly 60 seconds to start up on my RPi 2, where python is almost instant, and Node-RED takes 10-15 seconds.
On the RAM side things aren’t looking bright either. Python weighs in at around 32 MB RAM used, followed by Node-RED at 96 MB RAM, and Camel+Spring Boot at a whooping 182MB RAM.
CPU wise they seem to be more or less similar. I guess a little RAM is a cheap price to pay for an otherwise rock stable solution.
I’ve killed the Node-RED implementation. I’ve gone through two upgrades, and each and every one has been a pain. Node-RED module location switches places, and aren’t auto loaded from context (you have to explicitly configure which modules to load), meaning i have to manually configure it every time a new version is released.
The python implementation lives on a little while longer. Mostly because i’m stubborn and want to try to fix the MQTT connectivity issues - if they’re an error on my part.
As for Camel, it runs 24/7. A new feature in Apache Camel 2.17 is the remote shell which i’m looking forward to trying out. It looks like it could be real useful in daily maintenance.