From 8d4db5e22c95f66baf72b88cd138ed8214ad9711 Mon Sep 17 00:00:00 2001 From: Ricardo Stoklosa Date: Tue, 18 Aug 2026 10:15:37 -0300 Subject: [PATCH] feat(services): add TagoTiP service for device commands Wrap POST /tip/cmd behind services.tagotip.cmd({serial, protocol, body}) using a Service Authorization token. --- docs/source/Services/TagoTiP_Type.rst | 19 ++++++++ docs/source/Services/index.rst | 27 +++++++++++ pyproject.toml | 2 +- src/tagoio_sdk/modules/Services/Services.py | 2 + src/tagoio_sdk/modules/Services/TagoTiP.py | 50 +++++++++++++++++++++ tests/Services/test_tagotip.py | 32 +++++++++++++ uv.lock | 2 +- 7 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 docs/source/Services/TagoTiP_Type.rst create mode 100644 src/tagoio_sdk/modules/Services/TagoTiP.py create mode 100644 tests/Services/test_tagotip.py diff --git a/docs/source/Services/TagoTiP_Type.rst b/docs/source/Services/TagoTiP_Type.rst new file mode 100644 index 0000000..48ec321 --- /dev/null +++ b/docs/source/Services/TagoTiP_Type.rst @@ -0,0 +1,19 @@ +**TagoTiP Type** +=================== + + +.. _TagoTiPCommand: + +TagoTiPCommand +-------------- + + **Attributes:** + + | **serial**: str + | Serial of the target device + + | **protocol**: str + | Protocol used to deliver the command + + | **body**: str + | Command payload sent to the device diff --git a/docs/source/Services/index.rst b/docs/source/Services/index.rst index 3e9bf2a..2020b46 100644 --- a/docs/source/Services/index.rst +++ b/docs/source/Services/index.rst @@ -197,6 +197,32 @@ Send SMS to phone number "message": "Test", } ) +======= +TagoTiP +======= + +Send a command to a device through TagoTiP + +Requires a Service Authorization token in the module token. + + **Parameters:** + + | **command**: :ref:`TagoTiPCommand` + | Command object with serial, protocol and body + +.. code-block:: + :caption: **Example:** + + from tagoio_sdk import Services + + services = Services({"token": "your-service-authorization-token"}) + services.tagotip.cmd( + { + "serial": "mqtt1", + "protocol": "mqtt", + "body": "reboot-now", + } + ) .. toctree:: @@ -207,6 +233,7 @@ Send SMS to phone number Notification_Type Pdf_Type SMS_Type + TagoTiP_Type diff --git a/pyproject.toml b/pyproject.toml index d7a8fe2..8048669 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "tagoio-sdk" -version = "5.1.4" +version = "5.1.5" description = "Official Python SDK for TagoIO" authors = [{name = "TagoIO Inc.", email = "contact@tago.io"}] license = {text = "Apache-2.0"} diff --git a/src/tagoio_sdk/modules/Services/Services.py b/src/tagoio_sdk/modules/Services/Services.py index 60109b9..6b8d53a 100644 --- a/src/tagoio_sdk/modules/Services/Services.py +++ b/src/tagoio_sdk/modules/Services/Services.py @@ -9,6 +9,7 @@ from tagoio_sdk.modules.Services.Notification import Notification from tagoio_sdk.modules.Services.PDF import PDFService from tagoio_sdk.modules.Services.SMS import SMS +from tagoio_sdk.modules.Services.TagoTiP import TagoTiP from tagoio_sdk.params import get_params @@ -23,3 +24,4 @@ def __init__(self, params: Optional[GenericModuleParams] = None): self.Notification = Notification(self.params) self.Attachment = Attachment(self.params) self.PDF = PDFService(self.params) + self.tagotip = TagoTiP(self.params) diff --git a/src/tagoio_sdk/modules/Services/TagoTiP.py b/src/tagoio_sdk/modules/Services/TagoTiP.py new file mode 100644 index 0000000..d4ae113 --- /dev/null +++ b/src/tagoio_sdk/modules/Services/TagoTiP.py @@ -0,0 +1,50 @@ +from typing import TypedDict + +from tagoio_sdk.common.tagoio_module import TagoIOModule + + +class TagoTiPCommand(TypedDict): + serial: str + """ + Serial of the target device + """ + protocol: str + """ + Protocol used to deliver the command + """ + body: str + """ + Command payload sent to the device + """ + + +class TagoTiP(TagoIOModule): + def cmd(self, command: TagoTiPCommand) -> str: + """ + Send a command to a device through TagoTiP. + + Requires a Service Authorization token in the module `token`. + + :param TagoTiPCommand command: Command object with serial, protocol and body + + Example: + >>> from tagoio_sdk import Services + >>> services = Services({"token": "your-service-authorization-token"}) + >>> services.tagotip.cmd({ + ... "serial": "mqtt1", + ... "protocol": "mqtt", + ... "body": "reboot-now", + ... }) + """ + result = self.doRequest( + { + "path": "/tip/cmd", + "method": "POST", + "body": { + "serial": command["serial"], + "protocol": command["protocol"], + "body": command["body"], + }, + } + ) + return result diff --git a/tests/Services/test_tagotip.py b/tests/Services/test_tagotip.py new file mode 100644 index 0000000..125c64f --- /dev/null +++ b/tests/Services/test_tagotip.py @@ -0,0 +1,32 @@ +import os + +from requests_mock.mocker import Mocker + +from tagoio_sdk.modules.Services.Services import Services + + +os.environ["T_ANALYSIS_TOKEN"] = "your_token_value" + + +def testTagoTiPCmd(requests_mock: Mocker) -> None: + """Test cmd method of TagoTiP service.""" + requests_mock.post( + "https://api.tago.io/tip/cmd", json={"status": True, "result": "ok"} + ) + + services = Services({"token": "your-service-authorization-token"}) + + result = services.tagotip.cmd( + { + "serial": "mqtt1", + "protocol": "mqtt", + "body": "reboot-now", + } + ) + + assert result == "ok" + assert requests_mock.last_request.json() == { + "serial": "mqtt1", + "protocol": "mqtt", + "body": "reboot-now", + } diff --git a/uv.lock b/uv.lock index 03ba6a4..ca1646c 100644 --- a/uv.lock +++ b/uv.lock @@ -421,7 +421,7 @@ wheels = [ [[package]] name = "tagoio-sdk" -version = "5.1.4" +version = "5.1.5" source = { editable = "." } dependencies = [ { name = "python-dateutil" },