Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion docker/MQTTManager/include/entity_manager/entity_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,12 @@ void EntityManager::_command_callback(NSPanelMQTTManagerCommand &command) {
SPDLOG_ERROR("Received command to toggle light entity in slot {} in page with ID {} but entity could not be cast to a light.", command.toggle_entity_from_entities_page().entity_slot(), command.toggle_entity_from_entities_page().entity_page_id());
}
} else {
(*entity)->toggle();
auto scene = std::dynamic_pointer_cast<Scene>(*entity);
if (scene) {
scene->activate(EntityManager::get_room_id_for_panel_id(command.nspanel_id()));
} else {
(*entity)->toggle();
}
}
} else {
SPDLOG_DEBUG("Received command to toggle entity in slot {} in page with ID {} bot did not find such an entity.", command.toggle_entity_from_entities_page().entity_slot(), command.toggle_entity_from_entities_page().entity_page_id());
Expand Down Expand Up @@ -893,6 +898,14 @@ std::expected<std::shared_ptr<NSPanel>, EntityManager::EntityError> EntityManage
return std::unexpected(EntityManager::EntityError::NOT_FOUND);
}

std::expected<int32_t, EntityManager::EntityError> EntityManager::get_room_id_for_panel_id(uint32_t nspanel_id) {
auto nspanel = EntityManager::get_nspanel_by_id(nspanel_id);
if (nspanel.has_value()) {
return (*nspanel)->get_default_room_id();
}
return std::unexpected(EntityManager::EntityError::NOT_FOUND);
}

std::expected<std::shared_ptr<NSPanel>, EntityManager::EntityError> EntityManager::get_nspanel_by_mac(std::string mac) {
SPDLOG_TRACE("Trying to find NSPanel by MAC {}", mac);
std::lock_guard<std::mutex> mutex_guard(EntityManager::_nspanels_mutex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class EntityManager {

static std::expected<std::shared_ptr<NSPanel>, EntityError> get_nspanel_by_id(uint id);
static std::expected<std::shared_ptr<NSPanel>, EntityError> get_nspanel_by_mac(std::string mac);
static std::expected<int32_t, EntityError> get_room_id_for_panel_id(uint32_t nspanel_id);

private:
static inline std::vector<std::shared_ptr<MqttManagerEntity>> _entities;
Expand Down
15 changes: 13 additions & 2 deletions docker/MQTTManager/include/nspanel/nspanel.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "nspanel.hpp"
#include <scenes/scene.hpp>
#include "database_manager/database_manager.hpp"
#include "entity_manager/entity_manager.hpp"
#include "mqtt_manager/mqtt_manager.hpp"
Expand Down Expand Up @@ -1401,7 +1402,12 @@ void NSPanel::command_callback(NSPanelMQTTManagerCommand &command) {
auto entity = EntityManager::get_entity_by_id<MqttManagerEntity>(MQTT_MANAGER_ENTITY_TYPE::ANY, this->_settings.button1_detached_mode_entity_id.value());
if (entity) {
if ((*entity)->can_toggle()) {
(*entity)->toggle();
auto scene = std::dynamic_pointer_cast<Scene>(*entity);
if (scene) {
scene->activate(this->get_default_room_id());
} else {
(*entity)->toggle();
}
}
} else
SPDLOG_ERROR("Tried to toggle detached entity via panel but no entity was found with configured ID '{}'.", this->_settings.button1_detached_mode_entity_id.value());
Expand Down Expand Up @@ -1430,7 +1436,12 @@ void NSPanel::command_callback(NSPanelMQTTManagerCommand &command) {
auto entity = EntityManager::get_entity_by_id<MqttManagerEntity>(MQTT_MANAGER_ENTITY_TYPE::ANY, this->_settings.button2_detached_mode_entity_id.value());
if (entity) {
if ((*entity)->can_toggle()) {
(*entity)->toggle();
auto scene = std::dynamic_pointer_cast<Scene>(*entity);
if (scene) {
scene->activate(this->get_default_room_id());
} else {
(*entity)->toggle();
}
}
} else
SPDLOG_ERROR("Tried to toggle detached entity via panel but no entity was found with configured ID '{}'.", this->_settings.button2_detached_mode_entity_id.value());
Expand Down
23 changes: 18 additions & 5 deletions docker/MQTTManager/include/scenes/home_assistant_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ void HomeAssistantScene::reload_config() {
}
}

void HomeAssistantScene::activate() {
void HomeAssistantScene::activate(std::expected<int32_t, EntityManager::EntityError> triggering_room_id) {
SPDLOG_INFO("Activating scene {}::{}.", this->_id, this->_name);

if (this->_entity_id.starts_with("scene.")) {
nlohmann::json service_data;
service_data["type"] = "call_service";
Expand All @@ -50,11 +51,23 @@ void HomeAssistantScene::activate() {
nlohmann::json context;
context["scene_name"] = this->_name;
context["scene_id"] = this->_id;
auto room = EntityManager::get_room(this->_room_id);
if (!this->_is_global && room.has_value()) {
context["room_name"] = (*room)->get_name();
context["room_id"] = this->_room_id;

if (triggering_room_id.has_value()) {
auto triggering_room = EntityManager::get_room(*triggering_room_id);
if (triggering_room.has_value()) {
context["triggering_room_id"] = *triggering_room_id;
context["triggering_room_name"] = (*triggering_room)->get_name();
}
}

if (!this->_is_global) {
auto scene_room = EntityManager::get_room(this->_room_id);
if (scene_room.has_value()) {
context["scene_room_id"] = this->_room_id;
context["scene_room_name"] = (*scene_room)->get_name();
}
}

service_data["service_data"]["variables"]["nspanelmanager"] = context;
SPDLOG_DEBUG("Sending script with context: {}", context.dump());
service_data["type"] = "call_service";
Expand Down
2 changes: 1 addition & 1 deletion docker/MQTTManager/include/scenes/home_assistant_scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class HomeAssistantScene : public Scene {
public:
HomeAssistantScene(uint32_t id);
void reload_config();
void activate();
void activate(std::expected<int32_t, EntityManager::EntityError> triggering_room_id = std::unexpected(EntityManager::EntityError::NOT_FOUND));
void save();
void remove();
uint16_t get_id();
Expand Down
2 changes: 1 addition & 1 deletion docker/MQTTManager/include/scenes/nspm_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void NSPMScene::reload_config() {
}
}

void NSPMScene::activate() {
void NSPMScene::activate(std::expected<int32_t, EntityManager::EntityError> triggering_room_id) {
SPDLOG_INFO("Activating scene {}::{}.", this->_id, this->_name);
try {
auto light_states = database_manager::database.get_all<database_manager::SceneLightState>(sqlite_orm::where(sqlite_orm::c(&database_manager::SceneLightState::scene_id) == this->_id));
Expand Down
2 changes: 1 addition & 1 deletion docker/MQTTManager/include/scenes/nspm_scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class NSPMScene : public Scene {
~NSPMScene();

void reload_config();
void activate();
void activate(std::expected<int32_t, EntityManager::EntityError> triggering_room_id = std::unexpected(EntityManager::EntityError::NOT_FOUND));
void save();
void remove();
uint16_t get_id();
Expand Down
2 changes: 1 addition & 1 deletion docker/MQTTManager/include/scenes/openhab_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void OpenhabScene::reload_config() {
}
}

void OpenhabScene::activate() {
void OpenhabScene::activate(std::expected<int32_t, EntityManager::EntityError> triggering_room_id) {
SPDLOG_INFO("Activating scene {}::{}.", this->_id, this->_name);

std::string openhab_trigger_scene_url = fmt::format("{}/rest/rules/{}/runnow", MqttManagerConfig::get_setting_with_default<std::string>(MQTT_MANAGER_SETTING::OPENHAB_ADDRESS), this->_entity_id);
Expand Down
2 changes: 1 addition & 1 deletion docker/MQTTManager/include/scenes/openhab_scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class OpenhabScene : public Scene {
public:
OpenhabScene(uint32_t id);
void reload_config();
void activate();
void activate(std::expected<int32_t, EntityManager::EntityError> triggering_room_id = std::unexpected(EntityManager::EntityError::NOT_FOUND));
void save();
void remove();
uint16_t get_id();
Expand Down
4 changes: 3 additions & 1 deletion docker/MQTTManager/include/scenes/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ bool Scene::can_toggle() {
}

void Scene::toggle() {
this->activate();
// Satisfies MqttManagerEntity's pure virtual. In practice all scene activations go through
// activate(triggering_room_id) directly, so this path should never be reached.
this->activate(std::unexpected(EntityManager::EntityError::NOT_FOUND));
}

bool Scene::is_global() {
Expand Down
6 changes: 4 additions & 2 deletions docker/MQTTManager/include/scenes/scene.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#ifndef MQTT_MANAGER_SCENE_BASE_H
#define MQTT_MANAGER_SCENE_BASE_H
#include "entity/entity.hpp"
#include "entity_manager/entity_manager.hpp"
#include <expected>

class Scene : public MqttManagerEntity {
public:
virtual void activate() = 0;
virtual void activate(std::expected<int32_t, EntityManager::EntityError> triggering_room_id = std::unexpected(EntityManager::EntityError::NOT_FOUND)) = 0;
virtual void save() = 0;
virtual void remove() = 0;
virtual void reload_config() = 0;
Expand All @@ -17,7 +19,7 @@ class Scene : public MqttManagerEntity {
bool is_global();

// The same as activate()
void toggle();
void toggle() override;

virtual std::string get_name() = 0;
virtual bool can_save() = 0;
Expand Down