Coverage for /home/pi/Software/model-railway-signalling/model_railway_signals/editor/objects/objects_gpio.py: 100%
47 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-04-08 18:20 +0100
« prev ^ index » next coverage.py v7.2.7, created at 2024-04-08 18:20 +0100
1#-------------------------------------------------------------------------------------------------------------
2# This module contains all the functions for managing the GPIO sensor library objects.
3#-------------------------------------------------------------------------------------------------------------
4#
5# External API functions / objects intended for use by other editor modules:
6# update_local_gpio_sensors(trigger,timeout,mappings) - Configure the local GPIO sensor mappings
7# mqtt_update_gpio_sensors(pub_sensors,sub_sensors) - configure GPIO sensor publish & subscribe
8#
9# Makes the following external API calls to other editor modules:
10# objects_common.signal - To get The Object_ID for a given Item_ID
11# objects_common.track_sensor - To get The Object_ID for a given Item_ID
12#
13# Accesses the following external editor objects directly:
14# objects_common.schematic_objects - the master dictionary of Schematic Objects
15# objects_common.signal_index - The Index of Signal Objects (for iterating)
16# objects_common.track_sensor_index - The Index of Track Sensor Objects (for iterating)
17#
18# Makes the following external API calls to library modules:
19# gpio_sensors.gpio_sensor_exists - find if a GPIO sensor of a given ID already exists
20# gpio_sensors.delete_all_local_gpio_sensors - Delete all GPIO sensors prior to re-creating
21# gpio_sensors.reset_mqtt_configuration - Clear down the GPIO sensor publish/subscribe configuration
22# gpio_sensors.set_gpio_sensors_to_publish_state - Configure GPIO sensors to publish triggered events
23# gpio_sensors.subscribe_to_remote_gpio_sensor - Subscribe to trigger events from remote track sensors
24# gpio_sensors.create_gpio_sensor - Create a local GPIO sensor object (GPIO port mapping)
25#
26#-------------------------------------------------------------------------------------------------------------
28from typing import Union
29from ...library import gpio_sensors
30from . import objects_common
32#-------------------------------------------------------------------------------------------------------------
33# Common internal function to find any existing references to GPIO sensor from signal and track sensor
34# configurations so these can be carried forward to the new configuration if the GPIO sensor still exists
35# following any update to the MQTT publish/subscribe configuration or the GPIO local port mappings
36#-------------------------------------------------------------------------------------------------------------
38def find_existing_callback_mapping(gpio_sensor_id:Union[int,str]):
39 signal_passed, signal_approach, sensor_passed = 0, 0, 0
40 # Iterate through the signals to find if the GPIO sensor has been mapped to an approach/passed event
41 for signal_id in objects_common.signal_index:
42 signal_object = objects_common.schematic_objects[objects_common.signal(signal_id)]
43 if signal_object["passedsensor"][1] == str(gpio_sensor_id):
44 signal_passed = int(signal_id)
45 break
46 if signal_object["approachsensor"][1] == str(gpio_sensor_id):
47 signal_approach = int(signal_id)
48 break
49 # Iterate through the track sensors to find if the GPIO sensor has been mapped to a passed event
50 for track_sensor_id in objects_common.track_sensor_index:
51 track_sensor_object = objects_common.schematic_objects[objects_common.track_sensor(track_sensor_id)]
52 if track_sensor_object["passedsensor"] == str(gpio_sensor_id):
53 sensor_passed = int(track_sensor_id)
54 break
55 return(signal_passed, signal_approach, sensor_passed)
57#-------------------------------------------------------------------------------------------------------------
58# Common internal function to delete all references to GPIO sensors that no longer exist (from signal and
59# track sensor configurations). Called following any update to the MQTT publish/subscribe configuration
60# and also called following any update to the GPIO local port mapping configuration
61#-------------------------------------------------------------------------------------------------------------
63def delete_references_to_sensors_that_no_longer_exist():
64 for signal_id in objects_common.signal_index:
65 object_id = objects_common.signal(signal_id)
66 if not gpio_sensors.gpio_sensor_exists(objects_common.schematic_objects[object_id]["passedsensor"][1]):
67 objects_common.schematic_objects[object_id]["passedsensor"][1] = ""
68 if not gpio_sensors.gpio_sensor_exists(objects_common.schematic_objects[object_id]["approachsensor"][1]):
69 objects_common.schematic_objects[object_id]["approachsensor"][1] = ""
70 for sensor_id in objects_common.track_sensor_index:
71 object_id = objects_common.track_sensor(sensor_id)
72 if not gpio_sensors.gpio_sensor_exists(objects_common.schematic_objects[object_id]["passedsensor"]):
73 objects_common.schematic_objects[object_id]["passedsensor"] = ""
74 return()
76#-------------------------------------------------------------------------------------------------------------
77# Function to delete and then re-create local GPIO sensor mappings (following a GPIO settings "Apply).
78# This function first deletes any existing local GPIO sensor mappings (remote sensors that have been
79# subscribed to are retained) and then creates each new mapping in turn (specified in the new 'mappings' list).
80# Any mapped callback events (mapped to signals or track sensor mappings) are retained if the GPIO Sensor ID
81# still 'exists'. All local GPIO Sensors that no longer exist are removed from the signal/track sensor config.
82#-------------------------------------------------------------------------------------------------------------
84def update_local_gpio_sensors(trigger:float, timeout:float, gpio_mappings:list):
85 # Delete all existing 'local' GPIO sensor objects first
86 gpio_sensors.delete_all_local_gpio_sensors()
87 # Iterate through the sensor mappings to create each (new) GPIO sensor object in turn
88 for mapping in gpio_mappings:
89 sensor_id, gpio_port = mapping[0], mapping[1]
90 # Find the existing event callback mapping (if there is one)
91 signal_passed, signal_approach, sensor_passed = find_existing_callback_mapping(sensor_id)
92 # Re-create all existing event mappings if the specified GPIO sensor exists in the new configuration
93 # If not, the GPIO sensor is created without any event mappings (these can be added later as required)
94 gpio_sensors.create_gpio_sensor(sensor_id, gpio_port, signal_passed=signal_passed, sensor_passed=sensor_passed,
95 signal_approach=signal_approach, trigger_period=trigger, sensor_timeout=timeout)
96 # Remove any references to GPIO sensors that no longer exist from the Signal/Track Sensor configurations
97 delete_references_to_sensors_that_no_longer_exist()
98 return()
100#-------------------------------------------------------------------------------------------------------------
101# Function to delete and then re-create the GPIO sensor pub/sub configuration (following a MQTT settings "Apply).
102# This function first deletes all existing GPIO sensor subscriptions and sets all local sensors not to publish.
103# Any local sensors that appear in the 'pub_sensors' list are configured to publish GPIO sensor triggered events
104# to the network. Subscriptions for any remote GPIO sensors hat appear in the 'sub_sensors' list are then created
105# Any mapped callback events (mapped to signals or track sensor mappings) are retained if the GPIO Sensor ID
106# still 'exists'. All local GPIO Sensors that no longer exist are removed from the signal/track sensor config.
107#-------------------------------------------------------------------------------------------------------------
109def mqtt_update_gpio_sensors(pub_sensors:list,sub_sensors:list):
110 # Delete all publish/subscribe configuration (prior to re-creating)
111 gpio_sensors.reset_mqtt_configuration()
112 # Publishing is easy - we just provide the list of GPIO Sensors to publish
113 gpio_sensors.set_gpio_sensors_to_publish_state(*pub_sensors)
114 # Iterate through the list of GPIO sensors to subscribe - to create each (new) subscription in turn
115 for remote_identifier in sub_sensors:
116 signal_passed, signal_approach, sensor_passed = find_existing_callback_mapping(remote_identifier)
117 # Re-create all existing event mappings if the specified GPIO sensor exists in the new configuration
118 # If not, the GPIO sensor is created without any event mappings (these can be added later as required)
119 gpio_sensors.subscribe_to_remote_gpio_sensor(remote_identifier, sensor_passed=sensor_passed,
120 signal_passed=signal_passed, signal_approach=signal_approach)
121 # Remove any references to GPIO sensors that no longer exist from the Signal/Track Sensor configurations
122 delete_references_to_sensors_that_no_longer_exist()
123 return()
125#########################################################################################################