Firmware Update

Last Updated on : 2024-03-21 07:36:05download

Firmware update is the process of writing new firmware to a chip to replace the current firmware. Tuya supports regular firmware updates to meet your development and market requirements. Tuya also deactivates certain legacy firmware versions in line with chip iterations of the manufacturers. In the case of device feature updates, a firmware update is also required.

  • Starting from App SDK v3.35.5, you can update firmware that matches a specified product ID (PID). The new API method for starting firmware update supports Bluetooth devices, and multiple firmware versions can be selected in the same update task.
  • Only home creators and home admins are allowed to initiate an update. Common home members can only get information about the firmware update.

Update process

Request device update information
Initiate the module update
The module update is successful
Initiate the MCU update
The MCU update is successful

Get firmware update information

This method returns the firmware update model ThingSmartFirmwareUpgradeModel.

  • upgradeMode: The firmware update mode.
  • type: The firmware update channel type.
  • typeDesc: The description of the firmware type.

Firmware update modes

When you query the list of firmware updates, the upgradeMode field of ThingSmartFirmwareUpgradeModel includes the following valid values:

  • Generic firmware update: Its value is 0. This is an ordinary update mode, used to update the firmware on the device.

  • PID-specific firmware update: Its value is 1. This update mode applies the concept of products. Update versions can be differentiated by functional modules, such as product schema, panel settings, multilingual settings, and shortcut control.

    The new API methods are required to get the firmware list and trigger a PID-specific firmware update.

Firmware update channel types

When querying the list of firmware updates, the type field of ThingSmartFirmwareUpgradeModel indicates the update channel type for generic firmware, with typeDesc describing the channel.

The following table lists the type of generic firmware update. We recommend that you describe the firmware using the value of typeDesc returned by the model.

Channel type for generic firmware Meaning
0 Main network module, Wi-Fi module, and Bluetooth module.
1 Bluetooth module
2 GPRS module
3 Zigbee module
5 433 MHz module
6 NB-IoT module
9 MCU module
10 to 19 Extension module

API description

// Request the update for generic firmware and PID-based firmware.
- (void)checkFirmwareUpgrade:(void (^)(NSArray<ThingSmartFirmwareUpgradeModel *> *firmwares))success failure:(nullable ThingFailureError)failure;

// Deprecated. Used to request the update for generic firmware only.
- (void)getFirmwareUpgradeInfo:(nullable void (^)(NSArray <ThingSmartFirmwareUpgradeModel *> *upgradeModelList))success failure:(nullable ThingFailureError)failure;

Parameter description

Parameter Description
success The success callback. A list of firmware updates is returned.
failure The failure callback.

Data model of ThingSmartFirmwareUpgradeModel

Field Type Description
desc NSString The description of the update.
type NSInteger The type of firmware update channel, applying to generic firmware.
typeDesc NSString The description of the firmware update channel.
upgradeStatus NSInteger
  • 0: No update available
  • 1: An update available
  • 2: Updating
  • 5: Wait for the device to wake up
version NSString The new version of the firmware.
currentVersion NSString The current version of the firmware.
devType NSInteger
  • 0: Ordinary device
  • 1: Low power device
upgradeType NSInteger
  • 0: Update notification
  • 2: Forced update
  • 3: Check for update
url NSString The URL to download a Bluetooth firmware update.
fileSize NSString The size of the firmware update, in bytes. This field applies to Bluetooth devices only.
md5 NSString The MD5 hash value of the firmware.
controlType BOOL
  • YES: The device can be used during the update.
  • NO: The device cannot be used during the update.
waitingDesc NSString The description for waiting for the device to wake up.
upgradingDesc NSString The description shown when the firmware is being updated.
canUpgrade NSNumber
  • nil: No verification is required to start an update.
  • 0: The update verification fails, with the update being denied. You can show remind to inform the user about the failure.
  • 1: The update verification succeeds, with the update being accepted.
