public class RPCResponse‹T› {
private int code;
private @Nullable T data;
public int code() {
return code;
}
public @Nullable T data() {
return data;
}
public class IpcInfoBean {
// 设备序列号
public String sn;
// 设备型号
public String model_name;
// 设备名称
public String name;
// 软件版本号
public String software_version;
// 硬件版本号
public String hardware_version;
// IP地址
public String ip;
// MAC地址
public String mac;
}
public class WifiConfBean {
// 当前连接的SSID
public String ssid;
// 当前SSID的密码
public String password;
}
public static class IpcApBean {
// 返回扫描到的AP个数
public int num;
// 扫描到的AP
public List‹ApListBean› ap_list;
public static class ApListBean {
// 扫描到AP的ssid
public String ssid;
// 扫描到AP的加密方式
public String key_mgmt;
}
}
public class ZoomFocusBean {
// 当前的焦距
public int zoom;
// 能够调整的焦距最大值
public int max_zoom;
// 当前的聚焦值
public int focus;
// 能够调整的聚焦最大值
public int max_focus;
// 聚焦点在x方向的像素百分比
public int focused_x;
// 聚焦点在y方向的像素百分比
public int focused_y;
}
public class IrSettingBean {
// 夜视模式:0表示关闭,1表示开启,2表示自动。一般选2。
public int irmode;
}
public class DynamicDetectBean {
// 动态侦测移动灵敏度,范围[0, 3],0表示关闭,数值越大,越灵敏。
public int motion_level;
// 动态侦测声音灵敏度,范围[0, 3],0表示关闭,数值越大,越灵敏。
public int audio_level;
/**
* 动态侦测时间设置参数
* 以周为一个循环,用0xYY来表示选择哪一天,具体是0x80直接表示7×24小时,其余的,
* 以7bit来表示哪一天被选上,0x01表示选择周一,0x02表示选择周二,0x40表示选择
* 周天,0x7f表示选择一个礼拜的7天,与0x80的区别只是0x80直接默认724小时,而
* 0x7f选了7天后,还可以设置具体的开始时间和结束时间。
*/
public int weekday;
/**
* 动态侦测时间设置参数
* 用分钟来表示,以一天24小时为例,以分钟为最小粒度,总共24*60这样的时间数值,
* 60表示01:00,121表示02:01,依次类推。范围[0,1440]
*/
public long start_time;
/**
* 动态侦测时间设置参数
* 用分钟来表示,以一天24小时为例,以分钟为最小粒度,总共24*60这样的时间数值,
* 60表示01:00,121表示02:01,依次类推。范围[0,1440]
*/
public long stop_time;
}
public class IPCNameBean {
// IPC名称
public String name;
}
public class LedSettingBean {
// 指示灯开关:0表示关闭指示灯,1表示开启指示灯,即可以亮
public int led_switch;
}
public class RotationBean {
// 画面旋转角度
public int rotation;
}
public class SupportRotationsBean {
// 支持的画面旋转角度:{"0","90","180","270"}
public List‹String› angles;
}
public class ExternalStorageBean {
// SD卡的四种状态:0表示未插入SD卡;1表示已插入SD卡但未初始化;2表示SD卡已插入且正常;3表示SD卡无法识别
public int status;
}
public class LiveAddressBean {
// 高清直播地址,RTSP协议
public String hd_live_url;
// 全高清直播地址,RTSP协议
public String fhd_live_url;
}
public class PlaybackBean {
// 视频回放URL,RTSP协议
public String playback_url;
}
public class VideoRecordBean {
// 符合条件的视频总数量,每个视频大概1分钟时长
public int total_num;
// 当前返回的视频数量
public int return_num;
// 视频片段列表
public List‹VideoFragment› record_list;
public class VideoFragment {
// 视频的开始时间
public long start_time;
// 视频的结束时间
public long end_time;
// 视频的下载链接
public String url;
}
}
public class SnapshotBean {
// 快照下载地址
public String snapshot_url;
}
public class CurVideoBean {
// 视频片段下载链接,在生成后4~12s生效
public String url;
}
public class GroupBean {
// 分组数量
public int num;
// 分组列表
public List‹GroupInfo› face_group;
}
public class GroupInfo {
// 分组最大容量
public int capacity;
// 分组内当前记录数量
public int count;
// 分组名称
public String name;
// 分组描述
public String description;
// stranger分组独有
public int period;
// stranger分组独有,代表一个生人在一定时间内(period设置,单位为天)来过多少次(times设置)就移动到熟人分组中去。
public int times;
}
public class AttributesBean {
// 分组自定义属性数量
public int num;
// 自定义属性名称列表
public List‹String› name_list;
}
public class FaceDeleteSubResult {
// 删除成功的人脸ID列表
public List‹String› success_list;
// 删除失败的人脸ID列表
public List‹String› failed_list;
// 不存在的人脸ID列表
public List‹String› not_exist_list;
}
public class FaceRecordBean {
// 人脸ID
public String faceid;
// 所在分组名称
public String group_name;
// 年龄,为空则表示用户没有设置过此人脸的年龄
public int age;
// 所属年龄段,1表示1~6岁,2表示7~12岁,3表示13~18岁,4表示19~28岁,5表示29~35岁,6表示36~45岁,7表示45~55岁,8表示55岁~100
public int age_range;
// 性别,0表示未知,1表示男性,2表示女性
public int gender;
// 到达过的总次数
public int arrive_count;
// 最后到达时间戳
public int arrive_time;
}
public class FaceRecordListBean {
// 总人脸数量
public int total_num;
// 当前返回人脸数量
public int return_num;
public List‹FaceRecordListBean› faceid_list;
}
public class DoorLineBean {
// 参照分辨率:取值0和1,0表示1080P的分辨率,1表示720P的分辨率
public int resolution;
// 拌线的左边端点X坐标
public int start_x;
// 拌线的左边端点Y坐标
public int start_y;
// 拌线的右边端点X坐标
public int end_x;
// 拌线的右边端点Y坐标
public int end_y;
}
public class StatsUnit {
// 统计粒度的开始时间
public long start_time;
// 统计粒度的结束时间
public long end_time;
// 整数数组,表示男性统计数据,共有8个整数,从第一个整数开始依次表
// 示1~6岁、7~12岁、13~18岁、19~28岁、29~35岁、36~45岁、46~55岁、
// 56岁~100岁的男性人数。
public List‹Integer› male_num_stat;
// 整数数组,表示女性统计数组,含义同上
public List‹Integer› female_num_stat;
}
public class PeopleStatBean {
// 总人流数量/统计粒度内的人流数量
public int total;
public List‹StatsUnit› stat_list;
}
public class VisitorListBean {
// 符合条件的总人脸数量
public int total_num;
// 当前人脸数量
public int return_num;
public List‹FaceRecordBean› face_list;
}
public class VisitDetailBean {
// 总到访次数
public int total_times;
// 到访的具体时间戳
public List‹Long› came_in_time;
}
public class IPCEventList {
// 订阅的事件数量
public int num;
// 订阅的事件列表
public List‹IPCEvent› sub_event;
private class IPCEvent {
public String event;
public List‹String› http_callback;
}
}
public class FaceRecogEvent {
// 事件ID
public String event_id;
// 人脸ID
public String faceid;
// 分组名称
public String group_name;
// 年龄
public String age;
// 年龄段
public String age_range;
// 性别
public String gender;
// 事件类型
public String event_type;
// IPC序列号
public String sn;
// 事件上报时间
public String report_time;
}
}
3. RPCErrorCode类
public class RPCErrorCode {
// 正常,操作成功
public static final int SUCCESS = 0;
// app_id不合法
public static final int APPID_INVALID = 1;
// 合法性检查失败
public static final int PARAMS_INVALID = 2;
// 未知错误
public static final int UNKNOWN = 3;
// 请求激活的设备没有联网
public static final int DEVICE_NOT_ONLINE = 4;
// app_id或者secret key错误
public static final int SECRET_KEY_INVALID = 5;
// URL错误
public static final int URL_NOT_FOUND = 6;
// 设备未激活
public static final int DEVICE_NOT_ACTIVATED = 7;
// 设备激活失败
public static final int DEVICE_ACTIVATE_FAILED = 8;
// 设备已激活,不需要重复激活
public static final int DEVICE_ACTIVATED = 9;
// 设备已绑定,激活失败
public static final int DEVICE_BINDED = 10;
// SN错误,激活失败
public static final int SN_DISMATCH = 11;
// 操作不允许
public static final int OP_NOT_ALLOWED = 12;
// SSID不符合规范
public static final int WIRELESS_SSID_INVALID = 100;
// 密码不合法
public static final int WIRELESS_PASSWORD_INVALID = 101;
// 焦距范围不合法
public static final int LENS_ZOOM_PARAM_INVALID = 110;
// 聚焦范围不合法
public static final int LENS_FOCUS_PARAM_INVALID = 111;
// 自动聚焦的百分比错误
public static final int LENS_AUTOFOCUS_PARAM_INVALID = 112;
// 夜视模式参数不合法
public static final int LENS_IRMODE_PARAM_INVALID = 113;
// 动态侦测画面灵敏度不合法
public static final int DETECT_MOTION_LEVEL_INVALID = 114;
// 动态侦测声音灵敏度不合法
public static final int DETECT_AUDIO_LEVEL_INVALID = 115;
// 动态侦测日期不合法
public static final int DETECT_WEEKDAY_INVALID = 116;
// 动态侦测开始时间或者结束时间不合法
public static final int DETECT_TIME_PERIOD_INVALID = 117;
// 名字长度超出范围
public static final int CAM_INFO_NAME_INVALID = 118;
// 指示灯开关参数错误
public static final int CAM_INFO_LED_INVALID = 119;
// 旋转参数不合法
public static final int CAM_INFO_ROTATION_INVALID = 120;
// 指定时间段内的视频数据不存在
public static final int CAM_INFO_VIDEO_NOT_EXIST = 121;
// 指定的页码不存在
public static final int CAM_PAGE_NOT_EXIST = 122;
// 人脸分组重名
public static final int GROUP_NAME_EXISTED = 200;
// 人脸分组名称不合法
public static final int GROUP_NAME_INVALID = 201;
// 分组容量超出范围
public static final int GROUP_CAPACITY_INVALID = 202;
// 人脸分组ID不存在
public static final int GROUP_ID_INVALID = 203;
// 指定人脸分组不存在
public static final int GROUP_NOT_EXIST = 204;
// 要删除的人脸分组还有人脸,请先删除分组中的所有人脸
public static final int GROUP_NOT_EMPTY = 205;
// 存在同样的人脸ID
public static final int FACE_ID_EXISTED = 206;
// 指定人脸ID不存在
public static final int FACE_ID_NOT_EXIST = 207;
// 超出人脸分组的容量大小
public static final int GROUP_OVERFLOW = 208;
// 人脸ID操作不允许
public static final int FACE_ID_OP_NOT_ALLOWED = 209;
// 人脸照片不合格
public static final int FACE_ID_PIC_NOT_QUALIFIED = 210;
// 人脸服务未开启
public static final int FACE_SERVICE_NOT_RUNNING = 211;
// 人脸分组描述不合法
public static final int GROUP_DESCRIPTION_INVALID = 212;
// SD卡不存在
public static final int SDCARD_NOT_PLUGGED = 220;
// SD卡格式化失败,原因未知
public static final int SDCARD_FORMAT_FAILED = 221;
// 回放时间参数不正确
public static final int PALYBACK_TIME_INVALID = 230;
// 查询录像时间参数不正确
public static final int RECORD_TIME_INVALID = 231;
// RTSP服务未开启
public static final int RTSP_NOT_RUNNING = 232;
// 截图不成功
public static final int SNAPSHOT_FAILED = 233;
// 查询录像page参数不正确
public static final int RECORD_PAGE_INVALID = 234;
// 录像不存在
public static final int RECORD_NOT_EXIST = 235;
// 剪切的视频还未准备好
public static final int CLIP_FRAGMENT_NOT_READY = 236;
// 视频剪切服务未启动
public static final int CLIP_SERVICE_NOT_RUNNING = 237;
// 人脸属性名称不合法
public static final int ATTRIBUTE_NAME_INVALID = 240;
// 人脸属性重名
public static final int ATTRIBUTE_NAME_EXISTED = 241;
// 人脸属性数量超过最大限制
public static final int ATTRIBUTE_NUM_EXCEED = 242;
// 指定人脸属性不存在
public static final int ATTRIBUTE_NAME_NOT_EXISTED = 243;
// 拌线左边端点X坐标超出范围
public static final int PARAMS_START_X_INVALID = 260;
// 拌线左边端点Y坐标超出范围
public static final int PARAMS_START_Y_INVALID = 261;
// 拌线右边端点X坐标超出范围
public static final int PARAMS_END_X_INVALID = 262;
// 拌线右边端点Y坐标超出范围
public static final int PARAMS_END_Y_INVALID = 263;
// 分辨率设置超出范围
public static final int PARAMS_RESOLUTION_INVALID = 264;
// 人流统计信息粒度参数超出范围
public static final int PARAMS_PERIOD_INVALID = 265;
// 开始时间设置异常,必须使用UNIX时间戳
public static final int PARAMS_START_TIME_INVALID = 266;
// 结束时间设置异常,必须使用UNIX时间戳
public static final int PARAMS_END_TIME_INVALID = 267;
// 查询参数order设置异常
public static final int PARAMS_ORDER_INVALID = 268;
// 查询参数group name设置异常
public static final int PARAMS_GROUP_NAME_INVALID = 269;
// 查询参数gender设置异常
public static final int PARAMS_GENDER_INVALID = 270;
// 查询参数age设置异常
public static final int PARAMS_AGE_INVALID = 271;
// 查询参数age_range设置异常
public static final int PARAMS_AGE_RANGE_INVALID = 272;
// 查询参数page_num设置异常
public static final int PARAMS_PAGE_NUM_INVALID = 273;
// 查询参数page_size设置异常
public static final int PARAMS_PAGE_SIZE_INVALID = 274;
// 查询参数faceid设置异常
public static final int PARAMS_FACE_ID_INVALID = 275;
// 拌线右边端点X坐标-拌线左边端点X坐标差值小于100,距离不足
public static final int PARAMS_X_DISTANCE_INVALID = 276;
// 传入参数不是合理的json table格式
public static final int PARAMS_JSON_TABLE_INVALID = 277;
// 配置保存失败
public static final int SET_CONFIG_FAIL = 278;
// 配置读取失败
public static final int GET_CONFIG_FAIL = 279;
// 数据库中未发现人脸信息
public static final int FACE_ID_INFO_NO_FOUND = 280;
// 查询参数 用户新增人脸属性 设置异常
public static final int TIMEZONE_INVALID = 281;
// 查询参数 用户新增人脸属性值 数据类型设置异常
public static final int DETECT_PEOPLE_DETECT_INVALID = 282;
// 订阅的消息事件不存在
public static final int SUBSCRIBE_EVENT_NOT_EXIST = 310;
}
In order to use the IPC through OpenAPI, the user need to get the IP address of the IPC first.
The first step is to connect the IPC to the network. There are two ways to connect the device to Internet, wired and wireless. Wired network is preferred for its high stability and reliability.
1. Wired Network
For an IPC device with an Ethernet Port, you can connect it to a gateway(such as a wireless router) with an Ethernet cable, then the device can obtain the IP address through the DHCP server.
If the network is available, the LED on the IPC will soon turn blue, indicating that the IPC has connected to the Internet.
2. Wireless Network
The steps to connect to a wireless network are as follows:
Use your mobile phone or PC to scan the wireless hotspot of the IPC. The SSID of the wireless hotspot is SUNMI_XXXX, where XXXX is the hexadecimal number of the last 2 bytes of the MAC address. The MAC address can be found on the label on the back of the device or on the packaging box.
Use your mobile phone or PC to connect to the wireless hotspot. The mobile phone or PC will obtain an IP address assigned by the IPC, which is usually 192.168.200.XXX. The gateway address of mobile phone or PC is the address of IPC, which is usually 192.168.200.1.
Use the wireless configuration API to connect to wireless network. If everything is done correctly, the IPC will obtain the IP address from the gateway.
If the network is available, the LED on the IPC will soon turn blue, indicating that the IPC has connected to the Internet.
3. Get the Device’s IP address
After the setup of IPC’s network, the next step is to get the IP address of the IPC.
SUNMI provides Device Discovery Protocol for discovering all SUNMI devices that support this protocol on the same LAN. It’s used to scan and collect the basic information of the SUNMI devices, including serial number and IP addresss.
4. SUNMI Device Discovery Protocol
The SUNMI Device Discovery Protocol is for one device to broadcast UDP messages to find SUNMI devices in the same LAN, and other devices supporting this protocol will respond to those messages, which include basic informations of themselves.
4.1 Message Format
The Payload of UDP message is shown in the figure below. The whole message consists of header, Payload and CRC checksum.
4.1.1 Header
The Message Header, including flag, protocol version, message type and length.
Flag: currently fixed to 0xFFFF33FF.
Version: protocol version, currently only version 0x1 is supported.
Type: message type, 0x1 for the discovery request message and 0x2 for the discovery response message.
Len: length of the payload before base64 encoding.
4.1.2 Payload
This field contains the final payload. The raw data is in json format, and it needs to be base64 encoded before put on the payload.
4.1.3 CRC
This field contains the CRC32 (32-bit Cyclic Redundancy Check) value calculated from the header and payload fields. The receiver use this value to verify the message.
4.2 Protocol Port
Both sender and receiver use port 10001.
4.3 Discovery Request
When the sender wants to find devices support the SUNMI Device Discovery Protocol in the LAN, it need to send UDP broadcast message. The details are as follows:
In this message, field Type is 0x01, Len is 0x0, it means that the payload is empty.
4.4 Discovery Response
This message is sent by the receiver. It is used to tell the sender the informations of itself. The type is 0x02, and the length is calculated according to the data.
The payload content is shown in the figure below, which is the device information in json format.
ip: the IP address of the device.
mac: the MAC address of the device.
firmware: the firmware version of the device, such as 1.0.0
name: device name, currently fixed as SUNMI.
model: device model, such as FM020.
type: device type, currently fixed as IPC.
network: the mode of network connection about the sender. If the sender is connected to the wireless hotspot of IPC, the value is “AP”. If the sender is connected to same LAN of router with IPC, the value is “LAN”.
deviceid: device serial number.
4.5 Timeout handling
It is suggested to send Discovery Request messages with an interval of 1s, and 3 times at most. This is to prevent loss of messages from some devices.
After sending 3 Request Messages, the sender should set a timeout period of 2s, after which the Discovery Response message will not be received. That means the Discovery Response message can only be received in 5s after the first Discovery Request message.
After receiving a Discovery Request message, the receiver should reply with a Discovery Response message in unicast mode immediately.