edgeconductor 0.1.0__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.
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: edgeconductor
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for the EdgeConductor IoT Platform
5
+ Home-page: https://github.com/edgeconductor-creator/ec-platform
6
+ Author: EdgeConductor
7
+ Author-email: EdgeConductor <edgeconductor@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://edgeconductor.com
10
+ Project-URL: Repository, https://github.com/edgeconductor-creator/ec-platform
11
+ Project-URL: Documentation, https://edgeconductor.com/developers
12
+ Keywords: iot,mqtt,telemetry,device-management,edge-computing
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Topic :: System :: Hardware
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ Dynamic: author
20
+ Dynamic: home-page
21
+ Dynamic: requires-python
22
+
23
+ # edgeconductor
24
+
25
+ Official Python SDK for the [EdgeConductor IoT Platform](https://edgeconductor.com).
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install edgeconductor
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```python
36
+ from edgeconductor import Client
37
+
38
+ ec = Client(
39
+ api_key = "ec_live_xxxxxxxxxxxx", # from /org/settings → API Keys
40
+ base_url = "https://ec-registry.onrender.com",
41
+ )
42
+
43
+ # Register device
44
+ ec.devices.register(serial_no="MY-001", product_type="EC-CLIMATE-V1")
45
+
46
+ # Push telemetry
47
+ ec.telemetry.push("MY-001", temp=24.5, hum=60, co2=850, bat=4.05)
48
+
49
+ # Get current state
50
+ shadow = ec.devices.get_shadow("MY-001")
51
+ print(shadow) # {"temp": 24.5, "hum": 60, ...}
52
+
53
+ # Create automation rule
54
+ ec.rules.threshold(
55
+ org_id, name="CO₂ Alert",
56
+ field="co2", op=">", value=1000,
57
+ action={"key": "relay", "value": True},
58
+ )
59
+ ```
60
+
61
+ ## Links
62
+
63
+ - **Docs:** [edgeconductor.com/developers](https://edgeconductor.com/developers)
64
+ - **API Keys:** Login → /org/settings → API Keys
65
+ - **Support:** edgeconductor@gmail.com
@@ -0,0 +1,43 @@
1
+ # edgeconductor
2
+
3
+ Official Python SDK for the [EdgeConductor IoT Platform](https://edgeconductor.com).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install edgeconductor
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ from edgeconductor import Client
15
+
16
+ ec = Client(
17
+ api_key = "ec_live_xxxxxxxxxxxx", # from /org/settings → API Keys
18
+ base_url = "https://ec-registry.onrender.com",
19
+ )
20
+
21
+ # Register device
22
+ ec.devices.register(serial_no="MY-001", product_type="EC-CLIMATE-V1")
23
+
24
+ # Push telemetry
25
+ ec.telemetry.push("MY-001", temp=24.5, hum=60, co2=850, bat=4.05)
26
+
27
+ # Get current state
28
+ shadow = ec.devices.get_shadow("MY-001")
29
+ print(shadow) # {"temp": 24.5, "hum": 60, ...}
30
+
31
+ # Create automation rule
32
+ ec.rules.threshold(
33
+ org_id, name="CO₂ Alert",
34
+ field="co2", op=">", value=1000,
35
+ action={"key": "relay", "value": True},
36
+ )
37
+ ```
38
+
39
+ ## Links
40
+
41
+ - **Docs:** [edgeconductor.com/developers](https://edgeconductor.com/developers)
42
+ - **API Keys:** Login → /org/settings → API Keys
43
+ - **Support:** edgeconductor@gmail.com
@@ -0,0 +1,4 @@
1
+ from .client import Client, EdgeConductorError
2
+
3
+ __version__ = "0.1.0"
4
+ __all__ = ["Client", "EdgeConductorError"]
@@ -0,0 +1,197 @@
1
+ """
2
+ EdgeConductor Python SDK
3
+
4
+ Official Python SDK for the EdgeConductor IoT Platform.
5
+
6
+ Usage:
7
+ from edgeconductor import Client
8
+
9
+ ec = Client(api_key="ec_live_xxxx")
10
+
11
+ ec.devices.register(serial_no="MY-001", product_type="EC-CLIMATE-V1")
12
+ ec.telemetry.push("MY-001", temp=24.5, hum=60, co2=850)
13
+ shadow = ec.devices.get_shadow("MY-001")
14
+ """
15
+
16
+ import json
17
+ import urllib.request
18
+ import urllib.error
19
+ from typing import Optional, List, Dict, Any
20
+
21
+ DEFAULT_BASE_URL = "https://ec-registry.onrender.com"
22
+
23
+
24
+ class EdgeConductorError(Exception):
25
+ pass
26
+
27
+
28
+ class _BaseAPI:
29
+ def __init__(self, client: "Client"):
30
+ self._c = client
31
+
32
+
33
+ class Client:
34
+ def __init__(self, api_key: str, base_url: str = DEFAULT_BASE_URL):
35
+ if not api_key:
36
+ raise ValueError("EdgeConductor: api_key is required")
37
+ self._api_key = api_key
38
+ self._base_url = base_url.rstrip("/")
39
+ self.devices = DevicesAPI(self)
40
+ self.telemetry = TelemetryAPI(self)
41
+ self.rules = RulesAPI(self)
42
+ self.orgs = OrgsAPI(self)
43
+ self.audit = AuditAPI(self)
44
+
45
+ def _request(self, method: str, path: str, body: Optional[Dict] = None) -> Any:
46
+ url = f"{self._base_url}{path}"
47
+ data = json.dumps(body).encode() if body is not None else None
48
+ req = urllib.request.Request(
49
+ url, data=data, method=method,
50
+ headers={
51
+ "Content-Type": "application/json",
52
+ "Authorization": f"Bearer {self._api_key}",
53
+ },
54
+ )
55
+ try:
56
+ with urllib.request.urlopen(req) as res:
57
+ return json.loads(res.read())
58
+ except urllib.error.HTTPError as e:
59
+ msg = e.read().decode()
60
+ try:
61
+ msg = json.loads(msg).get("error", msg)
62
+ except Exception:
63
+ pass
64
+ raise EdgeConductorError(f"EC API {e.code}: {msg}") from e
65
+
66
+
67
+ class DevicesAPI(_BaseAPI):
68
+ def register(self, serial_no: str, product_type: str, fw_version: str = "1.0.0") -> Dict:
69
+ """Register a new device."""
70
+ return self._c._request("POST", "/devices/register", {
71
+ "serial_no": serial_no, "product_type": product_type, "fw_version": fw_version,
72
+ })
73
+
74
+ def list(self, org_id: Optional[str] = None, tenant_id: Optional[str] = None) -> List[Dict]:
75
+ """List devices filtered by org or tenant."""
76
+ params = f"org_id={org_id}" if org_id else f"tenant_id={tenant_id}" if tenant_id else ""
77
+ return self._c._request("GET", f"/devices{'?' + params if params else ''}")
78
+
79
+ def get(self, serial: str) -> Dict:
80
+ """Get device details + shadow."""
81
+ return self._c._request("GET", f"/devices/{serial}")
82
+
83
+ def get_shadow(self, serial: str) -> Optional[Dict]:
84
+ """Get device reported state (live sensor values)."""
85
+ return self.get(serial).get("shadow_reported")
86
+
87
+ def push_config(self, serial: str, **config) -> Dict:
88
+ """Push config to device (updates desired state → MQTT command)."""
89
+ return self._c._request("PATCH", f"/devices/{serial}/shadow/desired", config)
90
+
91
+ def push_ota(self, serial: str, firmware_id: str) -> Dict:
92
+ """Push OTA firmware update."""
93
+ return self._c._request("POST", f"/devices/{serial}/ota", {"firmware_id": firmware_id})
94
+
95
+ def reboot(self, serial: str) -> Dict:
96
+ """Remote reboot device."""
97
+ return self._c._request("POST", f"/devices/{serial}/reboot")
98
+
99
+ def assign(self, serial: str, org_id: Optional[str] = None, room_id: Optional[str] = None) -> Dict:
100
+ """Assign device to org/room."""
101
+ body = {}
102
+ if org_id: body["org_id"] = org_id
103
+ if room_id: body["room_id"] = room_id
104
+ return self._c._request("PATCH", f"/devices/{serial}/assign", body)
105
+
106
+
107
+ class TelemetryAPI(_BaseAPI):
108
+ def push(self, serial: str, **payload) -> Dict:
109
+ """
110
+ Push telemetry from device to cloud.
111
+
112
+ Example:
113
+ ec.telemetry.push("MY-001", temp=24.5, hum=60, co2=850, bat=4.05)
114
+ """
115
+ return self._c._request("POST", f"/devices/{serial}/telemetry", payload)
116
+
117
+ def history(self, serial: str, hours: int = 1, limit: int = 500) -> List[Dict]:
118
+ """Get historical telemetry (oldest first)."""
119
+ return self._c._request("GET", f"/devices/{serial}/telemetry?hours={hours}&limit={limit}")
120
+
121
+ def recent(self, serial: str, limit: int = 20) -> List[Dict]:
122
+ """Get last N telemetry records (newest first)."""
123
+ return self._c._request("GET", f"/devices/{serial}/telemetry?limit={limit}")
124
+
125
+
126
+ class RulesAPI(_BaseAPI):
127
+ def list(self, org_id: str) -> List[Dict]:
128
+ return self._c._request("GET", f"/orgs/{org_id}/rules")
129
+
130
+ def threshold(self, org_id: str, name: str, field: str, op: str, value: float,
131
+ action: Dict, room_id: Optional[str] = None, webhook_url: Optional[str] = None) -> Dict:
132
+ """
133
+ Create threshold rule.
134
+
135
+ Example:
136
+ ec.rules.threshold(
137
+ org_id, name="CO2 Alert",
138
+ field="co2", op=">", value=1000,
139
+ action={"key": "relay", "value": True}
140
+ )
141
+ """
142
+ return self._c._request("POST", f"/orgs/{org_id}/rules", {
143
+ "name": name, "rule_type": "threshold",
144
+ "condition": {"field": field, "op": op, "value": value},
145
+ "action": action,
146
+ "room_id": room_id, "webhook_url": webhook_url,
147
+ })
148
+
149
+ def schedule(self, org_id: str, name: str, time: str, days: List[str],
150
+ action: Dict, room_id: Optional[str] = None) -> Dict:
151
+ """
152
+ Create schedule rule.
153
+
154
+ Example:
155
+ ec.rules.schedule(
156
+ org_id, name="Morning ON",
157
+ time="09:00", days=["mon","tue","wed","thu","fri"],
158
+ action={"key": "relay", "value": True}
159
+ )
160
+ """
161
+ return self._c._request("POST", f"/orgs/{org_id}/rules", {
162
+ "name": name, "rule_type": "schedule",
163
+ "schedule_time": time, "schedule_days": days,
164
+ "action": action, "room_id": room_id,
165
+ })
166
+
167
+ def enable(self, rule_id: str) -> Dict:
168
+ return self._c._request("PATCH", f"/rules/{rule_id}", {"enabled": True})
169
+
170
+ def disable(self, rule_id: str) -> Dict:
171
+ return self._c._request("PATCH", f"/rules/{rule_id}", {"enabled": False})
172
+
173
+ def delete(self, rule_id: str) -> Dict:
174
+ return self._c._request("DELETE", f"/rules/{rule_id}")
175
+
176
+ def evaluate(self, org_id: str) -> Dict:
177
+ return self._c._request("POST", f"/orgs/{org_id}/rules/evaluate")
178
+
179
+
180
+ class OrgsAPI(_BaseAPI):
181
+ def get(self, org_id: str) -> Dict:
182
+ return self._c._request("GET", f"/orgs/{org_id}")
183
+
184
+ def list(self) -> List[Dict]:
185
+ return self._c._request("GET", "/orgs")
186
+
187
+ def rooms(self, org_id: str) -> List[Dict]:
188
+ return self._c._request("GET", f"/orgs/{org_id}/rooms")
189
+
190
+ def create_room(self, org_id: str, name: str, floor: str = "", building: str = "") -> Dict:
191
+ return self._c._request("POST", f"/orgs/{org_id}/rooms",
192
+ {"name": name, "floor": floor, "building": building})
193
+
194
+
195
+ class AuditAPI(_BaseAPI):
196
+ def list(self, org_id: str, limit: int = 50) -> List[Dict]:
197
+ return self._c._request("GET", f"/orgs/{org_id}/audit?limit={limit}")
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: edgeconductor
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for the EdgeConductor IoT Platform
5
+ Home-page: https://github.com/edgeconductor-creator/ec-platform
6
+ Author: EdgeConductor
7
+ Author-email: EdgeConductor <edgeconductor@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://edgeconductor.com
10
+ Project-URL: Repository, https://github.com/edgeconductor-creator/ec-platform
11
+ Project-URL: Documentation, https://edgeconductor.com/developers
12
+ Keywords: iot,mqtt,telemetry,device-management,edge-computing
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Topic :: System :: Hardware
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ Dynamic: author
20
+ Dynamic: home-page
21
+ Dynamic: requires-python
22
+
23
+ # edgeconductor
24
+
25
+ Official Python SDK for the [EdgeConductor IoT Platform](https://edgeconductor.com).
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install edgeconductor
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```python
36
+ from edgeconductor import Client
37
+
38
+ ec = Client(
39
+ api_key = "ec_live_xxxxxxxxxxxx", # from /org/settings → API Keys
40
+ base_url = "https://ec-registry.onrender.com",
41
+ )
42
+
43
+ # Register device
44
+ ec.devices.register(serial_no="MY-001", product_type="EC-CLIMATE-V1")
45
+
46
+ # Push telemetry
47
+ ec.telemetry.push("MY-001", temp=24.5, hum=60, co2=850, bat=4.05)
48
+
49
+ # Get current state
50
+ shadow = ec.devices.get_shadow("MY-001")
51
+ print(shadow) # {"temp": 24.5, "hum": 60, ...}
52
+
53
+ # Create automation rule
54
+ ec.rules.threshold(
55
+ org_id, name="CO₂ Alert",
56
+ field="co2", op=">", value=1000,
57
+ action={"key": "relay", "value": True},
58
+ )
59
+ ```
60
+
61
+ ## Links
62
+
63
+ - **Docs:** [edgeconductor.com/developers](https://edgeconductor.com/developers)
64
+ - **API Keys:** Login → /org/settings → API Keys
65
+ - **Support:** edgeconductor@gmail.com
@@ -0,0 +1,9 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ edgeconductor/__init__.py
5
+ edgeconductor/client.py
6
+ edgeconductor.egg-info/PKG-INFO
7
+ edgeconductor.egg-info/SOURCES.txt
8
+ edgeconductor.egg-info/dependency_links.txt
9
+ edgeconductor.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ edgeconductor
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "edgeconductor"
7
+ version = "0.1.0"
8
+ description = "Official Python SDK for the EdgeConductor IoT Platform"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ authors = [{ name = "EdgeConductor", email = "edgeconductor@gmail.com" }]
12
+ requires-python = ">=3.8"
13
+ keywords = ["iot", "mqtt", "telemetry", "device-management", "edge-computing"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Topic :: System :: Hardware",
18
+ "Topic :: Software Development :: Libraries",
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://edgeconductor.com"
23
+ Repository = "https://github.com/edgeconductor-creator/ec-platform"
24
+ Documentation = "https://edgeconductor.com/developers"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,18 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="edgeconductor",
5
+ version="0.1.0",
6
+ description="Official Python SDK for the EdgeConductor IoT Platform",
7
+ author="EdgeConductor",
8
+ author_email="edgeconductor@gmail.com",
9
+ url="https://github.com/edgeconductor-creator/ec-platform",
10
+ packages=find_packages(),
11
+ python_requires=">=3.8",
12
+ classifiers=[
13
+ "Programming Language :: Python :: 3",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Topic :: Software Development :: Libraries",
16
+ "Topic :: System :: Hardware",
17
+ ],
18
+ )