remind NSString The description shown when the update verification fails.
upgradeMode ThingSmartDeviceUpgradeMode The type of firmware update, available starting from v3.35.5.
  • 0: Generic firmware update
  • 1: PID-specific firmware update

Example

Objective-C:

- (void)getFirmwareUpgradeInfo {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];

    [self.device checkFirmwareUpgrade:^(NSArray<ThingSmartFirmwareUpgradeModel *> *upgradeModelList) {
        NSLog(@"getFirmwareUpgradeInfo success");
    } failure:^(NSError *error) {
        NSLog(@"getFirmwareUpgradeInfo failure: %@", error);
    }];
}

Swift:

func getFirmwareUpgradeInfo() {
    device?.checkFirmwareUpgrade({ (upgradeModelList) in
        print("getFirmwareUpgradeInfo success")
    }, failure: { (error) in
        if let e = error {
            print("getFirmwareUpgradeInfo failure: \(e)")
        }
    })
}

Query status of firmware being updated

This method returns information about the firmware being updated. If no firmware is being updated, a failure is returned.

API description

- (void)getFirmwareUpgradingStatus:(void (^)(ThingSmartFirmwareUpgradeStatusModel *status))success failure:(nullable ThingFailureError)failure

Parameter description

Parameter Description
success The success callback. An update status model is returned.
failure The failure callback. An error message is returned to indicate that the device is not being updated or the API request failed.

Data model of ThingSmartFirmwareUpgradeStatusModel

Field Type Description
upgradeStatus ThingSmartDeviceUpgradeStatus The update status. Valid values:
  • 2: Updating
  • 3: Update succeeded
  • 4: Update failed
  • 5: Wait for the device to wake up
  • 6: The update has been downloaded
  • 7: Update timeout
  • 100: The app is preparing, for example, connecting to a Bluetooth device, or downloading the update.
statusText NSString The description of the status.
statusTitle NSString The title of the status.
progress NSInteger The progress. In certain conditions, the value might be less than 0. If any, ignore this type of value.
type NSInteger The type of firmware update channel. The value is used when users confirm the update.
upgradeMode ThingSmartDeviceUpgradeMode
  • 0: Generic firmware update
  • 1: PID-specific firmware update, available starting from v3.35.5
error NSError The error message.

Example

Objective-C:

- (void)getFirmwareUpgradeInfo {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];

    [self.device getFirmwareUpgradingStatus:^(ThingSmartFirmwareUpgradeStatusModel *status) {
        NSLog(@"getFirmwareUpgradingStatus success");
    } failure:^(NSError *error) {
        NSLog(@"getFirmwareUpgradingStatus failure: %@", error);
    }];
}

Swift:

func getFirmwareUpgradeInfo() {
    device?.getFirmwareUpgradingStatus({ (status) in
        print("getFirmwareUpgradingStatus success")
    }, failure: { (error) in
        if let e = error {
            print("getFirmwareUpgradingStatus failure: \(e)")
        }
    })
}

Start update

API description

// Support the update for generic firmware and PID-based firmware.
// Support the update for Bluetooth LE and Bluetooth mesh gateways.
// Update multiple firmware images on a single device sequentially.
- (void)startFirmwareUpgrade:(NSArray<ThingSmartFirmwareUpgradeModel *> *)firmwares

// Deprecated. Use - startFirmwareUpgrade: to initiate an update.
// Support the generic firmware only, including Wi-Fi and Zigbee devices, not supporting Bluetooth LE devices.
// You can update one firmware image only.
// type: The type of the update, obtained from the device update method getFirmwareUpgradeInfo.
- (void)upgradeFirmware:(NSInteger)type success:(nullable ThingSuccessHandler)success failure:(nullable ThingFailureError)failure;

