Add KNX DALI Gateway Module and Message Queue Implementation
- Introduced KnxDaliModule class for handling DALI message queuing, commissioning, and KNX group-object dispatch. - Implemented Message and MessageQueue classes for managing message operations. - Removed obsolete OpenKNX IDF component files and CMake configurations. - Updated submodule reference for KNX. Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
#include "knx_dali_channel.h"
|
||||
#include "dali_define.hpp"
|
||||
#include "knxprod.h"
|
||||
#include "dali_helper.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
namespace gateway {
|
||||
namespace knx_dali_gw {
|
||||
|
||||
KnxDaliChannel::KnxDaliChannel() = default;
|
||||
KnxDaliChannel::~KnxDaliChannel() = default;
|
||||
|
||||
void KnxDaliChannel::init(uint8_t channel_index, bool is_group, DaliGatewayBridge& bridge) {
|
||||
index_ = channel_index;
|
||||
is_group_ = is_group;
|
||||
dali_ = &bridge;
|
||||
}
|
||||
|
||||
void KnxDaliChannel::setup() {
|
||||
if (dali_ == nullptr) return;
|
||||
// Query initial state
|
||||
DaliTarget target = is_group_ ? DaliTarget{DaliTargetKind::kGroup, static_cast<int>(index_)}
|
||||
: DaliTarget{DaliTargetKind::kShortAddress, static_cast<int>(index_)};
|
||||
(void)target; // Will be used in full port
|
||||
}
|
||||
|
||||
void KnxDaliChannel::loop() {
|
||||
if (dali_ == nullptr) return;
|
||||
loopDimming();
|
||||
loopStaircase();
|
||||
loopQueryLevel();
|
||||
}
|
||||
|
||||
void KnxDaliChannel::processInputKo(GroupObject& ko) {
|
||||
uint16_t asap = ko.asap();
|
||||
int slot = static_cast<int>(asap) - (is_group_ ? GRP_KoOffset : ADR_KoOffset) - index_ * (is_group_ ? GRP_KoBlockSize : ADR_KoBlockSize);
|
||||
|
||||
// TODO: Full slot-to-handler mapping from DaliChannel.cpp
|
||||
// For now, delegate to basic handlers
|
||||
switch (slot) {
|
||||
case 0: koHandleSwitch(ko); break;
|
||||
// ... more slots
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Dimming ----
|
||||
|
||||
void KnxDaliChannel::loopDimming() {
|
||||
if (dimm_direction_ == DimmDirection::kNone) return;
|
||||
uint64_t now = esp_timer_get_time() / 1000ULL;
|
||||
if (now - dimm_last_ < dimm_interval_) return;
|
||||
dimm_last_ = now;
|
||||
|
||||
DaliTarget target = is_group_ ? DaliTarget{DaliTargetKind::kGroup, static_cast<int>(index_)}
|
||||
: DaliTarget{DaliTargetKind::kShortAddress, static_cast<int>(index_)};
|
||||
|
||||
if (dimm_direction_ == DimmDirection::kUp) {
|
||||
if (current_step_ < max_) current_step_++;
|
||||
dali_->setArc(target, current_step_);
|
||||
} else {
|
||||
if (current_step_ > min_) current_step_--;
|
||||
dali_->setArc(target, current_step_);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Staircase ----
|
||||
|
||||
void KnxDaliChannel::loopStaircase() {
|
||||
if (interval_ == 0 || !current_state_) return;
|
||||
uint64_t now = esp_timer_get_time() / 1000ULL;
|
||||
if (now - start_time_ >= interval_ * 1000ULL) {
|
||||
current_state_ = false;
|
||||
interval_ = 0;
|
||||
DaliTarget target = is_group_ ? DaliTarget{DaliTargetKind::kGroup, static_cast<int>(index_)}
|
||||
: DaliTarget{DaliTargetKind::kShortAddress, static_cast<int>(index_)};
|
||||
dali_->off(target);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Query Level ----
|
||||
|
||||
void KnxDaliChannel::loopQueryLevel() {
|
||||
// Periodic status query — simplified for now
|
||||
}
|
||||
|
||||
// ---- Switch State ----
|
||||
|
||||
void KnxDaliChannel::setSwitchState(bool value, bool is_switch_command) {
|
||||
if (current_is_locked_) return;
|
||||
current_state_ = value;
|
||||
DaliTarget target = is_group_ ? DaliTarget{DaliTargetKind::kGroup, static_cast<int>(index_)}
|
||||
: DaliTarget{DaliTargetKind::kShortAddress, static_cast<int>(index_)};
|
||||
if (value) {
|
||||
dali_->on(target);
|
||||
} else {
|
||||
dali_->off(target);
|
||||
}
|
||||
if (value) {
|
||||
start_time_ = esp_timer_get_time() / 1000ULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Configuration setters ----
|
||||
|
||||
void KnxDaliChannel::setOnValue(uint8_t value) {
|
||||
on_day_ = value;
|
||||
on_night_ = value / 2;
|
||||
}
|
||||
|
||||
void KnxDaliChannel::setGroups(uint16_t groups) { groups_ = groups; }
|
||||
void KnxDaliChannel::setGroupState(uint8_t group, bool state) {
|
||||
if (state) groups_ |= (1 << group); else groups_ &= ~(1 << group);
|
||||
}
|
||||
void KnxDaliChannel::setGroupState(uint8_t group, uint8_t) {}
|
||||
void KnxDaliChannel::setMinMax(uint8_t min, uint8_t max) { min_ = min; max_ = max; }
|
||||
void KnxDaliChannel::setMinArc(uint8_t min) { min_ = min; }
|
||||
void KnxDaliChannel::setHcl(uint8_t curve, uint16_t temp, uint8_t) {
|
||||
hcl_curve_ = curve;
|
||||
hcl_current_temp_ = temp;
|
||||
}
|
||||
|
||||
// ---- Dimm State ----
|
||||
|
||||
void KnxDaliChannel::setDimmState(uint8_t value, bool, bool) {
|
||||
current_step_ = value;
|
||||
}
|
||||
|
||||
// ---- Color ----
|
||||
|
||||
void KnxDaliChannel::sendColor() {
|
||||
if (dali_ == nullptr) return;
|
||||
dali_->setColourRGB(static_cast<int>(index_), current_color_[0],
|
||||
current_color_[1], current_color_[2]);
|
||||
}
|
||||
|
||||
// ---- KO Handlers ----
|
||||
|
||||
void KnxDaliChannel::koHandleSwitch(GroupObject& ko) {
|
||||
bool on = static_cast<bool>(ko.value());
|
||||
setSwitchState(on);
|
||||
}
|
||||
|
||||
void KnxDaliChannel::koHandleDimmRel(GroupObject& ko) {
|
||||
int step = static_cast<int>(static_cast<float>(ko.value()));
|
||||
if (step > 0) {
|
||||
dimm_direction_ = DimmDirection::kUp;
|
||||
dimm_step_ = static_cast<uint8_t>(step);
|
||||
} else if (step < 0) {
|
||||
dimm_direction_ = DimmDirection::kDown;
|
||||
dimm_step_ = static_cast<uint8_t>(-step);
|
||||
} else {
|
||||
dimm_direction_ = DimmDirection::kNone;
|
||||
}
|
||||
dimm_last_ = esp_timer_get_time() / 1000ULL;
|
||||
}
|
||||
|
||||
void KnxDaliChannel::koHandleDimmAbs(GroupObject& ko) {
|
||||
uint8_t value = static_cast<uint8_t>(static_cast<float>(ko.value()) * 255.0f / 100.0f);
|
||||
setDimmState(value);
|
||||
dimm_direction_ = DimmDirection::kNone;
|
||||
DaliTarget target = is_group_ ? DaliTarget{DaliTargetKind::kGroup, static_cast<int>(index_)}
|
||||
: DaliTarget{DaliTargetKind::kShortAddress, static_cast<int>(index_)};
|
||||
dali_->setArc(target, value);
|
||||
}
|
||||
|
||||
void KnxDaliChannel::koHandleLock(GroupObject& ko) {
|
||||
bool lock = static_cast<bool>(ko.value());
|
||||
current_is_locked_ = lock;
|
||||
}
|
||||
|
||||
void KnxDaliChannel::koHandleColor(GroupObject& ko) {
|
||||
KNXValue val = ko.value();
|
||||
if (true) {
|
||||
// RGB packed in float or raw bytes
|
||||
// Simplified: store and send
|
||||
sendColor();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace knx_dali_gw
|
||||
} // namespace gateway
|
||||
Reference in New Issue
Block a user