matterbridge-daikin-ac
Version:
Daikin AC Matterbridge plugin
125 lines • 7.24 kB
JavaScript
import { createHash } from 'node:crypto';
import { airConditioner, bridgedNode, MatterbridgeEndpoint, powerSource } from 'matterbridge';
import { OnOff, TemperatureMeasurement, Thermostat } from 'matterbridge/matter/clusters';
import { DaikinAcDevice } from './DaikinAcDevice.js';
import { DaikinAcMode } from './models/DaikinAcMode.js';
class DaikinMatterDevice {
ip;
options;
platform;
daikinDevice;
Endpoint;
constructor(platform, ip, options = {}) {
this.ip = ip;
this.options = options;
this.platform = platform;
this.daikinDevice = new DaikinAcDevice(this.platform, this.ip, this.options);
}
async connect() {
await this.daikinDevice.connect();
this.daikinDevice.startUpdates((power) => {
this.Endpoint.setAttribute(OnOff.Cluster.id, 'onOff', power, this.Endpoint.log);
}, (power, mode) => {
const matterMode = this.mapDaikinModeToMatter(power, mode);
this.Endpoint.setAttribute(Thermostat.Cluster.id, 'systemMode', matterMode, this.Endpoint.log);
}, (indoorTemp) => {
this.Endpoint.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', indoorTemp * 100, this.Endpoint.log);
this.Endpoint.setAttribute(Thermostat.Cluster.id, 'localTemperature', indoorTemp * 100, this.Endpoint.log);
}, (targetTemp) => {
this.Endpoint.setAttribute(Thermostat.Cluster.id, 'occupiedCoolingSetpoint', targetTemp * 100, this.Endpoint.log);
this.Endpoint.setAttribute(Thermostat.Cluster.id, 'occupiedHeatingSetpoint', targetTemp * 100, this.Endpoint.log);
});
}
async createEndpoint() {
const uniqueStorageKey = `daikin-ac-${this.daikinDevice.name}`;
const hash = createHash('sha256').update(uniqueStorageKey).digest('hex');
const serial = hash.substring(0, 16);
this.Endpoint = new MatterbridgeEndpoint([airConditioner, bridgedNode, powerSource], { uniqueStorageKey: uniqueStorageKey }, this.platform.config.debug)
.createDefaultIdentifyClusterServer()
.createDefaultBridgedDeviceBasicInformationClusterServer(`AC ${this.daikinDevice.name}`, serial, 0xfff1, 'Matterbridge', `Matterbridge Daikin AC`, parseInt(this.platform.version.replace(/\D/g, '')), this.platform.version === '' ? 'Unknown' : this.platform.version, parseInt(this.platform.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.platform.matterbridge.matterbridgeVersion);
this.Endpoint.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
this.platform.log.info(`Command identify called identifyTime: ${identifyTime}`);
});
if (!this.daikinDevice.currentState) {
throw new Error('Daikin AC device is connected but current state is undefined');
}
const targetTemp = this.daikinDevice.currentState.targetTemperature === 'M' ? 24 : (this.daikinDevice.currentState.targetTemperature ?? 24); // Default to 24 if not set
const currentTemp = this.daikinDevice.currentState.indoorTemperature ?? 24;
this.Endpoint.createDefaultGroupsClusterServer()
.createDeadFrontOnOffClusterServer(this.daikinDevice.currentState.power)
.createDefaultThermostatClusterServer(this.daikinDevice.currentState.indoorTemperature, targetTemp, targetTemp)
.createDefaultThermostatUserInterfaceConfigurationClusterServer()
.createDefaultTemperatureMeasurementClusterServer(currentTemp * 100);
this.Endpoint.addCommandHandler('on', () => {
this.daikinDevice.switchOn();
});
this.Endpoint.addCommandHandler('off', () => {
this.daikinDevice.switchOff();
});
this.Endpoint.subscribeAttribute(Thermostat.Cluster.id, 'occupiedCoolingSetpoint', (newValue) => {
this.daikinDevice.setTargetTemperature(newValue / 100);
}, this.Endpoint.log);
this.Endpoint.subscribeAttribute(Thermostat.Cluster.id, 'occupiedHeatingSetpoint', (newValue) => {
this.daikinDevice.setTargetTemperature(newValue / 100);
}, this.Endpoint.log);
this.Endpoint.subscribeAttribute(Thermostat.Cluster.id, 'systemMode', (newValue) => {
this.daikinDevice.setMode(this.mapMatterModeToDaikin(newValue));
}, this.Endpoint.log);
}
async registerWithPlatform() {
this.platform.setSelectDevice(this.Endpoint.serialNumber ?? '', this.Endpoint.deviceName ?? '', undefined, 'hub');
if (this.platform.validateDevice(this.Endpoint.deviceName ?? '')) {
await this.platform.registerDevice(this.Endpoint);
}
}
async restoreState() {
const targetTemp = this.daikinDevice.currentState?.targetTemperature === 'M' ? 24 : (this.daikinDevice.currentState?.targetTemperature ?? 24); // Default to 24 if not set
const currentTemp = this.daikinDevice.currentState?.indoorTemperature ?? 24;
const power = this.daikinDevice.currentState?.power ?? false;
const mode = this.mapDaikinModeToMatter(power, this.daikinDevice.currentState?.mode);
await this.Endpoint.setAttribute(OnOff.Cluster.id, 'onOff', power, this.Endpoint.log);
await this.Endpoint.setAttribute(Thermostat.Cluster.id, 'occupiedCoolingSetpoint', targetTemp * 100, this.Endpoint.log);
await this.Endpoint.setAttribute(Thermostat.Cluster.id, 'occupiedHeatingSetpoint', targetTemp * 100, this.Endpoint.log);
await this.Endpoint.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', currentTemp * 100, this.Endpoint.log);
await this.Endpoint.setAttribute(Thermostat.Cluster.id, 'localTemperature', currentTemp * 100, this.Endpoint.log);
await this.Endpoint.setAttribute(Thermostat.Cluster.id, 'systemMode', mode, this.Endpoint.log);
}
mapDaikinModeToMatter(power, mode) {
if (!power || mode === undefined) {
return Thermostat.SystemMode.Off;
}
switch (mode) {
case 2:
return Thermostat.SystemMode.Dry;
case 3:
return Thermostat.SystemMode.Cool;
case 4:
return Thermostat.SystemMode.Heat;
case 6:
return Thermostat.SystemMode.FanOnly;
case 7:
return Thermostat.SystemMode.Auto;
default:
return Thermostat.SystemMode.Off; // Default to off if mode is unknown
}
}
mapMatterModeToDaikin(mode) {
switch (mode) {
case Thermostat.SystemMode.Cool:
return DaikinAcMode.Cool;
case Thermostat.SystemMode.Heat:
return DaikinAcMode.Heat;
case Thermostat.SystemMode.Auto:
return DaikinAcMode.Auto;
case Thermostat.SystemMode.Dry:
return DaikinAcMode.Dry;
case Thermostat.SystemMode.FanOnly:
return DaikinAcMode.FanOnly;
case Thermostat.SystemMode.Off:
default:
return DaikinAcMode.Off; // Default to off if mode is unknown
}
}
}
export { DaikinMatterDevice };
//# sourceMappingURL=DaikinMatterDevice.js.map