1.1. Memory card management

Mmemory card management use data point, for related data point refer to Data point id.

1.1.1. Status

Before starting to manage the memory card, you need to obtain the status of the memory card. If the device does not detect the memory card, you cannot proceed to the next step. If the memory card is abnormal, you need to format the memory card first.

enum TuyaSmartCameraSDCardStatus

Value Description
TuyaSmartCameraSDCardStatusNormal Memory card is normal working
TuyaSmartCameraSDCardStatusException Memory card is abnormal and needs to be formatted
TuyaSmartCameraSDCardStatusMemoryLow Memory card is low on memory
TuyaSmartCameraSDCardStatusFormatting Memory card is being formatted
TuyaSmartCameraSDCardStatusNone The device did not detect the memory card

1.1.2. Format

When formatting the memory card, there are two cases according to the implementation of the camera manufacturer. The firmware implemented by some manufacturers will actively report the progress of formatting, and will also actively report the current capacity status after formatting is completed. However, there are a few manufacturers' firmware that will not actively report, so it is necessary to periodically and actively query the formatting progress, when the progress reaches 100, and then actively query the current capacity status, you need to use the following interface to query the value of the function point:

- (void)valueForDP:(TuyaSmartCameraDPKey)dpName success:(TYSuccessID)success failure:(TYFailureError)failure;

1.1.3. Memory card recording

After the Tuya camera is inserted into the memory card, the captured image recording can be saved in the memory card, and the video recording switch and mode can be set through the SDK. There are two recording modes:

  • Continuous recording: The camera will continuously record the collected audio and video recordings on the memory card. When the capacity of the memory card is insufficient, the oldest recorded video data will be overwritten.
  • Event recording: The camera will only start recording video when the detection alarm is triggered. The length of the video will change according to the type of event and the duration of the event.

1.1.4. Example

ObjC

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.dpManager valueForDP:TuyaSmartCameraSDCardStatusDPName success:^(id result) {
        [self checkStatus:[result integerValue]];
    } failure:^(NSError *error) {

    }];
}

- (void)changeToEventRecordMode {
    if (![self.dpManager isSupportDP:TuyaSmartCameraSDCardRecordDPName]) {
        return;
    }
    BOOL isRecordOn = [[self.dpManager valueForDP:TuyaSmartCameraSDCardRecordDPName] boolValue];
    if (isRecordOn && [self.dpManager isSupportDP:TuyaSmartCameraRecordModeDPName]) {
        TuyaSmartCameraRecordMode recordMode = [self.dpManager valueForDP:TuyaSmartCameraRecordModeDPName];
        if (recordMode == TuyaSmartCameraRecordModeAlways) {
            [self.dpManager setValue:TuyaSmartCameraRecordModeEvent forDP:TuyaSmartCameraRecordModeDPName success:^(id result) {
                NSLog(@"current recording mode is %@", result);
            } failure:^(NSError *error) {
                                // Network error
            }];
        }
    }
}

- (void)checkStatus:(TuyaSmartCameraSDCardStatus)status {
    if (status == TuyaSmartCameraSDCardStatusNone) {
        return;
    }else if (status == TuyaSmartCameraSDCardStatusException) {
        [self formatAction];
    }else if (status == TuyaSmartCameraSDCardStatusFormatting) {
        [self handleFormatting];
    }else {
        [self getStorageInfo];
          [self changeToEventRecordMode];
    }
}

- (void)formatAction {
    __weak typeof(self) weakSelf = self;
    [self.dpManager setValue:@(YES) forDP:TuyaSmartCameraSDCardFormatDPName success:^(id result) {
        [weakSelf handleFormatting];
    } failure:^(NSError *error) {
        // Network error
    }];
}

- (void)handleFormatting {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          // Query the formatting progress, because some manufacturers' devices will not automatically report the progress
        int status = [self getFormatStatus];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (status >= 0 && status < 100) {
                [self performSelector:@selector(handleFormatting) withObject:nil afterDelay:2.0];
            } else if (status == 100) {
                  // After formatting successfully, query the capacity information of the device
                [self getStorageInfo];
            } else {
                                // fromatting failed
            }
        });
    });
}

