Category: General
Tesla Wall Connector API
RDF vs Property GRAPH (NoSQL) database
RDF Graph example (Query language: SPARQL)
As a framework for representing the Web, Resource Description Framework (RDF) captures structure using a triple, the basic unit in RDF. A triple is a statement with three elements: two nodes connected by an edge (also known as a relationship). Each triple is identified by a Uniform Resource Identifier (URI) as subject-predicate-object:
– The subject is a resource (node) in the graph;
– The predicate represents an edge (relationship)
– The object is another node or a literal value.
More information:
https://rdf4j.org/documentation/tutorials/getting-started/
Property Graph example (Query Language: Cypher)
Information is organized as nodes, relationships, and properties in a property graph. Nodes are tagged with one or more labels, identifying their role in the network. Nodes can also store any number of properties as key-value pairs. Relationships provide directed, named connections between two nodes. Relationships always have a direction, a type, a start node, and an end node, and they can have properties, just like nodes. Although relationships are always directed, they can be navigated efficiently in either direction.
What is the difference between SPARQL and Cypher Query Language?
– SPARQL is the query language for accessing data in the Resource description Framework (RDF) GRAPH database.
– Cypher is the corresponding language for the data represented in property GRAPH database
More information:
https://neo4j.com/blog/rdf-vs-property-graphs-knowledge-graphs/
Cypher queries examples
INSERT
CREATE (diana:Person {name: “Diana”})
CREATE (melissa:Person {name: “Melissa”, twitter: “@melissa”})
CREATE (xyz:Company {name: “XYZ”})
CREATE (diana)-[:WORKS_FOR]->(xyz)
CREATE (diana)-[:IS_FRIENDS_WITH]->(melissa)
UPDATE
MATCH (p:Person {name: ‘Diana’}) SET p.birthdate = date(‘1980-01-01’)
MATCH (:Person {name: ‘Diana’})-[rel:WORKS_FOR]-(:Company {name: ‘XYZ’}) SET rel.startYear = date({year: 2018})
DELETE
MATCH (j:Person {name: ‘Diana’})-[r:IS_FRIENDS_WITH]->(m:Person{name: ‘Melissa’}) DELETE j,r,m
SELECT
MATCH (p:Product) RETURN p.productName, p.unitPrice ORDER BY p.unitPrice DESC LIMIT 10;
SPARQL examples
INSERT
PREFIX plaat: <http://www.plaatsoft.nl/>
INSERT DATA {
<http://leerling/1> plaat:firstName “Kees”.
<http://leerling/2> plaat:firstName “Jan”.
<http://leerling/3> plaat:firstName “Piet”.
<http://leerling/4> plaat:firstName “Klaas”.
<http://school/1> plaat:name “Bospark”.
<http://school/1> plaat:level “LTS”.
<http://school/1> plaat:city “Alphen aan den Rijn”.
<http://school/2> plaat:name “Lammerschans”.
<http://school/2> plaat:level “MTS”.
<http://school/2> plaat:city “Leiden”.
<http://school/3> plaat:name “Hogeschool van Utrecht”.
<http://school/3> plaat:level “HTS”.
<http://school/3> plaat:city “Utrecht”.
<http://leerling/1> plaat:school <http://school/1>.
<http://leerling/1> plaat:school <http://school/2>.
<http://leerling/1> plaat:school <http://school/3>.
<http://leerling/2> plaat:school <http://school/1>.
<http://leerling/3> plaat:school <http://school/2>.
}
QUERY
# Show all leerlingen of school1
PREFIX plaat: <http://www.plaatsoft.nl/>
SELECT ?x ?firstName
WHERE
{
?x plaat:firstName ?firstName.
?x plaat:school <http://school/1>
}
DELETE
PREFIX plaat: <http://www.plaatsoft.nl/>
DELETE { ?x plaat:firstName ‘Kees’ }
WHERE { ?x plaat:firstName ‘Kees’ }
UPDATE (SPARQL use delete / insert pattern)
PREFIX plaat: <http://www.plaatsoft.nl/>
DELETE { ?x plaat:firstName ‘Kees’ }
INSERT { ?x plaat:firstName ‘William’ }
WHERE { ?x plaat:firstName ‘Kees’ }
BassieMusic Android App 2.10
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Fix permission issue on Android 13 or higher
– Bump target Android version to Android 14
Click here to download the latest version.
Webserver upgrade
Today i have migrated most of my websites to new hardware:
– Raspberry Pi 4B (2GB) / 32GB SDCard.
I have also upgrade the following software:
– Operating System to Debian Bookworm (kernel 6.1.0-rpi7-rpi-v8)
– WordPress to v6.4.2
– php to v8.2.7
If you detect any problem, please let me known!
BassieMusic Android App 2.9
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Bump target Android version to Android 13
Click here to download the latest version.
Install Jenkins (Docker Image) on Raspberry Pi
# Get Docker image
docker pull jenkins/jenkins:jdk11
# Start Docker image
docker run -d -p 8080:8080 jenkins/jenkins
# Get Portal Access key
docker exec -it
Install Sonar on Raspberry Pi
# Get GIT
sudo apt-get install git
# Get GIT repo
git clone https://github.com/SonarSource/docker-sonarqube.git
cd docker-sonarqube/9/community
# Build docker image
docker build -t sonarqube-custom .
# Start docker image
docker run -d -p 9000:9000 sonarqube-custom
# Remove container
docker rm sonarqube-custom
Raspberry Pi Farm upgrade
Today i have upgraded my Raspberry Pi farm:
– Upgrade OS (bullseye) to latest version
– Created wildcard *.plaatsoft.nl HTTP certificate
– Added HaProxy software load balancer (disable Apache reverse proxy)
– Now load balancer is taking care of the HTTPS offloading
– Now load balancer route HTTP traffic to correct apache node
– Upgrade WordPress to v6.0.2 and wordpress plugins
Migrate MySQL db to PostgreSQL db
mysql
CREATE USER 'family'@'192.168.2.106' IDENTIFIED BY 'family';
GRANT ALL PRIVILEGES ON family . * TO 'family'@'192.168.2.106';
flush privileges;psql
CREATE DATABASE family;
CREATE USER family WITH SUPERUSER ENCRYPTED PASSWORD 'family';
GRANT ALL PRIVILEGES ON DATABASE family TO family;sudo apt-get install pgloader
pgloader mysql://family:family@pi4/family postgresql://family:family@pi6/family
Postgres manually failover
How to failover from Master to Replication node and visa versa
Pi6 192.168.2.106 (MASTER)
Pi7 192.168.2.107 (REPLICATION)Make Replication node master
# Goto pi7
su postgres
/usr/lib/postgresql/13/bin/pg_ctl -D /data02/data promoteRestore old master
# Goto to pi6
sudo cp /data02/data/*.conf ../.
/usr/lib/postgresql/13/bin/pg_ctl -D /data02/data stop
rm -rf /data02/data/*
/usr/lib/postgresql/13/bin/pg_basebackup --pgdata=/data02/data --format=p --write-recovery-conf --checkpoint=fast --label=mffb --progress --host=pi7 --port=5432 --username=plaatsoft
rm /data02/data/standby.signal
/usr/lib/postgresql/13/bin/pg_ctl -D /data02/data start
psql -c "select * from pg_create_physical_replication_slot('standby1_slot');"# Goto to pi7
sudo cp /data02/data/*.conf ../.
/usr/lib/postgresql/13/bin/pg_ctl -D /data02/data stop
rm -rf /data02/data/*
/usr/lib/postgresql/13/bin/pg_basebackup --pgdata=/data02/data --format=p --write-recovery-conf --checkpoint=fast --label=mffb --progress --host=pi6 --port=5432 --username=plaatsoft
/usr/lib/postgresql/13/bin/pg_ctl -D /data02/data startCheck replication
CHECK MASTER NODE
postgres=# \x
postgres=# SELECT * FROM pg_stat_replication;postgres=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
f
(1 row)CHECK REPLICATION NODE
postgres=# \x
postgres=# SELECT * FROM pg_stat_wal_receiver;postgres=# select pg_is_in_recovery();
pg_is_in_recovery
-------------------
t
(1 row)
HaProxy for Postgres HA
Execute on each Postgresql node the following actions # Create check script sudo vi /usr/lib/postgresql/13/bin/pgsqlchk #!/bin/bash # This script checks if a postgres server is healthy running on localhost. It will return: # "HTTP/1.x 200 OK\r" (if postgres is running smoothly) # - OR - # "HTTP/1.x 500 Internal Server Error\r" (else) # The purpose of this script is make haproxy capable of monitoring postgres properly # It is recommended that a low-privileged postgres user is created to be used by this script. # For eg. create user healthchkusr login password 'hc321'; PGBIN=/usr/pgsql-10/bin PGSQL_HOST="localhost" PGSQL_PORT="5432" PGSQL_DATABASE="postgres" PGSQL_USERNAME="postgres" export PGPASSWORD="passwd" TMP_FILE="/tmp/pgsqlchk.out" ERR_FILE="/tmp/pgsqlchk.err" # We perform a simple query that should return a few results VALUE=`/usr/lib/postgresql/13/bin/psql -t -h localhost -U postgres -p 5432 -c "select pg_is_in_recovery()" 2> /dev/null` # Check the output. If it is not empty then everything is fine and we return something. Else, we just do not return anything. if [ $VALUE == "t" ] then /bin/echo -e "HTTP/1.1 206 OK\r\n" /bin/echo -e "Content-Type: Content-Type: text/plain\r\n" /bin/echo -e "\r\n" /bin/echo "Standby" /bin/echo -e "\r\n" elif [ $VALUE == "f" ] then /bin/echo -e "HTTP/1.1 200 OK\r\n" /bin/echo -e "Content-Type: Content-Type: text/plain\r\n" /bin/echo -e "\r\n" /bin/echo "Primary" /bin/echo -e "\r\n" else /bin/echo -e "HTTP/1.1 503 Service Unavailable\r\n" /bin/echo -e "Content-Type: Content-Type: text/plain\r\n" /bin/echo -e "\r\n" /bin/echo "DB Down" /bin/echo -e "\r\n" fi # Make script executable sudo chmod a+x /usr/lib/postgresql/13/bin/pgsqlchk # install xinetd and telnet sudo apt-get install xinetd telnet -y # Create xinitd file sudo vi /etc/xinetd.d/pgsqlchk service pgsqlchk { flags = REUSE socket_type = stream port = 23267 wait = no user = nobody server = /usr/lib/postgresql/13/bin/pgsqlchk log_on_failure += USERID disable = no only_from = 0.0.0.0/0 per_source = UNLIMITED } sudo bash -c 'echo "pgsqlchk 23267/tcp # pgsqlchk" >> /etc/services' sudo systemctl restart xinetd # Check if service is working telnet 127.0.0.1 23267 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. HTTP/1.1 206 OK Content-Type: Content-Type: text/plain Standby Connection closed by foreign host. Execute on HaProxy following actions # Install HaProxy sudo apt-get install haproxy -y sudo vi /etc/hosts Add pi6 192.168.2.106 Add pi7 192.168.2.107 sudo vi /etc/haproxy/haproxy.cfg global maxconn 100 defaults log global mode tcp retries 2 timeout client 30m timeout connect 4s timeout server 30m timeout check 5s listen stats mode http bind *:10000 stats enable stats refresh 10s stats uri / listen Postgres bind *:5432 option httpchk http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions server pi6 pi6:5432 maxconn 100 check port 23267 server pi7 pi7:5432 maxconn 100 check port 23267 systemctl restart haproxy Check HaProxy # Install postgres client sudo apt-get install postgresql-client # Start psql client psql -h localhost -U postgres postgres=# select pg_is_in_recovery(); pg_is_in_recovery ------------------- f (1 row)
Check HaProxy portal http://192.168.2.107:5000
BassieMusic Android App 2.8
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Refactored the code a lot
– Make everything more efficient and faster
– Deezer API intergration for automatic album cover downloads!
Click here to download the latest version.
BassieMusic Android App 2.7
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Better music metadata parsing
– Music cover images
– Better experience for tablet users
Click here to download the latest version.
BassieMusic Android App 2.6
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Added real shuffle mode by holding down the shuffle button
– Added music playing history by holding down the previous and next buttons
Click here to download the latest version.
BassieMusic Android App 2.5
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Make fast scrollbar optional
– Some bug fixes
Click here to download the latest version.
WarQuest Android App 2.3
A new WarQuest Android app (v2.3) is released in the Google Play Store by bplaat.
This version has the following new features:
– Major code rewrite
– More animations
– Add some stuff to the settings menu
– Bug fixes
Click here to download the latest version.
BassieMusic Android App 2.4
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Many bug fixes
– The music playing state is more consistent
– Some code future proofing
Click here to download the latest version.
BassieMusic Android App 2.3
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Added fast alphabetic scrollbar
– Fixed music sort order to be case insensitive
– Added more animations and polished the UI experience more
– Added remember last song feature
– Cleaned up the source code a lot
Click here to download the latest version.
BassieMusic Android App 2.2
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Fixed some bugs
– Added material design ripple animations to icon buttons
– Updated the settings page
Click here to download the latest version.
WarQuest Android App 2.2
A new WarQuest Android app (v2.2) is released in the Google Play Store by bplaat.
This version has the following new features:
– Removed support for Android versions lower then 5.0 Lollipop
– Add language and theme option to the settings page
– Fixed some dark mode / theme bugs
Click here to download the latest version.
BassieMusic Android App 2.1
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– Removed support for Android versions lower then 5.0 Lollipop
– Redesigned the search page
– Add better settings page
– Fixed some dark theme bugs
Click here to download the latest version.
BassieMusic Android App 2.0
PlaatSoft has released a new version of the BassieMusic Android App in the Google Play Store.
The following changes were made:
– A new music search function
– Fixed some bugs
Click here to download the latest version.