Sixfab Power HAT & vcgencmd: not found

Hi guys, perhaps someone has some advice here. I have the excellent Sixfab Power HAT and have used their power_api python library on a vanilla (non Balenafied) Raspberry Pi 4 with Raspberry Pi OS and it worked flawlessly so I was excited to bundle it up into a container and run it along side my other apps, however I keep running into the errors below.

I believe it may have something to do with FROM image (see below) I’m using that may not include the same libraries as the Pi OS out of the box, but I can’t tell where to turn. Any ideas?
The only clue I could find is another user on another forum said: vcgencmd is part of the libraspberrypi-bin package.

    [Logs]    [3/8/2021, 2:10:18 PM] [battman] ************* System Sensors **************
    [Logs]    [3/8/2021, 2:10:18 PM] [battman] /bin/sh: 1: vcgencmd: not found
    [Logs]    [3/8/2021, 2:10:18 PM] [battman] Traceback (most recent call last):
    [Logs]    [3/8/2021, 2:10:18 PM] [battman]   File "main.py", line 31, in <module>
    [Logs]    [3/8/2021, 2:10:18 PM] [battman]     print("System Temp: " + str(sixfab.get_system_temp()))
    [Logs]    [3/8/2021, 2:10:18 PM] [battman]   File "/root/.local/lib/python3.6/site-packages/power_api/power_api.py", line 196, in get_system_temp
    [Logs]    [3/8/2021, 2:10:18 PM] [battman]     return float(temp[:-3])
    [Logs]    [3/8/2021, 2:10:18 PM] [battman] ValueError: could not convert string to float: 

Dockerfile.template

FROM balenalib/%%BALENA_MACHINE_NAME%%-debian-python:3-build as build

RUN mkdir /install

WORKDIR /install

COPY requirements.txt /requirements.txt

ENV PATH=/root/.local/bin:$PATH

RUN pip3 install --user -r /requirements.txt

FROM balenalib/%%BALENA_MACHINE_NAME%%-debian-python:3-run

COPY --from=build /root/.local /root/.local

ENV PATH=/root/.local/bin:$PATH

WORKDIR /app

COPY ./main.py .

COPY ./start.sh .

# Enable udevd so that plugged dynamic hardware devices show up in our container.

ENV UDEV=1

# watch out for modprobe here

CMD ["/bin/sh","./start.sh"]

main.py

from power_api import SixfabPower
from datadog import initialize, statsd
import time

sixfab = SixfabPower()

## Point to DogStatsD agent
options = {
    'statsd_host':'127.0.0.1',
    'statsd_port':8125
}

while True:
    print("************* Input Sensors **************")
    print("Input Temp: " + str(sixfab.get_input_temp()))
    print("Input Voltage: " + str(sixfab.get_input_voltage()))
    print("Input Current: " + str(sixfab.get_input_current()))
    print("Input Power: " + str(sixfab.get_input_power()))             
    time.sleep(1)

    print("Pushing input sensors to Datadog ...")
    statsd.gauge('sfpower.input_temp.gauge', sixfab.get_input_temp())
    statsd.gauge('sfpower.input_voltage.gauge', sixfab.get_input_voltage())
    statsd.gauge('sfpower.input_current.gauge', sixfab.get_input_current())
    statsd.gauge('sfpower.input_power.gauge', sixfab.get_input_power())
    time.sleep(1)
    print("Done.")
    time.sleep(1)

    print("************* System Sensors **************")
    print("System Temp: " + str(sixfab.get_system_temp()))
    print("System Voltage: " + str(sixfab.get_system_voltage()))
    print("System Current: " + str(sixfab.get_system_current()))        #Required delay #default 50
    print("System Power: " + str(sixfab.get_system_power()))  
    time.sleep(1)

    print("Pushing system sensors to Datadog ...")
    statsd.gauge('sfpower.system_temp.gauge', sixfab.get_system_temp())
    statsd.gauge('sfpower.system_voltage.gauge', sixfab.get_system_voltage())
    statsd.gauge('sfpower.system_current.gauge', sixfab.get_system_current())
    statsd.gauge('sfpower.system_power.gauge', sixfab.get_system_power())
    time.sleep(1)
    print("Done.")
    time.sleep(1)

    print("************* Battery **************")
    print("Battery Temp: " + str(sixfab.get_battery_temp()))
    print("Battery Voltage: " + str(sixfab.get_battery_voltage()))
    print("Battery Current: " + str(sixfab.get_battery_current()))
    print("Battery Power: " + str(sixfab.get_battery_power()))
    print("Battery Level: " + str(sixfab.get_battery_level()))
    print("Battery Health: " + str(sixfab.get_battery_health()))
    time.sleep(1)

    print("Pushing battery sensors to Datadog ...")
    statsd.gauge('sfpower.battery_temp.gauge', sixfab.get_battery_temp())
    statsd.gauge('sfpower.battery_voltage.gauge', sixfab.get_battery_voltage())
    statsd.gauge('sfpower.battery_current.gauge', sixfab.get_battery_current())
    statsd.gauge('sfpower.battery_power.gauge', sixfab.get_battery_power())
    statsd.gauge('sfpower.battery_level.gauge', sixfab.get_battery_level())
    statsd.gauge('sfpower.battery_health.gauge', sixfab.get_battery_health())
    time.sleep(1)
    print("Done.")
    time.sleep(1)

    print("************* Fan **************")
    print("Fan Health: " + str(sixfab.get_fan_health()))
    print("Fan Speed: " + str(sixfab.get_fan_speed()))
    time.sleep(1)

    print("Pushing fan sensors to Datadog ...")
    statsd.gauge('sfpower.fan_health.gauge', sixfab.get_fan_health())
    statsd.gauge('sfpower.fan_speed.gauge', sixfab.get_fan_speed())
    time.sleep(1)
    print("Done.")
    time.sleep(1)

Update: Good news, I was able to get it working by disabling the sixfab temp calls (on input sensor, system sensor, and battery sensors).
vcgencmd is not installed by default, and doing apt-get install vcgencmd on a debian image fails because the apt package can’t be found.
I could just leave it at that, but I think there is a way to install via pip: vcgencmd · PyPI
So I’ll give that a shot and share here, in case anyone else runs into this problem.

@barryjump Nice work! Thanks for raising this and glad to hear you fixed it by disabling the sixfab temp calls. Interested to hear how the install via pip goes, fingers crossed!

No luck on pip install method. Strangely I get the same error that the package is missing, even after confirming in the build logs that it was installed. hmm…

@Jazzagi I’m wondering if it conflicts with balena cloud’s temperature calls for the web UI?

edit: duh, I forgot I’m on openbalena not Balena Cloud which doesn’t have a web ui, which presumably means its not collecting system metrics like cpu temp.

Hey @barryjump

Actually, Openbalena devices should be able to access those metrics using the cli, SDK or even via the API directly.

There’s more about using the balenadevice uuid command on the cli in the docs here - balena CLI Documentation - Balena Documentation

Let us know how you get on!