// 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); }