All posts by fash

MQTT Keyboard

A fancy keyboard….. At last a clickety keyboard. A Razer Blackwidow V3 mechanical keyboard. I’m not a gamer, but i like the clickety sounds. RGB leds are always nice to play with.

One of the nice things about razer is the Linux support!

Some nice links:

https://github.com/openrazer/openrazer

https://openrazer.github.io/

Even several python scripts can be found, but no MQTT.
So made a fast ‘n simple hack to control my keyboard with mqtt/nodered.

When someone is at the frontdoor, my keyboard changes from white to red.

Below a node-red example

My python code:

import paho.mqtt.client as mqttClient
import time
import os
import subprocess
import json

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):
    subprocess.Popen(["razer-cli", "-c", message.payload])

Connected = False

broker_address = "your.mqtt.brokerip.here"
port = 1883
#user = "user"
#password = "password"
client = mqttClient.Client("mqttrazer")
#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('razer/in')

try:
    while True:
        time.sleep(1)

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

Android / Oculus Quest screen record

Needed a way to record stuff from phone and VR set, found scrcpy.

A really usefull tool, you can control you phone, and what i was looking for .. screen record.

Used this to show via Jitsi screen share, how to do stuff on your phone.

scrcpy –record file.mkv

https://github.com/Genymobile/scrcpy#copy-paste

Switch fullscreen modeMOD+f
Rotate display leftMOD+ (left)
Rotate display rightMOD+ (right)
Resize window to 1:1 (pixel-perfect)MOD+g
Resize window to remove black bordersMOD+w | Double-left-click¹
Click on HOMEMOD+h | Middle-click
Click on BACKMOD+b | Right-click²
Click on APP_SWITCHMOD+s | 4th-click³
Click on MENU (unlock screen)⁴MOD+m
Click on VOLUME_UPMOD+ (up)
Click on VOLUME_DOWNMOD+ (down)
Click on POWERMOD+p
Power onRight-click²
Turn device screen off (keep mirroring)MOD+o
Turn device screen onMOD+Shift+o
Rotate device screenMOD+r
Expand notification panelMOD+n | 5th-click³
Expand settings panelMOD+n+n | Double-5th-click³
Collapse panelsMOD+Shift+n
Copy to clipboard⁵MOD+c
Cut to clipboard⁵MOD+x
Synchronize clipboards and paste⁵MOD+v
Inject computer clipboard textMOD+Shift+v
Enable/disable FPS counter (on stdout)MOD+i
Pinch-to-zoomCtrl+click-and-move
Drag & drop APK fileInstall APK from computer
Drag & drop non-APK filePush file to device

Ipcam sphere panorama

I made a little script to make a 360 spherical panorama photo, using a remote controlled IP cam,

Looking at the API CGI, i only needed to control the movement of the camera and getting a snapshot.

  • Point camera down
  • Point camera maximal left
  • Take picture
  • Point a little to the right
  • Take picture, loop until max right
  • Point a little more up and go max left
  • Doing same loop as above, until pointing maximal up
Made a little animation in blender

After getting all those pictures, i only needed to stitch them using Hugin.
When viewing the image with VR Glasses, i could look around my room, without image distortion, like below flattend example.

The ipcam generates a token, which you have to use in your curl commands.

TOKEN PART

