From 0149c81dd1df7b326b0beac36421eaf66e277daa Mon Sep 17 00:00:00 2001 From: wtz Date: Sat, 4 Apr 2026 11:30:30 +0800 Subject: [PATCH] init --- .gitignore | 4 + makergen/__init__.py | 7 ++ makergen/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 313 bytes makergen/__pycache__/core.cpython-312.pyc | Bin 0 -> 5184 bytes makergen/core.py | 78 ++++++++++++++++++ requirements.txt | 1 + 6 files changed, 90 insertions(+) create mode 100644 .gitignore create mode 100644 makergen/__init__.py create mode 100644 makergen/__pycache__/__init__.cpython-312.pyc create mode 100644 makergen/__pycache__/core.cpython-312.pyc create mode 100644 makergen/core.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ece1db6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +.venv/ +main.py + diff --git a/makergen/__init__.py b/makergen/__init__.py new file mode 100644 index 0000000..a054937 --- /dev/null +++ b/makergen/__init__.py @@ -0,0 +1,7 @@ +"""适配makergen的Python SDK""" + +__version__ = '0.1.0' + +from makergen.core import Device + +__all__ = ["Device"] diff --git a/makergen/__pycache__/__init__.cpython-312.pyc b/makergen/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57f227031ebfbd4edd7e81f6bf4a8f19918254c4 GIT binary patch literal 313 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 literal 0 HcmV?d00001 diff --git a/makergen/core.py b/makergen/core.py new file mode 100644 index 0000000..25991b8 --- /dev/null +++ b/makergen/core.py @@ -0,0 +1,78 @@ +import json +import threading +import time +from json import JSONDecodeError +from typing import Callable, Optional + +import websocket + + +class ServerException(Exception): + pass + + +class Device: + def __init__(self, device_id: str, device_key: str, + on_msg_callback: Optional[Callable[[str, any], None]] = lambda point, value : print(point, value), + on_error_callback: Optional[Callable[[Exception], None]] = lambda error: print(error), + base_url: str = "wss://api.makergen.cn"): + """ + 创建一个设备对象。需要调用connect方法才能真正连接。 + :param device_id: 设备ID,在控制台设备管理中显示 + :param device_key: Device Key,在控制台设备管理中显示 + :param on_msg_callback: 当收到消息后的回调。接收两个参数,第一个参数为控制点,字符串型;第二个参数为控制值,任意类型 + :param on_error_callback: 当遇到错误时的回调。接收一个参数,为错误对象;若遇到服务器或页面发送的消息不合规,传入ServerException对象 + :param base_url: makergen的基础URL,通常为wss://api.makergen.cn + """ + url = f"{base_url if base_url[-1] == '/' else base_url + "/"}ws/device/{device_id}?key={device_key}" + print(url) + self.ws = websocket.WebSocketApp( + url, + on_open=self._on_open, + on_message=self._on_message, + on_close=self._on_close, + on_error=self._on_error, + ) + self.on_msg_callback = on_msg_callback if on_msg_callback is not None else lambda _, __ : None + self.on_error_callback = on_error_callback if on_error_callback is not None else lambda _ : None + + def _on_open(self, ws): + print("open") + def _on_close(self, ws, close_status_code, close_msg): + print("close") + + def _on_message(self, ws, message): + try: + message_str = json.loads(message)["payload"] + self.on_msg_callback(message_str["point"], message_str["value"]) + except KeyError or JSONDecodeError: + self.on_error_callback(ServerException("Page or server sent an invalid message")) + except Exception as e: + self.on_error_callback(e) + + def _on_error(self, ws, error): + self.on_error_callback(error) + + def send_data(self, point: str, value: str): + self.ws.send(json.dumps({ + "type": "data", + "payload": { + "point": point, + "value": value + }, + "timestamp": int(time.time() * 1000) + })) + + def connect(self): + """ + 在新线程中运行客户端循环(推荐) + """ + wst = threading.Thread(target=self.ws.run_forever) + wst.daemon = True + wst.start() + + def main_loop(self): + """ + 在当前线程中运行客户端循环(不推荐) + """ + self.ws.run_forever() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2f738ef --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +websocket-client==1.9.0