-
Notifications
You must be signed in to change notification settings - Fork 44
Adding a retain flag supported by mqtt in the gateway and status topi… #237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -156,6 +156,67 @@ def initialize_sink(self, name): | |
| sink.cost = self.minimum_sink_cost | ||
|
|
||
|
|
||
| class SendGatewayStatusThread(Thread): | ||
| def __init__( | ||
| self, | ||
| period_s, | ||
| mqtt_wrapper, | ||
| gw_id, | ||
| ): | ||
| """ | ||
| Thread sending periodically Gateway Status to the MQTT broker. | ||
| Args: | ||
| period_s: the period to send the status | ||
| mqtt_wrapper: the mqtt wrapper to publish gateway status on | ||
| gw_id: the id of the gateway to be use for MQTT topic | ||
| """ | ||
| Thread.__init__(self) | ||
|
|
||
| # Daemonize thread to exit with full process | ||
| self.daemon = True | ||
|
|
||
| # How often to send status | ||
| self.period_s = period_s | ||
| self.mqtt_wrapper = mqtt_wrapper | ||
|
|
||
| self.gw_id = gw_id | ||
| self.running = False | ||
|
|
||
| def publish_status(self): | ||
| """ | ||
| Publish the gateway status in the MQTT Broker. | ||
| """ | ||
| event_online = wmm.StatusEvent(self.gw_id, wmm.GatewayState.ONLINE) | ||
| status_topic = TopicGenerator.make_status_topic(self.gw_id) | ||
| logging.info("Publishing periodic gateway status!") | ||
| self.mqtt_wrapper.publish(status_topic, event_online.payload, qos=1) | ||
|
|
||
| def is_connected(self): | ||
| """ | ||
| Check if the gateway is connected with the MQTT broker. | ||
| """ | ||
| return self.mqtt_wrapper.connected | ||
|
|
||
| def run(self): | ||
| """ | ||
| Main loop that send periodically the status of the gateway to the MQTT Broker. | ||
| """ | ||
| self.running = True | ||
|
|
||
| while self.running: | ||
| if self.is_connected(): | ||
| self.publish_status() | ||
|
|
||
| # Wait for period_s seconds | ||
| sleep(self.period_s) | ||
|
|
||
| def stop(self): | ||
| """ | ||
| Stop the periodical sending gateway status thread. | ||
| """ | ||
| self.running = False | ||
|
|
||
|
|
||
| class TransportService(BusClient): | ||
| """ | ||
| Implementation of gateway to backend protocol | ||
|
|
@@ -183,9 +244,12 @@ def __init__(self, settings, **kwargs): | |
| self.gw_model = settings.gateway_model | ||
| self.gw_version = settings.gateway_version | ||
|
|
||
| # Does broker support retain flag | ||
| self.retain_supported = not settings.mqtt_retain_flag_not_supported | ||
|
|
||
| self.whitened_ep_filter = settings.whitened_endpoints_filter | ||
|
|
||
| last_will_topic = TopicGenerator.make_status_topic(self.gw_id) | ||
| self.make_status_topic = TopicGenerator.make_status_topic(self.gw_id) | ||
| last_will_message = wmm.StatusEvent( | ||
| self.gw_id, wmm.GatewayState.OFFLINE | ||
| ).payload | ||
|
|
@@ -194,7 +258,7 @@ def __init__(self, settings, **kwargs): | |
| settings, | ||
| self._on_mqtt_wrapper_termination_cb, | ||
| self._on_connect, | ||
| last_will_topic, | ||
| self.make_status_topic, | ||
| last_will_message, | ||
| ) | ||
|
|
||
|
|
@@ -227,6 +291,18 @@ def __init__(self, settings, **kwargs): | |
| else: | ||
| self.data_event_id = None | ||
|
|
||
| if not self.retain_supported: | ||
| logging.info("Gateway status is sent every %d seconds", settings.mqtt_send_gateway_status_period_s) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line too long (111 > 79 characters) |
||
|
|
||
| self.send_status_thread = SendGatewayStatusThread( | ||
| settings.mqtt_send_gateway_status_period_s, | ||
| self.mqtt_wrapper, | ||
| self.gw_id, | ||
| ) | ||
| self.send_status_thread.start() | ||
| else: | ||
| logging.info("Retain flag is supported by the gateway") | ||
|
|
||
| def _on_mqtt_wrapper_termination_cb(self): | ||
| """ | ||
| Callback used to be informed when the MQTT wrapper has exited | ||
|
|
@@ -239,9 +315,12 @@ def _on_mqtt_wrapper_termination_cb(self): | |
| def _set_status(self): | ||
| event_online = wmm.StatusEvent(self.gw_id, wmm.GatewayState.ONLINE) | ||
|
|
||
| topic = TopicGenerator.make_status_topic(self.gw_id) | ||
|
|
||
| self.mqtt_wrapper.publish(topic, event_online.payload, qos=1, retain=True) | ||
| self.mqtt_wrapper.publish( | ||
| self.make_status_topic, | ||
| event_online.payload, | ||
| qos=1, | ||
| retain=self.retain_supported | ||
| ) | ||
|
|
||
| def _on_connect(self): | ||
| # Register for get gateway info | ||
|
|
@@ -283,13 +362,17 @@ def _on_connect(self): | |
| topic, self._on_otap_set_target_scratchpad_request_received | ||
| ) | ||
|
|
||
| topic = TopicGenerator.make_get_gw_status_request_topic() | ||
| self.mqtt_wrapper.subscribe( | ||
| topic, self._on_get_gw_status_request_received | ||
| ) | ||
|
|
||
| # Register ourself to our status in case someone else (by mistake) | ||
| # update our status. | ||
| # It will work only if we are allowed to register for event topic | ||
| # at broker level | ||
| topic = TopicGenerator.make_status_topic(self.gw_id) | ||
| self.mqtt_wrapper.subscribe( | ||
| topic, self._on_own_status_received | ||
| self.make_status_topic, self._on_own_status_received | ||
| ) | ||
|
|
||
| self._set_status() | ||
|
|
@@ -746,6 +829,29 @@ def _on_otap_set_target_scratchpad_request_received( | |
|
|
||
| self.mqtt_wrapper.publish(topic, response.payload, qos=2) | ||
|
|
||
| @deferred_thread | ||
| def _on_get_gw_status_request_received( | ||
| self, client, userdata, message | ||
| ): | ||
| # pylint: disable=unused-argument | ||
| res = wmm.GatewayResultCode.GW_RES_OK | ||
| logging.info("Get gateway status request received") | ||
| try: | ||
| request = wmm.GetGatewayStatusRequest.from_payload( | ||
| message.payload | ||
| ) | ||
| except wmm.GatewayAPIParsingException as e: | ||
| logging.error(str(e)) | ||
| return | ||
|
|
||
| response = wmm.GetGatewayStatusResponse( | ||
| request.req_id, self.gw_id, res, wmm.GatewayState.ONLINE | ||
| ) | ||
| topic = TopicGenerator.make_get_gw_status_response_topic( | ||
| self.gw_id | ||
| ) | ||
|
|
||
| self.mqtt_wrapper.publish(topic, response.payload, qos=1) | ||
|
|
||
| def parse_setting_list(list_setting): | ||
| """ This function parse ep list specified from setting file or cmd line | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -363,6 +363,31 @@ def add_mqtt(self): | |
| ), | ||
| ) | ||
|
|
||
| self.mqtt.add_argument( | ||
| "--mqtt_retain_flag_not_supported", | ||
| default=os.environ.get("WM_SERVICES_MQTT_RETAIN_FLAG_NOT_SUPPORTED", False), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line too long (88 > 79 characters) |
||
| type=self.str2bool, | ||
| nargs="?", | ||
| const=True, | ||
| help=( | ||
| "Set to true if broker support retain flag" | ||
| "Gateway is sending its status periodically only" | ||
| "if retain option is not supported" | ||
| "otherwise status is retained in the MQTT" | ||
| ), | ||
| ) | ||
|
|
||
| self.mqtt.add_argument( | ||
| "--mqtt_send_gateway_status_period_s", | ||
| default=os.environ.get("WM_SERVICES_MQTT_SEND_GATEWAY_STATUS_PERIOD_S", 20), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line too long (88 > 79 characters) |
||
| action="store", | ||
| type=self.str2int, | ||
| help=( | ||
| "Period in seconds of a gateway to send its status" | ||
| "to the backend if retain option is not supported" | ||
| ), | ||
| ) | ||
|
|
||
| def add_buffering_settings(self): | ||
| """ Parameters used to avoid black hole case """ | ||
| self.buffering.add_argument( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Black would make changes.
line too long (100 > 79 characters)