Community
OpenEnergyMonitor

Community

CPU loop in mqttsend (part of lwrfmqtt)

Hi there,

I have a new Pi4 and have installed the latest emonSD (Oct 19), and have been setting up lightwaveRF-pi from the OEM github page to control some RF plug sockets. I have used this before on my Pi3, but after installing lightwaveRF on the Pi4, I noticed the mqttsend process (part of the lightwaveRF) using 100% of a CPU, and the Pi4 CPU temperature reached a scary 82 degrees.

I know the Pi4 runs a bit hot, and this one is in a plastic case, but even after taking the lid off, the temperature was still around 75 degrees. I then compared this to my Pi3 running the same emonSD image and lightwaveRF install, and noticed that mqttsend was using 100% of a CPU there as well!

I assumed an issue in the installation of lightwaveRF, and started over with a fresh emonSD image and carefully checked the installation steps, but couldn’t find any mistakes.

After a bunch more digging, I think I may have found the problem. The mqttsend program can be run from the command line, as mentioned in the documentation on github:

To test manually start:

sudo ./mqttsend

When running it this way, it produces a message to the console:

Subscribing to topic lwrf
for client lwrf using QoS1

Press Q to quit

It will then print out any messages sent to the lwrf topic to help with testing. But this mqttsend is also part of lwrfmqtt service that runs all the time looking for messages sent to the lwrf topic, and converts them to OOK commands to be sent to the plug sockets.

In the mqttsend program, within int main, lines 94-97, is a do-while loop that checks if “Q” or “q” has been pressed on the keyboard.

With some very primitive print statements I proved that the program loops around the do-while loop, at the same time that top shows the process using 100% CPU.

I’m not much of a programmer (especially C), but some google searches seem to confirm that a loop that waits for an interrupt like this will be in a tight loop, and consume whatever CPU is available.

The logic of using a key to gracefully close the program makes sense for a program run manually, but this program is executed automatically at startup as part of the lwrfmqtt service, so I don’t see any way of issuing the “Q” anyway?

I did comment out the do-while loop, but the program just ran through int main and completed as there is no other loop to keep it executing. I don’t have the skills in C programming to know how to restructure the program to loop gracefully.

2 questions - anyone else using lightwaveRF and seeing mqttsend with high CPU usage?
Any suggestions on how to change the structure of the programs so it stays active without hogging a CPU (and causing a heat issue).

I believe @glyn.hudson used to use lightwaveRF so hoping he might be able to take a look.

Oh, apologies if this isn’t in the right category but I didn’t know where else to put it, but I am sure the moderators will move it if needed.

Thanks
Ian

I’ve mitigated the high CPU usage by using the renice command to change the Nice value to 19. Although Top still shows mqttsend using 100%, the overall CPU utilisation is around 1%, and Nice is at 25%.

thanks @IanDavies I don’t think the lightwaveRF scripts are being maintained any more, I think @glyn.hudson is thinking of moving away from using it, @glyn.hudson?

Sounds a like a sleep command is needed in the loop.