Functional programming: Algebraic data types

Based on this Wikipedia article.

Composite data types

Composite (or compound) data types consist of a few primitive data types or other composite types. Examples of composite data types are C/C++ structure and union.

Product data type

Let’s look at the C/C++ structure example:

struct account {
   int account_number;
   char *first_name;
   char *last_name;
   float balance;
};

This type contains account_number AND first_name AND last_name AND balance fields – the AND makes it a product type, where product is boolean AND.

Sum data type

Let’s now look at the following example of C/C++ union:

union number {
  int8_t i8;
  int16_t i16;
  int32_t i32;
  int64_t i64;
  float f32;
  double f64;
};

This type can accommodate an int8_t OR int16_t OR int32_t OR int64_t OR float OR double number – the OR makes the type a kind of sum type (not quite yet), where sum is boolean OR.

This is not the whole of the sum data type yet. The actual type of the data currently stored in a C/C++ union is only known at run time, and the program that uses the union should be able to handle that at run time.

The union can be extended to tagged union, which may look like this:

struct number {
  uint8_t tag;
  union {
    int8_t i8;
    int16_t i16;
    int32_t i32;
    int64_t i64;
    float f32;
    double f64;
  } value;
}

The tag specifies the type of the value at run time.

Such tagged union type is called sum data type.

Hybrid data types

Product and sum data types are the base algebraic data types. The data types composed of product and sum data types are called hybrid data types.

It probably makes not that much sense to use the struct number type for the balance field in the struct account, but here it is – a hybrid data type example:

struct account {
int account_number;
char *first_name;
char *last_name;
struct number balance;
};

Algebraic data types

The product, sum and hybrid data types are what is called algebraic data types.

See also

Functional Programming: Terminology

Raspberry PI: How to install Android emteria.OS, Google Play and Synthesia

Environment
  • Raspberry Pi 3 Model B, 32GB SD-card, Flatron IPS231 display, Rii i8 mini wireless keyboard/touchpad
  • Roland FP-30 piano
  • Ubuntu 18.04 LTS
  • Emteria.OS_Installer-v0.6-13.AppImage (Android 7.1)
  • Synthesia 10.5

Please keep in mind that the sequence described below presumes certain level of Linux and Android knowledge, e.g. how to mount SD-cards in Linux, how to edit  Android boot configuration settings, or how to use Android Debug Bridge.

Make emteria.OS SD-card

Follow emteria.OS download and install instructions – you will be asked to create an Emteria account.

Emteria.OS license

If you decide to not yet pay for emteria.OS personal or business license, and use free evaluation license – be prepared to system reboots after 8 hours, and an evaluation license notice pop up now and then.

Modify HDMI settings in /boot/config.txt

Mount the SD-card in your Linux box, edit emteria.OS’s /boot/config.txt, enable safe HDMI configuration:

hdmi_safe=1

#hdmi_group=2
#hdmi_drive=2
#hdmi_mode=82
#hdmi_cvt=1024 768 60 6 0 0 0
#hdmi_force_hotplug=1
disable_overscan=1

dtoverlay=vc4-kms-v3d,cma-256
avoid_warnings=2

dtparam=sd_force_pio=on
dtparam=i2c1=on
dtparam=i2c_arm=on

dtparam=audio=on
audio_pwm_mode=2

initial_turbo=30
start_x=1
kernel=u-boot.bin

Save the changed /boot/config.txt file, unmount the SD-card.

Alternatively, you might want to configure all HDMI parameters manually – this is a rather tricky process which only worked for me with a dated non-HD resolution display.

Boot emteria.OS

Insert the emteria.OS SD-card into your Raspberry Pi, connect display, keyboard and mouse, power up.

For the next step your Raspberry Pi has to be connected to internet – via ethernet or wifi. In case of wifi – choose your wifi network and enter password, as usually in Android. Check internet connectivity in the emteria.OS browser.

Install Google Play

The emteria.OS comes without Google Play Store which we will need in the next step to install and unlock Synthesia. To install Google Play Store – follow the process explained here:

Google Play installation

  • In the EmteriaOS/Raspberry PI browser go to https://opengapps.org/
  • Select ARM, 7.1, pico, and click the Download button
  • When download is finished – click the Emteria.OS Power Off app icon, then Recovery
  • After Android reboots Swipe to Allow Modifications
  • Click Install
  • Go to the Download folder and click the downloaded open_gapps-arm-7.1.-pico-20180315.zip
  • Swipe to Confirm Flash
  • Click Reboot System after flashing is finished

After reboot – start Google Play and configure your Google account

You have to be patient while Android is busy with “System optimization in progress, please wait…” – it takes quite some time (longer than 1 day) and a few reboots, Android will be rather unresponsive all that time.

That might be that the “Sytem optimization…” message, the evaluation license pop ups, and Android’s lack of responsiveness would feel a bit frustrating, and you would probably want to try to reboot your Raspberry Pi – just to check that it did not go south incidentally. Here is a way how to do that (please also see the screenshots further below):

  • Go to Android Settings – Emteria, and switch on the “Enable ADB over Ethernet”
  • Note the IP address of your Raspberry Pi
  • On your Linux box:
### Connect
$ adb connect 192.168.1.144
connected to 192.168.1.144:5555
### Just checking if it's there
$ adb devices
List of devices attached
192.168.1.144:5555	device
### Reboot
$ adb reboot

Install Synthesia

I downloaded and installed  Synthesia APK manually in the emteria.OS browser – to do that you need to go to generate Synthesia APK download link – the APK will be downloaded and installed.

Alternatively, you can install Synthesia from Google Play Store.

Unlock Synthesia

If you have Synthesia unlock key – unlock Synthesia as usually. For that you will need Google Play Store installed and your Google account configured, otherwise Synthesia complains it has no internet connection.

Screenshots

Synthesia installed

Evaluation version pop-up

Synthesia

Emteria settings

Disabling auto-update Goolge apps

Google Play

Synthesia unlock

Play demo

YouTube streaming

Raspberry Pi: How to debug Dart command line applications in IntelliJ

How to debug with gdb on command line – see Raspberry Pi: gdb debugging, command line.

How to debug with gdb in Eclipse – see Raspberry Pi: gdb debugging in Eclipse.

Environment
  • Ubuntu 18.04 LTS
  • IntelliJ IDEA Community 2018.3
  • Raspberry Pi 3 Model B
IntelliJ

Create Dart Remote Debug configuration for your Dart application:

Ubuntu terminal

Copy your application and open an ssh session to Raspberry Pi :

$ scp -r dartapp/ pi@192.168.0.60:/home/pi
$ ssh pi@192.168.0.60
SSH session on Raspberry Pi
$ cd ~/dartapp
$ pub get
Resolving dependencies... (1.9s)
Got dependencies!
$ dart --enable-vm-service:5858/0.0.0.0 --pause_isolates_on_start bin/main.dart 
Observatory listening on http://0.0.0.0:5858/
intellij

Now you can start debugging your application in IntelliJ.

Ubuntu: How to reschedule mlocate

What is mlocate can be found here.

By default it is scheduled to execute daily – that might not meet your expectations what you computer should do when you power it on.

Here is how to reschedule it to execute weekly:

### In the terminal
sudo chmod -x /etc/cron.daily/mlocate
sudo cp /etc/cron.daily/mlocate /etc/cron.weekly/mlocate
sudo chmod +x /etc/cron.weekly/mlocate

This has been checked with Ubuntu 18.04 LTS.

WordPress: changing permalink settings and 404 page not found

Taken from:

To be able to change permalink settings you might need to change access rights of the /var/www/html/<blogfolder>/.htaccess from 644 to 666:

### On your web server
$ cd /var/www/html/<blogfolder>
$ sudo chmod 666 .htaccess
### Do not forget to change back to 644 after you are done with permalinks
$ sudo chmod 644 .htaccess

If after changing WordPress permalink settings you get notorious “404 page not found” then check that the bold options in the <Directory /var/www/> section in the /etc/apache2/apache.conf file look like this:

<Directory /var/www/>
 Options Indexes FollowSymLinks
 AllowOverride All
 Require all granted
</Directory>

OpenSSL hints

Environment
  • Ubuntu 16.04 LTS
  • OpenSSL 1.0.2g 1 Mar 2016
Download server certificate
### Show certificate
$ openssl s_client -connect host:port -showcerts
### Download certificate
$ echo | openssl s_client -connect host:port 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > server.crt.pem
2-way TLS authentication test

Say, we’ve downloaded server certificate and generated your client private key and certificate. Now we want to test if everything works:

$ openssl s_client -connect hostname:port -CAfile server.crt.pem -cert client.crt.pem -key client-private.key.pem

If you private key is protected with a password you’ll be prompted to enter the password.

remove password (passphrase) from private key

You might want to remove the password from private key:

openssl rsa -in private.key.pem -out newprivate.key.pem

 

 

 

