JTK – Notes and Ramblings Things we have found …

9/13/2024

PiKVM Notes

Filed under: General — taing @ 3:43 pm

We started the journey with the Geekworm KVM-A3 Kit for Raspberry Pi 4 kit from Amazon.com. Add a Raspberry Pi 4, power supply and sd card to get started.

Both the PiKVM instruction and the Geekworm instructions are handy to have. You will need to download the PiKVM image (PiKVM V3 HAT BOX Image, OLED/FAN preactivated). We created the SD using RPi Imager.

For us the RTC and the OLED display were enabled out of the box. We did need to purchase a CR1220 3v Lithium button battery for the RTC.

You will want to get the clock set and syncing correctly. The steps below must be done as root with the filessystem set to rw. Remember to set the file system back to ro when done.

  • set the timezone
    • timedatectl set-timezone America/New_York)
  • temporarily disable systemd-timesyncd
    • systemctl stop systemd-timesyncd
  • set the correct time
    • timedatectl set-time 'YYYY-MM-DD HH:MM:SS'
  • update /etc/systemd/timesyncd.conf
    • nano /etc/systemd/timesyncd.conf
      • NTP="10.101.1.101"
  • restart systemd-timesyncd
    • systemctl stop systemd-timesyncd

Setting the static address is described in the PiKVM FAQ. It involves editing /etc/systemd/network/eth0.network.

The device we wanted to control had Display Port out. We added a DisplayPort to HDMI & DisplayPort adapter to allow the on-site KVM to share the screen with the PiKVM. It should be noted that with the adapter we chose the primary monitor is the HDMI output. In our case that requires a bit of fiddling after a reboot to get the two displays to mirror and not extend.

We also found that for our remote access www solution the display needed to be set to MJPEG/HTTP instead of the default H.264/WebRTC mode.

7/6/2024

Pi Weather Radio Updates

Filed under: General — taing @ 10:42 pm

After updating the Pi to Bookworm things didn’t seem to work correctly for the Pi SDR Weather Radio (pt 2, pt 3, pt 4). The problem was with the new version of ezstream. Turns out this is solvable from with a quick search. Newer versions of ezstream(1.x) no longer support the .xml format configuration format from version 0.x.

There is an included utility, ezstream-cfgmigrate, to solve the problem.

ezstream-cfgmigrate -0 ezstream.xml >ezstream.conf

will create a newly formatted file, ezstream.conf, to use.

I also realized I had never documented the current version of the scripts.

The first file is start.sh. This is typically going to be left running, typically with screen.

cd weatherRadio
rm -f one two three; mkfifo one two three

./to-same.sh <one &
./to-lame.sh <two &
./to-udp.sh <three &
rtl_fm -f 162550000 -s 22050 -p 14 | tee one two three |multimon-ng -t raw -a EAS /dev/stdin

Everything else happens in a subfolder. We first delete and creates three bash fifos, each processed by a separate script.

to-same.sh handles the actual SAME messages, MQTT and starting the speaker output:

multimon-ng -t raw -a EAS /dev/stdin | python3 ~/tg-dsame/dsame.py --mqtt jtk-openhab.home.arpa --json output.json --call /home/pi/weatherRadio/playRadio.sh --command boo

to-lame.sh (named before we switched to sox) handles the streaming via ezstream:

sox -t raw -r 22050 -b 16 -e signed -c 1 -v 7 - -r 22050 -t mp3 -c 1 -C 64 - sinc -3.5k |ezstream -c ezstream.conf

to-udp.sh creates the udp stream for playRadio.sh:

sox -t raw -r 22050 -b 16 -e signed -c 1 -v 7 - -r 22050 -t mp3 -c 1 -C 64 - sinc -3.5k|socat - udp4-sendto:localhost:5555

playRadio.sh pipes the udp stream from to-udp.sh to play using netcat and plays for two minutes to the attached speaker:

#!/bin/bash
nc -lu 5555|play -t mp3 -&
sleep 120
killall "play"

12/23/2023

TrueNAS Scale / FTP / Cleanup

Filed under: General — taing @ 7:19 pm

After getting TrueNAS setup I was time to create a FTP user for the cameras to record. First a local user is created. The user’s home directory is where the files go and will probably also wants to be a Dataset and configured as a Share. The user is configured with a shell of /usr/sbin/nologin.

