I had the idea to have my DS1820 read and stored to a prometheus service. In the past I had a telegraf service running starting some shell script. As usual the pi and the script died the sd-card death it deserved, so it was time to have a new implementation.

Implementations in shell

#!/bin/sh
cat $1

Runtime in shell

# time ./read_temp.sh /sys/devices/w1_bus_master1/28-011831b1c7ff/temperature
3812

real    0m0.853s
user    0m0.005s
sys 0m0.023s

Implementations in lua

1
2
3
4
5
#!/usr/bin/lua
file = io.open(arg[1], "r")
io.input(file)
print(io.read())
io.close(file)

Runtime in lua

# time ./read_temp.lua /sys/devices/w1_bus_master1/28-011831b1c7ff/temperature
3812

real    0m0.862s
user    0m0.000s
sys 0m0.026s

Implementations in awk

1
2
3
#!/usr/bin/awk -f

{ print "$1" }

Runtime in awk

# time ./read_temp.awk /sys/devices/w1_bus_master1/28-011831b1c7ff/temperature
3750
real    0m0.884s
user    0m0.013s
sys 0m0.012s

Most time is spend reading the sensor, not starting the interpreter. As personal preference, I go with awk.

After some iterations I ended with the following version. We need to first have 2 comment lines telling prometheus what the metric is. Next we read the sensor data and write all sensors to stdout.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/usr/bin/awk -f

BEGIN {
    print "# HELP temperature current temperator."
    print "# TYPE temperature gauge"
}

{
    split(FILENAME,array,"/")
    sensor_id=length(array)-1
    printf("temperature{sensor=\"%s\"} %s\n",array[sensor_id],$1/1000)
}

This is executed periodly via systemd timer every minute and updates the file read by node_exporter.

1
2
3
4
#!/bin/sh
/usr/local/bin/read_temp.awk \
  $(find /sys/devices/w1_bus_master1 -name temperature) \
  > /var/lib/node_exporter/temperature.prom

This makes reading the temperature easy and even if I add mode sensors it dynamically extends.

BUT

# HELP node_hwmon_temp_celsius Hardware monitor for temperature (input)
# TYPE node_hwmon_temp_celsius gauge
node_hwmon_temp_celsius{chip="thermal_thermal_zone0",sensor="temp0"} 34.324
node_hwmon_temp_celsius{chip="thermal_thermal_zone0",sensor="temp1"} 34.862
node_hwmon_temp_celsius{chip="w1_bus_master1_28_011831b1c7ff",sensor="temp1"} 11.375
node_hwmon_temp_celsius{chip="w1_bus_master1_28_0517b24af9ff",sensor="temp1"} 3.0620000000000003
node_textfile_mtime_seconds{file="/var/spool/node_exporter/temperature.prom"} 1.710634991e+09
# HELP node_thermal_zone_temp Zone temperature in Celsius
# TYPE node_thermal_zone_temp gauge
node_thermal_zone_temp{type="cpu-thermal",zone="0"} 34.324
# HELP temperature current temperator.
# TYPE temperature gauge
temperature{sensor="28-011831b1c7ff"} 11.312
temperature{sensor="28-0517b24af9ff"} 3.062

It wasn't expected to find an already working read of sensors, as I used the w1_temp kernel module.