Fluxengine disk reader

Last Updated or created 2022-12-01

I’ve build a drawbridge disk reader in the past:
https://www.henriaanstoot.nl/2022/04/26/started-to-build-a-drawbridge/
I found an even more interesting project.

I was looking for a solution to my XT laser problem.
https://www.henriaanstoot.nl/2022/11/25/disk-troubles-or-missing-old-skool-hardware/

And found this! The fluxengine
https://github.com/davidgiven/fluxengine

An open source project using a small controller board.
“Flashing” some software on the board and soldering a pinheader was easy.
When connecting a flat cable and a floppy drive, you end up with a device which can read many formats. Including dos 1.44/720 and amiga.

Nice package it came in

Using the power from a sata/ide harddisk adaptor

Reading and writing a MSDOS disk, no problem.
Imaging an amiga disk .. easy!

You need to compile some software, but it was well documented

Shelly alarm button

Last Updated or created 2022-12-01

For a while i’ve been using the wireless shelly button for all kinds of notifications.
Most of the time i like to use it as a kind of alarm/need-help-now button.

The f*ckin’ awesome button i’m talking about (pictured above) is a small (45x45mm 16mm height) button, which can connect to your wifi and send MQTT messages.
It even has a strap thingy to attach it to your keychain,

Four types of messages:

  • short press
  • 2x short presses
  • 3x short presses
  • and long press

When using pushover, you can push alarm and messages to your android (even overriding mute/silent if you configure it that way!)

Configuring the button:
https://www.shelly.cloud/documents/user_guide/shelly_button_1.pdf

Configuring pushover:
https://www.npmjs.com/package/node-red-node-pushover

My node red config:

