Tag Archives: programming

Photo manager addition using ML!

A few years ago i wrote a photo manager .. again .. ( see post about my first previous photo manager )
It is a web gui to find photos in my huge photo archive.
I manually added 190k tags to 120k photos in 20+ years.

I thought wouldn’t it be nice if i can generate additional metadata using Machine Learning. A few years ago i did some testing and followed a podcast and free course about machine learning.

So today i started to implement a addition to my gui. Machine recognition tags!

It already kinda works.

Things to do :

  • Make it a background job, my fileserver doesn’t run Tensorflow on a GPU, so it is slooow
  • Embed in existing GUI and stats
  • Design a editor to remove wrong tags

Below a part of ML images

Command to get a thumbnail sheet with only directory names:

montage -verbose -units PixelsPerInch -density 300 -tile 7x6 -label "%d" -font Arial -pointsize 6 -background "#FFFFFF" -fill "black" -define jpeg:size=253x154 -geometry 253x154+2+2 -auto-orient */*.JPG -title "ML Thumbs" thumbsheet.jpg

Maybe, i can use debug output like below.

['lakeside, lakeshore (score = 0.47934)', 'seashore, coast, seacoast, sea-coast (score = 0.11385)', 'sandbar, sand bar (score = 0.08822)', 'breakwater, groin, groyne, mole, bulwark, seawall, jetty (score = 0.06281)', 'valley, vale (score = 0.01790)', '']

Scraping podcast which uses a javascript to obfuscate mp3 links

wget-ting the page only gave me flat html, but no readable links.

We need the rendered version, phantomjs wil help

wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2

printsource.js

var system = require('system');
var page   = require('webpage').create();
var url    = system.args[1];
page.open(url, function () {
  console.log(page.content);
  phantom.exit();
});

Run phantomjs

phantomjs-2.1.1-linux-x86_64/bin/phantomjs printsource.js  https://xxxxxxxx/show/xxxx > out

So now i got the rendered page, get mp3’s and titles, for this example

cat out | sed 'N;s/\n/,/' | cut -f2,7 -d\" | while read line ; do
mp3=$( echo $line | cut -f1 -d\")
title=$( echo $line | cut -f3 -d\> | tr -d '/<>[]]\!,;' | tr -d "'" | sed s/CDATA//g | sed s#title##g | sed s/:/-/g )
echo "$mp3 $title"
wget $mp3 -O "$title.mp3"
done

bash downloadscript
done

Mqtt Bash Nodered Notify

When running scripts which take a long time, i don’t want to wait for things to finish before i can start the next one.

For example, using my dedup script or compiling stuff. I wanna know when it is finished.

So i made some scripts

Maybe you can hear the spoken text in the background playing downstairs

I’ve put a function in .bashrc, so i can use a command like
notify “Compiling is ready”
A command like this i can put at the end of a command or in a script file at the end.
make && make install && notify “compile ready”

What does it do when executed?

  • Send a mqtt message to the broker
  • Node-red will read this message and:
    • Send a message to my display on my desk – Sound and message notification. (See another post how i made this )
    • Send a message to a script on my Domoticz instance downstairs.
      • This will use a script to get a speech file from google, and play this on some small speakers in my livingroom
    • Send a pushover message to my phone
    • Display a message on my TV ( not in code below )

How?

At the end of your .bashrc

function notify() {
    if [ -z "$1" ]; then
        echo "Usage: $0 \"message\"";
        exit 1;
    fi
    mosquitto_pub -h 10.1.0.17 -t notify/bashscript -m "$1"
}

Scripts on my Domoticz instance

Python script

#!/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 = "10.1.0.17"
port = 1883
#user = "user"
#password = "password"
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()

Caching speech script

This script will look for a cached audiofile with requested text, and uses that. Else it wil request a audio file from google, caches it and plays it though the speakers.

#!/bin/bash
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 "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

Node-red flow

function notify() {
    if [ -z "$1" ]; then
        echo "Usage: $0 \"message\"";
        exit 1;
    fi
    mosquitto_pub -h 10.1.0.17 -t notify/bashscript -m [
    {
        "id": "1442fca698589679",
        "type": "mqtt in",
        "z": "cb6f001b.721c3",
        "name": "",
        "topic": "notify/bashscript",
        "qos": "2",
        "datatype": "auto",
        "broker": "8c74c5f6.9a7a48",
        "nl": false,
        "rap": false,
        "inputs": 0,
        "x": 180,
        "y": 580,
        "wires": [
            [
                "ddf5744bb5b73d4d",
                "faa5c794652d7a57",
                "b4e0107399248fea",
                "443f960b5d1cf40e"
            ]
        ]
    },
    {
        "id": "ddf5744bb5b73d4d",
        "type": "mqtt out",
        "z": "cb6f001b.721c3",
        "name": "",
        "topic": "speech/cmd",
        "qos": "",
        "retain": "",
        "broker": "8c74c5f6.9a7a48",
        "x": 590,
        "y": 560,
        "wires": []
    },
    {
        "id": "e95e828451d83158",
        "type": "comment",
        "z": "cb6f001b.721c3",
        "name": "bash notify",
        "info": "",
        "x": 170,
        "y": 540,
        "wires": []
    },
    {
        "id": "faa5c794652d7a57",
        "type": "mqtt out",
        "z": "cb6f001b.721c3",
        "name": "",
        "topic": "mqttlcd/message",
        "qos": "",
        "retain": "",
        "broker": "8c74c5f6.9a7a48",
        "x": 570,
        "y": 720,
        "wires": []
    },
    {
        "id": "b4e0107399248fea",
        "type": "delay",
        "z": "cb6f001b.721c3",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "outputs": 1,
        "x": 480,
        "y": 640,
        "wires": [
            [
                "ac4faf30b8adbe3f"
            ]
        ]
    },
    {
        "id": "ac4faf30b8adbe3f",
        "type": "function",
        "z": "cb6f001b.721c3",
        "name": "Empty payload",
        "func": "msg.payload = \"\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 640,
        "y": 640,
        "wires": [
            [
                "faa5c794652d7a57"
            ]
        ]
    },
    {
        "id": "dfbe26c12fc5e742",
        "type": "pushover",
        "z": "cb6f001b.721c3",
        "name": "Alleen Henri",
        "device": "rmx1931",
        "title": "Node-Red-Pushover",
        "priority": "1",
        "sound": "pushover",
        "url": "",
        "url_title": "",
        "html": false,
        "x": 850,
        "y": 500,
        "wires": []
    },
    {
        "id": "443f960b5d1cf40e",
        "type": "function",
        "z": "cb6f001b.721c3",
        "name": "Set pushover payload",
        "func": "\nmsg.topic = \"Bash Notify\";\nmsg.priority = 1;\nmsg.sound = \"cosmic\";\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 500,
        "wires": [
            [
                "dfbe26c12fc5e742"
            ]
        ]
    },
    {
        "id": "8c74c5f6.9a7a48",
        "type": "mqtt-broker",
        "name": "10.1.0.17",
        "broker": "10.1.0.17",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "15",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    }
]


MPF-1B – Z80 Training kit

One from my collection: A training kit for learning to write machine language.

Update: 20220514 – Save and Load a program
Update: 20220829 – Mad-1 computer runaway movie

A little example, life programming a little machine code.

ORG 1800
0E 80              ; LD C,0
21 C0 00           ; LD HL,00C0
CD E4 05           ; CALL 0X05E4
0E 01              ; LD C,0
21 00 01           ; LD HL,0100
CD E4 05           ; CALL 0X05E4
C3 00 18           ; JMP 0X1800

Found this cameo in the movie “Runaway”

Using a tape and COMX-35 cassette player, i can store and retreive programs

Old Skool saving a program
And loading a program

Above i mentioned a Runaway Cameo .. well there is a MAD-1 system cameo also. (Which also i in my collection)

Working Amiga 500

Got a working amiga again. \o/ woot
Needed to replace Paula chip, cleaning and some TLC.

Modulator
Chip donor

Scart cable i’ve got is one without the resistors, so my monitor isn’t detecting the signal.
Using a A520 modulator works. At least RF, don’t know why RCA/composite video isn’t working.

Even a memory expansion and second drive (5.24 inch) are working.

One of the first disks i tested

To do:

  • Fix something to get disk images from and to my pc.
  • (My old catweasel card only fits in a ISA slot which i don’t have any more)
  • I was wrong .. i’ve got a IV Catweasel .. PCI it is
  • Fix scart
  • Fix my Action Replay, which i soldered into a non working state apparently .. 🙂
  • Get a better mouse!
Catweasel IV

Disks to convert:

  • Personal text files from ages ago
  • My first seka demo
  • My oscillator drawing program
  • Other assembly source files

Got another one running today also:

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 )


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.

Android Applications

Today i talked about creating apps for mobiles with a colleague.

I made me wonder what programming IDE i’ve used in the past.

Things i’ve made:

  • clog killer – a game application i made while working at a job.
    It was the name of a process on our servers we all hated.
    It was slow and messed up your terminal.
  • Webled – have to install this one again, to see what its purpose was 🙂
  • Whistle hole calculator – When making your own tinwhistle/lowwhistle you had to calculate diameters and positions.
    I will make another post about this.
  • Made a Multiple-Choice Quiz tool, for learning Iai-do positions/terminology. (Japanese Martial Arts – See other posts)
  • A iscp Onkyo controller (see post about my web controller)

Tools used:

  • Android IDE
  • App inventor
  • ??
  • And mobile applications using html5, php, css3 and jquery mobile

App ideas, not started or not completed:

  • Game for blind people (Or people who are bored out of their skull going to meetings)
    It involves a evolving maze game on a black screen, you have to remember the way. Hitting a wall, buzzz .. dead, start all over again.
    So you can hold your phone under the table or behind your back.
    (Black screen and no sound, just the little vibrating thinghy.)
  • New way to select app’s using a widget.
  • Pull down search game. (Have to look at the source again, i forgot what i did)

Downloads and screenshots:

I’ll post more/better examples

Other:

Reversed engineered a tool found on a ‘hackers’ phone.
Apparently it was a security test setup nobody was aware of.
I was able to find urls and domains where some call-home functionality was involved.

Biltong again

In 2020 i made a Biltong drying thingy, using a Nextion and a Arduino.
Today i’m preparing for some Chilli Biltong, which i’m going to put in the drying box tomorrow.

2020 Version 1, now version 3 (no more display bugs)

Arduino functionality

  • Heating light
  • Temperature / Humidity
  • Air flow
  • MQTT to home automation
  • Nextion Display

Recipe

Meat
1 kg Beef Cut into 1.5cm - 2cm steak slices

Spice
2 tbsp black pepper coarsely ground.
2 tbsp course Sea Salt
1/2 tbsp smoked paprika
4 tbsp coriander seeds roasted and coarsely ground.
1 tbsp chili flakes

Marinade
50 ml worcestershire sauce
100 ml apple vinegar
1 tbsp tabasco sauce

Script – get images from Reolink cam

while true; do
wget "http://ip.number.or.hostname/cgi-bin/api.cgi?cmd=Snap&channel=0&rs=123asd&user=admin&password=MYSECRETPASS" -O $(date +%Y%m%d%H%M).jpg
sleep 60
done

Script to generate MP4 (60fps)

cat *.jpg | ffmpeg -f image2pipe -r 60 -vcodec mjpeg -i - -vcodec libx264 out.mp4
Part of Grafana log