硬件准备
环境搭建
设置您的智能追踪器
按照以下步骤为智能追踪器供电:
- 开机前,将 nano SIM 卡(需开通数据服务)插入 SIM 卡槽。若开机后插入 SIM 卡,需重启设备。
- 通过以下任一方式开机:
3.开机后,智能追踪器将连接至蜂窝网络并链接到 Acceleronix 资产管理 SaaS 平台。
连接至资产管理 SaaS 平台
Acceleronix 开发的资产管理 SaaS 平台为特定行业提供全面解决方案。它涵盖从 TSL 模型功能定义到 SaaS 平台管理及移动应用设备控制的全业务流程。
该资产管理 SaaS 平台支持用户对设备进行操作,可基于 TSL 模型对硬件数据进行动态分析。它集成了水质、温度、湿度、光线、二氧化碳等多种传感器,以适应不同场景。功能包括实时数据查看、历史运行曲线、数据聚合,以及基于位置设备的设备地图与轨迹回放。
设备开发
开机
完成硬件连接工作后,当PWR,SCK1亮起或电脑设备管理器的端口列表出现包含Quectel USB字样的COM口,表示开机成功
/USB.png)
烧录固件包
参考此章节,烧录固件包至开发板。
脚本导入与运行
1.参考此章节,将源码目录下的code文件夹中的所有文件按原目录结构导入到模组文件系统中,如下图所示
/Qpycom.png)
2.参考此章节,执行主程序文件_main.py
3.参考此章节,停止程序运行。
业务调试
程序启动
执行_main.py脚本后,程序开始运行,会打印拨号信息,包括拨号状态、IP地址、DNS服务器地址,设备号等
/860ce14a-e915-4207-9f29-36ac5b1a7a64.png)
数据检测
开始运行后会打印启动信息
/60eb6249-67ea-40d3-a59b-0612dbc9f308.png)
查看设备位置(LBS)
- 在设备列表中点击 详情,打开设备详情页。
- 进入 位置 标签页查看 LBS 位置数据。
/saas_location.png)
注意:位置每 30 分钟更新一次。如需手动刷新,请点击应用控制面板中的刷新按钮,然后重新加载页面即可查看更新后的位置。
查看和管理传感器数据#
- 当设备在线时,在 Wonderfree 应用中点击设备进入控制面板。
- 查看智能追踪器的实时传感器数据和 LBS 位置数据。
- 如需更新传感器数据或 LBS 位置,点击控制面板右上角的刷新按钮
/wonderfree4.png)
/wonderfree5.png)
软件框架
软件设计图
/software.png)
代码讲解
等待网络就绪
main.py的wait_network_ready类是计算最大等待次数(WAIT_NETWORK_READY_S)秒除以5秒间隔。如果网络就绪则返回True,超时则返回False。
创建应用实例#
create_app创建应用实例的函数。主要功能包括:创建Application应用对象,设置名称和版本初始化应用配置,加载指定路径的配置文件初始化各种服务模块(QTH客户端、GNSS服务、电池服务等),返回配置好的应用实例。
LBS定位服务#
init 方法初始化服务,可选绑定到应用实例 app
load 方法启动一个线程运行 start_update,用于周期性更新和发送LBS数据
read 方法通过 net.getCellInfo() 获取基站信息,格式化为特定字符串(如 $LBS,...)
start_update 方法在事件触发时,读取LBS数据并尝试发送到服务器,失败则重试或等待。成功后等待300秒,否则每2秒重试。
put_lbs 方法实现单次发送LBS数据,成功后退出循环。
GNSS定位服务
管理GNSS模块的初始化和状态控制
与应用程序集成 (init_app)
设置定位更新间隔 (update_interval)
传感器数据采集
SensorService.py的SensorService 类是一个用于管理传感器数据采集和更新的服务类,主要负责初始化 I2C 通道和多个传感器(SHTC3、LPS22HB 和 TCS34725),并持续从这些传感器中读取温度、湿度、气压和 RGB 颜色值。它还负责将这些数据发送到指定的QTH 客户端。
QTH平台客户端
QthClient 类是一个用于与 QTH(Quantum Technology Hub)平台进行通信的客户端类。它负责初始化、启动和管理与 QTH 平台的连接,并处理来自平台的各种事件和回调。
logger = getLogger(__name__)
class QthClient(object):
def __init__(self, app=None):
self.opt_lock = Lock()
if app:
self.init_app(app)
def __enter__(self):
self.opt_lock.acquire()
return self
def __exit__(self, *args, **kwargs):
self.opt_lock.release()
def init_app(self, app):
app.register("qth_client", self)
Qth.init()
Qth.setProductInfo(app.config["QTH_PRODUCT_KEY"], app.config["QTH_PRODUCT_SECRET"])
Qth.setServer(app.config["QTH_SERVER"])
Qth.setEventCb(
{
"devEvent": self.eventCallback,
"recvTrans": self.recvTransCallback,
"recvTsl": self.recvTslCallback,
"readTsl": self.readTslCallback,
"readTslServer": self.recvTslServerCallback,
"ota": {
"otaPlan":self.otaPlanCallback,
"fotaResult":self.fotaResultCallback
}
}
)
def load(self):
self.start()
def start(self):
Qth.start()
while not self.isStatusOk():
utime.sleep(3)
def stop(self):
Qth.stop()
def sendTsl(self, mode, value):
return Qth.sendTsl(mode, value)
def isStatusOk(self):
return Qth.state()
def sendLbs(self, lbs_data):
return Qth.sendOutsideLocation(lbs_data)
def sendGnss(self, nmea_data):
return Qth.sendOutsideLocation(nmea_data)
def eventCallback(self, event, result):
logger.info("dev event:{} result:{}".format(event, result))
if(2== event and 0 == result):
Qth.otaRequest()
def recvTransCallback(self, value):
ret =Qth.sendTrans(1, value)
logger.info("recvTrans value:{} ret:{}".format(value, ret))
def recvTslCallback(self, value):
logger.info("recvTsl:{}".format(value))
for cmdId, val in value.items():
logger.info("recvTsl {}:{}".format(cmdId, val))
if cmdId == 8:
CurrentApp().gnss_service.update_interval(val)
CurrentApp().lbs_service.update_interval(val)
def readTslCallback(self, ids, pkgId):
logger.info("readTsl ids:{} pkgId:{}".format(ids, pkgId))
value=dict()
temp1, humi =CurrentApp().sensor_service.get_temp1_and_humi()
press, temp2 = CurrentApp().sensor_service.get_press_and_temp2()
r,g,b = CurrentApp().sensor_service.get_rgb888()
for id in ids:
if 3 == id:
value[3]=temp1
elif 4 == id:
value[4]=humi
elif 5 == id:
value[5]=temp2
elif 6 == id:
value[6]=press
elif 7 == id:
value[7]={1:r, 2:g, 3:b}
Qth.ackTsl(1, value, pkgId)
def recvTslServerCallback(self, serverId, value, pkgId):
logger.info("recvTslServer serverId:{} value:{} pkgId:{}".format(serverId, value, pkgId))
Qth.ackTslServer(1, serverId, value, pkgId)
def otaPlanCallback(self, plans):
logger.info("otaPlan:{}".format(plans))
Qth.otaAction(1)
def fotaResultCallback(self, comp_no, result):
logger.info("fotaResult comp_no:{} result:{}".format(comp_no, result))
def sotaInfoCallback(self, comp_no, version, url, md5, crc):
logger.info("sotaInfo comp_no:{} version:{} url:{} md5:{} crc:{}".format(comp_no, version, url, md5, crc))
Qth.setMcuVer("MCU1", "V1.0.0", self.sotaInfoCallback, self.sotaResultCallback)
def sotaResultCallback(comp_no, result):
logger.info("sotaResult comp_no:{} result:{}".format(comp_no, result))