Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[YouTube] Android App Gestures

I don’t remember exactly when and how I found all this out, but I have noticed that many people don’t know many features/gestures.

  • If you double tap with one finger on the left or right of the screen, you can skip 10 seconds (I guess most people know this). If you tap more often, it can skip multiples of 10 seconds.
  • If you double tap with two fingers, you can skip to the next chapter (if the video has chapter marks).
  • If you simply tab and hold with one finger, you can fast forwards with 2x speed.
  • If you are watching a video, you can simply swipe up to view the video in full screen (will turn video into landscape mode) or swipe down to exit full screen mode.
  • In full screen mode, pinch with two fingers to zoom in or out. Then pan = move to that corner you want to look closer.
  • When searching for a specific scene, press and hold on the progress bar and then slightly swipe upwards. You get a larger progress bar, which contains preview images for the respective timestamps, and through which you can easily scroll.

And there are probably others that I don’t know about…

[YouTube] Combine Metube & SponsorBlock

I have been using MeTube for some time to occasionally download YouTube videos. Now I’ve been looking for a way to combine MeTube with SponsorBlock to get rid of the ads when downloading a file. And it turned out to be possible. You can either use SponsorBlock to add a chapter for an ad segment, or you can use it to remove the ad or any other segment using the remove_sponsor_segments parameter. Currently, it is not possible to do both things (create segment chapters + remove segments). Here the solution to remove ads while downloading:

Create the following JSON File:

{
  "postprocessors": [
    {
      "api": "https://sponsor.ajay.app/",
      "categories": [
        "intro",
        "outro",
        "poi_highlight",
        "selfpromo",
        "sponsor",
        "interaction" 
      ],
      "key": "SponsorBlock",
      "when": "after_filter"
    },
    {
      "force_keyframes": false,
      "key": "ModifyChapters",
      "remove_chapters_patterns": [],
      "remove_ranges": [],
      ""remove_sponsor_segments": ["sponsor","interaction","selfpromo"],
      "sponsorblock_chapter_title": "'[SponsorBlock]: ''%(category_names)l'"
    },
    {
      "add_chapters": true,
      "add_infojson": "none",
      "add_metadata": false,
      "key": "FFmpegMetadata"
    }
  ]
}

The relevant parts here are the categories:

  • intro — video intro segments
  • outro — video endings or credits
  • sponsor — sponsored ads/segments to skip
  • selfpromo — creator self-promotion clips
  • interaction — calls to action (like “subscribe” asks)
  • poi_highlight — important highlights or notable moments (Points of Interest)

And the remove_sponsor_segments parameter. Here you can provide all sections you want to have removed during a download.

The last step is to mount the JSON File into the Container:

version: '3'

services:
  metube:
    image: alexta69/metube
    ports:
      - "8081:8081"
    volumes:
      - ./downloads:/downloads
      - ./ytdl_options.json:/config/ytdl_options.json:ro # the first part must be the path/place of your new created json file
    environment:
      - YTDL_OPTIONS_FILE=/config/ytdl_options.json

To add video links to MeTube you can also use this handy Browser Add-on: MeTube Downloader

[Nextcloud] Docker update 30.0.11 to 31.0.5 – Encryption issues / MariaDB ROW_FORMAT=Dynamic

Today I updated to the latest Nextcloud docker container, as there were massive problems with the encryption app in previous versions. User couldn’t login and file versions could not be opened… Read more about it in the following two issues:

https://github.com/nextcloud/server/issues/51066
https://github.com/nextcloud/server/issues/52161

Allthough some users reported, that they still have issues, I tried the latest version. Luckily, in my case the update finished without issues and it solved all my problems related to the encryption app.

After the update, I got the usual warnings that I have to run some occ commands:

docker exec --user www-data nextcloud-app php occ db:add-missing-indices
docker exec --user www-data nextcloud-app php occ maintenance:repair --include-expensive

But then there was also a very long warning:

