Rolling code flash sync updates (#13)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Marius Muja 2023-06-24 16:02:50 -07:00 committed by GitHub
parent 77090527fe
commit a24a112c73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 18 deletions

View File

@ -23,6 +23,7 @@ namespace ratgdo {
static const char* const TAG = "ratgdo"; static const char* const TAG = "ratgdo";
static const int SYNC_DELAY = 2000; static const int SYNC_DELAY = 2000;
static const uint8_t MAX_CODES_WITHOUT_FLASH_WRITE = 3; static const uint8_t MAX_CODES_WITHOUT_FLASH_WRITE = 3;
static const uint32_t FLASH_WRITE_INTERVAL = 10000;
void IRAM_ATTR HOT RATGDOStore::isrObstruction(RATGDOStore* arg) void IRAM_ATTR HOT RATGDOStore::isrObstruction(RATGDOStore* arg)
{ {
@ -54,6 +55,9 @@ namespace ratgdo {
this->input_obst_pin_->attach_interrupt(RATGDOStore::isrObstruction, &this->store_, gpio::INTERRUPT_ANY_EDGE); this->input_obst_pin_->attach_interrupt(RATGDOStore::isrObstruction, &this->store_, gpio::INTERRUPT_ANY_EDGE);
// save counter to flash every 10s if it changed
set_interval(FLASH_WRITE_INTERVAL, std::bind(&RATGDOComponent::saveCounter, this, 1));
ESP_LOGV(TAG, "Syncing rolling code counter after reboot..."); ESP_LOGV(TAG, "Syncing rolling code counter after reboot...");
// many things happening at startup, use some delay for sync // many things happening at startup, use some delay for sync
@ -415,7 +419,7 @@ namespace ratgdo {
void RATGDOComponent::query() void RATGDOComponent::query()
{ {
this->forceUpdate_ = true; this->forceUpdate_ = true;
sendCommandAndSaveCounter(command::GET_STATUS); transmit(command::GET_STATUS);
} }
/************************* DOOR COMMUNICATION *************************/ /************************* DOOR COMMUNICATION *************************/
@ -437,6 +441,8 @@ namespace ratgdo {
delayMicroseconds(1260); // "LOW" pulse duration before the message start delayMicroseconds(1260); // "LOW" pulse duration before the message start
this->swSerial.write(this->txRollingCode, CODE_LENGTH); this->swSerial.write(this->txRollingCode, CODE_LENGTH);
saveCounter(MAX_CODES_WITHOUT_FLASH_WRITE);
} }
void RATGDOComponent::sync() void RATGDOComponent::sync()
@ -446,20 +452,20 @@ namespace ratgdo {
// the opener only sends a reply when the rolling code > previous rolling code for a given remote id // the opener only sends a reply when the rolling code > previous rolling code for a given remote id
// when used the first time there is no previous rolling code, so first command is ignored // when used the first time there is no previous rolling code, so first command is ignored
set_timeout(100, [=] { set_timeout(100, [=] {
sendCommandAndSaveCounter(command::GET_STATUS); transmit(command::GET_STATUS);
}); });
// send it twice since manual says it can take 3 button presses for door to open on first use // send it twice since manual says it can take 3 button presses for door to open on first use
set_timeout(200, [=] { set_timeout(200, [=] {
sendCommandAndSaveCounter(command::GET_STATUS); transmit(command::GET_STATUS);
}); });
} }
for (int i = 0; i <= MAX_CODES_WITHOUT_FLASH_WRITE; i++) { for (int i = 0; i <= MAX_CODES_WITHOUT_FLASH_WRITE; i++) {
set_timeout(300 + i * 100, [=] { set_timeout(300 + i * 100, [=] {
sendCommandAndSaveCounter(command::GET_STATUS); transmit(command::GET_STATUS);
}); });
} }
set_timeout(400 + 100 * MAX_CODES_WITHOUT_FLASH_WRITE, [=] { set_timeout(400 + 100 * MAX_CODES_WITHOUT_FLASH_WRITE, [=] {
sendCommandAndSaveCounter(command::GET_OPENINGS); transmit(command::GET_OPENINGS);
}); });
} }
@ -501,47 +507,48 @@ namespace ratgdo {
void RATGDOComponent::lightOn() void RATGDOComponent::lightOn()
{ {
this->lightState = LightState::LIGHT_STATE_ON; this->lightState = LightState::LIGHT_STATE_ON;
sendCommandAndSaveCounter(command::LIGHT, data::ON); transmit(command::LIGHT, data::ON);
} }
void RATGDOComponent::lightOff() void RATGDOComponent::lightOff()
{ {
this->lightState = LightState::LIGHT_STATE_OFF; this->lightState = LightState::LIGHT_STATE_OFF;
sendCommandAndSaveCounter(command::LIGHT, data::OFF); transmit(command::LIGHT, data::OFF);
} }
void RATGDOComponent::toggleLight() void RATGDOComponent::toggleLight()
{ {
this->lightState = light_state_toggle(this->lightState); this->lightState = light_state_toggle(this->lightState);
sendCommandAndSaveCounter(command::LIGHT, data::TOGGLE); transmit(command::LIGHT, data::TOGGLE);
} }
// Lock functions // Lock functions
void RATGDOComponent::lock() void RATGDOComponent::lock()
{ {
this->lockState = LockState::LOCK_STATE_LOCKED; this->lockState = LockState::LOCK_STATE_LOCKED;
sendCommandAndSaveCounter(command::LOCK, data::ON); transmit(command::LOCK, data::ON);
} }
void RATGDOComponent::unlock() void RATGDOComponent::unlock()
{ {
this->lockState = LockState::LOCK_STATE_UNLOCKED; transmit(command::LOCK, data::OFF);
sendCommandAndSaveCounter(command::LOCK, data::OFF);
} }
void RATGDOComponent::toggleLock() void RATGDOComponent::toggleLock()
{ {
this->lockState = lock_state_toggle(this->lockState); this->lockState = lock_state_toggle(this->lockState);
sendCommandAndSaveCounter(command::LOCK, data::TOGGLE); transmit(command::LOCK, data::TOGGLE);
} }
void RATGDOComponent::sendCommandAndSaveCounter(command::cmd command, uint32_t data, bool increment) void RATGDOComponent::saveCounter(int threshold)
{ {
transmit(command, data, increment);
this->pref_.save(&this->rollingCodeCounter); this->pref_.save(&this->rollingCodeCounter);
if (!this->lastSyncedRollingCodeCounter || this->rollingCodeCounter - this->lastSyncedRollingCodeCounter >= MAX_CODES_WITHOUT_FLASH_WRITE) { if (!this->lastSyncedRollingCodeCounter || this->rollingCodeCounter - this->lastSyncedRollingCodeCounter >= threshold) {
this->lastSyncedRollingCodeCounter = this->rollingCodeCounter; // do flash write outside of the component loop
global_preferences->sync(); defer([=] {
this->lastSyncedRollingCodeCounter = this->rollingCodeCounter;
global_preferences->sync();
});
} }
} }

View File

@ -160,9 +160,10 @@ namespace ratgdo {
void obstructionLoop(); void obstructionLoop();
void statusUpdateLoop(); void statusUpdateLoop();
void sendCommandAndSaveCounter(command::cmd command, uint32_t data = 0, bool increment = true); void saveCounter(int threshold);
void doorCommand(uint32_t data); void doorCommand(uint32_t data);
void toggleDoor(); void toggleDoor();
void openDoor(); void openDoor();
void closeDoor(); void closeDoor();