更新时间:2024-08-22 03:23:45下载pdf
使用当前网关设备替换目标网关设备。例如,当一个网关产生故障时,将该网关下的设备一个个地迁移到其它网关下,操作比较繁琐。使用此功能,可以一次性将故障网关下的全部设备迁移到新网关下。
另外,此功能还可以将群组、场景和自动化迁移到新网关下。
source 'https://github.com/tuya/tuya-pod-specs.git'
platform :ios, '11.0'
target 'Your_Project_Name' do
pod "ThingSmartBusinessExtensionKit"
end
网关替换状态
public enum ThingGatewayTransferStatus {
case unknown = 0
case deviceConfigInit = 1
case deviceDataInit = 2
case osConfigInit = 3
case finish = 4
case failed = 5
case none = 6
}
网关替换信息
open class ThingGatewayTransferInfo : NSObject {
/// The device ID of the faulty gateway
open var targetDeviceId: String
/// The device name of the faulty gateway
open var targetDeviceName: String
/// The device ID of the source gateway
open var sourceDeviceId: String
/// The status of transfer
open var status: ThingGatewayTransferStatus
/// The failure code, returned when failed
open var failedCode: String
/// The time in millisecond when status changed.
open var time: Double
}
网关替换回调
public protocol ThingGatewayTransferManagerDelegate : NSObjectProtocol {
func transferManager(_ manager: ThingGatewayTransferManager, statusDidUpdate model: ThingGatewayTransferInfo)
}
网关替换管理类
open class ThingGatewayTransferManager : NSObject {
...
}
在使用替换故障网关功能时,先判断设备是否支持替换故障网关。
本方法是一个类方法,与其功能相同的还有一个实例方法 deviceSupportsTransfer(success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
deviceId | string | 设备 ID |
success | block | 成功回调 |
failure | block | 失败回调 |
/// Determine whether the device supports transfer or not. True means yes, and false means no.
/// - Parameters:
/// - deviceId: the ID of the device which you want to transfer.
/// - success: success callback.
/// - failure: failure callback with error.
open class func deviceSupportsTransfer(_ deviceId: String, success: @escaping (Bool) -> Void, failure: @escaping (Error) -> Void)
通过该接口,您可以查询到当前网关设备的替换状态。在进行替换之前,应该通过本方法查询网关替换信息,确认网关是否正在替换中。
本方法是一个类方法,与其功能相同的还有一个 实例方法 deviceTransferInfo(success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
deviceId | string | 设备 ID |
success | block | 成功回调 |
failure | block | 失败回调 |
/// Get the transfer info of the device.
/// You can only call this method when the 'deviceSupportsTransfer:success:failure:' or 'deviceSupportsTransferWithSuccess:failure:' succeeds with true.
/// - Parameters:
/// - deviceId: the ID of the device which you want to transfer.
/// - success: success callback with ThingGatewayTransferInfo.
/// - failure: failure callback with error.
open class func deviceTransferInfo(withDeviceId deviceId: String, success: @escaping (ThingGatewayTransferInfo) -> Void, failure: @escaping (Error) -> Void)
本方法是一个类方法,与其功能相同的还有一个 实例方法 gateways(success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
deviceId | string | 设备 ID |
success | block | 成功回调 |
failure | block | 失败回调 |
/// Get the list of gateways.
/// You can only call this method when the 'deviceSupportsTransfer:success:failure:' or 'deviceSupportsTransferWithSuccess:failure:' succeeded with true.
/// - Parameters:
/// - deviceId: the ID of the device which you want to transfer.
/// - success: success callback with the device ID of gateways.
/// - failure: failure callback with error.
open class func gateways(withDeviceId deviceId: String, success: @escaping ([String]) -> Void, failure: @escaping (Error) -> Void)
在进行网关替换之前,应先判断设备是否支持网关替换,并判断设备是否在替换中。
本方法是一个类方法,与其功能相同的还有一个 实例方法 transfer(fromGateway:, success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
from | string | 被替换的旧网关的设备 ID |
to | string | 用于替换的新网关的设备 ID |
success | block | 成功回调 |
failure | block | 失败回调 |
/// Transfer the device to the specified gateway.
/// You can only call this method when the 'deviceSupportsTransfer:success:failure:' or 'deviceSupportsTransferWithSuccess:failure:' succeeded with true.
/// - Parameters:
/// - from: the device ID of the old gateway, which is one of the result returned by 'retrieveDeviceTransferGatewaysWithSuccess:failure:'.
/// - to: the device ID of the new gateway.
/// - success: success callback.
/// - failure: failure callback with error.
open class func transfer(fromGateway from: String, toGateway to: String, success: @escaping (ThingGatewayTransferInfo) -> Void, failure: @escaping (Error) -> Void)
在使用替换故障网关功能时,先判断设备是否支持替换故障网关。
本方法是一个实例方法,与其功能相同的还有一个 类方法 deviceSupportsTransfer(_:, success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
success | block | 成功回调 |
failure | block | 失败回调 |
/// Determine whether the device supports transfer or not. True means yes, and false means no.
/// - Parameters:
/// - success: success callback.
/// - failure: failure callback with error.
open func deviceSupportsTransfer(success: @escaping (Bool) -> Void, failure: @escaping (Error) -> Void)
通过该接口,您可以查询到当前网关设备的替换状态。在进行替换之前,应该通过本方法查询网关替换信息,确认网关是否正在替换中。
本方法是一个实例方法,与其功能相同的还有一个 类方法 deviceTransferInfo(deviceId:, success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
success | block | 成功回调 |
failure | block | 失败回调 |
/// Get the transfer info of the device.
/// You can only call this method when the 'deviceSupportsTransfer:success:failure:' or 'deviceSupportsTransferWithSuccess:failure:' succeeded with true.
/// - Parameters:
/// - success: success callback with ThingGatewayTransferInfo.
/// - failure: failure callback with error.
open func deviceTransferInfo(success: @escaping (ThingGatewayTransferInfo) -> Void, failure: @escaping (Error) -> Void)
本方法是一个实例方法,与其功能相同的还有一个 类方法 gateways(deviceId:, success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
success | block | 成功回调 |
failure | block | 失败回调 |
/// Get the list of gateways.
/// You can only call this method when the 'deviceSupportsTransfer:success:failure:' or 'deviceSupportsTransferWithSuccess:failure:' succeeded with true.
/// - Parameters:
/// - success: success callback with the device ID of gateways.
/// - failure: failure callback with error.
open func gateways(success: @escaping ([String]) -> Void, failure: @escaping (Error) -> Void)
在进行网关替换之前,应先判断设备是否支持网关替换,并判断设备是否在替换中。
本方法是一个实例方法,与其功能相同的还有一个 类方法 transfer(fromGateway:, toGateway:, success:, failure:)
。
入参 | 类型 | 说明 |
---|---|---|
gatewayId | string | 被替换网关的设备 ID |
success | block | 成功回调 |
failure | block | 失败回调 |
/// Transfer the device to the specified gateway.
/// You can only call this method when the 'deviceSupportsTransfer:success:failure:' or 'deviceSupportsTransferWithSuccess:failure:' succeeded with true.
/// - Parameters:
/// - gatewayId: the device ID of the gateway, which is one of the result returned by 'retrieveDeviceTransferGatewaysWithSuccess:failure:'.
/// - success: success callback.
/// - failure: failure callback with error.
open func transfer(fromGateway gatewayId: String, success: @escaping (ThingGatewayTransferInfo) -> Void, failure: @escaping (Error) -> Void)
入参 | 类型 | 说明 |
---|---|---|
listener | ThingGatewayTransferManagerDelegate | 监听者 |
/// Add a listener.
/// - Parameter listener: the listener which confirms ThingGatewayTransferManagerDelegate.
open func addListener(_ listener: ThingGatewayTransferManagerDelegate)
入参 | 类型 | 说明 |
---|---|---|
listener | ThingGatewayTransferManagerDelegate | 监听者 |
/// Remove a listener.
/// - Parameter listener: the listener which confirms ThingGatewayTransferManagerDelegate.
open func removeListener(_ listener: ThingGatewayTransferManagerDelegate)
更多信息,参考 Demo。
import UIKit
import SnapKit
class GatewayTransferController: UIViewController {
var deviceId: String
var ids: [String]?
lazy var label: UILabel = {
let view = UILabel(frame: CGRectZero)
view.textColor = UIColor.green
view.textAlignment = .center
return view
}()
lazy var manager: ThingGatewayTransferManager = {
let manager = ThingGatewayTransferManager.init(deviceId: self.deviceId)
return manager
}()
lazy var tableview: UITableView = {
return UITableView(frame: CGRectZero, style: .grouped)
}()
init(deviceId: String) {
self.deviceId = deviceId
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.view.addSubview(self.label)
self.label.snp.makeConstraints { make in
make.left.equalTo(0)
make.right.equalTo(0)
make.top.equalTo(100)
make.height.equalTo(30)
}
self.view.addSubview(self.tableview)
self.tableview.snp.makeConstraints { make in
make.left.right.equalTo(0)
make.top.equalTo(self.label.snp.bottom)
make.bottom.equalTo(-self.view.safeAreaInsets.bottom)
}
self.tableview.delegate = self
self.tableview.dataSource = self
self.manager.addListener(self)
self.loadData()
}
func loadData() {
SVProgressHUD.show()
self.manager.deviceSupportsTransfer {[weak self] support in
self?.manager.deviceTransferInfo(success: { info in
if (info.status == .none) {
self?.manager.gateways(success: { ids in
self?.ids = ids;
self?.label.text = "support"
SVProgressHUD.dismiss()
}, failure: { e in
self?.ids = nil;
self?.label.text = "support"
SVProgressHUD.dismiss()
})
}else{
self?.label.text = "device is transferring"
SVProgressHUD.dismiss()
}
}, failure: { e in
self?.label.text = "do not support"
SVProgressHUD.dismiss()
})
} failure: {[weak self] e in
self?.label.text = "do not support"
SVProgressHUD.dismiss()
}
}
}
extension GatewayTransferController: ThingGatewayTransferManagerDelegate {
func transferManager(_ manager: ThingGatewayTransferManager, statusDidUpdate model: ThingGatewayTransferInfo) {
if (model.status == .failed || model.status == .finish) {
SVProgressHUD.dismiss()
self.loadData()
}
}
}
extension GatewayTransferController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.ids != nil ? self.ids!.count : 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: .value1, reuseIdentifier: "cell")
}
cell?.textLabel?.text = self.ids![indexPath.row]
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.transfer(self.ids![indexPath.row])
}
func transfer(_ id: String) {
SVProgressHUD.show()
self.manager.transfer(fromGateway: id) { ThingGatewayTransferInfo in
} failure: { e in
}
}
}
展示如何实现简单的替换故障网关功能。
首先,简单实现一个界面。
界面初始化的时候,传入 deviceId
作为当前的设备 ID。
界面会展示一个 UILabel
和一个 UITableView
。此时,UILabel
不展示任何文案,UITableView
的分组为 1
,行数为 0
。另外,将会以 value1
的样式来创建 cell
。
import UIKit
import SnapKit
class GatewayTransferController: UIViewController {
var deviceId: String
lazy var label: UILabel = {
let view = UILabel(frame: CGRectZero)
view.textColor = UIColor.green
view.textAlignment = .center
return view
}()
lazy var tableview: UITableView = {
return UITableView(frame: CGRectZero, style: .grouped)
}()
init(deviceId: String) {
self.deviceId = deviceId
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.view.addSubview(self.label)
self.label.snp.makeConstraints { make in
make.left.equalTo(0)
make.right.equalTo(0)
make.top.equalTo(100)
make.height.equalTo(30)
}
self.view.addSubview(self.tableview)
self.tableview.snp.makeConstraints { make in
make.left.right.equalTo(0)
make.top.equalTo(self.label.snp.bottom)
make.bottom.equalTo(-self.view.safeAreaInsets.bottom)
}
self.tableview.delegate = self
self.tableview.dataSource = self
}
}
extension GatewayTransferController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: .value1, reuseIdentifier: "cell")
}
return cell!
}
}
接下来,懒加载一个 ThingGatewayTransferManager
实例 manager
。
class GatewayTransferController: UIViewController {
lazy var manager: ThingGatewayTransferManager = {
let manager = ThingGatewayTransferManager.init(deviceId: self.deviceId)
return manager
}()
}
之后,通过 ThingGatewayTransferManager.deviceSupportsTransfer(success:failure:)
接口,判断设备是否支持替换故障网关。
label
的文案设置为 support。label
的文案设置为 do not support,且流程到此结束。class GatewayTransferController: UIViewController {
override func viewDidLoad() {
...
self.loadData()
}
func loadData() {
SVProgressHUD.show()
self.manager.deviceSupportsTransfer {[weak self] support in
self?.label.text = "support"
SVProgressHUD.dismiss()
} failure: {[weak self] e in
self?.label.text = "do not support"
SVProgressHUD.dismiss()
}
}
}
当设备支持替换故障网关时,可以通过 ThingGatewayTransferManager.deviceTransferInfo(success:failure:)
来获取设备当前的迁移状态。当接口成功时,会返回网关迁移信息 info
。
如果 info
的 status
为 none
、finish
或 failed
,表示没有在迁移中,此时可以进行迁移。否则,表示设备在迁移中。
class GatewayTransferController: UIViewController {
func loadData() {
SVProgressHUD.show()
self.manager.deviceSupportsTransfer {[weak self] support in
self?.manager.deviceTransferInfo(success: { info in
if (info.status == .none || info.status == .finish || info.status == .failed) {
self?.label.text = "support"
SVProgressHUD.dismiss()
}else{
self?.label.text = "device is transferring"
SVProgressHUD.dismiss()
}
}, failure: { e in
self?.label.text = "support"
SVProgressHUD.dismiss()
})
} failure: {[weak self] e in
self?.label.text = "do not support"
SVProgressHUD.dismiss()
}
}
}
当设备不在迁移中时,通过 ThingGatewayTransferManager.gateways(success:failure:)
获取设备当前家庭下的网关列表,后续可以用当前设备来替换此网关列表中的任意网关。获取到的网关列表将存放到 ids
的数组中,方便后续渲染界面。
class GatewayTransferController: UIViewController {
var ids: [String]?
func loadData() {
SVProgressHUD.show()
self.manager.deviceSupportsTransfer {[weak self] support in
self?.manager.deviceTransferInfo(success: { info in
if (info.status == .none) {
self?.manager.gateways(success: { ids in
self?.ids = ids;
self?.label.text = "support"
SVProgressHUD.dismiss()
}, failure: { e in
self?.ids = nil;
self?.label.text = "support"
SVProgressHUD.dismiss()
})
}else{
self?.label.text = "device is transferring"
SVProgressHUD.dismiss()
}
}, failure: { e in
self?.label.text = "support"
SVProgressHUD.dismiss()
})
} failure: {[weak self] e in
self?.label.text = "do not support"
SVProgressHUD.dismiss()
}
}
}
现在已经获取了需要被替换的网关列表,可以使用之前的 tableview
来展示处理。
extension GatewayTransferController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.ids != nil ? self.ids!.count : 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell?.textLabel?.text = self.ids![indexPath.row]
return cell!
}
}
当用户单击 cell
、选择某个网关 ID 的时候,可以通过 ThingGatewayTransferManager.transfer(fromGateway:success:failure:)
来将其替换掉。
extension GatewayTransferController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.transfer(self.ids![indexPath.row])
}
func transfer(_ id: String) {
SVProgressHUD.show()
self.manager.transfer(fromGateway: id) { ThingGatewayTransferInfo in
} failure: { e in
}
}
}
替换故障网关后,通过 ThingGatewayTransferManager
的 listener
来通知替换结果。因此,还需要完成最后一步,注册 listener
并实现 ThingGatewayTransferManagerDelegate.transferManager(_:statusDidUpdate:)
方法。
class GatewayTransferController: UIViewController {
override func viewDidLoad() {
...
self.manager.addListener(self)
...
}
}
extension GatewayTransferController: ThingGatewayTransferManagerDelegate {
func transferManager(_ manager: ThingGatewayTransferManager, statusDidUpdate model: ThingGatewayTransferInfo) {
if (model.status == .failed || model.status == .finish) {
SVProgressHUD.dismiss()
self.loadData()
}
}
}
至此,简单的 Demo 已经完成。更多信息,参考 Demo。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