Vicki Downlink Encoder

Use the following script to start controlling Vicki LoRaWAN from your application in settings. Thanks to this script, you can skip understanding the hex device communication protocol of Vicki and go straight to development and testing.
If you will be using Vicki in large installations, we urge you to read the following points from the Device communication protocol document, so you can better understand the device:
const decToHex = (integer, shouldAddZero = true) => {
let number = (+integer).toString(16).toUpperCase()
if( (number.length % 2) > 0 && shouldAddZero ) { number= "0" + number }
return number
}
const dec2hexWithZero = (i) => {
return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
const toHex = (cmdName, cmdId, ...params) => {
if(cmdName == "SetOpenWindow") return cmdId.toString(16).padStart(2, '0') + params.reduce((paramString, param) => {
return paramString += param
}, "")
else return cmdId.toString(16).padStart(2, '0') + params.reduce((paramString, param) => {
return paramString += param.padStart(2, '0')
}, "")
}
const forceClose = () => {
return toHex('ForceClose', 0x0B);
}
const getAllParams = () => {
return toHex('GetAllParams',
'14',
'16',
'17',
'12',
'13',
'18',
'19',
'15',
'1B'
);
}
const getChildLock = () => {
return toHex('GetChildLock', 0x14);
}
const getInternalAlgoParams = () => {
return toHex('GetInternalAlgoParams', 0x16);
}
const getInternalAlgoTdiffParams = () => {
return toHex('GetInternalAlgoTdiffParams', 0x17);
}
const getJoinRetryPeriod = () => {
return toHex('GetJoinRetryPeriod', 0x19);
}
const getKeepAliveTime = () => {
return toHex('GetKeepAliveTime', 0x12);
}
const getOpenWindowParams = () => {
return toHex('GetOpenWindowParams', 0x13);
}
const getOperationalMode = () => {
return toHex('GetOperationalMode', 0x18);
}
const getTemperatureRange = () => {
return toHex('GetTemperatureRange', 0x15);
}
const getUplinkType = () => {
return toHex('GetUplinkType', 0x1B);
}
const recalibrateMotor = () => {
return toHex('RecalibrateMotor', 0x03);
}
const receivedKeepaliveCommand = () => {
return toHex('ReceivedKeepalive', 0x55);
}
const sendCustomHexCommand = (command) => {
return toHex('SendCustomHexCommand', command);
}
const setChildLock = (enabled) => {
let enabledValue = enabled ? 1 : 0;
return toHex('SetChildLock', 0x07, decToHex(enabledValue));
}
const setInternalAlgoParams = (period, pFirstLast, pNext) => {
return toHex('SetInternalAlgoParams', 0x0C, decToHex(period), decToHex(pFirstLast), decToHex(pNext));
}
const setInternalAlgoTdiffParams = (cold, warm) => {
return toHex('SetInternalAlgoTdiffParams', 0x1A, decToHex(cold), decToHex(warm));
}
const setJoinRetryPeriod = (period) => {
// period should be passed in minutes
let periodToPass = (period * 60) / 5;
return toHex('SetJoinRetryPeriod', 0x10, parseInt(periodToPass).toString(16));
}
const setKeepAlive = (time) => {
return toHex( 'SetKeepAlive', 0x02, parseInt(time).toString(16));
}
const setOpenWindow = (enabled, delta, closeTime, motorPosition) => {
let enabledValue = enabled ? 1 : 0;
let closeTimeValue = parseInt(closeTime) / 5;
let motorPositionBin = `000000000000${parseInt(motorPosition, 10).toString(2)}`;
motorPositionBin = motorPositionBin.substr(-12);
let motorPositionFirstPart = parseInt(motorPositionBin.substr(4), 2, 16);
let motorPositionSecondPart = parseInt(motorPositionBin.substr(0, 4), 2, 16);
return toHex(
'SetOpenWindow',
0x06,
decToHex(enabledValue),
decToHex(closeTimeValue),
decToHex(motorPositionFirstPart, false),
decToHex(motorPositionSecondPart, false),
decToHex(delta, false)
);
}
const setOperationalMode = (mode) => {
return toHex( 'SetOperationalMode', 0x0D, mode);
}
const setTargetTemperature = (targetTemperature) => {
return toHex( 'SetTargetTemperature', 0x0E, decToHex(targetTemperature));
}
const setTargetTemperatureAndMotorPosition = (motorPosition, targetTemperature) => {
return toHex('SetTargetTemperatureAndMotorPosition', 0x31, dec2hexWithZero(motorPosition), decToHex(targetTemperature))
}
const setTemperatureRange = (min, max) => {
return toHex( 'SetTemperatureRange', 0x08, decToHex(min), decToHex(max));
}
const setUplinkType = (type) => {
return toHex( 'SetUplinkType', 0x11, type);
}