CapnBry / HeaterMeter

HeaterMeter and LinkMeter Arduino BBQ Controller
https://tvwbb.com/forums/heatermeter-diy-bbq-controller.85/
MIT License
499 stars 83 forks source link

Hacking linkmeterd #41

Closed chrissnell closed 6 years ago

chrissnell commented 6 years ago

Hi @CapnBry. Just ordered my HM hardware and I'm super excited to test this.

I've been digging through the source tree with an eye on doing some hacking. My particular interest is modifying the linkmeterd service to support other control mechanisms like gRPC. I'm also not a huge fan of the tight coupling with OpenWRT and I was looking into what it would take to tease linkmeterd away from LuCi. It appears to be pretty tightly coupled.

So, I started thinking about rewriting linkmeterd in Go, completely decoupled from any OpenWRT dependencies. There's a couple of things that I want to better understand:

Thanks!

CapnBry commented 6 years ago

Hi Chris! The issue tracker isn't really the place for a discussion, so after this message if you want to continue discussion, please take it to the forums.

linkmeterd isn't very coupled to OpenWRT at all. It does pull in some of their libraries but those should build on any platform and it would be silly to rewrite them (luci.sys, nixio, and jsonc). It does use UCI to pull in the configuration but honestly that could all be hard coded into the source if needed. It does get more complicated if you start looking at notifications and whatnot because those rely on external linux utilities.

The thing that is tightly coupled is the HTTP interface, which runs the luci framework for generating the web pages. That would all need to be rewritten if you wanted to pry it out of OpenWRT.

The architecture is not very complicated. The atmega spits out data in serial sentences similar to GPS NMEA sentences. It can also receive commands via the keywords found in hmcore.cpp's handleCommandUrl, which are only 3: /set, /reboot, and /config (dump all config). The linkmeterd listens for those and writes them into the RRD file (and plugins and alarm notifications) and publishes them to any connected clients through a UNIX socket. There's lmclient which is just a utility for sending/receiving messages over the UNIX socket. The system there is simple fire-and-forget commands, or subscribe to the status updates (in JSON format).

The serial protocol is simple and segmentMap holds all the known sentences. The first group ($HMxx) are the sentences the atmega sends out, The second ($LMxx) are commands expected to be received over the UNIX socket. The 2x commented out values are UNIX commands accepted by the plugins, and the final one is the command to register a listener which gets the JSON data streamed. All are just COMMAND,param,param,param,...

I don't know what your plans are if you're trying to get rid of OpenWRT, but it would probably be less work to just write a new daemon from scratch that just takes the serial data and puts it into your database of choice using the segmentMap's $HMxx list as the requirements for what sentences to expect from HeaterMeter. None require any responses so it is safe to just ignore what you don't want.

EDIT: Or if you don't mind sticking with OpenWRT, you could just hang another service off linkmeterd that just does a @LMSS to listen for the status updates and convert them over to your preferred RPC mechanism.