diff --git a/MqttTopics.h b/MqttTopics.h index d6290d5..5332a1f 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -11,4 +11,4 @@ #define mqtt_topic_lockstate_trigger "nuki/lock/trigger" #define mqtt_topic_lockstate_completionStatus "nuki/lock/completionStatus" #define mqtt_topic_lockstate_action "nuki/lock/action" -#define mqtt_topic_door_sensor_state_action "nuki/lock/doorSensorState" +#define mqtt_topic_door_sensor_state "nuki/lock/doorSensorState" diff --git a/Network.cpp b/Network.cpp index 39eb38b..6c4587f 100644 --- a/Network.cpp +++ b/Network.cpp @@ -137,21 +137,47 @@ void Network::onMqttDataReceived(char *&topic, byte *&payload, unsigned int &len } } -void Network::publishKeyTurnerState(const char* state, const char* trigger, const char* completionStatus) +void Network::publishKeyTurnerState(const KeyTurnerState& keyTurnerState, const KeyTurnerState& lastKeyTurnerState) { - _mqttClient.publish(mqtt_topic_lockstate_state, state); - _mqttClient.publish(mqtt_topic_lockstate_trigger, trigger); - _mqttClient.publish(mqtt_topic_lockstate_completionStatus, completionStatus); -} + char str[50]; -void Network::publishDoorSensorState(const char *state) -{ - _mqttClient.publish(mqtt_topic_door_sensor_state_action, state); -} + if(keyTurnerState.lockState != lastKeyTurnerState.lockState) + { + memset(&str, 0, sizeof(str)); + nukiLockstateToString(keyTurnerState.lockState, str); + _mqttClient.publish(mqtt_topic_lockstate_state, str); + } -void Network::setLockActionReceived(void (*lockActionReceivedCallback)(const char *)) -{ - _lockActionReceivedCallback = lockActionReceivedCallback; + if(keyTurnerState.trigger != lastKeyTurnerState.trigger) + { + memset(&str, 0, sizeof(str)); + nukiTriggerToString(keyTurnerState.trigger, str); + _mqttClient.publish(mqtt_topic_lockstate_trigger, str); + } + + if(keyTurnerState.lastLockActionCompletionStatus != lastKeyTurnerState.lastLockActionCompletionStatus) + { + memset(&str, 0, sizeof(str)); + nukiCompletionStatusToString(keyTurnerState.lastLockActionCompletionStatus, str); + _mqttClient.publish(mqtt_topic_lockstate_completionStatus, str); + } + + if(keyTurnerState.doorSensorState != lastKeyTurnerState.doorSensorState) + { + memset(&str, 0, sizeof(str)); + nukiDoorSensorStateToString(keyTurnerState.doorSensorState, str); + _mqttClient.publish(mqtt_topic_door_sensor_state, str); + } + + if(keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) + { + uint8_t level = (keyTurnerState.criticalBatteryState & 0b11111100) >> 1; + bool critical = (keyTurnerState.criticalBatteryState & 0b00000001) > 0; + bool charging = (keyTurnerState.criticalBatteryState & 0b00000010) > 0; + publishInt(mqtt_topic_battery_level, level); // percent + publishBool(mqtt_topic_battery_critical, critical); + publishBool(mqtt_topic_battery_charging, charging); + } } void Network::publishBatteryReport(const BatteryReport& batteryReport) @@ -161,11 +187,9 @@ void Network::publishBatteryReport(const BatteryReport& batteryReport) publishFloat(mqtt_topic_battery_max_turn_current, (float)batteryReport.maxTurnCurrent / 1000.0); } -void Network::publishCriticalBattery(uint8_t level, bool isCritical, bool isCharging) +void Network::setLockActionReceived(void (*lockActionReceivedCallback)(const char *)) { - publishInt(mqtt_topic_battery_level, level); // milliwatt seconds - publishBool(mqtt_topic_battery_critical, isCritical); - publishBool(mqtt_topic_battery_charging, isCharging); + _lockActionReceivedCallback = lockActionReceivedCallback; } void Network::publishFloat(const char* topic, const float value, const uint8_t precision) diff --git a/Network.h b/Network.h index aa1802a..8383c88 100644 --- a/Network.h +++ b/Network.h @@ -16,10 +16,8 @@ public: bool isMqttConnected(); - void publishKeyTurnerState(const char* state, const char* trigger, const char* completionStatus); - void publishDoorSensorState(const char* state); + void publishKeyTurnerState(const KeyTurnerState& keyTurnerState, const KeyTurnerState& lastKeyTurnerState); void publishBatteryReport(const BatteryReport& batteryReport); - void publishCriticalBattery(uint8_t level, bool isCritical, bool isCharging); void setLockActionReceived(void (*lockActionReceivedCallback)(const char* value)); diff --git a/Nuki.cpp b/Nuki.cpp index 5f6cd3d..0f77f27 100644 --- a/Nuki.cpp +++ b/Nuki.cpp @@ -11,8 +11,8 @@ Nuki::Nuki(const std::string& name, uint32_t id, Network* network, Preferences* { nukiInst = this; - memset(&_lastKeyTurnerState, sizeof(KeyTurnerState), 0); memset(&_keyTurnerState, sizeof(KeyTurnerState), 0); + memset(&_lastKeyTurnerState, sizeof(KeyTurnerState), 0); memset(&_lastBatteryReport, sizeof(BatteryReport), 0); memset(&_batteryReport, sizeof(BatteryReport), 0); @@ -88,45 +88,24 @@ void Nuki::update() _nextLockStateUpdateTs = ts + 10 * 1000; } } + + memcpy(&_lastKeyTurnerState, &_keyTurnerState, sizeof(KeyTurnerState)); } void Nuki::updateKeyTurnerState() { _nukiBle.requestKeyTurnerState(&_keyTurnerState); + _network->publishKeyTurnerState(_keyTurnerState, _lastKeyTurnerState); if(_keyTurnerState.lockState != _lastKeyTurnerState.lockState) { char lockStateStr[20]; - lockstateToString(_keyTurnerState.lockState, lockStateStr); - char triggerStr[20]; - triggerToString(_keyTurnerState.trigger, triggerStr); - char completionStatusStr[20]; - completionStatusToString(_keyTurnerState.lastLockActionCompletionStatus, completionStatusStr); - - _network->publishKeyTurnerState(lockStateStr, triggerStr, completionStatusStr); + nukiLockstateToString(_keyTurnerState.lockState, lockStateStr); Serial.print(F("Nuki lock state: ")); Serial.println(lockStateStr); } - - if(_keyTurnerState.doorSensorState != _lastKeyTurnerState.doorSensorState) - { - char doorSensorStateStr[20]; - doorSensorStateToString(_keyTurnerState.doorSensorState, doorSensorStateStr); - _network->publishDoorSensorState(doorSensorStateStr); - } - - if(_keyTurnerState.criticalBatteryState != _lastKeyTurnerState.criticalBatteryState) - { - uint8_t level = (_keyTurnerState.criticalBatteryState & 0b11111100) >> 1; - bool critical = (_keyTurnerState.criticalBatteryState & 0b00000001) > 0; - bool charging = (_keyTurnerState.criticalBatteryState & 0b00000010) > 0; - _network->publishCriticalBattery(level, critical, charging); - } - - memcpy(&_lastKeyTurnerState, &_keyTurnerState, sizeof(KeyTurnerState)); } - void Nuki::updateBatteryState() { _nukiBle.requestBatteryReport(&_batteryReport); @@ -141,148 +120,6 @@ void Nuki::updateBatteryState() _network->publishBatteryReport(_batteryReport); } - -void Nuki::lockstateToString(const LockState state, char* str) -{ - switch(state) - { - case LockState::uncalibrated: - strcpy(str, "uncalibrated"); - break; - case LockState::locked: - strcpy(str, "locked"); - break; - case LockState::locking: - strcpy(str, "locking"); - break; - case LockState::unlocked: - strcpy(str, "unlocked"); - break; - case LockState::unlatched: - strcpy(str, "unlatched"); - break; - case LockState::unlockedLnga: - strcpy(str, "unlockedLnga"); - break; - case LockState::unlatching: - strcpy(str, "unlatching"); - break; - case LockState::calibration: - strcpy(str, "calibration"); - break; - case LockState::bootRun: - strcpy(str, "bootRun"); - break; - case LockState::motorBlocked: - strcpy(str, "motorBlocked"); - break; - default: - strcpy(str, "undefined"); - break; - } -} - - -void Nuki::triggerToString(const NukiTrigger trigger, char *str) -{ - switch(trigger) - { - case NukiTrigger::autoLock: - strcpy(str, "autoLock"); - break; - case NukiTrigger::automatic: - strcpy(str, "automatic"); - break; - case NukiTrigger::button: - strcpy(str, "button"); - break; - case NukiTrigger::manual: - strcpy(str, "manual"); - break; - case NukiTrigger::system: - strcpy(str, "system"); - break; - default: - strcpy(str, "undefined"); - break; - } -} - -void Nuki::completionStatusToString(const CompletionStatus status, char *str) -{ - switch (status) - { - case CompletionStatus::success: - strcpy(str, "success"); - break; - case CompletionStatus::busy: - strcpy(str, "busy"); - break; - case CompletionStatus::canceled: - strcpy(str, "canceled"); - break; - case CompletionStatus::clutchFailure: - strcpy(str, "clutchFailure"); - break; - case CompletionStatus::incompleteFailure: - strcpy(str, "incompleteFailure"); - break; - case CompletionStatus::invalidCode: - strcpy(str, "invalidCode"); - break; - case CompletionStatus::lowMotorVoltage: - strcpy(str, "lowMotorVoltage"); - break; - case CompletionStatus::motorBlocked: - strcpy(str, "motorBlocked"); - break; - case CompletionStatus::motorPowerFailure: - strcpy(str, "motorPowerFailure"); - break; - case CompletionStatus::otherError: - strcpy(str, "otherError"); - break; - case CompletionStatus::tooRecent: - strcpy(str, "tooRecent"); - break; - case CompletionStatus::unknown: - strcpy(str, "unknown"); - break; - default: - strcpy(str, "undefined"); - break; - - } -} - -void Nuki::doorSensorStateToString(const DoorSensorState state, char *str) -{ - switch(state) - { - case DoorSensorState::unavailable: - strcpy(str, "unavailable"); - break; - case DoorSensorState::deactivated: - strcpy(str, "deactivated"); - break; - case DoorSensorState::doorClosed: - strcpy(str, "doorClosed"); - break; - case DoorSensorState::doorOpened: - strcpy(str, "doorOpened"); - break; - case DoorSensorState::doorStateUnknown: - strcpy(str, "doorStateUnknown"); - break; - case DoorSensorState::calibrating: - strcpy(str, "calibrating"); - break; - default: - strcpy(str, "undefined"); - break; - } -} - LockAction Nuki::lockActionToEnum(const char *str) { if(strcmp(str, "unlock") == 0) return LockAction::unlock; @@ -300,8 +137,6 @@ LockAction Nuki::lockActionToEnum(const char *str) void Nuki::onLockActionReceived(const char *value) { nukiInst->_nextLockAction = nukiInst->lockActionToEnum(value); - Serial.print(F("Action: ")); - Serial.println((int)nukiInst->_nextLockAction); } const bool Nuki::isPaired() diff --git a/Nuki.h b/Nuki.h index b1994fd..5bd00cd 100644 --- a/Nuki.h +++ b/Nuki.h @@ -1,7 +1,6 @@ #pragma once #include "NukiBle.h" -#include "NukiConstants.h" #include "Network.h" class Nuki : public NukiSmartlockEventHandler @@ -22,13 +21,8 @@ private: void updateKeyTurnerState(); void updateBatteryState(); - void lockstateToString(const LockState state, char* str); // char array at least 14 characters LockAction lockActionToEnum(const char* str); // char array at least 14 characters - void triggerToString(const NukiTrigger trigger, char* str); // char arry at least 10 characters - void completionStatusToString(const CompletionStatus status, char* str); // char arry at least 18 characters - void doorSensorStateToString(const DoorSensorState state, char* str); // char arry at least 17 characters - NukiBle _nukiBle; BleScanner _bleScanner; Network* _network; diff --git a/lib/nuki_ble b/lib/nuki_ble index 4b6bb05..8e7fd1d 160000 --- a/lib/nuki_ble +++ b/lib/nuki_ble @@ -1 +1 @@ -Subproject commit 4b6bb05fcbd6f3a94519defef8ce584a088952a9 +Subproject commit 8e7fd1ded1f4cba330494c2e66ed794893c6903e diff --git a/main.cpp b/main.cpp index 2657c3c..970fabf 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,6 @@ #include "Arduino.h" -#include "Network.h" #include "Nuki.h" +#include "Network.h" #include "WebCfgServer.h" #include