Skip to content
Showing user profile of selected author: -

Blog website crawlers and bots in Apache2

Found a couple more bots crawling my website, and from the look at online resources it seems I catched a few of the bad guys. Crawlers which ignore the robots.txt standard, and just crawl a website for content.

Decided to do something against it, and added a filter in Apache2.

The way I have my webserver setup is that I have templates for every website (they all have different configs), and deploy them using Ansible. Parts of the website configuration which are the same, or at least similar, are handled by includes.


Continue reading "Blog website crawlers and bots in Apache2"

Create child pages in Redmine

Once or twice a year I have to setup a new Redmine project, which we use to organize conferences for PostgreSQL Europe.

Every single time I'm trying to figure out how the child pages for the meeting notes work.

Steps required:

  • Create a page "MeetingMinutes", doesn't need to have any content, but it must exist
  • Create the first child page with meeting minutes, as parent page select "MeetingMinutes"
  • On the main wiki page insert a link with: "{{child_pages(MeetingMinutes)}}"

Every time I forget step 1), because this page is only required as parent page, and serves no further purpose. And then I'm wondering why I can't create child pages.

Connect a Mac to a SMB server - as Guest

One of the things I do in our network is public drives. Every Linux system has a public "incoming" which is mapped to the primary user of the device (if there is one, like for a laptop). And this incoming shared drive can be accessed without password.

This makes it really convenient to copy files around from one laptop/user to another, or from mobile devices to laptops and vice versa, or use the printer/scanner to send the scan job directly to the laptop of the user's device. All in all, the users like this, and use it a lot. There is also minimal protection built-in, it will only work in our home network, access is blocked when the laptop is connected to a different network. But the folders are mostly empty anyway. For sharing files over the Internet we also have a Syncthing instance running, but that's a different story, and not as easy to use.

One thing which I was annoyed about is that by default a Mac will try to connect as a registered user. There is an option "Connect as Guest", but it's not pre-selected. Therefore every time I wanted to share something between Linux and Mac, I had to start "Finder", to to "Go" and then "Connect to Server", then click on the server from the list of last entries, and then also click on "Guest". The built-in help is also not useful, as it only talks about "click on Guest".

But it turns out that one can "pre-select" the Guest user. For this, the username is "Guest", and there is no password. This goes between the protocol and the hostname. Example:




There has to be a ":" between the username and the (non-existent) password, and the credentials are separated from the hostname by a "@". Using this connect string will auto-connect as anonymous user to the remote share. One click and a couple seconds saved!

Continue reading "Connect a Mac to a SMB server - as Guest"

openHAB: stop a ChromeCast

There are a number of ChromeCasts in our setup. I'm adding (physical) switches to turn displays on and off, and primarily control the volume. When I turn the display off, I also want the ChromeCast to stop doing whatever it is doing right now (stop streaming), and go back to the default application (for video CC).

The openHAB ChromeCast binding has a separate channel for that:

Switch    chromecast_chromecast_dfb5af5187ce1135b276239130aef282_stop     { channel="chromecast:chromecast:dfb5af5187ce1135b276239130aef282:stop" }

However since the channel is named "stop", it has to be "enabled" with "ON". Doesn't make sense? It is as it is:


And the result:

2021-01-18 17:13:20.305 [ome.event.ItemCommandEvent] - Item 'chromecast_chromecast_dfb5af5187ce1135b276239130aef282_stop' received command ON
2021-01-18 17:13:20.321 [nt.ItemStatePredictedEvent] - chromecast_chromecast_dfb5af5187ce1135b276239130aef282_stop predicted to become ON
2021-01-18 17:13:20.443 [vent.ItemStateChangedEvent] - chromecast_chromecast_dfb5af5187ce1135b276239130aef282_appName changed from <...> to UNDEF
2021-01-18 17:13:20.451 [vent.ItemStateChangedEvent] - chromecast_chromecast_dfb5af5187ce1135b276239130aef282_appId changed from <...> to UNDEF
2021-01-18 17:13:20.455 [vent.ItemStateChangedEvent] - chromecast_chromecast_dfb5af5187ce1135b276239130aef282_statustext changed from Casting: <...> to UNDEF
2021-01-18 17:13:20.457 [vent.ItemStateChangedEvent] - chromecast_chromecast_dfb5af5187ce1135b276239130aef282_idling changed from OFF to ON
2021-01-18 17:13:23.888 [vent.ItemStateChangedEvent] - chromecast_chromecast_dfb5af5187ce1135b276239130aef282_appName changed from UNDEF to Backdrop
2021-01-18 17:13:23.893 [vent.ItemStateChangedEvent] - chromecast_chromecast_dfb5af5187ce1135b276239130aef282_appId changed from UNDEF to E8C28D3C


openHAB: timestamp from last Item update

If openHAB has a Persistence service configured, the time of the last Item update (and a couple other times) is available in Rules. This makes it quite handy to check if a certain item hasn't been updated in a long time. As example I have the Tankerkoenig Binding installed, and this data is persisted in InfluxDB. This way I can see historic gas prices in Grafana.

