初次加入
This commit is contained in:
parent
9ce868092f
commit
1967009793
10
IoT/config.yaml
Normal file
10
IoT/config.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
server_uri: "6396c4c5d6.st1.iotda-device.cn-south-1.myhuaweicloud.com"
|
||||
port: 1883
|
||||
product_id: "673602f0d14760402fbd033b"
|
||||
secret: "RobotStorm"
|
||||
max_files: 20
|
||||
watch_dirs:
|
||||
- "/home/jsfb/jsfb_ws/collected_data"
|
||||
- "/home/jsfb/jsfb_ws/LanguageLog"
|
||||
- "/home/jsfb/jsfb_ws/UILog"
|
||||
- "/home/jsfb/jsfb_ws/MassageLog"
|
20
IoT/iot.service
Executable file
20
IoT/iot.service
Executable file
@ -0,0 +1,20 @@
|
||||
[Unit]
|
||||
Description=IoT service
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/home/jsfb/jsfb_ws/MassageRobot_aubo/IoT
|
||||
Environment="PATH=/home/jsfb/anaconda3/envs/CPU_robotarm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
ExecStart=/home/jsfb/anaconda3/envs/CPU_robotarm/bin/python iot_lite.pyc
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
StartLimitIntervalSec=0
|
||||
StartLimitBurst=0
|
||||
User=jsfb
|
||||
Group=jsfb
|
||||
TimeoutStopSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
BIN
IoT/iot_device_sdk_python/__init__.pyc
Normal file
BIN
IoT/iot_device_sdk_python/__init__.pyc
Normal file
Binary file not shown.
0
IoT/iot_device_sdk_python/client/__init__.py
Normal file
0
IoT/iot_device_sdk_python/client/__init__.py
Normal file
BIN
IoT/iot_device_sdk_python/client/__init__.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/__init__.pyc
Normal file
Binary file not shown.
48
IoT/iot_device_sdk_python/client/client_conf.py
Normal file
48
IoT/iot_device_sdk_python/client/client_conf.py
Normal file
@ -0,0 +1,48 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import Optional
|
||||
|
||||
from iot_device_sdk_python.client.connect_auth_info import ConnectAuthInfo
|
||||
from iot_device_sdk_python.client.mqtt_connect_conf import MqttConnectConf
|
||||
|
||||
|
||||
class ClientConf:
|
||||
"""
|
||||
客户端配置
|
||||
"""
|
||||
|
||||
def __init__(self, connect_auth_info: ConnectAuthInfo, mqtt_connect_conf: Optional[MqttConnectConf] = None):
|
||||
self.__connect_auth_info = connect_auth_info
|
||||
self.__mqtt_connect_conf = MqttConnectConf()
|
||||
if mqtt_connect_conf is not None:
|
||||
self.__mqtt_connect_conf = mqtt_connect_conf
|
||||
|
||||
@property
|
||||
def connect_auth_info(self):
|
||||
return self.__connect_auth_info
|
||||
|
||||
@connect_auth_info.setter
|
||||
def connect_auth_info(self, value):
|
||||
self.__connect_auth_info = value
|
||||
|
||||
@property
|
||||
def mqtt_connect_conf(self):
|
||||
return self.__mqtt_connect_conf
|
||||
|
||||
@mqtt_connect_conf.setter
|
||||
def mqtt_connect_conf(self, value):
|
||||
self.__mqtt_connect_conf = value
|
BIN
IoT/iot_device_sdk_python/client/client_conf.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/client_conf.pyc
Normal file
Binary file not shown.
319
IoT/iot_device_sdk_python/client/connect_auth_info.py
Normal file
319
IoT/iot_device_sdk_python/client/connect_auth_info.py
Normal file
@ -0,0 +1,319 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class ConnectAuthInfo:
|
||||
"""
|
||||
连接鉴权配置
|
||||
"""
|
||||
SECRET_AUTH = 0
|
||||
X509_AUTH = 1
|
||||
PROTOCOL_MQTT = "MQTT"
|
||||
BS_MODE_DIRECT_CONNECT = 0
|
||||
BS_MODE_STANDARD_BOOTSTRAP = 1
|
||||
BS_MODE_BOOTSTRAP_WITH_SCOPEID = 2
|
||||
|
||||
def __init__(self):
|
||||
""" id,在平台注册设备获得 """
|
||||
self._id: Optional[str] = None
|
||||
|
||||
""" 认证的类型:0表示密码方式,1表示x509证书方式;默认为0 """
|
||||
self._auth_type: int = self.SECRET_AUTH
|
||||
|
||||
""" 设备密码 """
|
||||
self._secret: Optional[str] = None
|
||||
|
||||
""" x509证书的pem文件路径 """
|
||||
self._cert_path: Optional[str] = None
|
||||
|
||||
""" x509证书的key文件路径 """
|
||||
self._key_path: Optional[str] = None
|
||||
|
||||
""" iot平台的ca证书存放路径,用于设备侧校验平台 """
|
||||
self._iot_cert_file: Optional[str] = None
|
||||
|
||||
""" 设备自注册场景下使用 """
|
||||
self._scope_id: Optional[str] = None
|
||||
|
||||
""" 设备接入平台地址(不包括端口) """
|
||||
self._server_uri: Optional[str] = None
|
||||
|
||||
""" 端口 """
|
||||
self._port: Optional[int] = None
|
||||
|
||||
""" 协议类型,不填则默认为MQTT """
|
||||
self._protocol: str = self.PROTOCOL_MQTT
|
||||
|
||||
""" 0表示直连模式,1表示标准设备发放流程,2表示通过自注册的方式进行批量发放;默认为0 """
|
||||
self._bs_mode: int = self.BS_MODE_DIRECT_CONNECT
|
||||
|
||||
""" 设备发放平台的证书路径 """
|
||||
self._bs_cert_path: Optional[str] = None
|
||||
|
||||
""" 设备发放时上报的消息 ,在静态策略数据上报方式中,需要在上报的属性 “baseStrategyKeyword” 包含设置的关键字"""
|
||||
self._bs_message: Optional[str] = None
|
||||
|
||||
""" 是否校验时间戳,"0"表示HMACSHA256不校验时间戳,"1"表示HMACSHA256校验时间戳;默认为"1"。 """
|
||||
self._check_timestamp: str = "1"
|
||||
|
||||
""" 是否支持重连,True表示支持重连, False表示不支持重连"""
|
||||
self._reconnect_on_failure = True
|
||||
""" 最小退避时间, 默认1s"""
|
||||
self._min_backoff = 1 * 1000 # 1s
|
||||
""" 最大退避时间,默认30s"""
|
||||
self._max_backoff = 30 * 1000
|
||||
""" 是否开启端侧规则"""
|
||||
self._enable_rule_manage = False
|
||||
""" max buffer max"""
|
||||
self._max_buffer_message = 0
|
||||
""" qos1时最多可以同时发布多条消息,默认20条 """
|
||||
self._inflight_messages: Optional[int] = 20
|
||||
""" 是否自动上报版本号"""
|
||||
self._auto_report_device_info: Optional[bool] = False
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
id,在平台注册设备获得
|
||||
"""
|
||||
return self._id
|
||||
|
||||
@id.setter
|
||||
def id(self, value):
|
||||
self._id = value
|
||||
|
||||
@property
|
||||
def auth_type(self):
|
||||
"""
|
||||
认证的类型:0表示密码方式,1表示x509证书方式;默认为0
|
||||
"""
|
||||
return self._auth_type
|
||||
|
||||
@auth_type.setter
|
||||
def auth_type(self, value):
|
||||
self._auth_type = value
|
||||
|
||||
@property
|
||||
def secret(self):
|
||||
"""
|
||||
设备密码
|
||||
"""
|
||||
return self._secret
|
||||
|
||||
@secret.setter
|
||||
def secret(self, value):
|
||||
self._secret = value
|
||||
|
||||
@property
|
||||
def cert_path(self):
|
||||
"""
|
||||
x509证书的pem文件路径
|
||||
"""
|
||||
return self._cert_path
|
||||
|
||||
@cert_path.setter
|
||||
def cert_path(self, value):
|
||||
self._cert_path = value
|
||||
|
||||
@property
|
||||
def key_path(self):
|
||||
"""
|
||||
x509证书的key文件路径
|
||||
"""
|
||||
return self._key_path
|
||||
|
||||
@key_path.setter
|
||||
def key_path(self, value):
|
||||
self._key_path = value
|
||||
|
||||
@property
|
||||
def iot_cert_path(self):
|
||||
"""
|
||||
iot平台的ca证书存放路径,用于设备侧校验平台
|
||||
"""
|
||||
return self._iot_cert_file
|
||||
|
||||
@iot_cert_path.setter
|
||||
def iot_cert_path(self, value):
|
||||
self._iot_cert_file = value
|
||||
|
||||
@property
|
||||
def server_uri(self):
|
||||
"""
|
||||
设备接入平台地址(不包括端口)
|
||||
"""
|
||||
return self._server_uri
|
||||
|
||||
@server_uri.setter
|
||||
def server_uri(self, value):
|
||||
self._server_uri = value
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
"""
|
||||
端口
|
||||
"""
|
||||
return self._port
|
||||
|
||||
@port.setter
|
||||
def port(self, value):
|
||||
self._port = value
|
||||
|
||||
@property
|
||||
def protocol(self):
|
||||
"""
|
||||
协议类型,不填则默认为MQTT
|
||||
"""
|
||||
return self._protocol
|
||||
|
||||
@protocol.setter
|
||||
def protocol(self, value):
|
||||
self._protocol = value
|
||||
|
||||
@property
|
||||
def scope_id(self):
|
||||
"""
|
||||
设备自注册场景下使用
|
||||
"""
|
||||
return self._scope_id
|
||||
|
||||
@scope_id.setter
|
||||
def scope_id(self, value):
|
||||
self._scope_id = value
|
||||
|
||||
@property
|
||||
def bs_mode(self):
|
||||
"""
|
||||
是否为设备发放场景,默认为1
|
||||
"""
|
||||
return self._bs_mode
|
||||
|
||||
@bs_mode.setter
|
||||
def bs_mode(self, value):
|
||||
self._bs_mode = value
|
||||
|
||||
@property
|
||||
def bs_cert_path(self):
|
||||
"""
|
||||
设备发放平台的证书路径
|
||||
"""
|
||||
return self._bs_cert_path
|
||||
|
||||
@bs_cert_path.setter
|
||||
def bs_cert_path(self, value):
|
||||
self._bs_cert_path = value
|
||||
|
||||
@property
|
||||
def bs_message(self):
|
||||
"""
|
||||
静态策略数据上报方式下上报的数据
|
||||
"""
|
||||
return self._bs_message
|
||||
|
||||
@bs_message.setter
|
||||
def bs_message(self, value):
|
||||
self._bs_message = value
|
||||
|
||||
@property
|
||||
def check_timestamp(self):
|
||||
"""
|
||||
是否校验时间戳,默认为"1"
|
||||
"""
|
||||
return self._check_timestamp
|
||||
|
||||
@check_timestamp.setter
|
||||
def check_timestamp(self, value):
|
||||
self._check_timestamp = value
|
||||
|
||||
@property
|
||||
def reconnect_on_failure(self):
|
||||
"""
|
||||
是否支持重连,TRUE支持重连
|
||||
"""
|
||||
return self._reconnect_on_failure
|
||||
|
||||
@reconnect_on_failure.setter
|
||||
def reconnect_on_failure(self, value):
|
||||
self._reconnect_on_failure = value
|
||||
|
||||
@property
|
||||
def min_backoff(self):
|
||||
"""
|
||||
最小退避时间
|
||||
"""
|
||||
return self._min_backoff
|
||||
|
||||
@min_backoff.setter
|
||||
def min_backoff(self, value):
|
||||
self._min_backoff = value
|
||||
|
||||
@property
|
||||
def max_backoff(self):
|
||||
"""
|
||||
最大退避时间
|
||||
"""
|
||||
return self._max_backoff
|
||||
|
||||
@max_backoff.setter
|
||||
def max_backoff(self, value):
|
||||
self._max_backoff = value
|
||||
|
||||
@property
|
||||
def enable_rule_manage(self):
|
||||
"""
|
||||
是否支持端侧规则
|
||||
"""
|
||||
return self._enable_rule_manage
|
||||
|
||||
@enable_rule_manage.setter
|
||||
def enable_rule_manage(self, value):
|
||||
self._enable_rule_manage = value
|
||||
|
||||
@property
|
||||
def max_buffer_message(self):
|
||||
"""
|
||||
最大缓存消息,默认为0,不缓存消息
|
||||
断链时,生产失败的消息存放队列,待重连后重新发送
|
||||
"""
|
||||
return self._max_buffer_message
|
||||
|
||||
@max_buffer_message.setter
|
||||
def max_buffer_message(self, value):
|
||||
self._max_buffer_message = value
|
||||
|
||||
@property
|
||||
def inflight_messages(self):
|
||||
"""
|
||||
qos1时最多可以同时发布多条消息,默认20条
|
||||
"""
|
||||
return self._inflight_messages
|
||||
|
||||
@inflight_messages.setter
|
||||
def inflight_messages(self, value):
|
||||
self._inflight_messages = value
|
||||
|
||||
@property
|
||||
def auto_report_device_info(self):
|
||||
"""
|
||||
qos1时最多可以同时发布多条消息,默认20条
|
||||
"""
|
||||
return self._auto_report_device_info
|
||||
|
||||
@auto_report_device_info.setter
|
||||
def auto_report_device_info(self, value):
|
||||
self._auto_report_device_info = value
|
BIN
IoT/iot_device_sdk_python/client/connect_auth_info.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/connect_auth_info.pyc
Normal file
Binary file not shown.
798
IoT/iot_device_sdk_python/client/device_client.py
Normal file
798
IoT/iot_device_sdk_python/client/device_client.py
Normal file
@ -0,0 +1,798 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
设备客户端,提供和平台的通讯能力,包括:
|
||||
|
||||
消息:双向,异步,不需要定义模型
|
||||
|
||||
属性:双向,设备可以上报属性,平台可以向设备读写属性,属性需要在模型定义
|
||||
|
||||
命令:单向,同步,平台向设备调用设备的命令
|
||||
|
||||
时间:双向,异步,需要在模型定义
|
||||
|
||||
用户不能直接创建DeviceClient实例,只能先创建IoTDevice实例,然后通过IoTDevice的get_client方法获取DeviceClient实例
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, annotations
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import traceback
|
||||
import sys
|
||||
import os
|
||||
import stat
|
||||
|
||||
from iot_device_sdk_python.client.connect_auth_info import ConnectAuthInfo
|
||||
from iot_device_sdk_python.client.iot_result import IotResult
|
||||
from iot_device_sdk_python.client.listener.command_listener import CommandListener
|
||||
from iot_device_sdk_python.client.listener.device_message_listener import DeviceMessageListener
|
||||
from iot_device_sdk_python.client.listener.device_shadow_listener import DeviceShadowListener
|
||||
from iot_device_sdk_python.client.listener.property_listener import PropertyListener
|
||||
from iot_device_sdk_python.client.listener.raw_device_message_listener import RawDeviceMessageListener
|
||||
from iot_device_sdk_python.client.mqtt_connect_conf import MqttConnectConf
|
||||
from iot_device_sdk_python.client.request.device_message import DeviceMessage
|
||||
from iot_device_sdk_python.client.request.raw_device_message import RawDeviceMessage
|
||||
from iot_device_sdk_python.client.request.shadow_data import ShadowData
|
||||
from iot_device_sdk_python.transport.mqtt.mqtt_connection import MqttConnection
|
||||
from iot_device_sdk_python.client.request.device_event import DeviceEvent
|
||||
from iot_device_sdk_python.client.request.device_events import DeviceEvents
|
||||
from iot_device_sdk_python.transport.raw_message import RawMessage
|
||||
from iot_device_sdk_python.transport.raw_message_listener import RawMessageListener
|
||||
from iot_device_sdk_python.transport.action_listener import ActionListener
|
||||
from iot_device_sdk_python.transport.connection import Connection
|
||||
from iot_device_sdk_python.utils.iot_util import get_request_id_from_msg, str_is_empty, get_event_time
|
||||
from iot_device_sdk_python.client.request.service_property import ServiceProperty
|
||||
from iot_device_sdk_python.client.request.command import Command
|
||||
from iot_device_sdk_python.client.request.command_response import CommandRsp
|
||||
from iot_device_sdk_python.client.request.props_set import PropSet
|
||||
from iot_device_sdk_python.client.request.props_get import PropsGet
|
||||
from iot_device_sdk_python.client.request.device_base_info import DeviceBaseInfo
|
||||
from iot_device_sdk_python.rule.model.action_handler import ActionHandler
|
||||
from iot_device_sdk_python.rule.model.actions import Action
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from iot_device_sdk_python.service.abstract_device import AbstractDevice
|
||||
|
||||
|
||||
class DeviceClient(RawMessageListener):
|
||||
_logger = logging.getLogger(__name__)
|
||||
# SDK版本信息,不能更改
|
||||
__SDK_VERSION = "Python_v1.2.0"
|
||||
__SERVER_INFO_PATH = os.path.join(sys.path[0], "server_info.json")
|
||||
__SERVER_URI = "server_uri"
|
||||
__PORT = "port"
|
||||
__SECRET = "secret"
|
||||
__BOOTSTRAP_TIMEOUT = 10.0
|
||||
|
||||
def __init__(self, connect_auth_info: ConnectAuthInfo, mqtt_connect_conf: MqttConnectConf, device: AbstractDevice):
|
||||
self.check_connect_auth_info(connect_auth_info)
|
||||
self.check_mqtt_connect_conf(mqtt_connect_conf)
|
||||
self.__connect_auth_info = connect_auth_info
|
||||
self.__mqtt_connect_conf = mqtt_connect_conf
|
||||
|
||||
self._device = device
|
||||
self.__connection: Optional[Connection] = None
|
||||
if self.__connect_auth_info.protocol == ConnectAuthInfo.PROTOCOL_MQTT:
|
||||
self.__connection = MqttConnection(connect_auth_info, mqtt_connect_conf, self)
|
||||
else:
|
||||
self._logger.error("Current SDK only supports PROTOCOL_MQTT.")
|
||||
return
|
||||
|
||||
|
||||
# 设备发放是否成功
|
||||
self.__bs_flag = False
|
||||
# 是否开启端侧规则
|
||||
self.__enable_rule_manage = connect_auth_info.enable_rule_manage
|
||||
# raw_msg_listener是原始消息接收监听器
|
||||
self.__raw_msg_listener_map = dict()
|
||||
# 设置原始消息监听器,用于接收平台下发的原始设备消息
|
||||
self.__raw_device_msg_listener: Optional[RawDeviceMessageListener] = None
|
||||
# 设置消息监听器,用于接收平台下发的设备消息
|
||||
self.__device_msg_listener: Optional[DeviceMessageListener] = None
|
||||
# 属性监听器,用于接收平台下发的属性读写操作
|
||||
self.__property_listener: Optional[PropertyListener] = None
|
||||
# 命令监听器,用于接收平台下发的命令
|
||||
self.__command_listener: Optional[CommandListener] = None
|
||||
# 影子监听器,用于接收平台下发的设备影子数据
|
||||
self.__shadow_listener: Optional[DeviceShadowListener] = None
|
||||
# 端侧规则监听器,用于自定义处理端侧规则
|
||||
self.__rule_action_handler: Optional[ActionHandler] = None
|
||||
|
||||
@staticmethod
|
||||
def check_connect_auth_info(connect_auth_info: ConnectAuthInfo):
|
||||
"""
|
||||
检查连接鉴权配置。若配置有问题,则抛出错误
|
||||
|
||||
Args:
|
||||
connect_auth_info: 连接鉴权配置
|
||||
"""
|
||||
if connect_auth_info is None:
|
||||
raise ValueError("ConnectAuthInfo is null")
|
||||
if str_is_empty(connect_auth_info.id):
|
||||
raise ValueError("ConnectAuthInfo id is invalid")
|
||||
if connect_auth_info.protocol != ConnectAuthInfo.PROTOCOL_MQTT:
|
||||
# 当前SDK只支持MQTT协议
|
||||
raise ValueError("ConnectAuthInfo protocol is invalid, currently protocol only support MQTT")
|
||||
if str_is_empty(connect_auth_info.server_uri):
|
||||
raise ValueError("ConnectAuthInfo server_uri is invalid")
|
||||
if connect_auth_info.auth_type not in [ConnectAuthInfo.SECRET_AUTH, ConnectAuthInfo.X509_AUTH]:
|
||||
raise ValueError("ConnectAuthInfo auth_type is invalid")
|
||||
if str_is_empty(connect_auth_info.secret) and (
|
||||
str_is_empty(connect_auth_info.cert_path) or str_is_empty(connect_auth_info.key_path)) is None:
|
||||
raise ValueError("ConnectAuthInfo secret or certificate is invalid")
|
||||
if connect_auth_info.port != 1883 and connect_auth_info.port != 8883:
|
||||
raise ValueError("ConnectAuthInfo port is invalid")
|
||||
if connect_auth_info.port == 8883 and str_is_empty(connect_auth_info.iot_cert_path):
|
||||
raise ValueError("ConnectAuthInfo iot_cert_path is invalid")
|
||||
if connect_auth_info.bs_mode not in [ConnectAuthInfo.BS_MODE_DIRECT_CONNECT,
|
||||
ConnectAuthInfo.BS_MODE_STANDARD_BOOTSTRAP,
|
||||
ConnectAuthInfo.BS_MODE_BOOTSTRAP_WITH_SCOPEID]:
|
||||
raise ValueError("ConnectAuthInfo bs_mode is invalid")
|
||||
if connect_auth_info.bs_mode == ConnectAuthInfo.BS_MODE_BOOTSTRAP_WITH_SCOPEID and str_is_empty(
|
||||
connect_auth_info.scope_id):
|
||||
raise ValueError("ConnectAuthInfo scope_id is invalid")
|
||||
if connect_auth_info.check_timestamp not in ["0", "1"]:
|
||||
raise ValueError("ConnectAuthInfo check_timestamp is invalid")
|
||||
|
||||
@staticmethod
|
||||
def check_mqtt_connect_conf(mqtt_connect_conf: MqttConnectConf):
|
||||
"""
|
||||
检查mqtt配置。若配置有问题,则抛出错误
|
||||
|
||||
Args:
|
||||
mqtt_connect_conf: mqtt配置
|
||||
"""
|
||||
if mqtt_connect_conf is None:
|
||||
raise ValueError("MqttConnectConf is null")
|
||||
if not isinstance(mqtt_connect_conf.keep_alive_time, int) \
|
||||
or mqtt_connect_conf.keep_alive_time < 30 \
|
||||
or mqtt_connect_conf.keep_alive_time > 1200:
|
||||
raise ValueError("MqttConnectConf keep_alive_time is invalid")
|
||||
if not isinstance(mqtt_connect_conf.qos, int) or mqtt_connect_conf.qos not in [0, 1]:
|
||||
raise ValueError("MqttConnectConf qos is invalid")
|
||||
if not isinstance(mqtt_connect_conf.timeout, float):
|
||||
raise ValueError("MqttConnectConf timeout is invalid")
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
和平台建立连接。连接成功时,SDK将自动向平台订阅系统定义的topic
|
||||
|
||||
Returns:
|
||||
int: 结果码,0表示连接成功,其他表示连接失败
|
||||
"""
|
||||
if self.__connect_auth_info.bs_mode == ConnectAuthInfo.BS_MODE_STANDARD_BOOTSTRAP or \
|
||||
self.__connect_auth_info.bs_mode == ConnectAuthInfo.BS_MODE_BOOTSTRAP_WITH_SCOPEID:
|
||||
# 设备发放场景
|
||||
if os.path.exists(self.__SERVER_INFO_PATH):
|
||||
server_info_dict = dict()
|
||||
try:
|
||||
# 已成功进行过设备发放,从文件中读取iot平台连接信息
|
||||
with open(self.__SERVER_INFO_PATH, 'r') as server_info:
|
||||
server_info_dict: dict = json.load(server_info)
|
||||
except Exception:
|
||||
self._logger.error("load server_info failed, traceback: %s", traceback.format_exc())
|
||||
|
||||
if "server_uri" in server_info_dict.keys() and "port" in server_info_dict.keys():
|
||||
server_uri = server_info_dict.get(self.__SERVER_URI)
|
||||
port = server_info_dict.get(self.__PORT)
|
||||
secret = server_info_dict.get(self.__SECRET)
|
||||
self.__connect_auth_info.server_uri = server_uri
|
||||
self.__connect_auth_info.port = port
|
||||
if secret:
|
||||
self.__connect_auth_info.secret = secret
|
||||
else:
|
||||
# 进行设备发放
|
||||
rc = self.__bootstrap()
|
||||
if rc != 0:
|
||||
# 发放失败
|
||||
self._logger.error("bootstrap device failed.")
|
||||
return rc
|
||||
else:
|
||||
# 进行设备发放
|
||||
rc = self.__bootstrap()
|
||||
if rc != 0:
|
||||
# 发放失败
|
||||
self._logger.error("bootstrap device failed.")
|
||||
return rc
|
||||
# 建立设备到iot平台的连接, 将连接模式设置为直连。
|
||||
self.__connect_auth_info.bs_mode = ConnectAuthInfo.BS_MODE_DIRECT_CONNECT
|
||||
rc = self.__connect()
|
||||
if rc != 0:
|
||||
return rc
|
||||
if self.__connect_auth_info.auto_report_device_info:
|
||||
# 建链成功后,SDK自动上报版本号,软固件版本号由设备上报
|
||||
self.report_device_info(DeviceBaseInfo())
|
||||
return rc
|
||||
|
||||
def __connect(self):
|
||||
"""
|
||||
和平台建立连接。连接成功时,SDK将自动向平台订阅系统定义的topic
|
||||
|
||||
Returns:
|
||||
int: 结果码,0表示连接成功,其他表示连接失败
|
||||
"""
|
||||
return self.__connection.connect()
|
||||
|
||||
def __bootstrap(self):
|
||||
"""
|
||||
进行设备发放流程,返回 0表示成功,返回其它表示失败
|
||||
"""
|
||||
rc = self.__connect()
|
||||
if rc != 0:
|
||||
return rc
|
||||
bs_topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/bootstrap/down"
|
||||
self.__connection.subscribe_topic(bs_topic, 0)
|
||||
topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/bootstrap/up"
|
||||
raw_message = RawMessage(topic, self.__connect_auth_info.bs_message)
|
||||
self.publish_raw_message(raw_message)
|
||||
start_time = time.time()
|
||||
while True:
|
||||
# 等待设备发放成功
|
||||
time.sleep(1)
|
||||
if self.__bs_flag:
|
||||
break
|
||||
now = time.time()
|
||||
if now - start_time > self.__BOOTSTRAP_TIMEOUT:
|
||||
self._logger.error("bootstrap failed, timeout.")
|
||||
return -1
|
||||
# 释放设备到发放服务端的连接
|
||||
self.close()
|
||||
return rc
|
||||
|
||||
def _get_connection(self):
|
||||
return self.__connection
|
||||
|
||||
def close(self):
|
||||
""" 释放connection连接 """
|
||||
self.__connection.close()
|
||||
|
||||
def on_message_received(self, message: RawMessage):
|
||||
"""
|
||||
收到原始消息后,依据topic的不同,调用不同的方法
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
try:
|
||||
topic = message.topic
|
||||
|
||||
# 若订阅了自定义的topic,这里先检查接收到的topic是否是自定义的
|
||||
raw_msg_listener = self.__raw_msg_listener_map[topic] if topic in self.__raw_msg_listener_map else None
|
||||
if raw_msg_listener is not None:
|
||||
raw_msg_listener.on_message_received(message)
|
||||
return
|
||||
|
||||
if "/messages/down" in topic:
|
||||
self.on_device_msg(message) # 平台下发消息到设备测
|
||||
elif "sys/commands/request_id" in topic:
|
||||
self.on_command(message) # 平台下发指令到设备侧
|
||||
elif "/sys/properties/set/request_id" in topic:
|
||||
self.on_properties_set(message) # 处理写属性操作
|
||||
elif "/sys/properties/get/request_id" in topic:
|
||||
self.on_properties_get(message) # 处理读属性操作
|
||||
elif "/sys/shadow/get/response" in topic:
|
||||
self.on_device_shadow(message) # 处理获取平台设备影子数据
|
||||
elif "/sys/events/down" in topic:
|
||||
self.on_event(message) # 处理平台下发事件
|
||||
elif "/sys/bootstrap/down" in topic:
|
||||
self.on_bootstrap(message)
|
||||
else:
|
||||
self._logger.warning("unknown topic: %s", topic)
|
||||
|
||||
except Exception as e:
|
||||
self._logger.error("on_message_received error, tracback: %s", traceback.format_exc())
|
||||
self._logger.error("on_message_received error: %s", str(e))
|
||||
|
||||
def report_device_message(self, device_message: DeviceMessage, listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
上报设备消息
|
||||
|
||||
Args:
|
||||
device_message: 设备消息
|
||||
listener: 发布监听器,若不设置监听器则设为None
|
||||
"""
|
||||
topic = '$oc/devices/' + self.__connect_auth_info.id + '/sys/messages/up'
|
||||
try:
|
||||
payload = json.dumps(device_message.to_dict())
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
|
||||
def report_properties(self, services: List[ServiceProperty], listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
上报设备属性
|
||||
|
||||
Args:
|
||||
services: 设备属性列表
|
||||
listener: 发布监听器,若不设置监听器则设为None
|
||||
"""
|
||||
topic = '$oc/devices/' + self.__connect_auth_info.id + '/sys/properties/report'
|
||||
service_list = list()
|
||||
for service in services:
|
||||
service_list.append(service.to_dict())
|
||||
try:
|
||||
payload = json.dumps({"services": service_list})
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
"""
|
||||
处理端侧规则
|
||||
"""
|
||||
if self.__enable_rule_manage:
|
||||
self._device.get_rule_manage_service().handle_rule(services)
|
||||
|
||||
def get_device_shadow(self, request_id: str, service_id: Optional[str] = None,
|
||||
object_device_id: Optional[str] = None, listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
设备侧获取平台的设备影子数据
|
||||
|
||||
Args:
|
||||
request_id: 请求id
|
||||
service_id: 服务id
|
||||
object_device_id: device_id
|
||||
listener: 发布监听器,若不设置监听器则设为None
|
||||
"""
|
||||
if object_device_id is not None:
|
||||
topic = "$oc/devices/" + object_device_id + "/sys/shadow/get/request_id=" + request_id
|
||||
else:
|
||||
topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/shadow/get/request_id=" + request_id
|
||||
|
||||
payload_dict = dict()
|
||||
if service_id is not None:
|
||||
payload_dict["service_id"] = service_id
|
||||
try:
|
||||
payload = json.dumps(payload_dict)
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
|
||||
def report_event(self, device_event: DeviceEvent, listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
事件上报
|
||||
|
||||
Args:
|
||||
device_event: 事件
|
||||
listener: 发布监听器,若不设置监听器则设为None
|
||||
"""
|
||||
device_events = DeviceEvents()
|
||||
device_events.device_id = self.__connect_auth_info.id
|
||||
device_events.services = [device_event]
|
||||
|
||||
topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/events/up"
|
||||
try:
|
||||
payload = json.dumps(device_events.to_dict())
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
|
||||
def report_sub_event(self, sub_device_id: str, device_event: DeviceEvent,
|
||||
listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
子设备事件上报
|
||||
|
||||
Args:
|
||||
sub_device_id: 子设备ID
|
||||
device_event: 事件
|
||||
listener: 发布监听器,若不设置监听器则设为None
|
||||
"""
|
||||
device_events = DeviceEvents()
|
||||
device_events.device_id = self.__connect_auth_info.id
|
||||
if sub_device_id is not None:
|
||||
device_events.device_id = sub_device_id
|
||||
device_events.services = [device_event]
|
||||
|
||||
topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/events/up"
|
||||
try:
|
||||
payload = json.dumps(device_events.to_dict())
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
|
||||
def respond_command(self, request_id: str, command_response: CommandRsp, listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
上报命令响应
|
||||
|
||||
Args:
|
||||
request_id: 请求id,响应的请求id必须和请求的一致
|
||||
command_response: 命令响应
|
||||
listener: 发布监听器
|
||||
"""
|
||||
topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/commands/response/request_id=" + request_id
|
||||
try:
|
||||
payload = json.dumps(command_response.to_dict())
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
|
||||
def publish_raw_message(self, raw_message: RawMessage, listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
发布消息
|
||||
|
||||
Args:
|
||||
raw_message: 消息
|
||||
listener: 发布监听器,若不设置监听器则设为None
|
||||
"""
|
||||
self.__connection.publish_message(raw_message, listener)
|
||||
|
||||
def on_device_msg(self, message: RawMessage):
|
||||
"""
|
||||
处理平台消息下发。若当前DeviceClient设置了消息监听器,则执行此消息监听器的on_device_message()方法。
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
self._logger.debug(f"receive message from platform, topic = %s, msg = %s", message.topic, message.payload)
|
||||
|
||||
raw_device_message = RawDeviceMessage(message.payload)
|
||||
device_msg = raw_device_message.to_device_message()
|
||||
|
||||
if self.__raw_device_msg_listener is not None:
|
||||
self.__raw_device_msg_listener.on_raw_device_message(raw_device_message)
|
||||
|
||||
if device_msg is not None:
|
||||
is_current_device = device_msg.device_id is None \
|
||||
or len(device_msg.device_id) == 0 \
|
||||
or device_msg.device_id == self.__connect_auth_info.id
|
||||
if self.__device_msg_listener is not None and is_current_device:
|
||||
self.__device_msg_listener.on_device_message(device_msg)
|
||||
else:
|
||||
self._device.on_device_message(device_msg)
|
||||
|
||||
def on_command(self, message: RawMessage):
|
||||
"""
|
||||
处理平台命令下发。若当前DeviceClient设置了命令监听器,则执行此命令监听器的on_command()方法。
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
request_id = get_request_id_from_msg(message)
|
||||
try:
|
||||
self._logger.debug("receive command from platform, topic = %s, msg = %s", message.topic,
|
||||
str(message.payload))
|
||||
cmd = json.loads(message.payload)
|
||||
except Exception as e:
|
||||
self._logger.error("json.loads failed, Exception: %s", str(e))
|
||||
raise e
|
||||
command = Command()
|
||||
command.convert_from_dict(cmd)
|
||||
if self.__command_listener is not None:
|
||||
self.__command_listener.on_command(request_id, command.service_id, command.command_name,
|
||||
command.paras)
|
||||
else:
|
||||
self._device.on_command(request_id, command)
|
||||
|
||||
def on_rule_command(self, request_id: str, command: Command):
|
||||
if self.__command_listener is not None:
|
||||
self.__command_listener.on_command(request_id, command.service_id, command.command_name, command.paras)
|
||||
return
|
||||
self._logger.warning("command listener was not config for rules.")
|
||||
|
||||
def on_device_shadow(self, message: RawMessage):
|
||||
"""
|
||||
处理平台设备影子数据下发。若当前DeviceClient设置了影子监听器,则执行此命令监听器的on_shadow_get()方法。
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
request_id = get_request_id_from_msg(message)
|
||||
try:
|
||||
payload: dict = json.loads(message.payload)
|
||||
device_id: str = payload.get("object_device_id")
|
||||
shadow_list: List[ShadowData] = list()
|
||||
shadow_dict_list: list = payload.get("shadow")
|
||||
for shadow_dict in shadow_dict_list:
|
||||
shadow = ShadowData()
|
||||
shadow.convert_from_dict(shadow_dict)
|
||||
shadow_list.append(shadow)
|
||||
if self.__shadow_listener is not None:
|
||||
self.__shadow_listener.on_shadow_get(request_id, device_id, shadow_list)
|
||||
else:
|
||||
# 没有设置影子监听器,这里不做处理
|
||||
pass
|
||||
except Exception as e:
|
||||
self._logger.error("handle device shadow failed, Exception: %s", str(e))
|
||||
pass
|
||||
|
||||
def on_properties_set(self, message: RawMessage):
|
||||
"""
|
||||
处理平台设置设备属性。若当前DeviceClient设置了属性监听器,则执行此命令监听器的on_property_set()方法。
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
request_id = get_request_id_from_msg(message)
|
||||
try:
|
||||
self._logger.debug("receive properties_set from platform, topic = %s, msg = %s",
|
||||
message.topic, str(message.payload))
|
||||
payload: dict = json.loads(message.payload)
|
||||
except Exception as e:
|
||||
self._logger.error("json.loads failed, Exception: %s", str(e))
|
||||
raise e
|
||||
prop_set: PropSet = PropSet()
|
||||
service_list: list = payload["services"]
|
||||
service_property_list = [ServiceProperty(service_id=a["service_id"],
|
||||
properties=a["properties"]) for a in service_list]
|
||||
prop_set.services = service_property_list
|
||||
if self.__property_listener is not None:
|
||||
self.__property_listener.on_property_set(request_id, prop_set.services)
|
||||
else:
|
||||
self._device.on_properties_set(request_id, prop_set)
|
||||
|
||||
def on_properties_get(self, message: RawMessage):
|
||||
"""
|
||||
处理平台查询设备属性。若当前DeviceClient设置了属性监听器,则执行此命令监听器的on_property_get()方法。
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
request_id = get_request_id_from_msg(message)
|
||||
try:
|
||||
self._logger.debug("receive properties_get from platform, topic = %s, msg = %s", message.topic,
|
||||
str(message.payload))
|
||||
obj = json.loads(message.payload)
|
||||
except Exception as e:
|
||||
self._logger.error("json.loads failed, Exception: %s", str(e))
|
||||
raise e
|
||||
prop_get = PropsGet()
|
||||
prop_get.convert_from_dict(obj)
|
||||
if self.__property_listener is not None:
|
||||
self.__property_listener.on_property_get(request_id, prop_get.service_id)
|
||||
else:
|
||||
self._device.on_properties_get(request_id, prop_get)
|
||||
|
||||
def on_event(self, message: RawMessage):
|
||||
"""
|
||||
处理平台事件下发
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
try:
|
||||
self._logger.debug("receive events from platform, topic = %s, msg = %s", message.topic,
|
||||
str(message.payload))
|
||||
payload: dict = json.loads(message.payload)
|
||||
except Exception as e:
|
||||
self._logger.error("json.loads failed, Exception: %s", str(e))
|
||||
raise e
|
||||
device_events = DeviceEvents()
|
||||
device_events.convert_from_dict(payload)
|
||||
if not device_events:
|
||||
self._logger.error("device events invalid, payload: %s", str(payload))
|
||||
return
|
||||
self._device.on_event(device_events)
|
||||
|
||||
def on_rule_action_handler(self, action: List[Action]):
|
||||
"""
|
||||
处理端侧规则
|
||||
|
||||
Args:
|
||||
action: 原始数据
|
||||
"""
|
||||
if self.__rule_action_handler is not None:
|
||||
self.__rule_action_handler.handle_rule_action(action)
|
||||
return
|
||||
self._device.on_rule_action_handler(action)
|
||||
|
||||
def on_bootstrap(self, message: RawMessage):
|
||||
"""
|
||||
处理设备发放信息
|
||||
|
||||
Args:
|
||||
message: 原始数据
|
||||
"""
|
||||
try:
|
||||
self._logger.debug("receive bootstrap info from platform, topic = %s, msg = %s", message.topic,
|
||||
str(message.payload))
|
||||
payload: dict = json.loads(message.payload)
|
||||
except Exception as e:
|
||||
self._logger.error("json.loads failed, Exception: %s", str(e))
|
||||
raise e
|
||||
address = str(payload.get("address"))
|
||||
device_secret = payload.get("deviceSecret")
|
||||
self.__connect_auth_info.server_uri = address.split(":")[0]
|
||||
self.__connect_auth_info.port = int(address.split(":")[-1])
|
||||
if device_secret:
|
||||
self.__connect_auth_info.secret = device_secret
|
||||
# 设备发放成功,保存获取的iot平台地址和端口
|
||||
if os.path.exists(self.__SERVER_INFO_PATH):
|
||||
os.remove(self.__SERVER_INFO_PATH)
|
||||
server_info_dict = {self.__SERVER_URI: self.__connect_auth_info.server_uri,
|
||||
self.__PORT: self.__connect_auth_info.port,
|
||||
self.__SECRET: device_secret}
|
||||
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
|
||||
modes = stat.S_IWUSR | stat.S_IRUSR
|
||||
with os.fdopen(os.open(self.__SERVER_INFO_PATH, flags, modes), 'w') as server_info:
|
||||
json.dump(server_info_dict, server_info)
|
||||
self._logger.info("bootstrap success, change server address to %s", address)
|
||||
self.__bs_flag = True
|
||||
|
||||
def respond_properties_get(self, request_id: str, services: List[ServiceProperty],
|
||||
listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
上报读属性响应
|
||||
|
||||
Args:
|
||||
request_id: 请求id,响应的请求id必须和请求的一致
|
||||
services: 设备属性列表
|
||||
listener: 发布监听器
|
||||
"""
|
||||
topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/properties/get/response/request_id=" + request_id
|
||||
service_list = list()
|
||||
for service in services:
|
||||
service_list.append(service.to_dict())
|
||||
try:
|
||||
payload = json.dumps({"services": service_list})
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
|
||||
def respond_properties_set(self, request_id: str, iot_result: IotResult, listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
上报写属性响应
|
||||
|
||||
Args:
|
||||
request_id: 请求id,响应的请求id必须和请求的一致
|
||||
iot_result: 写属性结果
|
||||
listener: 发布监听器
|
||||
"""
|
||||
topic = "$oc/devices/" + self.__connect_auth_info.id + "/sys/properties/set/response/request_id=" + request_id
|
||||
try:
|
||||
payload = json.dumps(iot_result.to_dict())
|
||||
except Exception as e:
|
||||
self._logger.error("json.dumps failed, Exception: %s", str(e))
|
||||
raise e
|
||||
self.publish_raw_message(RawMessage(topic, payload, self.__mqtt_connect_conf.qos), listener)
|
||||
|
||||
def set_raw_device_msg_listener(self, raw_device_msg_listener: RawDeviceMessageListener):
|
||||
"""
|
||||
设置原始消息监听器,用于接收平台下发的消息,消息保持为二进制格式。
|
||||
需要通过IoTDevice的getClient方法获取DeviceClient实例后,调用此方法设置消息监听器
|
||||
|
||||
Args:
|
||||
raw_device_msg_listener: 消息监听器
|
||||
"""
|
||||
if not isinstance(raw_device_msg_listener, RawDeviceMessageListener):
|
||||
self._logger.error("device_msg_listener should be RawDeviceMessageListener type")
|
||||
return
|
||||
self.__raw_device_msg_listener = raw_device_msg_listener
|
||||
|
||||
def set_device_msg_listener(self, device_msg_listener: DeviceMessageListener):
|
||||
"""
|
||||
设置消息监听器,用于接收平台下发的消息。
|
||||
需要通过IoTDevice的getClient方法获取DeviceClient实例后,调用此方法设置消息监听器
|
||||
|
||||
Args:
|
||||
device_msg_listener: 消息监听器
|
||||
"""
|
||||
if not isinstance(device_msg_listener, DeviceMessageListener):
|
||||
self._logger.error("device_msg_listener should be DeviceMessageListener type")
|
||||
return
|
||||
self.__device_msg_listener = device_msg_listener
|
||||
|
||||
def set_properties_listener(self, property_listener: PropertyListener):
|
||||
"""
|
||||
设置属性监听器,用于接收平台下发的属性读写
|
||||
需要通过IoTDevice的getClient方法获取DeviceClient实例后,调用此方法设置消息监听器
|
||||
|
||||
Args:
|
||||
property_listener: 属性监听器
|
||||
"""
|
||||
if not isinstance(property_listener, PropertyListener):
|
||||
self._logger.error("property_listener should be PropertyListener")
|
||||
return
|
||||
self.__property_listener = property_listener
|
||||
|
||||
def set_command_listener(self, command_listener: CommandListener):
|
||||
"""
|
||||
设置命令监听器,用于接收平台下发的命令。
|
||||
需要通过IoTDevice的getClient接口获取DeviceClient实例后,调用此方法设置命令监听器
|
||||
|
||||
Args:
|
||||
command_listener: 命令监听器
|
||||
"""
|
||||
if not isinstance(command_listener, CommandListener):
|
||||
self._logger.error("command_listener should be CommandListener")
|
||||
return
|
||||
self.__command_listener = command_listener
|
||||
|
||||
def set_device_shadow_listener(self, device_shadow_listener: DeviceShadowListener):
|
||||
"""
|
||||
设置影子监听器,用于接收平台下发的设备影子数据
|
||||
需要通过IoTDevice的getClient方法获取DeviceClient实例后,调用此方法设置消息监听器
|
||||
|
||||
Args:
|
||||
device_shadow_listener: 影子监听器
|
||||
"""
|
||||
if not isinstance(device_shadow_listener, DeviceShadowListener):
|
||||
self._logger.error("device_shadow_listener should be DeviceShadowListener")
|
||||
return
|
||||
self.__shadow_listener = device_shadow_listener
|
||||
|
||||
def set_rule_action_handler(self, rule_action_handler: ActionHandler):
|
||||
"""
|
||||
设置端侧规则监听器,用于自定义处理端侧规则
|
||||
需要通过IoTDevice的getClient方法获取DeviceClient实例后,调用此方法设置消息监听器
|
||||
|
||||
Args:
|
||||
rule_action_handler: 端侧规则监听器
|
||||
"""
|
||||
if not isinstance(rule_action_handler, ActionHandler):
|
||||
self._logger.error("rule_action_handler should be ActionHandler")
|
||||
return
|
||||
self.__rule_action_handler = rule_action_handler
|
||||
|
||||
def subscribe_topic(self, topic: str, qos: int, message_listener):
|
||||
"""
|
||||
订阅自定义topic。此接口只能用于订阅自定义topic
|
||||
需要通过IoTDevice的getClient方法获取DeviceClient实例后,调用此方法设置消息监听器
|
||||
|
||||
Args:
|
||||
topic: 自定义topic
|
||||
qos: qos
|
||||
message_listener: 接收自定义消息的监听器
|
||||
"""
|
||||
self.__connection.subscribe_topic(topic, qos)
|
||||
self.__raw_msg_listener_map[topic] = message_listener
|
||||
|
||||
def add_connect_listener(self, connect_listener):
|
||||
"""
|
||||
设置链路监听器,用户接收链路建立和断开事件
|
||||
|
||||
Args:
|
||||
connect_listener: 链路监听器
|
||||
"""
|
||||
self.__connection.add_connect_listener(connect_listener)
|
||||
|
||||
def set_connect_action_listener(self, connect_action_listener):
|
||||
"""
|
||||
设置连接动作监听器,用户接受连接成功或失败的事件
|
||||
|
||||
Args:
|
||||
connect_action_listener: 连接动作监听器
|
||||
"""
|
||||
self.__connection.set_connect_action_listener(connect_action_listener)
|
||||
|
||||
def report_device_info(self, device_info: DeviceBaseInfo, listener: Optional[ActionListener] = None):
|
||||
"""
|
||||
上报设备信息,包括:软件版本,硬件版本以及SDK版本
|
||||
需要通过IoTDevice的getClient方法获取DeviceClient实例后,调用此方法设置消息监听器
|
||||
|
||||
Args:
|
||||
device_info: 设备信息
|
||||
listener: 发布监听器,若不设置监听器则设为None
|
||||
"""
|
||||
device_event = DeviceEvent()
|
||||
device_event.service_id = "$sdk_info"
|
||||
device_event.event_type = "sdk_info_report"
|
||||
device_event.event_time = get_event_time()
|
||||
paras: dict = {"device_sdk_version": self.__SDK_VERSION,
|
||||
"sw_version": device_info.sw_version,
|
||||
"fw_version": device_info.fw_version}
|
||||
device_event.paras = paras
|
||||
self.report_event(device_event, listener)
|
||||
|
||||
def enable_rule_manage(self):
|
||||
return self.__enable_rule_manage
|
BIN
IoT/iot_device_sdk_python/client/device_client.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/device_client.pyc
Normal file
Binary file not shown.
53
IoT/iot_device_sdk_python/client/iot_result.py
Normal file
53
IoT/iot_device_sdk_python/client/iot_result.py
Normal file
@ -0,0 +1,53 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class IotResult:
|
||||
"""
|
||||
处理结果
|
||||
"""
|
||||
def __init__(self, result_code: int, result_desc: str):
|
||||
self._result_code: int = result_code
|
||||
self._result_desc: str = result_desc
|
||||
|
||||
@property
|
||||
def result_code(self):
|
||||
"""
|
||||
结果码,0表示成功,其他为失败
|
||||
"""
|
||||
return self._result_code
|
||||
|
||||
@result_code.setter
|
||||
def result_code(self, value):
|
||||
self._result_code = value
|
||||
|
||||
@property
|
||||
def result_desc(self):
|
||||
"""
|
||||
结果描述
|
||||
"""
|
||||
return self._result_desc
|
||||
|
||||
@result_desc.setter
|
||||
def result_desc(self, value):
|
||||
self._result_desc = value
|
||||
|
||||
def to_dict(self):
|
||||
return {"result_code": self._result_code, "result_desc": self._result_desc}
|
||||
|
||||
|
||||
SUCCESS = IotResult(0, "Success")
|
||||
FAIL = IotResult(1, "Fail")
|
||||
TIMEOUT = IotResult(2, "Timeout")
|
||||
|
BIN
IoT/iot_device_sdk_python/client/iot_result.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/iot_result.pyc
Normal file
Binary file not shown.
BIN
IoT/iot_device_sdk_python/client/listener/__init__.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/listener/__init__.pyc
Normal file
Binary file not shown.
@ -0,0 +1,35 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from abc import abstractmethod, ABCMeta
|
||||
|
||||
|
||||
class CommandListener(metaclass=ABCMeta):
|
||||
"""
|
||||
命令监听器,用于接收平台下发的命令。
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def on_command(self, request_id: str, service_id: str, command_name: str, paras: dict):
|
||||
"""
|
||||
命令处理
|
||||
|
||||
Args:
|
||||
request_id: 请求id
|
||||
service_id: 服务id
|
||||
command_name: 命令名
|
||||
paras: 命令参数
|
||||
"""
|
BIN
IoT/iot_device_sdk_python/client/listener/command_listener.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/listener/command_listener.pyc
Normal file
Binary file not shown.
@ -0,0 +1,36 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import Optional
|
||||
|
||||
from iot_device_sdk_python.transport.action_listener import ActionListener
|
||||
|
||||
|
||||
class DefaultPublishActionListener(ActionListener):
|
||||
"""
|
||||
默认发布监听器,用户可自行实现ActionListener类
|
||||
"""
|
||||
def on_success(self, message: str):
|
||||
"""
|
||||
发布成功
|
||||
"""
|
||||
print(message)
|
||||
|
||||
def on_failure(self, message: str, e: Optional[Exception]):
|
||||
"""
|
||||
发布失败
|
||||
"""
|
||||
print(message)
|
Binary file not shown.
@ -0,0 +1,33 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from abc import abstractmethod, ABCMeta
|
||||
from iot_device_sdk_python.client.request.device_message import DeviceMessage
|
||||
|
||||
|
||||
class DeviceMessageListener(metaclass=ABCMeta):
|
||||
"""
|
||||
设备消息监听器,用于接收平台下发的设备消息
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def on_device_message(self, message: DeviceMessage):
|
||||
"""
|
||||
处理平台下发的设备消息
|
||||
|
||||
Args:
|
||||
message: 设备消息内容
|
||||
"""
|
Binary file not shown.
@ -0,0 +1,37 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from abc import abstractmethod, ABCMeta
|
||||
from typing import List
|
||||
|
||||
from iot_device_sdk_python.client.request.shadow_data import ShadowData
|
||||
|
||||
|
||||
class DeviceShadowListener(metaclass=ABCMeta):
|
||||
"""
|
||||
影子数据下发监听器
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def on_shadow_get(self, request_id: str, object_device_id: str, shadow: List[ShadowData]):
|
||||
"""
|
||||
处理平台下发的设备影子数据
|
||||
|
||||
Args:
|
||||
request_id: 请求id
|
||||
object_device_id: 设备id
|
||||
shadow: 影子数据
|
||||
"""
|
Binary file not shown.
@ -0,0 +1,47 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import List
|
||||
from abc import abstractmethod, ABCMeta
|
||||
|
||||
from iot_device_sdk_python.client.request.service_property import ServiceProperty
|
||||
|
||||
|
||||
class PropertyListener(metaclass=ABCMeta):
|
||||
"""
|
||||
属性监听器,用于接收平台下发的属性读写操作
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def on_property_set(self, request_id: str, services: List[ServiceProperty]):
|
||||
"""
|
||||
处理写属性操作
|
||||
|
||||
Args:
|
||||
request_id: 请求id
|
||||
services: 服务属性列表
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def on_property_get(self, request_id: str, service_id: str):
|
||||
"""
|
||||
处理读属性操作
|
||||
|
||||
Args:
|
||||
request_id: 请求id
|
||||
service_id: 服务id,可选
|
||||
"""
|
||||
|
BIN
IoT/iot_device_sdk_python/client/listener/property_listener.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/listener/property_listener.pyc
Normal file
Binary file not shown.
@ -0,0 +1,35 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from abc import abstractmethod, ABCMeta
|
||||
|
||||
from iot_device_sdk_python.client.request.raw_device_message import RawDeviceMessage
|
||||
|
||||
|
||||
class RawDeviceMessageListener(metaclass=ABCMeta):
|
||||
"""
|
||||
设备消息监听器,用于接收平台下发的设备消息
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def on_raw_device_message(self, message: RawDeviceMessage):
|
||||
"""
|
||||
处理平台下发的设备消息
|
||||
|
||||
Args:
|
||||
message: 设备消息内容
|
||||
"""
|
Binary file not shown.
58
IoT/iot_device_sdk_python/client/mqtt_connect_conf.py
Normal file
58
IoT/iot_device_sdk_python/client/mqtt_connect_conf.py
Normal file
@ -0,0 +1,58 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
|
||||
class MqttConnectConf:
|
||||
"""
|
||||
mqtt 配置
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
""" 保活时间,仅MQTT协议,sdk默认填写120(单位:秒)。可选30~1200(秒)范围 """
|
||||
self._keep_alive_time: int = 120
|
||||
|
||||
""" 客户端qos,0或1,默认为1 """
|
||||
self._qos: int = 1
|
||||
|
||||
""" 连接超时时间 """
|
||||
self._timeout: float = 1.0
|
||||
|
||||
@property
|
||||
def keep_alive_time(self):
|
||||
""" 保活时间,仅MQTT协议,sdk默认填写120(单位:秒)。可选30~1200(秒)范围 """
|
||||
return self._keep_alive_time
|
||||
|
||||
@keep_alive_time.setter
|
||||
def keep_alive_time(self, value):
|
||||
self._keep_alive_time = value
|
||||
|
||||
@property
|
||||
def qos(self):
|
||||
""" 客户端qos,0或1,默认为1 """
|
||||
return self._qos
|
||||
|
||||
@qos.setter
|
||||
def qos(self, value):
|
||||
self._qos = value
|
||||
|
||||
@property
|
||||
def timeout(self):
|
||||
""" 连接超时时间 """
|
||||
return self._timeout
|
||||
|
||||
@timeout.setter
|
||||
def timeout(self, value):
|
||||
self._timeout = value
|
BIN
IoT/iot_device_sdk_python/client/mqtt_connect_conf.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/mqtt_connect_conf.pyc
Normal file
Binary file not shown.
BIN
IoT/iot_device_sdk_python/client/request/__init__.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/__init__.pyc
Normal file
Binary file not shown.
96
IoT/iot_device_sdk_python/client/request/command.py
Normal file
96
IoT/iot_device_sdk_python/client/request/command.py
Normal file
@ -0,0 +1,96 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class Command:
|
||||
"""
|
||||
设备命令
|
||||
"""
|
||||
def __init__(self):
|
||||
self._service_id: str = ""
|
||||
self._command_name: str = ""
|
||||
self._device_id: str = ""
|
||||
self._paras: dict = dict()
|
||||
|
||||
@property
|
||||
def service_id(self):
|
||||
"""
|
||||
设备的服务ID,在设备关联的产品模型中定义
|
||||
"""
|
||||
return self._service_id
|
||||
|
||||
@service_id.setter
|
||||
def service_id(self, value):
|
||||
self._service_id = value
|
||||
|
||||
@property
|
||||
def command_name(self):
|
||||
"""
|
||||
设备命令名称,在设备关联的产品模型中定义
|
||||
"""
|
||||
return self._command_name
|
||||
|
||||
@command_name.setter
|
||||
def command_name(self, value):
|
||||
self._command_name = value
|
||||
|
||||
@property
|
||||
def device_id(self):
|
||||
"""
|
||||
命令对应的目标设备ID,命令下发对应的最终目标设备,没有携带则表示目标设备即topic中指定的设备
|
||||
"""
|
||||
return self._device_id
|
||||
|
||||
@device_id.setter
|
||||
def device_id(self, value):
|
||||
self._device_id = value
|
||||
|
||||
@property
|
||||
def paras(self):
|
||||
"""
|
||||
设备命令的执行参数,具体字段在设备关联的产品模型中定义
|
||||
"""
|
||||
return self._paras
|
||||
|
||||
@paras.setter
|
||||
def paras(self, value):
|
||||
self._paras = value
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
将请求内容放到字典中
|
||||
|
||||
Returns:
|
||||
dict: 字典形式的请求
|
||||
"""
|
||||
return {"service_id": self._service_id,
|
||||
"command_name": self._command_name,
|
||||
"object_device_id": self._device_id,
|
||||
"paras": self._paras}
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["service_id", "command_name", "object_device_id", "paras"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "service_id":
|
||||
self.service_id = json_dict.get(key)
|
||||
elif key == "command_name":
|
||||
self.command_name = json_dict.get(key)
|
||||
elif key == "object_device_id":
|
||||
self.device_id = json_dict.get(key)
|
||||
elif key == "paras":
|
||||
self.paras = json_dict.get(key)
|
||||
else:
|
||||
pass
|
BIN
IoT/iot_device_sdk_python/client/request/command.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/command.pyc
Normal file
Binary file not shown.
101
IoT/iot_device_sdk_python/client/request/command_response.py
Normal file
101
IoT/iot_device_sdk_python/client/request/command_response.py
Normal file
@ -0,0 +1,101 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class CommandRsp:
|
||||
"""
|
||||
命令响应
|
||||
"""
|
||||
def __init__(self):
|
||||
self._result_code: int = 0
|
||||
self._response_name: str = ""
|
||||
self._paras: dict = dict()
|
||||
|
||||
@property
|
||||
def result_code(self):
|
||||
"""
|
||||
标识命令的执行结果,0表示成功,其他表示失败。不带默认认为成功。
|
||||
"""
|
||||
return self._result_code
|
||||
|
||||
@result_code.setter
|
||||
def result_code(self, value):
|
||||
self._result_code = value
|
||||
|
||||
@property
|
||||
def response_name(self):
|
||||
"""
|
||||
命令的响应名称,在设备关联的产品模型中定义
|
||||
"""
|
||||
return self._response_name
|
||||
|
||||
@response_name.setter
|
||||
def response_name(self, value):
|
||||
self._response_name = value
|
||||
|
||||
@property
|
||||
def paras(self):
|
||||
"""
|
||||
命令的响应参数,具体字段在设备关联的产品模型中定义
|
||||
"""
|
||||
return self._paras
|
||||
|
||||
@paras.setter
|
||||
def paras(self, value):
|
||||
self._paras = value
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
将响应内容放到字典中
|
||||
|
||||
Returns:
|
||||
dict: 字典形式的响应
|
||||
"""
|
||||
return {"result_code": self._result_code,
|
||||
"response_name": self._response_name,
|
||||
"paras": self._paras}
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["result_code", "response_name", "paras"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "result_code":
|
||||
self.result_code = json_dict.get(key)
|
||||
elif key == "response_name":
|
||||
self.response_name = json_dict.get(key)
|
||||
elif key == "paras":
|
||||
self.paras = json_dict.get(key)
|
||||
else:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def success_code():
|
||||
"""
|
||||
返回成功的结果码
|
||||
|
||||
Returns:
|
||||
int: 成功的结果码
|
||||
"""
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def fail_code():
|
||||
"""
|
||||
返回失败的结果码
|
||||
|
||||
Returns:
|
||||
int: 失败的结果码
|
||||
"""
|
||||
return -1
|
BIN
IoT/iot_device_sdk_python/client/request/command_response.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/command_response.pyc
Normal file
Binary file not shown.
41
IoT/iot_device_sdk_python/client/request/device_base_info.py
Normal file
41
IoT/iot_device_sdk_python/client/request/device_base_info.py
Normal file
@ -0,0 +1,41 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class DeviceBaseInfo:
|
||||
def __init__(self):
|
||||
self._fw_version: str = ""
|
||||
self._sw_version: str = ""
|
||||
|
||||
@property
|
||||
def fw_version(self):
|
||||
"""
|
||||
固件版本
|
||||
"""
|
||||
return self._fw_version
|
||||
|
||||
@fw_version.setter
|
||||
def fw_version(self, value):
|
||||
self._fw_version = value
|
||||
|
||||
@property
|
||||
def sw_version(self):
|
||||
"""
|
||||
软件版本
|
||||
"""
|
||||
return self._sw_version
|
||||
|
||||
@sw_version.setter
|
||||
def sw_version(self, value):
|
||||
self._sw_version = value
|
BIN
IoT/iot_device_sdk_python/client/request/device_base_info.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/device_base_info.pyc
Normal file
Binary file not shown.
108
IoT/iot_device_sdk_python/client/request/device_event.py
Normal file
108
IoT/iot_device_sdk_python/client/request/device_event.py
Normal file
@ -0,0 +1,108 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class DeviceEvent:
|
||||
"""
|
||||
服务的事件
|
||||
"""
|
||||
def __init__(self):
|
||||
self._service_id: str = ""
|
||||
self._event_type: str = ""
|
||||
self._event_time: str = ""
|
||||
self._event_id: str = ""
|
||||
self._paras: dict = dict()
|
||||
|
||||
@property
|
||||
def service_id(self):
|
||||
"""
|
||||
事件所属的服务
|
||||
"""
|
||||
return self._service_id
|
||||
|
||||
@service_id.setter
|
||||
def service_id(self, value):
|
||||
self._service_id = value
|
||||
|
||||
@property
|
||||
def event_type(self):
|
||||
"""
|
||||
事件类型
|
||||
"""
|
||||
return self._event_type
|
||||
|
||||
@event_type.setter
|
||||
def event_type(self, value):
|
||||
self._event_type = value
|
||||
|
||||
@property
|
||||
def event_time(self):
|
||||
"""
|
||||
事件发生的时间
|
||||
"""
|
||||
return self._event_time
|
||||
|
||||
@event_time.setter
|
||||
def event_time(self, value):
|
||||
self._event_time = value
|
||||
|
||||
@property
|
||||
def event_id(self):
|
||||
"""
|
||||
事件id,通过该参数关联对应的事件请求
|
||||
"""
|
||||
return self._event_id
|
||||
|
||||
@event_id.setter
|
||||
def event_id(self, value):
|
||||
self._event_id = value
|
||||
|
||||
@property
|
||||
def paras(self):
|
||||
"""
|
||||
事件具体的参数
|
||||
"""
|
||||
return self._paras
|
||||
|
||||
@paras.setter
|
||||
def paras(self, value):
|
||||
self._paras = value
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
将请求内容放到字典中
|
||||
|
||||
Returns:
|
||||
dict: 字典形式的请求
|
||||
"""
|
||||
return {"service_id": self._service_id, "event_type": self._event_type, "event_time": self._event_time,
|
||||
"event_id": self._event_id, "paras": self._paras}
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["service_id", "event_type", "event_time", "event_id", "paras"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "service_id":
|
||||
self.service_id = json_dict.get(key)
|
||||
elif key == "event_type":
|
||||
self.event_type = json_dict.get(key)
|
||||
elif key == "event_time":
|
||||
self.event_time = json_dict.get(key)
|
||||
elif key == "event_id":
|
||||
self.event_id = json_dict.get(key)
|
||||
elif key == "paras":
|
||||
self.paras = json_dict.get(key)
|
||||
else:
|
||||
pass
|
BIN
IoT/iot_device_sdk_python/client/request/device_event.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/device_event.pyc
Normal file
Binary file not shown.
78
IoT/iot_device_sdk_python/client/request/device_events.py
Normal file
78
IoT/iot_device_sdk_python/client/request/device_events.py
Normal file
@ -0,0 +1,78 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import List
|
||||
|
||||
from iot_device_sdk_python.client.request.device_event import DeviceEvent
|
||||
|
||||
|
||||
class DeviceEvents:
|
||||
"""
|
||||
设备事件
|
||||
"""
|
||||
def __init__(self):
|
||||
self._device_id: str = ""
|
||||
self._services: List[DeviceEvent] = []
|
||||
|
||||
@property
|
||||
def device_id(self):
|
||||
"""
|
||||
事件对应的最终目标设备,没有携带则表示目标设备即topic中指定的设备
|
||||
"""
|
||||
return self._device_id
|
||||
|
||||
@device_id.setter
|
||||
def device_id(self, value: str):
|
||||
self._device_id = value
|
||||
|
||||
@property
|
||||
def services(self):
|
||||
"""
|
||||
事件服务列表
|
||||
"""
|
||||
return self._services
|
||||
|
||||
@services.setter
|
||||
def services(self, value):
|
||||
self._services = value
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
将请求内容放到字典中
|
||||
|
||||
Returns:
|
||||
dict: 字典形式的请求
|
||||
"""
|
||||
service_list = list()
|
||||
for service in self._services:
|
||||
service_list.append(service.to_dict())
|
||||
return {"object_device_id": self._device_id, "services": service_list}
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["object_device_id", "services"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "object_device_id":
|
||||
self.device_id = json_dict.get(key)
|
||||
elif key == "services":
|
||||
device_event_dict_list = json_dict.get(key)
|
||||
for device_event_dict in device_event_dict_list:
|
||||
device_event = DeviceEvent()
|
||||
device_event.convert_from_dict(device_event_dict)
|
||||
self._services.append(device_event)
|
||||
else:
|
||||
pass
|
BIN
IoT/iot_device_sdk_python/client/request/device_events.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/device_events.pyc
Normal file
Binary file not shown.
94
IoT/iot_device_sdk_python/client/request/device_message.py
Normal file
94
IoT/iot_device_sdk_python/client/request/device_message.py
Normal file
@ -0,0 +1,94 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class DeviceMessage:
|
||||
"""
|
||||
设备消息
|
||||
"""
|
||||
def __init__(self):
|
||||
self._object_device_id: str = ""
|
||||
self._id: str = ""
|
||||
self._name: str = ""
|
||||
self._content: str = ""
|
||||
|
||||
@property
|
||||
def device_id(self):
|
||||
"""
|
||||
消息对应的最终目标设备,没有携带则表示目标设备即topic中指定的设备
|
||||
"""
|
||||
return self._object_device_id
|
||||
|
||||
@device_id.setter
|
||||
def device_id(self, value):
|
||||
self._object_device_id = value
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
消息id,消息的唯一标识
|
||||
"""
|
||||
return self._id
|
||||
|
||||
@id.setter
|
||||
def id(self, value):
|
||||
self._id = value
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
消息名称
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
self._name = value
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
"""
|
||||
消息内容
|
||||
"""
|
||||
return self._content
|
||||
|
||||
@content.setter
|
||||
def content(self, value):
|
||||
self._content = value
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
将请求内容放到字典中
|
||||
|
||||
Returns:
|
||||
dict: 字典形式的请求
|
||||
"""
|
||||
return {"object_device_id": self._object_device_id, "id": self._id, "name": self._name,
|
||||
"content": self._content}
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["object_device_id", "name", "id", "content"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "object_device_id":
|
||||
self.device_id = json_dict.get(key)
|
||||
elif key == "id":
|
||||
self.id = json_dict.get(key)
|
||||
elif key == "name":
|
||||
self.name = json_dict.get(key)
|
||||
elif key == "content":
|
||||
self.content = json_dict.get(key)
|
||||
else:
|
||||
pass
|
BIN
IoT/iot_device_sdk_python/client/request/device_message.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/device_message.pyc
Normal file
Binary file not shown.
53
IoT/iot_device_sdk_python/client/request/properties_data.py
Normal file
53
IoT/iot_device_sdk_python/client/request/properties_data.py
Normal file
@ -0,0 +1,53 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class PropertiesData:
|
||||
"""
|
||||
属性数据
|
||||
"""
|
||||
def __init__(self):
|
||||
self._properties: dict = dict()
|
||||
self._event_time: str = ""
|
||||
|
||||
@property
|
||||
def properties(self):
|
||||
"""
|
||||
设备服务的属性列表,具体字段在设备关联的产品模型里定义,可以设置多个字段
|
||||
"""
|
||||
return self._properties
|
||||
|
||||
@properties.setter
|
||||
def properties(self, value):
|
||||
self._properties = value
|
||||
|
||||
@property
|
||||
def event_time(self):
|
||||
return self._event_time
|
||||
|
||||
@event_time.setter
|
||||
def event_time(self, value):
|
||||
self._event_time = value
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["properties", "event_time"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "properties":
|
||||
self.properties = json_dict.get(key)
|
||||
elif key == "event_time":
|
||||
self.event_time = json_dict.get(key)
|
||||
else:
|
||||
pass
|
BIN
IoT/iot_device_sdk_python/client/request/properties_data.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/properties_data.pyc
Normal file
Binary file not shown.
56
IoT/iot_device_sdk_python/client/request/props_get.py
Normal file
56
IoT/iot_device_sdk_python/client/request/props_get.py
Normal file
@ -0,0 +1,56 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class PropsGet:
|
||||
"""
|
||||
读属性操作
|
||||
"""
|
||||
def __init__(self):
|
||||
self._device_id: str = ""
|
||||
self._service_id: str = ""
|
||||
|
||||
@property
|
||||
def device_id(self):
|
||||
"""
|
||||
命令对应的目标设备ID,命令下发对应的最终目标设备,没有携带则表示目标设备即topic中指定的设备
|
||||
"""
|
||||
return self._device_id
|
||||
|
||||
@device_id.setter
|
||||
def device_id(self, value):
|
||||
self._device_id = value
|
||||
|
||||
@property
|
||||
def service_id(self):
|
||||
"""
|
||||
设备的服务ID,在设备关联的产品模型中定义
|
||||
"""
|
||||
return self._service_id
|
||||
|
||||
@service_id.setter
|
||||
def service_id(self, value):
|
||||
self._service_id = value
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["object_device_id", "service_id"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "object_device_id":
|
||||
self.device_id = json_dict.get(key)
|
||||
elif key == "service_id":
|
||||
self.service_id = json_dict.get(key)
|
||||
else:
|
||||
pass
|
BIN
IoT/iot_device_sdk_python/client/request/props_get.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/props_get.pyc
Normal file
Binary file not shown.
50
IoT/iot_device_sdk_python/client/request/props_set.py
Normal file
50
IoT/iot_device_sdk_python/client/request/props_set.py
Normal file
@ -0,0 +1,50 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import List
|
||||
|
||||
from iot_device_sdk_python.client.request.service_property import ServiceProperty
|
||||
|
||||
|
||||
class PropSet:
|
||||
"""
|
||||
写属性操作
|
||||
"""
|
||||
def __init__(self):
|
||||
self._device_id: str = ""
|
||||
self._services: List[ServiceProperty] = []
|
||||
|
||||
@property
|
||||
def device_id(self):
|
||||
"""
|
||||
命令对应的目标设备ID,命令下发对应的最终目标设备,没有携带则表示目标设备即topic中指定的设备
|
||||
"""
|
||||
return self._device_id
|
||||
|
||||
@device_id.setter
|
||||
def device_id(self, value):
|
||||
self._device_id = value
|
||||
|
||||
@property
|
||||
def services(self):
|
||||
"""
|
||||
设备服务数据列表
|
||||
"""
|
||||
return self._services
|
||||
|
||||
@services.setter
|
||||
def services(self, value):
|
||||
self._services = value
|
BIN
IoT/iot_device_sdk_python/client/request/props_set.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/props_set.pyc
Normal file
Binary file not shown.
@ -0,0 +1,70 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
import json
|
||||
import logging
|
||||
from json import JSONDecodeError
|
||||
|
||||
from iot_device_sdk_python.client.request.device_message import DeviceMessage
|
||||
|
||||
|
||||
class RawDeviceMessage:
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
__SYSTEM_MESSAGE_KEYS = {"name", "id", "content", "object_device_id"}
|
||||
|
||||
"""
|
||||
设备消息
|
||||
"""
|
||||
|
||||
def __init__(self, payload: bytes):
|
||||
self._payload = payload
|
||||
|
||||
@property
|
||||
def payload(self):
|
||||
"""
|
||||
message下发的原始数据
|
||||
"""
|
||||
return self._payload
|
||||
|
||||
@payload.setter
|
||||
def payload(self, payload: bytes):
|
||||
self._payload = payload
|
||||
|
||||
def to_utf8_string(self):
|
||||
""""
|
||||
尝试将原始消息以utf-8格式decode,如无法decode,则raise UnicodeDecodeError
|
||||
"""
|
||||
return self._payload.decode('utf-8')
|
||||
|
||||
def to_device_message(self):
|
||||
try:
|
||||
device_msg_dict = json.loads(self.to_utf8_string())
|
||||
except (JSONDecodeError, UnicodeDecodeError):
|
||||
self._logger.debug("device message is not in system format")
|
||||
return None # can't convert the system format
|
||||
|
||||
if any(map(lambda a: a not in self.__SYSTEM_MESSAGE_KEYS, device_msg_dict.keys())):
|
||||
self._logger.debug("device message is not in system format because contain unexpected keys")
|
||||
return None
|
||||
|
||||
if any(map(lambda a: a is not None and not isinstance(a, str), device_msg_dict.values())):
|
||||
self._logger.debug("device message is not in system format because some values are not str")
|
||||
return None
|
||||
|
||||
device_msg = DeviceMessage()
|
||||
device_msg.convert_from_dict(device_msg_dict)
|
||||
return device_msg
|
BIN
IoT/iot_device_sdk_python/client/request/raw_device_message.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/raw_device_message.pyc
Normal file
Binary file not shown.
83
IoT/iot_device_sdk_python/client/request/service_property.py
Normal file
83
IoT/iot_device_sdk_python/client/request/service_property.py
Normal file
@ -0,0 +1,83 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
class ServiceProperty:
|
||||
"""
|
||||
服务属性
|
||||
"""
|
||||
def __init__(self, service_id: str = "", properties: dict = None, event_time: str = None):
|
||||
self._service_id: str = service_id
|
||||
self._properties: dict = properties
|
||||
self._event_time: str = event_time
|
||||
|
||||
@property
|
||||
def service_id(self):
|
||||
"""
|
||||
设备的服务ID,在设备关联的产品模型中定义
|
||||
"""
|
||||
return self._service_id
|
||||
|
||||
@service_id.setter
|
||||
def service_id(self, value):
|
||||
self._service_id = value
|
||||
|
||||
@property
|
||||
def properties(self):
|
||||
"""
|
||||
属性值,具体字段由设备模型定义
|
||||
"""
|
||||
return self._properties
|
||||
|
||||
@properties.setter
|
||||
def properties(self, value):
|
||||
self._properties = value
|
||||
|
||||
@property
|
||||
def event_time(self):
|
||||
"""
|
||||
设备采集数据UTC时间(格式为毫秒级别:yyyy-MM-dd'T'HH:mm:ss.SSS'Z'),
|
||||
如:20161219T114920Z或者2020-08-12T12:12:12.333Z。
|
||||
|
||||
设备上报数据不带该参数或参数格式错误时,则数据上报时间以平台时间为准。
|
||||
"""
|
||||
return self._event_time
|
||||
|
||||
@event_time.setter
|
||||
def event_time(self, value):
|
||||
self._event_time = value
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
将请求内容放到字典中
|
||||
|
||||
Returns:
|
||||
dict: 字典形式的请求
|
||||
"""
|
||||
return {"service_id": self._service_id, "properties": self._properties, "event_time": self._event_time}
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["service_id", "properties", "event_time"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "service_id":
|
||||
self.service_id = json_dict.get(key)
|
||||
elif key == "properties":
|
||||
self.properties = json_dict.get(key)
|
||||
elif key == "event_time":
|
||||
self.event_time = json_dict.get(key)
|
||||
else:
|
||||
pass
|
||||
|
BIN
IoT/iot_device_sdk_python/client/request/service_property.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/service_property.pyc
Normal file
Binary file not shown.
94
IoT/iot_device_sdk_python/client/request/shadow_data.py
Normal file
94
IoT/iot_device_sdk_python/client/request/shadow_data.py
Normal file
@ -0,0 +1,94 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import Optional
|
||||
|
||||
from iot_device_sdk_python.client.request.properties_data import PropertiesData
|
||||
|
||||
|
||||
class ShadowData:
|
||||
"""
|
||||
影子数据
|
||||
"""
|
||||
def __init__(self):
|
||||
self._service_id: str = ""
|
||||
self._desired: Optional[PropertiesData] = None
|
||||
self._reported: Optional[PropertiesData] = None
|
||||
self._version: Optional[int] = None
|
||||
|
||||
@property
|
||||
def service_id(self):
|
||||
"""
|
||||
服务id
|
||||
"""
|
||||
return self._service_id
|
||||
|
||||
@service_id.setter
|
||||
def service_id(self, value):
|
||||
self._service_id = value
|
||||
|
||||
@property
|
||||
def desired(self):
|
||||
"""
|
||||
设备影子desired区的属性列表
|
||||
"""
|
||||
return self._desired
|
||||
|
||||
@desired.setter
|
||||
def desired(self, value):
|
||||
self._desired = value
|
||||
|
||||
@property
|
||||
def reported(self):
|
||||
"""
|
||||
设备影子reported区的属性列表
|
||||
"""
|
||||
return self._reported
|
||||
|
||||
@reported.setter
|
||||
def reported(self, value):
|
||||
self._reported = value
|
||||
|
||||
@property
|
||||
def version(self):
|
||||
"""
|
||||
设备影子版本信息
|
||||
"""
|
||||
return self._version
|
||||
|
||||
@version.setter
|
||||
def version(self, value):
|
||||
self._version = value
|
||||
|
||||
def convert_from_dict(self, json_dict: dict):
|
||||
json_name = ["service_id", "desired", "reported", "version"]
|
||||
for key in json_dict.keys():
|
||||
if key not in json_name:
|
||||
continue
|
||||
if key == "service_id":
|
||||
self.service_id = json_dict.get(key)
|
||||
elif key == "desired":
|
||||
desired = PropertiesData()
|
||||
desired.convert_from_dict(json_dict.get(key))
|
||||
self.desired = desired
|
||||
elif key == "reported":
|
||||
reported = PropertiesData()
|
||||
reported.convert_from_dict(json_dict.get(key))
|
||||
self.reported = reported
|
||||
elif key == "version":
|
||||
self.version = json_dict.get(key)
|
||||
else:
|
||||
pass
|
BIN
IoT/iot_device_sdk_python/client/request/shadow_data.pyc
Normal file
BIN
IoT/iot_device_sdk_python/client/request/shadow_data.pyc
Normal file
Binary file not shown.
0
IoT/iot_device_sdk_python/devicelog/__init__.py
Normal file
0
IoT/iot_device_sdk_python/devicelog/__init__.py
Normal file
BIN
IoT/iot_device_sdk_python/devicelog/__init__.pyc
Normal file
BIN
IoT/iot_device_sdk_python/devicelog/__init__.pyc
Normal file
Binary file not shown.
137
IoT/iot_device_sdk_python/devicelog/device_log_service.py
Normal file
137
IoT/iot_device_sdk_python/devicelog/device_log_service.py
Normal file
@ -0,0 +1,137 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import Optional
|
||||
import logging
|
||||
import time
|
||||
|
||||
from iot_device_sdk_python.service.abstract_service import AbstractService
|
||||
from iot_device_sdk_python.client.request.device_event import DeviceEvent
|
||||
from iot_device_sdk_python.utils.iot_util import get_event_time
|
||||
|
||||
|
||||
class DeviceLogService(AbstractService):
|
||||
_logger = logging.getLogger(__name__)
|
||||
_LOG_CONFIG = "log_config"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._log_switch = True # 默认为True
|
||||
self._end_time = None
|
||||
self._connect_lost_dict: Optional[dict] = None
|
||||
self._connect_failed_dict: Optional[dict] = None
|
||||
|
||||
def on_event(self, device_event: DeviceEvent):
|
||||
"""
|
||||
设备日志服务的事件处理方法
|
||||
|
||||
Args:
|
||||
device_event: 设备事件
|
||||
"""
|
||||
if device_event.event_type == self._LOG_CONFIG:
|
||||
# 平台下发日志收集通知
|
||||
paras: dict = device_event.paras
|
||||
if "switch" in paras.keys():
|
||||
str_switch = paras.get("switch")
|
||||
else:
|
||||
self._logger.warning("event.paras doesn't contain key: switch. paras: %s", str(paras))
|
||||
return
|
||||
if "end_time" in paras.keys():
|
||||
end_time = paras.get("end_time")
|
||||
self.end_time = end_time
|
||||
else:
|
||||
self._logger.debug("event.paras doesn't contain key: end_time, paras: %s", str(paras))
|
||||
if str_switch == "on":
|
||||
self.log_switch = True
|
||||
elif str_switch == "off":
|
||||
self.log_switch = False
|
||||
|
||||
def report_device_log(self, timestamp: str, log_type: str, content: str):
|
||||
"""
|
||||
设备上报日志内容
|
||||
|
||||
Args:
|
||||
timestamp: 日志产生的时间戳,精确到秒
|
||||
log_type: 日志类型,总共有如下几种:
|
||||
|
||||
DEVICE_STATUS: 设备状态
|
||||
|
||||
DEVICE_PROPERTY: 设备属性
|
||||
|
||||
DEVICE_MESSAGE: 设备消息
|
||||
|
||||
DEVICE_COMMAND: 设备命令
|
||||
content: 日志内容
|
||||
"""
|
||||
device_event = DeviceEvent()
|
||||
device_event.service_id = self.service_id
|
||||
device_event.event_type = "log_report"
|
||||
device_event.event_time = get_event_time()
|
||||
paras: dict = {"timestamp": timestamp,
|
||||
"type": log_type,
|
||||
"content": content}
|
||||
device_event.paras = paras
|
||||
self.get_iot_device().get_client().report_event(device_event)
|
||||
|
||||
def can_report_log(self):
|
||||
"""
|
||||
根据平台上设置的开关和结束时间来判断能否上报日志
|
||||
|
||||
Returns:
|
||||
bool: True为能上报日志;False为不具备上报的条件;
|
||||
"""
|
||||
end_time: str = self.end_time
|
||||
if end_time is not None:
|
||||
end_time = end_time.replace("T", "")
|
||||
end_time = end_time.replace("Z", "")
|
||||
|
||||
current_time = time.strftime("%Y%m%d%H%M%S", time.localtime())
|
||||
|
||||
if self.log_switch and (end_time is None or current_time < end_time):
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def log_switch(self):
|
||||
return self._log_switch
|
||||
|
||||
@log_switch.setter
|
||||
def log_switch(self, value):
|
||||
self._log_switch = value
|
||||
|
||||
@property
|
||||
def end_time(self):
|
||||
return self._end_time
|
||||
|
||||
@end_time.setter
|
||||
def end_time(self, value):
|
||||
self._end_time = value
|
||||
|
||||
@property
|
||||
def connect_lost_dict(self):
|
||||
return self._connect_lost_dict
|
||||
|
||||
@connect_lost_dict.setter
|
||||
def connect_lost_dict(self, value):
|
||||
self._connect_lost_dict = value
|
||||
|
||||
@property
|
||||
def connect_failed_dict(self):
|
||||
return self._connect_failed_dict
|
||||
|
||||
@connect_failed_dict.setter
|
||||
def connect_failed_dict(self, value):
|
||||
self._connect_failed_dict = value
|
BIN
IoT/iot_device_sdk_python/devicelog/device_log_service.pyc
Normal file
BIN
IoT/iot_device_sdk_python/devicelog/device_log_service.pyc
Normal file
Binary file not shown.
BIN
IoT/iot_device_sdk_python/devicelog/listener/__init__.pyc
Normal file
BIN
IoT/iot_device_sdk_python/devicelog/listener/__init__.pyc
Normal file
Binary file not shown.
@ -0,0 +1,64 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from typing import Optional
|
||||
|
||||
from iot_device_sdk_python.transport.connect_action_listener import ConnectActionListener
|
||||
from iot_device_sdk_python.devicelog.device_log_service import DeviceLogService
|
||||
from iot_device_sdk_python.utils.iot_util import get_gmt_timestamp
|
||||
|
||||
|
||||
class DefaultConnActionLogListener(ConnectActionListener):
|
||||
def __init__(self, device_log_service: DeviceLogService):
|
||||
self._device_log_service = device_log_service
|
||||
|
||||
def on_success(self, token: int):
|
||||
"""
|
||||
首次建链成功
|
||||
|
||||
Args:
|
||||
token: 返回token
|
||||
"""
|
||||
# 只有当connect_failed_dict不为空时report一次设备日志,上报建链失败的原因
|
||||
# 若建链成功,这里不上报任何设备日志。因为会与DefaultConnLogListener的connect_complete()上报重复的日志,造成浪费
|
||||
if self._device_log_service.connect_failed_dict is not None:
|
||||
tmp = list(self._device_log_service.connect_failed_dict.keys())
|
||||
timestamp = tmp[0]
|
||||
self._device_log_service.report_device_log(timestamp, "DEVICE_STATUS",
|
||||
self._device_log_service.connect_failed_dict.get(timestamp))
|
||||
|
||||
def on_failure(self, token: int, err: Optional[Exception]):
|
||||
"""
|
||||
首次建链失败
|
||||
|
||||
Args:
|
||||
token: 返回token
|
||||
err: 失败异常
|
||||
"""
|
||||
failed_dict = dict()
|
||||
failed_dict[str(get_gmt_timestamp())] = "connect failed, the reason is " + str(err)
|
||||
self._device_log_service.connect_failed_dict = failed_dict
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -0,0 +1,67 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2023-2024 Huawei Cloud Computing Technology Co., Ltd. All rights reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from iot_device_sdk_python.transport.connect_listener import ConnectListener
|
||||
from iot_device_sdk_python.devicelog.device_log_service import DeviceLogService
|
||||
from iot_device_sdk_python.utils.iot_util import get_gmt_timestamp
|
||||
|
||||
|
||||
class DefaultConnLogListener(ConnectListener):
|
||||
def __init__(self, device_log_service: DeviceLogService):
|
||||
self._device_log_service = device_log_service
|
||||
|
||||
def connection_lost(self, cause: str):
|
||||
"""
|
||||
连接丢失通知
|
||||
|
||||
Args:
|
||||
cause: 连接丢失原因
|
||||
"""
|
||||
lost_dict = dict()
|
||||
str_current_time_millis = str(get_gmt_timestamp())
|
||||
lost_dict[str_current_time_millis] = "connect lost"
|
||||
self._device_log_service.connect_lost_dict = lost_dict
|
||||
|
||||
def connect_complete(self, reconnect: bool, server_uri: str):
|
||||
"""
|
||||
连接成功通知,如果是断链重连的情景,重连成功会上报断链的时间戳
|
||||
|
||||
Args:
|
||||
reconnect: 是否为重连(当前此参数没有作用)
|
||||
server_uri: 服务端地址
|
||||
"""
|
||||
self._device_log_service.report_device_log(str(get_gmt_timestamp()), "DEVICE_STATUS",
|
||||
"connect complete, the uri is " + str(server_uri))
|
||||
if self._device_log_service.connect_lost_dict is not None:
|
||||
key_list = list(self._device_log_service.connect_lost_dict.keys())
|
||||
timestamp = key_list[0]
|
||||
self._device_log_service.report_device_log(timestamp, "DEVICE_STATUS",
|
||||
self._device_log_service.connect_lost_dict.get(timestamp))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
0
IoT/iot_device_sdk_python/filemanager/__init__.py
Normal file
0
IoT/iot_device_sdk_python/filemanager/__init__.py
Normal file
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user