it:jednodeskove-pocitace:raspberry-pi-5-domaci-server

Toto je starší verze dokumentu!


Raspberry Pi 5 - domácí server

Dokumentovaná sestava se skládá z těchto komponent:

Napájecí zdroj je kvůli UPS desce, protože UPS deska dokáže přes jack konektor 2,5×5,5 mm dodat až 20W. To je maximum, které půjde do UPS desky dodat a zároveň pokud nebudu připojovat další náročné periferie, tak tento výkon utáhne NVMe disky.

Standardně Raspberry Pi 5 bootuje z microSD karty, ale je možné nakonfigurovat systém tak, aby bootoval přímo z NVMe SSD připojeného přes PCIe. Návod vychází z článku https://wiki.geekworm.com/NVMe_SSD_boot_with_the_Raspberry_Pi_5. Tento postup zahrnuje několik kroků:

1. Flashování NVMe SSD pomocí Raspberry Pi Imager

Pro instalaci operačního systému na NVMe SSD můžete použít nástroj Raspberry Pi Imager na Windows nebo macOS. K tomu budete potřebovat USB → NVMe adaptér.

Postup:

  • Nainstalujte a spusťte Raspberry Pi Imager.
  • Připojte NVMe SSD k počítači pomocí USB → NVMe adaptéru.
  • Vyberte operační systém pro instalaci (např. Raspberry Pi OS).
  • Zvolte disk (NVMe SSD připojené přes adaptér).
  • Klikněte na Write a potvrďte zápis.
  • Po dokončení NEODPOJUJTE NVMe SSD, dokud neprovedete aktivaci PCIe. Tedy bod níže a jednoduchá editace config.txt na NVMe disku. Pak je možné z disku nabootovat a řešit už další kroky.

2. Aktivace PCIe konektoru

Ve výchozím nastavení je PCIe port deaktivovaný a je nutné jej povolit.

Otevřete konfigurační soubor:

sudo nano /boot/firmware/config.txt

Přidejte následující řádky na konec souboru:

# Povolení PCIe externího konektoru
dtparam=pciex1
 
# Alternativní zápis pro povolení NVMe portu
dtparam=nvme

Uložte změny a restartujte Raspberry Pi:

sudo reboot

3. Nastavení NVMe disku jako primárního bootovacího zařízení

Po povolení PCIe portu je třeba upravit pořadí bootování v bootloaderu.

Možnost 1: Použití raspi-config

Spusťte konfigurátor:

sudo raspi-config

Zvolte:

  • 6 Advanced Options → A4 Boot Order → B2 NVMe/USB Boot
  • Potvrďte volbu Yes a restartujte:
sudo reboot

Možnost 2: Ruční úprava bootovacího řetězce

Otevřete EEPROM konfiguraci:

sudo rpi-eeprom-config --edit

Najděte řádek `BOOT_ORDER` a upravte ho na:

BOOT_ORDER=0xf416

Uložte změny a restartujte Raspberry Pi.

UPS desku jsem kupoval ve verzi 2.5. Je důležité si uvědomit, že UPS X728 není určena k automatickému spuštění Raspberry Pi po obnovení napájení. Její hlavní funkcí je zajistit nepřerušený provoz během výpadku, dokud je baterie dostatečně nabitá.

Jakmile baterie klesne na kritickou úroveň, Raspberry Pi by mělo být řízeně vypnuto, aby se zabránilo náhlé ztrátě dat nebo poškození systému. UPS však Raspberry Pi znovu automaticky nenastartuje, i když je baterie plně nabitá.

Pokud po zapnutí tlačítka na UPS svítí červená LED dioda na Raspberry Pi, znamená to, že deska je pod napětím, ale Raspberry Pi se samo nespustilo. Skutečné spuštění a běh systému indikují jiné LED diody na Raspberry Pi.

  • Napájení:
    • přes USB-C: 5Vdc, 3A
    • přes DC jack: 5Vdc ±5%, ≥4A
  • UPS výstup : 5.1V ±5% Max 8A
  • UPS nabíjecí proud: 2,3-3,2A
  • Terminální napětí baterie : 4,24V
  • Limit nabití : 4,1V

