Perl: Named captures in regexps

In a regular expression you can capture strings into variables using the default syntax:

$str = "2020-05-20";
$str =~ m/(\d{4})-(\d{2})-(\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $1, $2, $3);

In a more complex regular expression/string things may move around. In this case it's better to use named captures instead of numeric captures. This can be done by using the (?<name>) syntax. This will capture that parenthesis pair in to the hash %+ with the name specified.

$str = "2020-05-20";
$str =~ m/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $+{year},$+{month},$+{day});

Using named captures you can easily update your regular expression if the position of elements in your string change.

Note: If you use named captures, Perl also populates the numeric equivalent.

Leave A Reply

Adjective and animal lists

For a personal project I wanted to generate AdjectiveAnimal pairs. This required me to find a list of animal names and adjectives. This was not a trivial endeavor and required me to find, clean up, and organize several lists.

Feel free to borrow my lists if you want to save yourself a headache. Using these lists I can generate pairs like: PracticalOsprey, HumorousTermite, and DiplomaticTarpon.

I also wrote a tool to generate pairs based on these two lists.

Leave A Reply

Perl: Time::Piece

Perl has a great core module for dealing with dates and times: Time::Piece.

use Time::Piece;

my $t = localtime();

my $unixtime = $t->epoch(); # Unixtime
my $human    = $t->cdate(); # Human readable

# Format a date/time for output
print $t->strftime("%Y-%M-%d") . "\n";

# Convert a specific format to a date/time object
my $bd = localtime->strptime("1985-02-14", "%Y-%M-%d");
print "You were born on a " . $bd->fullday . " in " . $bd->year . "\n";

# Date/Time addition
print "In one hour it will be: " . (localtime() + 3600)->hms . "\n";

It works by overriding the built in localtime() and gmtime() functions and giving them an object oriented interface. I highly recommend looking at it if you have to deal with dates and times.

Leave A Reply

C/C++: Force floating point math

In C/C++ if you want to get a floating point result from integer division you need to cast at least one of the values as a float to force floating point division (not integer):

int a = 1;
int b = 7;

float c = (float)a / b;

If you don't cast one of the variables as a float you will get an integer result. This is true even if your resulting variable is cast as a float.

Leave A Reply

Tasmota API via HTTP using Curl

Tasmota has a huge catalog of commands that can be run via the serial console, MQTT, or HTTP. These commands are great for scripting purposes. The easiest way I've found to send a command is with Curl.

curl http://192.168.1.142/cm?cmnd=Power%20TOGGLE

The API will answer in JSON which is easily digestible with JQ.

curl -s http://192.168.1.142/cm?cmnd=STATUS+8 | jq
Leave A Reply

Espressif WiFi MCU cost comparison

Espressif has just released their newest WiFi enabled MCU the ESP32-S2. It's a successor to the ESP8266 and has many improvements. Not only does it have more CPU, more memory, and more GPIO pins it's also cheaper. Just for posterity's sake here is the current cost for of WiFi enabled MCUs.

MCU Cost
ESP8266 $1.60
ESP8285 $1.05
ESP32 $1.50
ESP32-S2 $0.99

Note: This is the cost for the bare IC only.

Leave A Reply

PHP: Sanitize a string down to printable characters

I needed a function to make strings into usuable URL identifiers. This function will take an input string and replace all non-url friendly characters with underscores.

function string_sanitize(string $str) {
    // Replace any non-word chars with underscores
    $str = preg_replace("/[\W_]+/", "_", $str);
    // Remove any leading/trailing underscores that are leftover
    $str = trim($str, "_");

    return $str;
}
Leave A Reply

Linux file IO redirection matrix

Borrowing from this amazing post about Linux file IO redirection here is a cool table that breaks down how to get the data where you want it.

Syntax TermStdOut TermStdErr FileStdOut FileStdErr File
command > no yes yes no create
command >> no yes yes no append
command 2> yes no no yes create
command 2>> yes no no yes append
command &> no no yes yes create
command &>> no no yes yes append
command | tee yes yes yes no create
command | tee -a yes yes yes no append
command |& tee yes yes yes yes create
command |& tee -a yes yes yes yes append
Leave A Reply

Arduino Relay shield on a Wemos D1

I bought an Arduino Relay Shield to use on my Wemos D1 (ESP8266). After some poking around here is the mapping for which pins enable which relays:

Pin Relay
GPIO13 Relay #1
GPIO12 Relay #2
GPIO14 Relay #3
GPIO4 Relay #4

To enable the relays on this shield you pull the appropriate pin HIGH. Other relay boards I've seen require you to pull the pin LOW, so don't get confused.

Here is the Tasmota template I used for the relay shield.

{"NAME":"Relay Shield","GPIO":[0,0,0,0,24,0,0,0,22,21,23,0,0],"FLAG":0,"BASE":18}
Leave A Reply

List of Dune Characters and Locations for my reference

Dune character and location notes:

Item Description
Duke Leto Atreides Leader of the Atreides, Paul's father
Lady Jessica Paul's mother, Bene Gesserit concubine to Leto, bears a son against the wishes of the Bene Gesserit
Paul Atreides Main character, son of Leto and Jessica. Fifteen years old
Bene Gesserit Sisterhood of "witches" who seek to gain political power, addicted to spice
Caladan Ocean homeworld of the Atreides
Arakis Desert world, home of the spice melange, setting for the entire book
Gurney Halleck Troubador Warrior, skilled in the use of the baliset, loyal friend to Leto
Thufir Hawat Old Mentat, master of assassins that has served house Atreides for many years
Duncan Idaho Swordmaster of the Ginaz, one of Leto's right hand men
Dr. Wellington Yueh Betrays Duke Leto
Princess Irulan "Narrator" of the book. Each chapter begins with one of her short diary entries
Sardaukar Elite military force of the Emperor
Fremen Local peoples of Arakis, glowing blue eyes
Mentat Human "computers", vast memories, ability to organize lots of information
Muad'Dib Small desert mouse, Paul later adopts this as his Fremen name
Kwisatz Haderach Male Bene Gesserit who can bridge space and time, result of breeding program
Liet Kynes Planetologist assigned by the emperor to assist in transition of Arakis
Salusa Secundus Harkonnen prison planet
Leave A Reply

Wemos D1 mini Pin mapping

I've been using the Wemos D1 mini for several home automation projects. Unforunately the pin designations on the board don't match what Tasmota uses. I was able to track down the Wemos D1 mini pin mappings to create a cheat sheet.

Label GPIO
D0 16
D1 5
D2 4
D3 0
D4 2
D5 14
D6 12
D7 13
D8 15
RX 3
TX 1
A0 ADC0

Bolded pins can be used for any project without limitation, other pins can be used but may have some limitations.

Leave A Reply

Linking two Tasmota devices (without MQTT)

I have two Tasmota enabled devices that I want to turn on/off at the same time. In my case I have a wall switch that powers the main lights, and a wall socket that powers some corner lights and a radio. Using Tasmota's rule system this is not too complicated. We need tell each Tasmota device that whenever the state of it's relay changes (for whatever reason: button, timer, etc.) it needs to tell the other Tasmota device to set it's relay to the matching state. We can use the WebSend feature built in to Tasmota to send commands between two devices.

On device #1

RULE1 on POWER1#State do WebSend [192.168.1.33] POWER1 %value% ENDON

On device #2

            RULE1 on POWER1#State do WebSend [192.168.1.34] POWER1 %value% ENDON

This can also be done using MQTT pretty simply, but I wanted to see if I could do it with vanilla Tasmota. Doing it direct with WebSend is pretty simple and saves having to run an MQTT broker if you just have two simple devices.

Leave A Reply

Books of 2020

List of books I read in 2020. Also see the list of 2019. The date indicated denotes the date I started reading the book.

2020-01-17 - Dune Messiah - 256 pages
2020-02-08 - Gerald's Game - 332 pages
2020-03-10 - Brain Droppings - 257 pages

Leave A Reply

Printf() and variable length precision

Formatting floating point numbers is usually best served with printf(). This example will print Pi to two decimal places:

printf("%0.2f", 3.14159265);

If you want to control how many digits of precision printf() uses you can use the * variable in your format

printf("%0.*f", 4, 3.14159265);

This example will print Pi with four digits of precision. The * substitution is used like a regular parameter, and printf() uses it in the order it receives it.

Leave A Reply

Perlfunc: file_put_contents()

PHP has a really handy function called file_put_contents() that simplifies writing to a file. I did a quick Perl version of that function for my scripts.

sub file_put_contents {
    my ($file, $str) = @_;

    open (my $fh, ">", $file) or return undef;
    print $fh $str or return 0;
    close $fh;

    return length($str);
}
Leave A Reply