Domoticz age checker
A script to check the age of sensors.
Sometimes you don’t have a good 433Mhz connection.
Or the battery has died of your sensor.
This script will warn you.
sensoragescript.sh (for cron)
#!/bin/bash #Call as follows #sensoragescript.sh <ipdomoticz> <idx-of-sensor> <age-to-test-in-seconds> now=$(date +%s) lastupdate=$(curl -s -i -H "Accept: application/json" "http://$1:8080/json.htm?type=devices&rid=$2" | grep LastUpdate | cut -f4 -d\" ) #echo $lastupdate seen=$(date -d "$lastupdate" +%s) #echo $seen #echo "$(( $now - $seen))" difftime="$(( $now - $seen))" if [ $difftime -gt $3 ] ; then echo "WARN : too old - $difftime seconds" exit 1 else echo "OK : $difftime seconds" exit 0 fi
Outputs:
./new.sh 192.168.1.1 123 60 OK : 22 seconds ./new.sh 192.168.1.1 123 60 WARN : too old - 69 seconds
check_mk / icinga check
#!/bin/bash IPDOMO=192.168.1.1 IDX=123 agewarn=300 now=$(date +%s) lastupdate=$(curl -s -i -H "Accept: application/json" "http://$IPDOMO:8080/json.htm?type=devices&rid=$IDX" | grep LastUpdate | cut -f4 -d\" ) seen=$(date -d "$lastupdate" +%s) difftime="$(( $now - $seen))" if [ $difftime -gt $agewarn ] ; then echo "1 \"WARN - Age check Fridge\" realage=$difftime|age=$agewarn Age of fridge" exit 1 else echo "0 \"OK - Age check Fridge\" realage=$difftime|age=$agewarn Age of fridge" exit 0 fi
Domotemp – domoticz temperature floorplan
For my home automation i’m using Home Assistant and Domoticz.
All 433Mhz Temperature/Humidity are connected to a RFXcom device on two domoticx instances. (Master slave construction)
I’ve made a php script and a bash script to draw all sensors on a floorplan in realtime.
There is also a cron running which takes a snapshot of the generated image every 5 minutes.
These images are being converted to MP4 and animated GIF to have a timelapse with all temperatures displayed on a floorplan.
The circles are where sensors are placed.
Colors are from blue till red, representing the heat.
In the center is the measured temperature value.
The (shortened) PHP script: (index.php)
<?php header('Content-type: image/png'); // This is the floorplan empty .. $png_image = imagecreatefrompng('plattegrondenmerge.png'); $white = ImageColorAllocate($png_image, 0, 0, 0); $max = 40; $min = -10; // living // getstate is a bash script (see below which gets the values from domoticz using curl) // 840 is the domoticz idx $temp840 = shell_exec('./getstate 840'); // A gray circle will be drawn if the temperature age is > 500 seconds $age = shell_exec('./new.sh 18 840 500 >/dev/null || echo gray'); // location of circle $start_x = 950; $start_y = 760; $line = $temp840 + 10; // get x-th line from colors $colorfromlist = shell_exec("tail --lines=$line ./colors2 | head -1"); if(strpos($age, "gray") !== false){ $colorfromlist = "128,128,128"; }; $colors = explode(",", $colorfromlist); $color = imagecolorallocatealpha($png_image, $colors[0], $colors[1], $colors[2], 50); // draw circle imagefilledellipse ($png_image, $start_x, $start_y, 175, 175, $color); $start_x = $start_x - 70; $start_y = $start_y + 15; // add text imagettftext($png_image, 24, 0, $start_x, $start_y, $white, './verdana.ttf', $temp840); // winecellar $temp840 = shell_exec('./getstate 839'); $age = shell_exec('./new.sh 18 839 700 >/dev/null || echo gray'); $start_x = 560; $start_y = 840; $line = $temp840 + 10; $colorfromlist = shell_exec("tail --lines=$line ./colors2 | head -1"); if(strpos($age, "gray") !== false){ $colorfromlist = "128,128,128"; }; $colors = explode(",", $colorfromlist); $color = imagecolorallocatealpha($png_image, $colors[0], $colors[1], $colors[2], 50); imagefilledellipse ($png_image, $start_x, $start_y, 175, 175, $color); $start_x = $start_x - 70; $start_y = $start_y + 15; imagettftext($png_image, 24, 0, $start_x, $start_y, $white, './verdana.ttf', $temp840); // ETC ETC imagesavealpha($png_image, TRUE); imagepng($png_image); imagedestroy($png_image); ?>
getstate bash script
(gets the temperature from domoticz instance1 given an idx)
#!/bin/bash curl -s --connect-timeout 2 --max-time 5 "http://ip-domoticz1:8080/json.htm?type=devices&rid=$1" | egrep "Temp|Humid" | awk '{print $3 }' | cut -f1 -d\. | grep -v \" | tr -d "\n\r" | sed s/,/%\ /g | awk '{ print $2"° "$1 }'
new.sh script gets the age of the reading from
domoticz1 or domoticz1
Usage: ./new.sh <domoticz-last-numer-ip> <idx> <maxageinseconds>
#!/bin/bash ## server idx time now=$(date +%s) lastupdate=$(curl -s -i -H "Accept: application/json" "http://192.168.1.$1:8080/json.htm?type=devices&rid=$2" | grep LastUpdate | cut -f4 -d\" ) #echo $lastupdate seen=$(date -d "$lastupdate" +%s) #echo $seen #echo "$(( $now - $seen))" difftime="$(( $now - $seen))" if [ $difftime -gt $3 ] ; then echo "WARN : too old - $difftime seconds" exit 1 else echo "OK : $difftime seconds" exit 0 fi
colors2 – a list of colors representing the temperature
red -> green -> blue
255,0,0 255,10,0 255,20,0 255,30,0 255,40,0 255,60,0 255,70,0 255,80,0 255,90,0 255,100,0 255,120,0 255,130,0 255,140,0 255,150,0 255,160,0 255,180,0 255,190,0 255,200,0 255,210,0 255,220,0 255,240,0 255,250,0 253,255,0 215,255,0 176,255,0 101,255,0 62,255,0 23,255,0 0,255,16 0,255,54 0,255,131 0,255,168 0,255,208 0,255,244 0,228,255 0,196,255 0,180,255 0,164,255 0,148,255 0,132,255 0,100,255 0,84,255 0,68,255 0,50,255 0,34,255 0,2,255 0,0,255 1,0,255 2,0,255 3,0,255 5,0,255
Crontab and gif/mp4 generators
# crontab 5 * * * * root /scripts/domotemp/crontemp.sh # crontemp.sh # stores an image with a date. cd /www/webdir/domotemp wget https://mydomoticzweb/domotemp/ -O $(date +%Y%m%d%H).png >/dev/null 2>/dev/null 1>/dev/null # rest scripts mkdir -p embed # below adds the time to the image ls 2020*png | sort -n -k1 | while read ; do hour=$(echo $REPLY | cut -c9,10) ; convert -pointsize 80 -fill black -draw 'text 1650 100 '\"$hour:00\"'' -resize 960x540 $REPLY embed/$REPLY ;done # convert to gif convert $(ls embed/2020*png | sort -n -k1) animation.gif # convert to mp4 ffmpeg -f image2 -r 24 -pattern_type glob -i '*.png' -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast -vf scale=1920:1080 domotemp.mp4
Making Art using 220V
I have a rol of printer paper that was used by an old 8bit computer. I forgot which one, one out of my collection.

