单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算法

  1. /*******************************************************************************
  2. *Function Name: Get_Inverter_Version_CRC32
  3. *Description:
  4. *Input: start:
  5. *Output:
  6. *Returns:
  7. *******************************************************************************/
  8. cyg_uint32 Get_Inverter_Version_CRC32(cyg_uint32 start_address, cyg_uint32 file_len)
  9. {
  10. //U8 loop = 0;
  11. cyg_uint16 index = 0;
  12. cyg_uint32 temp = 0;
  13. cyg_uint32 loop_i = 0;
  14. cyg_uint32 loop_j = 0;
  15. cyg_uint32 h_CRC = 0;
  16. cyg_uint32 flash_startAddr = 0;
  17. yz_up_mid_buf = hfmem_malloc(1024);
  18. if( yz_up_mid_buf == NULL )
  19. {
  20. return 0;
  21. }
  22. memset(yz_up_mid_buf, 0, 1024);
  23. flash_startAddr = start_address;
  24. for(loop_i = 0, h_CRC = 0xFFFFFFFF, loop_j = 0; loop_i < file_len; loop_i++, loop_j++)
  25. {
  26. if(loop_j == 1024)
  27. {
  28. loop_j = 0;
  29. memset((char*)yz_up_mid_buf, 0, 1024);
  30. yz_flash_read(flash_startAddr, (unsigned char *)yz_up_mid_buf, 1024);
  31. for(index = 0; index < 256; index++)
  32. {
  33. temp = yz_up_mid_buf[index * 4];
  34. temp = (temp << 8) & 0xff00;
  35. temp += yz_up_mid_buf[index * 4 + 1];
  36. temp = (temp << 8) & 0xffff00;
  37. temp += yz_up_mid_buf[index * 4 + 2];
  38. temp = (temp << 8) & 0xffffff00;
  39. temp += yz_up_mid_buf[index * 4 + 3];
  40. h_CRC = CRC32(h_CRC, (cyg_uint32 *)&temp, 1);
  41. }
  42. flash_startAddr += 1024;
  43. }
  44. }
  45. if(loop_j)
  46. {
  47. memset(yz_up_mid_buf, 0, 1024);
  48. yz_flash_read(flash_startAddr, (unsigned char *)yz_up_mid_buf, loop_j);
  49. for(index = 0; index < (loop_j / 4); index++)
  50. {
  51. temp = yz_up_mid_buf[index * 4];
  52. temp = (temp << 8) & 0xff00;
  53. temp += yz_up_mid_buf[index * 4 + 1];
  54. temp = (temp << 8) & 0xffff00;
  55. temp += yz_up_mid_buf[index * 4 + 2];
  56. temp = (temp << 8) & 0xffffff00;
  57. temp += yz_up_mid_buf[index * 4 + 3];
  58. h_CRC = CRC32(h_CRC, (cyg_uint32 *)&temp, 1);
  59. }
  60. loop_i = loop_j % 4;
  61. if(loop_i != 0)
  62. {
  63. if(loop_i == 1)
  64. {
  65. temp = yz_up_mid_buf[index * 4];
  66. }
  67. else if(loop_i == 2)
  68. {
  69. temp = yz_up_mid_buf[index * 4];
  70. temp = (temp << 8) & 0xff00;
  71. temp += yz_up_mid_buf[index * 4 + 1];
  72. }
  73. else if(loop_i == 3)
  74. {
  75. temp = yz_up_mid_buf[index * 4];
  76. temp = (temp << 8) & 0xff00;
  77. temp += yz_up_mid_buf[index * 4 + 1];
  78. temp = (temp << 8) & 0xffff00;
  79. temp += yz_up_mid_buf[index * 4 + 2];
  80. }
  81. h_CRC = CRC32(h_CRC, (cyg_uint32 *)&temp, 1);
  82. }
  83. }
  84. hfmem_free(yz_up_mid_buf);
  85. return h_CRC;
  86. }
  87. /*******************************************************************************
  88. *Function Name: CRC32
  89. *Description:
  90. *Input:
  91. *Output:
  92. *Returns:
  93. *******************************************************************************/
  94. cyg_uint32 CRC32(cyg_uint32 uCurCRC, cyg_uint32 * pcData, cyg_uint32 dwSize)
  95. {
  96. cyg_uint32 bits;
  97. cyg_uint32 xbit;
  98. cyg_uint32 data;
  99. cyg_uint32 uCRC = 0;
  100. uCRC = uCurCRC;
  101. while (dwSize--)
  102. {
  103. xbit = ((cyg_uint32)1 << 31);
  104. data = *pcData++;
  105. for (bits = 0; bits < 32; bits++)
  106. {
  107. if (uCRC & 0x80000000)
  108. {
  109. uCRC <<= 1;
  110. uCRC ^= 0x04c11db7;
  111. }
  112. else
  113. uCRC <<= 1;
  114. if (data & xbit)
  115. uCRC ^= 0x04c11db7;
  116. xbit >>= 1;
  117. }
  118. }
  119. return uCRC;
  120. }

CURL示例

  1. ## 3.10 采集器指令
  2. curl -X "POST" "https://api.solarmanpv.com/device/v1.0/upgrade?language=zh" \
  3. -H 'Authorization: bearer eyJhbGxxxxxxxxxxxxxxxxxxxLm10000uxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxuxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxxxxxxLm100uxxxxxxxLm100uSChpu1eLPQ' \
  4. -H 'Content-Type: application/json' \
  5. -d $'{
  6. "deviceId": "1234567890",
  7. "content": "AT+INVUPURL=http://fw.net.com/f/abc.bin",
  8. "timeoutSeconds": "600",
  9. "callBackUrl": "http://call.back.com:3000/solarman/api/callback/Success"
  10. }'

JAVA示例

  1. import java.io.IOException;
  2. import org.apache.http.client.fluent.*;
  3. import org.apache.http.entity.ContentType;
  4. public class SendRequest
  5. {
  6. public static void main(String[] args) {
  7. sendRequest();
  8. }
  9. private static void sendRequest() {
  10. // 3.10 采集器指令 (POST )
  11. try {
  12. // Create request
  13. Content content = Request.Post("https://api.solarmanpv.com/device/v1.0/upgrade?language=zh")
  14. // Add headers
  15. .addHeader("Authorization", "bearer eyJhbGxxxxxxxxxxxxxxxxxxxLm10000uxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxuxxxxxxxxxxxLm100uxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxLm100uxxxxxxxxxxxxxxxxLm100uxxxxxxxLm100uSChpu1eLPQ")
  16. .addHeader("Content-Type", "application/json")
  17. // Add body
  18. .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)
  19. // Fetch request and return content
  20. .execute().returnContent();
  21. // Print content
  22. System.out.println(content);
  23. }
  24. catch (IOException e) { System.out.println(e); }
  25. }
  26. }