UNPKG

@iotize/tap

Version:

IoTize Device client for Javascript

144 lines 12.3 kB
import { bitWiseAnd, bitWiseOr } from '@iotize/common/byte-stream'; import { TapStreamReader, TapStreamWriter } from '@iotize/tap/client/impl'; import { CanSignal, } from './definitions'; export const DBC_DATA_FRAME_LENGTH = 8; export function encodeCanMessage(input, signals) { const result = TapStreamWriter.create(DBC_DATA_FRAME_LENGTH); for (const [attrName, signal] of Object.entries(signals)) { // TODO improve exception with try catch to know with field fail tapStreamWriteCanSignal(input[attrName], signal, result); } result.pos = DBC_DATA_FRAME_LENGTH; return result.toBytes; } export function decodeCanMessage(stream, signals) { if (stream instanceof Uint8Array) { stream = new TapStreamReader(stream); } const result = {}; for (const [attrName, signal] of Object.entries(signals)) { result[attrName] = tapStreamReadCanSignal(stream, signal); } return result; } export function dbcBitPositionToDataFrameIndex(start) { const index = Math.abs((start % 8) - 7); // Equivalent de [-7, -5, -3, -1, 1, 3, 5, 7] return start + (-7 + 2 * index); } export function tapStreamReadCanSignal(stream, signal) { const { bitLength } = signal; checkMaxLength(bitLength); if (stream instanceof Uint8Array) { stream = new TapStreamReader(stream); } const result = readBitsFromDbcSignalStream(stream, signal); return decodeSignalValueNumber(result, signal); } function readBitsFromDbcSignalStream(stream, { endianess, startBit, bitLength }) { const startIndex = dbcBitPositionToDataFrameIndex(startBit); let result; if (endianess === CanSignal.Endianess.LITTLE_ENDIAN) { result = 0 >>> 0; for (let dbcPosition = startBit + bitLength - 1; dbcPosition >= startBit; dbcPosition--) { let frameIndex = dbcBitPositionToDataFrameIndex(dbcPosition); stream.setBitPosition(frameIndex); result = result * 2 + stream.readBits(1); } } else { stream.pos = 0; stream.forwardBits(startIndex); result = stream.readBitsInt(bitLength); } return result; } export function decodeSignalValueNumber(result, { offset, scaling, signed, bitLength: length }) { if (signed) { result = fromSignedOnNBits(result, length); } if (scaling !== undefined) { result = result * scaling; } if (offset !== undefined) { result = result + offset; } return result; } export function encodeSignalValueNumber(value, { offset, scaling, signed, bitLength: length }) { if (offset !== undefined) { value = value - offset; } if (scaling !== 0 && scaling !== undefined) { value = Math.round(value / scaling); } if (signed) { value = toSignedOnNBits(value, length); } return value; } export function tapStreamWriteCanSignal(value, signal, stream) { const { bitLength: length } = signal; checkMaxLength(length); value = encodeSignalValueNumber(value, signal); writeBitsToDbcMessageStream(stream, value, signal); } export function writeBitsToDbcMessageStream(stream, value, { endianess, startBit, bitLength, }) { if (endianess === CanSignal.Endianess.LITTLE_ENDIAN) { let mask = bitShift1(bitLength - 1); for (let dbcPosition = startBit + bitLength - 1; dbcPosition >= startBit; dbcPosition--) { let frameIndex = dbcBitPositionToDataFrameIndex(dbcPosition); stream.setBitPosition(frameIndex); const bitValue = bitWiseAnd(value, mask); stream.writeBoolean(bitValue, 1); mask = mask / 2; } } else { const startIndex = dbcBitPositionToDataFrameIndex(startBit); stream.pos = 0; stream.forwardBits(startIndex); stream.writeBits(value, bitLength); } } function checkMaxLength(length) { if (length > 52) { // TODO proper error throw new Error(`CAN signal with bit length > 52 bits are not supported`); } } export function fromSignedOnNBits(value, length) { checkMaxLength(length); const signedMask = bitShift1(length - 1); const negative = bitWiseAnd(value, signedMask) != 0; if (negative) { const valueMask = signedMask - 1; const cp2 = bitWiseAnd(valueMask, value); return cp2 - signedMask; } else { return value; } } export function toSignedOnNBits(value, length) { checkMaxLength(length); if (value < 0) { if (value < -Math.pow(2, length)) { throw new Error(`Value ${value} is too small to be encoded as a signed on ${length} bits`); } const signedMask = bitShift1(length - 1); const valueMask = signedMask - 1; const cp2 = bitWiseAnd(valueMask, value >>> 0); const result = bitWiseOr(cp2, signedMask); return result; } else { if (value >= Math.pow(2, length)) { throw new Error(`Value ${value} is too big to be encoded as a signed on ${length} bits`); } return value; } } function bitShift1(size) { return Math.pow(2, size); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbGl0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3RhcmdldC9jYW4vZGJjL3NyYy9saWIvdXRpbGl0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDM0UsT0FBTyxFQUVMLFNBQVMsR0FHVixNQUFNLGVBQWUsQ0FBQztBQUV2QixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLENBQUM7QUFFdkMsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixLQUFvQyxFQUNwQyxPQUFzQjtJQUV0QixNQUFNLE1BQU0sR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDN0QsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDeEQsZ0VBQWdFO1FBQ2hFLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDMUQ7SUFDRCxNQUFNLENBQUMsR0FBRyxHQUFHLHFCQUFxQixDQUFDO0lBQ25DLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztBQUN4QixDQUFDO0FBRUQsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixNQUFvQyxFQUNwQyxPQUFzQjtJQUV0QixJQUFJLE1BQU0sWUFBWSxVQUFVLEVBQUU7UUFDaEMsTUFBTSxHQUFHLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQ3RDO0lBQ0QsTUFBTSxNQUFNLEdBQTJCLEVBQUUsQ0FBQztJQUMxQyxLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFD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