外观
历史数据
接口说明
按时间范围分页查询指定设备的历史环境数据。
返回的每条记录是「一次上报快照」:记录里带一个 data 数组, 包含该次上报的全部因子读数(name / value / unit / icon / alarm)。
适合:导出明细、数据核对、按时间轴回溯异常。
只要曲线不要明细?
用 聚合数据(曲线),一次请求即可拿到按小时/天/月聚合好的数据,数据量小很多。
请求地址
text
GET https://yunshangwenshi.auto-control.com.cn/api/weather-data/list1
请求方法
GET
请求参数
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
deviceId | String | 是 | 设备 ID,取自 设备列表 的 id 字段 | 20612 |
stationId | String | 是 | 站点 ID,取自 站点列表 的 id 字段 | 12115 |
startTimestamp | String | 否 | 开始时间(毫秒级时间戳),默认当天 0 点 | 1789207221385 |
endTimestamp | String | 否 | 结束时间(毫秒级时间戳),默认当前时间戳 | 1789466421385 |
pageNumber | Int | 否 | 页码,默认 1 | 1 |
pageSize | Int | 否 | 单页数量,默认 100 | 2 |
缺少 deviceId 会返回业务错误
实测不传 deviceId 会返回 code: 404 + message: "ResourceNotFound" (注意 HTTP 状态码仍是 200):
json
{
"requestId": "e3636f86-bd10-43d4-b686-7c88ae879816",
"code": 404,
"message": "ResourceNotFound",
"errorDetail": "The specified DEVICE query=DataListQuery(pageNumber=1, pageSize=100, deviceId=null, stationId=25, ...) does not exist.",
"success": false
}1
2
3
4
5
6
7
2
3
4
5
6
7
errorDetail 里可以看到平台内部实际使用的默认值(pageSize=100)与参数集合。 该字段只用于排查,不要作为业务判断依据。
pageSize 的默认值与上限
实测平台内部默认 pageSize=100。虽未明确说明上限,建议按 ≤ 100 使用, 并在翻页时以返回的 pageSize 为准(而不是自己请求的值)。
请求头
| 请求头 | 值 | 必填 |
|---|---|---|
Authorization | Bearer <token> | 是 |
返回字段
顶层
| 字段名 | 类型 | 说明 |
|---|---|---|
requestId | String | 请求唯一标识 |
code | Int | 状态码,200 为成功 |
data | Object | 分页对象,见下 |
timestamp | Long | 响应时间戳(毫秒) |
success | Boolean | 是否成功 |
分页对象(data)
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
data | Array | 当前页的记录列表 | [ {...} ] |
pageNumber | Int | 当前页码 | 1 |
pageSize | Int | 单页数量 | 2 |
totalCount | Int | 总记录数(不是总页数) | 983 |
记录对象(data.data[])
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
createDate | String | 该次上报的时间 | 2026-09-15 17:59:14 |
data | Array | 本次上报的因子读数数组(见下) | [ {...} ] |
deviceId | String | 设备 ID | 20612 |
deviceCode | String | 设备编码 | 0010202606040002 |
deviceName | String | 设备名称 | 吴琼触摸屏测试 |
deviceTypeId | String | 设备类型编码 | C001 |
deviceTypeName | String | 设备类型名称 | 日光温室控制器 |
customerId | String | 客户 ID | 1667372262 |
stationId | String | 站点 ID | 12115 |
stationName | String | 站点名称 | 吴琼触摸屏测试 |
记录里也是 data 字段,注意两层同名
body.data 是分页对象,body.data.data[] 是记录数组,record.data[] 才是因子读数。 三层里有两层都叫 data,写代码时极易取错层。
因子读数对象(record.data[])
| 字段名 | 类型 | 说明 | 示例 |
|---|---|---|---|
name | String | 因子名 | atc / lp_1 |
displayName | String | 展示名(中文) | 空气温度 / 1#液位 |
value | Number | 物理值 | 18.3 |
unit | String | 单位 | ℃ |
icon | String | 图标标识(等于因子名,不含序号后缀) | atc / lp |
alarm | Boolean | 是否触发报警 | false |
number | String | 序号 | "0" / "1" |
name 带不带序号后缀,取决于设备,没有统一规则
实测同一账号下的两种形态:
| 设备类型 | name 形态 | displayName |
|---|---|---|
日光温室控制器(C001) | 不带后缀:atc、ahc、co2、stc、swc、light | 空气温度 |
施肥机(C003) | 带后缀:lp_1、lp_2、ecfii、phfii | 1#液位 |
稳定做法:用 icon 字段取因子名(它始终不含后缀), 或者对 name 做「截掉最后一个 _数字」的归一化处理。
请求示例
curl
bash
curl 'https://yunshangwenshi.auto-control.com.cn/api/weather-data/list?deviceId=20612&stationId=12115&startTimestamp=1789207221385&endTimestamp=1789466421385&pageNumber=1&pageSize=2' \
-H "Authorization: Bearer <token>"1
2
2
HTTP 报文
http
GET /api/weather-data/list?deviceId=20612&stationId=12115&pageNumber=1&pageSize=2 HTTP/1.1
Host: yunshangwenshi.auto-control.com.cn
Authorization: Bearer <token>
Accept: application/json1
2
3
4
2
3
4
Python
python
from datetime import datetime, timedelta
import requests
BIZ_HOST = "https://yunshangwenshi.auto-control.com.cn"
def query_history(token: str, device_id, station_id, start_ms: int, end_ms: int,
page_size: int = 100):
"""分页遍历时间范围内的全部记录,逐条 yield。"""
page = 1
while True:
resp = requests.get(
f"{BIZ_HOST}/api/weather-data/list",
params={
"deviceId": device_id, "stationId": station_id,
"startTimestamp": start_ms, "endTimestamp": end_ms,
"pageNumber": page, "pageSize": page_size,
},
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
body = resp.json()
if body.get("code") != 200:
raise RuntimeError(f"查询失败: {body.get('code')} {body.get('message')}")
page_obj = body["data"]
rows = page_obj.get("data") or []
if not rows:
break
for row in rows:
yield row
total = page_obj.get("totalCount", 0)
if page * page_size >= total:
break
page += 1
def normalize_factor(item) -> str:
"""取因子名:优先 icon,其次去掉 name 的 _数字 后缀。"""
icon = item.get("icon")
if icon:
return icon
name = item.get("name", "")
head, _, tail = name.rpartition("_")
return head if head and tail.isdigit() else name
if __name__ == "__main__":
now = datetime.now()
start = now - timedelta(days=3)
n = 0
for record in query_history("<你的 token>", 20612, 12115,
int(start.timestamp() * 1000),
int(now.timestamp() * 1000)):
flat = {normalize_factor(d): d["value"] for d in record.get("data", [])}
print(record["createDate"], flat)
n += 1
print(f"共 {n} 条上报记录")1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
返回示例
json
{
"requestId": "d2952b40-6310-468a-bdd0-475dd3fdefd2",
"code": 200,
"data": {
"data": [
{
"data": [
{ "name": "stc", "value": -40.0, "displayName": "土壤温度", "unit": "℃", "icon": "stc", "alarm": false, "number": "0" },
{ "name": "co2", "value": 0.0, "displayName": "二氧化碳", "unit": "PPM", "icon": "co2", "alarm": false, "number": "0" },
{ "name": "atc", "value": -40.0, "displayName": "空气温度", "unit": "℃", "icon": "atc", "alarm": false, "number": "0" },
{ "name": "light", "value": 0.0, "displayName": "光亮度", "unit": "Klux","icon": "light", "alarm": false, "number": "0" },
{ "name": "ahc", "value": 0.0, "displayName": "空气湿度", "unit": "%", "icon": "ahc", "alarm": false, "number": "0" },
{ "name": "swc", "value": 0.0, "displayName": "土壤湿度", "unit": "%", "icon": "swc", "alarm": false, "number": "0" }
],
"deviceTypeId": "C001",
"deviceTypeName": "日光温室控制器",
"deviceCode": "0010202606040002",
"deviceId": "20612",
"deviceName": "吴琼触摸屏测试",
"customerId": "1667372262",
"stationName": "吴琼触摸屏测试",
"stationId": "12115",
"createDate": "2026-09-15 17:59:14"
}
],
"pageNumber": 1,
"pageSize": 2,
"totalCount": 983
},
"timestamp": 1789466421385,
"success": true
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
多路因子的返回形态(施肥机):
json
{
"name": "lp_1", "value": 3.33, "displayName": "1#液位", "unit": "m",
"icon": "lp", "alarm": false, "number": "1"
}1
2
3
4
2
3
4
注意事项
大时间范围查询要分页拉完
建议单次查询时间范围控制在 7 天以内,过大会显著拉长响应时间。 超出页数时按 totalCount 循环翻页(见上面的 Python 示例)。
unit 大小写与实时接口不一致
light 在本接口是 Klux(大写 K),在 实时数据 是 klux(小写 k)。 比较单位时请忽略大小写。
单条记录里的 data 可能是空数组
某次上报没有产生可用因子读数时,data 会是 []。 遍历时请判空,不要直接取 record["data"][0]。