Tag Archives: bash

Gluster testing with docker

GlusterFS (Gluster File System) is an open source Distributed File System that can scale out in building-block fashion to store multiple petabytes of data.

Below is a test environment which creates 5 docker instances, which represent 5 gluster servers.
This was for test repairing our work gluster.

First install gluster and pull a image: docker pull gluster/gluster-centos

gethosts

for f in 1 2 3 4 5;
do 
echo "$(docker exec -it gluster_${f} ip a s | grep 172 | awk '{ print $2 }' | cut -f1 -d/) gluster_${f}"
done

create_dockers

for f in 1 2 3 4 5; do
docker run --name gluster_${f} --privileged=true -d gluster/gluster-centos /usr/sbin/init
done

create_bricks

for f in 1 2 3 4 5; do
docker exec -it gluster_${f} mkdir -p /bricks/brick01
done

destroy_dockers

for f in 1 2 3 4 5; do
docker stop gluster_${f}
docker rm gluster_${f}
done

diskcreator

for f in $(seq 1 5); do
dd if=/dev/zero of=/root/disk${f} count=1 bs=100M
losetup /dev/loop${f} /root/disk${f}
docker run --name gluster_${f} --privileged=true --device=/dev/loop${f} -d  gluster/gluster-centos /usr/sbin/init
done

lvm-dockers

modprobe dm_thin_pool (in docker)
modprobe dm_thin_pool (ook in VM zelf)
modprobe device-mapper ??

pvcreate /dev/loop0
vgcreate brick01 /dev/loop0
lvcreate -L 50M -T brick01 -n thin_brick01

lvcreate -V 40M -T brick01/thin_brick01 -n testvolume
mkfs -t xfs -i size=512 /dev/brick01/testvolume
mount /dev/brick01/testvolume /bricks/brick01

lvextend -L+10M /bricks/brick01
xfs_growfs /dev/brick01/testvolume
fash@fash-Vortex:~$ cat docker-lvm
modprobe dm_thin_pool (in docker)
modprobe dm_thin_pool (ook in VM zelf)
modprobe device-mapper ??

pvcreate /dev/loop0
vgcreate brick01 /dev/loop0
lvcreate -L 50M -T brick01 -n thin_brick01

lvcreate -V 40M -T brick01/thin_brick01 -n testvolume
mkfs -t xfs -i size=512 /dev/brick01/testvolume
mount /dev/brick01/testvolume /bricks/brick01

lvextend -L+10M /bricks/brick01
xfs_growfs /dev/brick01/testvolume

How to use

./create

./gethosts voor info

docker exec -it gluster_1 /bin/bash

# GEEN HOSTSNAMES INGEVULD!
gluster peer probe 172.17.0.2
gluster peer probe 172.17.0.3
gluster peer probe 172.17.0.4
gluster peer probe 172.17.0.5

Geen persistent storage aangemaakt evt kunnen we ook in de docker zelf testen

docker exec -it gluster_1 mkdir -p /bricks/brick01
docker exec -it gluster_2 mkdir -p /bricks/brick01
docker exec -it gluster_3 mkdir -p /bricks/brick01
docker exec -it gluster_4 mkdir -p /bricks/brick01

gluster volume create testvolume 172.17.0.2:/bricks/brick01 172.17.0.3:/bricks/brick01 172.17.0.4:/bricks/brick01 172.17.0.5:/bricks/brick01 force

gluster volume start testvolume

### NOG TE TESTEN
#gluster volume create testvolume replica 2 172.17.0.2:/bricks/brick01 172.17.0.3:/bricks/brick01 172.17.0.4:/bricks/brick01 172.17.0.5:/bricks/brick01 force

### NOG TE TESTEN
#gluster volume create testvolume replica 2 arbiter 1 172.17.0.2:/bricks/brick01 172.17.0.3:/bricks/brick01 172.17.0.4:/bricks/brick01 172.17.0.5:/bricks/brick01 force

mount -t glusterfs 172.17.0.2:/testvolume /media/

cd /media

touch {1..9}

exit

for f in 1 2 3 4 ; do echo "gluster_${f}" ; docker exec -it gluster_${f} ls /bricks/brick01 ;done

# DESTROY 
for f in 1 2 3 4 5; do 
docker stop gluster_${f}
docker rm gluster_${f}
done

Howto reset-replicated-brick-same-server

Using clean glusterdockers

./create_dockers
./create_bricks
./gethosts

# docker exec -it gluster_1 /bin/bash


# gluster peer probe 172.17.0.2
# gluster peer probe 172.17.0.3
# gluster peer probe 172.17.0.4
# gluster peer probe 172.17.0.5

# Gluster peer status 
----------------------------------
(peers = 3 + localhost maakt 4 ;-)

# gluster volume create testvolume replica 2 172.17.0.2:/bricks/brick01 172.17.0.3:/bricks/brick01 172.17.0.4:/bricks/brick01 172.17.0.5:/bricks/brick01 force

# gluster volume start testvolume ; gluster volume info testvolume
----------------------------------

Volume Name: testvolume
Type: Distributed-Replicate
Volume ID: e5536d11-77ee-40a5-9282-e4223979f443
Status: Started
Snapshot Count: 0
Number of Bricks: 2 x 2 = 4
----------------------------------


# mount -t glusterfs 172.17.0.2:/testvolume /media/
# cd /media
# touch {1..9}

# exit

From dockerhost we see the files nicely spread over the bricks

# for f in 1 2 3 4 ; do echo "gluster_${f}" ; docker exec -it gluster_${f} ls /bricks/brick01 ;done
------------------------------------------------------------------------
gluster_1
1  5  7  8  9
gluster_2
1  5  7  8  9
gluster_3
2  3  4  6
gluster_4
2  3  4  6
---------------------------------------------------------------------------------



Logon op gluster_3
# docker exec -it gluster_3 /bin/bash
# rm -rf /bricks

- wacht ff -

# gluster volume status
----------------------------------------------------------------------------
Status of volume: testvolume
Gluster process                             TCP Port  RDMA Port  Online  Pid
------------------------------------------------------------------------------
Brick 172.17.0.2:/bricks/brick01            49152     0          Y       210  
Brick 172.17.0.3:/bricks/brick01            49152     0          Y       151  
Brick 172.17.0.4:/bricks/brick01            N/A       N/A        N       N/A   <----- gone  
Brick 172.17.0.5:/bricks/brick01            49152     0          Y       152 
----------------------------------------------------------------------------

# exit

From dockerhost:

# for f in 1 2 3 4 ; do echo "gluster_${f}" ; docker exec -it gluster_${f} ls /bricks/brick01 ;done
------------------------------------------------------------------------------------
gluster_1
1  5  7  8  9
gluster_2
1  5  7  8  9
gluster_3
ls: cannot access /bricks/brick01: No such file or directory
gluster_4
2  3  4  6
--------------------------------------------------------------------------------------

Logon on gluster_1
# docker exec -it gluster_1 /bin/bash

# gluster volume reset-brick testvolume 172.17.0.4:/bricks/brick01 start

#This is the moment to swap the md3260, but we are using here the next commands:

Create new storage on gluster_3
# docker exec -it gluster_3 mkdir -p /bricks/brick01 
# docker exec -it gluster_3 ls /bricks/brick01 

Logon on gluster_1
# docker exec -it gluster_1 /bin/bash

# gluster volume reset-brick testvolume 172.17.0.4:/bricks/brick01  172.17.0.4:/bricks/brick01 commit force


[root@svr1035 ~]# 


From dockerhost we see the files nicely spread over the bricks

# for f in 1 2 3 4 ; do echo "gluster_${f}" ; docker exec -it gluster_${f} ls /bricks/brick01 ;done
------------------------------------------------------------------------
gluster_1
1  5  7  8  9
gluster_2
1  5  7  8  9
gluster_3
2  3  4  6
gluster_4
2  3  4  6
---------------------------------------------------------------------------------

Laser engrave tools

For my winerack i engraved some wooden panels.

When doing so, i needed to fix the height of the engraver to get the focus of the beam right.

At start i removed all Z positions from the GCODE file after calibrating. Later i used a script wrote that fixed the height setting to 110.

#!/bin/bash
# Usage: confirm height focus at 110
# ./scriptname filetofix.gcode
myz=110
cat "$1" | sed s/Z1/Z${myz}/g | sed s/Z6/Z${myz}/g > "fixed.$1"

Another tool i made is the one below, it takes a GCODE file, calulates where the borders are (min/max x and y)
And sets the FAN2 (laser intensity to a minimum)
After that it generates GCODE to draw a box wherein the to be engraved object is made

Now you can run the GCODE file multiple times to position it on the wood to you can get the minimum of spoils.

#!/bin/bash
# Usage: scriptname file.gcode 
# It wil create a pointtest file for test running
myz=110
MAXX=$(cat "$1" | grep "G0 X" | awk '{ print $2 }' | cut -c2- | sort -n | tail -1)
MINX=$(cat "$1" | grep "G0 X" | awk '{ print $2 }' | cut -c2- | sort -n | head -1)
MAXY=$(cat "$1" | grep "G0 X" | awk '{ print $3 }' | cut -c2- | sort -n | tail -1)
MINY=$(cat "$1" | grep "G0 X" | awk '{ print $3 }' | cut -c2- | sort -n | head -1)

cat > "pointtest - $1" << EOF
;BingoStart
G90
M17 Z
G0 F3000
G0 Z${myz} F3000
M18 Z
G0 X${MINX} Y${MINY}
M106 S2
G0 F3000
G0 X${MINX} Y${MAXY}
M106 S2
G0 F3000
G0 X${MAXX} Y${MAXY}
M106 S2
G0 F3000
G0 X${MAXX} Y${MINY}
M106 S2
G0 F3000
G0 X${MINX} Y${MINY}
M106 S2
G0 F3000
G0 X${MINX} Y${MAXY}
M106 S2
G0 F3000
G0 X${MAXX} Y${MAXY}
M106 S2
G0 F3000
G0 X${MAXX} Y${MINY}
M106 S2
G0 F3000
G0 X${MINX} Y${MINY}
M106 S2
M107
;end
EOF

GCODES

  • M17 Z – disable Z movement
  • G0 – rapid move
    G0 X100 Y100 (Goto 100,100)
    G0 F3000 (speed)
  • M106 – set fan speed (I my case, this is laser intensity)
    M106 – S2
  • G90 – set absolute coordinates
  • M107 – fan off

More info about gcodes: http://www.science.smith.edu/cdf/pdf_files/Techno_GCODE%20Commands.pdf

Wacom tablet doesn’t behave

Changed some code controlling my wacom drawing tablet.
I use this one to draw Art, diagrams and touch up photo’s.

When using multiple screens, i had the problem it would stretch the draw area over multiple screens, streching the ratio. Or it took the work screen to work on.

#!/bin/bash
# using xinput here, check post about two mouses/keyboards on one machine

# Use xrandr to check names check 
MONITOR="DP-1"
PAD_NAME='Wacom BambooFun 6x8 Pad pad'

#undo
xsetwacom --set "$PAD_NAME" Button 1 "key +ctrl +z -z -ctrl" 
xsetwacom --set "$PAD_NAME" Button 2 "key e"
xsetwacom --set "$PAD_NAME" Button 3 "key h"

ID_STYLUS=`xinput | grep "Pen stylus" | cut -f 2 | cut -c 4-5`
xinput map-to-output $ID_STYLUS $MONITOR
ID_STYLUS_2=`xinput | grep "Pen eraser" | cut -f 2 | cut -c 4-5`
xinput map-to-output $ID_STYLUS_2 $MONITOR

exit 0

Most of the times i use Krita and Gimp.

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.

An obfuscated view of the 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

Garbage display

I wanted to know when trash is being collected. So i made a dual led thingy.

Version without lid .. just to test

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

Arpscanner

Changed stuff in my arpscanner

I want to know whats on my network, and be informed when a alien device connects.
This also helps me gathering all devices and macaddresses for a cmdb.

I’ve got below in my crontab

5 * * * * root /usr/local/bin/arpscanner

And the script:

#!/bin/bash
# Using a scanner on a specific vlan/interface
arp-scan -l -g  -I p1p1.10 | grep ^10 | grep -vi packets > /var/log/arpscanner
cat /var/log/arpscanner | awk '{ print $2 }'| while read ; do
grep $REPLY /var/local/arpscanner.lst >/dev/null || echo $REPLY | mail -s arpscanner henri@henriaanstoot.nl
done

