单OpenApi账号调用接口的每分钟请求数最大限制:50
本功能默认不开启,需与责任商务沟通开通
请务必使用设备商身份获取Token,仅设备商Token有权限使用本接口
当前阶段仅支持子设备(如逆变器)的DeviceID维度下发指令,暂不支持设备的SN维度,不支持采集器维度
DeviceID请通过设备列表接口获取
| 自定义指令 | ||||
|---|---|---|---|---|
| 接口描述 | 支持通过OpenApi进行采集器指令的下发。 | |||
| 请求URL | https://api.solarmanpv.com/device/v1.0/upgrade | |||
| 请求方式 | post | |||
| 请求类型 | application/json | |||
| 返回类型 | / | |||
| 请求参数 | ||||
| 参数名 | 数据类型 | 参数类型 | 是否必填 | 描述说明 |
| language | string | query | N | 语言类型,示例值:zh |
| authorization | string | header | Y | accessToken,示例值:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 |
| callBackUrl | string | body | Y | 指令结果回调地址 ,示例值:https://www.solarman.cn/ 回调结果中的响应参数定义见下文 回调地址请求类型:POST 发送完指令后 ,前60秒每3秒请求一次指令结果,60秒之后每30秒请求一次指令结果,有指令结果后就发起回调, 回调方需要返回“SUCCESS”响应,否则会重新发起回调,超过 600s 仍然无法回调成功则丢弃,不再回调 注意:回调返回值为大写SUCCESS字符串,不需要返回json |
| content | string | body | Y | 采集器指令内容 |
| deviceId | string | body | Y | 设备在平台内的唯一标识 ,示例值:200124137 该ID为子设备(如逆变器)的device_id 该ID可通过设备列表获取 非子设备SN,非采集器SN,非采集器device_id |
| timeoutSeconds | INT | body | N | 控制命令的超时时间,若超过该时间没有收到反馈结果则判定为指令失败。该时间默认600秒。 可自定义输入的范围为10-600秒 |
| 响应参数 | ||||
| 参数名 | 数据类型 | 描述说明 | ||
| code | string | 信息码 ,示例值:10000 | ||
| msg | string | 信息描述 ,示例值:success | ||
| success | boolean | 是否成功 ,示例值:true | ||
| requestId | string | 请求标识 ,示例值:1d6f6eca9bee4b6483d4af064b659eec | ||
| collectionTime | string | 设备最新数据接收时间戳,示例值:1615900034 | ||
| connectStatus | INT | 平台定义的设备通讯状态 0:离线 1:在线 | ||
| orderId | string | 指令任务的ID | ||
| 示例 | ||||
| 请求参数 | { “deviceID”: “1800800121-Igen”, “timeoutSeconds”: 120, “callBackUrl”: “http://localhost:8019/device/v1.0/callback“, “content”: “0103001B0001F40D” } |
|||
| 返回值 | { “code”: null, “msg”: null, “success”: true, “requestId”: “311d34904f1841999f2f58b9b43f8719”, “collectionTime”: “1615900034”, “connectStatus”: 1, “orderId”: “19928812” } |
支持的指令
| 英臻采集器网络制式 | 功能 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|---|
| GPRS/4G | 子设备固件升级 | AT+SFTPUPURL= | 125.125.125.125:21 | username | password | / | file_path_name | 2 | CRC32 |
| 描述,蜂窝制式采集器,必须使用本指令进行升级 内容与内容之间以’,’逗号分割 |
固定内容,不可修改 | ip:端口 | ftp账号 | ftp密码 | 文件路径 | 文件名 | 固定内容,不可修改 | CRC32算法,见后文 | |
| 示例指令 | AT+SFTPUPURL=125.125.125.125:21,username,password,/,file_path_name,2,CRC32 | ||||||||
| WIFI/ETH | 子设备固件升级 | AT+INVUPURL= | http://url.url/file_path_name/ | ||||||
| 描述,WIFI和ETH采集器,必须使用本指令进行升级 内容与内容之间以’,’逗号分割 |
固定内容 | 1. url地址 1. 必须以http://开头 1. url整体长度不得超过70个字符, 1. 必须是公网可访问,通过GET可以直接下载文件的地址 |
|||||||
| 示例指令 | AT+INVUPURL=http://url.url/file_path_name |
附录
CRC32算法
/********************************************************************************Function Name: Get_Inverter_Version_CRC32*Description:*Input: start:*Output:*Returns:*******************************************************************************/cyg_uint32 Get_Inverter_Version_CRC32(cyg_uint32 start_address, cyg_uint32 file_len){//U8 loop = 0;cyg_uint16 index = 0;cyg_uint32 temp = 0;cyg_uint32 loop_i = 0;cyg_uint32 loop_j = 0;cyg_uint32 h_CRC = 0;cyg_uint32 flash_startAddr = 0;yz_up_mid_buf = hfmem_malloc(1024);if( yz_up_mid_buf == NULL ){return 0;}memset(yz_up_mid_buf, 0, 1024);flash_startAddr = start_address;for(loop_i = 0, h_CRC = 0xFFFFFFFF, loop_j = 0; loop_i < file_len; loop_i++, loop_j++){if(loop_j == 1024){loop_j = 0;memset((char*)yz_up_mid_buf, 0, 1024);yz_flash_read(flash_startAddr, (unsigned char *)yz_up_mid_buf, 1024);for(index = 0; index < 256; index++){temp = yz_up_mid_buf[index * 4];temp = (temp << 8) & 0xff00;temp += yz_up_mid_buf[index * 4 + 1];temp = (temp << 8) & 0xffff00;temp += yz_up_mid_buf[index * 4 + 2];temp = (temp << 8) & 0xffffff00;temp += yz_up_mid_buf[index * 4 + 3];h_CRC = CRC32(h_CRC, (cyg_uint32 *)&temp, 1);}flash_startAddr += 1024;}}if(loop_j){memset(yz_up_mid_buf, 0, 1024);yz_flash_read(flash_startAddr, (unsigned char *)yz_up_mid_buf, loop_j);for(index = 0; index < (loop_j / 4); index++){temp = yz_up_mid_buf[index * 4];temp = (temp << 8) & 0xff00;temp += yz_up_mid_buf[index * 4 + 1];temp = (temp << 8) & 0xffff00;temp += yz_up_mid_buf[index * 4 + 2];temp = (temp << 8) & 0xffffff00;temp += yz_up_mid_buf[index * 4 + 3];h_CRC = CRC32(h_CRC, (cyg_uint32 *)&temp, 1);}loop_i = loop_j % 4;if(loop_i != 0){if(loop_i == 1){temp = yz_up_mid_buf[index * 4];}else if(loop_i == 2){temp = yz_up_mid_buf[index * 4];temp = (temp << 8) & 0xff00;temp += yz_up_mid_buf[index * 4 + 1];}else if(loop_i == 3){temp = yz_up_mid_buf[index * 4];temp = (temp << 8) & 0xff00;temp += yz_up_mid_buf[index * 4 + 1];temp = (temp << 8) & 0xffff00;temp += yz_up_mid_buf[index * 4 + 2];}h_CRC = CRC32(h_CRC, (cyg_uint32 *)&temp, 1);}}hfmem_free(yz_up_mid_buf);return h_CRC;}/********************************************************************************Function Name: CRC32*Description:*Input:*Output:*Returns:*******************************************************************************/cyg_uint32 CRC32(cyg_uint32 uCurCRC, cyg_uint32 * pcData, cyg_uint32 dwSize){cyg_uint32 bits;cyg_uint32 xbit;cyg_uint32 data;cyg_uint32 uCRC = 0;uCRC = uCurCRC;while (dwSize--){xbit = ((cyg_uint32)1 << 31);data = *pcData++;for (bits = 0; bits < 32; bits++){if (uCRC & 0x80000000){uCRC <<= 1;uCRC ^= 0x04c11db7;}elseuCRC <<= 1;if (data & xbit)uCRC ^= 0x04c11db7;xbit >>= 1;}}return uCRC;}
CURL示例
## 3.10 采集器指令curl -X "POST" "https://api.solarmanpv.com/device/v1.0/upgrade?language=zh" \-H 'Authorization: bearer eyJhbGxxxxxxxxxxxxxxxxxxxLm10000uxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxuxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxxxxxxLm100uxxxxxxxLm100uSChpu1eLPQ' \-H 'Content-Type: application/json' \-d $'{"deviceId": "1234567890","content": "AT+INVUPURL=http://fw.net.com/f/abc.bin","timeoutSeconds": "600","callBackUrl": "http://call.back.com:3000/solarman/api/callback/Success"}'
JAVA示例
import java.io.IOException;import org.apache.http.client.fluent.*;import org.apache.http.entity.ContentType;public class SendRequest{public static void main(String[] args) {sendRequest();}private static void sendRequest() {// 3.10 采集器指令 (POST )try {// Create requestContent content = Request.Post("https://api.solarmanpv.com/device/v1.0/upgrade?language=zh")// Add headers.addHeader("Authorization", "bearer eyJhbGxxxxxxxxxxxxxxxxxxxLm10000uxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxuxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxxxxxxLm100uxxxxxxxLm100uSChpu1eLPQ").addHeader("Content-Type", "application/json")// Add body.bodyString("{\"deviceId\": \"1234567890\",\"content\": \"AT+INVUPURL=http://fw.net.com/f/abc.bin\",\"timeoutSeconds\": \"600\",\"callBackUrl\": \"http://call.back.com:3000/solarman/api/callback/Success\"}", ContentType.APPLICATION_JSON)// Fetch request and return content.execute().returnContent();// Print contentSystem.out.println(content);}catch (IOException e) { System.out.println(e); }}}