The FTP service is then enabled. The service is configured to always chroot.

Now it is time to create a cron job to cleanup these folders. The following command is set to run each night at midnight as the camera ftp user:

find /mnt/tank1/video/// -type f -mtime +30 -print0 | xargs -0 rm -f

This should find and delete all of the files in the folder older than 30 days.

There has been an issue with some of the Amcrest camera and FTP but for now ours seem to be uploading correctly.

12/1/2023

TrueNAS Scale and Dropbox

Filed under: General — taing @ 5:59 pm

Unfortunately, TrueNAS Scale doesn’t natively support the Dropbox service. It does support Dropbox through Cloud Data Protection however that only provides for one way sync. The gist found at https://gist.github.com/kbumsik/b7cc243e297a3a66837151024049f43c provides an option. The gist will not survive a system update but can be re-enabled.

Make sure you create a regular user for dropbox and give them a home directory in your pool/home. For example, user dropbox with a home directory of /mnt/tank1/home/dropbox. The gist will have you the dropbox headless linux install directly from Dropbox along with the handy dropbox.py script from Dropbox before adding their service script. A summary of the commands from Dropbox and the gist:

su dropbox
wget https://www.dropbox.com/download?plat=lnx.x86_64
tar -xzf name_of_downloaded_file
.dropbox-dist/dropboxd
# this can take a long time especially on reinstallation

wget https://linux.dropbox.com/packages/dropbox.py
sudo mkdir /etc/db
sudo cp dropbox.py /etc/db/dropbox-cli
sudo chmod +x /etc/db/dropbox-cli

wget https://gist.githubusercontent.com/kbumsik/b7cc243e297a3a66837151024049f43c/raw/b339fbeee2ba1081723612bec5aacf92cc60e7c2/dropbox-start.target

# Edit the service unit for your needs - be sure user id is correct and adjust path for dropbox-cli
pico dropbox-start.target

sudo cp dropbox-start.target /etc/systemd/system/dropbox-start.service
sudo systemctl enable --now dropbox-start.service
sudo systemctl status dropbox-start.service

I have saved dropbox.py and dropbox-start.target at truenas dropbox.zip in case the gist goes missing.

UPDATE: after a short while the process gave me an error that it couldn’t monitor the entire folder structure and suggest I run the following command to resolve:

echo fs.inotify.max_user_watches=100000 | sudo tee -a /etc/sysctl.conf; sudo sysctl -p

UPDATE #2: After updating to TrueNAS Scale Dragonfish-24.04.0 /usr is Read Only. The commands above have been updated. You will need to edit dropbox-start.target with the proper path from dropbox-cli.

11/3/2023

Airthings Wave Plus

Filed under: General — taing @ 9:40 pm

There are some resources online for getting the Airthings Wave Plus to communicate with your Raspberry Pi and Openhab. The first article is from Airthings and is a bit out of date but a very good starting point. The find_wave.py script they refer to is no longer on their site but I found it at https://cdn2.hubspot.net/hubfs/4406702/Tech/find_wave.py.

This all takes us down a rabbit hole of python 2.7 lack of current support. “sudo apt-get install python-2” got the proper version of Python itself installed but that still leaves some dependencies missing. I found a note on installing the no longer supported version of pip for Python 2.7 for Raspbian Bullseye.

sudo curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
sudo python2 get-pip.py

However, I was still not able to get bluepy installed for Python 2.7.

So now we try to adapt the script for Python 3. Not too bad, we need parenthesis for the print statements/functions. Once the syntax was correct my first run “sudo python3 find_wave.py” or “sudo blescan” rewarded me with the error message:

BTLEManagementError(“Failed to execute management command ‘%s'” % (cmd), rsp)

“bluetoothctl power off” followed by “bluetoothctl power on” seems to resolve the issue. There is quite a bit of discussion on this error on github.

Once we got find_wave.py working it was time to try read_waveplus.py. Once again this is written for Python 2.7 but a quick fixup of all of the print statements got it working for Python 3.

~/waveplus-reader $ sudo python3 read_waveplus.py 2930165120 5

Press ctrl+C to exit program

Device serial number: 2930165120
??????????????????????????????????????????????????????????????????????????????????????????????????????????
?     Humidity ? Radon ST avg ? Radon LT avg ?  Temperature ?     Pressure ?    CO2 level ?    VOC level ?
??????????????????????????????????????????????????????????????????????????????????????????????????????????
?     34.0 %rH ?     74 Bq/m3 ?     74 Bq/m3 ?   19.43 degC ?   977.64 hPa ?    546.0 ppm ?     46.0 ppb ?
?     34.0 %rH ?     74 Bq/m3 ?     74 Bq/m3 ?   19.43 degC ?   977.64 hPa ?    546.0 ppm ?     46.0 ppb ?
?     34.0 %rH ?     74 Bq/m3 ?     74 Bq/m3 ?   19.43 degC ?   977.64 hPa ?    546.0 ppm ?     46.0 ppb ?

There are lots of folks who have various version of Airthings to MQTT. There is even a nifty ESP32 gateway project. But the project that interested me most for the Pi also creates a mini dashboard and was recommended in the Openhab forums.

For now the Openhab Bluetooth binding extension is working. If issues develop the MQTT gateway will probably be the solution.

UPDATE(July 2024): after updating the Pi to Bookworm bluepy was no longer installed. Currently it is not available as a Debian python3-xxx package and it considered an externally-managed-environment by pip3. This means sudo pip3 install bluepy will fail. There are a couple of choice to work around this. The recommended method is to create a virtual environment and install there. If I had the patience and time I would have chosen this path. Instead I chose the --break-system-packages route. This option will allow you to install into the global python environment with pip3.

sudo pip3 install bluepy --break-system-packages

In my situation this was expedient.

Pi has no network

Filed under: General — taing @ 9:07 pm

On my Raspberry Pi running Bullseye after running “sudo apt-get dist-upgrade” dhclient failed to start at boot. A local login and one could run “”sudo dhclient” and all would be well.

Fortunately the good folks at stackexchange had seen and solved the problem. Edit /etc/systemd/system/dhcpcd.service.d/wait.conf to change “/usr/lib/dhcpcd5/dhcpcd” to “/usr/sbin/dhcpcd”.

10/30/2023

More upgrades – PHP & Webtrees

Filed under: General — taing @ 10:09 pm

In the process of the upgrades discussed in the previous post – Ubuntu 18.04(Bionic Beaver) to 22.04(Jammy Jellyfish) there were additional issues for Webtrees and PHP.

The current release of webtrees (2.1) requires PHP 7.4, 8.0, 8.1 or 8.2. In the process of upgrading, PHP 8.1 was installed but lacked the required modules to function properly. This can be solved by a simple apt-get command to install the required pieces:

sudo apt-get install php8.1-{cli,common,curl,zip,gd,mysql,xml,mbstring,imagick,intl}

There is a discussion of this at https://www.webtrees.net/index.php/forum/help-for-2-0/35292-update-php-error-solved and https://www.webtrees.net/index.php/forum/help-for-2-0/35369-upgrade-ubuntu-to-20-04-02-broke-webtrees.

It is also worth noting the apache2 commands to enable/disable Apache PHP modules:

sudo a2dismod php7.4
sudo a2enmod php8.1

There is a discussion of installing multiple versions of PHP at https://tecadmin.net/how-to-install-php-on-ubuntu-22-04/ and https://linux.how2shout.com/how-to-install-php-7-4-on-ubuntu-22-04-lts-jammy-linux/. The articles discuss a PPA for the versions not in the standard apt sources. Once multiple versions are installed installed you can use

sudo update-alternatives --config php

to change versions. You can easily confirm the default version using “php -v”.

10/29/2023

MythTV & MySQL Notes

Filed under: General — taing @ 11:01 pm

It was time to update the out of date server that is running the MythTV backend, so we went from 18.04(Bionic Beaver) to 20.04(Focal Fossa) to 22.04(Jammy Jellyfish). This is quite a jump. Most things survived the upgrades. According the Ubuntu we should have standard support until June 2027.

MySQL had an issue starting. The log at /var/log/mysql/error.log showed “unknown variable ‘query_cache_limit=1M'”. Turns out that query_cache_limit and query_cache_size are no longer valid in my.cnf for version 8.x. Removing these from the config file solved the problem. Read more at https://serverfault.com/questions/1042327/after-an-upgrade-to-ubuntu-20-04-lts-why-does-mysql-not-start.

There is the problem that after the upgrades the schema of the MythTV database was updated to 1376 instead of the 1348 on the clients. Off to do more upgrading…

It was also necessary to get a GUI view of the MythTV backend system. This machine hasn’t had a monitor connected in years, so the solution was VNC. The instructions at https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-vnc-on-ubuntu-20-04 got me started. The short version is “sudo apt-get install tightvncserver”, minor adjustment to ~/.vnc/xstartup and “vncserver” along with TightVNC from the PC with the correct IP:port from the command line got it working.

There’s a bit more in the tutorial if you want the VNC server running as a service or need to mess with resolution… For example, “vncserver -geometry 1280×800” to set the screen dimensions or “vncserver -kill :1” to close the server.

1/25/2023

Openhab transforms and MQTT JSON data

Filed under: General — taing @ 5:57 pm

In a previous post discussing Openhab JSONPATH transformations there was an issue when the same MQTT topic is used for several different messages. In the case of the LaCrosse Weather sensor one message contains temperature and humidity and the other message contains wind speed and direction.

The solution is to chain transformations. First use a REGEX to filter and then use the JSONPATH to extract the value. This is discussed in the Openhab forums. For the weather sensor the wind direction transformation looks like:

REGEX:(.*wind_dir_deg.*)?JSONPATH:$.wind_dir_deg

Pay special attention to the union symbol ?. It is really what makes the magic. As explained in the forum post the parenthesis in the REGEX pass the entire message on to the next transform if there is a match.

Mighty Mule and LaCrosse Update

Filed under: General,Home Automation,RTL-SDR — taing @ 4:45 pm

It turns out there is another Mighty Mule Driveway Alarm somewhere in the neighborhood so the config from our previous article needed to be updated. The other signal is weak but it triggers frequently and requires the config to be a bit more sophisticated. The first step was to update the rtl_433.conf file to send the MQTT messages as a JSON packet:

output json
output mqtt://broker_ip_address,events=rtl_433/garage[/model]

The result looks something like(after I prettied it up with a bit of formatting):

rtl_433/garage/MightyMule-FM231 {
	"time":"2023-01-24 18:37:05.994411",
	"model":"MightyMule-FM231",
	"count":1,
	"num_rows":1,
	"len":9,
	"data":"ff8",
	"battery_ok":"0",
	"id":15,
	"motion":"true",
	"mod":"ASK",
	"freq":433.89011,
	"rssi":-9.5411,
	"snr":12.69084,
	"noise":-22.2319
}

It’s all the same data but in one message. The Openhab config gets changed to have a String Channel for the MQTT JSON packet, an String Item linked to this and two additional String Items a new rule will manipulate. The rule checks the if the id matches our unit and then updates the appropriate items. The id is set on the transmitter and receiver with the dip switches. The rule is very basic but it does the job:

rule "Driveway Alarm" when
  Item Mighty_Mule_JSON received update
then
  var jsonval = Mighty_Mule_JSON.state.toString
  var id = transform("JSONPATH", "$.id", jsonval)
  var time = transform("JSONPATH", "$.time", jsonval)
  if (id == "5") {
    MightyMule_Driveway_Motion.postUpdate("ON")
    MightyMule_Driveway_Motion_Change.postUpdate(time)
  }
end

Changing the rtl_433 MQTT output to be JSON also required updating the channels for the LaCrosse Weather station. Previously the Generic MQTT Thing had channels for individual MQTT messages for temperature, humidity, wind speed and wind direction. Now the JSON messages from the weather station require the channel to have a JSONPATH transformation. The weather station will send two messages, one with temperature and humidity and one with wind speed and direction:

rtl_433/garage/LaCrosse-TX141W {
	"time":"2023-01-24 18:09:36.626950",
	"protocol":73,
	"model":"LaCrosse-TX141W",
	"id":149742,
	"channel":0,
	"battery_ok":1,
	"temperature_C":-0.8,
	"humidity":74,
	"test":0,
	"mic":"CRC",
	"mod":"ASK",
	"freq":433.87334,
	"rssi":-0.135693,
	"snr":22.09624,
	"noise":-22.2319
}

rtl_433/garage/LaCrosse-TX141W {
	"time":"2023-01-24 18:09:36.626950",
	"protocol":73,
	"model":"LaCrosse-TX141W",
	"id":149742,
	"channel":0,
	"battery_ok":1,
	"wind_avg_km_h":4.5,
	"wind_dir_deg":139,
	"test":0,
	"mic":"CRC",
	"mod":"ASK",
	"freq":433.87334,
	"rssi":-0.135693,
	"snr":22.09624,
	"noise":-22.2319
}

A MQTT channel with a topic of rtl_433/garage/LaCrosse-TX141W will receive both messages. The trick is in the JSONPATH transformation. To extract temperature, for example, use JSONPATH:$.temperature_C. This means there are four channels with the same MQTT topic and different JSONPATH transformations. The log file will get warnings that you can’t extract wind speed from the temp/humidity message or temp/humidity from the wind message.

NOTE: Our LaCrosse S81120-INT includes the LaCrosse TX145WSDTH which sends messages as LaCrosse-TX141W.

?

1/23/2023

Mighty Mule Driveway Alarm

Filed under: General — taing @ 9:07 am

Some time ago a Mighty Mule FM231 Driveway Alarm was installed. This is an electromagnetic inductive sensor with a transmitter and indoor receiver. Various ways of linking this to Openhab were considered. Since an sdr is already setup and configured to handle the LaCrosse weather station, the best solution seems to be to use a rtl_433 decoder to generate messages to the MQTT broker.

Once you have rtl_433 setup with your sdr, the next step is to add the decoder to your rtl_433.conf file:

decoder {
    name=MightyMule-FM231,
    modulation=OOK_PWM,
    short=650,
    long=1200,
    sync=3800,
    reset=1100,
    rows=1,
    bits=9,
    get=@4:{1}:battery_ok:[0:1 1:0],
    get=@5:{4}:id,
    get=@0:{1}:motion:[0:true 1:true],
    unique
}

The next step is to assure you have rtl_433 setup to send MQTT messages to your broker:

output mqtt://broker_ip_address,devices=rtl_433/garage[/model]

For me this results in messages that look something like:

rtl_433/garage/MightyMule-FM231/time 2023-01-22 11:39:48.795951
rtl_433/garage/MightyMule-FM231/count 1
rtl_433/garage/MightyMule-FM231/num_rows 1
rtl_433/garage/MightyMule-FM231/len 9
rtl_433/garage/MightyMule-FM231/data 728
rtl_433/garage/MightyMule-FM231/battery_ok 1
rtl_433/garage/MightyMule-FM231/id 5
rtl_433/garage/MightyMule-FM231/motion true
rtl_433/garage/MightyMule-FM231/mod ASK
rtl_433/garage/MightyMule-FM231/freq 433.98368
rtl_433/garage/MightyMule-FM231/rssi -0.124222
rtl_433/garage/MightyMule-FM231/snr 25.3924
rtl_433/garage/MightyMule-FM231/noise -25.5166

With this all setup, a Openhab Generic MQTT Thing was created with a Channel for the MQTT topic “rtl_433/garage/MightyMule-FM231/motion”. Two items were created, one for the channel itself and a second linking to the channel with a “Timestamp on Change” profile. Metadata for an Expiration Timer was added to the motion item to reset(the unit never sends motion false).

1/13/2023

Yoda Lights Up

Filed under: Arduino,General — taing @ 4:25 pm

As a follow-up to Yoda Speaks, we now have Yoda Lights Up. We have added a Sparkfun WS2812 Thru-Hole RGB LED to Yoda’s hand. There is a helpful Sparkfun WS2812 Hook-up guide. It allows for easy setup with the Sparkfun Papa Soundie we are using for the sound playback.

The LED is connected to Vcc/+5vdc, GND and Pin 10. We chose to use the FastLED library for our setup. There is a wiki online to answer many of your questions. As for code, our example is pretty simple:

#include <FastLED.h>

#define DATA_PIN    10
#define NUM_LEDS    1
#define LED_TYPE    WS2812
#define COLOR_ORDER RGB

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
}

void loop() {
  leds[0].setRGB(0,255,0);
// or
  leds = CRGB::Green;
  FastLED.show(); 
  delay(30);
}

Sparkfun points to some example code and the Adafruit NeoPixel library. Additional it is also recommended to add a series resistor(220 – 470 ?) on the data line and a filter capacitor(100µF – 1000µF) across the power lines if using more than a pixel of two. If you are using a large number of pixels there is a nice article on Large Power Loads and Daisy Chained LED Strips.

Older Posts »

Powered by WordPress