New and checked devices i put in the file mentioned above:
/var/local/arpscanner.lst

                00:21:5d:gg:gg:7a       Description
                ac:67:b2:gg:gg:a0       Liligo Twatch
                b8:27:eb:gg:dd:fd       Nieuwe octoprint
                d8:f1:5b:gg:gg:4a       WLAN Dungeon
                48:3f:da:gg:gg:fe       Uboot ESP
                8e:93:79:gg:gg:5d       Tablet Monique
                d8:f1:5b:gg:gg:06       ESP Radar
                dc:a6:32:gg:gg:fb       RPI4
                00:1e:ec:gg:gg:ab       laptop
                68:05:ca:gg:gg:68       storage bak

        etcetera

Mount Taranaki New Zealand

While traveling New Zealand we went to see Mt Taranaki

Mount Taranaki (Māori: Taranaki Maunga), also known as Mount Egmont, is a dormant stratovolcano in the Taranaki region on the west coast of New Zealand’s North Island. It is the second highest point in the North Island, after Mount Ruapehu.

I made this timelapse using a Nikon D750.

Convert a series of jpgs into a 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 output.mp4

Password generator dutch

Generates easy to remember passwords, using 3 words and a number

EXAMPLES:
TotaalHeuvelSorry25
ZorgenEnkeleDubbel42
TweedeMaalCadeau18
BlauwMamaZeep99
NetFoutFles88
KeusZijDaar18
AanbodVuurKaart98
ReddenGelijkHaan68
WakkerLatenHaten47

Words in list below are generated on lenght and SFW.
For getting a list of words a certain lenght use:

# Words between 4 and 7 characters
grep -o -w '\w\{4,7\}' /usr/share/dict/dutch
# Didn't use wordlist above due to many not easyly to remember words.
#!/bin/bash
me=`basename "$0"`
cat $me | sed '1,/^WOORDEN$/d' | shuf | head -3 | while read ; do echo -n $REPLY ;done ; echo $(shuf -i 10-99 -n 1)
exit 0
WOORDEN
Aan
Aanbod
Aanval
Aap
Aarde
Aardig
Acht
Achter
Actief
Ademen
Afname
Afval
Alleen
Alles
Als
Altijd
Ander
Andere
Anders
Angst
Appel
Arm
Auto
Avond
Baan
Baby
Bad
Bal
Bang
Bank
Basis
Bed
Been
Beer
Beest
Beetje
Begin
Begrip
Beide
Beker
Bel
Bellen
Berg
Beroep
Best
Beter
Bezoek
Bieden
Bij
Bijna
Bijten
Binnen
Blad
Blauw
Blazen
Blij
Bloed
Bloem
Bodem
Boek
Boete
Boom
Boon
Boord
Boos
Bord
Bos
Bot
Bouwen
Boven
Breed
Breken
Brief
Broer
Broek
Brood
Brug
Bruin
Bui
Buiten
Bureau
Buren
Bus
Cadeau
Cirkel
Cool
Daar
Daarom
Dag
Dak
Dan
Dansen
Dapper
Dat
Deel
Deken
Deksel
Delen
Derde
Deze
Dienen
Diep
Dier
Dik
Ding
Dit
Doen
Dom
Donker
Dood
Door
Doos
Dorp
Draad
Dragen
Drie
Drogen
Dromen
Droog
Druk
Dubbel
Dun
Dus
Duur
Duwen
Echt
Een
Één
Eend
Eerste
Eeuw
Effect
Eigen
Eiland
Einde
Eis
Elk
Enkele
Erg
Eten
Even
Examen
Falen
Feest
Feit
Fel
Fijn
Film
Fit
Fles
Foto
Fout
Fris
Fruit
Gaan
Gat
Gebied
Gedrag
Geel
Geen
Geit
Geld
Gelijk
Geloof
Geluid
Geluk
Gemak
Gemeen
Genoeg
Genot
Geur
Gevaar
Geven
Gevolg
Gewoon
Gezond
Gif
Glad
Glas
God
Goed
Goud
Graf
Grap
Gras
Grens
Grijs
Groen
Groep
Grof
Grond
Groot
Haan
Haar
Haast
Hal
Halen
Half
Hallo
Hamer
Hand
Hard
Hart
Haten
Hebben
Heel
Heet
Helder
Helft
Help
Hem
Hemel
Hen
Herfst
Hert
Het
Heuvel
Hier
Hij
Hobby
Hoe
Hoed
Hoek
Hoewel
Hond
Honger
Hoofd
Hoog
Hoogte
Hoop
Horen
Hotel
Houden
Huilen
Huis
Hun
Huren
Hut
Huur
Idee
Ieder
Iemand
Iets
Ijs
Ijzer
Jaar
Jagen
Jas
Jij
Jong
Jongen
Jouw
Jullie
Kaars
Kaart
Kaas
Kamer
Kans
Kant
Kap
Kast
Kat
Kennen
Kennis
Keuken
Keus
Kiezen
Kijken
Kind
Kip
Kist
Klaar
Klas
Klasse
Kleden
Klein
Kleren
Kleur
Klok
Klopt
Knie
Koers
Koffer
Koffie
Kok
Koken
Kom
Komen
Koning
Koorts
Kop
Kopen
Kort
Kost
Kosten
Koud
Kraam
Kracht
Krant
Kruis
Kuil
Kunnen
Kunst
Laag
Laat
Laatst
Lach
Lachen
Ladder
Laken
Lamp
Land
Lang
Langs
Laten
Leeg
Leeuw
Leger
Leiden
Lenen
Lengte
Lepel
Leren
Les
Leuk
Leven
Lezen
Licht
Liefde
Liegen
Liggen
Lijk
Lijken
Links
Lip
List
Lomp
Lood
Lopen
Los
Lot
Lucht
Lui
Lunch
Maag
Maal
Maan
Maand
Maar
Maat
Maken
Mama
Man
Mand
Manier
Map
Markt
Meel
Meer
Meest
Meisje
Melk
Meneer
Mensen
Mes
Met
Meubel
Middel
Midden
Mij
Mijn
Min
Minder
Minuut
Mis
Missen
Mits
Model
Modern
Moeder
Moeten
Mogen
Moment
Mond
Mooi
Moord
Morgen
Munt
Muziek
Naald
Naam
Naar
Naast
Nacht
Nat
Natuur
Nee
Neer
Negen
Nek
Nemen
Net
Netjes
Neus
Niet
Niets
Nieuw
Nieuws
Nobel
Noch
Nodig
Noemen
Nog
Nood
Nooit
Noord
Noot
Nul
Nummer
Object
Oceaan
Offer
Olie
Oma
Onder
Oneven
Ons
Onze
Oog
Ooit
Ook
Oom
Oor
Oorlog
Oost
Opa
Opeens
Open
Oranje
Orde
Oud
Ouder
Over
Overal
Paar
Paard
Pad
Pagina
Pan
Papa
Papier
Park
Pas
Pen
Peper
Per
Piano
Pijn
Plaat
Plaats
Plank
Plant
Plat
Plein
Plus
Poes
Poort
Praten
Prijs
Prins
Privé
Punt
Raak
Raam
Radio
Raken
Recht
Rechts
Redden
Reeds
Regen
Reiken
Reizen
Rennen
Rest
Rijk
Rijst
Rijzen
Ring
Rok
Rond
Rood
Rook
Rots
Roze
Rubber
Ruiken
Ruimte
Samen
Sap
Schaap
Schaar
Scherp
Schip
School
Schoon
Sex
Simpel
Sinds
Slapen
Slecht
Slim
Slot
Smaak
Smal
Sneeuw
Snel
Soep
Sok
Soms
Soort
Sorry
Spel
Spelen
Sport
Staal
Stad
Stap
Start
Steen
Stelen
Stem
Ster
Sterk
Steun
Stil
Stilte
Stoel
Stof
Stom
Stop
Storm
Straat
Studie
Stuk
Succes
Suiker
Taal
Taart
Tafel
Tak
Tand
Tante
Tas
Taxi
Team
Teen
Tegen
Teken
Tellen
Tennis
Terug
Test
Thee
Thuis
Tien
Tijd
Titel
Toen
Totaal
Traan
Tram
Trein
Trui
Tuin
Tussen
Tweede
Uit
Uur
Vaak
Vader
Vak
Vallen
Vals
Van
Vangen
Varken
Vast
Veel
Veer
Veilig
Ver
Verder
Verf
Vers
Vet
Vier
Vies
Vijand
Vijf
Vijver
Vinden
Vinger
Vis
Vlag
Vlees
Vlieg
Vloer
Voeden
Voelen
Voet
Vogel
Vol
Voor
Vork
Vorm
Vos
Vouwen
Vraag
Vragen
Vrede
Vreemd
Vriend
Vrij
Vroeg
Vrouw
Vullen
Vuur
Waar
Waarom
Wakker
Want
Wapen
Warm
Wassen
Wat
Water
Week
Weer
Weg
Welke
Welkom
Wens
Wereld
Werk
West
Wie
Wiel
Wij
Wijn
Wijs
Wild
Willen
Wind
Winkel
Winnen
Winter
Wissen
Wit
Wolf
Wolk
Wonder
Woord
Woud
Wreed
Zaak
Zacht
Zak
Zand
Zee
Zeep
Zeer
Zeggen
Zeil
Zeker
Zelfde
Zes
Zetten
Zeven
Ziek
Ziel
Zien
Zij
Zijn
Zilver
Zingen
Zinken
Zitten
Zoals
Zoeken
Zoet
Zomer
Zon
Zonder
Zonnig
Zoon
Zorg
Zorgen
Zou
Zout
Zuid
Zulke
Zullen
Zus
Zwaar
Zwak

X-plane on linux

Starting x-plane can be a problem on Linux when screens are not properly detected. (Like order of screens or sizes)

Below is a three-screen start script for Linux.

#!/bin/bash
#Will start a three screen xplane session
#Screen are @ 1920x1080 resolution
numscreens=3
count=0
if [ -z $1 ] ; then
./X-Plane-x86_64 --monitor_bounds=0,0,1920,1080,1920,0,1920,1080,3840,0,1920,1080
 while [  $count -lt $numscreens ]; do
    sleep 1
    count=$( wmctrl -l | grep X-System | wc -l)
 done
fi
screencount=1
wmctrl -l | grep X-Syst |awk '{ print $1 }' | while read ; do 
	wmctrl -i -r "$REPLY" -T "X-System_$screencount"
	let  screencount=screencount+1
done
wmctrl -r "X-System_1" -e 1,0,0,1920,1080
wmctrl -r "X-System_2" -e 1,1920,0,1920,1080
wmctrl -r "X-System_3" -e 1,3840,0,1920,1080

Fun with Xrandr

xrandr is an official configuration utility to the RandR (Resize and Rotate) X Window System extension. It can be used to set the size, orientation or reflection of the outputs for a screen.

Someone broke my screen at a hackers event. The terminal was really hard to read with the black parts, so i tilted the screen

Quiet friday at work, playing with my little trusty 2530p.
I’m using xmonad, so i don’t need any fancy work laptop.

Another quiet friday at work, working from home, i turned all monitoring displays upside-down, sideways, or rotated them every so much seconds.

While this is a lot of fun to use, i used this to get my monitorsetups exactly the way i wanted, at home or at work.
Different screen sizes, height differences .. no problem.

A fun tool to use is:
https://github.com/qurn/xrandr-keystone-helper

Some scripts:

# VGA off
xrandr --output VGA1 --off

# examples
xrandr --output LVDS1 --mode 1280x800 --output VGA1 --mode 1280x1024 --pos 0x1280 --left-of LVDS1
xrandr --output LVDS-1 --mode 1280x800 --output SVIDEO-1 --mode 1920x1080 --pos 0x0 --left-of SVIDEO-1
xrandr --output LVDS-1 --mode 1280x800 --pos 0x1920 --output VGA-1 --mode 1920x1080 --pos 0x2200 --right-of LVDS-1 --output DVI-I-1-1 --mode 1920x1080 --pos 0x0 --left-of LVDS-1

# zoomthingy
xrandr --output VGA1 --mode 1920x1080 --panning 1920x1080
xrandr --output VGA1 --mode 640x480 --panning 1920x1080+2910+0 --scale 1x1

# fix detection
xrandr --setprovideroutputsource 1 0

# add mode
xrandr --addmode DP-1 1440x720

# transform (see also terminal picture above)
xrandr --output LVDS --mode 1366x768 --panning 1166x768 --transform 1,0,-200,0,1,0,0,0,1

# Funky stuff
for f in `seq 1 9` ;do echo xrandr --output LVDS1 --transform 0.5403,-0.8$(echo -n $f)41,0,0.841,0.5403,0,0,0,1.5 ; sleep 5; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do echo xrandr --output LVDS1 --transform 0.5403,-0.8$f41,0,0.841,0.5403,0,0,0,1.5 ; sleep 5; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.1$(echo -n $f)5403,-0.8$(echo -n $f)41,0,0.841,0.5403,0,0,0,1.5 ; sleep 2; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.4$(echo -n $f)5403,-0.8$(echo -n $f)41,0,0.5$(echo -n $f)841,0.5403,0,0,0,1.5 ; sleep 1; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.4$(echo -n $f)5403,-0.8$(echo -n $f)41,0,0.5$(echo -n $f)841,0.5$(echo -n $f)403,0,0,0,1.5 ; sleep 1; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.4$(echo -n $f)5403,-0.8$(echo -n $f)41,0,0.$(echo -n $f)841,0.5403,0,0,0,1.5 ; sleep 2; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.5403,-0.8$(echo -n $f)41,0,0.841,0.5403,0,0,0,1.5 ; sleep 5; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.5403,-0.8$f41,0,0.841,0.5403,0,0,0,1.5 ; sleep 5; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.5$(echo -n $f)403,-0.8$(echo -n $f)41,0,0.8$(echo -n $f)41,0.5$(echo -n $f)403,0,0,0,1.5 ; sleep 5; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.5$f403,-0.841,0,0.841,0.5403,0,0,0,1.5 ; sleep 5; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.5$f403,-0.841,0,0.841,0.5403,0,0,0,1.5 ; sleep 5; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1; done
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.$(echo -n $f)5403,-0.8$(echo -n $f)41,0,0.841,0.5403,0,0,0,1.5 ; sleep 2; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
for f in `seq 1 9` ;do xrandr --output LVDS1 --transform 0.$f403,-0.841,0,0.841,0.5403,0,0,0,1.5 ; sleep 5; done ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.1,0.1,0,0.1,1,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform -0.11038,0.993888,0,-0.99388,-0.11038,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform -0.11,0.99,0,-0.99,-0.11,0,0,0,1
xrandr --output LVDS1 --transform 0.15425,0.988,0,-0.988,0.15425,0,0,0,1
xrandr --output LVDS1 --transform 0.2,-0.2,0,0.2,0.2,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5,-0.5,0,0.5,0.5,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5,0.5,0,0.5,1,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.54030,-0.841,0.841,0.54030,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.54030,-0.841,0.841,0.5403,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0,0,0.1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0,0,1.1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0,0.1,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform -0.5403,-0.841,0,0.841,0.5403,0,0,0,1.5 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,-0.841,0.5403,0,0,0,1.5 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,-0.5403,0,0,0,1.5 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0,0,1.5 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,0.841,0,0.841,0.5403,0,0,0,1.5 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0,0,1 --scale 2x2; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0,0,2 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0,0.1,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0,0.841,0.5403,0.1,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0.1,0.841,0.5403,0,0,0,1.5 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0.1,0.841,0.5403,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.5403,-0.841,0.841,0.5403,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.9,-0.1,30,0.1,0.9,-80,0,0,0.8 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.9,-0.9,0,0.9,0.9,0,0,0,1 --scale 1.1x1.1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.9,-0.9,0,0.9,0.9,0,0,0,1 --scale 1.5x1.5 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.9,-0.9,0,0.9,0.9,0,0,0,1 --scale 2x2 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.9,-0.9,0,0.9,0.9,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 0.9,-0.9,-0.1,30,0.1,0.9,-80,0,0,0.8 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 1.1,1.1,0,1.1,1,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1
xrandr --output LVDS1 --transform 2.1,2.1,0,2.1,1,0,0,0,1 ; sleep 5 ; xrandr --output LVDS1 --transform 0,0.10,-124,0,1.24,0,0,0.000316,1 --scale 1x1