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

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#------------------------------------------------------------------------------------------------------------- 

27 

28from typing import Union 

29from ...library import gpio_sensors 

30from . import objects_common 

31 

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#------------------------------------------------------------------------------------------------------------- 

37 

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) 

56 

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#------------------------------------------------------------------------------------------------------------- 

62 

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() 

75 

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#------------------------------------------------------------------------------------------------------------- 

83 

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() 

99 

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#------------------------------------------------------------------------------------------------------------- 

108 

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() 

124 

125#########################################################################################################