Falsches Zeilenformat in deiner Datenbank gefunden. ROW_FORMAT=Dynamic bietet die beste Datenbankleistung für Nextcloud. Bitte aktualisiere das Zeilenformat in der folgenden Liste: oc_richdocuments_template, oc_direct_edit, oc_flow_operations, oc_migrations, oc_talk_sessions, oc_circles_remote, oc_circles_member, oc_trusted_servers, oc_richdocuments_direct, oc_directlink, oc_talk_invitations, oc_cards, oc_filecache, oc_oauth2_clients, oc_storages_credentials, oc_login_flow_v2, oc_group_admin, oc_files_trash, oc_deck_labels, oc_deck_stacks, oc_ocsms_sendmessage_queue, oc_weather_city, oc_collres_collections, oc_jobs, oc_deck_assigned_users, oc_phonetrack_points, oc_deck_cards, oc_ldap_group_mapping_backup, oc_ocsms_config, oc_mail_mailboxes, oc_accounts, oc_twofactor_providers, oc_calendarchanges, oc_gpodder_subscriptions, oc_appconfig, oc_mail_coll_addresses, oc_polls_notif, oc_calendarobjects, oc_addressbookchanges, oc_calendars, oc_twofactor_totp_secrets, oc_user_status, oc_talk_internalsignaling, oc_vcategory_to_object, oc_dav_cal_proxy, oc_calendar_resources, oc_talk_commands, oc_mail_message_tags, oc_authtoken, oc_polls_log, oc_ocsms_smsdatas, oc_phonetrack_proxims, oc_share, oc_text_steps, oc_polls_preferences, oc_preferences, oc_weather_config, oc_twofactor_backupcodes, oc_circles_circle, oc_deck_boards, oc_webauthn, oc_federated_reshares, oc_activity, oc_mimetypes, oc_collres_resources, oc_notifications, oc_mail_classifiers, oc_notes_meta, oc_schedulingobjects, oc_circles_mount, oc_circles_membership, oc_talk_attendees, oc_news_folders, oc_deck_assigned_labels, oc_mail_aliases, oc_oauth2_access_tokens, oc_phonetrack_geofences, oc_news_items, oc_polls_options, oc_filecache_extended, oc_phonetrack_pubshares, oc_news_feeds, oc_groups, oc_text_documents, oc_files_lock, oc_polls_polls, oc_calendarsubscriptions, oc_text_sessions, oc_whats_new, oc_phonetrack_shares, oc_onlyoffice_filekey, oc_polls_share, oc_calendar_reminders, oc_bruteforce_attempts, oc_share_external, oc_systemtag_object_mapping, oc_systemtag, oc_cards_properties, oc_calendar_rooms, oc_talk_bridges, oc_mail_attachments, oc_polls_comments, oc_storages, oc_ocsms_user_datas, oc_flow_operations_scope, oc_calendar_rooms_md, oc_richdocuments_assets, oc_calendarobjects_props, oc_phonetrack_sessions, oc_mail_local_messages, oc_comments_read_markers, oc_calendar_appt_configs, oc_calendar_invitations, oc_richdocuments_wopi, oc_gpodder_episode_action, oc_recent_contact, oc_circles_event, oc_circles_share_lock, oc_calendar_resources_md, oc_circles_token, oc_circles_mountpoint, oc_deck_board_acl, oc_authorized_groups, oc_phonetrack_filtersb, oc_activity_mq, oc_flow_checks, oc_profile_config, oc_accounts_data, oc_announcements_map, oc_mail_accounts, oc_known_users, oc_collres_accesscache, oc_mail_provisionings, oc_announcements, oc_onlyoffice_permissions, oc_addressbooks, oc_group_user, oc_ldap_user_mapping, oc_notifications_settings, oc_calendar_appt_bookings, oc_deck_attachment, oc_file_locks, oc_ratelimit_entries, oc_polls_votes, oc_ocsms_conversation_read_states, oc_dav_shares, oc_phonetrack_tileserver, oc_talk_rooms, oc_polls_watch, oc_notifications_pushhash, oc_mail_tags, oc_privacy_admins, oc_systemtag_group, oc_ldap_group_mapping, oc_mail_messages, oc_mail_recipients, oc_onlyoffice_instance, oc_comments, oc_ldap_group_members, oc_users, oc_properties, oc_user_transfer_owner, oc_mail_trusted_senders, oc_phonetrack_devices, oc_vcategory, oc_mounts. Weitere Informationen findest du in der Dokumentation ↗.

For all these tables a row format adjustment was required. I used ChatGPT to generate the ALTER TABLE commands for all tables that were mentioned in the warning and used the following commands to enter the MariaDB Container:

# Access MariaDB, check your .env file for user and password
docker exec -it nextcloud-db mysql -u nextcloud -p

# Display database 
SHOW DATABASES;

# select the nextcloud database
USE NEXTCLOUD;

# alter row format
ALTER TABLE oc_richdocuments_template ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_direct_edit ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_flow_operations ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_migrations ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_talk_sessions ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_remote ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_member ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_trusted_servers ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_richdocuments_direct ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_directlink ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_talk_invitations ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_cards ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_filecache ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_oauth2_clients ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_storages_credentials ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_login_flow_v2 ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_group_admin ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_files_trash ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_labels ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_stacks ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ocsms_sendmessage_queue ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_weather_city ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_collres_collections ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_jobs ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_assigned_users ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_points ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_cards ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ldap_group_mapping_backup ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ocsms_config ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_mailboxes ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_accounts ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_twofactor_providers ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendarchanges ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_gpodder_subscriptions ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_appconfig ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_coll_addresses ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_notif ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendarobjects ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_addressbookchanges ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendars ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_twofactor_totp_secrets ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_user_status ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_talk_internalsignaling ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_vcategory_to_object ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_dav_cal_proxy ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_resources ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_talk_commands ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_message_tags ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_authtoken ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_log ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ocsms_smsdatas ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_proxims ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_share ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_text_steps ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_preferences ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_preferences ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_weather_config ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_twofactor_backupcodes ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_circle ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_boards ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_webauthn ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_federated_reshares ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_activity ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mimetypes ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_collres_resources ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_notifications ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_classifiers ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_notes_meta ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_schedulingobjects ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_mount ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_membership ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_talk_attendees ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_news_folders ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_assigned_labels ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_aliases ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_oauth2_access_tokens ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_geofences ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_news_items ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_options ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_filecache_extended ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_pubshares ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_news_feeds ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_groups ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_text_documents ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_files_lock ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_polls ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendarsubscriptions ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_text_sessions ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_whats_new ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_shares ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_onlyoffice_filekey ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_share ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_reminders ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_bruteforce_attempts ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_share_external ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_systemtag_object_mapping ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_systemtag ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_cards_properties ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_rooms ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_talk_bridges ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_attachments ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_comments ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_storages ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ocsms_user_datas ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_flow_operations_scope ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_rooms_md ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_richdocuments_assets ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendarobjects_props ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_sessions ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_local_messages ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_comments_read_markers ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_appt_configs ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_invitations ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_richdocuments_wopi ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_gpodder_episode_action ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_recent_contact ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_event ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_share_lock ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_resources_md ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_token ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_circles_mountpoint ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_board_acl ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_authorized_groups ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_filtersb ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_activity_mq ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_flow_checks ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_profile_config ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_accounts_data ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_announcements_map ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_accounts ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_known_users ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_collres_accesscache ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_provisionings ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_announcements ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_onlyoffice_permissions ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_addressbooks ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_group_user ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ldap_user_mapping ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_notifications_settings ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_calendar_appt_bookings ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_deck_attachment ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_file_locks ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ratelimit_entries ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_votes ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ocsms_conversation_read_states ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_dav_shares ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_tileserver ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_talk_rooms ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_polls_watch ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_notifications_pushhash ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_tags ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_privacy_admins ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_systemtag_group ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ldap_group_mapping ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_messages ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_recipients ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_onlyoffice_instance ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_comments ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_ldap_group_members ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_users ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_properties ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_user_transfer_owner ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mail_trusted_senders ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_phonetrack_devices ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_vcategory ROW_FORMAT=DYNAMIC;
ALTER TABLE oc_mounts ROW_FORMAT=DYNAMIC;

# exit MariaDB
EXIT;

After a refresh in the NC webinterface, all warnings were gone.

[Homelab] Notes on “How To Run A Server At Home Without An IPv4 Address”

Since my domain provider does not support DynDNS, I can only create subdomains for my VPS with a static IP address, but not for any of my services hosted at home. Fortunately, there is a really cool workaround I’ve been using for some years, which I got from here: https://blog.wirelessmoves.com/2019/06/how-to-run-a-server-at-home-without-an-ipv4-address.html

Now with the migration to a new server running Ubuntu 24.04, I had to redo the steps and noticed three minor differences.

# The .ssh folder and authorized_keys file did not exist per default
mkdir .ssh
sudo nano .ssh/authorized_keys

# The systemd command to restart the ssh service
sudo systemctl restart ssh.service

# Insted of netstat I had to use 'ss' to monitor the tcp ports
watch -n 0.5 "ss -tulpn"

Since I’m really not a Linux or command line expert and would surely forget about it otherwise, I’m writing it down for my next server migration 🙂

[NAS] IPMI Docker

In my TrueNAS Server I use an ASRock Rack C2550D4I motherboard, which is quite old. It has a Java IPMI Interface, which was/is really handy. The problem is that it requires an old version of Java, and I haven’t had a computer in the household with Java installed at all for a few years, let alone a version that old. But luckily I recently stumbled across this docker project: https://github.com/solarkennedy/ipmi-kvm-docker

The setup is super easy and with the help of this cool project, I can finally use the IPMI functionality of my NAS again.