Tento návod popisuje postup pro zprovoznění softwaru UPS X728 a jeho správné nastavení.

Aktivace I2C podpory

Nejprve zapněte podporu I2C pomocí `raspi-config`:

sudo raspi-config

Poté nainstalujte potřebné balíčky:

apt-get install i2c-tools
apt install python3-smbus

Ověření připojení přes I2C:

root@propasiv-server:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- 36 -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

#36 - adresa chipu pro měření úrovně nabití baterie #68 - adresa RTC chipu

Instalace X728 ovladačů a skriptů

Nainstalujte potřebné nástroje:

sudo apt install -y gpiod

Stáhněte ovladače:

git clone https://github.com/geekworm-com/x728-script

Nastavte práva pro skripty:

cd x728-script
chmod +x *.sh

Konfigurace tlačítka pro fyzické vypnutí

Přesuňte potřebné soubory na správná místa:

sudo cp -f ./xPWR.sh /usr/local/bin/
sudo cp -f x728-pwr.service /lib/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable x728-pwr
sudo systemctl start x728-pwr

Tento postup umožní, aby fyzické tlačítko na UPS desce X728 fungovalo takto:

  • Stisknutí po dobu 1-2 sekundrestart zařízení.
  • Stisknutí po dobu 3 sekundbezpečné vypnutí (safe shutdown).
  • Stisknutí po dobu 7-8 sekundnucené vypnutí (force shutdown).

Tento postup nedělá nic jiného – pouze definuje chování tlačítka.

Softwarové vypnutí UPS (bez použití Linuxového `shutdown`)

Pro správné softwarové vypnutí je nutné nastavit vlastní alias:

1. Připravte skript `xSoft.sh`:

sudo cp -f ./xSoft.sh /usr/local/bin/

2. Vytvořte alias `x728off`, který bude bezpečně vypínat UPS:

echo "alias x728off='sudo /usr/local/bin/xSoft.sh 0 '''26''' '" >> ~/.bashrc

3. Aktivujte změny v `.bashrc`:

source ~/.bashrc

4. Nyní můžete bezpečně vypnout UPS příkazem:

x728off

Pozor: Nepoužívejte klasický Linuxový příkaz `shutdown`, jinak se UPS nevypne správně a může zůstat zapnutá.

Test bezpečného vypnutí

Softwarové bezpečné vypnutí:

x728off

Nepoužívejte příkaz `shutdown` v Linuxu, jinak se X728 nevypne správně.

Hardwarové bezpečné vypnutí

Pomocí fyzického tlačítka na UPS lze ověřit bezpečné vypnutí:

  • 1-2 sekundy – restart zařízení.
  • 3 sekundy – bezpečné vypnutí, LED diody pomalu zhasnou.
  • 7-8 sekund – vynucené vypnutí, okamžité zhasnutí.

Tímto postupem zajistíte, že UPS X728 bude správně fungovat a umožní bezpečné vypnutí jak softwarově, tak fyzickým tlačítkem.

Přehled dostupných skriptů pro další práci s UPS

Každý skript demonstruje jinou funkcionalitu UPS X728:

  • x728-v2.x-bat.py – Čtení napětí baterie a jejího nabití.
  • x728-v2.x-pld.py – Detekce výpadku napájení z AC adaptéru.
  • x728-v2.x-asd.py – Automatické vypnutí při poklesu napětí baterie pod nastavenou hodnotu.
Problém s knihovnou RPi.GPIO a řešení pomocí libgpiod

Starší ukázkové skripty používají knihovnu RPi.GPIO, která není podporována v jádru Linuxu 6.6.x. Pokud spustíte skript jako:

sudo python3 sample/x728-v2.x-plsd.py

může se objevit chyba kvůli nesprávnému gpiochip číslu.

Doporučuje se přejít na knihovnu libgpiod, která je oficiálně doporučena a lépe podporována. UPS X728 poskytuje jediný oficiální skript využívající libgpiod:

sudo python3 sample/x728-v2.x-plsd-gpiod.py

U ostatních skriptů, které stále používají RPi.GPIO, je doporučeno přepsání na libgpiod nebo jejich převedení na shell skripty.

Skript jsem si tedy přizpůsobil pro libgpiod:

#!/usr/bin/env python
 
import struct
import smbus
import time
import gpiod
import logging
 
 
# Log interval
LOG_INTERVAL = 300  # seconds
last_power_state = None # Stores last power state
last_log_time = 0 # Stores last log timestamp
 
 
# Logging configuration
logging.basicConfig(filename='/var/log/x728-battery.log', level=logging.INFO, format='%(asctime)s - %(message)s')
 
 
# GPIO chip and line definitions
#chipname = "gpiochip0"  # Use "gpiochip4" for Raspberry Pi 4/3
chipname = "gpiochip4"  # Use "gpiochip4" for Raspberry Pi 5
out_line_offset = 26  # Corresponds to GPIO26
pld_line_offset = 6  # Power loss detection pin
buzzer_line_offset = 20  # Buzzer control pin
 
# I2C address for battery monitoring
I2C_ADDR = 0x36
 
# Initialize I2C bus
bus = smbus.SMBus(1)
 
# Open GPIO chip
chip = gpiod.Chip(chipname)
 
# Get the output lines
out_line = chip.get_line(out_line_offset)
out_line.request(consumer="battery_monitor", type=gpiod.LINE_REQ_DIR_OUT)
 
buzzer_line = chip.get_line(buzzer_line_offset)
buzzer_line.request(consumer="power_monitor", type=gpiod.LINE_REQ_DIR_OUT)
 
# Get the input line for power loss detection
pld_line = chip.get_line(pld_line_offset)
pld_line.request(consumer="power_monitor", type=gpiod.LINE_REQ_EV_BOTH_EDGES)
 
def readVoltage(bus):
    """Reads battery voltage from I2C bus."""
    address = I2C_ADDR
    read = bus.read_word_data(address, 2)
    swapped = struct.unpack("<H", struct.pack(">H", read))[0]
    voltage = swapped * 1.25 / 1000 / 16
    return voltage
 
def readCapacity(bus):
    """Reads battery capacity from I2C bus."""
    address = I2C_ADDR
    read = bus.read_word_data(address, 4)
    swapped = struct.unpack("<H", struct.pack(">H", read))[0]
    capacity = swapped / 256
    if capacity > 100:
        capacity = 100
    return capacity
 
def print_power_status():
    """Monitors power status and logs changes."""
    global last_power_state, last_log_time
    state = pld_line.get_value()
    current_time = time.time()
 
    if state == 1:
        print("Power Supply A/C Lost") # First detection of power loss
        if last_power_state != 1:
            logging.warning("Power Supply A/C Lost")
        elif current_time - last_log_time > LOG_INTERVAL: # Subsequent logging at intervals
            logging.warning("Power Supply A/C Lost")
            last_log_time = current_time
 
        # Activate buzzer to indicate power loss
        for _ in range(3):  # Buzzer alarm cycle
            buzzer_line.set_value(1)
            time.sleep(0.1)
            buzzer_line.set_value(0)
            time.sleep(0.1)
    else:
        print("AC Power OK")
        if last_power_state != 0: # First detection of power restoration
            logging.info("AC Power OK")
        elif current_time - last_log_time > LOG_INTERVAL: # Subsequent logging at intervals
            logging.info("AC Power OK")
            last_log_time = current_time
        buzzer_line.set_value(0)
 
    last_power_state = state
    return state
 
 