token=$( curl -s -d  '[{"cmd":"Login","action":0,"param":{"rs": "abcd", "User":{"userName":"admin","password":"SECRETPASSWORD"}}}]'  "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=Login&token=null"  -H 'Content-Type: application/json' | grep name | cut -f4 -d\" )

GETTING A IMAGE FROM IPCAM

wget "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=Snap&channel=0&rs=123asd&user=admin&password=SECRETPASSWORD" -O output.jpg

CONTROLLING MOVEMENT

curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"Left","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"

COMPLETE SCRIPT

#!/bin/bash
token=$( curl -s -d  '[{"cmd":"Login","action":0,"param":{"rs": "abcd", "User":{"userName":"admin","password":"SECRETPASSWORD"}}}]'  "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=Login&token=null"  -H 'Content-Type: application/json' | grep name | cut -f4 -d\" )
echo $token

if [ $2 == "max" ]; then
curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"'$1'","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"
exit 0
fi


for x in $(seq -w 1 25) ; do
	for y in $(seq -w 1 12) ; do
                wget "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=Snap&channel=0&rs=123asd&user=admin&password=SECRETPASSWORD" -O ${x}${y}.jpg
		curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"Right","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"
		sleep 0.5
		curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"Stop","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"
		sleep 5
	done

	curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"Left","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"
	sleep 30
	curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"Stop","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"
	sleep 1
        curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"Up","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"
	sleep 0.5
	curl -X POST  -d '[{"cmd":"PtzCtrl","action":0,"param":{"rs": "abcd", "channel":0,"op":"Stop","speed":1,"id":1}}]' "http://camera.ip.number.here/cgi-bin/api.cgi?cmd=PtzCtrl&token=$token"
sleep 5
done
1st panorama (Black and White due to night mode camera)

Books read / to read (Paper and Calibre)

  • Je hebt wel iets te verbergen
  • Missing microbe’s
  • John Cleese
  • Michael McIntyre
  • Komt een vrouw bij de hacker
  • The cathedral and the bazaar
  • Ons feilbare denken
  • Singularity is near
  • Randall Munro books
  • Dat wordt niets met Bert Visscher (read, see other post)
  • Ultimate Cigar Book
  • Oak Island

But most of the times manuals/howto books about beer, fermenting, computers .. reference guides.

We used to have a lot of books, but when Monique moved out she took a lot with her. And i’ve got a lot of digital versions of books now. We needed the space, so i got rid of the paper ones.

I’m using Calibre and Calibre in server mode, to access my ebooks and comics.

I use fbreader a lot and sometimes the calibre webreader.
My tunebooks are in there also, and i’m using my DIY bluetooth pageflipper to flip though the pages. (Other post)

Calibre in server mode

 ./calibre-server --userdb /home/fash/calibreusers.sqlite  /tank/Calibre/library /tank/Calibre/adult /tank/Calibre/sortedlibrary /tank/Calibre/comics /tank/Calibre/computer /tank/Calibre/manuals /tank/Calibre/PdfMusic /tank/Calibre/Nasla
g --port=8008 --enable-auth --auth-mode 'basic'

# To manage users
# calibre-server --userdb /srv/calibre/users.sqlite --manage-users

# Server is behind a reverse proxy

Some comics i’ve collected are:

  • Stamgasten
  • Dirkjan
  • Storm
  • Kuifje (TinTin)
  • Klepzeiker
  • Koen Hottentot
  • Guust Flater
  • Maus
  • Metal Hurlant

RTMP / RTSP / HLS Streaming video

UPDATE: 20220906 – Started testing with steaming VR/360 also

RTMP stands for Realtime Messaging Protocol
RTSP stands for Realtime Streaming Protocol
HLS is a HTTP Live Streaming method

I needed a way to stream semi-realtime video to a website.
There are multiple use cases.

  • Streaming a boardgame online
  • Showing my desktop, while i was working on projects.
  • Watched (streamed) Curse of Oak Island with some friends while being in a Jitsi meeting at the same time together.

In all cases i used OBS to stream to the website.

Prepare the stream server:

Install nginx, with the rtmp module

wget http://nginx.org/download/nginx-1.9.7.tar.gz
wget https://github.com/arut/nginx-rtmp-module/archive/master.zip
tar -xvf nginx-1.9.7.tar.gz
unzip master.zip
cd nginx-1.9.7
./configure --add-module=../nginx-rtmp-module-master/
make && make install
mkdir -p /HLS/live/test # live is the stream name, test is the pass key
chown -R {nginx user} /HLS

create a config file

worker_processes  1;
error_log  logs/error.log debug;
events {
worker_connections  1024;
}
rtmp {
server {
listen 1935;
allow play all;

application live {
allow play all;
live on;
record all;
record_path /video_recordings;
record_unique on;
hls on;
hls_nested on;
hls_path /HLS/live;
hls_fragment 10s;

}

application vod {
play /video_recordings;
}

http {
include       mime.types;
default_type  application/octet-stream;

server {
listen 80;
server_name www.fash.nu;
add_header Access-Control-Allow-Origin *;

location /live {
types {
application/vnd.apple.mpegurl m3u8;
}
alias /HLS/live;
add_header Cache-Control no-cache;
}

location /mobile {
types {
application/vnd.apple.mpegurl m3u8;
}
alias /HLS/mobile;
add_header Cache-Control no-cache;
}

location / {
root   html;
index  index.html index.htm;
}
}

You need a webpage containing the embedded player

<!-- HTML -->
<video id='hls-example'  class="video-js vjs-default-skin" width="400" height="300" controls>
<source type="application/x-mpegURL" src="http://www.fash.nu:8080/live/test/index.m3u8">
</video>


<!-- JS code -->
<!-- If you'd like to support IE8 (for Video.js versions prior to v7) -->
<script src="https://vjs.zencdn.net/ie8/ie8-version/videojs-ie8.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.14.1/videojs-contrib-hls.js"></script>
<script src="https://vjs.zencdn.net/7.2.3/video.js"></script>

<script>
var player = videojs('hls-example');
player.play();
</script>

Run the server part:

/usr/local/nginx/sbin/nginx -c /root/stream.conf

Now you can connect OBS to the streaming server

Open the webpage and enjoy!

2nd webcam showed card details. Also text boxes appeared who’s turn it was.

UPDATE: 20220906 – Started testing with steaming VR/360 also

When attending the MCH2022 talk about streaming 360 video, i made a mental note to try this with my Vuze cam, using current setup and the one suggested in the talk : https://www.youtube.com/watch?v=460vo1O5pC4

To check : EGJS

Vuze Android App

Top beers i wrote down, or remembered

BEERBREWER
Trinity in blackpuhaste estland
Funky FalconTwo chefs brewing
Troubadour MagmaThe Musketeers
Hop zij met onsJopen
Smoked wheat everydayJopen
De verloren zoon #7Jopen
Double denim smoked barley wineTempest Brewing
GuinnessGuinness
Duchesse de bourgogneBrouwerij Verhaeghe Vichte
WestvleterenWestvleteren
Baltic DubbelInsel Brauerei
Birra NazionaleBaladin
Sans PardonDochter van de korenaar
StaalBier door mannen
Ola dubh 12Harviestoun Brewery
Dark IslandOrkney Brew
Brewer’s Reserve Brandy Barrel BarleywineCentral Waters