Last Updated on : 2023-06-05 02:49:21download
Memory card management relies on data points (DPs). For more information about DPs, see DPs.
Before memory card management, you must get the status of memory cards. If the device does not detect a memory card, you cannot proceed to the next step. If the memory card is abnormal, you need to format the memory card first.
enum ThingSmartCameraSDCardStatus
Value | Description |
---|---|
ThingSmartCameraSDCardStatusNormal | Memory card is normal working |
ThingSmartCameraSDCardStatusException | Memory card is abnormal and needs to be formatted |
ThingSmartCameraSDCardStatusMemoryLow | Memory card is low on memory |
ThingSmartCameraSDCardStatusFormatting | Memory card is being formatted |
ThingSmartCameraSDCardStatusNone | The device did not detect the memory card |
When the memory card is formatted, 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 is 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:(ThingSmartCameraDPKey)dpName success:(ThingSuccessID)success failure:(ThingFailureError)failure;
After a memory card is inserted into a Powered by Tuya
(PBT) camera, the captured images can be saved to the memory card, and the video recording switch and mode can be set based on the SDK. There are two recording modes:
- (void)viewDidLoad {
[super viewDidLoad];
[self.dpManager valueForDP:ThingSmartCameraSDCardStatusDPName success:^(id result) {
[self checkStatus:[result integerValue]];
} failure:^(NSError *error) {
}];
}
- (void)changeToEventRecordMode {
if (![self.dpManager isSupportDP:ThingSmartCameraSDCardRecordDPName]) {
return;
}
BOOL isRecordOn = [[self.dpManager valueForDP:ThingSmartCameraSDCardRecordDPName] boolValue];
if (isRecordOn && [self.dpManager isSupportDP:ThingSmartCameraRecordModeDPName]) {
ThingSmartCameraRecordMode recordMode = [self.dpManager valueForDP:ThingSmartCameraRecordModeDPName];
if (recordMode == ThingSmartCameraRecordModeAlways) {
[self.dpManager setValue:ThingSmartCameraRecordModeEvent forDP:ThingSmartCameraRecordModeDPName success:^(id result) {
NSLog(@"current recording mode is %@", result);
} failure:^(NSError *error) {
// Network error
}];
}
}
}
- (void)checkStatus:(ThingSmartCameraSDCardStatus)status {
if (status == ThingSmartCameraSDCardStatusNone) {
return;
}else if (status == ThingSmartCameraSDCardStatusException) {
[self formatAction];
}else if (status == ThingSmartCameraSDCardStatusFormatting) {
[self handleFormatting];
}else {
[self getStorageInfo];
[self changeToEventRecordMode];
}
}
- (void)formatAction {
__weak typeof(self) weakSelf = self;
[self.dpManager setValue:@(YES) forDP:ThingSmartCameraSDCardFormatDPName 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 {
// Formatting failed
}
});
});
}
- (int)getFormatStatus {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block int status = -1;
[self.dpManager valueForDP:ThingSmartCameraSDCardFormatStateDPName 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:ThingSmartCameraSDCardStorageDPName 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
}];
}
override func viewDidLoad() {
super.viewDidLoad()
self.dpManager.value(forDP: .sdCardStatusDPName, success: { result in
self.checkStatus(status: ThingSmartCameraSDCardStatus(rawValue: result as! UInt)!)
}) { _ in
// Network error
}
}
func checkStatus(status: ThingSmartCameraSDCardStatus) {
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 == ThingSmartCameraRecordMode.always.rawValue {
self.dpManager.setValue(ThingSmartCameraRecordMode.event.rawValue, forDP: .recordModeDPName, success: { result in
print("current recording mode is ", result as! String)
}) { _ in
// Network error
}
}
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback