Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ctm.ts, Add support for CTM Lyng DimmerPille & CTM Lyng MBD Dim #7266

Merged
merged 2 commits into from
Mar 27, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
112 changes: 112 additions & 0 deletions src/devices/ctm.ts
Expand Up @@ -6,6 +6,7 @@ import {KeyValue, Definition, Tz, Fz} from '../lib/types';
import * as reporting from '../lib/reporting';
import * as constants from '../lib/constants';
import * as utils from '../lib/utils';
import * as ota from '../lib/ota';
const e = exposes.presets;
const ea = exposes.access;

Expand Down Expand Up @@ -344,6 +345,16 @@ const tzLocal = {
await entity.read('genOnOff', ['onOff']);
},
} satisfies Tz.Converter,
ctm_mbd_brightness: {
key: ['brightness'],
convertSet: async (entity, key, value, meta) => {
await entity.command(
'genLevelCtrl', 'moveToLevel', {level: value, transtime: 1}, utils.getOptions(meta.mapped, entity));
},
convertGet: async (entity, key, meta) => {
await entity.read('genLevelCtrl', ['currentLevel']);
},
} satisfies Tz.Converter,
ctm_device_mode: {
key: ['device_mode'],
convertGet: async (entity, key, meta) => {
Expand Down Expand Up @@ -637,6 +648,48 @@ const definitions: Definition[] = [
fromZigbee: [fz.on_off, fz.brightness, fz.lighting_ballast_configuration],
toZigbee: [tz.on_off, tz.light_onoff_brightness, tz.light_brightness_move, tz.ballast_config],
meta: {disableDefaultResponse: true},
ota: ota.zigbeeOTA,
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingBallastCfg']);
await endpoint.read('genOnOff', ['onOff']);
await reporting.onOff(endpoint);
await endpoint.read('genLevelCtrl', ['currentLevel']);
await reporting.brightness(endpoint);
await endpoint.read('lightingBallastCfg', ['minLevel', 'maxLevel', 'powerOnLevel']);
await endpoint.configureReporting('lightingBallastCfg', [{
attribute: 'minLevel',
minimumReportInterval: 0,
maximumReportInterval: constants.repInterval.HOUR,
reportableChange: null}]);
await endpoint.configureReporting('lightingBallastCfg', [{
attribute: 'maxLevel',
minimumReportInterval: 0,
maximumReportInterval: constants.repInterval.HOUR,
reportableChange: null}]);
await endpoint.configureReporting('lightingBallastCfg', [{
attribute: 'powerOnLevel',
minimumReportInterval: 0,
maximumReportInterval: constants.repInterval.HOUR,
reportableChange: null}]);
},
exposes: [e.light_brightness(),
e.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(99)
.withDescription('Specifies the minimum brightness value'),
e.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(99)
.withDescription('Specifies the maximum brightness value'),
e.numeric('ballast_power_on_level', ea.ALL).withValueMin(1).withValueMax(99)
.withDescription('Specifies the initialisation light level. Can not be set lower than "ballast_minimum_level"')],
},
{
zigbeeModel: ['DimmerPille'],
model: 'CTM_DimmerPille',
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks the code of this device exactly the same as mTouch_Dim, can you add it as a whitelabel instead? Example:

{vendor: 'Bosch', model: 'BSP-EZ2', description: 'Plug compact FR', fingerprint: [{modelID: 'RBSH-SP-ZB-FR'}]},

vendor: 'CTM Lyng',
description: 'CTM Lyng DimmerPille',
fromZigbee: [fz.on_off, fz.brightness, fz.lighting_ballast_configuration],
toZigbee: [tz.on_off, tz.light_onoff_brightness, tz.light_brightness_move, tz.ballast_config],
meta: {disableDefaultResponse: true},
ota: ota.zigbeeOTA,
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingBallastCfg']);
Expand Down Expand Up @@ -700,6 +753,7 @@ const definitions: Definition[] = [
fromZigbee: [fz.thermostat, fzLocal.ctm_thermostat],
toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature, tzLocal.ctm_thermostat,
tzLocal.ctm_thermostat_preset, tzLocal.ctm_thermostat_child_lock, tzLocal.ctm_thermostat_gets],
ota: ota.zigbeeOTA,
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['hvacThermostat']);
Expand Down Expand Up @@ -802,6 +856,7 @@ const definitions: Definition[] = [
description: 'mStikk OP, wall socket',
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
toZigbee: [tz.on_off],
ota: ota.zigbeeOTA,
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
Expand Down Expand Up @@ -997,6 +1052,7 @@ const definitions: Definition[] = [
fromZigbee: [fz.illuminance, fz.occupancy, fzLocal.ctm_mbd_device_enabled, fzLocal.ctm_relay_state],
toZigbee: [tzLocal.ctm_mbd_device_enabled, tzLocal.ctm_relay_state],
meta: {disableDefaultResponse: true},
ota: ota.zigbeeOTA,
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'msIlluminanceMeasurement', 'msOccupancySensing']);
Expand All @@ -1019,6 +1075,62 @@ const definitions: Definition[] = [
.withDescription('Turn the device on or off'),
],
},
{
zigbeeModel: ['MBD Dim'],
model: 'CTM_MBD_Dim',
vendor: 'CTM Lyng',
description: 'MBD Dim, motion detector with dimmer',
fromZigbee: [fz.illuminance, fz.occupancy, fzLocal.ctm_mbd_device_enabled, fzLocal.ctm_relay_state,
fz.brightness, fz.lighting_ballast_configuration],
toZigbee: [tzLocal.ctm_mbd_device_enabled, tzLocal.ctm_relay_state, tzLocal.ctm_mbd_brightness, tz.ballast_config],
meta: {disableDefaultResponse: true},
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingBallastCfg',
'msIlluminanceMeasurement', 'msOccupancySensing']);
await endpoint.read('genOnOff', ['onOff']);
await reporting.onOff(endpoint);
await endpoint.read('genLevelCtrl', ['currentLevel']);
await reporting.brightness(endpoint);
await endpoint.read('lightingBallastCfg', ['minLevel', 'maxLevel', 'powerOnLevel']);
await endpoint.configureReporting('lightingBallastCfg', [{
attribute: 'minLevel',
minimumReportInterval: 0,
maximumReportInterval: constants.repInterval.HOUR,
reportableChange: null}]);
await endpoint.configureReporting('lightingBallastCfg', [{
attribute: 'maxLevel',
minimumReportInterval: 0,
maximumReportInterval: constants.repInterval.HOUR,
reportableChange: null}]);
await endpoint.configureReporting('lightingBallastCfg', [{
attribute: 'powerOnLevel',
minimumReportInterval: 0,
maximumReportInterval: constants.repInterval.HOUR,
reportableChange: null}]);
await endpoint.read('msIlluminanceMeasurement', ['measuredValue']);
await reporting.illuminance(endpoint);
await endpoint.read('msOccupancySensing', ['occupancy']);
await reporting.occupancy(endpoint);
// Relay State
await endpoint.read('genOnOff', [0x5001], {manufacturerCode: Zcl.ManufacturerCode.DATEK_WIRELESS_AS});
await endpoint.configureReporting('genOnOff', [{
attribute: {ID: 0x5001, type: dataType.boolean},
minimumReportInterval: 1,
maximumReportInterval: constants.repInterval.HOUR,
reportableChange: 0}], {manufacturerCode: Zcl.ManufacturerCode.DATEK_WIRELESS_AS});
},
exposes: [e.light_brightness(), e.illuminance(), e.illuminance_lux(), e.occupancy(),
e.binary('device_enabled', ea.ALL, 'ON', 'OFF')
.withDescription('Turn the device on or off'),
e.numeric('ballast_minimum_level', ea.ALL).withValueMin(10).withValueMax(97)
.withDescription('Specifies the minimum brightness value'),
e.numeric('ballast_maximum_level', ea.ALL).withValueMin(10).withValueMax(97)
.withDescription('Specifies the maximum brightness value'),
e.numeric('ballast_power_on_level', ea.ALL).withValueMin(10).withValueMax(97)
.withDescription('Specifies the initialisation light level. Can not be set lower than "ballast_minimum_level"'),
],
},
];

export default definitions;
Expand Down