diff --git a/docs/Application_guide/en/README.md b/docs/Application_guide/en/README.md
index f669890cff0709df5f45804d62b5f9593695cf7d..74c5659171fe360891669d0309f5620b0de77835 100644
--- a/docs/Application_guide/en/README.md
+++ b/docs/Application_guide/en/README.md
@@ -102,7 +102,8 @@ QuecPython Application Guide is a guide on how to use the commonly used function
- [Wearable Solution](solutions/Wear/readme.md)
- [Electricity Meter](solutions/electricity-meter/README.md)
- [Tracker Solution](solutions/tracker/README.md)
-
+- [Smart Tracker Solution Based on EG912U](solutions/tracker_box(EG912U)/README.md)
+-
Helios SDK
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/3b5b2ebd-e154-459d-8992-1d4615834b8e.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/3b5b2ebd-e154-459d-8992-1d4615834b8e.png
new file mode 100644
index 0000000000000000000000000000000000000000..0eeac776f428f7cf2e43d4c5d874e45e121655fa
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/3b5b2ebd-e154-459d-8992-1d4615834b8e.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/60eb6249-67ea-40d3-a59b-0612dbc9f308.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/60eb6249-67ea-40d3-a59b-0612dbc9f308.png
new file mode 100644
index 0000000000000000000000000000000000000000..1dc97ed9cb91109dfee0dd3359fd16b9153521be
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/60eb6249-67ea-40d3-a59b-0612dbc9f308.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/860ce14a-e915-4207-9f29-36ac5b1a7a64.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/860ce14a-e915-4207-9f29-36ac5b1a7a64.png
new file mode 100644
index 0000000000000000000000000000000000000000..c084009280e911c36d4c6f5644c13eb04323d7c5
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/860ce14a-e915-4207-9f29-36ac5b1a7a64.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/Qpycom.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/Qpycom.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f6ab07b08ff44df9c62ce85ae8b6d529309739b
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/Qpycom.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/USB.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/USB.png
new file mode 100644
index 0000000000000000000000000000000000000000..575a02096cca25723bdc02123f4fe85bc7f352a8
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/USB.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/add_device.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/add_device.png
new file mode 100644
index 0000000000000000000000000000000000000000..85a199774230e6726fda6c60578e5767e0dde9e1
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/add_device.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/box.jpg b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/box.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..342f04693869f1cfe94e9454550a412eaa1988dc
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/box.jpg differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/box.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/box.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd14bbf7f4e5663c57f91c383f543939b7c76304
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/box.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/device_control_panel.jpg b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/device_control_panel.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d7a9a4317794f7e8580f32e118f227ac7d0af651
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/device_control_panel.jpg differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/device_qr_code.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/device_qr_code.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c0c815ec17cb0d4c97b01cf48bfcc6c436fe354
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/device_qr_code.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/ebb64f59-a7ec-4742-b2f3-40d6e58a0bdf.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/ebb64f59-a7ec-4742-b2f3-40d6e58a0bdf.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4775f003e5b6b7ae0b8666bb412aa7cb5375588
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/ebb64f59-a7ec-4742-b2f3-40d6e58a0bdf.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/f735bcd9b0c85d0aaad96173b315ca73.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/f735bcd9b0c85d0aaad96173b315ca73.png
new file mode 100644
index 0000000000000000000000000000000000000000..cc9bf76734ff4e370391c3d8590b0ab8f80e1984
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/f735bcd9b0c85d0aaad96173b315ca73.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/fw/8915DM_cat1_open_EG912UGLAAR05A01M08_TEST0807.pac b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/fw/8915DM_cat1_open_EG912UGLAAR05A01M08_TEST0807.pac
new file mode 100644
index 0000000000000000000000000000000000000000..a8eadd4e5d4cec2902896391c6e398e8a5ae69ed
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/fw/8915DM_cat1_open_EG912UGLAAR05A01M08_TEST0807.pac differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/gnss_antenna.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/gnss_antenna.png
new file mode 100644
index 0000000000000000000000000000000000000000..2de0a5c5f3cc788e7e13c7b241041c78eefeeb4b
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/gnss_antenna.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/lte_antenna.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/lte_antenna.png
new file mode 100644
index 0000000000000000000000000000000000000000..93c162d804cc63e652af347e676389f1c1ebbba8
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/lte_antenna.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/power_button.PNG b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/power_button.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..6d3edf9428a32b3f44e25b7a6065cd54294a3a47
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/power_button.PNG differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/raspberry_pi_sensor_hat_b_board.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/raspberry_pi_sensor_hat_b_board.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a5667c7435a898e3b22699066d7473681811354
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/raspberry_pi_sensor_hat_b_board.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/saas_location.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/saas_location.png
new file mode 100644
index 0000000000000000000000000000000000000000..d65c4712f7ccf3e7734df53c950afa15d8a84590
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/saas_location.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/saas_login.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/saas_login.png
new file mode 100644
index 0000000000000000000000000000000000000000..f6cefcaf569164ed4f11d9ce56806f29fb03db90
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/saas_login.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/search_device_imei.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/search_device_imei.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c170ca8ffd1df38c7e29db8090a9e3f1a29b559
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/search_device_imei.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/sensor.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/sensor.png
new file mode 100644
index 0000000000000000000000000000000000000000..86608b7c993723d848b8a252001aabac330754c2
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/sensor.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/software.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/software.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b13882e0c6dbac373afc61160b60057a820f3a5
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/software.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/usb-c_sim.jpg b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/usb-c_sim.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..dd28eabadd315ca3f9b98a95a051d715c9e20b30
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/usb-c_sim.jpg differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree.png
new file mode 100644
index 0000000000000000000000000000000000000000..22d335e319d40d96ce5cd28937cc49170575058b
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree0.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree0.png
new file mode 100644
index 0000000000000000000000000000000000000000..04f81ae01a6128c950c48debe2f148e47e23118b
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree0.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree3.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree3.png
new file mode 100644
index 0000000000000000000000000000000000000000..d22cd8ad80c96f51be963c2e4b346f47c10be341
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree3.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree4.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree4.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b5125fed2d20735a3eb3ed8fa160a2b7879f46e
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree4.png differ
diff --git a/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree5.png b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree5.png
new file mode 100644
index 0000000000000000000000000000000000000000..6453e8edbfd01604eb1dc6ab408699b39b8b6c27
Binary files /dev/null and b/docs/Application_guide/en/media/solutions/tracker_box(EG912U)/wonderfree5.png differ
diff --git a/docs/Application_guide/en/sidebar.yaml b/docs/Application_guide/en/sidebar.yaml
index b03850bc7690a91829d5e3f09928fc2292211691..1a572cbf4b82a052cbe2a8feaa8df75207a6bdba 100644
--- a/docs/Application_guide/en/sidebar.yaml
+++ b/docs/Application_guide/en/sidebar.yaml
@@ -346,6 +346,15 @@ items:
file: solutions/tracker/quick_start.md
- label: software design
file: solutions/tracker/software_design.md
+ label: Smart Tracker Solution Based on EG912U
+ file: solutions/tracker_box(EG912U)/README.md
+ items:
+ - label: development resources
+ file: solutions/tracker_box(EG912U)/dev_resources.md
+ - label: quick start
+ file: solutions/tracker_box(EG912U)/quick_start.md
+ - label: software design
+ file: solutions/tracker_box(EG912U)/software_design.md
- label: SensorHub
file: solutions/SensorHub/README.md
items:
diff --git a/docs/Application_guide/en/solutions/README.md b/docs/Application_guide/en/solutions/README.md
index 13186def85e552a4322e2f1060659f12db85cf27..9dd59b17bc29a10ddfe8eecf943542015552cb6e 100644
--- a/docs/Application_guide/en/solutions/README.md
+++ b/docs/Application_guide/en/solutions/README.md
@@ -11,6 +11,7 @@ To facilitate your application development and accelerate your project implement
- [Wearable Solution](./Wear/readme.md)
- [Electricity-Meter solution](./electricity-meter/README.md)
- [Tracker Solution](./tracker/README.md)
+- [Smart Tracker Solution Based on EG912U](solutions/tracker_box(EG912U)/README.md)
- [SensorHub solution](./SensorHub/README.md)
- [DTU based on EG912U](./DTU-EG912U/README.md)
- [Poc](./poc/README.md)
diff --git a/docs/Application_guide/en/solutions/tracker_box(EG912U)/README.md b/docs/Application_guide/en/solutions/tracker_box(EG912U)/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..e3a5cc132205b83659c8cb26f88fdcd21559aaf3
--- /dev/null
+++ b/docs/Application_guide/en/solutions/tracker_box(EG912U)/README.md
@@ -0,0 +1,13 @@
+# Smart Tracker solution based on EG912U
+
+This Acceleronix solution is implemented based on the QuecPython EG912U standard development board and features the following characteristics:
+
+- Provide accurate and high-precision GNSS positioning.
+- Powerful and rich interfaces.
+- Using the python language is convenient for secondary development
+
+
+
+- [Development resources](./dev_resources.md)
+- [Quick start](./quick_start.md)
+- [Software design](./software_design.md)
\ No newline at end of file
diff --git a/docs/Application_guide/en/solutions/tracker_box(EG912U)/dev_resources.md b/docs/Application_guide/en/solutions/tracker_box(EG912U)/dev_resources.md
new file mode 100644
index 0000000000000000000000000000000000000000..059f93bac3ebe2dbcee90b5b394dfef409416d5f
--- /dev/null
+++ b/docs/Application_guide/en/solutions/tracker_box(EG912U)/dev_resources.md
@@ -0,0 +1,33 @@
+# Development resources summary
+
+## Hardware information
+
+ - Finished tracker box
+
+ > - Purchase channel: Contact Quectel staff for purchase
+
+## Software documentation
+
+ - USB driver for QuecPython module [QuecPython_USB_Driver_Win10_ASR](https://developer.quectel.com/wp-content/uploads/2024/09/Quectel_Windows_USB_DriverU_V1.0.19.zip)
+ - [QuecPython 固件](../../media/solutions/tracker_box(EG912U)/fw)
+
+## Development tools
+
+- QPYcom - QuecPython debug tool
+ - version: V3.9.0
+ - Download: [QPYcom](https://developer.quectel.com/wp-content/uploads/2024/09/QPYcom_V3.9.0.zip)
+- VSCode
+ - Download: [VSCode](https://gitee.com/link?target=https%3A%2F%2Fcode.visualstudio.com%2F)
+
+## Source Code
+
+- The steps to obtain the source code from the Github repository are as follows:
+
+```shell
+git clone https://github.com/QuecPython/tracker-box
+cd tracker-box
+git checkout tracker-box-EG912U
+```
+
+[Github Download](https://github.com/QuecPython/tracker-box/archive/refs/heads/tracker-box-EG912U.zip)
+
diff --git a/docs/Application_guide/en/solutions/tracker_box(EG912U)/quick_start.md b/docs/Application_guide/en/solutions/tracker_box(EG912U)/quick_start.md
new file mode 100644
index 0000000000000000000000000000000000000000..0181b80465d9800be6378d3fe8ead047ce9e977c
--- /dev/null
+++ b/docs/Application_guide/en/solutions/tracker_box(EG912U)/quick_start.md
@@ -0,0 +1,100 @@
+# Quick Start
+
+## Hardware preparation
+
+- A Windows computer, recommended for the Win10 system.
+
+- A set of tracker box devices
+
+- Nano SIM card.
+
+
+
+## Environment construction
+
+- Download and install the EG912U series module driver:[QuecPython_USB_Driver_Win10_ASR](https://developer.quectel.com/wp-content/uploads/2024/09/Quectel_Windows_USB_DriverU_V1.0.19.zip)
+
+
+- Download and install [VSCode](https://gitee.com/link?target=https%3A%2F%2Fcode.visualstudio.com%2F)
+- Download and unzip [QPYcom](https://developer.quectel.com/wp-content/uploads/2024/09/QPYcom_V3.9.0.zip)
+- [Download Firmware](../../media/solutions/tracker_box(EG912U)/fw)
+- Download [Source code](https://github.com/QuecPython/tracker-box/archive/refs/heads/tracker-box-EG912U.zip)
+
+## Set up your smart tracker
+
+Follow the steps below to power the smart tracker:
+
+1. Before powering on, insert the nano SIM card (with data service enabled) into the SIM card slot. If you insert the SIM card after powering on, you need to restart the device.
+2. Power on using any of the following methods:
+
+
+- Method 1: Press the power button on the side of the device.
+
+
+
+
+
+- Method 2: Connect the smart tracker to your laptop or power bank using the included USB-C cable, and the device will automatically power on.
+
+3.After startup, the smart tracker will connect to the cellular network and link to the Acceleronix asset management SaaS platform.
+
+## Connect to the asset management SaaS platform
+
+Acceleronix's asset management SaaS platform offers comprehensive solutions for specific industries. It covers the entire business process from the definition of TSL model functions to SaaS platform management and mobile application device control.
+
+This asset management SaaS platform enables users to operate devices and can conduct dynamic analysis of hardware data based on the TSL model. It integrates multiple sensors such as water quality, temperature, humidity, light and carbon dioxide to adapt to different scenarios. The functions include real-time data viewing, historical operation curves, data aggregation, as well as device maps and trajectory playback based on location devices.设备开发
+
+## Device Development
+
+### Power on
+
+After completing the hardware connection work, if a COM port containing the words "Quectel USB" appears in the port list of the computer device manager, it indicates that the computer has successfully booted up.
+
+
+
+### Firmware Package Burning
+
+Refer to [this chapter](https://gitee.com/link?target=https%3A%2F%2Fdeveloper.quectel.com%2Fdoc%2Fquecpython%2FApplication_guide%2Fen%2Fdev-tools%2FQPYcom%2Fqpycom-dw.html%23%E4%B8%8B%E8%BD%BD%E5%9B%BA%E4%BB%B6) Burn the corresponding firmware package to the development board.
+
+### Script Import and Execution
+
+1. Refer to [this chapter](https://gitee.com/link?target=https%3A%2F%2Fdeveloper.quectel.com%2Fdoc%2Fquecpython%2FGetting_started%2Fen%2F4G%2Ffirst_python.html%23Transfer-Files-Between-PC-and-Module) Import all files from the `code` folder in the source code directory into the module file system, as shown in the following figure:
+
+
+
+1. Refer to [this chapter](https://gitee.com/link?target=https%3A%2F%2Fdeveloper.quectel.com%2Fdoc%2Fquecpython%2FGetting_started%2Fen%2F4G%2Ffirst_python.html%23Run-Script) Execute the main program file `_main.py`.
+2. Refer to [this chapter](https://gitee.com/link?target=https%3A%2F%2Fdeveloper.quectel.com%2Fdoc%2Fquecpython%2FGetting_started%2Fen%2F4G%2Ffirst_python.html%23Stop-a-Running-Program) Stop the program from running.
+
+## Business Debugging
+
+### Program Startup
+
+After executing the _main.py script, the program starts running and prints the dialing information, including the dialing status, IP address, DNS server address, device number, etc
+
+
+
+### Data Detection
+
+After starting to run, startup information will be printed.
+
+
+
+### View device location
+
+1. Click **Details** in the device list to open the device details page.
+
+2. Go to the **Location** tab to view LBS location data.
+
+
+
+> Note: The location is updated every 30 minutes. If you need to manually refresh, please click the refresh button in the application control panel, then reload the page to view the updated location.
+
+### View and manage sensor data
+
+1. When the device is online, click on the device in the Wonderfree app to enter the control panel.
+1. View the real-time sensor data and LBS location data of the smart tracker.
+1. If you need to update sensor data or LBS location, click the refresh button in the upper right corner of the control panel.
+
+
+
+
\ No newline at end of file
diff --git a/docs/Application_guide/en/solutions/tracker_box(EG912U)/software_design.md b/docs/Application_guide/en/solutions/tracker_box(EG912U)/software_design.md
new file mode 100644
index 0000000000000000000000000000000000000000..33afa84676ac760e7224a109ae6af408d811195f
--- /dev/null
+++ b/docs/Application_guide/en/solutions/tracker_box(EG912U)/software_design.md
@@ -0,0 +1,439 @@
+# Software Design Explanation
+
+## Software Framework
+
+
+
+## Code Explanation
+
+### Wait for the network to be ready
+
+The `wait_network_ready` class in main.py calculates the maximum number of waiting times by dividing the number of seconds in WAIT_NETWORK_READY_S by the 5-second interval. It returns True if the network is ready, and False if it times out.
+
+```python
+def wait_network_ready():
+ wait_cnt = WAIT_NETWORK_READY_S / 5
+ is_ready = False
+
+ while wait_cnt:
+ lte = dataCall.getInfo(1, 0)
+ if lte[2][0] == 1:
+ is_ready = True
+ break
+
+ utime.sleep(5)
+ wait_cnt -= 1
+
+ return is_ready
+
+```
+
+### Create an application instance
+
+The `create_app` function creates an application instance. Its main functions include: creating an `Application` application object, setting the name and version, initializing the application configuration, loading the configuration file from the specified path, initializing various service modules (such as QTH Client, GNSS Service, Battery Service, etc.), and returning the configured application instance.
+
+```python
+def create_app(name="SimpliKit", version="1.0.0", config_path="/usr/config.json"):
+ _app = Application(name, version)
+ _app.config.init(config_path)
+
+ qth_client.init_app(_app)
+ lbs_service.init_app(_app)
+ gnss_service.init_app(_app)
+ sensor_service.init_app(_app)
+
+ return _app
+```
+
+### LBS Location Service
+
+The `init` method initializes the service and optionally binds to the application instance `app`.
+
+The `load` method starts a thread to run `start_update`, which is used for periodic updates and sending LBS data.
+
+The `read` method retrieves base station information via `net.getCellInfo()` and formats it into a specific string (e.g., `$LBS,...`).
+
+The `start_update` method, when an event is triggered, reads LBS data and attempts to send it to the server; if it fails, it retries or waits. After success, it waits for 300 seconds; otherwise, it retries every 2 seconds.
+
+The `put_lbs` method implements sending LBS data once and exits the loop upon success.
+
+```python
+class LbsService(object):
+
+ def __init__(self, app=None):
+ self.__net = net
+ if app is not None:
+ self.init_app(app)
+
+ def __str__(self):
+ return '{}'.format(type(self).__name__)
+ def init_app(self, app):
+ self.event = app.event
+ app.register('lbs_service', self)
+
+ def load(self):
+ logger.info('loading {} extension, init lbs will take some seconds'.format(self))
+ Thread(target=self.start_update).start()
+
+ def read(self):
+ cell_info = net.getCellInfo()
+ if cell_info != -1 and cell_info[2]:
+ first_tuple = cell_info[2]
+ mcc_decimal = first_tuple[0][2] # Retrieve the decimal MCC (e.g., 1120)
+ #mcc_hex = "{:x}".format(mcc_decimal).upper() # Convert to hexadecimal (e.g., '460')
+
+ lbs_data = "$LBS,{},{},{},{},{},0*69;".format(
+ mcc_decimal,
+ first_tuple[0][3],
+ first_tuple[0][5],
+ first_tuple[0][1],
+ first_tuple[0][7]
+ )
+ return lbs_data
+
+ def read(self):
+ cell_info = net.getCellInfo()
+ if cell_info != -1 and cell_info[2]:
+ first_tuple = cell_info[2]
+ mcc_decimal = first_tuple[0][2] # Retrieve the decimal MCC (e.g., 1120)
+ #mcc_hex = "{:x}".format(mcc_decimal).upper() # Convert to hexadecimal (e.g., '460')
+
+ lbs_data = "$LBS,{},{},{},{},{},0*69;".format(
+ mcc_decimal,
+ first_tuple[0][3],
+ first_tuple[0][5],
+ first_tuple[0][1],
+ first_tuple[0][7]
+ )
+ return lbs_data
+
+ def put_lbs(self):
+ while True:
+ lbs_data = self.read()
+ if lbs_data is None:
+ utime.sleep(2)
+ continue
+
+ for _ in range(3):
+ with CurrentApp().qth_client:
+ if CurrentApp().qth_client.sendLbs(lbs_data):
+ break
+ else:
+ logger.debug("send lbs data to qth server fail, next report will be after 2 seconds")
+ utime.sleep(2)
+ continue
+
+ logger.debug("send LBS data to qth server success")
+ break
+```
+
+### GNSS positioning service
+
+Manage the initialization and state control of GNSS modules Integrate with the application (init_app) Set the location update interval (update_interval)
+
+```python
+class GnssService(object):
+
+ def __init__(self, app=None):
+ self.interval = 300
+ self.__gnss = quecgnss
+
+ if app is not None:
+ self.init_app(app)
+
+ def __str__(self):
+ return '{}'.format(type(self).__name__)
+ def init_app(self, app):
+ self.event = app.event
+ self.gnss_sleep_event = app.gnss_sleep_event
+ self.interval = app.config["SLEEP_INTERVAL_SECONDS"]
+ app.register('gnss_service', self)
+ def load(self):
+ logger.info('loading {} extension, init quecgnss will take some seconds'.format(self))
+ result = self.init()
+ logger.info('{} init gnss res: {}'.format(self, result))
+ if result:
+ Thread(target=self.start_update).start()
+
+ def init(self):
+ if self.__gnss.init() != 0:
+ logger.warn('{} gnss init FAILED'.format(self))
+ return False
+ return True
+ def status(self):
+ # 0 int GNSS模块处于关闭状态
+ # 1 int GNSS模块固件升级中
+ # 2 int GNSS模块定位中,这种模式下即可开始读取GNSS定位数据,定位数据是否有效需要用户获取到定位数据后,解析对应语句来判断,比如判断GNRMC语句的status是 A 还是 V,A 表示定位有效,V表示定位无效。
+ return self.__gnss.get_state()
+
+ def enable(self, flag=True):
+ return self.__gnss.gnssEnable(bool(flag)) == 0
+ def read(self, size=4096):
+ raw = self.__gnss.read(size)
+ if raw != -1:
+ size, data = raw
+ # KHK
+ #logger.debug('gnss read raw {} bytes data:\n{}'.format(size, data))
+ return NmeaDict.load(data)
+ def check_gnss_signal(self, nmea_dict):
+
+ snr_threshold = 15
+ min_sats = 3
+ has_3d_fix = False
+ if "$GNGSA" in nmea_dict:
+ for line in nmea_dict["$GNGSA"]:
+ parts = line.split(",")
+ if len(parts) > 2 and (parts[2] == "3" or parts[2] == "2"):
+ has_3d_fix = True
+ break
+ if not has_3d_fix:
+ return False
+
+ snrs = []
+
+ def extract_snrs(lines):
+ for line in lines:
+ parts = line.split(",")
+ i = 4
+ while i + 3 < len(parts):
+ snr_str = parts[i + 3]
+ if snr_str.isdigit():
+ snrs.append(int(snr_str))
+ i += 4
+ if "$GPGSV" in nmea_dict:
+ extract_snrs(nmea_dict["$GPGSV"])
+
+ if "$GBGSV" in nmea_dict:
+ extract_snrs(nmea_dict["$GBGSV"])
+
+ if "$GAGSV" in nmea_dict:
+ extract_snrs(nmea_dict["$GAGSV"])
+
+ # count satelites with SNR > 15
+ count = 0
+ for snr in snrs:
+ if snr > snr_threshold:
+ count += 1
+ if count >= min_sats:
+ return True
+ return False
+
+ def update_interval(self,interval):
+ ...
+```
+
+### Sensor Data Acquisition
+
+The `SensorService` class in SensorService.py is a service class for managing sensor data acquisition and update, primarily responsible for initializing the I2C channel and multiple sensors (SHTC3, LPS22HB, and TCS34725), and continuously reading temperature, humidity, air pressure, and RGB color values from these sensors. It is also responsible for sending this data to the specified QTH client.
+
+```python
+class SensorService(object):
+
+ def __init__(self, app=None):
+ # i2c channel 0
+ self.i2c_channel0 = I2C(I2C.I2C1, I2C.STANDARD_MODE)
+ # SHTC3
+ self.shtc3 = Shtc3(self.i2c_channel0, SHTC3_SLAVE_ADDR)
+ self.shtc3.init()
+ # LPS22HB
+ self.lps22hb = Lps22hb(self.i2c_channel0, LPS22HB_SLAVE_ADDRESS)
+ self.lps22hb.init()
+ # TCS34725
+ self.tcs34725 = Tcs34725(self.i2c_channel0, TCS34725_SLAVE_ADDR)
+ self.tcs34725.init()
+
+ if app is not None:
+ self.init_app(app)
+
+ def __str__(self):
+ return '{}'.format(type(self).__name__)
+
+ def init_app(self, app):
+ app.register('sensor_service', self)
+
+ def load(self):
+ logger.info('loading {} extension, init sensors will take some seconds'.format(self))
+ Thread(target=self.start_update).start()
+ def get_temp1_and_humi(self):
+ return self.shtc3.getTempAndHumi()
+
+ def get_press_and_temp2(self):
+ return self.lps22hb.getTempAndPressure()
+ def get_rgb888(self):
+ rgb888 = self.tcs34725.getRGBValue()
+ logger.debug("R: {}, G: {}, B: {}".format((rgb888 >> 16) & 0xFF, (rgb888 >> 8) & 0xFF, rgb888 & 0xFF))
+
+ r = (rgb888 >> 16) & 0xFF
+ g = (rgb888 >> 8) & 0xFF
+ b = rgb888 & 0xFF
+ return r, g, b
+ def start_update(self):
+ prev_temp1 = None
+ prev_humi = None
+ prev_press = None
+ prev_temp2 = None
+ prev_rgb888 = None
+
+
+ while True:
+ data = {}
+ try:
+ temp1, humi = self.shtc3.getTempAndHumi()
+ logger.debug("temp1: {:0.2f}, humi: {:0.2f}".format(temp1, humi))
+
+ if prev_temp1 is None or abs(prev_temp1 - temp1) > 1:
+ data.update({3: round(temp1, 2)})
+ prev_temp1 = temp1
+
+ if prev_humi is None or abs(prev_humi - humi) > 1:
+ data.update({4: round(humi, 2)})
+ prev_humi = humi
+ except Exception as e:
+ logger.error("getTempAndHumi error:{}".format(e))
+
+ utime.sleep_ms(100)
+
+ try:
+ press, temp2 = self.lps22hb.getTempAndPressure()
+ logger.debug("press: {:0.2f}, temp2: {:0.2f}".format(press, temp2))
+
+ if prev_temp2 is None or abs(prev_temp2 - temp2) > 1:
+ data.update({5: round(temp2, 2)})
+ prev_temp2 = temp2
+
+ if prev_press is None or abs(prev_press - press) > 1:
+ data.update({6: round(press, 2)})
+ prev_press = press
+
+ except Exception as e:
+ logger.error("getTempAndPressure error:{}".format(e))
+
+ utime.sleep(1)
+
+
+```
+
+
+
+### QTH Platform Client
+
+The `QthClient class` is a client class used for communicating with the QTH (Quantum Technology Hub) platform. It is responsible for initializing, starting, and managing the connection to the QTH platform, as well as handling various events and callbacks from the platform.
+
+```python
+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))
+ # 当使用url下载固件完成,且MCU更新完毕后,需要获取MCU最新的版本信息,并通过setMcuVer进行更新
+ 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))
+
+```
+
diff --git a/docs/Application_guide/zh/README.md b/docs/Application_guide/zh/README.md
index eaf29976b0c61db2c154cd88d341b23b77a30d5c..10b443ab07c8c83cc880f9e3b0297643b446c6c5 100644
--- a/docs/Application_guide/zh/README.md
+++ b/docs/Application_guide/zh/README.md
@@ -92,6 +92,7 @@ QuecPython 开发指南,是对QuecPython常用功能模块如何使用的指
- [可穿戴解决方案](solutions/Wear/readme.md)
- [电表](solutions/electricity-meter/README.md)
- [智能定位器](solutions/tracker/README.md)
+- [基于EG912U的Smart Tracker解决方案](solutions/tracker_box(EG912U)/README.md)
- [公网对讲机](solutions/poc/README.md)
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/3b5b2ebd-e154-459d-8992-1d4615834b8e.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/3b5b2ebd-e154-459d-8992-1d4615834b8e.png
new file mode 100644
index 0000000000000000000000000000000000000000..0eeac776f428f7cf2e43d4c5d874e45e121655fa
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/3b5b2ebd-e154-459d-8992-1d4615834b8e.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/60eb6249-67ea-40d3-a59b-0612dbc9f308.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/60eb6249-67ea-40d3-a59b-0612dbc9f308.png
new file mode 100644
index 0000000000000000000000000000000000000000..1dc97ed9cb91109dfee0dd3359fd16b9153521be
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/60eb6249-67ea-40d3-a59b-0612dbc9f308.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/860ce14a-e915-4207-9f29-36ac5b1a7a64.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/860ce14a-e915-4207-9f29-36ac5b1a7a64.png
new file mode 100644
index 0000000000000000000000000000000000000000..c084009280e911c36d4c6f5644c13eb04323d7c5
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/860ce14a-e915-4207-9f29-36ac5b1a7a64.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/Qpycom.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/Qpycom.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f6ab07b08ff44df9c62ce85ae8b6d529309739b
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/Qpycom.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/USB.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/USB.png
new file mode 100644
index 0000000000000000000000000000000000000000..575a02096cca25723bdc02123f4fe85bc7f352a8
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/USB.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/add_device.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/add_device.png
new file mode 100644
index 0000000000000000000000000000000000000000..85a199774230e6726fda6c60578e5767e0dde9e1
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/add_device.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/box.jpg b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/box.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..342f04693869f1cfe94e9454550a412eaa1988dc
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/box.jpg differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/box.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/box.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd14bbf7f4e5663c57f91c383f543939b7c76304
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/box.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/device_control_panel.jpg b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/device_control_panel.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d7a9a4317794f7e8580f32e118f227ac7d0af651
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/device_control_panel.jpg differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/device_qr_code.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/device_qr_code.png
new file mode 100644
index 0000000000000000000000000000000000000000..8c0c815ec17cb0d4c97b01cf48bfcc6c436fe354
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/device_qr_code.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/ebb64f59-a7ec-4742-b2f3-40d6e58a0bdf.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/ebb64f59-a7ec-4742-b2f3-40d6e58a0bdf.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4775f003e5b6b7ae0b8666bb412aa7cb5375588
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/ebb64f59-a7ec-4742-b2f3-40d6e58a0bdf.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/fw/8915DM_cat1_open_EG912UGLAAR05A01M08_TEST0807.pac b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/fw/8915DM_cat1_open_EG912UGLAAR05A01M08_TEST0807.pac
new file mode 100644
index 0000000000000000000000000000000000000000..a8eadd4e5d4cec2902896391c6e398e8a5ae69ed
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/fw/8915DM_cat1_open_EG912UGLAAR05A01M08_TEST0807.pac differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/gnss_antenna.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/gnss_antenna.png
new file mode 100644
index 0000000000000000000000000000000000000000..2de0a5c5f3cc788e7e13c7b241041c78eefeeb4b
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/gnss_antenna.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/lte_antenna.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/lte_antenna.png
new file mode 100644
index 0000000000000000000000000000000000000000..93c162d804cc63e652af347e676389f1c1ebbba8
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/lte_antenna.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/power_button.PNG b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/power_button.PNG
new file mode 100644
index 0000000000000000000000000000000000000000..6d3edf9428a32b3f44e25b7a6065cd54294a3a47
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/power_button.PNG differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/raspberry_pi_sensor_hat_b_board.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/raspberry_pi_sensor_hat_b_board.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a5667c7435a898e3b22699066d7473681811354
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/raspberry_pi_sensor_hat_b_board.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/saas_location.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/saas_location.png
new file mode 100644
index 0000000000000000000000000000000000000000..d65c4712f7ccf3e7734df53c950afa15d8a84590
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/saas_location.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/saas_login.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/saas_login.png
new file mode 100644
index 0000000000000000000000000000000000000000..f6cefcaf569164ed4f11d9ce56806f29fb03db90
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/saas_login.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/search_device_imei.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/search_device_imei.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c170ca8ffd1df38c7e29db8090a9e3f1a29b559
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/search_device_imei.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/sensor.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/sensor.png
new file mode 100644
index 0000000000000000000000000000000000000000..86608b7c993723d848b8a252001aabac330754c2
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/sensor.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/software.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/software.png
new file mode 100644
index 0000000000000000000000000000000000000000..b7af1fab919a71a1b28a630fadc2b0e894fe18ef
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/software.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/usb-c_sim.jpg b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/usb-c_sim.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..dd28eabadd315ca3f9b98a95a051d715c9e20b30
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/usb-c_sim.jpg differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree.png
new file mode 100644
index 0000000000000000000000000000000000000000..22d335e319d40d96ce5cd28937cc49170575058b
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree0.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree0.png
new file mode 100644
index 0000000000000000000000000000000000000000..04f81ae01a6128c950c48debe2f148e47e23118b
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree0.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree3.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree3.png
new file mode 100644
index 0000000000000000000000000000000000000000..d22cd8ad80c96f51be963c2e4b346f47c10be341
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree3.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree4.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree4.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b5125fed2d20735a3eb3ed8fa160a2b7879f46e
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree4.png differ
diff --git a/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree5.png b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree5.png
new file mode 100644
index 0000000000000000000000000000000000000000..6453e8edbfd01604eb1dc6ab408699b39b8b6c27
Binary files /dev/null and b/docs/Application_guide/zh/media/solutions/tracker_box(EG912U)/wonderfree5.png differ
diff --git a/docs/Application_guide/zh/sidebar.yaml b/docs/Application_guide/zh/sidebar.yaml
index 9b2d2d19339ace5c1d983b9bbbdae2f88526a09a..e2f4322ca402665023870e3a1a79f912a6c84cc7 100644
--- a/docs/Application_guide/zh/sidebar.yaml
+++ b/docs/Application_guide/zh/sidebar.yaml
@@ -349,6 +349,15 @@ items:
file: solutions/tracker/quick_start.md
- label: 软件设计讲解
file: solutions/tracker/software_design.md
+ - label: 基于EG912U的Smart Tracker解决方案
+ file: solutions/tracker_box(EG912U)/README.md
+ items:
+ - label: 开发资源汇总
+ file: solutions/tracker_box(EG912U)/dev_resources.md
+ - label: 快速上手
+ file: solutions/tracker_box(EG912U)/quick_start.md
+ - label: 软件设计讲解
+ file: solutions/tracker_box(EG912U)/software_design.md
- label: SensorHub
file: solutions/SensorHub/README.md
items:
diff --git a/docs/Application_guide/zh/solutions/README.md b/docs/Application_guide/zh/solutions/README.md
index afd35410caf6bc3e1f056dfaaac3e6b54087e87b..092057084968dc6104c36b28c89b1a6d7d8f5ff8 100644
--- a/docs/Application_guide/zh/solutions/README.md
+++ b/docs/Application_guide/zh/solutions/README.md
@@ -11,6 +11,7 @@
- [可穿戴解决方案](./Wear/readme.md)
- [电表解决方案](./electricity-meter/README.md)
- [智能定位器](./tracker/README.md)
+- [基于EG912U的Smart Tracker解决方案](./tracker_box(EG912U)/README.md)
- [SensorHub](./SensorHub/README.md)
- [基于 EG912U 核心版 DTU](./DTU-EG912U/README.md)
- [公网对讲机](./poc/README.md)
diff --git a/docs/Application_guide/zh/solutions/tracker_box(EG912U)/README.md b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ef94715f88c061008662c3c338bb9e7ade156f15
--- /dev/null
+++ b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/README.md
@@ -0,0 +1,15 @@
+# 基于EG912U的Smart Tracker解决方案
+
+该Acceleronix方案基于QuecPython **EG912U** 标准开发板实现,具有以下特性:
+
+- 提供准确的高精度GNSS定位。
+- 强大丰富的接口。
+- 使用python语言,便于二次开发
+
+
+
+------
+
+- [开发资源汇总](./dev_resources.md)
+- [快速上手](quick_start.md)
+- [软件设计讲解](./software_design.md)
\ No newline at end of file
diff --git a/docs/Application_guide/zh/solutions/tracker_box(EG912U)/dev_resources.md b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/dev_resources.md
new file mode 100644
index 0000000000000000000000000000000000000000..82cc1af6cbbd8b342ce1090b84f9ab988c38a6c3
--- /dev/null
+++ b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/dev_resources.md
@@ -0,0 +1,36 @@
+# 开发资源汇总
+
+## 硬件资料
+
+- tracker box成品
+
+ > - 购买渠道:联系移远工作人员购买
+
+## 软件资料
+
+- QuecPython 模块的 USB 驱动:[QuecPython_USB_Driver_Win10_ASR](https://developer.quectel.com/wp-content/uploads/2024/09/Quectel_Windows_USB_DriverU_V1.0.19.zip)
+- [QuecPython 固件](../../media/solutions/tracker_box(EG912U)/fw)。
+
+## 开发工具
+
+- QPYcom - QuecPython 调试工具
+
+ - 版本:V3.9.0
+
+ - 下载 [QPYcom](https://developer.quectel.com/wp-content/uploads/2024/09/QPYcom_V3.9.0.zip)
+
+- VSCode - 代码编辑器
+
+ - 下载 [VSCode](https://code.visualstudio.com/)
+
+## 实验源码
+
+- 版本:v2.0.1
+
+- 从 Github 仓库获取源代码步骤如下:
+
+ ```shell
+ git clone https://github.com/QuecPython/tracker-box
+ cd tracker-box
+ git checkout tracker-box-EG912U
+ ```
diff --git a/docs/Application_guide/zh/solutions/tracker_box(EG912U)/quick_start.md b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/quick_start.md
new file mode 100644
index 0000000000000000000000000000000000000000..d7988a5e0aaadf951556be900b4edcc2719a75fc
--- /dev/null
+++ b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/quick_start.md
@@ -0,0 +1,99 @@
+# 快速上手
+
+## 硬件准备
+
+- Windows电脑一台,建议 `Win10` 系统。
+
+- 一套[EG912U Quecpython 标准开发板](https://developer.quectel.com/doc/quecpython/Dev_board_guide/zh/bg95-evb.html)
+
+- 一张能够正常使用的SIM卡
+
+
+## 环境搭建
+
+- 下载并安装 EG912U 系列模组驱动:[QuecPython_USB_Driver_Win10_ASR](https://developer.quectel.com/wp-content/uploads/2024/09/Quectel_Windows_USB_DriverU_V1.0.19.zip)。
+
+
+- 下载并安装 [VSCode](https://code.visualstudio.com/)。
+- 下载并解压 [QPYCom](https://developer.quectel.com/wp-content/uploads/2024/09/QPYcom_V3.9.0.zip) 工具到电脑的合适位置。
+- 下载[固件包](../../media/solutions/tracker_box(EG912U)/fw)。
+- 下载[实验源码](https://github.com/QuecPython/tracker-box/archive/refs/heads/main.zip)
+
+## 设置您的智能追踪器
+
+按照以下步骤为智能追踪器供电:
+
+1. 开机前,将 nano SIM 卡(需开通数据服务)插入 SIM 卡槽。若开机后插入 SIM 卡,需重启设备。
+2. 通过以下任一方式开机:
+
+
+- 方式 1:按下设备侧面的电源按钮。
+
+
+
+
+
+- 方式 2:使用随附的 USB-C 线缆将智能追踪器连接至笔记本电脑或充电宝,设备将自动开机。
+
+3.开机后,智能追踪器将连接至蜂窝网络并链接到 Acceleronix 资产管理 SaaS 平台。
+
+## 连接至资产管理 SaaS 平台
+
+Acceleronix 开发的资产管理 SaaS 平台为特定行业提供全面解决方案。它涵盖从 TSL 模型功能定义到 SaaS 平台管理及移动应用设备控制的全业务流程。
+
+该资产管理 SaaS 平台支持用户对设备进行操作,可基于 TSL 模型对硬件数据进行动态分析。它集成了水质、温度、湿度、光线、二氧化碳等多种传感器,以适应不同场景。功能包括实时数据查看、历史运行曲线、数据聚合,以及基于位置设备的设备地图与轨迹回放。
+
+## 设备开发
+
+### 开机
+
+完成硬件连接工作后,当PWR,SCK1亮起或电脑设备管理器的端口列表出现包含Quectel USB字样的COM口,表示开机成功
+
+
+
+### 烧录固件包
+
+参考[此章节](https://developer.quectel.com/doc/quecpython/Getting_started/zh/4G/flash_firmware.html),烧录[固件包](https://developer.quectel.com/wp-content/uploads/2024/09/QPY_OCPU_V0003_BG95M3_FW.zip )至开发板。
+
+### 脚本导入与运行
+
+1.参考[此章节](https://developer.quectel.com/doc/quecpython/Getting_started/zh/4G/first_python.html#PC与模组间的文件传输),将源码目录下的code文件夹中的所有文件按原目录结构导入到模组文件系统中,如下图所示
+
+
+
+2.参考[此章节](https://developer.quectel.com/doc/quecpython/Getting_started/zh/4G/first_python.html#执行脚本文件),执行主程序文件_main.py
+
+3.参考[此章节](https://developer.quectel.com/doc/quecpython/Getting_started/zh/4G/first_python.html#停止程序运行),停止程序运行。
+
+## 业务调试
+
+### 程序启动
+
+执行_main.py脚本后,程序开始运行,会打印拨号信息,包括拨号状态、IP地址、DNS服务器地址,设备号等
+
+
+
+### 数据检测
+
+开始运行后会打印启动信息
+
+
+
+### 查看设备位置(LBS)
+
+1. 在设备列表中点击 **详情**,打开设备详情页。
+2. 进入 **位置** 标签页查看 LBS 位置数据。
+
+> **注意**:位置每 30 分钟更新一次。如需手动刷新,请点击应用控制面板中的刷新按钮,然后重新加载页面即可查看更新后的位置。
+
+### 查看和管理传感器数据
+
+1. 当设备在线时,在 Wonderfree 应用中点击设备进入控制面板。
+
+2. 查看智能追踪器的实时传感器数据和 LBS 位置数据。
+
+3. 如需更新传感器数据或 LBS 位置,点击控制面板右上角的刷新按钮
+
+
+
+
\ No newline at end of file
diff --git a/docs/Application_guide/zh/solutions/tracker_box(EG912U)/software_design.md b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/software_design.md
new file mode 100644
index 0000000000000000000000000000000000000000..6e71620372019387bf8a8f0bb7d17bcb6b85b15a
--- /dev/null
+++ b/docs/Application_guide/zh/solutions/tracker_box(EG912U)/software_design.md
@@ -0,0 +1,445 @@
+# 软件设计讲解
+
+## 软件框架
+
+### 软件设计图
+
+
+
+## 代码讲解
+
+### 等待网络就绪
+
+main.py的`wait_network_ready`类是计算最大等待次数(WAIT_NETWORK_READY_S)秒除以5秒间隔。如果网络就绪则返回True,超时则返回False。
+
+```python
+def wait_network_ready():
+ wait_cnt = WAIT_NETWORK_READY_S / 5
+ is_ready = False
+
+ while wait_cnt:
+ lte = dataCall.getInfo(1, 0)
+ if lte[2][0] == 1:
+ is_ready = True
+ break
+
+ utime.sleep(5)
+ wait_cnt -= 1
+
+ return is_ready
+
+```
+
+### 创建应用实例
+
+create_app创建应用实例的函数。主要功能包括:创建Application应用对象,设置名称和版本初始化应用配置,加载指定路径的配置文件初始化各种服务模块(QTH客户端、GNSS服务、电池服务等),返回配置好的应用实例。
+
+```python
+def create_app(name="SimpliKit", version="1.0.0", config_path="/usr/config.json"):
+ _app = Application(name, version)
+ _app.config.init(config_path)
+
+ qth_client.init_app(_app)
+ lbs_service.init_app(_app)
+ gnss_service.init_app(_app)
+ sensor_service.init_app(_app)
+
+ return _app
+```
+
+### LBS定位服务
+
+`init` 方法初始化服务,可选绑定到应用实例 `app`
+
+`load` 方法启动一个线程运行 `start_update`,用于周期性更新和发送LBS数据
+
+`read` 方法通过 `net.getCellInfo()` 获取基站信息,格式化为特定字符串(如 `$LBS,...`)
+
+`start_update` 方法在事件触发时,读取LBS数据并尝试发送到服务器,失败则重试或等待。成功后等待300秒,否则每2秒重试。
+
+`put_lbs` 方法实现单次发送LBS数据,成功后退出循环。
+
+```python
+class LbsService(object):
+
+ def __init__(self, app=None):
+ self.__net = net
+ if app is not None:
+ self.init_app(app)
+
+ def __str__(self):
+ return '{}'.format(type(self).__name__)
+ def init_app(self, app):
+ self.event = app.event
+ app.register('lbs_service', self)
+
+ def load(self):
+ logger.info('loading {} extension, init lbs will take some seconds'.format(self))
+ Thread(target=self.start_update).start()
+
+ def read(self):
+ cell_info = net.getCellInfo()
+ if cell_info != -1 and cell_info[2]:
+ first_tuple = cell_info[2]
+ mcc_decimal = first_tuple[0][2] # Retrieve the decimal MCC (e.g., 1120)
+ #mcc_hex = "{:x}".format(mcc_decimal).upper() # Convert to hexadecimal (e.g., '460')
+
+ lbs_data = "$LBS,{},{},{},{},{},0*69;".format(
+ mcc_decimal,
+ first_tuple[0][3],
+ first_tuple[0][5],
+ first_tuple[0][1],
+ first_tuple[0][7]
+ )
+ return lbs_data
+
+ def read(self):
+ cell_info = net.getCellInfo()
+ if cell_info != -1 and cell_info[2]:
+ first_tuple = cell_info[2]
+ mcc_decimal = first_tuple[0][2] # Retrieve the decimal MCC (e.g., 1120)
+ #mcc_hex = "{:x}".format(mcc_decimal).upper() # Convert to hexadecimal (e.g., '460')
+
+ lbs_data = "$LBS,{},{},{},{},{},0*69;".format(
+ mcc_decimal,
+ first_tuple[0][3],
+ first_tuple[0][5],
+ first_tuple[0][1],
+ first_tuple[0][7]
+ )
+ return lbs_data
+
+ def put_lbs(self):
+ while True:
+ lbs_data = self.read()
+ if lbs_data is None:
+ utime.sleep(2)
+ continue
+
+ for _ in range(3):
+ with CurrentApp().qth_client:
+ if CurrentApp().qth_client.sendLbs(lbs_data):
+ break
+ else:
+ logger.debug("send lbs data to qth server fail, next report will be after 2 seconds")
+ utime.sleep(2)
+ continue
+
+ logger.debug("send LBS data to qth server success")
+ break
+```
+
+### GNSS定位服务
+
+管理GNSS模块的初始化和状态控制
+
+与应用程序集成 (init_app)
+
+设置定位更新间隔 (update_interval)
+
+```python
+class GnssService(object):
+
+ def __init__(self, app=None):
+ self.interval = 300
+ self.__gnss = quecgnss
+
+ if app is not None:
+ self.init_app(app)
+
+ def __str__(self):
+ return '{}'.format(type(self).__name__)
+ def init_app(self, app):
+ self.event = app.event
+ self.gnss_sleep_event = app.gnss_sleep_event
+ self.interval = app.config["SLEEP_INTERVAL_SECONDS"]
+ app.register('gnss_service', self)
+ def load(self):
+ logger.info('loading {} extension, init quecgnss will take some seconds'.format(self))
+ result = self.init()
+ logger.info('{} init gnss res: {}'.format(self, result))
+ if result:
+ Thread(target=self.start_update).start()
+
+ def init(self):
+ if self.__gnss.init() != 0:
+ logger.warn('{} gnss init FAILED'.format(self))
+ return False
+ return True
+ def status(self):
+ # 0 int GNSS模块处于关闭状态
+ # 1 int GNSS模块固件升级中
+ # 2 int GNSS模块定位中,这种模式下即可开始读取GNSS定位数据,定位数据是否有效需要用户获取到定位数据后,解析对应语句来判断,比如判断GNRMC语句的status是 A 还是 V,A 表示定位有效,V表示定位无效。
+ return self.__gnss.get_state()
+
+ def enable(self, flag=True):
+ return self.__gnss.gnssEnable(bool(flag)) == 0
+ def read(self, size=4096):
+ raw = self.__gnss.read(size)
+ if raw != -1:
+ size, data = raw
+ # KHK
+ #logger.debug('gnss read raw {} bytes data:\n{}'.format(size, data))
+ return NmeaDict.load(data)
+ def check_gnss_signal(self, nmea_dict):
+
+ snr_threshold = 15
+ min_sats = 3
+ has_3d_fix = False
+ if "$GNGSA" in nmea_dict:
+ for line in nmea_dict["$GNGSA"]:
+ parts = line.split(",")
+ if len(parts) > 2 and (parts[2] == "3" or parts[2] == "2"):
+ has_3d_fix = True
+ break
+ if not has_3d_fix:
+ return False
+
+ snrs = []
+
+ def extract_snrs(lines):
+ for line in lines:
+ parts = line.split(",")
+ i = 4
+ while i + 3 < len(parts):
+ snr_str = parts[i + 3]
+ if snr_str.isdigit():
+ snrs.append(int(snr_str))
+ i += 4
+ if "$GPGSV" in nmea_dict:
+ extract_snrs(nmea_dict["$GPGSV"])
+
+ if "$GBGSV" in nmea_dict:
+ extract_snrs(nmea_dict["$GBGSV"])
+
+ if "$GAGSV" in nmea_dict:
+ extract_snrs(nmea_dict["$GAGSV"])
+
+ # count satelites with SNR > 15
+ count = 0
+ for snr in snrs:
+ if snr > snr_threshold:
+ count += 1
+ if count >= min_sats:
+ return True
+ return False
+
+ def update_interval(self,interval):
+ ...
+```
+
+### 传感器数据采集
+
+SensorService.py的`SensorService` 类是一个用于管理传感器数据采集和更新的服务类,主要负责初始化 I2C 通道和多个传感器(SHTC3、LPS22HB 和 TCS34725),并持续从这些传感器中读取温度、湿度、气压和 RGB 颜色值。它还负责将这些数据发送到指定的QTH 客户端。
+
+```python
+class SensorService(object):
+
+ def __init__(self, app=None):
+ # i2c channel 0
+ self.i2c_channel0 = I2C(I2C.I2C1, I2C.STANDARD_MODE)
+ # SHTC3
+ self.shtc3 = Shtc3(self.i2c_channel0, SHTC3_SLAVE_ADDR)
+ self.shtc3.init()
+ # LPS22HB
+ self.lps22hb = Lps22hb(self.i2c_channel0, LPS22HB_SLAVE_ADDRESS)
+ self.lps22hb.init()
+ # TCS34725
+ self.tcs34725 = Tcs34725(self.i2c_channel0, TCS34725_SLAVE_ADDR)
+ self.tcs34725.init()
+
+ if app is not None:
+ self.init_app(app)
+
+ def __str__(self):
+ return '{}'.format(type(self).__name__)
+
+ def init_app(self, app):
+ app.register('sensor_service', self)
+
+ def load(self):
+ logger.info('loading {} extension, init sensors will take some seconds'.format(self))
+ Thread(target=self.start_update).start()
+ def get_temp1_and_humi(self):
+ return self.shtc3.getTempAndHumi()
+
+ def get_press_and_temp2(self):
+ return self.lps22hb.getTempAndPressure()
+ def get_rgb888(self):
+ rgb888 = self.tcs34725.getRGBValue()
+ logger.debug("R: {}, G: {}, B: {}".format((rgb888 >> 16) & 0xFF, (rgb888 >> 8) & 0xFF, rgb888 & 0xFF))
+
+ r = (rgb888 >> 16) & 0xFF
+ g = (rgb888 >> 8) & 0xFF
+ b = rgb888 & 0xFF
+ return r, g, b
+ def start_update(self):
+ prev_temp1 = None
+ prev_humi = None
+ prev_press = None
+ prev_temp2 = None
+ prev_rgb888 = None
+
+
+ while True:
+ data = {}
+ try:
+ temp1, humi = self.shtc3.getTempAndHumi()
+ logger.debug("temp1: {:0.2f}, humi: {:0.2f}".format(temp1, humi))
+
+ if prev_temp1 is None or abs(prev_temp1 - temp1) > 1:
+ data.update({3: round(temp1, 2)})
+ prev_temp1 = temp1
+
+ if prev_humi is None or abs(prev_humi - humi) > 1:
+ data.update({4: round(humi, 2)})
+ prev_humi = humi
+ except Exception as e:
+ logger.error("getTempAndHumi error:{}".format(e))
+
+ utime.sleep_ms(100)
+
+ try:
+ press, temp2 = self.lps22hb.getTempAndPressure()
+ logger.debug("press: {:0.2f}, temp2: {:0.2f}".format(press, temp2))
+
+ if prev_temp2 is None or abs(prev_temp2 - temp2) > 1:
+ data.update({5: round(temp2, 2)})
+ prev_temp2 = temp2
+
+ if prev_press is None or abs(prev_press - press) > 1:
+ data.update({6: round(press, 2)})
+ prev_press = press
+
+ except Exception as e:
+ logger.error("getTempAndPressure error:{}".format(e))
+
+ utime.sleep(1)
+
+
+```
+
+
+
+### QTH平台客户端
+
+`QthClient` 类是一个用于与 QTH(Quantum Technology Hub)平台进行通信的客户端类。它负责初始化、启动和管理与 QTH 平台的连接,并处理来自平台的各种事件和回调。
+
+```python
+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))
+ # 当使用url下载固件完成,且MCU更新完毕后,需要获取MCU最新的版本信息,并通过setMcuVer进行更新
+ 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))
+
+```
+