I dont think it is thermal paper, maybe the printer uses electricity just like the movie clip you see below. (Well .. not using 220V directly on the paper maybe) 🙂
Work video-call joke
Using OBS and chromakey (greenscreen)
3D Printing
In 2012 I started with 3D printing, I didn’t have my own yet. So it was done using shapeways.
April 2019 I ordered my own, a Creality CR-10S.
Specs
- Build Volume: 300 x 300 x 400mm
- Layer Thickness: 0.1-0.4mm
- Positioning Precision: Z-axis – 0.0025mm, X & Y-axis – 0.015mm
- Nozzle Temperature: 250°C
- Printing Speed: 200mm/s
- Filament Diameter: 1.75mm
- Printer Weight: 9kg
- Printing Filament: PLA, ABS, TPU, Wood, Carbon fiber, etc.
- Input Support: SD card/USB
- File Types: STL/OBJ/G-Code/JPG
- Supports(OS): Windows/Linux/Mac/XP
- Printing Software: Cura/Repetier-Host
- Frame & Body: Imported V-Slot Aluminum Bearings
- Power Requirement Input: AC110V~220V, Output: 12V, Power 270W
- Output: DC12V, 10A 100~120W (Support storage battery)
- Working Condition Temp:10-30°C, Humidity: 20-50%
Problem with this 3D Printer is the lack of a thermal runaway detection. My solution is a MQTT/Nodered warning system which plays an alarm and uses a shelly to disconnect the power.
https://www.henriaanstoot.nl/2022/05/11/mqtt-bash-nodered-notify/
Software I Use – see other posts
- Openscad
- Cura
- Meshroom
- Blender
- Sketchup
Hardware
- Octoprint on a raspberry pi – (with Octoscreen)
- Octoprint monitor
I’m using a filament sensor like the one in below picture
It used to be a DIY thingy using an arduino. (below)
Filament under my table ( in the “dark” )
Software on my mobile
- Octoremote
https://play.google.com/store/apps/details?id=com.kabacon.octoremote
Hints and tips
- Use painters tape against bending of the glass, it will warp because of the heat.
- Use 3D spray to fix model to base-plate.
(I used a gluestick before) - Always think of model placement, less support the better.
- Try to remember which fill-in is the best for your purpose.
- Calibrate distance print tool and glass using printing paper.
- Know your printer, make a lot of test prints when starting.
- Learn / read about 3D printing finishing. Sanding/smoothing/melting.
I’ve got some smoothing liquid (print coating) , a dremel and below tool
- Use a print model to test your leveling
( https://www.printables.com/model/69956-bed-level-calibration-square-grid ) - Learn how gcode’s work!
Want to know what filament is in your gcode?
grep M104 <file.gcode> # M104 is the temperature M104 200 -> PLA M104 240 -> PETG
Laser engraving using my 3D printer (pre lasercutter)
Websites
- Yeggi
- Thingiverse
- printables – not that much
UPDATE 20230803
Best gap filler i found which is easily sanded down with a dremel.
Alabastine Polyester Plamuur
DDC i2c monitor control
I wanted to control the input of my monitors, these are my findings.
DDC – Display Data Channel
I2C – (Inter-Integrated Circuit, eye-squared-C), alternatively known as IIC, is a synchronous, multi-master/multi-slave (controller/target) bus
Getting monitor information with the ddccontrol -p command
##### PART OF THE OUTPUT ##### Detected monitors : - Device: dev:/dev/i2c-9 DDC/CI supported: Yes Monitor Name: VESA standard monitor Input type: Digital (Automatically selected) - Device: dev:/dev/i2c-7 DDC/CI supported: Yes Monitor Name: VESA standard monitor Input type: Digital - Device: dev:/dev/i2c-6 DDC/CI supported: Yes Monitor Name: VESA standard monitor Input type: Digital Reading EDID and initializing DDC/CI at bus dev:/dev/i2c-9... I/O warning : failed to load external entity "/usr/share/ddccontrol-db/monitor/AOC2490.xml"
Switching inputs
ddcutil -b 7 setvcp 0x60 0x11 # 7 is Second monitor (starts with 6), 0x60 is the input register (see below) and 0x11 is HDMI ddcutil -b 6 setvcp 0x60 0x0f # First monitor DP (Displaylink) alternative command ddccontrol -r 0x60 -w 15 dev:/dev/i2c-7
List the control registers
ddccontrol -d dev:/dev/i2c-6 ddccontrol version 0.6.0 Copyright 2004-2005 Oleg I. Vdovikin (oleg@cs.msu.su) Copyright 2004-2006 Nicolas Boichat (nicolas@boichat.ch) This program comes with ABSOLUTELY NO WARRANTY. You may redistribute copies of this program under the terms of the GNU General Public License. Reading EDID and initializing DDC/CI at bus dev:/dev/i2c-6... I/O warning : failed to load external entity "/usr/share/ddccontrol-db/monitor/AOC2490.xml" Document not parsed successfully. EDID readings: Plug and Play ID: AOC2490 [VESA standard monitor] Input type: Analog =============================== WARNING =============================== There is no support for your monitor in the database, but ddccontrol is using a basic generic profile. Many controls will not be supported, and some controls may not work as expected. Please update ddccontrol-db, or, if you are already using the latest version, please send the output of the following command to ddccontrol-users@lists.sourceforge.net: LANG= LC_ALL= ddccontrol -p -c -d Thank you. =============================== WARNING =============================== Controls (valid/current/max) [Description - Value name]: Control 0x02: +/1/2 C [New Control Value - No changes] Control 0x04: +/0/1 C [Restore Factory Defaults] Control 0x05: +/0/1 C [Restore Brightness and Contrast] Control 0x08: +/0/1 C [Restore Factory Default Color] Control 0x10: +/90/100 C [Brightness] Control 0x12: +/50/100 C [Contrast] Control 0x14: +/5/13 C [???] Control 0x16: +/50/100 C [Red maximum level] Control 0x18: +/50/100 C [Green maximum level] Control 0x1a: +/50/100 C [Blue maximum level] Control 0x60: +/772/4 C [Input Source Select (Main)] Control 0x62: +/17/100 C [Audio Speaker Volume Adjust] Control 0x6c: +/50/100 C [Red minimum level] Control 0x6e: +/50/100 C [Green minimum level] Control 0x70: +/50/100 C [Blue minimum level] Control 0xac: +/6750/65535 [???] Control 0xae: +/6000/65535 [???] Control 0xb2: +/1/8 [???] Control 0xb6: +/3/8 C [???] Control 0xc8: +/5/65302 C [???] Control 0xc9: +/8/65535 C [???] Control 0xcc: +/4/255 [???] Control 0xd6: +/1/4 C [DPMS Control - On] Control 0xdf: +/513/65535 C [???] Control 0xfe: +/4/255 [???]
Setting volume (reg 0x62) of monitor 2
ddcutil -b 7 setvcp 0x62 0x01
AOC monitor PROBLEM
You can’t switch from an input which is not active!
So my workstation is connected via DP, and i can switch to HDMI.
Now i HAVE TO use the hdmi to switch back to DP.
A solution could be to ssh into the machine connected with HDMI (passwordless login) and switch back to DP.
I made a mqtt button sending a topic that was read by the two machines using the mqtt python program elsewhere on this site.
(Rotary Mqtt Volume control)
gddccontrol
Explaining shelly and hotel circuit (while drinking whisky and playing with 220v)
Needed to explain a method you can use with shelly devices to some colleagues.
Forgot about this test later, a friend of mine visited me a few days later and warned me about this still being there.
Colleage at work brings a Freecom Internet Radio
Big mistake 😉 It a Linux ARM system with Busybox
Less do some searching on the web.
Ah .. enable telnet
Open in a browser:
http://192.168.1.x/admin/cgi-bin/debug.cgi
Enable telnet:
Connect and install Pong:
telnet 192.168.1.x (username root) # wget http://agilo.acjs.net/files/mppong/setup.sh # chmod 755 setup.sh # ./setup.sh # ./start.sh # ./start.sh musicpal # For the normal player
Links i have to look into:
https://www.qemu.org/docs/master/system/arm/musicpal.html
Garbage display
I wanted to know when trash is being collected. So i made a dual led thingy.
When we lived in Utrecht, the website which mentions when, what is collected was easy .. like a API
We live in Hilversum now, so i had to write a scraper.
UPDATE : Script not working anymore. Site has been changed, and I’m not willing to run a headless browser (phantomjs) to scrape the info
See below my new solution
Script to set leds
#!/bin/bash set -x if [[ $# -eq 0 ]] ; then curl http://10.1.0.46/control?cmd=NeoPixel,1,0,0,0 curl http://10.1.0.46/control?cmd=NeoPixel,2,0,0,0 exit 0 fi set -x if [ $1 = "GFT" ] ;then led1="150,0,0" ;fi if [ $1 = "Rest" ] ;then led1="150,150,150" ;fi if [ $1 = "Paper" ] ;then led1="0,0,150" ;fi if [ $1 = "Plastic" ] ;then led1="75,191,0" ;fi if [ $1 = "Textiel" ] ;then led1="191,191,191" ;fi if [ $1 = "Kerstbomen" ] ;then led1="191,0,0" ;fi if [ "w$2" = "wgft" ] ;then led2="255,0,0" ;fi if [ "w$2" = "wRest" ] ;then led2="150,150,150" ;fi if [ "w$2" = "wpapier" ] ;then led2="0,0,255" ;fi if [ "w$2" = "wplastic" ] ;then led2="100,255,0" ;fi if [ "w$2" = "wTextiel" ] ;then led2="191,191,191" ;fi if [ "w$2" = "wKerstbomen" ] ;then led2="191,0,0" ;fi if [[ $# -eq 1 ]] ; then led2=$led1 fi curl http://10.1.0.46/control?cmd=NeoPixel,1,$led1 curl http://10.1.0.46/control?cmd=NeoPixel,2,$led2
Scraper ( calls setleds and mqtt )
#!/bin/bash cd /home/pi/ ./afvalleds curl -s https://inzamelkalender.gad.nl/adres/1222HP:39 > /tmp/afvalcurl today=$(date +%F) tomorrow=$(date --date="next day" +%F) for f in petfles-blik-drankpak-pmd.svg appel-gft.svg kliko-grijs-rest.svg doos-karton-papier.svg shirt-textiel.svg kerstboom.svg ; do p1=$(cat /tmp/afvalcurl | grep -i -A2 "$f" | grep class | cut -f2 -d\> | cut -f1 -d\< | cut -f2- -d" ") p2=$(echo $p1 | sed s/mei/may/g | sed s/okt/oct/g ) p3=$(date --date="$p2" +%F) dater=$p3 now=$(date -d $(date --date="1 days ago" +%F) +%s) p3epoch=$(date --date="$p3" +%s) diff=$(expr $p3epoch - $now) if [ $diff -lt 0 ] ; then dater=$(date -d "$p3 1 year" +%F) fi whatdate=$(echo $f | sed s/petfles-blik-drankpak-pmd.svg/Plastic/g |sed s/appel-gft.svg/GFT/g | sed s/kliko-grijs-rest.svg/Rest/g | sed s/doos-karton-papier.svg/Paper/g | sed s/shirt-textiel.svg/Textiel/g | sed s/kerstboom.svg/Kerstbomen/g) mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/$whatdate" -m "$dater" if [ "w$today" == "w$dater" ]; then alltoday="$alltoday $whatdate" fi if [ "w$tomorrow" == "w$dater" ]; then alltomorrow="$alltomorrow $whatdate" fi done mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Today" -m "$alltoday" mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Tomorrow" -m "$alltomorrow" ./afvalleds $alltomorrow
Utrecht scraper
#!/bin/bash set -x curl -s "http://json.mijnafvalwijzer.nl/?method=postcodecheck&postcode=3543eh&huisnummer=72&" > /tmp/afv cat /tmp/afv | python -mjson.tool > /tmp/afv.json today=$(cat /tmp/afv.json | grep -A1 $(date +%Y-%m-%d) | grep nameType | cut -f4 -d\" | paste -sd "/" -) today=$(echo $today | sed s/\ /,/g) tomorrow=$(cat /tmp/afv.json | grep -A1 $(date -d "+1 days" +%Y-%m-%d) | grep nameType | cut -f4 -d\" | paste -sd "/" -) tomorrow=$(echo $tomorrow" | sed s/\ /,/g) cat /tmp/afv.json | grep -B1 nameType | grep -B1 gft | cut -f4 -d\" | grep 202 > /tmp/gft.afv cat /tmp/afv.json | grep -B1 nameType | grep -B1 papier | cut -f4 -d\" | grep 202 > /tmp/papier.afv cat /tmp/afv.json | grep -B1 nameType | grep -B1 plastic | cut -f4 -d\" | grep 202 > /tmp/plastic.afv cat /tmp/afv.json | grep -B1 nameType | grep -B1 kerst | cut -f4 -d\" | grep 202 > /tmp/kerst.afv ( ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/gft.afv > /dev/null && echo "$dater GFT" | head -1 done ) | head -1 ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/papier.afv > /dev/null && echo "$dater Papier" | head -1 done ) | head -1 ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/plastic.afv > /dev/null && echo "$dater Plastic" | head -1 done ) | head -1 ( for f in $(seq 1 31) ; do dater=$(date -d "+$f days" +%Y-%m-%d) grep $dater /tmp/kerst.afv > /dev/null && echo "$dater Kerstboom" | head -1 done ) | head -1 ) | sort -n -k1 | sed s/\ /,/g > /tmp/afv.sorted gft=$(cat /tmp/afv.sorted | grep GFT | cut -f1 -d,) papier=$(cat /tmp/afv.sorted | grep Papier | cut -f1 -d,) plastic=$(cat /tmp/afv.sorted | grep Plastic | cut -f1 -d,) mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Today" -m "$today " mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Tomorrow" -m "$tomorrow " mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Papier" -m "$papier" mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/GFT" -m "$gft" mosquitto_pub -h 127.0.0.1 -p 1883 -t "afvalwijzer/Plastic" -m "$plastic"
Update new solution
My home assistant has a hacs addon installed which does the heavy lifting for me.
Why not use this info?
I wrote about NR and HA here
So getting the info for NR to parse:
I only need to use the lightblue node bottom right!
It is the current state node, inject a timestamp every day to get new values.
Parse this and send using Mqtt to my Led display thingy