python-openhab-rest-client 0.1.0__tar.gz → 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. {python_openhab_rest_client-0.1.0/python_openhab_rest_client.egg-info → python_openhab_rest_client-0.1.1}/PKG-INFO +1 -1
  2. python_openhab_rest_client-0.1.1/openhab/Actions.py +100 -0
  3. python_openhab_rest_client-0.1.1/openhab/Addons.py +405 -0
  4. python_openhab_rest_client-0.1.1/openhab/Audio.py +152 -0
  5. python_openhab_rest_client-0.1.1/openhab/Auth.py +241 -0
  6. python_openhab_rest_client-0.1.1/openhab/ChannelTypes.py +129 -0
  7. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/openhab/Client.py +38 -6
  8. python_openhab_rest_client-0.1.1/openhab/ConfigDescriptions.py +94 -0
  9. python_openhab_rest_client-0.1.1/openhab/Discovery.py +69 -0
  10. python_openhab_rest_client-0.1.1/openhab/Events.py +791 -0
  11. python_openhab_rest_client-0.1.1/openhab/Iconsets.py +42 -0
  12. python_openhab_rest_client-0.1.1/openhab/Inbox.py +178 -0
  13. python_openhab_rest_client-0.1.1/openhab/Items.py +708 -0
  14. python_openhab_rest_client-0.1.1/openhab/Links.py +258 -0
  15. python_openhab_rest_client-0.1.1/openhab/Logging.py +138 -0
  16. python_openhab_rest_client-0.1.1/openhab/ModuleTypes.py +93 -0
  17. python_openhab_rest_client-0.1.1/openhab/Persistence.py +298 -0
  18. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/openhab/ProfileTypes.py +24 -2
  19. python_openhab_rest_client-0.1.1/openhab/Rules.py +615 -0
  20. python_openhab_rest_client-0.1.1/openhab/Services.py +219 -0
  21. python_openhab_rest_client-0.1.1/openhab/Sitemaps.py +279 -0
  22. python_openhab_rest_client-0.1.1/openhab/Systeminfo.py +74 -0
  23. python_openhab_rest_client-0.1.1/openhab/Tags.py +214 -0
  24. python_openhab_rest_client-0.1.1/openhab/Templates.py +83 -0
  25. python_openhab_rest_client-0.1.1/openhab/ThingTypes.py +89 -0
  26. python_openhab_rest_client-0.1.1/openhab/Things.py +512 -0
  27. python_openhab_rest_client-0.1.1/openhab/Transformations.py +177 -0
  28. python_openhab_rest_client-0.1.1/openhab/UI.py +208 -0
  29. python_openhab_rest_client-0.1.1/openhab/UUID.py +39 -0
  30. python_openhab_rest_client-0.1.1/openhab/Voice.py +396 -0
  31. python_openhab_rest_client-0.1.1/openhab/tests/Actions.py +42 -0
  32. python_openhab_rest_client-0.1.1/openhab/tests/Addons.py +111 -0
  33. python_openhab_rest_client-0.1.1/openhab/tests/Audio.py +50 -0
  34. python_openhab_rest_client-0.1.1/openhab/tests/Auth.py +71 -0
  35. python_openhab_rest_client-0.1.1/openhab/tests/ChannelEvents.py +30 -0
  36. python_openhab_rest_client-0.1.1/openhab/tests/ChannelTypes.py +42 -0
  37. python_openhab_rest_client-0.1.1/openhab/tests/ConfigDescriptions.py +32 -0
  38. python_openhab_rest_client-0.1.1/openhab/tests/Discovery.py +32 -0
  39. python_openhab_rest_client-0.1.1/openhab/tests/Events.py +49 -0
  40. python_openhab_rest_client-0.1.1/openhab/tests/Iconsets.py +20 -0
  41. python_openhab_rest_client-0.1.1/openhab/tests/Inbox.py +60 -0
  42. python_openhab_rest_client-0.1.1/openhab/tests/InboxEvents.py +37 -0
  43. python_openhab_rest_client-0.1.1/openhab/tests/ItemEvents.py +121 -0
  44. python_openhab_rest_client-0.1.1/openhab/tests/Items.py +150 -0
  45. python_openhab_rest_client-0.1.1/openhab/tests/LinkEvents.py +30 -0
  46. python_openhab_rest_client-0.1.1/openhab/tests/Links.py +74 -0
  47. python_openhab_rest_client-0.1.1/openhab/tests/Logging.py +47 -0
  48. python_openhab_rest_client-0.1.1/openhab/tests/ModuleTypes.py +30 -0
  49. python_openhab_rest_client-0.1.1/openhab/tests/Persistence.py +92 -0
  50. python_openhab_rest_client-0.1.1/openhab/tests/ProfileTypes.py +21 -0
  51. python_openhab_rest_client-0.1.1/openhab/tests/Rules.py +83 -0
  52. python_openhab_rest_client-0.1.1/openhab/tests/Services.py +72 -0
  53. python_openhab_rest_client-0.1.1/openhab/tests/Sitemaps.py +72 -0
  54. python_openhab_rest_client-0.1.1/openhab/tests/Systeminfo.py +33 -0
  55. python_openhab_rest_client-0.1.1/openhab/tests/Tags.py +62 -0
  56. python_openhab_rest_client-0.1.1/openhab/tests/Templates.py +34 -0
  57. python_openhab_rest_client-0.1.1/openhab/tests/ThingEvents.py +61 -0
  58. python_openhab_rest_client-0.1.1/openhab/tests/ThingTypes.py +35 -0
  59. python_openhab_rest_client-0.1.1/openhab/tests/Things.py +81 -0
  60. python_openhab_rest_client-0.1.1/openhab/tests/Transformations.py +62 -0
  61. python_openhab_rest_client-0.1.1/openhab/tests/UI.py +72 -0
  62. python_openhab_rest_client-0.1.1/openhab/tests/UUID.py +21 -0
  63. python_openhab_rest_client-0.1.1/openhab/tests/Voice.py +106 -0
  64. python_openhab_rest_client-0.1.1/openhab/tests/__init__.py +69 -0
  65. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1/python_openhab_rest_client.egg-info}/PKG-INFO +1 -1
  66. python_openhab_rest_client-0.1.1/python_openhab_rest_client.egg-info/SOURCES.txt +106 -0
  67. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/setup.py +1 -1
  68. python_openhab_rest_client-0.1.1/tests/Actions.py +39 -0
  69. python_openhab_rest_client-0.1.1/tests/Addons.py +35 -0
  70. python_openhab_rest_client-0.1.1/tests/Audio.py +18 -0
  71. python_openhab_rest_client-0.1.1/tests/Auth.py +32 -0
  72. python_openhab_rest_client-0.1.1/tests/ChannelEvents.py +16 -0
  73. python_openhab_rest_client-0.1.1/tests/ChannelTypes.py +23 -0
  74. python_openhab_rest_client-0.1.1/tests/ConfigDescriptions.py +20 -0
  75. python_openhab_rest_client-0.1.1/tests/Discovery.py +19 -0
  76. python_openhab_rest_client-0.1.1/tests/Events.py +22 -0
  77. python_openhab_rest_client-0.1.1/tests/Iconsets.py +18 -0
  78. python_openhab_rest_client-0.1.1/tests/Inbox.py +26 -0
  79. python_openhab_rest_client-0.1.1/tests/InboxEvents.py +19 -0
  80. python_openhab_rest_client-0.1.1/tests/ItemEvents.py +28 -0
  81. python_openhab_rest_client-0.1.1/tests/Items.py +46 -0
  82. python_openhab_rest_client-0.1.1/tests/LinkEvents.py +20 -0
  83. python_openhab_rest_client-0.1.1/tests/Links.py +25 -0
  84. python_openhab_rest_client-0.1.1/tests/Logging.py +23 -0
  85. python_openhab_rest_client-0.1.1/tests/ModuleTypes.py +20 -0
  86. python_openhab_rest_client-0.1.1/tests/Persistence.py +32 -0
  87. python_openhab_rest_client-0.1.1/tests/ProfileTypes.py +16 -0
  88. python_openhab_rest_client-0.1.1/tests/Rules.py +35 -0
  89. python_openhab_rest_client-0.1.1/tests/Services.py +30 -0
  90. python_openhab_rest_client-0.1.1/tests/Sitemaps.py +25 -0
  91. python_openhab_rest_client-0.1.1/tests/Systeminfo.py +17 -0
  92. python_openhab_rest_client-0.1.1/tests/Tags.py +33 -0
  93. python_openhab_rest_client-0.1.1/tests/Templates.py +20 -0
  94. python_openhab_rest_client-0.1.1/tests/ThingEvents.py +23 -0
  95. python_openhab_rest_client-0.1.1/tests/ThingTypes.py +20 -0
  96. python_openhab_rest_client-0.1.1/tests/Things.py +34 -0
  97. python_openhab_rest_client-0.1.1/tests/Transformations.py +30 -0
  98. python_openhab_rest_client-0.1.1/tests/UI.py +45 -0
  99. python_openhab_rest_client-0.1.1/tests/UUID.py +16 -0
  100. python_openhab_rest_client-0.1.1/tests/Voice.py +38 -0
  101. python_openhab_rest_client-0.1.0/openhab/Actions.py +0 -43
  102. python_openhab_rest_client-0.1.0/openhab/Addons.py +0 -163
  103. python_openhab_rest_client-0.1.0/openhab/Audio.py +0 -66
  104. python_openhab_rest_client-0.1.0/openhab/Auth.py +0 -105
  105. python_openhab_rest_client-0.1.0/openhab/ChannelTypes.py +0 -54
  106. python_openhab_rest_client-0.1.0/openhab/ConfigDescriptions.py +0 -44
  107. python_openhab_rest_client-0.1.0/openhab/Discovery.py +0 -28
  108. python_openhab_rest_client-0.1.0/openhab/Events.py +0 -302
  109. python_openhab_rest_client-0.1.0/openhab/Iconsets.py +0 -21
  110. python_openhab_rest_client-0.1.0/openhab/Inbox.py +0 -64
  111. python_openhab_rest_client-0.1.0/openhab/Items.py +0 -264
  112. python_openhab_rest_client-0.1.0/openhab/Links.py +0 -98
  113. python_openhab_rest_client-0.1.0/openhab/Logging.py +0 -55
  114. python_openhab_rest_client-0.1.0/openhab/ModuleTypes.py +0 -47
  115. python_openhab_rest_client-0.1.0/openhab/Persistence.py +0 -103
  116. python_openhab_rest_client-0.1.0/openhab/Rules.py +0 -206
  117. python_openhab_rest_client-0.1.0/openhab/Services.py +0 -78
  118. python_openhab_rest_client-0.1.0/openhab/Sitemaps.py +0 -88
  119. python_openhab_rest_client-0.1.0/openhab/Systeminfo.py +0 -34
  120. python_openhab_rest_client-0.1.0/openhab/Tags.py +0 -82
  121. python_openhab_rest_client-0.1.0/openhab/Templates.py +0 -38
  122. python_openhab_rest_client-0.1.0/openhab/ThingTypes.py +0 -42
  123. python_openhab_rest_client-0.1.0/openhab/Things.py +0 -199
  124. python_openhab_rest_client-0.1.0/openhab/Transformations.py +0 -58
  125. python_openhab_rest_client-0.1.0/openhab/UI.py +0 -75
  126. python_openhab_rest_client-0.1.0/openhab/UUID.py +0 -18
  127. python_openhab_rest_client-0.1.0/openhab/Voice.py +0 -147
  128. python_openhab_rest_client-0.1.0/python_openhab_rest_client.egg-info/SOURCES.txt +0 -73
  129. python_openhab_rest_client-0.1.0/tests/actions.py +0 -55
  130. python_openhab_rest_client-0.1.0/tests/addons.py +0 -96
  131. python_openhab_rest_client-0.1.0/tests/audio.py +0 -16
  132. python_openhab_rest_client-0.1.0/tests/auth.py +0 -45
  133. python_openhab_rest_client-0.1.0/tests/channel_events.py +0 -14
  134. python_openhab_rest_client-0.1.0/tests/channel_types.py +0 -29
  135. python_openhab_rest_client-0.1.0/tests/config_descriptions.py +0 -23
  136. python_openhab_rest_client-0.1.0/tests/discovery.py +0 -23
  137. python_openhab_rest_client-0.1.0/tests/events.py +0 -41
  138. python_openhab_rest_client-0.1.0/tests/iconsets.py +0 -19
  139. python_openhab_rest_client-0.1.0/tests/inbox.py +0 -53
  140. python_openhab_rest_client-0.1.0/tests/inbox_events.py +0 -15
  141. python_openhab_rest_client-0.1.0/tests/item_events.py +0 -38
  142. python_openhab_rest_client-0.1.0/tests/items.py +0 -120
  143. python_openhab_rest_client-0.1.0/tests/link_events.py +0 -14
  144. python_openhab_rest_client-0.1.0/tests/links.py +0 -74
  145. python_openhab_rest_client-0.1.0/tests/logging_test.py +0 -43
  146. python_openhab_rest_client-0.1.0/tests/module_types.py +0 -14
  147. python_openhab_rest_client-0.1.0/tests/persistence.py +0 -78
  148. python_openhab_rest_client-0.1.0/tests/profile_types.py +0 -13
  149. python_openhab_rest_client-0.1.0/tests/rules.py +0 -151
  150. python_openhab_rest_client-0.1.0/tests/services.py +0 -52
  151. python_openhab_rest_client-0.1.0/tests/sitemaps.py +0 -65
  152. python_openhab_rest_client-0.1.0/tests/systeminfo.py +0 -14
  153. python_openhab_rest_client-0.1.0/tests/tags.py +0 -53
  154. python_openhab_rest_client-0.1.0/tests/templates.py +0 -28
  155. python_openhab_rest_client-0.1.0/tests/test.py +0 -11
  156. python_openhab_rest_client-0.1.0/tests/thing_events.py +0 -17
  157. python_openhab_rest_client-0.1.0/tests/thing_types.py +0 -28
  158. python_openhab_rest_client-0.1.0/tests/things.py +0 -75
  159. python_openhab_rest_client-0.1.0/tests/transformations.py +0 -38
  160. python_openhab_rest_client-0.1.0/tests/ui.py +0 -70
  161. python_openhab_rest_client-0.1.0/tests/uuid.py +0 -18
  162. python_openhab_rest_client-0.1.0/tests/voice.py +0 -119
  163. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/LICENSE +0 -0
  164. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/README.md +0 -0
  165. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/openhab/__init__.py +0 -0
  166. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/python_openhab_rest_client.egg-info/dependency_links.txt +0 -0
  167. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/python_openhab_rest_client.egg-info/requires.txt +0 -0
  168. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/python_openhab_rest_client.egg-info/top_level.txt +0 -0
  169. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/setup.cfg +0 -0
  170. {python_openhab_rest_client-0.1.0 → python_openhab_rest_client-0.1.1}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-openhab-rest-client
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: A Python client for the openHAB REST API. This library enables easy interaction with the openHAB REST API to control smart home devices, retrieve status information, and process events.
5
5
  Home-page: https://github.com/Michdo93/python-openhab-rest-client
