190 lines
5.4 KiB
C++
190 lines
5.4 KiB
C++
// signal_manager.cpp - Signal Manager Implementation
|
|
|
|
#include "signal_manager.h"
|
|
|
|
SignalDefinition signalDefs[MAX_MANUAL_SIGNALS];
|
|
uint16_t signalDefCount = 0;
|
|
SignalValue signalValues[MAX_MANUAL_SIGNALS];
|
|
|
|
void initSignalManager() {
|
|
signalDefCount = 0;
|
|
for (int i = 0; i < MAX_MANUAL_SIGNALS; i++) {
|
|
signalDefs[i].enabled = false;
|
|
signalValues[i].valid = false;
|
|
}
|
|
|
|
// Try to load saved signals
|
|
loadSignalsFromSD();
|
|
}
|
|
|
|
bool addManualSignal(const char* name, uint32_t canId, uint32_t startBit,
|
|
uint32_t length, bool isLittleEndian, bool isSigned,
|
|
float factor, float offset) {
|
|
if (signalDefCount >= MAX_MANUAL_SIGNALS) {
|
|
return false;
|
|
}
|
|
|
|
// Check if signal already exists
|
|
for (uint16_t i = 0; i < signalDefCount; i++) {
|
|
if (strcmp(signalDefs[i].name, name) == 0) {
|
|
// Update existing
|
|
signalDefs[i].canId = canId;
|
|
signalDefs[i].startBit = startBit;
|
|
signalDefs[i].length = length;
|
|
signalDefs[i].isLittleEndian = isLittleEndian;
|
|
signalDefs[i].isSigned = isSigned;
|
|
signalDefs[i].factor = factor;
|
|
signalDefs[i].offset = offset;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Add new signal
|
|
SignalDefinition* sig = &signalDefs[signalDefCount++];
|
|
strncpy(sig->name, name, 31);
|
|
sig->canId = canId;
|
|
sig->startBit = startBit;
|
|
sig->length = length;
|
|
sig->isLittleEndian = isLittleEndian;
|
|
sig->isSigned = isSigned;
|
|
sig->factor = factor;
|
|
sig->offset = offset;
|
|
sig->source = SIGNAL_SOURCE_MANUAL;
|
|
sig->enabled = true;
|
|
|
|
// Initialize value slot
|
|
strncpy(signalValues[signalDefCount - 1].name, name, 31);
|
|
signalValues[signalDefCount - 1].value = 0;
|
|
signalValues[signalDefCount - 1].valid = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool removeSignal(const char* name) {
|
|
for (uint16_t i = 0; i < signalDefCount; i++) {
|
|
if (strcmp(signalDefs[i].name, name) == 0) {
|
|
// Shift remaining signals
|
|
for (uint16_t j = i; j < signalDefCount - 1; j++) {
|
|
signalDefs[j] = signalDefs[j + 1];
|
|
signalValues[j] = signalValues[j + 1];
|
|
}
|
|
signalDefCount--;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool enableSignal(const char* name, bool enable) {
|
|
SignalDefinition* sig = getSignalDef(name);
|
|
if (sig) {
|
|
sig->enabled = enable;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
SignalDefinition* getSignalDef(const char* name) {
|
|
for (uint16_t i = 0; i < signalDefCount; i++) {
|
|
if (strcmp(signalDefs[i].name, name) == 0) {
|
|
return &signalDefs[i];
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
SignalValue* getSignalValue(const char* name) {
|
|
for (uint16_t i = 0; i < signalDefCount; i++) {
|
|
if (strcmp(signalValues[i].name, name) == 0) {
|
|
return &signalValues[i];
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void updateSignalFromCAN(const CanFrame* frame) {
|
|
if (!frame) return;
|
|
|
|
// Check DBC signals first
|
|
if (dbcDB.loaded) {
|
|
DbcMessage* msg = getMessageById(frame->id);
|
|
if (msg) {
|
|
DbcSignal* signals;
|
|
uint16_t count = getSignalsForMessage(frame->id, &signals);
|
|
for (uint16_t i = 0; i < count; i++) {
|
|
float value = extractSignalValue(frame->data, &signals[i]);
|
|
|
|
// Update signal value if we have a matching manual signal
|
|
SignalValue* sv = getSignalValue(signals[i].name);
|
|
if (sv) {
|
|
sv->value = value;
|
|
sv->timestamp = frame->timestamp / 1000; // Convert to ms
|
|
sv->valid = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check manual signals
|
|
for (uint16_t i = 0; i < signalDefCount; i++) {
|
|
if (signalDefs[i].canId == frame->id && signalDefs[i].enabled) {
|
|
// Create a temporary DbcSignal for extraction
|
|
DbcSignal tempSig;
|
|
strncpy(tempSig.name, signalDefs[i].name, 32);
|
|
tempSig.startBit = signalDefs[i].startBit;
|
|
tempSig.length = signalDefs[i].length;
|
|
tempSig.isLittleEndian = signalDefs[i].isLittleEndian;
|
|
tempSig.isSigned = signalDefs[i].isSigned;
|
|
tempSig.factor = signalDefs[i].factor;
|
|
tempSig.offset = signalDefs[i].offset;
|
|
|
|
float value = extractSignalValue(frame->data, &tempSig);
|
|
signalValues[i].value = value;
|
|
signalValues[i].timestamp = frame->timestamp / 1000;
|
|
signalValues[i].valid = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void updateAllSignals(const CanFrame* frame) {
|
|
updateSignalFromCAN(frame);
|
|
}
|
|
|
|
uint16_t getEnabledSignals(SignalValue* values, uint16_t maxCount) {
|
|
uint16_t count = 0;
|
|
for (uint16_t i = 0; i < signalDefCount && count < maxCount; i++) {
|
|
if (signalDefs[i].enabled && signalValues[i].valid) {
|
|
values[count++] = signalValues[i];
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
bool loadSignalsFromSD() {
|
|
// TODO: Implement loading from SD card
|
|
return false;
|
|
}
|
|
|
|
bool saveSignalsToSD() {
|
|
// TODO: Implement saving to SD card
|
|
return false;
|
|
}
|
|
|
|
void getSignalsJSON(char* buffer, size_t bufferSize) {
|
|
int pos = snprintf(buffer, bufferSize, "{\"count\":%d,\"signals\":[", signalDefCount);
|
|
|
|
for (uint16_t i = 0; i < signalDefCount && pos < (int)bufferSize - 100; i++) {
|
|
if (i > 0) {
|
|
pos += snprintf(buffer + pos, bufferSize - pos, ",");
|
|
}
|
|
SignalDefinition* sig = &signalDefs[i];
|
|
pos += snprintf(buffer + pos, bufferSize - pos,
|
|
"{\"name\":\"%s\",\"canId\":\"0x%X\",\"startBit\":%d,\"length\":%d,\"enabled\":%s,\"value\":%.2f}",
|
|
sig->name, sig->canId, sig->startBit, sig->length,
|
|
sig->enabled ? "true" : "false",
|
|
signalValues[i].value);
|
|
}
|
|
|
|
strncat(buffer, "]}", bufferSize - pos - 1);
|
|
}
|