JTK – Notes and Ramblings Things we have found …

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.

12/30/2022

Shades – a start

Filed under: General,Home Automation — taing @ 12:21 pm

I decide to try the Home Depot Decorator Collection Shades. These have a motorize option that is controllable via Bluetooth using either their remote or a smartphone app (Android or iOS). The motor kit (FAQ) is pretty simple to install.

Unfortunately, there is no documented integration API. I found a few discussions online:

I am waiting to try the Bluetooth clone/copy MAC address scheme.

I did follow the shelly1 option as far as getting the required wires added. Simply add wires to the BTN (red wire on ribbon cable) and +W pins –

.

I have not yet completed the shelly1 connection or the integration into Openhab.

Yoda Speaks

Filed under: Arduino,General — taing @ 11:49 am

It was finally time to put the Sparkfun Papa Soundie to work. The Sparkfun hook-up guide provides most of the details – a 3.3v ATmega328P paired with the VLSI‘s VS1000D audio codec IC. They have created an Arduino library to control the VS1000D. This can be downloaded as a zip (archive version).

For the really adventurous there is VSIDE from VLSI to reprogram the firmware in the VS1000D – there are application examples, source code samples and additional PC tools available. We archived a copy of the VS1000D programmers guide.

I supplemented the Papa Soundie with a small speaker and a PIR motion sensor, Sparkfun’s OpenPIR. The sensor is based around the NCS36000 PIR controller and will work with 3v to 5.75v. Sparkfun has created a hook-up guide, also.

Audacity made quick work of converting a few .wav and .mp3 sound clips of Yoda’s voice to the preferred Ogg Vorbis / .ogg format. The preinstalled firmware on the VS1000D wants to find files in either .ogg or .wav format on the microSD card. The files should be named AUDIOxx.OGG or FILESxx.WAV (xx is 00 thru 31). Unfortunately, you need to start with 00 and not skip any slots.

I based my project on the Hardware Example Project from the Sparkfun Hook-up Guide. I removed the code for the servo and added code to prevent immediate re-triggering and to randomly select the file to play. The random selection is configured not to repeat a file until all have played – card deal style.

#include "SparkFun_PapaSoundie.h"

  int motionStatusOld = LOW;
  int motionStatus = LOW;
  int sounds[] = {1, 2, 3, 4, 5};
  int len = 5;

#define PIR_DOUT 9 

PapaSoundie sfx = PapaSoundie();

void setup() {
  Serial.begin(115200);  // Serial is used to view Analog out
  // Analog and digital pins should both be set as inputs (not actually necessary for Analog):
  pinMode(PIR_DOUT, INPUT);
  Serial.println("Getting ready");
  sfx.begin();
}

void loop() {
  int rnd;
  int choice;
  motionStatusOld = motionStatus;
  motionStatus = digitalRead(PIR_DOUT);
  if (motionStatus == HIGH && motionStatus != motionStatusOld) {
    if (len > 1) {
      rnd = random(len);
      choice = sounds[rnd];
      sounds[rnd] = sounds[len-1];
      len = len - 1;
    } else {
      choice = sounds[0];
      len = 5;
        for ( int i = 0; i < len; ++i ){
          sounds[i] = i+1;
        }      
    }
    
    Serial.println(choice);
    
    
    sfx.playFileNumber(choice);
    delay(1000);
  }
}

The wiring is very basic – 5vdc and ground in on the VIN and GND pins, 3.3vdc and ground out to the sensor from the 3.3v and GND pins and the output of the sensor to pin D9.

Keep in mind the sensor does require a bit of time after power-up before being active. The LED on the sensor PCB will blink slowly during start-up. Once up and running the LED will indicate motion.

I think the next step might be to add an LED. Possibly the Sparkfun RGB addressable thru hole version. This is a thru hole 8mm version of the typical WS2812. Three are details in their WS2812 Guide. Adafruit has a very nice Arduino library for the WS2812.

Sound activated Yoda

12/29/2022

Sonoff S31 and B1

Filed under: General,Home Automation — taing @ 9:47 pm

Sadly, I never posted any notes on the Sonoff products. Long ago I ordered a set of S31 outlets and B1 lamps. Both of which I reflashed with espurna. The notes on how to flash tasmota are helpful here, too. I found a quick tutorial on flashing with a Raspberry Pi in their docs. In todays world you might need to use pip3 instead of pip to install esptool. Tinkerman has posted lots of great details for the S31.

NEVER connect the S31 to mains power when flashing. For the S31 the connections to the Pi are very simpleSonoff S31 connections Raspberry Pi connections:

    S31 Pin - Pi Pin
    Vcc     - #1 (3.3vdc) - do not connect yet
    RX      - #8 (TX)
    TX      - #10 (RX)
    GND     - #39 (Ground)

Once you have the wiring ready you can setup the Pi – make sure you have esptool installed. If not sudo pip3 install esptool should handle it. You can then use raspi-config -> InterfaceOptions -> Serial to say No to shell on the serial port and Yes to Serial hardware.