Parameter description

  • -startFirmwareUpgrade:

    Parameter Description
    firmwares Call getFirmwareUpgradeInfo to get the information about the firmware update.
    success The success callback.
    failure The failure callback.
  • -upgradeFirmware:success:failure:

    Parameter Description
    type The type of update. Call getFirmwareUpgradeInfo to get the value.
    success The success callback.
    failure The failure callback.
    • The status returned by getFirmwareUpgradeInfo includes the following:

      • No update available (upgradeStatus: 0)
      • An update available (upgradeStatus: 1)
      • Updating (upgradeStatus: 2)
      • Wait for the device to wake up (upgradeStatus: 5)

      The status information is displayed to indicate the update status. An update can be initiated only when a new version is available (upgradeStatus: 1). In practice, filter the status and display it on the app.

    • Some devices need verification before updating. Call getFirmwareUpgradeInfo to get the firmware information. The canUpgrade in the update information model ThingSmartFirmwareUpgradeModel indicates whether the update can be installed.

      Verification result Value
      No verification is required to start an update. canUpgrade == nil
      The update verification fails, with the update being denied. canUpgrade != nil && canUpgrade.integerValue == 0
      The update verification succeeds, with the update being accepted. canUpgrade != nil && canUpgrade.integerValue == 1

      If the update verification fails, you can show remind to inform the user about the failure.

Example

Objective-C:

- (void)upgradeFirmwareNew {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];

    // firmwares: The firmware update information returned by getFirmwareUpgradeInfo.
    // Note: According to the above instructions, filter out firmware that does not comply with the rules.
    [self.device startFirmwareUpgrade:firmwares];
}

Swift:

func upgradeFirmware() {
      // firmwares: The firmware update information returned by getFirmwareUpgradeInfo.
      // Note: According to the above instructions, filter out firmware that does not comply with the rules.
    device?.startFirmwareUpgrade(firmwares);
}

Continue with update

Currently, this API method applies only when the error.code of ThingOTAErrorCodeSignalStrengthNotSatisfy is returned in the update progress callback.

For Wi-Fi devices and combo devices, to ensure a successful update, the minimum signal strength level is specified. When an update is triggered, the system checks whether the device signal strength is within an acceptable range. If not, error.code = ThingOTAErrorCodeSignalStrengthNotSatisfy will be returned in the callback. You can add a UI interaction for users to choose whether to proceed with the update installation. For example, a dialog box appears, saying The device signal is weak, and the update might fail. Continue to update?

API description

- (void)confirmWarningUpgradeTask:(BOOL)isContinue;

Parameter description

Parameter Description
isContinue Indicates whether to continue the update task.

This process applies to only the update that is initiated by -startFirmwareUpgrade:.

Example

Objective-C:

- (void)continueFirmware {
    // isContinue  The user decides whether to continue with the update.
    [self.device confirmWarningUpgradeTask:isContinue];
}

Swift:

func continueFirmware() {
    // isContinue The user decides whether to continue with the update.
    device?.confirmWarningUpgradeTask(isContinue)
}

Cancel update

Currently, only low power devices can cancel an update. After an update is initiated, a low power device may be in sleep mode (upgradeStatus = 5). This API method can be called to cancel the update task.

API description

// Currently, you can cancel the update for low power devices only.
- (void)cancelFirmwareUpgrade:(ThingSuccessHandler)success
                      failure:(nullable ThingFailureError)failure;

// Deprecated. The recommended alternative is -cancelFirmwareUpgrade:failure:
// type: Obtained from getFirmwareUpgradeInfo
- (void)cancelUpgradeFirmware:(NSInteger)type success:(nullable ThingSuccessHandler)success failure:(nullable ThingFailureError)failure;

Parameter description

Parameter Description
success The success callback.
failure The failure callback.

This API method applies only to the device with the upgradeStatus being 5 (wait for the device to wake up).

Example

Objective-C:

- (void)cancelFirmware {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];
    // type: The firmware type returned by getFirmwareUpgradeInfo
    // ThingSmartFirmwareUpgradeModel - type
    // Only applies to devices with upgradeStatus of 5 (wait for the device to wake up).

    [self.device cancelFirmwareUpgrade:^{
        NSLog(@"cancel success");
    } failure:^(NSError *error) {
        NSLog(@"cancel failure: %@", error);
    }];
}

Swift:

func cancelFirmware() {
    // Only applies to devices with upgradeStatus of 5 (wait for the device to wake up).
    device?.cancelFirmwareUpgrade(success: {
        print("cancel success")
    }, failure: { (error) in
        if let e = error {
            print("cancel failure: \(e)")
        }
    })
}

Listen for callback

For the update initiated by -startFirmwareUpgrade:, we recommend that you use -device:otaUpdateStatusChanged: to register the callback. This callback includes the status changes, progress, and failure reasons. Other deprecated callback methods can still be executed. To prevent repeated callback listeners, we recommend that you port respective logic to this callback.

Example

Objective-C:

- (void)device:(ThingSmartDevice *)device otaUpdateStatusChanged:(ThingSmartFirmwareUpgradeStatusModel *)statusModel {
        // Firmware update status and progress callback.
        // Using with -startFirmwareUpgrade: is recommended.
}

- (void)device:(ThingSmartDevice *)device firmwareUpgradeStatusModel:(ThingSmartFirmwareUpgradeStatusModel *)upgradeStatusModel {
    // Firmware update status callback.
    // Using with -upgradeFirmware:success:failure: is recommended.
}

- (void)deviceFirmwareUpgradeSuccess:(ThingSmartDevice *)device type:(NSInteger)type {
    // The firmware update is successful. Deprecated. The recommended alternative is - device:firmwareUpgradeStatusModel:
}

- (void)deviceFirmwareUpgradeFailure:(ThingSmartDevice *)device type:(NSInteger)type {
    // The firmware update failed. Deprecated. The recommended alternative is - device:firmwareUpgradeStatusModel:
}

- (void)device:(ThingSmartDevice *)device firmwareUpgradeProgress:(NSInteger)type progress:(double)progress {
    // The progress of the firmware update.
    // Using with -upgradeFirmware:success:failure: is recommended.
}

Swift:

func device(_ device: ThingSmartDevice, firmwareUpgradeStatusModel upgradeStatusModel: ThingSmartFirmwareUpgradeStatusModel) {
    // Change in device update status.
}

func deviceFirmwareUpgradeSuccess(_ device: ThingSmartDevice!, type: Int) {
    // Firmware update is successful. Deprecated soon. The recommended alternative is device(_:, firmwareUpgradeStatusModel:)
}

func deviceFirmwareUpgradeFailure(_ device: ThingSmartDevice!, type: Int) {
    // Firmware update failed. Deprecated soon. The recommended alternative is device(_:, firmwareUpgradeStatusModel:)
}

func device(_ device: ThingSmartDevice!, firmwareUpgradeProgress type: Int, progress: Double) {
    // The progress of firmware update.
}

Automatically update to the latest version

Certain devices support an automatic update to the latest version. You can use ThingSmartDeviceModel - supportAuto to check whether a device supports this feature.

API description

// Get the toggle status.
- (void)getAutoUpgradeSwitchInfoWithSuccess:(nullable ThingSuccessID)success
                                    failure:(nullable ThingFailureError)failure;

// Save the toggle status.
- (void)saveUpgradeInfoWithSwitchValue:(NSInteger)switchValue
                               success:(nullable ThingSuccessHandler)success
                               failure:(nullable ThingFailureError)failure;

Parameter description

Parameter Description
switchValue The status of the feature. Valid values:
  • 0: Disable
  • 1: Enable
success The success callback.
failure The failure callback.

Example

Objective-C:

- (void)getAutoUpgradeSwitchInfo {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];
    // Use ThingSmartDeviceModel - supportAuto to determine if the device supports auto updates.

    [self.device getAutoUpgradeSwitchInfoWithSuccess:^(NSNumber *status) {
        // 0: Off. 1: On. The example turns off auto updates.
        NSLog(@"current switch status: %@", status);
    } failure:^(NSError *error) {
        NSLog(@"get current switch status fail. %@", error);
    }];
}

