I’ve been using laptops for a while for my PVE setup as you can get some good cheap machines, with an energy efficient chip and as long as it has lots of RAM it will handle anything I throw at it.
A while ago I worked out how to stop it switching off/hibernating when I closed the lid, but I recently realised that the screen was still on (power hog). I’ve fixed that.
I also want to send battery status information to HomeAssistant so I can cycle the battery via a smart plug.
First the lid problem. This is controlled by the logind daemon.
Create a drop-in folder for the daemon mkdir /etc/systemd/logind.conf.d/
Create the drop-in file nano /etc/systemd/logind.conf.d/lid.conf with contents of
1
2
3
4
[Login]
HandleLidSwitch=lock
HandleLidSwitchExternalPower=lock
HandleLidSwitchDocked=locky
Sometimes you might want to replace lock with ignore
You could just restart the daemon, but it is better to reboot the machine.
Second, switching off the machine. For this I will just refer you to the solution I found, but note I put the systemd file in the same position as the Battery Monitor daemon Monitoring a PVE Machine’s Battery Status.
I’ve used PVE (Proxmox Virtual Environment) for a while now for Node-RED, MQTT Broker, Emoncms etc and it really is bullet proof. My preferred setup is on an old laptop so this setup has a built-in UPS (its battery). I’ve thought for a while that I really should cycle the battery to enhance how long it runs and preserve the lifespan.
Needing to get a new laptop so I can upgrade the old system to V8, I decided to work out the best way to monitor the battery. I have installed Netdata and then accessed the Battery chart via the API previously and while I do Install Netdata, this means of battery monitoring was not great. ACPI provides more data including a status value.
First step, install acpi and a parser called jc that I have used in the past to take the acpi data and transform it into a JSON output. You also need the mosquitto-clients for publishing the data. These are installed via apt-get install acpi jc mosquitto-clients. Test it.
1
2
3
4
5
6
7
8
9
10
# acpi -b | jc --acpi -r -p
[
{
"type":"Battery",
"id":"0",
"state":"Charging",
"charge_percent":"98",
"until_charged":"00:08:02"
}
]
Now for the easy part and although I knew how, I used Co-Pilot to generate the script and the systemd unit to run it.
Shell script
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
# Get the hostname
HOSTNAME=$(hostname)
# MQTT Broker details
MQTT_BROKER="broker.address"
MQTT_PORT=1883
MQTT_TOPIC="$HOSTNAME/acpi/data"
# MQTT Authentication
MQTT_USER="user"
MQTT_PASSWORD="password"
# Sleep time between data transmissions (in seconds)
SLEEP_TIME=30
while true;do
# Originally done as separate lines, but on a newer system, it didn't like it so all done in one now
# Read ACPI data
# ACPI_DATA=$(acpi -b| jc --acpi -r)
# Read ACPI data and replace word 'state' with 'mode'
# ACPI_DATA=$(acpi -b| jc --acpi -r | sed 's/"state"/"mode"/g')
Save this script to /usr/local/bin/acpi_mqtt_data.sh
Create a systemd Unit in /usr/lib/systemd/system as acpi-mqtt.service. If you put the various Environment values in, you do not need them in the Shell script.
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit]
Description=ACPI Data MQTT Publisher
After=network.target
[Service]
ExecStart=/usr/local/bin/acpi_mqtt_data.sh
Restart=always
User=your_user
Group=your_group
Environment="MQTT_BROKER=mqtt.example.com"
Environment="MQTT_PORT=1883"
Environment="MQTT_TOPIC=$(hostname)/acpi/data"
Environment="MQTT_USER=your_username"
Environment="MQTT_PASSWORD=your_password"
Environment="SLEEP_TIME=30"
[Install]
WantedBy=multi-user.target
Save the file then
1
systemctl reload
Reload the daemon, enable the unit (so it auto starts at boot) and start it.
Adding this information into a Sensor in HomeAssistant, plugging in a Smart Switch and creating the automation to cycle the battery will be just as easy.
Job done.
[edit]
If only. The HA part turned out to be a bit of a PITA. The MQTT sensor refused to process the key named state. Modified the script above to change that key to mode.
1
2
3
4
5
6
7
sensor:
-name:"pve_battery"
state_topic:"pve/acpi/data"
value_template:"{{ value_json[0].charge_percent }}"# Using charge_percent as the state
DietPi is just a great distribution. If you haven’t tried it, do.
There is a function within the system called
dietpi-drivemanager and it does what it says on the tin, manages drives. For me I wanted to move the
rootfs to an SSD. Easily done with DietPi.
Once I had done that, I wanted to reclaim the 16GB SD Card for other things and reuse an old 2GB card. This turned out to be quite easy as well.
From the top – I inserted the smaller SDCard into a USB adapter and plugged it into the Pi.
The smaller card shows up as
sdb with
lsblk command. First, format the smaller card and create a new partition (taken from this item).
1
2
3
4
5
6
7
8
9
10
11
12
13
root@DietPi:~# fdisk /dev/sdb
Command(mfor help):n
Partition type
pprimary(1primary,0extended,3free)
eextended(container for logical partitions)
Select(defaultp):p
Partition number(1,3,4,default1):1
First sector(2048-15407103,default2048):8192
Last sector,+sectorsor+size{K,M,G,T,P}(8192-122879,default nnnnnnnn):122879
Createdanew partition1of type'Linux'and of size56MiB.
Command(mfor help):w
Remember the last command to actually make the changes.
Format the partition as fat
1
root@DietPi:~# mkfs.fat /dev/sda1
Once the filesystem is made you’re ready to copy – I used dd
1
root@DietPi:~# dd if=/dev/mmcblk0p1 of=/dev/sdb1
Next, you need to edit the
/etc/fstab file.
You need to edit this line and insert the right PARTUUID for the new boot partition. Use the
blkid command to get the value. Remember, it will still be shown as the PARTUUID for
/dev/sdb1
1
PARTUUID=cb7b86f7-01/boot vfat noatime,lazytime01
I then un-mounted the /boot partition, removed the card and inserted the smaller card before rebooting.
As the boot partition is not mentioned in the cmdline.txt file, I did not find a need to edit it.
Bingo! I now have the boot on an otherwise redundant 2GB card and free up a 16GB card for other things. Reduce, reuse recycle.by
I have been using pywws to extract the weather station data from my Maplin WH1080 for 6 years now but have now suffered from the dreaded (in pywws circles) USB Lockup – basically the weather station stops talking to the Raspberry Pi.
Via a strange set of circumstances on the OpenEnergyMonitor community, I discovered the package rtl_433 and wondered if I could read the data directly from the sensors which were clearly still working as the base station continued to show updates.
The short answer was “Yes I can”.
First step was to identify a suitable USB DVB stick that uses the Realtek RTL2832U chip. I chose this one from Amazon.
While I waited the day for delivery (oh woe is me), I got to installing the rtl_433 package.
The rtl_433 GitHub page links you to a list of repositories. As I wanted to run it on a Raspberry Pi, I noted it was available in the ‘testing’ repository. Never having installed anything from a different repo this took me on a different track as explained here.
Once installed, and once the stick arrived (today), I simply plugged the stick in at typed
1
rtl_433-R32
That was it. My data appeared.
I did want it passed into MQTT so I ended up (having asked a stupid question and been pointed to the wiki) with;
I wanted to install the rtl_443 package onto my Raspberry Pi, running Buster edition of Raspbian, so I could read the data from my WH1080. The GitHub page pointed me to the Raspbian testing repository.
To install this package from testing, the first task was to edit
/etc/apt/sources.list and add the repository;
1
deb http://raspbian.raspberrypi.org/raspbian/ testing main
Then
sudo apt update . At this point I then just did
sudo apt-get install rtl-433 but I suggest you don’t if you don’t want everything updated from the testing repository (I didn’t).
Instead create file
/etc/apt/preferences and include;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Package:*
Pin:releasea=stable
Pin-Priority:700
Package:*
Pin:releaseo=Raspberry Pi Foundation,a=testing,n=buster,l=Raspberry Pi Foundation,c=main,b=armhf
Pin-Priority:675
Package:*
Pin:releasea=testing
Pin-Priority:650
Package:*
Pin:releasea=unstable
Pin-Priority:600
and
sudo apt update
This will put the raspbian testing repository as a lower priority than the main and standard repositories. You can check this by using
apt-cache policy to list the repositories.
Note, by default, Raspbian is picking up a Debian repository – no idea why, but it is a bit confusing if you do a
apt list--upgradable
All that is needed to install the package is a
sudo apt install rtl_433
The fact Microsoft is forcing Teams onto every computer is extremely annoying and it seems they have made it deliberately difficult to prevent it from auto starting.
I’ve found 3 different fixes;
From the main Windows interface,
Select the Start Windows logo Start button button, then select Settings Gear-shaped Settings icon > Apps > Startup. Select Off for Teams.
If you don’t see the Startup option in Settings, right-click the Start Windows logo Start button button, select Task Manager, then select the Startup tab. (If you don’t see the Startup tab, select More details.) Select the app you want to change, then select Enable to run it at startup or Disable so it doesn’t run.
The aim of this investigation was to find a way to deploy HTTPS certificates on my LAN. This might seem over the top, but a) Troy Hunt thinks it is a good idea and b) I was getting fed up of the ‘insecure’ messages.
After much fiddling and experimenting I have settled on this process.
Things to note:
You do not need any web server on the internet. You just need to be able to edit your domain DNS record.
Use a subdomain for each certificate/server – these do not need to actually exist on the DNS.
I’m not going to go into detail about things that are easily found with Google search.
Prerequisites
Domian – you need to have one available – I bought mine for $10 from Google Domains.
Host the DNS for the domain where you can edit the records – I was going to use Google Domains (hence the purchase) but ended up with the domain on CloudFlare DNS servers.
For me I am using Lighttpd so some of this is that server specific and my OS is DietPi.
Set Up DNS Access
Assuming you have got your CloudFlare account all setup, go to your profile page, scroll down and click on ‘View’ next to Global API Key. You will need it in the next step.
Install & Configure certbot
You may need
sudo for these commands if not on DietPi as root. Also remember that any scripts need to be made executable
chmod+x .
If like me you use DietPi, then
dietpi-software install92 else
apt-get install certbot . Then:
apt-get install python3-certbot-dns-cloudflare
Create a folder called
.secrets and create /edit a file called
cloudflare.ini . Include the following lines from setting up access to CloudFlare DNS above. Treat this like a password so
chmod600
1
2
dns_cloudflare_email=xyz@nowhere.com
dns_cloudflare_api_key=11111111111111111111111111
Now create a small script to generate the certificate (you will need to change the domain and the path to match your ini file) – you will only need this once (hopefully):
You can run this script, answer the questions and the certificate should be generated.
Note the
cat command in the script. certbot does not generate the right combined certificate for lighttpd so this needs to be done manually. That is a bit of a pain and requires a little more setting up to get renewal to work automatically.
Setting Up Renewal
To get a new combined certificate on renewal a small script is needed that will execute once the certificate has been renewed and deployed.
A modern install of certbot will install systemd timer for you so it should just renew. To check the timer
1
systemctl list-timers--all
Lighttpd Configuration
This is included for me more than anything, as it can easily be found, but this is the addition to the standard
/etc/lighttpd/lighttpd.conf file that I find works.
# This should be always true for insecure incomming connections:
$HTTP["host"]=~".*"{
# redirect to https, port 443:
url.redirect=(".*"=>"https://%0$0")
}
}
Restart lighttpd (and clear cache).
Setting up an internal FQDN
Outside the scope of this but, if you have PiHole installed simply add the domain and IP to the
/etc/hosts file on the PiHole, restart PiHole and you should be able to just type in the domain name and be directed to a secure https address.
Sharing things I have managed to do (usually so I don’t forget how I did them) plus a few thoughts thrown in for good measure. All about technology one way or another.