6
6
  Author: Michael Christian Dörflinger
@@ -0,0 +1,100 @@
1
+ from .Client import OpenHABClient
2
+ import json
3
+ import requests
4
+
5
+
6
+ class Actions:
7
+ def __init__(self, client: OpenHABClient):
8
+ """
9
+ Initializes the Actions class with an OpenHABClient object.
10
+
11
+ :param client: An instance of OpenHABClient that is used for REST-API communication.
12
+ """
13
+ self.client = client
14
+
15
+ def getAllActions(self, thingUID: str, language: str = None) -> list:
16
+ """
17
+ Get all available actions for provided thing UID.
18
+
19
+ :param thingUID: The UID of the thing for which actions are to be retrieved.
20
+ :param language: (Optional) Language setting for the Accept-Language header.
21
+
22
+ :return: A list of actions.
23
+ """
24
+ header = {"Content-Type": "application/json"}
25
+ if language:
26
+ header["Accept-Language"] = language
27
+
28
+ try:
29
+ response = self.client.get(f"/actions/{thingUID}", header=header)
30
+
31
+ if isinstance(response, dict) and "status" in response:
32
+ status_code = response["status"]
33
+ else:
34
+ return response
35
+
36
+ except requests.exceptions.HTTPError as err:
37
+ status_code = err.response.status_code
38
+ if status_code == 204:
39
+ return {"error": "No actions found."}
40
+ elif status_code == 404:
41
+ return {"error": f"Thing not found: {thingUID}"}
42
+ else:
43
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
44
+
45
+ except requests.exceptions.RequestException as err:
46
+ return {"error": f"Request error: {str(err)}"}
47
+
48
+ if status_code == 200:
49
+ return {"message": "OK"}
50
+ elif status_code == 204:
51
+ return {"error": "No actions found."}
52
+ elif status_code == 404:
53
+ return {"error": f"Thing not found: {thingUID}"}
54
+
55
+ return {"error": f"Unexpected response: {status_code}"}
56
+
57
+ def executeAction(self, thingUID: str, actionUID: str, actionInputs: dict, language: str = None) -> str:
58
+ """
59
+ Executes a thing action.
60
+
61
+ :param thingUID: The UID of the thing on which the action is to be executed.
62
+ :param actionUID: The UID of the action to be executed.
63
+ :param actionInputs: The inputs for the action as a dictionary.
64
+ :param language: (Optional) Language setting for the Accept-Language header.
65
+
66
+ :return: A response from the server.
67
+ """
68
+ header = {"Content-Type": "application/json"}
69
+ if language:
70
+ header["Accept-Language"] = language
71
+
72
+ try:
73
+ response = self.client.post(
74
+ f"/actions/{thingUID}/{actionUID}", header=header, data=json.dumps(actionInputs))
75
+
76
+ if isinstance(response, dict) and "status" in response:
77
+ status_code = response["status"]
78
+ else:
79
+ return response
80
+
81
+ except requests.exceptions.HTTPError as err:
82
+ status_code = err.response.status_code
83
+ if status_code == 404:
84
+ return {"error": "Action not found."}
85
+ elif status_code == 500:
86
+ return {"error": "Creation of action handler or execution failed."}
87
+ else:
88
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
89
+
90
+ except requests.exceptions.RequestException as err:
91
+ return {"error": f"Request error: {str(err)}"}
92
+
93
+ if status_code == 200:
94
+ return {"message": "OK"}
95
+ elif status_code == 404:
96
+ return {"error": "Action not found."}
97
+ elif status_code == 500:
98
+ return {"error": "Creation of action handler or execution failed."}
99
+
100
+ return {"error": f"Unexpected response: {status_code}"}
@@ -0,0 +1,405 @@
1
+ import json
2
+ from .Client import OpenHABClient
3
+ import urllib.parse
4
+ import requests
5
+
6
+
7
+ class Addons:
8
+ def __init__(self, client: OpenHABClient):
9
+ """
10
+ Initializes the Addons class with an OpenHABClient instance.
11
+
12
+ :param client: An instance of OpenHABClient used for REST API communication.
13
+ """
14
+ self.client = client
15
+
16
+ def getAddons(self, serviceID: str = None, language: str = None) -> dict:
17
+ """
18
+ Retrieves a list of all available add-ons.
19
+
20
+ :param serviceID: Optional service ID to filter the results.
21
+ :param language: Optional language preference for the response.
22
+
23
+ :return: A dictionary containing the add-ons data.
24
+ """
25
+ params = {"serviceId": serviceID} if serviceID else {}
26
+ header = {"Content-Type": "application/json"}
27
+ if language:
28
+ header["Accept-Language"] = language
29
+
30
+ try:
31
+ response = self.client.get("/addons", header=header, params=params)
32
+
33
+ if isinstance(response, dict) and "status" in response:
34
+ status_code = response["status"]
35
+ else:
36
+ return response
37
+
38
+ except requests.exceptions.HTTPError as err:
39
+ status_code = err.response.status_code
40
+ if status_code == 404:
41
+ return {"error": "Service not found."}
42
+ else:
43
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
44
+
45
+ except requests.exceptions.RequestException as err:
46
+ return {"error": f"Request error: {str(err)}"}
47
+
48
+ if status_code == 200:
49
+ return {"message": "OK"}
50
+ elif status_code == 404:
51
+ return {"error": "Service not found."}
52
+
53
+ return {"error": f"Unexpected response: {status_code}"}
54
+
55
+ def getAddon(self, addonID: str, serviceID: str = None, language: str = None) -> dict:
56
+ """
57
+ Retrieves details of a specific add-on by its ID.
58
+
59
+ :param addonID: The unique identifier of the add-on.
60
+ :param serviceID: Optional service ID to filter the results.
61
+ :param language: Optional language preference for the response.
62
+
63
+ :return: A dictionary containing details of the specified add-on.
64
+ """
65
+ params = {"serviceId": serviceID} if serviceID else {}
66
+ header = {"Content-Type": "application/json"}
67
+ if language:
68
+ header["Accept-Language"] = language
69
+
70
+ try:
71
+ response = self.client.get(
72
+ f"/addons/{addonID}", header=header, params=params)
73
+
74
+ if isinstance(response, dict) and "status" in response:
75
+ status_code = response["status"]
76
+ else:
77
+ return response
78
+
79
+ except requests.exceptions.HTTPError as err:
80
+ status_code = err.response.status_code
81
+ if status_code == 404:
82
+ return {"error": "Not found."}
83
+ else:
84
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
85
+
86
+ except requests.exceptions.RequestException as err:
87
+ return {"error": f"Request error: {str(err)}"}
88
+
89
+ if status_code == 200:
90
+ return {"message": "OK"}
91
+ elif status_code == 404:
92
+ return {"error": "Not found."}
93
+
94
+ return {"error": f"Unexpected response: {status_code}"}
95
+
96
+ def getAddonConfig(self, addonID: str, serviceID: str = None) -> dict:
97
+ """
98
+ Retrieves the configuration of a specific add-on.
99
+
100
+ :param addonID: The unique identifier of the add-on.
101
+ :param serviceID: Optional service ID to filter the results.
102
+
103
+ :return: A dictionary containing the configuration of the specified add-on.
104
+ """
105
+ params = {"serviceId": serviceID} if serviceID else {}
106
+
107
+ try:
108
+ response = self.client.get(
109
+ f"/addons/{addonID}/config", header={"Content-Type": "application/json"}, params=params)
110
+
111
+ if isinstance(response, dict) and "status" in response:
112
+ status_code = response["status"]
113
+ else:
114
+ return response
115
+
116
+ except requests.exceptions.HTTPError as err:
117
+ status_code = err.response.status_code
118
+ if status_code == 500:
119
+ return {"error": "Configuration can not be read due to internal error."}
120
+ elif status_code == 404:
121
+ return {"error": "Add-on does not exist."}
122
+ else:
123
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
124
+
125
+ except requests.exceptions.RequestException as err:
126
+ return {"error": f"Request error: {str(err)}"}
127
+
128
+ if status_code == 200:
129
+ return {"message": "OK"}
130
+ elif status_code == 404:
131
+ return {"error": "Add-on does not exist."}
132
+ elif status_code == 500:
133
+ return {"error": "Configuration can not be read due to internal error."}
134
+
135
+ return {"error": f"Unexpected response: {status_code}"}
136
+
137
+ def updateAddonConfig(self, addonID: str, configData: dict, serviceID: str = None) -> dict:
138
+ """
139
+ Updates the configuration of a specific add-on and returns the updated configuration.
140
+
141
+ :param addonID: The unique identifier of the add-on.
142
+ :param configData: A dictionary containing the new configuration settings.
143
+ :param serviceID: Optional service ID to specify the target service.
144
+
145
+ :return: A dictionary containing the updated configuration.
146
+ """
147
+ data = {
148
+ **configData} # Create a copy to avoid modifying the original dictionary
149
+ if serviceID:
150
+ data["serviceId"] = serviceID
151
+
152
+ try:
153
+ response = self.client.put(
154
+ f"/addons/{addonID}/config", header={"Content-Type": "application/json"}, data=json.dumps(data))
155
+
156
+ if isinstance(response, dict) and "status" in response:
157
+ status_code = response["status"]
158
+ else:
159
+ return response
160
+
161
+ except requests.exceptions.HTTPError as err:
162
+ status_code = err.response.status_code
163
+ if status_code == 500:
164
+ return {"error": "Configuration can not be updated due to internal error."}
165
+ elif status_code == 404:
166
+ return {"error": "Add-on does not exist."}
167
+ else:
168
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
169
+
170
+ except requests.exceptions.RequestException as err:
171
+ return {"error": f"Request error: {str(err)}"}
172
+
173
+ if status_code == 200:
174
+ return {"message": "OK"}
175
+ elif status_code == 404:
176
+ return {"error": "Add-on does not exist."}
177
+ elif status_code == 500:
178
+ return {"error": "Configuration can not be updated due to internal error."}
179
+
180
+ return {"error": f"Unexpected response: {status_code}"}
181
+
182
+ def installAddon(self, addonID: str, serviceID: str = None, language: str = None) -> dict:
183
+ """
184
+ Installs an add-on by its ID.
185
+
186
+ :param addonID: The unique identifier of the add-on.
187
+ :param serviceID: Optional service ID to specify the target service.
188
+ :param language: Optional language preference for the response.
189
+
190
+ :return: A dictionary containing the installation status.
191
+ """
192
+ data = {"serviceId": serviceID} if serviceID else {}
193
+ header = {"Content-Type": "application/json"}
194
+ if language:
195
+ header["Accept-Language"] = language
196
+
197
+ try:
198
+ response = self.client.post(
199
+ f"/addons/{addonID}/install", header=header, data=data)
200
+
201
+ if isinstance(response, dict) and "status" in response:
202
+ status_code = response["status"]
203
+ else:
204
+ return response
205
+
206
+ except requests.exceptions.HTTPError as err:
207
+ status_code = err.response.status_code
208
+ if status_code == 404:
209
+ return {"error": "Not found."}
210
+ else:
211
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
212
+
213
+ except requests.exceptions.RequestException as err:
214
+ return {"error": f"Request error: {str(err)}"}
215
+
216
+ if status_code == 200:
217
+ return {"message": "OK"}
218
+ elif status_code == 404:
219
+ return {"error": "Not found."}
220
+
221
+ return {"error": f"Unexpected response: {status_code}"}
222
+
223
+ def uninstallAddon(self, addonID: str, serviceID: str = None, language: str = None) -> dict:
224
+ """
225
+ Uninstalls an add-on by its ID.
226
+
227
+ :param addonID: The unique identifier of the add-on.
228
+ :param serviceID: Optional service ID to specify the target service.
229
+ :param language: Optional language preference for the response.
230
+
231
+ :return: A dictionary containing the uninstallation status.
232
+ """
233
+ data = {"serviceId": serviceID} if serviceID else {}
234
+ header = {"Content-Type": "application/json"}
235
+ if language:
236
+ header["Accept-Language"] = language
237
+
238
+ try:
239
+ response = self.client.post(
240
+ f"/addons/{addonID}/uninstall", header=header, data=data)
241
+
242
+ if isinstance(response, dict) and "status" in response:
243
+ status_code = response["status"]
244
+ else:
245
+ return response
246
+
247
+ except requests.exceptions.HTTPError as err:
248
+ status_code = err.response.status_code
249
+ if status_code == 404:
250
+ return {"error": "Not found."}
251
+ else:
252
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
253
+
254
+ except requests.exceptions.RequestException as err:
255
+ return {"error": f"Request error: {str(err)}"}
256
+
257
+ if status_code == 200:
258
+ return {"message": "OK"}
259
+ elif status_code == 404:
260
+ return {"error": "Not found."}
261
+
262
+ return {"error": f"Unexpected response: {status_code}"}
263
+
264
+ def getAddonServices(self, language: str = None) -> dict:
265
+ """
266
+ Retrieves a list of all available add-on services.
267
+
268
+ :param language: Optional language preference for the response.
269
+
270
+ :return: A dictionary containing the available add-on services.
271
+ """
272
+ header = {"Content-Type": "application/json"}
273
+ if language:
274
+ header["Accept-Language"] = language
275
+
276
+ try:
277
+ response = self.client.get(
278
+ "/addons/services", header=header, params=None)
279
+
280
+ if isinstance(response, dict) and "status" in response:
281
+ status_code = response["status"]
282
+ else:
283
+ return response
284
+
285
+ except requests.exceptions.HTTPError as err:
286
+ status_code = err.response.status_code
287
+ if status_code != 200:
288
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
289
+
290
+ except requests.exceptions.RequestException as err:
291
+ return {"error": f"Request error: {str(err)}"}
292
+
293
+ if status_code == 200:
294
+ return {"message": "OK"}
295
+
296
+ return {"error": f"Unexpected response: {status_code}"}
297
+
298
+ def getAddonSuggestions(self, language: str = None) -> dict:
299
+ """
300
+ Retrieves a list of suggested add-ons for installation.
301
+
302
+ :param language: Optional language preference for the response.
303
+
304
+ :return: A dictionary containing suggested add-ons.
305
+ """
306
+ header = {"Content-Type": "application/json"}
307
+ if language:
308
+ header["Accept-Language"] = language
309
+
310
+ try:
311
+ response = self.client.get(
312
+ "/addons/suggestions", header=header, params=None)
313
+
314
+ if isinstance(response, dict) and "status" in response:
315
+ status_code = response["status"]
316
+ else:
317
+ return response
318
+
319
+ except requests.exceptions.HTTPError as err:
320
+ status_code = err.response.status_code
321
+ if status_code != 200:
322
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
323
+
324
+ except requests.exceptions.RequestException as err:
325
+ return {"error": f"Request error: {str(err)}"}
326
+
327
+ if status_code == 200:
328
+ return {"message": "OK"}
329
+
330
+ return {"error": f"Unexpected response: {status_code}"}
331
+
332
+ def getAddonTypes(self, language: str = None) -> dict:
333
+ """
334
+ Retrieves a list of all available add-on types.
335
+
336
+ :param language: Optional language preference for the response.
337
+
338
+ :return: A dictionary containing available add-on types.
339
+ """
340
+ header = {"Content-Type": "application/json"}
341
+ if language:
342
+ header["Accept-Language"] = language
343
+
344
+ try:
345
+ response = self.client.get(
346
+ "/addons/types", header=header, params=None)
347
+
348
+ if isinstance(response, dict) and "status" in response:
349
+ status_code = response["status"]
350
+ else:
351
+ return response
352
+
353
+ except requests.exceptions.HTTPError as err:
354
+ status_code = err.response.status_code
355
+ if status_code == 404:
356
+ return {"error": "Service not found."}
357
+ else:
358
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
359
+
360
+ except requests.exceptions.RequestException as err:
361
+ return {"error": f"Request error: {str(err)}"}
362
+
363
+ if status_code == 200:
364
+ return {"message": "OK"}
365
+ elif status_code == 404:
366
+ return {"error": "Service not found."}
367
+
368
+ return {"error": f"Unexpected response: {status_code}"}
369
+
370
+ def installAddonFromUrl(self, url: str) -> dict:
371
+ """
372
+ Installs an add-on from a given URL.
373
+
374
+ :param url: The URL of the add-on to install.
375
+
376
+ :return: A dictionary containing the installation status.
377
+ """
378
+ encoded_url = urllib.parse.quote(url, safe='') # Encode the URL
379
+ endpoint = f"/addons/url/{encoded_url}/install"
380
+
381
+ try:
382
+ response = self.client.post(
383
+ endpoint, header={"Content-Type": "text/plain"}, data=None)
384
+
385
+ if isinstance(response, dict) and "status" in response:
386
+ status_code = response["status"]
387
+ else:
388
+ return response
389
+
390
+ except requests.exceptions.HTTPError as err:
391
+ status_code = err.response.status_code
392
+ if status_code == 400:
393
+ return {"error": "The given URL is malformed or not valid."}
394
+ else:
395
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
396
+
397
+ except requests.exceptions.RequestException as err:
398
+ return {"error": f"Request error: {str(err)}"}
399
+
400
+ if status_code == 200:
401
+ return {"message": "OK"}
402
+ elif status_code == 400:
403
+ return {"error": "The given URL is malformed or not valid."}
404
+
405
+ return {"error": f"Unexpected response: {status_code}"}
@@ -0,0 +1,152 @@
1
+ from .Client import OpenHABClient
2
+ import requests
3
+
4
+
5
+ class Audio:
6
+ def __init__(self, client: OpenHABClient):
7
+ """
8
+ Initializes the Audio class with an OpenHABClient object.
9
+
10
+ :param client: An instance of OpenHABClient used for REST API communication.
11
+ """
12
+ self.client = client
13
+
14
+ def getDefaultSink(self, language: str = None):
15
+ """
16
+ Retrieves the default sink if defined, or the first available sink.
17
+
18
+ :param language: (Optional) Language setting for the Accept-Language header.
19
+
20
+ :return: A dictionary containing information about the default sink.
21
+ """
22
+ header = {"Content-Type": "application/json"}
23
+ if language:
24
+ header["Accept-Language"] = language
25
+
26
+ try:
27
+ response = self.client.get("/audio/defaultsink", header=header)
28
+
29
+ if isinstance(response, dict) and "status" in response:
30
+ status_code = response["status"]
31
+ else:
32
+ return response
33
+
34
+ except requests.exceptions.HTTPError as err:
35
+ status_code = err.response.status_code
36
+ if status_code == 404:
37
+ return {"error": "Sink not found."}
38
+ else:
39
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
40
+
41
+ except requests.exceptions.RequestException as err:
42
+ return {"error": f"Request error: {str(err)}"}
43
+
44
+ if status_code == 200:
45
+ return {"message": "OK"}
46
+ elif status_code == 404:
47
+ return {"error": "Sink not found."}
48
+
49
+ return {"error": f"Unexpected response: {status_code}"}
50
+
51
+ def getDefaultSource(self, language: str = None):
52
+ """
53
+ Retrieves the default source if defined, or the first available source.
54
+
55
+ :param language: (Optional) Language setting for the Accept-Language header.
56
+
57
+ :return: A dictionary containing information about the default source.
58
+ """
59
+ header = {"Content-Type": "application/json"}
60
+ if language:
61
+ header["Accept-Language"] = language
62
+
63
+ try:
64
+ response = self.client.get("/audio/defaultsource", header=header)
65
+
66
+ if isinstance(response, dict) and "status" in response:
67
+ status_code = response["status"]
68
+ else:
69
+ return response
70
+
71
+ except requests.exceptions.HTTPError as err:
72
+ status_code = err.response.status_code
73
+ if status_code == 404:
74
+ return {"error": "Sink not found."}
75
+ else:
76
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
77
+
78
+ except requests.exceptions.RequestException as err:
79
+ return {"error": f"Request error: {str(err)}"}
80
+
81
+ if status_code == 200:
82
+ return {"message": "OK"}
83
+ elif status_code == 404:
84
+ return {"error": "Service not found."}
85
+
86
+ return {"error": f"Unexpected response: {status_code}"}
87
+
88
+ def getSinks(self, language: str = None):
89
+ """
90
+ Retrieves a list of all available sinks.
91
+
92
+ :param language: (Optional) Language setting for the Accept-Language header.
93
+
94
+ :return: A list of available sinks.
95
+ """
96
+ header = {"Content-Type": "application/json"}
97
+ if language:
98
+ header["Accept-Language"] = language
99
+
100
+ try:
101
+ response = self.client.get("/audio/sinks", header=header)
102
+
103
+ if isinstance(response, dict) and "status" in response:
104
+ status_code = response["status"]
105
+ else:
106
+ return response
107
+
108
+ except requests.exceptions.HTTPError as err:
109
+ status_code = err.response.status_code
110
+ if status_code != 200:
111
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
112
+
113
+ except requests.exceptions.RequestException as err:
114
+ return {"error": f"Request error: {str(err)}"}
115
+
116
+ if status_code == 200:
117
+ return {"message": "OK"}
118
+
119
+ return {"error": f"Unexpected response: {status_code}"}
120
+
121
+ def getSources(self, language: str = None):
122
+ """
123
+ Retrieves a list of all available sources.
124
+
125
+ :param language: (Optional) Language setting for the Accept-Language header.
126
+
127
+ :return: A list of available sources.
128
+ """
129
+ header = {"Content-Type": "application/json"}
130
+ if language:
131
+ header["Accept-Language"] = language
132
+
133
+ try:
134
+ response = self.client.get("/audio/sources", header=header)
135
+
136
+ if isinstance(response, dict) and "status" in response:
137
+ status_code = response["status"]
138
+ else:
139
+ return response
140
+
141
+ except requests.exceptions.HTTPError as err:
142
+ status_code = err.response.status_code
143
+ if status_code != 200:
144
+ return {"error": f"HTTP error {status_code}: {str(err)}"}
145
+
146
+ except requests.exceptions.RequestException as err:
147
+ return {"error": f"Request error: {str(err)}"}
148
+
149
+ if status_code == 200:
150
+ return {"message": "OK"}
151
+
152
+ return {"error": f"Unexpected response: {status_code}"}