设备图片上传
约 1979 字大约 7 分钟
设备图片上传
在一些物联网应用场景中,设备需要向云平台上报图片,实现可视化的远程监测和告警。ThingsCloud 为设备提供了专用的图片上传服务,设备通过简单的 HTTP 请求即可将图片上传到平台,并自动关联到设备属性中。
以下是一些典型的应用场景:
- 农业虫情监测:虫情测报灯自动诱捕害虫并拍照,设备将照片上传至云平台,结合 AI 识别实现虫害统计和预警。
- 安防预警:门磁传感器、红外人体感应器触发报警后,联动摄像头抓拍现场照片并上传,便于远程确认警情。
- 红外火警相机:热成像相机检测到温度异常或明火时,自动拍摄可见光照片上传,辅助消防预警和溯源。
- 工业质检异常:产线视觉检测设备发现产品缺陷时,将异常品照片上传,供质量管理人员远程复核和追溯。
- 设备运行状态截图:带有屏幕的工控设备或仪表,定期截屏上传,方便运维人员远程查看现场界面。
- AI 识别结果:边缘计算设备完成图像识别后,将标记了识别结果的照片上传,用于留档或人工二次确认。
以上场景中,设备只需要将图片以原始二进制形式通过 HTTP POST 发送到图片上传服务,平台会自动将图片存储到项目集成的 OSS 对象存储中,并将图片 URL 更新到相关设备属性中,方便在控制台、可视化看板以及用户应用中直接查看图片。
提示
设备图片上传功能,需要企业版及以上版本支持。
准备工作
进入控制台的 项目设置 > 第三方集成,完成阿里云对象存储的集成配置,具体步骤请参阅 阿里云 OSS 对象存储集成指南。
图片上传接入点
接入点格式如下:
| 接入类型 | 用途 | 接入点示例 |
|---|---|---|
| HTTP | 普通方式,基于明文传输。 适合不支持 SSL 的设备。 | http:// <endpoint> |
| HTTPs | 安全方式,基于 SSL 证书的加密传输方式。 适合对通信安全要求严格的设备。 | https:// <endpoint> |
如需获得设备图片上传接入点 <endpoint>,请联系技术支持。
图片上传 API
设备向云平台上报图片时,调用如下 API:
POST https://<endpoint>/device/v1/<AccessToken>/<identifier>/image
HTTP 请求头
调用图片上传 API 时,需要在 HTTP 请求头中加入以下字段:
| 请求头 | 必填 | 说明 |
|---|---|---|
| Content-Type | 是 | 必须为 application/octet-stream,表示请求正文为原始二进制数据 |
| Region | 是 | 设备所属的区域标识,例如 <region> |
| Project-Key | 是 | 项目密钥,用于设备身份认证 |
请求头示例如下:
Content-Type: application/octet-stream
Region: <Region>
Project-Key: <ProjectKey>
URL 路径参数
| 参数 | 说明 |
|---|---|
| AccessToken | 设备的证书令牌,用于标识设备身份。 |
| identifier | 设备类型中定义的属性标识符,必须是文本数据类型并设置为图片 URL 格式,上传成功后图片 URL 将自动上报到该属性。 |
请求正文
HTTP 请求的正文部分为原始图片二进制数据,不支持 multipart/form-data 或其它格式。
支持的图片格式
设备上传的图片必须满足以下格式要求:
| 图片格式 | 说明 |
|---|---|
| JPEG | image/jpeg |
| PNG | image/png |
| GIF | image/gif |
| WebP | image/webp |
| BMP | image/bmp |
图片大小限制
单张图片大小不得超过 500 KB。
请求频率限制
为了防止滥用,图片上传服务对请求频率进行了限制:
| 限流类型 | 时间窗口 | 最大请求次数 | 说明 |
|---|---|---|---|
| 设备限流 | 10 秒 | 1 次 | 按单个设备限流 |
调用成功响应
图片上传成功且完成属性上报后,HTTP 响应正文如下:
{
"result": 1,
"image_url": "https://..."
}
| 字段 | 说明 |
|---|---|
| result | 1 表示成功 |
| image_url | 图片在云端的访问地址 |
错误响应
当请求参数不正确或处理失败时,接口会返回相应的错误信息:
{
"result": 0,
"errcode": 4001,
"message": "Missing Region header"
}
错误码一览
| 错误码 | HTTP 状态码 | 错误信息 | 说明 |
|---|---|---|---|
| 4001 | 400 | Missing Region header | 缺少 Region 请求头 |
| 4002 | 400 | Missing Project-Key header | 缺少 Project-Key 请求头 |
| 4003 | 400 | Request body must be image binary data | 请求正文不是有效的图片二进制数据 |
| 4004 | 400 | Invalid image format | 不支持的图片格式 |
| 4005 | 413 | Image size exceeds limit | 图片大小超过 500 KB 限制 |
| 4006 | 400 | Missing Content-Type: application/octet-stream header | 缺少或错误的 Content-Type 请求头 |
| 1022 | 400 | Upload authentication failed | 项目不存在或 Project-Key 无效 |
| 1480 | 400 | Upload authentication failed | 设备不存在或已停用 |
| 1424 | 400 | Upload authentication failed | 设备未绑定设备类型 |
| 1470 | 400 | Upload authentication failed | 属性定义标识符 identifier 不存在 |
| 1471 | 400 | Upload authentication failed | 属性定义的数据类型不正确 |
| 1023 | 400 | Upload authentication failed | 项目未配置阿里云 OSS 对象存储 |
| 4008 | 400 | Region not found | 指定的区域不存在 |
| 4009 | 400 | Device Attribute report failed | 图片上传成功,但属性上报失败(上传服务层面的封装错误码) |
| 401 | 400 | Device Attribute report failed | 设备不存在或 AccessToken 无效 |
| 451 | 400 | Device Attribute report failed | 设备已停用 |
| 402 | 400 | Device Attribute report failed | 属性数据格式无效 |
| 403 | 400 | Device Attribute report failed | 设备消息频率过高,请稍后重试 |
| 413 | 400 | Device Attribute report failed | 设备今日消息数超过上限 |
| 4041 | 404 | The requested endpoint does not exist | 请求的接口不存在 |
| 4291 | 429 | Request frequency is too high, please wait for a moment. | 请求频率过高 |
| 4292 | 429 | Request frequency is too high, please wait for a moment. | 请求频率过高 |
| 5001 | 500 | Internal server error | 服务器内部错误 |
完整请求示例
以下是一个使用 curl 命令上传图片的完整示例:
curl -X POST https://<endpoint>/device/v1/<AccessToken>/<identifier>/image \
-H "Content-Type: application/octet-stream" \
-H "Region: <region>" \
-H "Project-Key: <ProjectKey>" \
--data-binary "@/path/to/image.jpg"
示例代码
Node.js
以下示例使用 axios 发送图片二进制数据:
const fs = require('fs');
const axios = require('axios');
async function uploadImage(imagePath) {
const endpoint = '<endpoint>'; // 图片上传接入点
const accessToken = '<AccessToken>'; // 设备访问令牌
const identifier = '<identifier>'; // 图片类型属性标识符
const projectKey = '<ProjectKey>'; // 项目密钥
const region = '<region>'; // 设备所属区域
const imageBuffer = fs.readFileSync(imagePath);
try {
const response = await axios.post(
`https://${endpoint}/device/v1/${accessToken}/${identifier}/image`,
imageBuffer,
{
headers: {
'Content-Type': 'application/octet-stream',
'Region': region,
'Project-Key': projectKey,
},
maxBodyLength: 512 * 1024, // 500 KB 限制
}
);
console.log('上传成功:', response.data);
// { result: 1, image_url: 'https://...' }
} catch (error) {
if (error.response) {
console.error('上传失败:', error.response.status, error.response.data);
} else {
console.error('请求异常:', error.message);
}
}
}
// 调用示例
uploadImage('./image.jpg');
运行步骤:
- 确保已安装 Node.js 运行环境。
- 安装
axios依赖:npm install axios - 将以上代码保存为
upload.js,修改其中的<endpoint>、<AccessToken>、<identifier>、<ProjectKey>、<region>为实际值。 - 执行程序:
node upload.js
提示
Node.js 的详细语法和进阶用法,请参阅 Node.js 官方文档。
Python
以下示例使用 requests 发送图片二进制数据:
import requests
def upload_image(image_path):
endpoint = '<endpoint>' # 图片上传接入点
access_token = '<AccessToken>' # 设备访问令牌
identifier = '<identifier>' # 图片类型属性标识符
project_key = '<ProjectKey>' # 项目密钥
region = '<region>' # 设备所属区域
url = f"https://{endpoint}/device/v1/{access_token}/{identifier}/image"
headers = {
'Content-Type': 'application/octet-stream',
'Region': region,
'Project-Key': project_key,
}
with open(image_path, 'rb') as f:
image_data = f.read()
try:
response = requests.post(url, data=image_data, headers=headers)
result = response.json()
if result.get('result') == 1:
print('上传成功:', result['image_url'])
else:
print('上传失败:', result)
except requests.exceptions.RequestException as e:
print('请求异常:', e)
# 调用示例
upload_image('./image.jpg')
运行步骤:
- 确保已安装 Python 3 运行环境。
- 安装
requests依赖:pip install requests - 将以上代码保存为
upload.py,修改其中的<endpoint>、<AccessToken>、<identifier>、<ProjectKey>、<region>为实际值。 - 执行程序:
python upload.py
提示
Python 的详细语法和进阶用法,请参阅 Python 官方文档。