try:
    while True:
        print("******************")
        voltage = readVoltage(bus)
        capacity = readCapacity(bus)
        print(f"Voltage: {voltage:.2f}V")
        print(f"Battery: {capacity:.0f}%")
 
        # Log battery voltage and capacity at intervals
        if time.time() - last_log_time > LOG_INTERVAL:
            logging.info(f"Voltage: {voltage:.2f}V, Battery: {capacity:.0f}%")
            last_log_time = time.time()
 
        # Monitor power loss detection
        power_status = print_power_status()
 
        if capacity == 100:
            print("Battery FULL")
 
        if capacity < 20:
            print("Battery Low")
 
        # This condition ensures shutdown only if the battery is below 99% and the power is disconnected.
        # This means that if the power is connected, the server will not shut down.
        # Everyone should evaluate whether this is safe and adjust the condition if necessary.
        if voltage < 3.00 and power_status == 1:
            print("Battery LOW!!!")
            logging.critical("Battery LOW! Shutdown in 10 seconds")
            print("Shutdown in 10 seconds")
            time.sleep(10)
            out_line.set_value(1)
            time.sleep(3)
            out_line.set_value(0)
 
 
        time.sleep(2)
 
except KeyboardInterrupt:
    print("Exiting...")
finally:
    chip.close()

Automatické spuštění po restartu

Pro zajištění automatického spuštění skriptu po restartu použijeme systemd service, což je spolehlivý způsob, jak zajistit, že skript poběží na pozadí.

Vytvoření systemd služby

Otevřete terminál a vytvořte soubor pro službu:

sudo nano /etc/systemd/system/x728-battery.service

Do souboru vložte následující obsah a uložte:

[Unit]
Description=X728 Battery Monitor
After=multi-user.target
 
[Service]
Type=simple
ExecStart=/usr/bin/python3 /etc/local-scripts/x728-script/sample/x728-v2.x-asd-gpiod.py
Restart=always
User=root
StandardOutput=append:/var/log/x728-battery.log
StandardError=append:/var/log/x728-battery.log
 
[Install]
WantedBy=multi-user.target
Aktivace služby při startu

Načtěte systemd a povolte službu při startu:

sudo systemctl daemon-reload
sudo systemctl enable x728-battery.service
Okamžité spuštění služby

Pro okamžité spuštění služby spusťte:

sudo systemctl start x728-battery.service
Kontrola stavu služby

Pro ověření, zda služba běží správně, použijte:

sudo systemctl status x728-battery.service

Nastavení a čtení RTC času

Tento návod popisuje kompletní nastavení a použití RTC (Real Time Clock) na UPS X728. UPS využívá RTC modul pro udržení přesného času i po odpojení napájení. Tento postup byl testován na Raspberry Pi OS.

Povolení RTC modulu

1. Otevřete konfigurační soubor `/boot/config.txt` a přidejte na konec nebo pod sekci `[all]` tento řádek:

sudo nano /boot/config.txt

Přidejte:

dtoverlay=i2c-rtc,ds1307

Uložte změny stisknutím Ctrl+O, potvrďte Enter, a ukončete editor Ctrl+X.

2. Restartujte Raspberry Pi:

sudo reboot
Zakázání falešného hwclocku

Raspberry Pi OS obsahuje fake-hwclock, který simuluje RTC a může způsobovat problémy s reálným RTC modulem. Proto je nutné ho odstranit:

sudo apt-get -y remove fake-hwclock
sudo update-rc.d -f fake-hwclock remove
sudo systemctl disable fake-hwclock
Úprava udev pravidel

Pro správné fungování RTC je třeba upravit soubor `/lib/udev/hwclock-set` a zakomentovat řádky 7-12:

sudo nano /lib/udev/hwclock-set

Najděte následující část kódu:

#!/bin/sh
# Reset the System Clock to UTC if the hardware clock from which it
# was copied by the kernel was in localtime.

dev=$1

#if [ -e /run/systemd/system ] ; then
#    exit 0
#fi
#
#/sbin/hwclock --rtc=$dev --systz
#/sbin/hwclock --rtc=$dev --hctosys

Každý řádek označený `#` je zakomentován a nebude se vykonávat.

Uložte změny a ukončete editor.

Ověření a nastavení času

Po dokončení výše uvedených kroků restartujte Raspberry Pi:

sudo reboot

Po restartu můžete ověřit aktuální systémový čas:

date

Pokud je čas nesprávný, nastavte ho ručně:

date -s "5 MAR 2019 13:00:00"

Uložte nastavený čas do RTC:

sudo hwclock -w

Pro ověření času uloženého v RTC modulu použijte:

sudo hwclock -r

Poznámka: Ujistěte se, že jsou v UPS X728 vloženy baterie, aby se uložený čas zachoval i po vypnutí zařízení.

Po dokončení tohoto postupu bude při každém startu Raspberry Pi čas automaticky synchronizován z RTC modulu.

Možné problémy a jejich řešení

Tato sekce popisuje možné problémy při používání UPS X728 a jejich řešení. Informace čerpám z oficiální dokumentace výrobce: [Zdroj: Geekworm Wiki - X728 FAQ](https://wiki.geekworm.com/X728#FAQ)

Problém: Zobrazuje se hláška „This power supply is not capable of supplying 5A“ na Raspberry Pi 5

UPS X728/X729 má dostatečnou kapacitu pro napájení 5A, nicméně je potřeba provést následující nastavení:

Krok 1: Úprava konfigurace napájení (povinné)

Otevřete terminál v Raspberry Pi OS a spusťte příkaz:

sudo rpi-eeprom-config -e

Na konec souboru přidejte následující řádek:

PSU_MAX_CURRENT=5000

Uložte změny stisknutím Ctrl+O, potvrďte klávesou Enter, a ukončete editor stisknutím Ctrl+X.

Krok 2: Zvýšení proudového limitu USB (volitelné, pokud používáte USB zařízení s vyšší spotřebou)

Otevřete konfigurační soubor:

sudo nano /boot/firmware/config.txt

Přidejte tento řádek:

usb_max_current_enable=1

Uložte změny a zavřete editor stejným způsobem jako v předchozím kroku.

Restartujte Raspberry Pi, aby se změny projevily:

sudo reboot

Poznámka: Pokud používáte jiný operační systém (například Ubuntu), je nutné nejprve nahrát Raspberry Pi OS, provést výše uvedené úpravy a teprve poté znovu nahrát požadovaný operační systém.

Softwarové řízení nabíjení pomocí GPIO16

Od verze X728 v2.5 je možné softwarově řídit nabíjení baterie pomocí GPIO16. Tato funkce je určena pouze pro pokročilé uživatele, kteří mají zkušenosti s Linuxem. Pokud si nejste jisti, doporučuje se ponechat jumper „CHG Ctrl“ zkratovaný, což umožní automatické nabíjení při připojení napájecího adaptéru.

Možnosti nastavení „CHG Ctrl“ jumperu: - Jumper zkratovaný → Baterie se automaticky nabíjí, pokud je připojen napájecí adaptér. - Jumper otevřený → Nabíjení lze ovládat přes GPIO16:

  1. GPIO16 = HIGH → Nabíjení povoleno.
  2. GPIO16 = LOW → Nabíjení zakázáno.
Ovládání nabíjení pomocí GPIO16

Pro ruční ovládání nabíjení je nutné nejprve zjistit odpovídající GPIO pin:

GPIO=16
 
# Zjištění skutečného čísla GPIO pinu
GPIO=$(cat /sys/kernel/debug/gpio | grep "GPIO$GPIO" | awk -F'gpio-' '{print $2}' | awk -F' ' '{print $1}')
echo "$GPIO" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio$GPIO/direction

Povolení nabíjení:

echo "1" > /sys/class/gpio/gpio$GPIO/value

Zakázání nabíjení:

echo "0" > /sys/class/gpio/gpio$GPIO/value

Poznámka: Nakonec jsem tuto funkci nevyužil, ale uvádím ji pro kompletní dokumentaci, pokud by bylo v budoucnu potřeba řídit nabíjení softwarově.

  • it/jednodeskove-pocitace/raspberry-pi-5-domaci-server.1739619366.txt.gz
  • Poslední úprava: 2025/02/15 11:36
  • autor: Petr Nosek