When the Telegram Bot answers the "/tanken" question, it appends the timestamp of the last gas prices update.


Continue reading "openHAB: timestamp from last Item update"

Online indicator for remote controllable power plugs in openHAB

Recently I installed a number of new power sockets (like this one). The Hue bridge can not only add each switch to a light group, but also reports each plug as a Thing in openHAB. There I thought it will be a nice touch if openHAB actually reports when it sees a device plugged in. The power socket has a LED which turns on when the plug is on. The Hue bridge reports OFFLINE and ONLINE. That's useful.

The plan is to turn the LED light - and the power plug - on and off for a few second.


Continue reading "Online indicator for remote controllable power plugs in openHAB"

openHAB: reset DateTime in rules

In one of my openHAB rules I'm using a timestamp to track when an Item went offline. This is used in my monitoring to let the user (me) know how long the Item is already offline.

Background: we have a couple ChromeCasts in our network. When they are connected to a 5GHz Wi-Fi they are quite unstable and often loose the network connection. Usually the openHAB binding reconnects the device quickly, but it happens that the device stays offline. It might have something to do with the router, but nevertheless I want to know when things go offline.

For this I defined a virtual Switch as DateTime:

DateTime	LivingRoom_OfflineSince		"Offline Since [%tY-%tm-%td%tH:%tM:%tS]"

When the ChromeCast goes offline, this Switch is updated in a rule with the current time:

LivingRoom_OfflineSince.postUpdate( new DateTimeType() )


However resetting the DateTime switch when the item comes back online proved to be a small challenge, the documentation is unclear. People write online about "UnDeftype", "UNDEF", "(unknown)", "UnDefType.UNDEF", "UnDefType.NULL" and a couple more.

In the end it's quite easy:


Just update the Item with NULL. Don't use sendCommand() here, you only want to update the Item, not send a new command to a virtual switch.

Restic backup

Was asked quite a few times how I do my backups with Restic.

For more than 10 years I was using "Duplicity" for backups, but in 2019 I changed to Restic. The main reason for the change was that Duplicity still can't handle "Big Data", as in: larger directories. In 2009 someone opened an issue on the Duplicity bugtracker, and this problem still exists as of today. For about two years I was shifting around the problem, excluding files, trying to make the sigfile smaller. But at some point I decided that it is enough and I need to change the tool.

Duplicity knows two backup modes: "full backup" and "incremental backup". Once in a while you take a full backup, and then you add incremental backups to that full backup. In order to restore a certain backup you need the full backup and the incremental backups. Therefore my go-to mode was to always have two full backups and a couple incremental backups in-between. Even if something goes wrong with the latest full backup, I can still go back to the previous full backup (of course with some changes lost, but that's still better than nothing). When taking a new full backup, the oldest one is only deleted when the new one is completed. Accordingly when a new incremental backup is created, it's a new set of files. Removing the backup removes all the files from this incremental backup. That worked well, but needed scheduling. Over time I wrote a wrapper script around Duplicity, which did schedule new full and incremental backups.

Restic works in a different way. There is no concept of "full backup" and "incremental backup". Basically every backup is a full backup, and Restic figures out which files changed, got deleted, or added. Also it does deduplication: if files are moved around, or appear multiple times, they are not added multiple times into the backup. Deduplication is something which Duplicity can't do. But because Restic can do deduplication, there is no common set of files which belong to a single snapshot. Data blobs from one backup can stay in the repository forever, removing snapshots might not remove any files at all.

Restic on the other hand needs "prune" to remove old data. A snapshot can be removed according to the policy specified, but this does not remove the data from the backup directory. A "prune" run will go over the data and remove any block which is no longer needed.

My first question - after figuring out which other backup tool to use: shall I replicate the wrapper script, or try something else? Given that the backup doesn't need complex scheduling, I decided against writing a complex wrapper. And since I am now deploying all devices with Ansible, I decided to integrate this into my Playbooks, and deploy a set of shell scripts. The goal was to have a small number of dedicated scripts doing the daily backup work, and another set of "helper" scripts which I can use to inspect the backup, modify it, or restore something.

My main goals for this: "small number of programs/scripts" (Unix style: each tool does one job), "rapid development" (don't spend weeks writing another scheduler), "rapid deployment" (re-run Playbooks and let Ansible deploy this to all devices).


Continue reading "Restic backup"

openHAB: Configuration model '....rules' has errors, therefore ignoring it: no viable alternative at input '...'

The openHAB rule system is not very helpful by pointing out when it's missing something, or when there is an error to actually point to the problem.

Was debugging an error message for a while and couldn't figure out what is wrong:

Configuration model '....rules' has errors, therefore ignoring it: [152,5]: no viable alternative at input '...'

The line number specified was somewhere else in the file, and had nothing to do with the rule in question. After removing almost everything from the rule, except a logInfo() message, the error still happened - and then it occured to me: I forgot to specify "Item".

My faulty code was:

rule "Rule Name"
    Sensor_name received update

where it should have been:

rule "Rule Name"
    Item Sensor_name received update

Error message totally not helpful ...