Skip to content

Instantly share code, notes, and snippets.

@ThiefMaster
Last active February 5, 2025 19:41
Show Gist options
  • Save ThiefMaster/9d2c2f30b9998e3b27b4271bd56aa9b1 to your computer and use it in GitHub Desktop.
Save ThiefMaster/9d2c2f30b9998e3b27b4271bd56aa9b1 to your computer and use it in GitHub Desktop.
This script can be used on a Shelly 2PM (gen3) to nicely control a french heater that's using the "fil pilote" protocol.
const CONFIG = {
// ID of the virtual component to select the mode
componentId: 200,
// ID of the relay with the diode providing a negative wave
negativeWaveSwitch: 0,
// ID of the relay with the diode providing a positive wave
positiveWaveSwitch: 1,
};
const simpleModes = {
comfort: [false, false],
eco: [true, true],
antifrost: [true, false],
off: [false, true],
};
const timerDurations = {
comfort_minus1: 3,
comfort_minus2: 7,
};
CONFIG.componentName = 'enum:' + CONFIG.componentId;
let currentMode = null;
let timer = null;
Shelly.call('Enum.GetStatus', {id: CONFIG.componentId}, function (res) {
print('Initial mode', res.value);
currentMode = res.value;
handleModeChange();
});
Shelly.addStatusHandler(function (evt) {
if (evt.component !== CONFIG.componentName) { return; }
print('New mode', evt.delta.value);
currentMode = evt.delta.value;
handleModeChange();
});
function setOutput(a, b) {
Shelly.call('Switch.set', {id: CONFIG.negativeWaveSwitch, on: a});
Shelly.call('Switch.set', {id: CONFIG.positiveWaveSwitch, on: b});
}
function handleModeChange() {
print('Mode changed to', currentMode);
if (timer !== null) {
print('Clearing timer');
Timer.clear(timer);
timer = null;
}
const simple = simpleModes[currentMode];
const duration = timerDurations[currentMode];
if (simple) {
print('Simple mode -> updating relays:', simple);
setOutput.apply(null, simple);
} else if (duration) {
print('Time-based mode -> starting timer:', duration);
timedCycle(duration);
} else {
print('Invalid mode', currentMode);
}
}
function timedCycle(duration) {
const onDuration = duration * 1000;
const offDuration = 300000 - onDuration;
print('Starting ON cycle', duration);
setOutput(true, true);
timer = Timer.set(onDuration, false, function () {
print('Starting OFF cycle', offDuration / 1000);
setOutput(false, false);
timer = Timer.set(offDuration, false, timedCycle, duration);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment