Last Updated on : 2024-08-22 03:29:14download
Replace a gateway with the current gateway. For example, when a gateway fails, it can be quite cumbersome to migrate the devices connected to that gateway one by one to another gateway. With the replacement feature, users can complete the migration in one go.
Additionally, the groups, scenes, and automations can also be migrated to the new gateway.
source 'https://github.com/tuya/tuya-pod-specs.git'
platform :ios, '11.0'
target 'Your_Project_Name' do
pod "ThingSmartBusinessExtensionKit"
end
Gateway replacement status
public enum ThingGatewayTransferStatus {
case unknown = 0
case deviceConfigInit = 1
case deviceDataInit = 2
case osConfigInit = 3
case finish = 4
case failed = 5
case none = 6
}
Gateway replacement information
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 milliseconds when status changed.
open var time: Double
}
Gateway replacement callback
public protocol ThingGatewayTransferManagerDelegate : NSObjectProtocol {
func transferManager(_ manager: ThingGatewayTransferManager, statusDidUpdate model: ThingGatewayTransferInfo)
}
Gateway replacement manager
open class ThingGatewayTransferManager : NSObject {
...
}
Before using the gateway replacement feature, check if the device supports it.
This is a class method. The instance method deviceSupportsTransfer(success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
deviceId | string | The device ID. |
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
Get the replacement status of the current gateway. Before a replacement, use this method to check if the gateway is currently undergoing a replacement operation.
This is a class method. The instance method deviceTransferInfo(success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
deviceId | string | The device ID. |
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
This is a class method. The instance method gateways(success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
deviceId | string | The device ID. |
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
Before replacing a gateway, check if the device supports gateway replacement and check if a replacement operation is currently in progress.
This is a class method. The instance method transfer(fromGateway:, success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
from | string | The device ID of the old gateway. |
to | string | The device ID of the new gateway. |
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
Before using the gateway replacement feature, check if the device supports it.
This is an instance method. The class method deviceSupportsTransfer(_:, success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
Get the replacement status of the current gateway. Before a replacement, use this method to check if the gateway is currently undergoing a replacement operation.
This is an instance method. The class method deviceTransferInfo(deviceId:, success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
This is an instance method. The class method gateways(deviceId:, success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
Before replacing a gateway, check if the device supports gateway replacement and check if a replacement operation is currently in progress.
This is an instance method. The class method transfer(fromGateway:, toGateway:, success:, failure:)
serves the same purpose.
Request parameters | Type | Description |
---|---|---|
gatewayId | string | The device ID of the old gateway. |
success | block | The success callback. |
failure | block | The failure callback. |
/// 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)
Request parameters | Type | Description |
---|---|---|
listener | ThingGatewayTransferManagerDelegate | The listener. |
/// Add a listener.
/// - Parameter listener: the listener which confirms ThingGatewayTransferManagerDelegate.
open func addListener(_ listener: ThingGatewayTransferManagerDelegate)
Request parameters | Type | Description |
---|---|---|
listener | ThingGatewayTransferManagerDelegate | The listener. |
/// Remove a listener.
/// - Parameter listener: the listener which confirms ThingGatewayTransferManagerDelegate.
open func removeListener(_ listener: ThingGatewayTransferManagerDelegate)
For more information, see 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
}
}
}
The following sections describe how to implement faulty gateway replacement.
Implement a simple UI.
When the UI is initialized, pass in the deviceId
as the device ID.
The UI will display a UILabel
and a UITableView
. The UILabel
has no text to display, and the UITableView
has 1
sections and 0
rows. We will create a cell
with the value1
style.
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!
}
}
Lazy load a manager
instance of ThingGatewayTransferManager
.
class GatewayTransferController: UIViewController {
lazy var manager: ThingGatewayTransferManager = {
let manager = ThingGatewayTransferManager.init(deviceId: self.deviceId)
return manager
}()
}
Check if the device supports replacing a faulty gateway using ThingGatewayTransferManager.deviceSupportsTransfer(success:failure:)
.
label
text to support.label
text to do not support. The process ends here.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()
}
}
}
If the device supports replacing a faulty gateway, you can get the current migration status using ThingGatewayTransferManager.deviceTransferInfo(success:failure:)
. The method returns the gateway migration info
on success.
If info
status
is none
, finish
, or failed
, it means there is no migration in progress, and you can proceed with the migration. Otherwise, the device is undergoing migration.
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()
}
}
}
If the device is not migrating, get the list of gateways in the current home using ThingGatewayTransferManager.gateways(success:failure:)
. You can replace any gateway from this list with the current device. Store the retrieved gateway list in the array of ids
for later UI rendering.
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()
}
}
}
Use the tableview
to display the list of gateways in the current home.
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!
}
}
When users tap a cell
to select a gateway ID, replace the specified gateway using 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
}
}
}
Use the listener
of ThingGatewayTransferManager
to notify the result of the replacement. Register listener
and implement 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()
}
}
}
For more information, see Demo.
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback