diff --git a/README.md b/README.md index 9e21605..45debb3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # AIS-140 +[中文](./README_ZH.md) | English + ## Introduction This is based on QuecPython. @@ -25,7 +27,7 @@ def server_cmd(cmd, key, val): Args: cmd(str): SET/GET/CLR. - key(str): + key(str): PIP - Primary Server IP PPT - Primary Server Port SIP - Secondary Server IP @@ -64,8 +66,8 @@ def main(): # Send Health Monitoring Packet hbt_kwargs = {...} - res = ais_client.send_heart_beat(**hbt_kwargs) - print("ais_client.send_heart_beat() %s" % res) + res = ais_client.send_health_monitoring(**hbt_kwargs) + print("ais_client.send_health_monitoring() %s" % res) # Send Location/Alert Information Packet lai_kwargs = {...} @@ -92,8 +94,11 @@ def main(): |-- ais_client_demo.py |-- ais_server_demo.py |-- docs + |-- en + |-- API_Reference.md + |-- zh + |-- API参考手册.md |-- AIS-140 (2016).pdf - |-- VT140-Protocol_V1._20200104.pdf ``` - `code` floder is incloud AIS client codes. @@ -102,7 +107,7 @@ def main(): - `demo` floder is incloud AIS client demo and AIS server demo. - `demo/ais_client_demo.py` is an AIS client demo base on QuecPython. - `demo/ais_server_demo.py` is an AIS server demo base on CPython. -- `docs` floder is incloud AIS-140 protocal documents. +- `docs` floder is incloud AIS-140 protocal documents and API reference. ## How To Use @@ -179,3 +184,27 @@ You can see log `ais_client.send_login() True.` in our QPYcom REPL, than the `Lo **Note:** > You can refer to `demo/ais_client_demo.py` to write client requests that conform to business logic. + +## Usage + +- [API Reference Manual](./docs/en/API_Reference.md) +- [Client Example Code](./demo/ais_client_demo.py) +- [Server Example Code](./demo/ais_server_demo.py) + +## Contribution + +We welcome contributions to improve this project! Please follow these steps to contribute: + +1. Fork the repository. +2. Create a new branch (`git checkout -b feature/your-feature`). +3. Commit your changes (`git commit -m 'Add your feature'`). +4. Push to the branch (`git push origin feature/your-feature`). +5. Open a Pull Request. + +## License + +This project is licensed under the Apache License. See the [LICENSE](./LICENSE) file for details. + +## Support + +If you have any questions or need support, please refer to the [QuecPython documentation](https://python.quectel.com/doc/en) or open an issue in this repository. diff --git a/README_ZH.md b/README_ZH.md new file mode 100644 index 0000000..de36c6d --- /dev/null +++ b/README_ZH.md @@ -0,0 +1,38 @@ +# AIS-140 + +中文 | [English](./README.md) + +## 概述 + +AIS-140,全称 AUTOMOTIVE INDUSTRY STANDARD,汽车行业标准,是印度制定的一套针对车载卫星定位系统的通信协议。该协议主要用于道路车辆的卫星定位设备与后台监控中心之间的数据通讯,支持车辆定位、跟踪、应急救援等功能。它由印度汽车工业标准委员会 (AISC) 制定,印度汽车研究协会(ARAI)发布,是印度智能交通系统(ITS)的重要组成部分。 + +本项目基于 QuecPython 语言开发。 + +目前支持的版本为 AIS-140 (2016)。 + +该库的目的是提供构建车辆位置跟踪和紧急按钮的构建块。 **该库不提供完整的解决方案,因为任何实现都是特定于其预期用途的**。该库中的文档提供了有关如何最好地构建完整解决方案的指导。 + +## 用法 + +- [API 参考手册](./docs/zh/API参考手册.md) +- [用户使用手册](./docs/zh/用户使用手册.md) +- [客户端示例代码](./demo/ais_client_demo.py) +- [服务端示例代码](./demo/ais_server_demo.py) + +## 贡献 + +我们欢迎对本项目的改进做出贡献!请按照以下步骤进行贡献: + +1. Fork 此仓库。 +2. 创建一个新分支(`git checkout -b feature/your-feature`)。 +3. 提交您的更改(`git commit -m 'Add your feature'`)。 +4. 推送到分支(`git push origin feature/your-feature`)。 +5. 打开一个 Pull Request。 + +## 许可证 + +本项目使用 Apache 许可证。详细信息请参阅 [LICENSE](./LICENSE) 文件。 + +## 支持 + +如果您有任何问题或需要支持,请参阅 [QuecPython 文档](https://python.quectel.com/doc) 或在本仓库中打开一个 issue。 diff --git a/code/ais.py b/code/ais.py index e77472b..40df2c2 100644 --- a/code/ais.py +++ b/code/ais.py @@ -434,11 +434,11 @@ def parse(self, msg): msg = msg.encode() return msg - def send_login(self, vender_id, device_name, imei, firmware_version, protocal_version, latitude, + def send_login(self, vender_id, vehicle_reg_no, imei, firmware_version, protocal_version, latitude, latitude_dir, longitude, longtiude_dir): kwgs = { "vender_id": vender_id, - "device_name": device_name, + "vehicle_reg_no": vehicle_reg_no, "imei": imei, "firmware_version": firmware_version, "protocal_version": protocal_version, @@ -447,14 +447,14 @@ def send_login(self, vender_id, device_name, imei, firmware_version, protocal_ve "longitude": longitude, "longtiude_dir": longtiude_dir } - msg = "$,LGN,{vender_id},{device_name},{imei},{firmware_version},{protocal_version}," \ + msg = "$,LGN,{vender_id},{vehicle_reg_no},{imei},{firmware_version},{protocal_version}," \ "{latitude},{latitude_dir},{longitude},{longtiude_dir}*".format(**kwgs) return self.__send_msg(msg) - def send_heart_beat(self, vender_id, firmware_version, imei, battery_percentage, - Low_battery_threshold_value, memory_percentage, - data_update_rate_when_ignition_on, data_update_rate_when_ignition_off, - digital_io_status, analog_io_status): + def send_health_monitoring(self, vender_id, firmware_version, imei, battery_percentage, + Low_battery_threshold_value, memory_percentage, + data_update_rate_when_ignition_on, data_update_rate_when_ignition_off, + digital_io_status, analog_io_status): kwgs = { "vender_id": vender_id, "firmware_version": firmware_version, diff --git a/demo/ais_client_demo.py b/demo/ais_client_demo.py index dd46839..5717544 100644 --- a/demo/ais_client_demo.py +++ b/demo/ais_client_demo.py @@ -70,7 +70,7 @@ def server_cmd(cmd, key, val): # Send Login Packet login_kwargs = { "vender_id": "QUECTEL", - "device_name": "AISTRACKER", + "vehicle_reg_no": "car123456", "imei": modem.getDevImei(), "firmware_version": modem.getDevFwVersion(), "protocal_version": "AIS140", @@ -96,8 +96,8 @@ def server_cmd(cmd, key, val): "digital_io_status": "0001", "analog_io_status": 12.6 } - res = ais_client.send_heart_beat(**hbt_kwargs) - logger.debug("ais_client.send_heart_beat() %s" % res) + res = ais_client.send_health_monitoring(**hbt_kwargs) + logger.debug("ais_client.send_health_monitoring() %s" % res) time.sleep(1) # Send Location/Alert Information Packet @@ -162,7 +162,7 @@ def server_cmd(cmd, key, val): "distance": 12345, "provider": "G", "vehicle_reg_no": "CAR12345", - "reply_number": "" + "reply_number": "NA" } res = ais_client.send_emergency(**meg_kwargs) logger.debug("ais_client.send_emergency() %s" % res) diff --git a/docs/VT140-Protocol_V1.0_20200104.pdf b/docs/VT140-Protocol_V1.0_20200104.pdf deleted file mode 100644 index 0f37ba9..0000000 Binary files a/docs/VT140-Protocol_V1.0_20200104.pdf and /dev/null differ diff --git a/docs/en/API_Reference.md b/docs/en/API_Reference.md new file mode 100644 index 0000000..8079b7f --- /dev/null +++ b/docs/en/API_Reference.md @@ -0,0 +1,413 @@ +# AIS-140 API Reference + +[中文](../zh/API参考手册.md) | English + +This module is based on the TCP/UDP protocol and implements the relevant functions of the AIS-140 protocol client module, including data reporting and instruction reception and analysis functions. + +## AIS-140 Client Module Initialization + +### `AISClient` + +> To initialize the AIS-140 client module, you need to provide the corresponding server IP or domain name, port, connection mode (TCP/UDP), etc. + +```python +from usr.ais import AISClient + +# Init AIS Client. +ais_client = AISClient( + ip="xxx.xxx.xxx.xxx", + port=9000, + method="TCP", + timeout=600, + keep_alive=0 +) +``` + +**Parameter Description:** + +|Parameters|Type|Description| +|:---|:---|:---| +|ip|str|Server IPV4/IPV6 address| +|port|int|Server port number| +|domain|str|Server domain name (this parameter and `ip` can be optionally filled in). If both are filled in, the domain name will be used as the connection address.| +|method|str|Protocol type, `TCP` / `UDP`, default: `TCP`| +|timeout|int|Timeout for receiving server messages, unit: seconds, default: 600| +|keep_alive|int|TCP protocol keep-alive time, unit: minutes, default: 0, range: 0 ~ 120, when it is 0, the TCP keep-alive mechanism is not enabled| + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|obj|AIS-140 client instance object| + +## Set server command callback function + +### `AISClient.set_callback` + +> Used to receive instructions issued by the server to set, query, and clear device configurations. + +```python +def server_cmd(cmd, key, val): + logger.debug("cmd[%s], key[%s], val[%s]" % (cmd, key, val)) + +res = ais_client.set_callback(server_cmd) +``` + +**Callback Parameter Description:** + +|Parameters|Type|Description| +|:---|:---|:---| +|cmd|str|Instruction operation type:
`SET` - Set up
`GET` - Query
`CLR` - Clear| +|key|str|Command identifier:
`PIP` - Primary Server IP (Primary server ip or domain)
`PPT` - Primary Server Port
`SIP` - Secondary Server IP (Secondary server ip or domain)
`SPT` - Secondary Server Port
`EO` - Emergency OFF (Emergency OFF or stop emergency message. Only set is allowed with this key.)
`ED` - Emergency Duration (Emergency timeout duration in minutes.)
`APN` - Network APN (Network access point name)
`SL` - Speed Limit (Speed limit in km/h)
`VN` - Vehicle Registration Number
`UR` - Update Rate (Update duration/data rate in seconds when Vehicle in motion.)
`URE` - Update Rate Emergency (Update duration or data rate in seconds for emergency packet.)
`URH` - Update Rate Health Packet (Update duration or data rate in minutes for health monitoring packet.)
`VID` - Vendor ID
`ODM` - Odometer (This command can be used to reset odometer or set odometer to a value. The value is in kilometers and can be floating point.)| +|val|str|Command identifier value| + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|bool|`True` - Success
`False` - Fail| + +## Connect To Server + +### `AISClient.connect` + +> Establish a TCP/UDP connection with the server. + +```python +# Connect Server +res = ais_client.connect() +``` + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|bool|`True` - Success
`False` - Fail| + +## Disconnect From Server + +### `AISClient.disconnect` + +> Disconnect the TCP/UDP connection from the server. + +```python +# Disconnect Server +res = ais_client.disconnect() +``` + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|bool|`True` - Success
`False` - Fail| + +## Send Login Packet + +### `AISClient.send_login` + +> A login packet is sent to server whenever there is a new TCP connection made by device to server. + +```python +# Send Login Packet +login_kwargs = { + "vender_id": "QUECTEL", + "vehicle_reg_no": "car123456", + "imei": "IMEI", + "firmware_version": "FIRMWARE_VERSION", + "protocal_version": "AIS140", + "latitude": "12.896545", + "latitude_dir": "N", + "longitude": "76.358759", + "longtiude_dir": "E" +} +res = ais_client.send_login(**login_kwargs) +``` + +**Parameter Description:** + +|Parameters|Type|Description| +|:---|:---|:---| +|vender_id|str|Manufacturer's Name| +|vehicle_reg_no|str|Vehicle number on which the device is installed| +|imei|str|IMEI| +|firmware_version|str|Version of the firmware used in the hardware| +|protocal_version|str|Version of the frame format protocol.| +|latitude|str|The current setpoint value of the latitude, upto 6 decimal places| +|latitude_dir|str|N (North) / S (South)| +|longitude|str|The current setpoint value longitude, upto 6 decimal places| +|longitude_dir|str|E (East) / W (West)| + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|bool|`True` - Success
`False` - Fail| + +## Send Health Monitoring Packets + +### `AISClient.send_health_monitoring` + +> This packet defines status or health of device. + +```python +# Send Health Monitoring Packet +hbt_kwargs = { + "vender_id": "QUECTEL", + "firmware_version": "FIRMWARE_VERSION", + "imei": "IMEI", + "battery_percentage": "60%", + "Low_battery_threshold_value": "30%", + "memory_percentage": "30%", + "data_update_rate_when_ignition_on": 10, + "data_update_rate_when_ignition_off": 60, + "digital_io_status": "0001", + "analog_io_status": 12.6 +} +res = ais_client.send_health_monitoring(**hbt_kwargs) +``` + +**Parameter Description:** + +|Parameters|Type|Description| +|:---|:---|:---| +|vender_id|str|Manufacturer's Name| +|firmware_version|str|Version of the firmware used in the hardware| +|imei|str|IMEI| +|battery_percentage|str|Built-in battery percentage| +|Low_battery_threshold_value|str|Low battery alarm threshold percentage| +|memory_percentage|str|Indicates flash memory used in percentage| +|data_update_rate_when_ignition_on|int|ACC ON data upload interval (s)| +|data_update_rate_when_ignition_off|int|ACC OFF data upload interval (s)| +|digital_io_status|str|Digital input status:
0001 (DIN1 = 0,DIN2 = 0,DIN3 = 0,DIN4 = 1)| +|analog_io_status|float|Analog input status (in V)| + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|bool|`True` - Success
`False` - Fail| + +## Send Positioning or Alarm Data Packets + +### `AISClient.send_loction_alert_information` + +> This is a periodic location information packet sent by device to server. + +```python +# Send Location/Alert Information Packet +lai_kwargs = { + "vender_id": "QUECTEL", + "firmware_version": "FIRMWARE_VERSION", + "packet_type": PacketTypes.NormalReport, + "alert_id": AlertID.LocationUpdate, + "packet_status": "L", + "imei": "IMEI", + "vehicle_reg_no": "car123456", + "gps_fix": 1, + "date": "29042024", + "time": "152000", + "latitude": "12.896545", + "latitude_dir": "N", + "longitude": "76.358759", + "longitude_dir": "E", + "speed": 25, + "heading": 135, + "no_of_satellites": 10, + "altitude": 76, + "pdop": 2.5, + "hdop": 1.9, + "operator_name": "QUECTEL", + "ignition": 1, + "main_power_status": 1, + "main_input_voltage": 12.4, + "internal_battery_voltage": 4.2, + "emergency_status": 0, + "temper_alert": "C", + "gsm_strength": 31, + "mcc": 404, + "mnc": 98, + "lac": 123, + "cell_id": 456, + "nmr": "1,2,3,1,2,3,1,2,3,1,2,3", + "digital_input_status": "0000", + "digital_output_status": "00", + "analog_input_1": 6.7, + "analog_input_2": 2.5, + "odometer": 123456, +} +res = ais_client.send_loction_alert_information(**lai_kwargs) +``` + +**Parameter Description:** + +|Parameters|Type|Description| +|:---|:---|:---| +|vender_id|str|Manufacturer's Name| +|firmware_version|str|Version of the firmware used in the hardware| +|packet_type|str|See [`PacketTypes`](#packettypes) enumeration type| +|alert_id|str|See [`AlertID`](#alertid) enumeration type| +|packet_status|str|Status of packet
`L` - Live Packet
`H` - History Packet| +|imei|str|IMEI| +|vehicle_reg_no|str|Mapped Vehicle Registration Number| +|gps_fix|int|GPS Fix information
0 - GPS Invalid
1 - GPS Fix| +|date|str|Date value as per GPS in DDMMYYYY format| +|time|str|Time value as per GPS in HHMMSS format| +|latitude|str|Latitude value upto 6 decimal places| +|latitude_dir|str|N (North) / S (South)| +|longitude|str|Longitude value upto 6 decimal places| +|longitude_dir|str|E (East) / W (West)| +|speed|float|Speed of vehicle upto 1 decimal place in km/h| +|heading|float|Course over ground in degrees| +|no_of_satellites|int|No. of satellite in view for location fix| +|altitude|int|Altitude of device in meters| +|pdop|foat|Positional dilution of precision| +|hdop|float|Horizontal dilution of precision| +|operator_name|str|Name of network operator| +|ignition|int|Status of Ignition
0 - Ignition Off
1 - Ignition On| +|main_power_status|int|Main power status
0 - Vehicle Battery Disconnected
1 - Vehicle Battery Connected| +|main_input_voltage|float|Indicator showing source voltage in Volts (Upto 1 decimal place)| +|internal_battery_voltage|float|Indicator of battery charge in volts (upto 1 decimal place)| +|emergency_status|int|Emergency status
0 - Emergency Off
1 - Emergency On| +|temper_alert|str|Temper alert
`O` - Box open
`C` - Box Closed| +|gsm_strength|int|Value range from 0 – 31| +|mcc|int|Mobile Country Code| +|mnc|int|Mobile Network Code| +|lac|int|Location Area Code| +|cell_id|int|GSM Cell ID| +|nmr|str|NMR (Network Measurement Report)
Cell ID, LAC and Signal Strength of 4 Neighboring cells
Such as: `(CELL ID,LAC,GSM STRENGTH)` * 4| +|digital_input_status|str|Status of 4 Digital Inputs in order:
[DIN3, DIN2, DIN1, DIN0]
0 - Off, 1 - On
Such as: `0001`| +|digital_output_status|str|Status of 2 Digital Outputs in order:
[DOUT1, DOUT0]
0 - Off, 1 - On
Such as: `01`| +|analog_input_1|float|Analog Input 1 voltage in V| +|analog_input_2|float|Analog Input 2 voltage in V| +|odometer|int|Odometer value in m| + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|bool|`True` - Success
`False` - Fail| + +## Send Emergency Alert Packet + +### `AISClient.send_emergency` + +> When SOS button is pressed, device send following emergency packet to server. + +```python +# Send Emergency Packet +meg_kwargs = { + "vender_id": "QUECTEL", + "packet_type": "EMR", + "imei": modem.getDevImei(), + "packet_status": "NM", + "date_time": "18122017124850", + "gps_fix": "A", + "latitude": 12.896545, + "latitude_dir": "N", + "longitude": 76.358759, + "longitude_dir": "E", + "altitude": 123, + "speed": 25, + "distance": 12345, + "provider": "G", + "vehicle_reg_no": "CAR12345", + "reply_number": "NA" +} +res = ais_client.send_emergency(**meg_kwargs) +``` + +**Parameter Description:** + +|Parameters|Type|Description| +|:---|:---|:---| +|vender_id|str|Manufacturer's Name| +|packet_type|str|Emergency Packet type
`EMR` - Emergency Message
`SEM` - Stop Message| +|imei|str|IMEI| +|packet_status|str|Status of packet
`NM` - Normal Packet
`SP` - Stored Packet| +|date_time|str|Date value as per GPS date time per GPS time (DDMMYYYYHHmmss)| +|gps_fix|str|GPS Fix information
`V` - GPS Invalid
`A` - GPS fix| +|latitude|str|Latitude value upto 6 decimal places| +|latitude_dir|str|N (North) / S (South)| +|longitude|str|Longitude value upto 6 decimal places| +|longitude_dir|str|E (East) / W (West)| +|altitude|int|Altitude of device in meters| +|speed|float|Speed of vehicle upto 1 decimal place in km/h| +|distance|int|Distance calculated from previous GPS data| +|provider|str|`G` - Fine GPS
`N` - Coarse GPS or data from Netwrok| +|vehicle_reg_no|str|Vehicle Registration Number| +|reply_number|str|The mobile number to which Test response needs to be sent. If not, fill in `NA`.| + +**Return Value Description:** + +|Type|Description| +|:---|:---| +|bool|`True` - Success
`False` - Fail| + +## Packet Type Enumeration Value + +### PacketTypes + +> Packet type enumeration value, used to send positioning or alarm data packets `send_loction_alert_information` interface `packet_type` parameter. + +```python +from usr.ais import PacketTypes + +PacketTypes.NormalReport +PacketTypes.EmergencyAlert +... +``` + +**Enumeration Value Description:** + +|Enumeration value|Corresponding value|Description| +|:---|:---|:---| +|NormalReport|`NR`|Normal Report| +|EmergencyAlert|`EA`|Emergency Alert| +|TemperAlert|`TA`|Temper Alert| +|HealthPacket|`HP`|Health Packet| +|IgnitionOn|`IN`|Ignition On| +|IgnitionOff|`IF`|Ignition Off| +|VehicleBatteryDisconnected|`BD`|Vehicle Battery Disconnected| +|VehicleBatteryReconnected|`BR`|Vehicle Battery Reconnected| +|InternalBatteryLow|`BL`|Internal Battery Low| +|HarshBreaking|`HB`|Harsh Breaking| +|HarshAcceleration|`HA`|Harsh Acceleration| +|RashTurning|`RT`|Rash Turning| +|SOSEmergencyButtonWireDisconnect|`WD`|SOS Emergency Button Wire Disconnect| +|OverspeedAlert|`OS`|Overspeed Alert| + +## Alarm Identification Enumeration Value + +### AlertID + +> Alarm ID enumeration value, used to send positioning or alarm data packets `send_loction_alert_information` interface `alert_id` parameter. + +```python +from usr.ais import AlertID + +AlertID.LocationUpdate +AlertID.LocationUpdateHistory +... +``` + +**Enumeration Value Description:** + +|Enumeration value|Corresponding value|Description| +|:---|:---|:---| +|LocationUpdate|`01`|Default Message from device| +|LocationUpdateHistory|`02`|If GPRS is not available at time of sending message| +|Mainsoff|`03`|When device is disconnected from vehicle battery| +|LowBattery|`04`|Device internal battery low alert| +|LowBatteryremoved|`05`|Device internal battery ok| +|MainsOn|`06`|Device is reconnected to vehicle battery| +|IgnitionOn|`07`|Vehicle ignition on alert| +|IgnitionOff|`08`|Vehicle Ignition off alert| +|TemperAlert|`09`|Device box open| +|EmergencyOn|`10`|Emergency on alert| +|EmergencyOff|`11`|Emergency off alert| +|OTAAlert|`12`|Parameter change/query alert packet| +|HarshBreaking|`13`|Alert indication a hash break| +|HarshAcceleration|`14`|Alert indicating harsh acceleration| +|RashTurning|`15`|Alert indicating rash turn| +|WireDisconnect|`16`|SOS/Emergency button wire disconnect alert| +|Overspeed|`17`|Alert indicating overspeed| diff --git "a/docs/zh/API\345\217\202\350\200\203\346\211\213\345\206\214.md" "b/docs/zh/API\345\217\202\350\200\203\346\211\213\345\206\214.md" new file mode 100644 index 0000000..9ee3271 --- /dev/null +++ "b/docs/zh/API\345\217\202\350\200\203\346\211\213\345\206\214.md" @@ -0,0 +1,417 @@ +# AIS-140 API 参考手册 + +中文 | [English](../en/API_Reference.md) + +本模块基于 TCP/UDP 协议,实现了 AIS-140 协议客户端模块的相关功能,包含数据上报和指令接收解析功能。 + +## AIS-140 客户端模块初始化 + +### `AISClient` + +> 初始化 AIS-140 客户端模块,需要提供对应服务器IP或域名,端口,连接模式(TCP/UDP)等。 + +```python +from usr.ais import AISClient + +# Init AIS Client. +ais_client = AISClient( + ip="xxx.xxx.xxx.xxx", + port=9000, + method="TCP", + timeout=600, + keep_alive=0 +) +``` + +**参数说明:** + +|参数|类型|说明| +|:---|:---|:---| +|ip|str|对应服务器 IPV4/IPV6 地址| +|port|int|对应服务器端口号| +|domain|str|对应服务器域名(该参数与 `ip` 选填其实中一个即可),如果都填写,则以域名为连接地址| +|method|str|协议类型,`TCP` / `UDP`,默认:`TCP`| +|timeout|int|接收服务器消息超时时间,单位:秒,默认:600| +|keep_alive|int|TCP 协议保活时间,单位:分钟,默认:0,范围:0 ~ 120,当为 0 时,则不开启 TCP 保活机制| + +**返回值说明:** + +|类型|说明| +|:---|:---| +|obj|AIS-140 客户端实例对象| + +## 设置服务器指令回调函数 + +### `AISClient.set_callback` + +> 用于接收服务器下发的指令,设置、查询、清除设备配置。 + +```python +def server_cmd(cmd, key, val): + logger.debug("cmd[%s], key[%s], val[%s]" % (cmd, key, val)) + +res = ais_client.set_callback(server_cmd) +``` + +**回调函数参数说明:** + +|参数|类型|说明| +|:---|:---|:---| +|cmd|str|指令操作类型:
`SET` - 设置
`GET` - 查询
`CLR` - 清除| +|key|str|指令标识:
`PIP` - 主服务器 IP(主服务器IP或域名)
`PPT` - 主服务器端口
`SIP` - 辅助服务器 IP(辅助服务器IP或域名)
`SPT` - 辅助服务器端口
`EO` - 紧急关闭(紧急关闭或停止紧急消息。仅允许使用此键进行设置。)
`ED` - 紧急情况持续时间(紧急超时持续时间以分钟为单位。)
`APN` - 网络 APN(网络接入点名称)
`SL` - 速度限制(速度限制以公里/小时为单位)
`VN` - 车辆登记号码
`UR` - 更新频率(车辆行驶时更新持续时间/数据速率(以秒为单位)。)
`URE` - 报警更新频率(更新紧急数据包的持续时间或数据速率(以秒为单位)。)
`URH` - 健康监控数据包更新频率(健康监控数据包的更新持续时间或数据速率(以分钟为单位)。)
`VID` - 供应商 ID
`ODM` - 设置里程表(该命令可用于重置里程表或将里程表设置为一个值。该值以公里为单位,可以是浮点数。)| +|val|str|指令标识值| + +**注意:** + +服务器下发的指令内容需要根据实际的服务器协议来确认,不同的服务器有不同的业务指令。 + +**返回值说明:** + +|类型|说明| +|:---|:---| +|bool|`True` - 成功
`False` - 失败| + +## 连接服务器 + +### `AISClient.connect` + +> 与服务器建立 TCP/UDP 连接。 + +```python +# 连接服务器 +res = ais_client.connect() +``` + +**返回值说明:** + +|类型|说明| +|:---|:---| +|bool|`True` - 成功
`False` - 失败| + +## 断开服务器连接 + +### `AISClient.disconnect` + +> 与服务器断开 TCP/UDP 连接。 + +```python +# 断开服务器连接 +res = ais_client.disconnect() +``` + +**返回值说明:** + +|类型|说明| +|:---|:---| +|bool|`True` - 成功
`False` - 失败| + +## 发送登录数据包 + +### `AISClient.send_login` + +> 每当设备与服务器建立新的 TCP 连接时,就会向服务器发送登录数据包。 + +```python +# 发送登录数据包 +login_kwargs = { + "vender_id": "QUECTEL", + "vehicle_reg_no": "car123456", + "imei": "IMEI", + "firmware_version": "FIRMWARE_VERSION", + "protocal_version": "AIS140", + "latitude": "12.896545", + "latitude_dir": "N", + "longitude": "76.358759", + "longtiude_dir": "E" +} +res = ais_client.send_login(**login_kwargs) +``` + +**参数说明:** + +|参数|类型|说明| +|:---|:---|:---| +|vender_id|str|供应商 ID| +|vehicle_reg_no|str|车辆登记号| +|imei|str|IMEI| +|firmware_version|str|固件版本| +|protocal_version|str|协议版本| +|latitude|str|纬度,精确到小数点后 6 位| +|latitude_dir|str|纬度方向,N(北)/ S(南)| +|longitude|str|经度,精确到小数点后 6 位| +|longitude_dir|str|经度方向,E(东)/ W(西)| + +**返回值说明:** + +|类型|说明| +|:---|:---| +|bool|`True` - 成功
`False` - 失败| + +## 发送健康监控数据包 + +### `AISClient.send_health_monitoring` + +> 该数据包定义设备的状态或健康状况。 + +```python +# 发送健康监控数据包 +hbt_kwargs = { + "vender_id": "QUECTEL", + "firmware_version": "FIRMWARE_VERSION", + "imei": "IMEI", + "battery_percentage": "60%", + "Low_battery_threshold_value": "30%", + "memory_percentage": "30%", + "data_update_rate_when_ignition_on": 10, + "data_update_rate_when_ignition_off": 60, + "digital_io_status": "0001", + "analog_io_status": 12.6 +} +res = ais_client.send_health_monitoring(**hbt_kwargs) +``` + +**参数说明:** + +|参数|类型|说明| +|:---|:---|:---| +|vender_id|str|供应商 ID| +|firmware_version|str|固件版本| +|imei|str|IMEI| +|battery_percentage|str|电池电量百分比| +|Low_battery_threshold_value|str|低电报警阈值| +|memory_percentage|str|内存使用百分比| +|data_update_rate_when_ignition_on|int|设备点火时数据上报周期,单位:秒| +|data_update_rate_when_ignition_off|int|设备熄火时数据上报周期,单位:秒| +|digital_io_status|str|数字输入状态:
0001 (DIN1 = 0,DIN2 = 0,DIN3 = 0,DIN4 = 1)| +|analog_io_status|float|输入电压值,单位:伏特| + +**返回值说明:** + +|类型|说明| +|:---|:---| +|bool|`True` - 成功
`False` - 失败| + +## 发送定位或报警数据包 + +### `AISClient.send_loction_alert_information` + +> 这是设备向服务器周期性发送的位置信息包。 + +```python +# 发送定位或报警数据包 +lai_kwargs = { + "vender_id": "QUECTEL", + "firmware_version": "FIRMWARE_VERSION", + "packet_type": PacketTypes.NormalReport, + "alert_id": AlertID.LocationUpdate, + "packet_status": "L", + "imei": "IMEI", + "vehicle_reg_no": "car123456", + "gps_fix": 1, + "date": "29042024", + "time": "152000", + "latitude": "12.896545", + "latitude_dir": "N", + "longitude": "76.358759", + "longitude_dir": "E", + "speed": 25, + "heading": 135, + "no_of_satellites": 10, + "altitude": 76, + "pdop": 2.5, + "hdop": 1.9, + "operator_name": "QUECTEL", + "ignition": 1, + "main_power_status": 1, + "main_input_voltage": 12.4, + "internal_battery_voltage": 4.2, + "emergency_status": 0, + "temper_alert": "C", + "gsm_strength": 31, + "mcc": 404, + "mnc": 98, + "lac": 123, + "cell_id": 456, + "nmr": "1,2,3,1,2,3,1,2,3,1,2,3", + "digital_input_status": "0000", + "digital_output_status": "00", + "analog_input_1": 6.7, + "analog_input_2": 2.5, + "odometer": 123456, +} +res = ais_client.send_loction_alert_information(**lai_kwargs) +``` + +**参数说明:** + +|参数|类型|说明| +|:---|:---|:---| +|vender_id|str|供应商 ID| +|firmware_version|str|固件版本| +|packet_type|str|详见 [`PacketTypes`](#packettypes) 枚举类型| +|alert_id|str|详见 [`AlertID`](#alertid) 枚举类型| +|packet_status|str|包状态
`L` - 实时数据包
`H` - 历史数据包| +|imei|str|IMEI| +|vehicle_reg_no|str|车辆登记号| +|gps_fix|int|GPS 数据是否有效
0 - 无效
1 - 有效| +|date|str|GPS 日期数据,数据格式:DDMMYYYY(日月年)| +|time|str|GPS 时间数据,数据格式:hhmmss(时分秒)| +|latitude|str|纬度,精确到小数点后 6 位| +|latitude_dir|str|纬度方向,N(北)/ S(南)| +|longitude|str|经度,精确到小数点后 6 位| +|longitude_dir|str|经度方向,E(东)/ W(西)| +|speed|float|车辆速度,单位:公里/小时(精确至小数点后 1 位)| +|heading|float|地面航向,单位:度| +|no_of_satellites|int|用于定位的可见卫星数量| +|altitude|int|设备的海拔高度,单位:米| +|pdop|foat|位置精度稀释| +|hdop|float|水平精度衰减| +|operator_name|str|网络运营商名称| +|ignition|int|点火状态
0 - 熄火
1 - 点火| +|main_power_status|int|主电源状态
0 - 车辆电池断开
1 - 车辆电池连接| +|main_input_voltage|float|显示源电压的指示器,单位:伏特(精确到小数点后 1 位)| +|internal_battery_voltage|float|电池电量指示器,单位:伏特(精确到小数点后 1 位)| +|emergency_status|int|报警状态
0 - 报警关
1 - 报警开| +|temper_alert|str|防拆报警
`O` - 盒子打开
`C` - 盒子关闭| +|gsm_strength|int|GSM信号强度,范围 0 ~ 31| +|mcc|int|移动国家代码| +|mnc|int|移动网络代码| +|lac|int|位置区域码| +|cell_id|int|GSM 小区 ID| +|nmr|str|网络测量报告(Network Measurement Report)
4 个相邻小区的小区 ID、LAC 和信号强度
如:`(CELL ID,LAC,GSM STRENGTH)` * 4| +|digital_input_status|str|4 个数字输入的状态(按顺序):
[DIN3,DIN2,DIN1,DIN0]
0 - 关闭,1 - 开启
如:`0001`| +|digital_output_status|str|2 个数字输入的状态(按顺序):
[DOUT1,DOUT0]
0 - 关闭,1 - 开启
如:`01`| +|analog_input_1|float|模拟输入 1 电压,单位:伏特(精确到小数点后 1 位)| +|analog_input_2|float|模拟输入 2 电压,单位:伏特(精确到小数点后 1 位)| +|odometer|int|里程表值,单位:米| + +**返回值说明:** + +|类型|说明| +|:---|:---| +|bool|`True` - 成功
`False` - 失败| + +## 发送紧急报警数据包 + +### `AISClient.send_emergency` + +> 当设备紧急按键被触发时,则开始上报该紧急报警数据包 + +```python +# 发送紧急报警数据包 +meg_kwargs = { + "vender_id": "QUECTEL", + "packet_type": "EMR", + "imei": modem.getDevImei(), + "packet_status": "NM", + "date_time": "18122017124850", + "gps_fix": "A", + "latitude": 12.896545, + "latitude_dir": "N", + "longitude": 76.358759, + "longitude_dir": "E", + "altitude": 123, + "speed": 25, + "distance": 12345, + "provider": "G", + "vehicle_reg_no": "CAR12345", + "reply_number": "NA" +} +res = ais_client.send_emergency(**meg_kwargs) +``` + +**参数说明:** + +|参数|类型|说明| +|:---|:---|:---| +|vender_id|str|供应商 ID| +|packet_type|str|紧急数据包类型
`EMR` - 紧急呼救信号
`SEM` - 停止讯息| +|imei|str|IMEI| +|packet_status|str|数据包状态
`NM` - 普通数据包
`SP` - 存储数据包| +|date_time|str|GPS 日期时间值,数据格式:DDMMYYYYHHmmss(日月年时分秒)| +|gps_fix|str|GPS 数据是否有效
`V` - 无效
`A` - 有效| +|latitude|str|纬度,精确到小数点后 6 位| +|latitude_dir|str|纬度方向,N(北)/ S(南)| +|longitude|str|经度,精确到小数点后 6 位| +|longitude_dir|str|经度方向,E(东)/ W(西)| +|altitude|int|设备的海拔高度,单位:米| +|speed|float|车辆速度,单位:公里/小时(精确至小数点后 1 位)| +|distance|int|根据之前的 GPS 数据计算出的距离| +|provider|str|`G` - 来自 GPS 精确定位
`N` - 粗略 GPS 或 基站定位数据| +|vehicle_reg_no|str|车辆登记号| +|reply_number|str|需要发送测试响应的手机号码,无则填写 `NA`| + +**返回值说明:** + +|类型|说明| +|:---|:---| +|bool|`True` - 成功
`False` - 失败| + +## 数据包类型枚举值 + +### PacketTypes + +> 数据包类型枚举值,用于发送定位或报警数据包 `send_loction_alert_information` 接口 `packet_type` 参数。 + +```python +from usr.ais import PacketTypes + +PacketTypes.NormalReport +PacketTypes.EmergencyAlert +... +``` + +**枚举值说明:** + +|枚举值|对应值|说明| +|:---|:---|:---| +|NormalReport|`NR`|正常数据包| +|EmergencyAlert|`EA`|紧急报警包| +|TemperAlert|`TA`|拆卸报警包| +|HealthPacket|`HP`|心跳数据包| +|IgnitionOn|`IN`|点火数据包| +|IgnitionOff|`IF`|熄火数据包| +|VehicleBatteryDisconnected|`BD`|车辆电池断开数据包| +|VehicleBatteryReconnected|`BR`|车辆电池连接数据包| +|InternalBatteryLow|`BL`|内置电池低电报警包| +|HarshBreaking|`HB`|撞击报警包| +|HarshAcceleration|`HA`|急加速报警包| +|RashTurning|`RT`|急转弯报警包| +|SOSEmergencyButtonWireDisconnect|`WD`|SOS 紧急按钮断线报警包| +|OverspeedAlert|`OS`|超速报警包| + +## 报警标识枚举值 + +### AlertID + +> 报警ID枚举值,用于发送定位或报警数据包 `send_loction_alert_information` 接口 `alert_id` 参数。 + +```python +from usr.ais import AlertID + +AlertID.LocationUpdate +AlertID.LocationUpdateHistory +... +``` + +**枚举值说明:** + +|枚举值|对应值|说明| +|:---|:---|:---| +|LocationUpdate|`01`|来自设备的默认消息| +|LocationUpdateHistory|`02`|如果发送消息时 GPRS 不可用| +|Mainsoff|`03`|当设备与车辆电池断开连接时| +|LowBattery|`04`|设备内部电池电量低警报| +|LowBatteryremoved|`05`|设备内部电池正常| +|MainsOn|`06`|设备重新连接至车辆电池| +|IgnitionOn|`07`|车辆点火开| +|IgnitionOff|`08`|车辆点火关| +|TemperAlert|`09`|设备盒打开| +|EmergencyOn|`10`|紧急报警开| +|EmergencyOff|`11`|紧急报警关| +|OTAAlert|`12`|参数变更/查询警报| +|HarshBreaking|`13`|撞击报警| +|HarshAcceleration|`14`|急加速报警| +|RashTurning|`15`|急转弯报警| +|WireDisconnect|`16`|SOS 紧急按钮断线报警| +|Overspeed|`17`|超速报警| diff --git "a/docs/zh/\347\224\250\346\210\267\344\275\277\347\224\250\346\211\213\345\206\214.md" "b/docs/zh/\347\224\250\346\210\267\344\275\277\347\224\250\346\211\213\345\206\214.md" new file mode 100644 index 0000000..e2f3946 --- /dev/null +++ "b/docs/zh/\347\224\250\346\210\267\344\275\277\347\224\250\346\211\213\345\206\214.md" @@ -0,0 +1,76 @@ +# 用户使用手册 + +- 本项目提供了构建**车辆位置跟踪**和**紧急按钮**的构建块。**本项目不提供完整的解决方案,因为任何实现都是特定于其预期用途的**。 +- 本项目通过 TCP/UDP 协议与服务器进行数据通信交互,需要依赖项 `usocket` 模块。 +- 本文档提供了有关如何最好地构建完整解决方案的指导。 + +## 如何使用 + +### 运行 AIS-140 服务 + +> 如果您有自己的 AIS-140 服务器,则可以跳过此说明。 + +#### 1. 安装环境 + +- 操作系统: Window or Linux. + +- 语言: Python (Python-3.11.2). + +#### 2. 配置服务器并运行样例 + +- 在 [`ais_server_demo.py`](../../demo/ais_server_demo.py) 文件中修改你的服务器端口. + +```python +SERVER_PORT = 31500 # 修改为你自己的服务的端口 +... + +if __name__ == '__main__': + try: + logging.info("Start Server !") + socket_serve = TCPServer(('', SERVER_PORT), ReceiveHandler) + for i in range(THREAD_WORKERS_NUM): + t = Thread(target=socket_serve.serve_forever) + t.daemon = True + t.start() + socket_serve.serve_forever() + except KeyboardInterrupt: + socket_serve.shutdown() + logging.info("Stop Server !") +``` + +- 运行 `python ais_server_demo.py` 文件. 当看到交互输出 `[INFO] xxxx-xx-xxx xxx xx:xx:xx ais_server_demo.py: Start Server !`, 则服务端已经正常启动。 + +```shell +>>> python ais_server_demo.py +[INFO] xxxx-xx-xxx xxx xx:xx:xx ais_server_demo.py: Start Server ! +``` + +### 运行 AIS-140 客户端 + +#### 1. 运行环境 + +您需要使用我们的 QuecPython 模块。 + +#### 2. 配置客户端并运行样例 + +- 在 [`ais_client_demo.py`](../../demo/ais_client_demo.py) 文件中配置服务器 IP 和端口。 + +```python +if __name__ == "__main__": + # 初始化客户端。 + cfg = { + "ip": "xxx.xxx.xxx.xxx", + "port": 9000, + } # 替换成你自己的服务器 IP 和端口。 + ais_client = AISClient(**cfg) + ais_client.set_callback(server_cmd) +``` + +- 将代码下载到 QuecPython 模块 + +**说明:** + +- 如何下载 Python 代码并在 QuecPython 模块中运行 Python Demo 可参考 [QuecPython 文档中心](https://python.quectel.com/doc/Getting_started/en/index.html)。 +- 您可以将完整的 `code` 目录代码 和 `demo/ais_client_demo.py` 下载到我们的 QuecPython 模块,并运行 `ais_client_demo.py` 来测试 AIS-140 车辆位置跟踪和紧急按钮。 +- 你可以在 [QPYcom 工具](https://python.quectel.com/doc/Application_guide/zh/dev-tools/QPYcom/index.html)的交互界面看到日志 `ais_client.send_login() True.`,则 `Login Packet` 消息报已经发送到服务器端。 +- 您可以参考 `demo/ais_client_demo.py` 来编写符合业务逻辑的客户端请求。