SDK流程简介
1. 通用流程图
2. 关键点说明
1) SDK已经封装了所有的用户、配置、发现、连接、控制的过程,开发者使用这些API可以完成上述流程中的功能开发,不需要再自行实现通讯协议。
2) SDK采取回调和block两种工作方式,采取回调的接口必须设置必要的委托,比如通用委托和设备委托,具体请参见流程详解。SDK在主线程中给APP回调。
SDK流程详解
1. 初始化部分
1.1. 初始化部分流程图
1.2. 引用头文件
import <GizWifiSDK/GizWifiSDK.h>
1.3. 设置SDK通用委托
注册SDK通用委托是为了能让APP收到来自GizWifiSDK类的响应事件,包含了配置设备、绑定设备等回调接口。这是SDK使用中十分重要的一个委托,与GizWifiSDK类相关的许多操作都会在这里回调。如果没有正确注册通用委托,将无法正常使用SDK的部分接口。注册委托时,APP可以根据自己的需求实现回调接口。
1.4. 初始化SDK
SDK启动前,任何功能都是无法正常使用的。SDK启动时,会进行SDK初始化,并自动发现当前局域网设备。SDK将通过通用委托,上报已发现的设备以及相应的事件。APP可以先设置SDK的通用委托,再启动SDK,以便处理这些事件通知。
SDK启动时需要指定应用程序的AppID和APPSecret,开发者需要先在机智云网站上为自己的APP申请一个AppID,请在应用的AppDelegate中调用该方法指定应用的AppID和APPSecret。该方法只需要调用一次。
SDK的日志可以帮助开发者发现APP运行时发生的问题。SDK默认将所有日志信息输出到调试终端和日志文件中,日志文件保存在应用程序的Documents\GizWifiSDK\GizSDKLog目录下。APP可以通过日志接口改变日志输出到终端和日志文件的级别。
【示例代码】
// 设置SDK委托
[GizWifiSDK sharedInstance].delegate = self;
// 设置AppInfo
NSDictionary* appInfo = @{@"appId": @"your_app_id", @"appSecret": @"your_app_secret"};
// 设置要过滤的设备productKey列表。不过滤则直接传nil
NSArray *productInfo = [NSArray arrayWithObjects: @{@"productKey": @"your_product_key", @"productSecret": @"your_product_secret"}, nil];
// 指定要切换的域名信息。使用机智云生产环境则传nil
// NSDictionary* cloudServiceInfo = @{@"appApi": @"your_api_domain"};
// 调用SDK的启动接口
[GizWifiSDK startWithAppInfo:appInfo productInfo:productInfo cloudServiceInfo:nil];
// 实现系统事件通知回调
- (void)wifiSDK:(GizWifiSDK *)wifiSDK didNotifyEvent:(GizEventType)eventType eventSource:(id)eventSource eventID:(GizWifiErrorCode)eventID eventMessage: (NSString *)eventMessage {
if(eventType == GizEventSDK) {
// SDK发生异常的通知
NSLog(@"SDK event happened: [%@] = %@", @(eventID), eventMessage);
} else if(eventType == GizEventDevice) {
// 设备连接断开时可能产生的通知
GizWifiDevice* mDevice = (GizWifiDevice*)eventSource;
NSLog(@"device mac %@ disconnect caused by %@", mDevice.macAddress, eventMessage);
} else if(eventType == GizEventM2MService) {
// M2M服务返回的异常通知
NSLog(@"M2M domain %@ exception happened: [%@] = %@", (NSString*)eventSource, @(eventID), eventMessage);
} else if(eventType == GizEventToken) {
// token失效通知
NSLog(@"token %@ expired: %@", (NSString*)eventSource, eventMessage);
}
}
2. 用户部分
机智云的用户系统包含了用户的注册、登录、重置密码、修改个人信息等功能,机智云以APPID区分用户系统,不同APPID的用户系统相互独立。更换APPID后,需要重新注册用户。
2.1. 用户部分主要流程图
用户的注册方式有多种,比如手机号、普通用户名、邮箱等,APP可以根据需要采取不同的方式。其他流程比如登录、密码修改、个人信息修改等部分,请直接阅读下面的流程文档。
2.2. 用户注册
机智云提供三种用户注册方式:手机注册、普通用户注册、邮箱注册。
2.2.1. 注册手机用户
通过手机注册账号,需要一个有效的手机号。注册时需要两步操作:获取短信验证码、用短信验证码注册用户。
第一步:获取短信验证码。SDK向云端发送短信验证码请求,如果请求成功,云端会给手机发送短信验证码。
【示例代码】
[[GizWifiSDK sharedInstance] requestSendPhoneSMSCode:@"your_phone_number" callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 请求短信验证码成功
} else {
// 请求短信验证码失败
}
}];
第二步:用短信验证码注册。APP把手机收到的短信验证码传给SDK,填上手机号和密码就可以注册了。
【示例代码】
[[GizWifiSDK sharedInstance] registerUser:@"your_phone_number" password:@"your_password" verifyCode:@"your_verify_code" accountType:GizUserPhone callback:^(OpenApiLoginResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 注册成功
} else {
// 注册失败
}
}];
2.2.2. 注册普通用户
注册普通用户,使用用户名、密码即可创建一个账号。
【示例代码】
[[GizWifiSDK sharedInstance] registerUser:@"your_user_name" password:@"your_password" verifyCode:nil accountType:GizUserNormal callback:^(OpenApiLoginResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 注册成功
} else {
// 注册失败
}
}];
2.2.3. 注册邮箱用户
通过有效的电子邮箱地址,注册一个账号。注册成功后,云端会给指定邮箱发送注册成功的邮件。
【示例代码】
[[GizWifiSDK sharedInstance] registerUser:@"your_email_address" password:@"your_password" verifyCode:nil accountType:GizUserEmail callback:^(OpenApiLoginResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 注册成功
} else {
// 注册失败
}
}];
2.3. 用户登录
机智云提供四种用户登录方式:短信验证码登录、实名登录、匿名登录、第三方账号登录。短信验证码登录和实名登录适用于设计了登录界面。匿名登录适用于没有设计登录界面,由后台自动生成用户账号的APP。登录后获取到的token有效期为7天。
2.3.1. 实名登录
实名用户登录时,用户名可以是注册过的手机号、邮箱、普通用户名。登录账号要先注册好,如果更换了AppID,登录账号需要重新注册。
【示例代码】
[[GizWifiSDK sharedInstance] userLogin:@"your_username" password:@"your_password" callback:^(OpenApiLoginResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 登录成功
} else {
// 登录失败
}
}];
2.3.2. 手机验证码登录
验证码登录时,需要使用已经注册过的手机号,如果更换了AppID,登录账号需要重新注册。
【示例代码】
[[GizWifiSDK sharedInstance] dynamicLogin:@"your_phone_number" code:@"your_verify_code" callback:^(OpenApiLoginResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 登录成功
} else {
// 登录失败
}
}];
2.3.3. 匿名登录
用户每次匿名登录时,获取到的uid是相同的。匿名用户登录时,如果账号不存在,系统会根据设备唯一标识码,生成一个匿名账号,并登录该账号。
【示例代码】
[[GizWifiSDK sharedInstance] userLoginAnonymous:^(OpenApiLoginResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 登录成功
} else {
// 登录失败
}
}];
2.3.4. 第三方账号登录
目前支持的第三方账号有百度、新浪、QQ、微信、Facebook、Twitter、Google、Amazon。用户可以使用这些API获取到uid和token登录机智云,使用第三方账号登录时无需在机智云上注册,可直接登录。
开发者可通过百度、新浪、QQ、微信、Facebook、Twitter、Google、Amazon的api获取uid和token, 具体方法请参考各第三方平台的开发者文档。也可以使用以下工具获取第三方账号uid、token:
ShareSDK http://mob.com/
【示例代码】
//以qq账号为例
[[GizWifiSDK sharedInstance] userLoginWithThirdAccount:GizThirdQQ uid:@"your_uid" token:@"your_token" tokenSecret:nil callback:^(OpenApiLoginResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 登录成功
} else {
// 登录失败
}
}];
2.4. 重置密码
如果忘记了用户密码,可以通过手机验证码或邮箱设置新的密码。SDK支持手机号重置密码和邮箱重置密码两种,手机号重置需要接收验证码,邮箱重置需要进⼊邮箱,根据链接提示进行重置。
2.4.1. 手机号重置密码
手机号重置密码时,需要先获取短信验证码再重置。获取短信验证码方式与手机注册时相同。
第一步:获取短信验证码
【示例代码】
[[GizWifiSDK sharedInstance] requestSendPhoneSMSCode:@"your_phone_number" callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 请求短信验证码成功
} else {
// 请求短信验证码失败
}
}];
第二步:用短信验证码重置密码
【示例代码】
[[GizWifiSDK sharedInstance] resetPassword:@"your_phone_number" verifyCode:@"your_verify_code" newPassword:@"your_new_password" accountType:GizUserPhone callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 修改成功
} else {
// 修改失败
}
}];
2.4.2.邮箱重置密码
邮箱重置密码时,云端会给指定邮箱发送安全链接。用户需要到邮箱中查收邮件,并按邮件指示执行重置操作。重置密码邮件有可能进入用户的邮箱的垃圾箱中,需提醒用户。
【示例代码】
[[GizWifiSDK sharedInstance] resetPassword:@"your_email_address" verifyCode:nil newPassword:@"your_new_password" accountType:GizUserEmail callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
//重置密码邮件发送成功,提示用户查收
} else {
//重置密码邮件发送失败,弹出错误信息
}
}];
2.5. 修改密码
用户登录后可以修改密码。
【示例代码】
[[GizWifiSDK sharedInstance] changeUserPassword:@"your_old_password" newPassword:@"your_new_password" callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 修改密码成功
} else {
// 修改密码失败
}
}];
2.6. 匿名用户转换
匿名注册的用户可以转换为普通用户或者手机用户,转换后匿名用户的信息会转移到实名用户下,原匿名账号失效。但普通用户和手机用户必须是还未注册过的,已注册的用户名是无法转换的。
2.6.1. 匿名用户转普通用户
转普通用户时,填入待转换的用户名、密码就可以了。
【示例代码】
[[GizWifiSDK sharedInstance] transAnonymousUser:@"your_user_name" password:@"your_password" verifyCode:nil accountType:GizUserNormal callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 匿名用户转换成功
} else {
// 匿名用户转换失败
}
}];
2.6.2. 匿名用户转手机用户
转手机用户时,需要填入待转换的手机号、密码、短信验证码,登录的token。获取短信验证码的过程与手机注册时一样。
【示例代码】
[[GizWifiSDK sharedInstance] transAnonymousUser:@"your_phone_number" password:@"your_password" verifyCode:@"your_verify_code" accountType:GizUserPhone callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 匿名用户转换成功
} else {
// 匿名用户转换失败
}
}];
2.7. 修改用户信息
实名用户不支持修改普通用户名,可以修改邮箱、手机号,可以补充个人信息。实名用户必须登录后才能修改这些信息,并且待修改的邮箱或手机号必须是没有注册过的。
实名用户修改邮箱或手机号成功后,可以使用修改后的邮箱或手机号登录。登录后获得的绑定设备列表与原实名用户一致。
2.7.1. 修改用户邮箱
修改用户邮箱时,用户类型可以指定为邮箱用户。以下为修改用户邮箱的示例代码。
【示例代码】
[[GizWifiSDK sharedInstance] changePhoneOrEmail:@"your_email_address" code:nil accountType:GizUserEmail callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 修改账号成功
} else {
// 修改账号失败
}
}];
2.7.2. 修改用户手机号
修改用户手机号时,用户类型可以指定为手机用户。修改手机号之前,需要先获取手机验证码。以下示例代码为修改用户手机号的代码,获取短信验证码的代码请参考手机号注册。
【示例代码】
[[GizWifiSDK sharedInstance] changePhoneOrEmail:@"your_phone_number" code:@"your_verify_code" accountType:GizUserPhone callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 修改账号成功
} else {
// 修改账号失败
}
}];
2.7.3. 修改用户个人信息
个人信息包含多项内容,通过GizOpenApiUser类指定。其中不想修改的信息填nil,云端会保留上次修改过的值。
【示例代码】
GizOpenApiUser *newUserInfo = [GizOpenApiUser new];
newUserInfo.userGender = GizUserGenderFemale;
newUserInfo.name = @"your_new_name";
newUserInfo.language = GIZ_LANGUAGE_EN;
newUserInfo.address = @"your_address";
newUserInfo.birthday = @"your_birthday";
[[GizWifiSDK sharedInstance] changeUserInfo:newUserInfo callback:^(OpenApiResult * _Nonnull result) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 修改用户信息成功
} else {
// 修改用户信息失败
}
}];
3. 配置设备入网部分
控制设备前,需要先让设备连到路由器上。连上路由器的设备,如果路由器能接入外网,设备会自动注册到机智云。
有两种配置方式能够让设备连到路由器上,一种是Airlink方式,一种是Softap方式,APP可以根据产品需求采取相应的配置方式。在开始配置前,设备要先进入配置模式,然后APP调用配置接口发送要配置的路由器ssid和密码。设备配置成功后,SDK给APP返回已配置成功的设备对象。
SDK的设备配置接口如果超时时间还未结束,无法进行下一次配置。此外,因为设备配置成功的广播包只有APP连到同一路由上才能收取,因此这个超时时间应该预留出APP连接到路由器的时间。
需要注意的是,如果配置上线的设备不是APP要获取的产品类型,该设备就不会出现在设备列表中。
3.1. 设备配置流程图
3.2. AirLink配置
AirLink使⽤UDP广播方式,由手机端发出含有目标路由器名称和密码的广播,设备上的Wifi模块接收到广播包后自动连接目标路由器,连上路由器后发出配置成功广播,通知手机配置已完成。
模块开启AirLink模式后,如果一分钟内未收到AirLink广播或无法正确连上路由器,将进入SoftAP模式。
【示例代码】
[GizWifiSDK sharedInstance].delegate = self;
// airlink配置
[[GizWifiSDK sharedInstance] setDeviceOnboardingDeploy:@"your_ssid" key:@"your_key" configMode:GizWifiAirLink softAPSSIDPrefix:nil timeout:60 wifiGAgentType:@[@(GizGAgentESP)] ];
// 实现回调
- (void)wifiSDK:(GizWifiSDK *)wifiSDK didSetDeviceOnboarding:(NSError *)result device:(GizWifiDevice *)device {
if(result.code == GIZ_SDK_SUCCESS) {
// 配置成功
} else {
// 配置失败
}
}
3.3. SoftAP配置
设备进入SoftAP模式后,会产生一个Wifi热点。手机连上此热点后,将要配置的SSID和密码发给设备。设备上的Wi-Fi模块接收到SoftAP配置包后自动连接目标路由器,与airlink一样,连上路由器后发出配置成功广播,通知手机配置已完成。
使用机智云提供的模组固件,设备产生的Wifi热点以“XPG-GAgent-”开头,密码为” 123456789”。其他厂商提供的模组,SoftAP热点名称由各自厂商指定。APP可以根据需要传入正确的热点前缀。
【示例代码】
// MCU发出进入SoftAP串口指令,通知模组开启SoftAP模式。
详情请参考《智能云空调-机智云接入串口通信协议文档》
//让手机连接模组的SoftAP热点
//配置设备入网,发送要配置的wifi名称、密码
[GizWifiSDK sharedInstance].delegate = self;
[[GizWifiSDK sharedInstance] setDeviceOnboardingDeploy:@"your_ssid" key:@"your_key" configMode:GizWifiSoftAP softAPSSIDPrefix:@"your_gagent_hotspot_prefix" timeout:60 wifiGAgentType:@[@(GizGAgentESP)]];
//模块收到配置信息,尝试连接路由器并自动关闭热点
//让手机连接到配置的wifi上
//等待配置完成或超时,回调配置完成接口
- (void)wifiSDK:(GizWifiSDK *)wifiSDK didSetDeviceOnboarding:(NSError *)result device:(GizWifiDevice *)device {
if(result.code == GIZ_SDK_SUCCESS) {
// 配置成功
} else {
// 配置失败
}
}
4. 设备发现和订阅部分
4.1. 设备发现和订阅流程图
4.2. 设备发现
APP设置好委托,启动SDK后,就可以收到SDK的设备列表推送。每次局域网设备或者用户绑定设备发生变化时,SDK都会主动上报最新的设备列表。设备断电再上电、有新设备上线等都会触发设备列表发生变化。用户登录后,SDK会主动把用户已绑定的设备列表上报给APP,绑定设备在不同的手机上登录帐号都可获取到。
如果APP想要刷新绑定设备列表,可以调用绑定设备列表接口,同时可以指定自己关心的产品类型标识,SDK会把筛选后的设备列表返回给APP。
SDK提供设备列表缓存,设备列表中的设备对象在整个APP生命周期中一直有效。缓存的设备列表会与当前最新的已发现设备同步更新。
【示例代码】
// 使用缓存的设备列表刷新UI
NSArray* devices = [GizWifiSDK sharedInstance].deviceList;
// 实现回调
- (void)wifiSDK:(GizWifiSDK* _Nonnull)wifiSDK didDiscovered:(GizError* _Nonnull)result deviceList:(NSArray <GizWifiDevice*>* _Nullable)deviceList {
// 提示错误原因
if(result.code != GIZ_SDK_SUCCESS) {
NSLog(@"result: %@", result.localizedDescription);
}
// 显示设备列表
NSLog(@"discovered deviceList: %@", deviceList);
}
[GizWifiSDK sharedInstance].delegate = self;
[[GizWifiSDK sharedInstance] getBoundDevicesSpecialProductKeys:[NSArray arrayWithObjects: @"your_product_key", nil]];
4.3. 设置设备的委托
在设备列表中得到设备对象,为其设置设备委托,以便于刷新设备UI。APP根据自己的需要实现相应的回调。
4.4. 设备订阅和绑定
APP得到设备列表后,给设备设置委托后,可以订阅设备。已订阅的设备将被自动绑定和自动登录,设备登录成功后会主动上报最新状态。
自动绑定仅限于局域网设备。对于无法在局域网内发现的设备,APP可以通过手动绑定的方式完成绑定。绑定成功的设备,需要订阅后才能使用。
无论是手动绑定还是自动绑定,设备的remark和alias信息,都需要在设备绑定成功后再设置。
解除订阅的设备,连接会被断开,不能再继续下发控制指令了。
4.4.1. 设备订阅
所有通过SDK得到的设备,都可以订阅,订阅结果通过回调返回。订阅成功的设备,要在其网络状态变为可控时才能查询状态和下发控制指令。
【示例代码】
// 以设备列表中的第一个设备实例为例,为其设置委托
GizWifiDevice* mDevice = nil;
for (int i = 0; i < deviceList.count; i++) {
mDevice = deviceList[0];
mDevice.delegate = self;
[mDevice setSubscribe:YES autoGetDeviceStatus:YES];
break;
}
// 实现回调
- (void)device:(GizWifiDevice *)device didSetSubscribe:(GizError *)result isSubscribed:(BOOL)isSubscribed {
if(result.code == GIZ_SDK_SUCCESS) {
// 订阅或取消订阅成功
}
}
4.4.2. 非局域网设备绑定
APP可以通过设备的mac、productKey、productSecret完成非局域网设备的绑定,可以用上述信息生成二维码,APP通过扫码方式绑定。GPRS设备、蓝牙设备等都是无法通过Wifi局域网发现的设备,都属于非局域网设备。
【示例代码】
[[GizWifiSDK sharedInstance] bindDevice:@"your_mac" productKey:@"your_product_key" alias:nil callback:^(OpenApiResult * _Nonnull result, NSString * _Nullable did) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 绑定成功
} else {
// 绑定失败
}
}
4.4.3. 设置设备绑定信息
不订阅设备也可以设置设备的绑定信息。在设备列表中找到要修改的设备,如果是已绑定的,就可以修改remark和alias信息。
【示例代码】
// mDevice是从设备列表中获取到的设备实体对象,为其设置委托
mDevice.delegate = self;
[mDevice setCustomInfo:@"your_remark" alias:@"your_alias"];
// 实现回调
- (void)device:(GizWifiDevice * _Nonnull)device didSetCustomInfo:(GizError * _Nonnull)result {
if(result.code == GIZ_SDK_SUCCESS) {
// 修改成功
} else {
// 修改失败
}
}
4.5. 设备解绑
已绑定的设备可以解绑,解绑需要APP调用接口完成操作,SDK不支持自动解绑。对于已订阅的设备,解绑成功时会被解除订阅,同时断开设备连接,设备状态也不会再主动上报了。设备解绑后,APP刷新绑定设备列表时就得不到该设备了。
【示例代码】
[[GizWifiSDK sharedInstance] unbindDevices:@[device] callback:^(OpenApiResult * _Nonnull result, NSArray * _Nullable successDids) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 解绑成功
} else {
// 解绑失败
}
}];
4.6. 获取硬件信息
不订阅设备也可以获取硬件信息。APP可以获取模块协议版本号,mcu固件版本号等硬件信息,但只有局域网设备才支持该功能。
【示例代码】
// mDevice是从设备列表中获取到的设备实体对象,为其设置委托
mDevice.delegate = self;
[mDevice getHardwareInfo];
// 实现回调
- (void)device:(GizWifiDevice * _Nonnull)device didGetHardwareInfo:(GizError * _Nonnull)result hardwareInfo:(NSDictionary <NSString *, NSString *>* _Nullable)hardwareInfo {
if(result.code == GIZ_SDK_SUCCESS) {
// 获取成功
NSString *hardWareInfo = [NSString stringWithFormat:@"WiFi Hardware Version: %@,\
WiFi Software Version: %@,\
MCU Hardware Version: %@,\
MCU Software Version: %@,\
Firmware Id: %@,\
Firmware Version: %@,\
Product Key: %@“
, [hwInfo valueForKey: @"wifiHardVersion"]
, [hwInfo valueForKey: @"wifiSoftVersion"]
, [hwInfo valueForKey: @"mcuHardVersion"]
, [hwInfo valueForKey: @"mcuSoftVersion"]
, [hwInfo valueForKey: @"wifiFirmwareId"]
, [hwInfo valueForKey: @"wifiFirmwareVer"]
, [hwInfo valueForKey: @"productKey"];
} else {
// 获取失败
}
}
5. 设备控制部分
SDK通过字典键值对方式进行设备控制和状态接收。SDK接收到APP下发的指令字典后,对应解析为设备可识别的数据,发送给设备。反之,SDK收到设备回复或上报的数据后,对应解析为字典键值对上报给APP。
智能设备需正确烧写了GAgent固件和机智云串口通讯协议。如果设备定义了数据点,APP发送的指令必须符合数据点定义。如果设备没有定义数据点,设备指令可以按照透传数据以自定义格式下发。
5.1. 设备控制流程图
5.2. 发送控制指令
设备订阅变成可控状态后,APP可以发送控制指令。控制指令是字典格式,键值对为数据点名称和值。操作指令的确认回复,通过didReceiveData回调返回。
APP下发操作指令时可以指定sn,通过回调参数中的sn能够对应到下发指令是否发送成功了。但回调参数dataMap有可能是空字典,这取决于设备回复时是否携带当前数据点的状态。
如果APP下发指令后只关心是否有设备状态上报,那么下发指令的sn可填0,这时回调参数sn也为0。
【示例代码】
//在设备列表中得到设备对象,设置委托
mDevice.delegate = self;
// 对已订阅变为可控状态的设备,发送开灯指令
int sn = 5;
[mDevice write:@{@"LED_OnOff": @(YES)} withSN:@(sn)];
// 实现回调
- (void)device:(GizWifiDevice *)device didReceiveData:(GizError *)result attrStatus:(NSDictionary *)attrStatus withSN:(NSNumber *)sn {
if(result.code == GIZ_SDK_SUCCESS && sn == 5) {
// 命令序号相符,开灯指令执行成功
} else {
// 执行失败
}
}
5.3. 接收设备状态
设备订阅变成可控状态后,APP可以随时收到设备状态的主动上报,仍然通过didReceiveData回调返回。设备上报状态时,回调参数sn为0,回调参数dataMap为设备上报的状态。
【示例代码】
- (void)device:(GizWifiDevice *)device didReceiveData:(GizError *)result attrStatus:(NSDictionary *)attrStatus withSN:(NSNumber *)sn {
//基本数据,与发送的数据格式⼀一致
NSDictionary *data = [attrStatus valueForKey:@"data"];
// 报警
NSArray *alarms = [attrStatus valueForKey:@"alerts"];
// 故障
NSArray *faults = [attrStatus valueForKey:@"faults"];
//透传数据
NSDictionary *binary = [attrStatus valueForKey:@“binary"];
//处理这些类型的数据
}
5.4. 设备状态查询
设备订阅变成可控状态后,APP可以查询设备状态。设备状态查询结果也通过didReceiveData回调返回,回调参数sn为0。回调参数dataMap为设备回复的状态。
【示例代码】
// mDevice是从设备列表中获取到的设备实体对象,为其设置委托
mDevice.delegate = self;
[mDevice getDeviceStatus:nil];
- (void)device:(GizWifiDevice *)device didReceiveData:(GizError *)result attrStatus:(NSDictionary *)attrStatus withSN:(NSNumber *)sn {
if(result.code == GIZ_SDK_SUCCESS) {
// 数据解析与3.5.3相同
} else {
// 查询失败
}
}
6. 设备定时任务
通过给设备设置定时任务,可以让设备在预定的日期和时间执行某些操作。这些操作可以在一个月内的某几天重复,也可以在一周内的某几天重复。
定时任务可以先设定好,然后在任何时候开始执行或停止执行。定时任务创建时默认开启。
6.1. 流程图
6.2. 创建定时任务
定时任务可以重复执行,也可以只执行一次,重复执行分为按月重复和按周重复。但同时只能指定一种重复方式,即或者不重复或者按周重复或者按月重复。
下面分别以这三种情况举例说明。
6.2.1. 创建一次性定时任务
假设我们需要在2020年10月12日早上6点30分开灯。如下代码中,日期和时间想要设置为几月几日几时几分,就设定为对应的值。
比如我们希望设定的是2020年10月12日早上6点30分,那么date为2020-10-12,time为06:30,其中time是24小时制,date按照示例代码格式传值即可。
【示例代码】
NSDictionary *attr = @{@"LED_OnOff": @YES};
NSString *time = @"06:30";
NSString *date = @"2020-10-12";
NSNumber *enable = @(YES);
NSString *remark = @"一次性开灯任务";
GizScheduler *schduler = [GizScheduler schedulerOneTime:@"your_device_did" attrs:attr date:date time:time enabled:enable.boolValue remark:remark];
[GizSchedulerManager createScheduler:schduler callback:^(OpenApiResult * _Nonnull result, NSString * _Nonnull schdulerId) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 定时任务创建成功
} else {
// 创建失败
}
}];
6.2.2. 创建按周重复的定时任务
我们现在让定时任务按周重复执行,现在要每周的周一至周五早上6点30分都开灯。
【示例代码】
// 每周一到周五重复执行的定时任务
NSDictionary *attr = @{@"LED_OnOff": @YES};
NSArray *weekDays = @[@GizScheduleMonday, @GizScheduleTuesday, @GizScheduleWednesday, @GizScheduleThursday, @GizScheduleFriday];
NSString *time = @"06:30";
NSNumber *enable = @(YES);
NSString *remark = @"按周重复执行的开灯任务";
GizScheduler *schduler = [GizScheduler schedulerWeekRepeat:@"your_device_did" attrs:attr time:time weekDays:weekDays enabled:enable.boolValue remark:remark];
[GizSchedulerManager createScheduler:schduler callback:^(OpenApiResult * _Nonnull result, NSString * _Nonnull schdulerId) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 定时任务创建成功
} else {
// 创建失败
}
}];
6.2.3. 创建按月重复的定时任务
我们现在让定时任务按周重复执行,现在要每个月的1号、15号早上6点30分都开灯。
【示例代码】
// 每月1号和15号重复执行的定时任务
NSDictionary *attr = @{@"LED_OnOff": @YES};
NSArray *monthDays = @[@(1), @(15)];
NSString *time = @"06:30";
NSNumber *enable = @(YES);
NSString *remark = @"按月重复执行的开灯任务";
GizScheduler *schduler = [GizScheduler schedulerDayRepeat:@"your_device_did" attrs:attr time:time monthDays:monthDays enabled:enable.boolValue remark:remark];
[GizSchedulerManager createScheduler:schduler callback:^(OpenApiResult * _Nonnull result, NSString * _Nonnull schdulerId) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 定时任务创建成功
} else {
// 创建失败
}
}];
6.3. 获取定时任务列表
创建定时任务后,可以通过查询得到已经创建好的所有定时任务列表。得到定时任务列表后,可以对已经创建好的定时任务做修改或删除。
【示例代码】
[GizSchedulerManager getSchedulerList:@"your_device_did" callback:^(OpenApiResult * _Nonnull result, NSArray<GizScheduler *> * _Nonnull schedulerList) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 定时任务列表同步更新成功
} else {
// 同步更新失败
}
}];
6.4. 修改定时任务
可以修改已经创建好的定时任务。修改时,从获取到的定时任务列表中取出定时任务对象,编辑好要修改的内容。 注意,一旦定时任务创建好之后,就被分配了一个ID,这个ID是不能被修改的。
【示例代码】
// 把之前创建好的一次性定时任务修改成每月1号和15号重复执行的定时任务,scheduler是定时任务列表中要修改的定时任务对象
scheduler.time = @"06:30";
scheduler.remark = @"开灯任务";
scheduler.attrs = @{@"LED_OnOff": @YES};
scheduler.monthDays = @[@1, @15];
scheduler.type = GizSchedulerDayRepeat;
[GizSchedulerManager editScheduler:scheduler callback:^(OpenApiResult * _Nonnull result, NSString * _Nonnull schdulerId) {
if(result.error.code == GIZ_SDK_SUCCESS) {
// 定时任务创建成功
} else {
// 创建失败
}
}];
6.5. 删除定时任务
在得到的定时任务列表中,找到要删除的定时任务ID,删除定时任务。
【示例代码】
// your_scheduler_id 是你要删除的定时任务id
[GizSchedulerManager deleteScheduler:@"your_scheduler_id" callback:^(OpenApiResult * _Nonnull result) {
r = result;
[expectation fulfill];
}];