version: '3.9'
services:
    ipmi-kvm-docker:
        image: solarkennedy/ipmi-kvm-docker
        environment:
            - RES=1600x900x24
        ports:
            - '8080:8080'

[Proxmox] Upgrade 7.4 to 8.0 – Failed to run lxc.hook.pre-start for container

After updating my Proxmox Server to PVE8.0, suddenly two lxc containers did not start anymore.

root@pve:~# pct start 192
run_buffer: 322 Script exited with status 2
lxc_init: 844 Failed to run lxc.hook.pre-start for container "192"
__lxc_start: 2027 Failed to initialize container "192"
startup for container '192' failed

I tried to view the error.log but couldn’t find any helpful information.

lxc-start -lDEBUG -o error.log -F -n 192

When googling, I stumbled across this reddit post. Although the issue was a bit different, I tried the recommended steps. The first command, directly led me to the right direction…

root@pve:~# pct mount 192
mounting container failed
directory '/mnt/nfs/data/folder' does not exist

For whatever reason, after restarting proxmox it did not mount the nfs shares properly on the host. And of course, after this hint, I noticed that both containers were trying to mount some of these folders, which were actually nfs shares from my NAS. A simple mount -a on the host fixed it immediately. Besides of this little problem, everything went well with the proxmox upgrade!

[YouTube] Ad-free consumption and other helpful add-ons

When I was at a friend’s house the other day and a YouTube playlist was playing on the TV, I was really shocked. After every video, there were one or two ads (and some of them even in between). I was not aware how extremely many ads you get when using YouTube without an ad blocker. Therefore, a small collection of apps, add-ons and links that help to make YouTube a bit more enjoyable:

Browser

AndroidTV / FireTV

Android

HTPC

DNS Blocking (i.e. with PiHole)


Update 15.01.2024: When using YouTube in a Browser in combination with uBlock, you likely receive the following message right now: “Ad blockers are not allowed on YouTube”. The only working solutions to prevent this message and to continue watching ad-free is disabling uBlock on YouTube and use this Script with Tampermonkey (at least for me).

Update 25.01.2025: I found Chrome Mask very helpful, as I continue to experience problems when using uBlock in combination with Firefox on YouTube.


Update 23.07.2025: To stop the super annoying AI translations, you can use the browser Add-on YouTube No Translation (GitHub).
When using ReVanced, you can force the App to use the original Audio. Got to the ReVanced Settings:
– Miscellaneous → Spoof Video Streams → Standard-Client → iOS TV
– Video → Force original audio → turn on

[Home Assistant] Stromzähler auslesen: LOGAREX LK13BE803049

Wurde der Stromzähler in den letzten Jahren getauscht, solltet ihr eine moderne Messeinrichtung haben, welche eine Infrarot (IR) Schnittstelle für das Auslesen von Daten anbietet. Dazu gibt es bereits eine große Anzahl an Anleitungen, z. B. hier und hier. Daher nur kurz zusammengefasst, welche Schritte notwendig waren für meinen LOGAREX LK13BE803049 (Baujahr 2018).

Stromzähler vorbereiten

Um Zugriff auf alle Daten, die der Stromzähler so sammelt zu bekommen, benötigt man eine PIN. Diese PIN kann man über das Online-Portal des Messstellenbetreibers herausfinden, alternativ geht das auch via Hotline oder Mail. Hat man seine PIN, am besten in der Anleitung nachschlagen, wie die PIN eingeben (Seite 6) und wie der “vollständiger Datensatz” (Seite 8) aktiviert wird. Ansonsten bekommt man nur einen Bruchteil der vorhanden Daten zurück.

IR Lese-Schreibkopf

Kann man selber basteln für wenige Euro oder alternativ fertig kaufen. Ich habe diesen (WIFI lese-schreib-Kopf EHZ Volkszähler Hichi Smartmeter) gekauft, da hier ein ESP32 dabei ist und dieser sogar bereits mit Tasmota geflasht wurde. Um Abstürze im Betrieb zu verhindern, darauf achten, dass das Netzteil der Micro-USB Stromversorgung genug Leistung hat. Ist die Stromversorgung sichergestellt, mittels Smartphone mit dem vom ESP32 geöffneten Access Point verbinden und die WLAN Daten des Heimnetzes im Tasmota Webinterface eingeben (sollte sich automatisch öffnen nach der AP Verbindung). Nun kann das ganze Teil mithilfe des Magneten am Stromzähler über der IR Schnittstelle (Optische Datenschnittstelle D0) angebracht werden. Im Idealfall hat man dafür noch eine freie Steckdose in der Nähe des Stromzählers.