Switch node

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[
{
"id": "abb6a4fea5021683",
"type": "mqtt in",
"z": "458ff8a6.218fa8",
"name": "",
"topic": "shellies/shellybutton1-11CDAC2C21D3/input_event/0",
"qos": "2",
"datatype": "auto",
"broker": "8c74c5f6.9a7a48",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 320,
"y": 760,
"wires": [
[
"bebce75c2be0b54d"
]
]
},
{
"id": "8eac36b9c194977b",
"type": "comment",
"z": "458ff8a6.218fa8",
"name": "Shelly Button",
"info": "",
"x": 200,
"y": 720,
"wires": []
},
{
"id": "699c63fede80052b",
"type": "debug",
"z": "458ff8a6.218fa8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 890,
"y": 700,
"wires": []
},
{
"id": "604ae0babdcf3929",
"type": "switch",
"z": "458ff8a6.218fa8",
"name": "",
"property": "payload.event",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "S",
"vt": "str"
},
{
"t": "eq",
"v": "SS",
"vt": "str"
},
{
"t": "eq",
"v": "SSS",
"vt": "str"
},
{
"t": "eq",
"v": "L",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 4,
"x": 690,
"y": 700,
"wires": [
[
"699c63fede80052b",
"5f289f050b9eea26"
],
[
"e895ce98af0a9c35"
],
[
"50c9c06fc3dbdcdd"
],
[
"06efa30e61695599"
]
]
},
{
"id": "e895ce98af0a9c35",
"type": "debug",
"z": "458ff8a6.218fa8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 890,
"y": 760,
"wires": []
},
{
"id": "50c9c06fc3dbdcdd",
"type": "debug",
"z": "458ff8a6.218fa8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 890,
"y": 820,
"wires": []
},
{
"id": "06efa30e61695599",
"type": "debug",
"z": "458ff8a6.218fa8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 890,
"y": 880,
"wires": []
},
{
"id": "bebce75c2be0b54d",
"type": "json",
"z": "458ff8a6.218fa8",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 600,
"y": 780,
"wires": [
[
"604ae0babdcf3929",
"699c63fede80052b"
]
]
},
{
"id": "5f289f050b9eea26",
"type": "pushover",
"z": "458ff8a6.218fa8",
"name": "",
"device": "",
"title": "Alarm",
"priority": "2",
"sound": "persistent",
"url": "",
"url_title": "",
"html": false,
"x": 1150,
"y": 640,
"wires": []
},
{
"id": "8c74c5f6.9a7a48",
"type": "mqtt-broker",
"name": "MQTTBROKER",
"broker": "MQTTBROKER",
"port": "1883",
"clientid": "",
"usetls": false,
"compatmode": true,
"keepalive": "15",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"closeTopic": "",
"closePayload": "",
"willTopic": "",
"willQos": "0",
"willPayload": ""
}
]
[ { "id": "abb6a4fea5021683", "type": "mqtt in", "z": "458ff8a6.218fa8", "name": "", "topic": "shellies/shellybutton1-11CDAC2C21D3/input_event/0", "qos": "2", "datatype": "auto", "broker": "8c74c5f6.9a7a48", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 320, "y": 760, "wires": [ [ "bebce75c2be0b54d" ] ] }, { "id": "8eac36b9c194977b", "type": "comment", "z": "458ff8a6.218fa8", "name": "Shelly Button", "info": "", "x": 200, "y": 720, "wires": [] }, { "id": "699c63fede80052b", "type": "debug", "z": "458ff8a6.218fa8", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 890, "y": 700, "wires": [] }, { "id": "604ae0babdcf3929", "type": "switch", "z": "458ff8a6.218fa8", "name": "", "property": "payload.event", "propertyType": "msg", "rules": [ { "t": "eq", "v": "S", "vt": "str" }, { "t": "eq", "v": "SS", "vt": "str" }, { "t": "eq", "v": "SSS", "vt": "str" }, { "t": "eq", "v": "L", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 4, "x": 690, "y": 700, "wires": [ [ "699c63fede80052b", "5f289f050b9eea26" ], [ "e895ce98af0a9c35" ], [ "50c9c06fc3dbdcdd" ], [ "06efa30e61695599" ] ] }, { "id": "e895ce98af0a9c35", "type": "debug", "z": "458ff8a6.218fa8", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 890, "y": 760, "wires": [] }, { "id": "50c9c06fc3dbdcdd", "type": "debug", "z": "458ff8a6.218fa8", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 890, "y": 820, "wires": [] }, { "id": "06efa30e61695599", "type": "debug", "z": "458ff8a6.218fa8", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 890, "y": 880, "wires": [] }, { "id": "bebce75c2be0b54d", "type": "json", "z": "458ff8a6.218fa8", "name": "", "property": "payload", "action": "", "pretty": false, "x": 600, "y": 780, "wires": [ [ "604ae0babdcf3929", "699c63fede80052b" ] ] }, { "id": "5f289f050b9eea26", "type": "pushover", "z": "458ff8a6.218fa8", "name": "", "device": "", "title": "Alarm", "priority": "2", "sound": "persistent", "url": "", "url_title": "", "html": false, "x": 1150, "y": 640, "wires": [] }, { "id": "8c74c5f6.9a7a48", "type": "mqtt-broker", "name": "MQTTBROKER", "broker": "MQTTBROKER", "port": "1883", "clientid": "", "usetls": false, "compatmode": true, "keepalive": "15", "cleansession": true, "birthTopic": "", "birthQos": "0", "birthPayload": "", "closeTopic": "", "closePayload": "", "willTopic": "", "willQos": "0", "willPayload": "" } ]
[
    {
        "id": "abb6a4fea5021683",
        "type": "mqtt in",
        "z": "458ff8a6.218fa8",
        "name": "",
        "topic": "shellies/shellybutton1-11CDAC2C21D3/input_event/0",
        "qos": "2",
        "datatype": "auto",
        "broker": "8c74c5f6.9a7a48",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 320,
        "y": 760,
        "wires": [
            [
                "bebce75c2be0b54d"
            ]
        ]
    },
    {
        "id": "8eac36b9c194977b",
        "type": "comment",
        "z": "458ff8a6.218fa8",
        "name": "Shelly Button",
        "info": "",
        "x": 200,
        "y": 720,
        "wires": []
    },
    {
        "id": "699c63fede80052b",
        "type": "debug",
        "z": "458ff8a6.218fa8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 890,
        "y": 700,
        "wires": []
    },
    {
        "id": "604ae0babdcf3929",
        "type": "switch",
        "z": "458ff8a6.218fa8",
        "name": "",
        "property": "payload.event",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "S",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "SS",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "SSS",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "L",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 4,
        "x": 690,
        "y": 700,
        "wires": [
            [
                "699c63fede80052b",
                "5f289f050b9eea26"
            ],
            [
                "e895ce98af0a9c35"
            ],
            [
                "50c9c06fc3dbdcdd"
            ],
            [
                "06efa30e61695599"
            ]
        ]
    },
    {
        "id": "e895ce98af0a9c35",
        "type": "debug",
        "z": "458ff8a6.218fa8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 890,
        "y": 760,
        "wires": []
    },
    {
        "id": "50c9c06fc3dbdcdd",
        "type": "debug",
        "z": "458ff8a6.218fa8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 890,
        "y": 820,
        "wires": []
    },
    {
        "id": "06efa30e61695599",
        "type": "debug",
        "z": "458ff8a6.218fa8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 890,
        "y": 880,
        "wires": []
    },
    {
        "id": "bebce75c2be0b54d",
        "type": "json",
        "z": "458ff8a6.218fa8",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 600,
        "y": 780,
        "wires": [
            [
                "604ae0babdcf3929",
                "699c63fede80052b"
            ]
        ]
    },
    {
        "id": "5f289f050b9eea26",
        "type": "pushover",
        "z": "458ff8a6.218fa8",
        "name": "",
        "device": "",
        "title": "Alarm",
        "priority": "2",
        "sound": "persistent",
        "url": "",
        "url_title": "",
        "html": false,
        "x": 1150,
        "y": 640,
        "wires": []
    },
    {
        "id": "8c74c5f6.9a7a48",
        "type": "mqtt-broker",
        "name": "MQTTBROKER",
        "broker": "MQTTBROKER",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "15",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    }
]

Security cam ftp search major changes in images.

Last Updated or created 2022-12-01

Weird title i know.

I have several ip cameras which monitor movement in and around our home.

I’m using Zoneminder and other home automation systems but i want to scan through a bunch of files uploaded by the security cameras to my secondary fileserver.

So what is interesting?

  • Major movement compared to a base image
  • Movement compared to a previous uploaded image
  • Setting a threshold when to output information (note the 65% mark)
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
| 76 % | 1438 | SDAlarm_20221129-213515.jpg | 3145 | .......-.......................X.....................................................................
| 76 % | 1439 | SDAlarm_20221129-213517.jpg | 3661 | ..............-.....................X................................................................
| 76 % | 1440 | SDAlarm_20221129-213519.jpg | 3739 | ...........-.........................X...............................................................
| 77 % | 1441 | SDAlarm_20221129-213521.jpg | 3704 | .....-...............................X...............................................................
| 76 % | 1438 | SDAlarm_20221129-213515.jpg | 3145 | .......-.......................X..................................................................... | 76 % | 1439 | SDAlarm_20221129-213517.jpg | 3661 | ..............-.....................X................................................................ | 76 % | 1440 | SDAlarm_20221129-213519.jpg | 3739 | ...........-.........................X............................................................... | 77 % | 1441 | SDAlarm_20221129-213521.jpg | 3704 | .....-...............................X...............................................................
| 76 % | 1438 | SDAlarm_20221129-213515.jpg | 3145 | .......-.......................X.....................................................................
| 76 % | 1439 | SDAlarm_20221129-213517.jpg | 3661 | ..............-.....................X................................................................
| 76 % | 1440 | SDAlarm_20221129-213519.jpg | 3739 | ...........-.........................X...............................................................
| 77 % | 1441 | SDAlarm_20221129-213521.jpg | 3704 | .....-...............................X...............................................................

Looking at the output we see:
At 76% of the captured images (image 1438) the threshold was above 3000 and the minus gives us the information of the difference between this image and the previous, the X marks the difference between current image and the baseline.
| percent | image number | filename | difference | graphbar

Bash script:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#!/bin/bash
threshold=3000
baseline=$( ls SDAlarm*jpg | head -1)
previous=$( ls SDAlarm*jpg | head -1)
total=$( ls *.jpg |wc -l)
echo "Number of files : $total"
nr=1
ls *jpg | while read; do
graph="....................................................................................................."
diff=$(compare -verbose -metric MAE $baseline $REPLY /dev/null 2>&1 | grep all | awk '{ print $2 }' | cut -f1 -d. )
prevdiff=$(compare -verbose -metric MAE $previous $REPLY /dev/null 2>&1 | grep all | awk '{ print $2 }' | cut -f1 -d. )
line=$( echo "100 / $total * $nr" | bc -l | cut -f1 -d.)
line=$(( $line + 1))
#echo -n "$line | $nr | $REPLY | "
#echo $diff
draw1=$(( $diff / 100 + 1))
draw2=$(( $prevdiff / 100 + 1))
graph=$(echo $graph | sed "s/./X/$draw1")
graph=$(echo $graph | sed "s/./-/$draw2")
if [ $diff -gt $threshold ] ; then
printf "| %4s %% | %3s | %30s | %5s | %102s \n" $line $nr $REPLY $diff $graph
fi
nr=$(( $nr +1 ))
previous=$REPLY
done
#!/bin/bash threshold=3000 baseline=$( ls SDAlarm*jpg | head -1) previous=$( ls SDAlarm*jpg | head -1) total=$( ls *.jpg |wc -l) echo "Number of files : $total" nr=1 ls *jpg | while read; do graph="....................................................................................................." diff=$(compare -verbose -metric MAE $baseline $REPLY /dev/null 2>&1 | grep all | awk '{ print $2 }' | cut -f1 -d. ) prevdiff=$(compare -verbose -metric MAE $previous $REPLY /dev/null 2>&1 | grep all | awk '{ print $2 }' | cut -f1 -d. ) line=$( echo "100 / $total * $nr" | bc -l | cut -f1 -d.) line=$(( $line + 1)) #echo -n "$line | $nr | $REPLY | " #echo $diff draw1=$(( $diff / 100 + 1)) draw2=$(( $prevdiff / 100 + 1)) graph=$(echo $graph | sed "s/./X/$draw1") graph=$(echo $graph | sed "s/./-/$draw2") if [ $diff -gt $threshold ] ; then printf "| %4s %% | %3s | %30s | %5s | %102s \n" $line $nr $REPLY $diff $graph fi nr=$(( $nr +1 )) previous=$REPLY done
#!/bin/bash
threshold=3000
baseline=$( ls  SDAlarm*jpg | head -1)
previous=$( ls  SDAlarm*jpg | head -1)
total=$( ls *.jpg |wc -l)
echo "Number of files : $total"
nr=1
ls *jpg | while read; do
graph="....................................................................................................."
diff=$(compare -verbose -metric MAE $baseline $REPLY /dev/null  2>&1 | grep all | awk '{ print $2 }' | cut -f1 -d. )
prevdiff=$(compare -verbose -metric MAE $previous $REPLY /dev/null  2>&1 | grep all | awk '{ print $2 }' | cut -f1 -d. )
line=$( echo "100 / $total * $nr" | bc -l | cut -f1 -d.)
line=$(( $line + 1))
#echo -n "$line | $nr | $REPLY | "
#echo $diff
draw1=$(( $diff / 100 + 1))
draw2=$(( $prevdiff / 100 + 1))
graph=$(echo $graph | sed "s/./X/$draw1")
graph=$(echo $graph | sed "s/./-/$draw2")
if [ $diff -gt $threshold ] ; then
printf "| %4s %% | %3s | %30s | %5s | %102s \n" $line  $nr $REPLY $diff $graph
fi
nr=$(( $nr +1 ))
previous=$REPLY
done

Want to see only difference with previous image?

change:

if [ $diff -gt $threshold ] ; then
into
if [ $prevdiff -gt $threshold ] ; then