- (void)saveAutoUpgradeSwitchInfo {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];
    // Use ThingSmartDeviceModel - supportAuto to determine if the device supports auto updates.

    NSInteger status = 0; // 0: Off. 1: On. The example turns off auto updates.
    [self.device saveUpgradeInfoWithSwitchValue:status success:^{
        NSLog(@"save auto switch status success.");
    } failure:^(NSError *error) {
        NSLog(@"save auto switch status fail. %@", error);
    }];
}

Swift:

func getAutoUpgradeSwitchInfo() {
    // Use ThingSmartDeviceModel - supportAuto to determine if the device supports auto updates.
    device?.getAutoUpgradeSwitchInfo(success: { status in
        // 0: Off. 1: On.
        if let value = status {
            print("get current status: \(value)")
        }
    }, failure: { error in
        if let e = error {
            print("get status failure: \(e)")
        }
    })
}

func saveAutoUpgradeSwitchInfo() {
    // Use ThingSmartDeviceModel - supportAuto to determine if the device supports auto updates.
    let status = 0 // 0: Off. 1: On. The example turns off auto updates.
    device?.saveUpgradeInfo(withSwitchValue: 0, success: {
        print("save success")
    }, failure: { error in
        if let e = error {
            print("success failure: \(e)")
        }
    })
}

Common home members get update information

This API method is only applicable to apps developed based on App SDK v5.1.0 or later.

API description

- (void)memberCheckFirmwareStatus:(void (^)(NSArray<ThingSmartMemberCheckFirmwareInfo *> *infos))success
                          failure:(ThingFailureError)failure;

Parameter description

Parameter Description
success The success callback.
failure The failure callback.

Data model of ThingSmartMemberCheckFirmwareInfo

Field Type Description
type NSInteger Firmware update channel types
upgradeStatus NSInteger
  • 0: No update available
  • 1: An update available
  • 2: Updating
  • 5: Wait for the device to wake up
version NSString The new version of the firmware.
upgradeText NSString The information about firmware update.

Example

Objective-C:

- (void)getAutoUpgradeSwitchInfo {
    // self.device = [ThingSmartDevice deviceWithDeviceId:@"your_device_id"];
    [self.device memberCheckFirmwareStatus:^(NSArray<ThingSmartMemberCheckFirmwareInfo *> * _Nonnull infos) {
        NSLog(@"member check success");
    } failure:^(NSError *error) {
        NSLog(@"member check failure");
    }];
}

Swift:

func getAutoUpgradeSwitchInfo() {
    device?.memberCheckFirmwareStatus(success: { infos in
            print("member check success: \(infos)")
    }, failure: { error in
        if let e = error {
            print("member check failure: \(e)")
        }
    })
}

Error codes

The error codes in ThingSmartFirmwareUpgradeStatusModel only apply to the new API methods for OTA updates.

Error codes Description Notes
5000 All device firmware versions are up to date. -
5001 No firmware update found. -
5002 For Bluetooth devices, only one device can be updated in the same task. In most cases, this error code applies to Bluetooth LE devices, Tuya mesh sub-devices, and Bluetooth mesh sub-devices.
5003 Failed to download the firmware package by using the app. -
5004 Failed to check whether signal strength detection is required. -
5005 The signal strength level of the device does not meet firmware update requirements. We recommend that you implement a UI interaction to ask users whether to continue the update. The update might fail if it is continued. You can call - confirmWarningUpgradeTask: to continue or cancel the update.
5006 Failed to connect to the device. In most cases, this error code applies to Bluetooth LE devices, Tuya mesh sub-devices, and Bluetooth mesh sub-devices.
5007 A timeout error has occurred while unbinding the Bluetooth LE device from the gateway. -
5009 The MD5 check failed while downloading firmware by using the app. -
5010 Failed to send the firmware by using the app. In most cases, this error code applies to Bluetooth LE devices, Tuya mesh sub-devices, and Bluetooth mesh sub-devices.
5012 The device is offline. -
5013 The verification before the update failed. -
5014 The Bluetooth feature is not enabled on the mobile phone. -
5015 Failed to get the list of available firmware updates. -
5016 The device update timed out. -
5099 Global error codes -