All posts by fash

Scripts on my domoticz instance

Script NO1:
Below is a script which checks all sensors and switches available on my domoticz instance, and gives me information about last updates.
For example when a device is out of reach or battery empty.

Usage:

Outputs to console, or you can use it in check_mk monitoring.
(For the latter, create a script

vi /usr/lib/check_mk_agent/local/checkfrontdoor
chmod +x /usr/lib/check_mk_agent/local/checkfrontdoor
put in the script 
#!/bin/bash
cd /path/to/script/
./belowscript "Frontdoor" 300 checkmk

Code:

#!/bin/bash
#set -x
# after running once check stateseconds for names
if [ $# -eq 0 ]; then
echo "$(basename $0) - without options .. getting states"
echo "use $(basename $0) "Sensorname" seconds" for check
echo "Getting all states"
: > stateseconds
curl -s -i -H "Accept: application/json" "http://127.0.0.1:8080/json.htm?type=devices&filter=all&used=true&order=Name" | egrep "Name|Last" | grep -v HardwareName |grep -vi levelnames> states
sed -i 'N;s/\n/,/' states
now=$(date +%s)
cat states  | awk '{ print $3" "$4$7$8$9$10$11$12 }' | sed s/,,/,/g |rev | cut -c2- | rev | while read ; do
name="$(echo $REPLY | cut -f2 -d, )"
dater="$(echo $REPLY | cut -f1 -d, | sed s/\"//g)"
#echo $dater
seen=$(date -d "$dater" +%s)
#echo $seen
echo "$name $(( $now - $seen))" >> stateseconds
echo -n "."
done
fi
echo ""
if [[ ! -z "$1" && ! -z $2 ]]; then
checkold=$(cat stateseconds | grep "$1\"" | head -1 | awk '{ print $2 }')
total=$(( checkold - $2 ))
if [ -z $3 ] ; then
if [ $checkold -gt $2 ] ; then echo "$name lastseen longer than $2 seconds ago ($total sec)" ; exit 1 ;fi
else
if [ $checkold -gt $2 ] ; then echo "2 \"$1\" - Sensor older than $2 seconds" ; exit 1
else
echo "0 \"$1\" - Sensor age ok" ; exit 0
fi
fi
fi

Above to your Mqtt broker?

#!/bin/bash
# change 300 ( age below 5 minutes )
# and $2>=900 ( age above 15 minutes )
./agecheck.sh # Updates statefile
cat stateseconds | tr -d '"-/:"_' | sort -n -k2 | awk '$2<=300' | while read; do
sensorname=$(echo $REPLY | awk '{ print $1 }' )
age=$(echo $REPLY | awk '{ print $2 }' )
mosquitto_pub -h 10.1.0.17 -t sensorsage/$sensorname -m "$age"
done

Script NO:2
This is a mqtt speech script with caching sounds, speech generated for me by google

MQTT Part

#!/usr/bin/python
import paho.mqtt.client as mqttClient
import time
import os
import subprocess
import shlex
Connected = False

def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Connected to broker")
        global Connected
        Connected =True
    else:
        print("Connection failed")

def on_message(client, userdata, message):
    print "Message received: " + message.topic + " : " + message.payload
    fileName = "/home/pi/domoticz/scripts/speech" + " \"" + message.payload + "\""
    print fileName
    args = shlex.split(fileName)
    time.sleep(1)
    p = subprocess.Popen(args)


broker_address = "mqttbroker"
port = 1883
user = "myuser"
password = "mysecretpass"
client = mqttClient.Client("speechcmd")
client.username_pw_set(user, password=password)
client.on_connect = on_connect
client.on_message = on_message

client.connect(broker_address, port=port)
client.loop_start()

while Connected != True:
    time.sleep(0.1)

client.subscribe('speech/cmd')

try:
    while True:
        time.sleep(1)

except KeyboardInterrupt:
    print "exiting"
    client.disconnect()
    client.loop_stop()

Speech part (uses mpg123 to play sound though speaker)

#!/bin/bash
#set -x

INPUT=$*
input2=$(echo $INPUT | base64)
echo "$input2 = $INPUT" >> /home/pi/cache/files-text-relation
if [ -f /home/pi/cache/$input2.mp3 ] ; then
mpg123 -q /home/pi/cache/$input2.mp3 1>/dev/null 2>/dev/null
else
echo not cached
STRINGNUM=0

ary=($INPUT)
for key in "${!ary[@]}"
  do
    SHORTTMP[$STRINGNUM]="${SHORTTMP[$STRINGNUM]} ${ary[$key]}"
    LENGTH=$(echo ${#SHORTTMP[$STRINGNUM]})
    #echo "word:$key, ${ary[$key]}"
    #echo "adding to: $STRINGNUM"
    if [[ "$LENGTH" -lt "100" ]]; then
      #echo starting new line
      SHORT[$STRINGNUM]=${SHORTTMP[$STRINGNUM]}
    else
      STRINGNUM=$(($STRINGNUM+1))
      SHORTTMP[$STRINGNUM]="${ary[$key]}"
      SHORT[$STRINGNUM]="${ary[$key]}"
    fi
done

for key in "${!SHORT[@]}"
  do
    #echo "line: $key is: ${SHORT[$key]}"

    echo "Playing line: $(($key+1)) of $(($STRINGNUM+1))"
    NEXTURL=$(echo ${SHORT[$key]} | xxd -plain | tr -d '\n' | sed 's/\(..\)/%\1/g')
echo $NEXTURL
    mpg123 -w $input2 -q "http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=$NEXTURL&tl=En-us"
    ffmpeg -i $input2 -codec:a libmp3lame -qscale:a 2 /home/pi/cache/$input2.mp3
mpg123 /home/pi/cache/$input2.mp3
done
fi

set msg.payload to “Doorbell”
and Mqtt topic to “speech/cmd”

To be continued !

Cold smoke

Today some smoking again.

Salmon and cheese

For curing the salmon (500gr) i used:

  • 100 gr seasalt
  • 80gr licht caster sugar
  • 3 teaspoons dille
  • 1 teaspoon crushed juniper berries

Dry salmon, put a layer of above mixture in a container, put the salmon on top, with another layer. Put a heavy weight ontop to squeeze the water out of the salmon, while its in the refrigerator. Next day: Wash the salmon, drying it with paper kitchentowel. Put the salmon back into the refrigerator again to dry some more.
I’ve put the salmon in my smoker with a cold smoke generator for 8 hours, the cheese needed only 2 hours.

Little book with jokes and programs.

A long time ago i took a book about doing funny stuff in dos, and wrote own additions in the sidelines of the book. Or used the empty pages.

It contains jokes using autoexec.bat and config.sys. Additions by me are most of the time things you could do with debug.com, a little program which existed on any pc at that time.

A little program which created static on a CGA or Hercules monitor. Yes, that long ago. CGA provided 16 colors in 80×25 or 40×25 text modes, but only four colors at 320×200 resolution and two colors at 640×200. Hercules was only monochrome and a max resolution of 720×348. It was on a hercules card i made my first copperbar. ( Before the effect was named copperbar ). Due to difference in timing on every machine, you had to get the copperbar timing right by using two keys i’d assigned the timing to.

MOV AL,00                      # Fill AL register with 0
MOV DX,0x03D8 (cga) 03B8 (herc)# DX with address
OUT DX,AL                      # Set address with AL
MOV AL,[0101]                  # Reg AL with contents 
INC AL                         # Increment AL
MOV [0101],AL                  # Address fill with AL
JMP 100                        # Jump to start

The opcodes for the program :

b0 00
66 ba d8 03
ee
a0 41 00 00 00  
fe c0
a2 41 00 00 00 
e9 60 00 00 00

Sometimes i put these little programs in autoexec.bat, so at next restart of the pc, it would do something weird. My little BOFH jokes. Friends and computerstores where not safe.

Another example:

Two drives in a PC ? (Wie A: zegt moet ook B: zeggen)
Use with care, below will f*ck up your drives. (And makes a lot of noise while doing so.)

MOV DX,0x03F2
MOV AL,71
OUT DX,AL
MOV AL,74
OUT DX,AL
JMP 100

( https://en.wikipedia.org/wiki/Floppy-disk_controller )


C64 plus drive running again

20220502: Fixed another C64, PIA (Peripheral Interface Adapter) was dead, luckily i’ve got several spare-part c64’s. So that was a easy fix.

20220504: Got my sd2iec adaptor in, see bottom of this page.

Booting with a power cartridge
None of my old computers was unmodified
Demo by my old friend Sepp

Drive is a 1541model 2

De wires are going to the DOUT pins of the memory chips. Showing activity using leds. Sometimes i monitored CS .. also informative.

SD2IES Cardreader

Little small funky gadget, it replaces a 1541 Floppy drive with a SDCard reader where you can store a lot of floppydisk images on.
More on this later.

NOTE : Doesn’t work together with my KCS Power cartridge.

I’ve tested two cartridges.

Final cartridge III fastload test on a program did ~3 seconds. ( Normal load time ~17 seconds. ) KCS powercartridge didn’t work. Tip: press `runstop` when using FC3 while turning on to get into basic not the desktop.

FFmpeg tricks

Mp4 to gif (resize, cut and convert)

startsecond=0
duration=3
ffmpeg -ss $startsecond -t $duration -i 'input.mp4' -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif

Gif to MP4

ffmpeg -i kanban.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" gifkanban.mp4

Converting MP4 for Davinci MOV

ffmpeg -i input.mp4 -c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p -c:a pcm_s16le -f mov output.mov

And back from Davinci to MP4

ffmpeg -i render.mov -c:v libx264 -pix_fmt yuv420p -crf 16 -force_key_frames 'expr:gte(t,n_forced/2)' -bf 2 -vf yadif -use_editlist 0 -movflags +faststart -c:a aac -q:a 1 -ac 2 -ar 48000 -f mp4 out.mp4

QTVR to png (note number of frames)

ffmpeg -i ../test.mov %02d.png
ffmpeg -i %02d.png -vf "tile=1x24,transpose=1" mh.png

Nikon MOV to mp4 (no reencoding)

ffmpeg -i input.mov -c copy -movflags +faststart  output.mp4

Nikon MOV to mp4 (problems with audio?
“Could not find tag for codec pcm_s16le in stream #1, codec not currently supported in container”

ffmpeg -i input.mov -c copy -c:a aac -b:a 128k -movflags +faststart  output.mp4
Maybe add -strict experimental 

MPG to MP4 (Not happy with this one)

ffmpeg -i vhs-rip.mpg"  -c:v libx264 -crf 10 -strict -2 1993-luv.mp4

FLV to MP4

ffmpeg -i filename.flv -c:v libx264 -crf 19 -strict experimental filename.mp4

Lossless cut with ffmpeg

ffmpeg  -ss 00:$2 -t 00:$3 -i $1 -vcodec copy -an cut_$1  
# an = no sound
# use -acodec copy for same codec as original audio

Timelapse JPG to MP4

ffmpeg -f image2 -r 24 -start_number 8296 -i "750_%04d.JPG"  -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast -vf scale=1920:1080 b.mp4

png to gif from a list

#cat png.list
file off.png
duration 1
file 20.png
duration 1
file 40.png
duration 1
file 60.png
duration 1
file 80.png
duration 1
file 90.png
duration 1
file 100.png
duration 1

# ffmpeg -f concat -i png.list -loop 0 hexlight.gif


Rotate mp4 clockwise/anticlockwise

ffmpeg -i VID20230110132531.mp4 -filter:v transpose=2 -c:v libx264 -preset veryfast -crf 22 -c:a copy -metadata:s:v rotate="" test.mp4

Concat video together

ffmpeg -f concat -i inputs.txt -c copy merge.mp4
inputs.txt
file start.mp4
file end.mp4


Error “width/height not divisible by 2 (1301×933)”

ffmpeg -i input.mp4 -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4

Dvd/DV/Mpg etcetera overviews

I made two scripts, which take a movie, find out its lenght divide by 9. And generates a image montage of snapshots at certain times in the movie. ( A movie of 90 minutes, gets a snapshot every 10 minutes )

Example of snapshots of a movie

Below takes images as above and convert them into animated gifs. All movies in a path or directory structure gets a index page containing all animated gifs.

Example of generated directory index

I’ll post something about my media sorter also.
A ajax website using drag drop viewing/sorting images (png/gifs/jpgs) and movies.

#!/bin/bash
# Uses montage, ffmpeg, convert and mediainfo
rm thumbs/*
rm montage/*
(
set -x
numberofframes=9
find  -type f | egrep -i "flv$|mov$|mkv$|avi$|mpg$|mp4$|VTS_01_1.VOB$|wmv$" |  while read filez; do
        crunchpath=$(echo $filez | sed "s,/,,g" |  sed "s, ,,g" |tr -cd '[:alnum:]' ).gif
        crunchback=$crunchpath
        echo $crunchpath
        if [ -f thumbs/$crunchpath ] ; then
                echo "$file exists"
                else
	mkdir /tmp/thumbs/ 2>/dev/null
	mkdir thumbs 2>/dev/null
	mkdir montage 2>/dev/null
        rm -f /tmp/thumbs/*png
sec=0
                totaltime1=$( mediainfo -f "$filez" | grep ^Dura  | awk '{print $3}' |grep -v "\:" | tail -1 )
                totaltime2=$( mediainfo -f "$filez" | grep ^Dura  | awk '{print $4}' |grep -v "\:" | tail -1 )
totaltime1a=$(echo $totaltime1| tr -d 'a-z')
echo $totaltime1 | grep h && sec=$((3600 * $totaltime1a))
echo $totaltime1 | grep mn && sec=$((60 * $totaltime1a))
echo $totaltime1 | grep s && sec=$totaltime1a
echo "sec : $sec"
echo $totaltime2 | grep -v ms | grep  s && sec=$[ $sec + $(echo $totaltime2 | tr -d 'a-z')]
echo "sec : $sec"
                width=$( mediainfo -f "$filez" | grep "Width"| grep pixels | awk '{ print $3 }' )
                height=$( mediainfo -f "$filez" | grep "Height"| grep pixels | awk '{ print $3 }' )
        if [ "$sec" == "" ] ; then sec=1 ; fi
                timer=$[ $sec / $numberofframes ]
                        echo  "converting step "
                        echo  "timer is $timer"
mark=0
                for f in `seq -w 1 $numberofframes` ; do
                        echo  "$f,$timer"
			echo $[$f*$timer]
                        ffmpeg -ss $[$f*$timer] -i "$filez" -vframes 1 /tmp/thumbs/$f.png 1>/dev/null 2>/dev/null </dev/null
if [ $f -eq 8 ] ; then cp /tmp/thumbs/8.png /tmp/thumbs9.png ;fi
newsizer=$(echo -n $widther ; echo -n "x" ; echo -n $sizeh)
if [ $sizeh -gt $sizew ] ; then mv /tmp/thumbs/$f.png /tmp/ff.png ; convert -resize $newsizer\! /tmp/ff.png /tmp/thumbs/$f.png ; echo aangepast ; echo $newsizer ; mark=1; fi
                done
                        echo " "
                        echo "generating $crunchpath"
	newwidth=$[ $width / 2 ]
	newheight=$[ $height / 2 ]
	newsize=$(echo -n $newwidth ; echo -n "x" ; echo -n $newheight)
	newsize2=$(echo -n $width ; echo -n "x" ; echo -n $newheight)
	echo $newsize
if [ $mark == 0 ] ; then        convert -delay 100 -resize $newsize\! /tmp/thumbs/*.png thumbs/$crunchpath </dev/null ; else
convert -delay 100 -resize $newsize2\! /tmp/thumbs/*.png thumbs/$crunchpath </dev/null 
fi
montage /tmp/thumbs/*png  -geometry +3+3 -tile 3x3 montage/$crunchpath.jpg
	echo "<img src=\"$crunchpath\">" >> thumbs/_index.html
        fi
done
) > /tmp/thumb.log

Project mixer

I made a sound mixer controller for my applications, a while ago.

Some arduino project laying around on my desk. (OBS controller, Mqtt-sound-and-display-with-mute-acknowledge-button and Octoprint monitor, below that my dusty mixer)

I’m probably make a V2 with new functionality:

  • Switching applications which are using sound from speakers to headset and vice versa.
  • Led showing muted channels
  • Rotary buttons? Or motorized sliders?

See my other post ..

https://www.henriaanstoot.nl/2022/03/18/audio-switcher/

Esp32 Epaper and HA (Esphome)

Flashing a TTGO (ESP32) via your browser from ESPHome
esphome:
  name: epaperesp32

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "xxxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Epaperesp32 Fallback Hotspot"
    password: "xxxxxxxxxxxx"

captive_portal:

font:
  - file: 'fonts/tahoma.ttf'
    id: font1
    size: 16

spi:
  clk_pin: 13
  mosi_pin: 14

display:
  - platform: waveshare_epaper
    cs_pin: 15
    dc_pin: 27
    busy_pin: 25
    reset_pin: 26
    model: 2.13in-ttgo
    full_update_every: 30
    lambda: |-
      it.print(0, 0, id(font1), "Pruts");
      

Mikrotik Mqtt

Today Vincent mentioned a link about mqtt and mikrotiks, i knew about addons, but not mqtt .. lets try this.

When you want to use MQTT with Mikrotik you have to install the iot package from extra_packages.

  • Download correct package zip from ( https://mikrotik.com/download )
    • Download extra packages zip for your system
  • Extract and use file upload
  • Reboot your mikrotik

(i had to upgrade my firmware first, iot package was not build for my version)

Create a entry in IoT > Mqtt to your broker.

save below in a script ending with a .rsc extention, and upload in file manager

# Required packages: iot

################ Configuration #################
# Name of an existing MQTT broker that should be used for publishing, the one you just created
:local broker "10.1.0.17"

# MQTT topic where the message should be published
# i've got mine in a tree called mikrotik/switchtype/
:local topic "mikrotik/rb2011/topic"

############### System ###############
# You can create your own variables below
:put ("[*] Gathering system info...")
:local cpuLoad [/system resource get cpu-load]
:local freeMemory [/system resource get free-memory]
:local usedMemory ([/system resource get total-memory] - $freeMemory)
:local rosVersion [/system package get value-name=version \
    [/system package find where name ~ "^routeros"]]
:local model [/system routerboard get value-name=model]
:local serialNumber [/system routerboard get value-name=serial-number]
:local upTime [/system resource get uptime]

################## MQTT ###################
# create a message
:local message \
    "{\"model\":\"$model\",\
                \"sn\":\"$serialNumber\",\
                \"ros\":\"$rosVersion\",\
                \"cpu\":$cpuLoad,\
                \"umem\":$usedMemory,\
                \"fmem\":$freeMemory,\
                \"uptime\":\"$upTime\"}"

:log info "$message";
:put ("[*] Total message size: $[:len $message] bytes")
:put ("[*] Sending message to MQTT broker...")
/iot mqtt publish broker=$broker topic=$topic message=$message
:put ("[*] Done")

Import script using

import mikrotikmqtt.rsc

Todo’s:

Import is just @ import time, need to “cron” this?

Secretly i hate wordpress

Don’t get me wrong, its a wonderful tool.

In the past i created a lot of websites. From scratch. I wanted to learn html and using databases. Sites got bigger and bigger, most of them personal interest. But there where several work and music band related websites.
Besides that my pipetunesearch pet project, which lasted 20 years. This one started as ‘how to create a php website with a database backend’

So why hating wordpress? It’s all being done for you, but i want do it yourself and learn from it.
I’ve made several sites with their own CMS. No way secure, but secure by obsurity, whereas wordpress sites a being hacked with zeroday exploits using bots. No-one WANTED, even to hack mine.

I started with SSI (server site includes), php3, cgi scripts in bash/perl/c etcetera. I loved (and still do) interactive websites, connection to a backend, reacting on user input. Sometimes while doing so, creating a thing before it was a thing.

For my webcam, which wasn’t anything more dan a video capturing card, with a simple composite little B/W camera. This camera was mounted on some big steppermotors, and held in place by a chunk of metal, machined by a friend of mine.

I learned to make streaming webcams by generating a progressive jpg being created by a cgi script. Controlling the movement was done by .. by anything which i needed to get things working. I think i where several binaries written in C and glued together with perl or bash. Pushing the little control buttons always send the user to the next page. Reloading and restarting the webcam stream.
Then i found the 402 no content header, sending this to the browser kept it from progressing to the next page.
Loads of problems to overcome, but learned a lot!

Sometimes you have to choose.
DIY or NOT. Flacky or proven to work for many, made by many.

M5stick and Home Assistant

Using Esphome in HA, you can flash arduino’s using your browser.

I wanted to test with a M5stickC because of the intergrated sensors.

Steps to take:

  • Install Esphome
    add repo from https://esphome.io/guides/getting_started_hassio.html
  • Connect M5Stick to usb ( you can do this from the same machine where your browser is running ), i connected the device directly to the NUC where Home Assistant is running.
  • Open EspHome integration
  • New Device (First time it will ask for your default Wifi credentials)
  • Give it a name, and select Pick specifiec board (M5Stick-c)
  • When presented a edit field with yml, past below for first test
  • Click install to flash
esphome:
  name: m5stickc

esp32:
  board: m5stick-c
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "xxxxxxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "M5Stickc Fallback Hotspot"
    password: "xxxxxxxxxxxxxxx"

captive_portal:
web_server:

globals: 
i2c:
  - id: bus_b
    sda: 21
    scl: 22
    scan: true
  - id: bus_c
    sda: 32
    scl: 33
    scan: true
binary_sensor:
sensor:
  - platform: mpu6886
    i2c_id: bus_b
    address: 0x68
    accel_x:
      name: "MPU6886 Accel X"
    accel_y:
      name: "MPU6886 Accel Y"
    accel_z:
      name: "MPU6886 Accel z"
    gyro_x:
      name: "MPU6886 Gyro X"
    gyro_y:
      name: "MPU6886 Gyro Y"
    gyro_z:
      name: "MPU6886 Gyro z"
    temperature:
      name: "MPU6886 Temperature"
spi:
  clk_pin: GPIO13
  mosi_pin: GPIO15
# Below is test  
color:
  - id: my_red
    red: 100%
    green: 0%
    blue: 0%
  - id: my_yellow
    red: 100%
    green: 100%
    blue: 0%
  - id: my_green
    red: 0%
    green: 100%
    blue: 0%
  - id: my_blue
    red: 0%
    green: 0%
    blue: 100%
  - id: my_gray
    red: 50%
    green: 50%
    blue: 50%

#Display size 135*240
display:
  - platform: st7789v
    id: tft
    cs_pin: GPIO5
    dc_pin: GPIO23
    reset_pin: GPIO18
    rotation: 270

Biggest problem was finding GPIO pins for i2c.