cabana/src/utils/dbc.js

184 lines
4.1 KiB
JavaScript

function findMaxByteStateChangeCount(messages) {
return Object.values(messages)
.map(m => m.byteStateChangeCounts)
.reduce((counts, countArr) => counts.concat(countArr), []) // flatten arrays
.reduce((count1, count2) => (count1 > count2 ? count1 : count2), 0); // find max
}
function addCanMessage(
canMessage,
dbc,
canStartTime,
messages,
prevMsgEntries,
byteStateChangeCountsByMessage
) {
var { address, busTime, data, bus } = canMessage;
var id = bus + ":" + address.toString(16);
if (messages[id] === undefined)
messages[id] = createMessageSpec(dbc, address, id, bus);
const prevMsgEntry =
messages[id].entries.length > 0
? messages[id].entries[messages[id].entries.length - 1]
: prevMsgEntries[id] || null;
if (
byteStateChangeCountsByMessage[id] &&
messages[id].byteStateChangeCounts.every(c => c === 0)
) {
messages[id].byteStateChangeCounts = byteStateChangeCountsByMessage[id];
}
const { msgEntry, byteStateChangeCounts } = parseMessage(
dbc,
busTime,
address,
data,
canStartTime,
prevMsgEntry
);
messages[id].byteStateChangeCounts = byteStateChangeCounts.map(
(count, idx) => messages[id].byteStateChangeCounts[idx] + count
);
messages[id].entries.push(msgEntry);
return msgEntry;
}
function createMessageSpec(dbc, address, id, bus) {
const frame = dbc.messages.get(address);
const size = frame ? frame.size : 8;
return {
address: address,
id: id,
bus: bus,
entries: [],
frame: frame,
byteColors: Array(size).fill(0),
byteStateChangeCounts: Array(size).fill(0)
};
}
function determineByteStateChangeTimes(
hexData,
time,
msgSize,
lastParsedMessage
) {
const byteStateChangeCounts = Array(msgSize).fill(0);
let byteStateChangeTimes;
if (!lastParsedMessage) {
byteStateChangeTimes = Array(msgSize).fill(time);
} else {
byteStateChangeTimes = Array.from(lastParsedMessage.byteStateChangeTimes);
for (let i = 0; i < byteStateChangeTimes.length; i++) {
const currentData = hexData.substr(i * 2, 2),
prevData = lastParsedMessage.hexData.substr(i * 2, 2);
if (currentData !== prevData) {
byteStateChangeTimes[i] = time;
byteStateChangeCounts[i] = 1;
}
}
}
return { byteStateChangeTimes, byteStateChangeCounts };
}
function createMessageEntry(
dbc,
address,
time,
relTime,
data,
byteStateChangeTimes
) {
return {
signals: dbc.getSignalValues(address, data),
time,
relTime,
hexData: Buffer.from(data).toString("hex"),
byteStateChangeTimes,
updated: Date.now()
};
}
function parseMessage(dbc, time, address, data, timeStart, lastParsedMessage) {
let hexData;
if (typeof data === "string") {
hexData = data;
data = Buffer.from(data, "hex");
} else {
hexData = Buffer.from(data).toString("hex");
}
const msgSpec = dbc.messages.get(address);
const msgSize = msgSpec ? msgSpec.size : 8;
const relTime = time - timeStart;
const {
byteStateChangeTimes,
byteStateChangeCounts
} = determineByteStateChangeTimes(
hexData,
relTime,
msgSize,
lastParsedMessage
);
const msgEntry = createMessageEntry(
dbc,
address,
time,
relTime,
data,
byteStateChangeTimes
);
return { msgEntry, byteStateChangeCounts };
}
const BIG_ENDIAN_START_BITS = [];
for (let i = 0; i < 64; i += 8) {
for (let j = 7; j > -1; j--) {
BIG_ENDIAN_START_BITS.push(i + j);
}
}
function bigEndianBitIndex(matrixBitIndex) {
return BIG_ENDIAN_START_BITS.indexOf(matrixBitIndex);
}
function matrixBitNumber(bigEndianIndex) {
return BIG_ENDIAN_START_BITS[bigEndianIndex];
}
function setMessageByteColors(message, maxByteStateChangeCount) {
message.byteColors = message.byteStateChangeCounts
.map(
count =>
isNaN(count)
? 0
: Math.min(255, 75 + 180 * (count / maxByteStateChangeCount))
)
.map(red => "rgb(" + Math.round(red) + ",0,0)");
return message;
}
export default {
bigEndianBitIndex,
addCanMessage,
createMessageSpec,
matrixBitNumber,
parseMessage,
findMaxByteStateChangeCount,
setMessageByteColors,
createMessageEntry
};