Raspberry Pi: Flower Care (aka MI Flower) sensor

Environment
  • Raspberry Pi 3 Model B
Flower Care sensor

See http://www.huahuacaocao.com/product.

Looks and feels very nice:

Be aware that there are two versions of the sensor – Chinese and  international. I saw complains on internet about chinese sensor that were bricked after software upgrade when used outside of China. It is not quite clear what exactly was bricked – mobile phone app or the sensor itself.

FIGURE out the flower care MAC Address
### Check if bluetooth service running
$ service bluetooth status
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled)
Active: active (running) since Sun 2019-04-07 08:16:38 UTC; 5 days ago
Docs: man:bluetoothd(8)
Main PID: 1068 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─1068 /usr/lib/bluetooth/bluetoothd

### Start the service if it's not running
$ service bluetooth start

### Start bluetoothctl
$ bluetoothctl 
[NEW] Controller B8:27:EB:8A:A0:E6 raspberrypi [default]
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:xx:xx:xx Discovering: yes
[NEW] Device C4:7C:8D:xx:xx:xx0 Flower care

Python demo on Raspbery Pi

Details see on GitHub.

$ git clone https://github.com/open-homeautomation/miflora.git
$ cd miflora/
$ . ./build.sh 
$ python3 setup.py build
$ sudo python3 setup.py install
$ python3 demo.py C4:7C:8D:xx:xx:xx
Getting data from Mi Flora
FW: 2.7.0
Name: Flower care
Temperature: 18.3
Moisture: 27
Light: 105
Conductivity: 59
Battery: 100

Raspberry Pi: Running Mosquitto MQTT server

Environment
  • Raspberry Pi 3 Model B

Install and run as service

Taken from YouTube.

Installation
$ sudo apt-get update
$ sudo apt-get dist-upgrade
### Install mosquitto
$ sudo apt-get install mosquitto
### Optional - install mosquitto clients
$ sudo apt-get install mosquitto-clients

Install and run in Docker container

Based on this.

install docker
### Install Docker
$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh

### Pull Mosquitto image
$ docker pull eclipse-mosquitto
RUN with default configuration
$ docker run -it -p 1883:1883 -p 9001:9001 --restart unless-stopped eclipse-mosquitto
run with custom mosquitto configuration

Say, we want to persist Mosquitto log in local file system

  • create local mosquitto.conf (e.g. at /home/pi/mosquitto/config/mosquitto.conf location)
  • add this line to it:
log_dest /mosquitto/log/mosquitto.log

Then run the container:

$ docker run -it -p 1883:1883 -p 9001:9001 --restart unless-stopped -v /home/pi/mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf -v /mosquitto/log eclipse-mosquitto

Inspect the container:

### Figure out container id
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED...
4aaf067565c9 eclipse-mosquitto "/docker-entrypoint.…" 14 minutes...

### Inspect rge container
$ docker inspect 4aaf067565c9
...
"Mounts": [
{
"Type": "bind",
"Source": "/home/pi/mosquitto/config/mosquitto.conf",
"Destination": "/mosquitto/config/mosquitto.conf",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "volume",
"Name": "7cbeec58f1dee862c14b65b1ab59b180df1ec5fc4736a0a88136a28c88e5e68c",
"Source": "/var/lib/docker/volumes/7cbeec58f1dee862c14b65b1ab59b180df1ec5fc4736a0a88136a28c88e5e68c/_data",
"Destination": "/mosquitto/log",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "e5f9ff21ba6a94a84347bcf6aa7203e510db1ea578da63cbe8ce256d96b44914",
"Source": "/var/lib/docker/volumes/e5f9ff21ba6a94a84347bcf6aa7203e510db1ea578da63cbe8ce256d96b44914/_data",
"Destination": "/mosquitto/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...

### Check log file
$ sudo cat /var/lib/docker/volumes/7cbeec58f1dee862c14b65b1ab59b180df1ec5fc4736a0a88136a28c88e5e68c/_data/mosquitto.log
1548170247: mosquitto version 1.5.5 starting
1548170247: Config loaded from /mosquitto/config/mosquitto.conf.
1548170247: Opening ipv4 listen socket on port 1883.
1548170247: Opening ipv6 listen socket on port 1883.
...

See more on how to run mosquitto in docker container here.

Testing

### Console 1
$ mosquitto_sub -t "hellomosquitto"

### Console 2
$ mosquitto_pub -t "hellomosquitto" -m "Hello, Mosquitto!"

### Console 1 prints
Hello, Mosquitto!