RegisteringAsADataSource - robdobsn/RaftCore GitHub Wiki
SysMods are able to publish state information dynamically and can be registered (by themselves or by another module) as a data source.
-
Message Generator Callback (
msgGenCB):- This is the function responsible for formatting the state information in the desired way. It creates the actual content that will be published when needed.
-
State Detection Callback (
stateDetectCB):- This function is used to detect changes in the state that should trigger publishing. It computes a hash of the current state data so that the publisher can check if it has changed since the last publication. If the hash changes, it triggers the publication of the new state.
Data sources are registered using the registerDataSource function. Here’s a breakdown of how this process works:
bool SysManager::registerDataSource(const char* sysModName,
const char* pubTopic,
SysMod_publishMsgGenFn msgGenCB,
SysMod_stateDetectCB stateDetectCB)- sysModName: The name of the system module (SysMod) to which the data source is being registered.
- pubTopic: The topic to generate data for. Note that this is case sensitive.
- msgGenCB: The callback function that generates the message content.
- stateDetectCB: The callback function that computes the state hash to detect changes.
- The SysManager iterates through the list of registered
SysModinstances, looking for a match with the providedsysModName. - If a match is found, it registers the
msgGenCBandstateDetectCBcallbacks for the specifiedpubTopic(which must exist in theStatePublisherconfiguration) - Once registered, the
StatePublisherwill call these functions when required.
The hash mechanism is used to detect when the state of a module has changed. The StatePublisher calls the SysMod's state detection function passing an empty byte vector and the StatePublisher checks it against the previous response to see if anything has changed.
-
State Hashing: The state detection callback (
stateDetectCB) computes a hash of the current state. This is typically done by converting significant state data into bytes and appending to the vector passed in to form a unique signature of the state. -
Hash Comparison: The computed hash is compared to the previous hash stored in the system. If the new hash differs from the previous one, it indicates that the state has changed.
-
Triggering State Change: When a state change is detected, the system will trigger a publication of the new state data. The data is generated using the message generator callback (
msgGenCB) and sent to the appropriate communication channels.
Let's start with the SysMod which is going to generate the data. Here's how the SysMod can register itself as a data source.
void MySysMod::setup()
{
// Register as a data source
getSysManager()->registerDataSource(_scaderCommon.getModuleName().c_str(),
"MyStatus",
[this](const char* messageName, CommsChannelMsg& msg) {
String statusStr = getStatusJSON();
msg.setFromBuffer((uint8_t*)statusStr.c_str(), statusStr.length());
return true;
},
[this](const char* messageName, std::vector<uint8_t>& stateHash) {
return getStatusHash(stateHash);
}
);
}And an example function to format data to be published, this publishes a single value from a variable called _value (we we assume is a 16 bit integer).
String MySysMod::getStatusJSON() const
{
return "{\"value\":" + String(_value) + "}";
}Here's the hash function used to detect changes - since _value is a 16 bit integer we can use the upper and lower bytes to uniquely define its value in the hash vector.
void MySysMod::getStatusHash(std::vector<uint8_t>& stateHash)
{
stateHash.push_back(_value & 0xff);
stateHash.push_back((_value >> 8) & 0xff);
}