Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ def auto_check_and_lock_door():
lockDoor()
if mqttObject:
try:
mqttObject.publish_status(f"{time.strftime('%Y-%m-%d %H:%M:%S')} Türe wurde automatisch verriegelt (Sperrzeit).")
# timestamp automatically prepended by publish_status
mqttObject.publish_status("Türe wurde automatisch verriegelt (Sperrzeit).")
except Exception as e:
logger.debug(f"MQTT-Publish fehlgeschlagen: {e}")

Expand All @@ -457,7 +458,7 @@ def auto_check_and_lock_door():
unlockDoor()
if mqttObject:
try:
mqttObject.publish_status(f"{time.strftime('%Y-%m-%d %H:%M:%S')} Türe wurde automatisch entriegelt (Sperrzeit vorbei).")
mqttObject.publish_status("Türe wurde automatisch entriegelt (Sperrzeit vorbei).")
except Exception as e:
logger.debug(f"MQTT-Publish fehlgeschlagen: {e}")

Expand Down
8 changes: 6 additions & 2 deletions mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import logging
import time
from datetime import datetime
from config import Config as config

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -109,8 +110,11 @@ def publish_status(message):
return False

if _client:
_client.publish(config.MQTT_TOPIC_MESSAGE, message)
logger.info(f"MQTT gesendet: {message}")
# prepend current date/time to every status message automatically
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
full_message = f"{ts} {message}"
_client.publish(config.MQTT_TOPIC_MESSAGE, full_message)
logger.info(f"MQTT gesendet: {full_message}")
return True
else:
logger.warning("MQTT-Client nicht verbunden, Nachricht nicht gesendet.")
Expand Down
22 changes: 15 additions & 7 deletions paketbox.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Paketbox control script
# Version 0.8.9
# Version 0.8.10
# import time
import sys
import logging
Expand Down Expand Up @@ -86,25 +86,31 @@ def pinChanged(pin, oldState, newState):
handler.Paket_Tuer_Zusteller_geoeffnet()
if mqttObject:
mqttObject.publish_paket_zusteller_event("ON")
mqttObject.publish_status("Paketbox wurde geöffnet.")
elif pin == 5:
logger.info(f"Briefkasten Zusteller geöffnet.")
if mqttObject:
mqttObject.publish_briefkasten_event("ON")
mqttObject.publish_status("Briefkasten wurde geöffnet.")
elif pin == 6:
logger.info(f"Briefkasten Türe zum Leeren geöffnet.")
if mqttObject:
mqttObject.publish_briefkasten_entleeren_event("ON")
mqttObject.publish_status("Briefkasten wurde geleert.")
elif pin == 7:
logger.info(f"Paketbox Türe zum Leeren geöffnet.")
if mqttObject:
mqttObject.publish_paketbox_entleeren_event("ON")
mqttObject.publish_status("Paketbox wurde geleert.")
handler.setLigthtPaketboxOn()
elif pin == 9:
logger.info(f"Tür Mültonne geöffnet.")
handler.lichtMueltonneOn()
elif pin == 10:
logger.info(f"Lichtschranke ist nicht mehr ausgelöst.")
handler.reset_light_barrier()
if mqttObject:
mqttObject.publish_status("Lichtschranke zurückgesetzt.")

elif oldState == 1 and newState == 0: # falling edge
if pin == 0:
Expand Down Expand Up @@ -138,16 +144,18 @@ def pinChanged(pin, oldState, newState):
if mqttObject:
mqttObject.publish_paketbox_entleeren_event("OFF")
handler.setLigthtPaketboxOff()
# handler.ResetErrorState()
# handler.ResetDoors()
elif pin == 8:
logger.info(f"Türöffner Taster 6 gedrückt.")
logger.info(f"Reset wird ausgelöst.")
handler.ResetErrorState()
handler.ResetDoors()
elif pin == 9:
logger.info(f"Tür Mültonne geschlossen.")
handler.lichtMueltonneOff()
elif pin == 10:
logger.info(f"Lichtschranke hat ausgelöst.")
handler.set_light_barrier_triggered(True)
if mqttObject:
mqttObject.publish_status("Lichtschranke ausgelöst.")

else:
logger.warning(f"pinChanged: oldState == newState keine Änderung erkannt.")
Expand All @@ -168,7 +176,7 @@ def main():
global mqttObject
mqttObject = mqtt
mqttObject.start_mqtt()
mqttObject.publish_status(f"{time.strftime('%Y-%m-%d %H:%M:%S')} Paketbox bereit.")
mqttObject.publish_status("Paketbox bereit.")
# Initialize door states based on current GPIO readings
statusOld = initialize_door_states()
statusNew = [0] * len(Config.INPUTS)
Expand All @@ -195,14 +203,14 @@ def main():
statusNew[i] = GPIO.input(pin)
if statusNew[i] != statusOld[i]:
pinChanged(i, statusOld[i], statusNew[i])
logger.info(f"GPIO {pin} changed: {statusOld[i]} -> {statusNew[i]}")
logger.debug(f"GPIO {pin} changed: {statusOld[i]} -> {statusNew[i]}")
statusOld[i] = statusNew[i]

# Monitor for error conditions
if ( not sendMqttErrorState and pbox_state.is_any_error()):
logger.warning(f"WARNUNG: System im Fehlerzustand! {pbox_state}")
if mqttObject:
mqttObject.publish_status(f"{time.strftime('%Y-%m-%d %H:%M:%S')} FEHLER Paketbox: {pbox_state}")
mqttObject.publish_status(f"FEHLER Paketbox: {pbox_state}")
sendMqttErrorState = True

except KeyboardInterrupt:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_paketbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,24 @@ def test_motor_failure_setOutputWithRuntime_fails(self, mock_timer, mock_setOutp
# Timer should not be started for endlagen_pruefung
mock_timer.assert_not_called()

def test_publish_status_adds_timestamp(self):
"""Verify that mqtt.publish_status prefixes messages with a date/time string."""
import mqtt
# ensure MQTT_AVAILABLE is True and client is mocked
mqtt.MQTT_AVAILABLE = True
mock_client = MagicMock()
mqtt._client = mock_client

result = mqtt.publish_status("Testnachricht")
self.assertTrue(result, "publish_status should return True when client present")
# ensure publish was called exactly once
mock_client.publish.assert_called_once()
topic, sent = mock_client.publish.call_args[0]
self.assertEqual(topic, mqtt.config.MQTT_TOPIC_MESSAGE)
# message should start with a timestamp like 'YYYY-MM-DD HH:MM:SS '
import re
self.assertRegex(sent, r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Testnachricht$")

@patch('handler.get_gpio')
@patch('handler.setOutputWithRuntime')
@patch('handler.threading.Timer')
Expand Down