Añadir lsn50-v2-xkc-y25-v-drainage/config/codec-production.js
This commit is contained in:
parent
70f76ba107
commit
45ced2c42b
106
lsn50-v2-xkc-y25-v-drainage/config/codec-production.js
Normal file
106
lsn50-v2-xkc-y25-v-drainage/config/codec-production.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// ChirpStack v4+ Codec (JavaScript)
|
||||||
|
// LSN50 v2.x - Production codec for PA12 + Downlink control (TDC + 5VT)
|
||||||
|
//
|
||||||
|
// Verified mapping (uplink): PA12 = bytes[6] bit1 (0x02) on FPort 2 (MOD=1, 11 bytes)
|
||||||
|
// Downlink commands (Dragino common):
|
||||||
|
// - Set TDC (seconds): 0x01 + 3 bytes (big-endian)
|
||||||
|
// - Set 5VT (ms): 0x07 + 2 bytes (big-endian)
|
||||||
|
|
||||||
|
const CFG = {
|
||||||
|
INVERT_LOGIC: false,
|
||||||
|
EXPECTED_UP_FPORT: 2,
|
||||||
|
EXPECTED_UP_LEN: 11,
|
||||||
|
CMD_FPORT: 2,
|
||||||
|
LIMITS: {
|
||||||
|
TDC_SEC_MIN: 5,
|
||||||
|
TDC_SEC_MAX: 86400,
|
||||||
|
VT_MS_MIN: 0,
|
||||||
|
VT_MS_MAX: 60000
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function decodeUplink(input) {
|
||||||
|
const b = input.bytes || [];
|
||||||
|
const fPort = input.fPort;
|
||||||
|
const rawHex = b.map(x => x.toString(16).padStart(2, "0")).join("");
|
||||||
|
|
||||||
|
const byte6 = (b.length > 6) ? b[6] : 0x00;
|
||||||
|
const pa12 = (byte6 & 0x02) ? 1 : 0;
|
||||||
|
const drenaje = CFG.INVERT_LOGIC ? (pa12 ? 0 : 1) : pa12;
|
||||||
|
|
||||||
|
const warnings = [];
|
||||||
|
if (fPort !== CFG.EXPECTED_UP_FPORT) warnings.push(`Unexpected fPort=${fPort}, expected ${CFG.EXPECTED_UP_FPORT}`);
|
||||||
|
if (b.length !== CFG.EXPECTED_UP_LEN) warnings.push(`Unexpected payload length=${b.length}, expected ${CFG.EXPECTED_UP_LEN}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
drenaje,
|
||||||
|
pa12,
|
||||||
|
byte6,
|
||||||
|
payload_len: b.length,
|
||||||
|
payload_hex: rawHex,
|
||||||
|
warnings: warnings.length ? warnings : undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function u16be(n) {
|
||||||
|
return [(n >> 8) & 0xff, n & 0xff];
|
||||||
|
}
|
||||||
|
|
||||||
|
function u24be(n) {
|
||||||
|
return [(n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff];
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertInt(name, v) {
|
||||||
|
if (typeof v !== "number" || !isFinite(v) || Math.floor(v) !== v) {
|
||||||
|
throw new Error(`${name} must be an integer`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clampInt(name, v, min, max) {
|
||||||
|
assertInt(name, v);
|
||||||
|
if (v < min || v > max) throw new Error(`${name} out of range [${min}, ${max}]: ${v}`);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodeDownlink(input) {
|
||||||
|
const data = (input && input.data) ? input.data : {};
|
||||||
|
const cmd = data.cmd;
|
||||||
|
|
||||||
|
if (!cmd) {
|
||||||
|
return { bytes: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd === "set_tdc") {
|
||||||
|
const tdc = clampInt("tdc_sec", data.tdc_sec, CFG.LIMITS.TDC_SEC_MIN, CFG.LIMITS.TDC_SEC_MAX);
|
||||||
|
const bytes = [0x01].concat(u24be(tdc));
|
||||||
|
return {
|
||||||
|
fPort: CFG.CMD_FPORT,
|
||||||
|
bytes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd === "set_5vt") {
|
||||||
|
const vt = clampInt("vt_ms", data.vt_ms, CFG.LIMITS.VT_MS_MIN, CFG.LIMITS.VT_MS_MAX);
|
||||||
|
const bytes = [0x07].concat(u16be(vt));
|
||||||
|
return {
|
||||||
|
fPort: CFG.CMD_FPORT,
|
||||||
|
bytes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd === "profile_active") {
|
||||||
|
const vt = clampInt("vt_ms", (data.vt_ms ?? 2000), CFG.LIMITS.VT_MS_MIN, CFG.LIMITS.VT_MS_MAX);
|
||||||
|
const bytes = [0x07].concat(u16be(vt));
|
||||||
|
return { fPort: CFG.CMD_FPORT, bytes };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd === "profile_sleep") {
|
||||||
|
const vt = clampInt("vt_ms", (data.vt_ms ?? 0), CFG.LIMITS.VT_MS_MIN, CFG.LIMITS.VT_MS_MAX);
|
||||||
|
const bytes = [0x07].concat(u16be(vt));
|
||||||
|
return { fPort: CFG.CMD_FPORT, bytes };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Unknown cmd: ${cmd}`);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user