449a3a801a
- 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>
185 lines
5.4 KiB
C++
185 lines
5.4 KiB
C++
#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
|