The S31 will enter loader mode if you hold down the button, connect Vcc and continue holding the button for 10 seconds. You are now ready to actually flash the device(I was using an older Pi 2):

esptool.py --port /dev/ttyAMA0 erase_flash
esptool.py --port /dev/ttyAMA0 write_flash -fm dout 0x0 /path/to/downloaded/image

If you are using a Pi 3 or 4 replace ttyAMA0 with ttyS0.

The bad news is the Sonoff B1 is no longer made and their replacement uses a different chip and is not re-flashable. For the B1 lamps I have MQTT control after reflashing is awesome. MQTT make the integration with Openhab super easy. If you happen to come across these at a good price then the flashing instructions at the Tasmota site are very helpful.

5/30/2022

Updates and a new RTL-SDR

Filed under: Home Automation,RTL-SDR — Tags: , — taing @ 5:53 pm

Time for some updates and to add the new RadarBox 978 MHz radio. The system is still Raspian based on Buster. Keep in mind the initially the RTL-SDR for ads-b data is device 1(RTL2832U) and the weather station data is on device 0(RTL2838UHIDIR).

I’ll take these things somewhat in the order originally installed. readsb(our option over the other dump1090 alternatives) can be updated using the same bash script that was used for the install. Be sure to keep your current /etc/default/readsb file.

sudo bash -c "$(wget -O - https://github.com/wiedehopf/adsb-scripts/raw/master/readsb-install.sh)"

tar1090(an improved web page to display your data) can be updated much like readsb using the original install script.

sudo bash -c "$(wget -nv -O - https://github.com/wiedehopf/tar1090/raw/master/install.sh)"

FlightAware is updated from your site’s My ADS-B Stats page. Once on your stats page, click on the gear and choose update.

Instruction for updating ADSBexchange can be found on their github page. The short answer is a bit of command line:

curl -L -o /tmp/axupdate.sh https://github.com/adsbxchange/adsb-exchange/raw/master/update.sh
sudo bash /tmp/axupdate.sh

FlightRadar24 should update from its repository with apt-get.

Updating graphs1090 is once again as simple as running the original install script again.

sudo bash -c "$(curl -L -o - https://github.com/wiedehopf/graphs1090/raw/master/install.sh)"

I found nothing on the RadarBox site regarding updates so I left it alone for now.

At this point everything should work as before with ADSBexchange, FlightAware, FlightRadar24 and RadarBox all still working.

Now it is time to update the serial numbers on the dongles, add the new 978MHz dongle and update the existing config files to work with that info. I used the notes at dump978-fa install instructions to set the serial numbers of the dongles. The RadarBox flightstick instructions also show how to update the serial numbers. I also updated /etc/rtl_433/rtl_433.conf to point to my new device with serial number 433(rtl_eeprom -s 433) for the LaCrosse Weather Station.

I then continued to follow the dump978 instructions.

sudo apt update
sudo apt install -y dump978-fa
sudo sed -i -e 's/RECEIVER_OPTIONS.*/RECEIVER_OPTIONS="--sdr-gain 43.9 --sdr driver=rtlsdr,serial=978 --format CS8"/' /etc/default/dump978-fa
sudo systemctl restart dump978-fa

Then a quick install of the ADS-B exchange UAT/978 feed client following the github instructions.

sudo bash -c "$(wget -q -O - https://raw.githubusercontent.com/adsbxchange/adsbexchange-978/master/install.sh)"

A quick edit to /etc/rbfeeder.ini to enable UAT/978MHz and a reboot and we are in business.

http://<pi-ip>/tar1090/
http://<pi-ip>/ax978/
http://<pi-ip>/radar/
http://<pi-ip>/graphs1090/
http://<pi-ip>:8754/

https://flightaware.com/adsb/stats/user/xxx
https://www.adsbexchange.com/myip/
https://www.flightradar24.com/account/feed-stats/?id=xxxxx
https://www.radarbox.com/stations/xxxxxx

Updating Pi –

Filed under: General,Router/PC Config — taing @ 2:06 pm

After being away from things for a bit, it was time to update several of the Pis but I was met with an unfortunate error wen executing sudo apt-get update:

E: Repository 'http://raspbian.raspberrypi.org/raspbian buster InRelease' changed its 'Suite' value from 'stable' to 'oldstable'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.
E: Repository 'http://archive.raspberrypi.org/debian buster InRelease' changed its 'Suite' value from 'testing' to 'oldstable'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.

After consulting the oracle I found an article that had a solution. Turns out that Buster moved to “oldstable” after Bullseye became the current “stable”. The simple solution is:

sudo apt-get update --allow-releaseinfo-change

This will update the appropriate configuration setting for atp-get to allow thing to continue.

12/30/2021

Lua and encryption

Filed under: General — taing @ 2:07 pm

Several times I’ve gone looking for a bit of Lua to do some encryption. For most of these cases I need to have something reversible – meaning I need to recover the original text not just prove it matches with a hash…

This time I have a few candidates:

First is Bruce Schneier’s Solitaire algorithm. I found a Lua implementation. Solitaire is unfortunately limited to the 26 uppercase letters.

Then I found a pair of AES implementations – first and second. These come from the same guy on github but the first one seems a bit more standalone. From what I read these are both pretty slow.

I then stumbled upon https://github.com/philanc/plc where there are several algorithms implemented in pure Lua. morus sounds good and is described as very fast but requires 64 bit integers.

I also found a small simple algorithm that seems to be a good fit. One word of caution here is the results from this will be quite different if you only have 32 bit Lua. I’m not sure what impact 32 bit only has on the security of the method.

12/29/2020

DDC and CEC and more TV control

Filed under: Home Automation — taing @ 10:54 am

The quest to control the TVs and monitors continues. One promising option is DDC/C control. I was able to install ddcutil: sudo apt-get install ddcutil. For the older Acer units with Nvidia Ion graphics I was able to retrieve EDID but was unable to detect DDC.

The ddcutil website suggested adding the following in /etc/modprobe.d/nvidia-ddc :

options nvidia NVreg_RegistryDwords=RMUseSwI2c=0x01;RMI2cSpeed=100

I found that for the GeForce GT 710 machine this helped but not for the Acer with Ion graphics. Unfortunately, the Samsung T24C550 TV only seems to support a limits subset of DDC commands.

Next up was ddccontrol. After installing, it wasn’t able to detect DDC on the Acer with Ion but was more successful of the GeForce system. Unfortunately, there was no entry for the Samsung in the ddccontrol database so only generic commands appear to be available.

It is worth noting that even on the GeForce system once the monitor went to sleep it wasn’t detected at all by either ddcutil or ddccontrol.

Further notes on using ddcutil without being root can be found at https://frdmtoplay.com/using-ddccontrol-as-a-non-root-user/#:~:text=ddcutil%20is%20a%20CLI%20based,is%20not%20’officially’%20supported. This really comes down to adding users to the i2cusers group.

CEC

CEC is another option for controlling HDMI devices. While CEC can be used with a variety of devices it is especially useful on the Raspberry Pi. Again, unfortunately it is not supported by most Nvidia cards but is reported to work with the Nvidia Shield.

Your first step will be to install cec-utils: sudo apt-get install cec-utils. Hopefully a scan will turn up your device.

 echo "scan" | cec-client -s -d 1

If it does not it is worth looking into cec-util from the v4l-utils package. You may find to need to install/create the drivers for /dev/cec0.

For my Samsung, CEC was not enabled by default. Samsung refers to CEC as Anynet+. It can be enabled in the Service Menu. To enter the service menu, with the power to the TV off press MUTE 1 8 2 POWER quickly on the remote. Other Samsung units use INFO MENU MUTE POWER for the service menu.

I found some good info on using Raspberry Pi with CEC and a variety of devices at https://www.raspberrypi.org/forums/viewtopic.php?f=35&t=15593&p=158409&hilit=cec_client#p158409.

An no discussion of using CEC would be complete without mentioning CEC-O-Matic. This website allows you to “build your own” CEC commands.

Samsung – In Depth

There is lots of in depth info on Samsung TVs and firmware at https://wiki.samygo.tv/index.php?title=This_is_the_first_document_you_have_to_read.

Vizio Smartcast

If you have a Vizio with Smartcast there is a bit of detective work shown on github.

12/20/2020

Roku Remote Control

Filed under: General,Home Automation,RTL-SDR — taing @ 10:36 pm

Back in April I mentioned adding some Roku remote control. At this point I’m thinking more javascript than Python.

Roku has a good External Control Protocol reference online.

Sending commands

Unfortunately, the Roku API will not accept Cross Origin Request. This is not an issue if communicating from Node or Python but from the browser using xhr or fetch() you will get CORS errors. When sending POST for button presses you don’t care about the response for a “mode:’no-cors’ ” will work.

let resp = await fetch("http://roku-ip:8060/keypress/play", {method:'POST', mode:'no-cors'})

For the GET for status from the browser one option is a “proxy” add the “Access-Control-Allow-Origin” header. Borrowing the idea from https://medium.com/gitignore/building-a-roku-remote-web-app-1c0db0056be4 we set our Apache web server.

sudo pico /etc/apache2/apache2.conf to edit the config file and add the following lines:

<Location /roku>
    ProxyPass "http://roku-ip:8060/"
    ProxyPassReverse "/" 
    Header add "Access-Control-Allow-Origin" "*"
</Location>

You will need to have several modules loaded in Apache for this to work: headers and proxy_http. This can be done with:

sudo a2enmod proxy_http
sudo a2enmod headers
sudo systemctl restart apache2

Deep Links

A very important link for launching directly into netflix content is https://unogs.com/search/. From this site you can find the contentid for much of the netflix content.

This allows for directly linking to content with something like:

curl -d '' "http://roku-ip:8060/launch/12?contentid=70136120&mediatype=series"

This is a simple POST to the URL with no body.

The folks at unofficial Netflix online Global Search also provide an API.

Older Posts »

Powered by WordPress