- (int)getFormatStatus {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    __block int status = -1;
    [self.dpManager valueForDP:TuyaSmartCameraSDCardFormatStateDPName success:^(id result) {
        status = [result intValue];
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSError *error) {
        dispatch_semaphore_signal(semaphore);
    }];
        // timeout
    dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 300.0f * NSEC_PER_SEC));
    return status;
}

- (void)getStorageInfo {
    __weak typeof(self) weakSelf = self;
    [self.dpManager valueForDP:TuyaSmartCameraSDCardStorageDPName success:^(id result) {
        NSArray *components = [result componentsSeparatedByString:@"|"];
        if (components.count < 3) {
              // Data invalid
            return;
        }
        weakSelf.total = [[components firstObject] integerValue];
        weakSelf.used = [[components objectAtIndex:1] integerValue];
        weakSelf.left = [[components lastObject] integerValue];
    } failure:^(NSError *error) {
        // Network error
    }];
}

Swift

override func viewDidLoad() {
    super.viewDidLoad()
    self.dpManager.value(forDP: .sdCardStatusDPName, success: { result in
        self.checkStatus(status: TuyaSmartCameraSDCardStatus(rawValue: result as! UInt)!)
    }) { _ in
        // Network error
    }
}

func checkStatus(status: TuyaSmartCameraSDCardStatus) {
    switch status {
    case .exception:
        self.formatSDCard()
        break
    case .formatting:
        self.handleFormatting()
        break
    case .none:
        return
    default:
        self.getStorageInfo()
        self.changeToEventRecordMode()
    }
}

func formatSDCard() {
    self.dpManager.setValue(true, forDP: .sdCardFormatDPName, success: { [weak self] _ in
        self?.handleFormatting()
    }) { _ in
        // Network error
    }
}

func handleFormatting() {
    DispatchQueue.global().async {
        // Query the formatting progress, because some manufacturers' devices will not automatically report the progress
        let status = self.getFormatStatus()
        DispatchQueue.main.async {
            if status >= 0, status < 100 {
                self.handleFormatting()
            }else if status == 100 {
                // After formatting successfully, query the capacity information of the device
                self.getStorageInfo()
            }else {
                // Formatting failed
            }
        }
    }
}

func getFormatStatus() -> Int {
    let semaphore = DispatchSemaphore.init(value: 0)
    var status = -1
    self.dpManager.value(forDP: .sdCardFormatStateDPName, success: { result in
        status = result as! Int
        semaphore.signal()
    }) { _ in
        semaphore.signal()
    }
    // timeout
    let _ = semaphore.wait(timeout: DispatchTime(uptimeNanoseconds: 300 * NSEC_PER_SEC))
    return status
}

func getStorageInfo() {
    self.dpManager.value(forDP: .sdCardStorageDPName, success: { result in
        let components = (result as! String).split(separator: "|")
        guard components.count == 3 else {
            // Data invalid
            return
        }
        let total = Int(components[0])
        let used = Int(components[1])
        let left = Int(components[2])
    }) { _ in
        // Network error
    }
}

func changeToEventRecordMode() {
    guard self.dpManager.isSupportDP(.sdCardRecordDPName) else {
        return
    }
    let isRecordOn = self.dpManager.value(forDP: .sdCardRecordDPName) as! Bool
    guard self.dpManager.isSupportDP(.recordModeDPName), isRecordOn else {
        return
    }

    let recordMode = self.dpManager.value(forDP: .recordModeDPName) as! String
    if recordMode == TuyaSmartCameraRecordMode.always.rawValue {
        self.dpManager.setValue(TuyaSmartCameraRecordMode.event.rawValue, forDP: .recordModeDPName, success: { result in
            print("current recording mode is ", result as! String)
        }) { _ in
            // Network error
        }
    }

}

results matching ""

    No results matching ""