From 48655d42367192fcaf826ffebe19524b8fc9f7f7 Mon Sep 17 00:00:00 2001 From: LePailleurThibault Date: Wed, 26 Oct 2022 17:24:55 +0200 Subject: [PATCH] Updating the protobuf messages to handle request on the gateway status Adding Gateways status request and response topics. This can be used in the case where the mqtt broker does not support retained message and we would like to know the status of the gateways as soon as possible. The concerned topics in the mqtt broker are : gw-request/get_gw_status gw-response/get_gw_status// --- tests/test_get_gw_status.py | 32 +++++++ wirepas_mesh_messaging/__init__.py | 1 + wirepas_mesh_messaging/get_gw_status.py | 122 ++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 tests/test_get_gw_status.py create mode 100644 wirepas_mesh_messaging/get_gw_status.py diff --git a/tests/test_get_gw_status.py b/tests/test_get_gw_status.py new file mode 100644 index 0000000..e0d5e35 --- /dev/null +++ b/tests/test_get_gw_status.py @@ -0,0 +1,32 @@ +# flake8: noqa + +import wirepas_mesh_messaging +from default_value import * +import time + + +def test_generate_parse_request(): + request = wirepas_mesh_messaging.GetGatewayStatusRequest(REQUEST_ID) + + request2 = wirepas_mesh_messaging.GetGatewayStatusRequest.from_payload( + request.payload + ) + + for k, v in request.__dict__.items(): + assert v == request2.__dict__[k] + + +def test_generate_parse_response(): + request = wirepas_mesh_messaging.GetGatewayStatusResponse( + REQUEST_ID, + GATEWAY_ID, + RES_OK, + GATEWAY_STATE, + ) + + request2 = wirepas_mesh_messaging.GetGatewayStatusResponse.from_payload( + request.payload + ) + + for k, v in request.__dict__.items(): + assert v == request2.__dict__[k] diff --git a/wirepas_mesh_messaging/__init__.py b/wirepas_mesh_messaging/__init__.py index b97898f..63ae933 100644 --- a/wirepas_mesh_messaging/__init__.py +++ b/wirepas_mesh_messaging/__init__.py @@ -21,6 +21,7 @@ from .get_configs import GetConfigsRequest, GetConfigsResponse from .get_gw_info import GetGatewayInfoRequest, GetGatewayInfoResponse +from .get_gw_status import GetGatewayStatusRequest, GetGatewayStatusResponse from .set_config import SetConfigRequest, SetConfigResponse from .received_data import ReceivedDataEvent from .status import StatusEvent, GatewayState diff --git a/wirepas_mesh_messaging/get_gw_status.py b/wirepas_mesh_messaging/get_gw_status.py new file mode 100644 index 0000000..88f5b7f --- /dev/null +++ b/wirepas_mesh_messaging/get_gw_status.py @@ -0,0 +1,122 @@ +""" + Get gateway status + ================ + + .. Copyright: + Copyright 2019 Wirepas Ltd under Apache License, Version 2.0. + See file LICENSE for full license details. +""" + +from .proto import GenericMessage, ON, OFF + +from .request import Request +from .response import Response +from .status import GatewayState, API_VERSION + +from .wirepas_exceptions import GatewayAPIParsingException + + +class GetGatewayStatusRequest(Request): + """ + GetGatewayStatusRequest: Request to obtain the gateway status + + Attributes: + req_id (int): unique request id + """ + + def __init__(self, req_id=None, **kwargs): + super(GetGatewayStatusRequest, self).__init__(req_id=req_id, **kwargs) + + @classmethod + def from_payload(cls, payload): + message = GenericMessage() + try: + message.ParseFromString(payload) + except Exception: + # Any Exception is promoted to Generic API exception + raise GatewayAPIParsingException( + "Cannot parse GetGatewayStatusRequest payload" + ) + + d = Request._parse_request_header(message.wirepas.get_gateway_status_req.header) + return cls(d["req_id"]) + + @property + def payload(self): + message = GenericMessage() + # Fill the request header + get_gateway_status = message.wirepas.get_gateway_status_req + self._load_request_header(get_gateway_status) + + return message.SerializeToString() + + +class GetGatewayStatusResponse(Response): + """ + GetGatewayStatusResponse: Response to answer a GetGatewayStatusRequest + + Attributes: + req_id (int): unique request id that this Response is associated + gw_id (str): gw_id (str): gateway unique identifier + res (GatewayResultCode): result of the operation + state (GatewayState): state of the gateway + version (int): API version for gateway. Should be always 1 + """ + + def __init__( + self, + req_id, + gw_id, + res, + state, + version=API_VERSION, + **kwargs + ): + super(GetGatewayStatusResponse, self).__init__(req_id, gw_id, res, **kwargs) + self.version = version + self.state = state + + @classmethod + def from_payload(cls, payload): + message = GenericMessage() + try: + message.ParseFromString(payload) + except Exception: + # Any Exception is promoted to Generic API exception + raise GatewayAPIParsingException( + "Cannot parse GetGatewayStatusResponse payload" + ) + + response = message.wirepas.get_gateway_status_resp + + if response.status.state == ON: + online = GatewayState.ONLINE + else: + online = GatewayState.OFFLINE + + if response.status.version != API_VERSION: + raise RuntimeError("Wrong API version") + + d = Response._parse_response_header(response.header) + + return cls( + d["req_id"], + d["gw_id"], + d["res"], + online, + ) + + @property + def payload(self): + message = GenericMessage() + + response = message.wirepas.get_gateway_status_resp + self._load_response_header(response) + + response.status.version = API_VERSION + if self.state == GatewayState.ONLINE: + response.status.state = ON + else: + response.status.state = OFF + + return message.SerializeToString()