Group Objects
Declare, register, read, write, and react to KNX group objects with the portable typed object aliases of the kbox-stack.
Group objects are the values your application exchanges over the KNX bus. The stack gives you typed C++ objects that map to the group addresses configured in ETS. This page is fully portable — nothing here depends on a specific MCU.
Typed object aliases
Every group object is a DeviceObject under the hood. You use one of the typed
aliases, which carry their own storage:
| Alias | Backing type | Typical use |
|---|---|---|
BitObject | 1-bit | switch, on/off, alive |
ByteObject | 1-byte | scene number, state 0/1/2 |
FloatObject | 2-byte | KNX 2-octet float (DPT 9.x) raw word |
ByteArrayObject<N> | N bytes | multi-byte / octet payloads |
DeviceObject is non-copyable and non-movable (its copy/move members are
deleted). Always pass group objects by reference (DeviceObject&), never by
value — and store them as members, not temporaries.
Declaring objects
Declare each object as a member field, constructed with its objectId. The id is
what ties the object to its group address in the ETS project.
class MyLogic : public KnxLogicBase {
// ...
private:
BitObject onOff_{Object_OnOff_Bit}; // incoming on/off
BitObject onOffFeedback_{Object_OnOffFeedback_Bit}; // outgoing status
ByteObject ledState_{Object_LedState_Byte}; // incoming state
ByteObject ledStateFeedback_{Object_LedStateFeedback_Byte};
BitObject alive_{Object_AliveNotification_Bit}; // outgoing alive
};Registering: Tables().Push
An object only participates in bus traffic once it is pushed into the database. Register every object in the constructor:
MyLogic::MyLogic(IKnxStack& stack) : KnxLogicBase(stack) {
this->stack.Tables().Push(&onOff_);
this->stack.Tables().Push(&onOffFeedback_);
this->stack.Tables().Push(&ledState_);
this->stack.Tables().Push(&ledStateFeedback_);
this->stack.Tables().Push(&alive_);
}See Database for capacity limits and lookups.
Accessors
Read and write an object's value through its typed accessors. Note that
SetValueAsFloat / GetValueAsFloat work on the raw 16-bit word — encode
the DPT 9.x float yourself.
| Method | Purpose |
|---|---|
SetValueAsBit(bool) | set a 1-bit value |
SetValueAsByte(uint8_t) | set a 1-byte value |
SetValueAsFloat(uint16_t) | set the raw 2-octet float word |
SetValue(ByteSpan) | set a multi-byte value |
GetValueAsBit() → bool | read a 1-bit value |
GetValueAsByte() → uint8_t | read a 1-byte value |
GetValueAsFloat() → uint16_t | read the raw 2-octet float word |
GetValueSpan() → ByteSpan | read the raw bytes |
GetValueInto(uint8_t* out, uint8_t cap) → uint8_t | copy bytes out, returns length |
onOffFeedback_.SetValueAsBit(true);
uint8_t state = ledState_.GetValueAsByte();Reacting: onDifference
When a group write arrives from the bus, the stack calls your onDifference
handler with a Difference. Route on difference.objectId, then read the new
value from difference.newData (a KnxData):
void MyLogic::OnDifference(Difference& difference) {
switch (difference.objectId) {
case Object_OnOff_Bit: {
bool on = difference.newData.GetDataBit();
// apply on/off ...
break;
}
case Object_LedState_Byte: {
uint8_t state = difference.newData.GetDataByte();
// apply state ...
break;
}
default:
break; // an object this logic does not care about
}
}KnxData exposes GetDataBit(), GetDataByte(), and GetDataWord() (plus
GetDataSpan() for raw bytes). difference.oldData holds the previous value if
you need to compare.
Sending feedback
To publish a value onto the bus, set it on the object, then call
SendTelegramGroupValueWrite:
onOffFeedback_.SetValueAsBit(on);
this->stack.SendTelegramGroupValueWrite(onOffFeedback_);Group object flags
Each object's communication behaviour is controlled by config flags. The named
constants live in GroupObjectFlag.h.
Config flags are read per-access straight from the group-object table — see
Database · Lookups (GetConfigFlags). An ETS slot left
at 0x00 has Communication off and stays inert.