Skip to content

Instantly share code, notes, and snippets.

@monosoul
Last active April 2, 2026 03:53
Show Gist options
  • Select an option

  • Save monosoul/b2e07598d96eee3eaf9c07fb00576cbd to your computer and use it in GitHub Desktop.

Select an option

Save monosoul/b2e07598d96eee3eaf9c07fb00576cbd to your computer and use it in GitHub Desktop.
Schneider Electric MEG5779 converter for Zigbee2MQTT
import {thermostat, deviceAddCustomCluster, numeric, enumLookup} from 'zigbee-herdsman-converters/lib/modernExtend';
import {access} from 'zigbee-herdsman-converters/lib/exposes';
// ZCL constants (hardcoded to avoid CJS/ESM interop issues with zigbee-herdsman)
const SCHNEIDER_ELECTRIC = 0x105e;
const UINT8 = 0x20;
const UINT16 = 0x21;
const ENUM8 = 0x30;
const HVAC_USER_INTERFACE_CFG_ID = 0x0204;
const HVAC_THERMOSTAT_ID = 0x0201;
const manufacturerOptions = {manufacturerCode: SCHNEIDER_ELECTRIC};
export default {
zigbeeModel: ['MEG5779'],
model: 'MEG5779',
vendor: 'Schneider Electric',
description: 'Merten Connected Room Temperature Controller',
fromZigbee: [
{
cluster: 'hvacThermostat',
type: ['attributeReport', 'readResponse'],
convert: (model, msg, publish, options, meta) => {
if (msg.data.pIHeatingDemand !== undefined) {
return {running_state: msg.data.pIHeatingDemand > 0 ? 'heat' : 'idle'};
}
},
},
],
extend: [
// Same as built-in, but without cooling setpoints/mode
thermostat({
setpoints: {
values: {
occupiedHeatingSetpoint: {min: 4, max: 40, step: 0.5},
unoccupiedHeatingSetpoint: {min: 4, max: 40, step: 0.5},
},
},
setpointsLimit: {
maxHeatSetpointLimit: {min: 4, max: 40, step: 0.5},
minHeatSetpointLimit: {min: 4, max: 40, step: 0.5},
},
systemMode: {
values: ['off', 'heat'],
},
runningState: {
values: ['idle', 'heat'],
configure: {reporting: false},
},
piHeatingDemand: {
values: access.ALL,
},
}),
// --- From built-in: display brightness/timeout ---
deviceAddCustomCluster('hvacUserInterfaceCfg', {
ID: HVAC_USER_INTERFACE_CFG_ID,
name: 'hvacUserInterfaceCfg',
attributes: {
displayBrightnessActive: {ID: 0xe000, type: UINT8, write: true, min: 0, max: 100, manufacturerCode: SCHNEIDER_ELECTRIC},
displayBrightnessInactive: {ID: 0xe001, type: UINT8, write: true, min: 0, max: 100, manufacturerCode: SCHNEIDER_ELECTRIC},
displayActiveTimeout: {ID: 0xe002, type: UINT16, write: true, min: 5, max: 600, manufacturerCode: SCHNEIDER_ELECTRIC},
},
commands: {},
commandsResponse: {},
}),
numeric({
name: 'display_brightness_active',
cluster: 'hvacUserInterfaceCfg',
attribute: 'displayBrightnessActive',
description: 'Sets brightness of the temperature display during active state',
entityCategory: 'config',
unit: '%',
valueMin: 0,
valueMax: 100,
valueStep: 1,
zigbeeCommandOptions: manufacturerOptions,
}),
numeric({
name: 'display_brightness_inactive',
cluster: 'hvacUserInterfaceCfg',
attribute: 'displayBrightnessInactive',
description: 'Sets brightness of the temperature display during inactive state',
entityCategory: 'config',
unit: '%',
valueMin: 0,
valueMax: 100,
valueStep: 1,
zigbeeCommandOptions: manufacturerOptions,
}),
numeric({
name: 'display_active_timeout',
cluster: 'hvacUserInterfaceCfg',
attribute: 'displayActiveTimeout',
description: 'Sets timeout of the temperature display active state',
entityCategory: 'config',
unit: 'seconds',
valueMin: 5,
valueMax: 600,
valueStep: 5,
zigbeeCommandOptions: manufacturerOptions,
}),
// --- From built-in: UI config ---
enumLookup({
name: 'temperature_display_mode',
lookup: {celsius: 0, fahrenheit: 1},
cluster: 'hvacUserInterfaceCfg',
attribute: 'tempDisplayMode',
description: 'The unit of the temperature displayed on the device screen.',
}),
enumLookup({
name: 'keypad_lockout',
lookup: {unlock: 0, lock1: 1},
cluster: 'hvacUserInterfaceCfg',
attribute: 'keypadLockout',
description: 'Enables/disables physical input on the device.',
}),
// --- Your additions: advanced thermostat config ---
deviceAddCustomCluster('hvacThermostat', {
ID: HVAC_THERMOSTAT_ID,
name: 'hvacThermostat',
attributes: {
thermostatApplication: {ID: 0xe216, type: ENUM8, write: true, manufacturerCode: SCHNEIDER_ELECTRIC},
heatingFuel: {ID: 0xe217, type: ENUM8, write: true, manufacturerCode: SCHNEIDER_ELECTRIC},
heatTransferMedium: {ID: 0xe218, type: ENUM8, write: true, manufacturerCode: SCHNEIDER_ELECTRIC},
heatingEmitterType: {ID: 0xe21a, type: ENUM8, write: true, manufacturerCode: SCHNEIDER_ELECTRIC},
},
commands: {},
commandsResponse: {},
}),
enumLookup({
name: 'thermostat_application',
cluster: 'hvacThermostat',
attribute: 'thermostatApplication',
description: 'Type of space being heated',
lookup: {occupied_space: 0x00, floor: 0x01, not_known: 0xff},
entityCategory: 'config',
zigbeeCommandOptions: manufacturerOptions,
}),
enumLookup({
name: 'heating_fuel',
cluster: 'hvacThermostat',
attribute: 'heatingFuel',
description: 'Type of fuel used for heating',
lookup: {
electricity: 0x00, gas: 0x01, oil: 0x02, solid_fuel: 0x03,
solar: 0x04, community_heating: 0x05, heat_pump: 0x06, not_specified: 0xff,
},
entityCategory: 'config',
zigbeeCommandOptions: manufacturerOptions,
}),
enumLookup({
name: 'heat_transfer_medium',
cluster: 'hvacThermostat',
attribute: 'heatTransferMedium',
description: 'Medium used to transfer heat',
lookup: {nothing: 0x00, hydronic: 0x01, air: 0x02},
entityCategory: 'config',
zigbeeCommandOptions: manufacturerOptions,
}),
enumLookup({
name: 'heating_emitter_type',
cluster: 'hvacThermostat',
attribute: 'heatingEmitterType',
description: 'Type of heating emitter',
lookup: {
direct: 0x00, radiator: 0x01, fan_assisted_radiator: 0x02,
radiant_panel: 0x03, floor: 0x04, not_specified: 0xff,
},
entityCategory: 'config',
zigbeeCommandOptions: manufacturerOptions,
}),
],
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment