Serialshutdown.py und rc.local funktioniert nicht korrekt

588 views
0 Comments

Hallo,
ich habe hier einen RPI3B+, Raspian-OS mit Strompi3 und Battery-Hat alles mit neuester FW.
Config:
————————————————————————————————————————————-
pi@raspberrypi:~ $ sudo -E python3 /home/pi/strompi/StromPi3_Status.py
———————————
StromPi-Status:
———————————
Time: 09:21:44
Date: Saturday 16.05.20
StromPi-Output: mUSB
StromPi-Mode: mUSB -> Battery
Raspberry Pi Shutdown: Enabled
Shutdown-Timer: 30 seconds
Powerfail Warning: Enabled
Serial-Less Mode: Disabled
Power Save Mode: Disabled
PowerOn-Button: Disabled
PowerOn-Button-Timer: 30 seconds
Battery-Level Shutdown: 25%
Powerfail-Counter: 19
PowerOff Mode: Disabled
———————————
Alarm-Configuration:
———————————
WakeUp-Alarm: Disabled
Alarm-Mode: Time-Alarm
Alarm-Time: 00:00
Alarm-Date: 01.11
WakeUp-Alarm: Monday
Weekend Wakeup: Disabled
Minute Wakeup Timer: 30 minutes
PowerOff-Alarm: Disabled
PowerOff-Alarm-Time: 00:00
Interval-Alarm: Disabled
Interval-On-Time: 00 minutes
Interval-Off-Time: 00 minutes
———————————
Voltage-Levels:
———————————
Wide-Range-Inputvoltage: not connected
LifePo4-Batteryvoltage: 3.493V [100%] [charging]
microUSB-Inputvoltage: 5.175V
Output-Voltage: 5.128V
pi@raspberrypi:~ $
————————————————————————————————————————————-
Software für Strompi3 habe ich installiert, im Minicom Serielle Kommunikation okay. Serialless wird nicht benötigt.
Und zur Sicherheit habe ich noch Battery Shutdown-Mode bei 25% enabled.
Ziel ist es einen RPI (pihole) zuverlässig runterzufahren, wenn die RPI-Stromversorgung über mUSB
ausgeschaltet wird und wenn die Stromversorgung wieder eingeschaltet wird den RPI wieder hochzufahren.
Das Skript serialShutdown.py habe ich wie folgt leicht modifiziert:
————————————————————————————————————————————-
#!/usr/bin/env python
import serial
import os
##############################################################################
#Hier muss der wait_for_shutdowntimer eingestellt werden – dieser wartet mit dem Herunterfahren des Raspberry Pi,
# fuer den Fall dass die primaere Stromquelle wiederhergesttelt werden sollte
# Dieser Timer muss kleiner sein, als der im StromPi3 eingestellte shutdown-timer, damit sicher heruntergefahren wird.
#Here you have to set the wait_for_shutdowntimer in seconds – it waits with the shutdown of the Raspberry pi,
# in the case the primary voltage source turns back on.
# This timer have to be set lower than the configured shutdown-timer in the StromPi3 to make a safe shutdown.
##############################################################################
wait_for_shutdowntimer = 20;
##############################################################################
t=0 #Temporary time-variable
ser = serial.Serial(
port=’/dev/serial0′,
baudrate = 38400,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
counter=0
while 1:
x=ser.readline()
y = x.decode(encoding=’UTF-8′,errors=’strict‘)
if y==(‚xxxShutdownRaspberryPixxx\n‘):
print („PowerFail – Raspberry Pi Shutdown in 20 Seconds“)
t= wait_for_shutdowntimer + 1
elif y==(‚xxx–StromPiPowerBack–xxx\n‘):
print („PowerBack – Raspberry Pi Shutdown aborted“)
t=0
if t>0:
t-=1
if t == 1:
os.system(„sudo shutdown -h +1 PiHole Powerfail. Shutdown in 1 Minute“)

Es soll eine Shutdown-Meldung für eine Minute an den SSH und -WENN MÖGLICH- ein Fenster am Desktop aufpoppen. (Was zur Zeit wohl nicht funktioniert, da das Skript in RC.Local offensichtlich keine Popp-Up Windows auf dem Desktop erzeugen kann.
Das Skript zum herunterfahren habe ich  in die /etc/rc.local eingefügt:
————————————————————————————————————————————-
!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will „exit 0“ on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
#_IP=$(hostname -I) || true
#if [ „$_IP“ ]; then
# printf „My IP address is %s\n“ „$_IP“
#fi
#Dieses Skript fährt den Raspberry Pi herunter, wenn die primäre
#Spannungsversorgung ausfällt.
sudo -E python3 /home/pi/strompi/serialShutdown1.py &
exit 0
————————————————————————————————————————————-
nach dem Neustart zeigt /var/syslog folgende Meldung:
————————————————————————————————————————————-
May 16 08:52:26 raspberrypi dbus-daemon[594]: [session uid=1000 pid=594] Successfully activated service ‚ca.desrt.dconf‘
May 16 08:54:01 raspberrypi kernel: [ 197.197143] Under-voltage detected! (0x00050005)
May 16 08:54:05 raspberrypi kernel: [ 201.357195] Voltage normalised (0x00000000)
May 16 08:54:48 raspberrypi rc.local[394]: Traceback (most recent call last):
May 16 08:54:48 raspberrypi rc.local[394]: File „/usr/lib/python3/dist-packages/serial/serialposix.py“, line 501, in read
May 16 08:54:48 raspberrypi rc.local[394]: ‚device reports readiness to read but returned no data ‚
May 16 08:54:48 raspberrypi rc.local[394]: serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
May 16 08:54:48 raspberrypi rc.local[394]: During handling of the above exception, another exception occurred:
May 16 08:54:48 raspberrypi rc.local[394]: Traceback (most recent call last):
May 16 08:54:48 raspberrypi rc.local[394]: File „/home/pi/strompi/serialShutdown1.py“, line 30, in <module>
May 16 08:54:48 raspberrypi rc.local[394]: x=ser.readline()
May 16 08:54:48 raspberrypi rc.local[394]: File „/usr/lib/python3/dist-packages/serial/serialposix.py“, line 509, in read
May 16 08:54:48 raspberrypi rc.local[394]: raise SerialException(‚read failed: {}‘.format(e))
May 16 08:54:48 raspberrypi rc.local[394]: serial.serialutil.SerialException: read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
May 16 08:55:03 raspberrypi kernel: [ 259.597269] Under-voltage detected! (0x00050005)
May 16 08:55:09 raspberrypi kernel: [ 265.837302] Voltage normalised (0x00000000)
May 16 08:55:11 raspberrypi kernel: [ 267.917371] Under-voltage detected! (0x00050005)
May 16 08:55:18 raspberrypi kernel: [ 274.157440] Voltage normalised (0x00000000)
————————————————————————————————————————————-
…und das skript scheint nicht zu funktionieren, zumindest bekomme ich keine Meldung, das System scheint aber irgendwie runterzufahren. Grundsätzlich bekomme ich beim Shutdown unter Raspian -wie bei meinen anderen Kubuntu-Systemen- trotz ausgeschaltetem SPLAH beim boot keine System-Meldungen beim runterfahren. Beim booten schon.
Was mir noch aufgefallen ist das Problem das strompi_config_gui.py aufzurufen, daß
in /home/pi/strompi liegt.
————————————————————————————————————————————-
pi@raspberrypi:~ $ ls
Desktop Downloads Music Public strompistatus.sh Templates
Documents MagPi Pictures strompi temp Videos
pi@raspberrypi:~ $ sudo -E python3 strompi/strompi_config_gui.py
Traceback (most recent call last):
File „strompi/strompi_config_gui.py“, line 1234, in <module>
Logo1 = ImageTk.PhotoImage(Image.open(„logo.gif“))
File „/usr/lib/python3/dist-packages/PIL/Image.py“, line 2634, in open
fp = builtins.open(filename, „rb“)
FileNotFoundError: [Errno 2] No such file or directory: ‚logo.gif‘
pi@raspberrypi:~ $
————————————————————————————————————————————-
wechsle ich in das Verzeichnis ’strompi‘ direkt:
————————————————————————————————————————————-
pi@raspberrypi:~ $ cd strompi
pi@raspberrypi:~/strompi $ sudo -E python3 strompi_config_gui.py
————————————————————————————————————————————-
Funktioniert das strompi_config_gui einwandfrei.
Nochmal zu dem serialShutdown.py-skript (egal ob von mir modifiziert (serialShutdown1.py) oder
unmodifiziert, ausgeführt in der console:
————————————————————————————————————————————-
pi@raspberrypi:~ $ sudo -E python3 /home/pi/strompi/serialShutdown1.py
PowerFail – Raspberry Pi Shutdown in 20 Seconds
PowerBack – Raspberry Pi Shutdown aborted
PowerFail – Raspberry Pi Shutdown in 20 Seconds
Shutdown scheduled for Sat 2020-05-16 10:17:46 CEST, use ’shutdown -c‘ to cancel.
————————————————————————————————————————————-
Das skript reagiert auf das abziehen und stecken des mUSB aber erst nachdem ich das ein paar mal kommuniziert haben. Startet das System neu und hat die rc.local durchlaufen starte ich serialShutdown1.py auf der Konsole:
————————————————————————————————————————————-pi@raspberrypi:~ $ sudo -E python3 /home/pi/strompi/serialShutdown1.py
Traceback (most recent call last):
File „/usr/lib/python3/dist-packages/serial/serialposix.py“, line 501, in read
‚device reports readiness to read but returned no data ‚
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File „/home/pi/strompi/serialShutdown.py“, line 30, in <module>
x=ser.readline()
File „/usr/lib/python3/dist-packages/serial/serialposix.py“, line 509, in read
raise SerialException(‚read failed: {}‘.format(e))
serial.serialutil.SerialException: read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
pi@raspberrypi:~ $
————————————————————————————————————————————-
kann es sein, daß das serialShutdown1.py aus der rc.local trotz Fehlermeldung in der /var/syslog
läuft und die Kommunikation behindert?
Starte ich danach:
————————————————————————————————————————————-
pi@raspberrypi:~ $ sudo -E python3 /home/pi/strompi/RTCSerial.py
+—————————————–
The date und time has been synced: Raspberry Pi -> StromPi
—————————————–
————————————————————————————————————————————-
funktioniert serialShutdown1.py einwandfrei.
————————————————————————————————————————————-pi@raspberrypi:~ $ sudo -E python3 /home/pi/strompi/serialShutdown1.py
PowerFail – Raspberry Pi Shutdown in 20 Seconds
PowerBack – Raspberry Pi Shutdown aborted

system startet => mUSB fail => 20 sec. für mUSB reconnect =====
===NO=> Shutdown mit 1min. Wartezeit und Systemweite Meldung
Wie komme ich in RASPIAN an eine detailierte Anzeige der Shutdown-Meldungen am Bildschirm? (ich weis, daß ist nicht euer Bier und es könnte sein, daß es mit der Bildschirm-Meldung daran liegt, daß ich VNC benutze.
Vielen Dank für euere Geduld und die Unterstützung.
Gruß aus Stuttgart
Overkill

Answered question

3 Answers

Dirk (anonymous) 0 Comments

@Overkill auch dein Script ist Fehlerhaft. Die Variable wait_for_shutdowntimer wird nur Benutzt um die Anzahl der Schleifendurchläufe anzugeben. Er fehlt noch eine Kleinigkeit: direkt vor oder nach t-=1 muss ein time.sleep(1) eingefügt werden, dann wartet er auch eine Sekunde. Wobei am Anfang des Scriptes auch time importiert werden muss.

Sollte die Variable z.B auf 600 stehen und der Strom fällt 120 Sekunden aus fährt er nach ca 10 Sekunden Herunter, was ja nicht gewünscht ist, mit meiner änderung

Answered question

Guten Tag Overkill,
danke, dass du deine Arbeit hier teilst. Ich wünsche ein angenehmes Wochenende.
Mit freundlichen Grüßen
Nils (Joy-IT)

Answered question
Overkill (anonymous) 0 Comments

Hallo,
das Problem mit der /serialShutdown1.py ist gelöst. Es gab hier immer die Meldung, daß die SERIAL bereits ‚in Use‘ wäre obwohl das Skript als einziges in der rc.local stand.
Beim Vergleich mit dem Skript ‚RTCSerial.py‘ zeigt, daß dort mit
if serial_port.isOpen(): serial_port.close()
serial_port.open()
die serielle Schnittstelle RPI<=>Strompi definiert geschlossen und dann  wieder geöffnet wird. Dies fehlt bei serialshutdown1.py, ich habe nun
ein neues Skript ‚powerfail1.py‘ generiert und die Skripte serialshutdown1.py und RTCSerial.py zusammengefügt und für euch -so gut ich das als   alter Basic-Programmierer ohne jede Ahnung von Python auf die Schnelle hinbekommen habe:
————————————————————————————————————————————
#!/usr/bin/env python
# ########################################################################
# ########################## Time Sync RPI <=> Strompi #########################
# #############modified & commented by Overkill (DL4SKF) 17.05.2020 ###################
# ################### mail via ‚killerqueen(at)bossmail.de‘ ###########################
# ########################################################################
# Include Python library’s
import serial
import threading
from time import sleep
import time
import datetime
import os
# defining Serial-I/O RPI <=> Strompi
serial_port = serial.Serial()
serial_port.baudrate = 38400
serial_port.port = ‚/dev/serial0‘
serial_port.timeout = 1
serial_port.bytesize = 8
serial_port.stopbits = 1
serial_port.parity = serial.PARITY_NONE
# coordinating definied open/close Serial-I/O RPI <=> Strompi. Avoiding multiple access on Serial port
# serial-I/O will be closed after…
if serial_port.isOpen(): serial_port.close()
# Now open Serial-I/O
serial_port.open()
# Serial-I/O RPI <=> Strompi. Reading Values from both devices in Variables
try:
serial_port.write(str.encode(‚Q‘))
sleep(1)
serial_port.write(str.encode(‚\x0D‘))
sleep(1)
serial_port.write(str.encode(‚date-rpi‘))
sleep(0.1)
serial_port.write(str.encode(‚\x0D‘))
data = serial_port.read(9999);
date = int(data)
strompi_year = date // 10000
strompi_month = date % 10000 // 100
strompi_day = date % 100
sleep(0.1)
serial_port.write(str.encode(‚time-rpi‘))
sleep(0.1)
serial_port.write(str.encode(‚\x0D‘))
data = serial_port.read(9999);
timevalue = int(data)
strompi_hour = timevalue // 10000
strompi_min = timevalue % 10000 // 100
strompi_sec = timevalue % 100
rpi_time = datetime.datetime.now().replace(microsecond=0)
strompi_time = datetime.datetime(2000 + strompi_year, strompi_month, strompi_day, strompi_hour, strompi_min, strompi_sec, 0)
command = ’set-time %02d %02d %02d‘ % (int(rpi_time.strftime(‚%H‘)),int(rpi_time.strftime(‚%M‘)),int(rpi_time.strftime(‚%S‘)))
# syncing Time/date from RPI to Strompi
if rpi_time > strompi_time:
serial_port.write(str.encode(’set-date %02d %02d %02d %02d‘ % (int(rpi_time.strftime(‚%d‘)),int(rpi_time.strftime(‚%m‘)),int(rpi_time.strftime(‚%Y‘))%100,int(rpi_time.isoweekday()))))
sleep(0.5)
serial_port.write(str.encode(‚\x0D‘))
sleep(1)
serial_port.write(str.encode(’set-clock %02d %02d %02d‘ % (int(rpi_time.strftime(‚%H‘)),int(rpi_time.strftime(‚%M‘)),int(rpi_time.strftime(‚%S‘)))))
sleep(0.5)
serial_port.write(str.encode(‚\x0D‘))
print (‚———————————————————-‚)
print (‚The date und time has been synced: Raspberry Pi -> StromPi‘)
print (‚———————————————————-‚)
# syncing Time/date from Strompi to RPI
else:
os.system(’sudo date +%%y%%m%%d –set=%02d%02d%02d‘ % (strompi_year, strompi_month, strompi_day))
os.system(’sudo date +%%T -s „%02d:%02d:%02d“‚ % (strompi_hour, strompi_min, strompi_sec))
print (‚———————————————————-‚)
print (‚The date und time has been synced: StromPi -> Raspberry Pi‘)
print (‚———————————————————-‚)
# Keyboard-Interrupt to disable skript, not usefull now, dont know to hanle this for the moment I’ll dont modify this.
except KeyboardInterrupt:
print(‚interrupted!‘)
# closing serial-I/O
serial_port.close()
# ######################## End of Time Sync RPI <=> Strompi #######################
# ########################################################################
# ######################### Powerfail => execute shutdown ########################
# ########################################################################
print (‚**********************************************************‘)
print (‚*** starting POWERFAIL-Monitoring and Shutdown if true ***‘)
print (‚**********************************************************‘)
# defining Serial-I/O RPI <=> Strompi
serial_port = serial.Serial()
serial_port.baudrate = 38400
serial_port.port = ‚/dev/serial0′
serial_port.timeout = 1
serial_port.bytesize = 8
serial_port.stopbits = 1
serial_port.parity = serial.PARITY_NONE
# coordinating definied open/close Serial-I/O RPI <=> Strompi. Avoiding multiple access on Serial port
# serial-I/O will be closed after…
if serial_port.isOpen(): serial_port.close()
# Now open Serial-I/O
serial_port.open()
#Here you have to set the wait_for_shutdowntimer in seconds – it waits with the shutdown of the Raspberry pi,
# in the case the primary voltage source turns back on.
# This timer have to be set lower than the configured shutdown-timer in the StromPi3 to make a safe shutdown.
##############################################################################
wait_for_shutdowntimer = 20;
##############################################################################
t=0 #Temporary time-variable
# Reading Strompi Powerstatus in a Loop, defining Loop Counter
counter=0
while 1:
x=serial_port.readline()
y = x.decode(encoding=’UTF-8′,errors=’strict‘)
if y==(‚xxxShutdownRaspberryPixxx\n‘):
print („PowerFail – Raspberry Pi Shutdown in 20+60 Seconds“)
t= wait_for_shutdowntimer + 1
elif y==(‚xxx–StromPiPowerBack–xxx\n‘):
print („PowerBack – Raspberry Pi Shutdown aborted“)
t=0
if t>0:
t-=1
if t == 1:
# closing serial-I/O and shutting down RPI after ‚wait_for_shutdowntimer‘ has expired AND POWERFAIL is true
serial_port.close()
os.system(„sudo shutdown -h +1 DL4SKF PiHole Powerfail. Shutdown in 1 Minute“)
————————————————————————————————————————————
Dieses skript mit Endung ‚.py‘ im Home-Verzeichniss ablegen und mit ‚chmod +x [skriptname] in der console ausführbar machen.
Ihr könnt es als User in der Console wie folgt ausführen: (Mein skript heist: ‚powerfail1.py‘ und liegt in: /home/pi/strompi)
sudo -E python3 /home/pi/strompi/powerfail1.py
So könnt Ihr jetzt das Skript auch in der /etc/rc.local für den Autostart beim Systemstart ablegen. Duch das geziehlte öffnen/schließen in den Skripten dürfte das jetzt funktionieren. Eine Shutdown-Benachrichtigung wird auf der SSH-Konsole ausgegeben, nicht auf dem Desktop.
Wenn ich das gelöst habe, lass‘ ich es euch wissen.
Gruß Overkill

Answered question
Write your answer.