Script anlegen in Tasmota

Erneut das Tasmota Webinterface aufrufen, am besten diesmal vom Desktop PC, und über den Button Consoles zu Edit Script navigieren. Dort müssen nun einige Zeilen eingetragen werden, die sich je nach Stromzähler unterscheiden können. Eine Übersicht der möglichen Werte des LOGAREX Zählers findet ihr in der Anleitung auf Seite 10. Bei mir sah das Ergebnis dann so aus:

>D
>B
=>sensor53 r
>M 1
+1,3,o,0,9600,LOGAREX
1,1-0:1.8.0*255(@1,BEZUG,KWh,total_in,4
1,1-0:2.8.0*255(@1,EINSPEISUNG,KWh,total_out,4
1,1-0:16.7.0*255(@1,Verbrauch aktuell,W,current,16
1,1-0:1.8.0*96(@1,letzter Tag,KWh,total_day,1
1,1-0:1.8.0*97(@1,letzte Woche,KWh,total_week,1
1,1-0:1.8.0*98(@1,letzter Monat,KWh,total_month,1
1,1-0:1.8.0*99(@1,letztes Jahr,KWh,total_year,1
#

Home Assistant

Via MQTT und Tasmota Integration können die Werte direkt an Home Asisstant übertragen werden und z.B. im Energy Dashboard verwendet werden. Dafür einfach die Schritte unter 4b von dieser Anleitung umsetzten. Falls MQTT auf eurem Home Assistant noch nicht eingerichtet ist, müsst ihr das noch tun. Dafür gibt es auch einen Haufen Anleitungen oder Videos. Am besten einfach eine recht aktuelle Anleitung heraussuchen. Bei der Einrichtung legt ihr auch einen separaten User für MQTT an, welchen ihr dann angeben müsst in Tasmota. So sah es bei mir dann aus.

In der Tasmota Integration in Home Assistant wurde das Device mit entsprechen Entitäten direkt gefunden.

Da die Werte jedoch ohne Einheit übertragen werden, muss diese noch händisch in der configuration.yaml gepflegt werden. Wenn ich mich recht erinnere, ist danach ein Neustart von Home Assistent erforderlich.

 # Tasmota Stromzähler
homeassistant:
  customize:
    sensor.tasmota_logarex_total_in:
      device_class: energy 
      unit_of_measurement: "kWh"
      state_class: total_increasing
    sensor.tasmota_logarex_total_out:
      device_class: energy 
      unit_of_measurement: "kWh"
      state_class: total_increasing
    sensor.tasmota_logarex_current: 
      device_class: power 
      unit_of_measurement: "W"
    sensor.tasmota_logarex_total_day:
      device_class: energy 
      unit_of_measurement: "kWh"
      state_class: total_increasing
    sensor.tasmota_logarex_total_week:
      device_class: energy 
      unit_of_measurement: "kWh"
      state_class: total_increasing  
    sensor.tasmota_logarex_total_month:
      device_class: energy 
      unit_of_measurement: "kWh"
      state_class: total_increasing  
    sensor.tasmota_logarex_total_year:
      device_class: energy 
      unit_of_measurement: "kWh"
      state_class: total_increasing  

So sieht die Anzeige der Sensoren direkt etwas brauchbarer aus. 🙂

Die schöne Energieverteilungsanzeige vom Energy Dashboard kann auch in jedem anderen Dashboard verwendet werden via:

type: energy-distribution
link_dashboard: true

Einen Überblick der weiteren Energy Cards findet man hier.

Im Energy Dashboard kann auch ein Preis für die kWh hinterlegt werden. So sieht man direkt seinen Verbrauch für ausgewählte Zeiträume. Hier mal ein extremes Beispiel, an dem wir den ganzen Tag Äpfel eingekocht und Kuchen gebacken haben. So ein Verbrauch ist bei uns natürlich nicht die Regel. 🙂

Für mein Smartphone Dashboard habe ich dann noch die neue Statictics Card genutzt, um einen noch einfacheren Einblick in meine laufenden Kosten zu bekommen. Die Anordnung erfolgt durch eine Grid Card.

square: false
columns: 2
type: grid
cards:
  - type: statistic
    entity: sensor.tasmota_logarex_total_in_cost
    period:
      calendar:
        period: day
    stat_type: change
    name: Kosten heute
  - type: statistic
    entity: sensor.tasmota_logarex_total_in_cost
    period:
      calendar:
        period: day
        offset: -1
    stat_type: change
    name: Kosten gestern