Skip to content

Commit

Permalink
Updated configuration parameter checking (default device handling)
Browse files Browse the repository at this point in the history
  • Loading branch information
eibenp committed Dec 28, 2024
1 parent b7fb769 commit 42411b6
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 28 deletions.
4 changes: 2 additions & 2 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@
"key": "devices[].mac",
"flex": "1 1 50%",
"title": "MAC address (Serial Number):",
"description": "MAC address of the device using lowercase letters and no separators or special value: default"
"description": "MAC address of the device using lowercase letters and no separators<br />OR<br />special value: <b>default</b>"
},
{
"key": "devices[].name",
Expand Down Expand Up @@ -370,7 +370,7 @@
"key": "devices[].temperatureStepSize",
"flex": "1 1 50%",
"title": "Temperature step size:",
"description": "Valid values: 0.5 (for °F) and 1 (for °C)<BR />(0.5 if empty or invalid)",
"description": "Valid values: 0.5 (for °F) and 1 (for °C)<BR />(Calculate from Homebridge UI temperature units parameter if empty or invalid)",
"condition": {
"functionBody": "return (model.devices && model.devices[arrayIndices] && model.devices[arrayIndices].mac && /^[a-f0-9]{12}|default$/.test(model.devices[arrayIndices].mac) && model.devices[arrayIndices].disabled !== true);"
}
Expand Down
84 changes: 60 additions & 24 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,14 @@ export class GreeACPlatform implements DynamicPlatformPlugin {
this.log.debug('registerDevice - deviceInfo:', JSON.stringify(deviceInfo));
const devcfg = this.config.devices?.find((item) => item.mac === deviceInfo.mac) || {};
const deviceConfig = {
// parameters read from config
...devcfg,
// fix incorrect values read from config but do not add any value if parameter is missing
...((devcfg.speedSteps && devcfg.speedSteps !== 3 && devcfg.speedSteps !== 5) || devcfg.speedSteps === 0 ?
{speedSteps: 5} : {}),
...((devcfg.temperatureSensor && Object.values(TS_TYPE).includes((devcfg.temperatureSensor as string).toLowerCase())) ?
{temperatureSensor: (devcfg.temperatureSensor as string).toLowerCase()} : {temperatureSensor: TS_TYPE.disabled}),
{speedSteps: DEFAULT_DEVICE_CONFIG.speedSteps} : {}),
...(devcfg.temperatureSensor && Object.values(TS_TYPE).includes((devcfg.temperatureSensor as string).toLowerCase()) ?
{temperatureSensor: (devcfg.temperatureSensor as string).toLowerCase()}
: (devcfg.temperatureSensor ? {temperatureSensor: DEFAULT_DEVICE_CONFIG.temperatureSensor} : {})),
...(devcfg.minimumTargetTemperature &&
(devcfg.minimumTargetTemperature < Math.min(TEMPERATURE_LIMITS.coolingMinimum, TEMPERATURE_LIMITS.heatingMinimum) ||
devcfg.minimumTargetTemperature > Math.max(TEMPERATURE_LIMITS.coolingMaximum, TEMPERATURE_LIMITS.heatingMaximum)) ?
Expand All @@ -197,24 +200,23 @@ export class GreeACPlatform implements DynamicPlatformPlugin {
(devcfg.maximumTargetTemperature < Math.min(TEMPERATURE_LIMITS.coolingMinimum, TEMPERATURE_LIMITS.heatingMinimum) ||
devcfg.maximumTargetTemperature > Math.max(TEMPERATURE_LIMITS.coolingMaximum, TEMPERATURE_LIMITS.heatingMaximum)) ?
{ maximumTargetTemperature: DEFAULT_DEVICE_CONFIG.maximumTargetTemperature } : {}),
...((devcfg.defaultVerticalSwing && ![commands.swingVertical.value.default, commands.swingVertical.value.fixedHighest,
...(devcfg.defaultVerticalSwing && ![commands.swingVertical.value.default, commands.swingVertical.value.fixedHighest,
commands.swingVertical.value.fixedHigher, commands.swingVertical.value.fixedMiddle, commands.swingVertical.value.fixedLower,
commands.swingVertical.value.fixedLowest].includes(devcfg.defaultVerticalSwing)) ?
commands.swingVertical.value.fixedLowest].includes(devcfg.defaultVerticalSwing) ?
{ defaultVerticalSwing: DEFAULT_DEVICE_CONFIG.defaultVerticalSwing } : {}),
...((devcfg.overrideDefaultVerticalSwing && !Object.values(OVERRIDE_DEFAULT_SWING).includes(devcfg.overrideDefaultVerticalSwing)) ?
...(devcfg.overrideDefaultVerticalSwing && !Object.values(OVERRIDE_DEFAULT_SWING).includes(devcfg.overrideDefaultVerticalSwing) ?
{ overrideDefaultVerticalSwing: DEFAULT_DEVICE_CONFIG.overrideDefaultVerticalSwing } : {}),
...((devcfg.encryptionVersion && !Object.values(ENCRYPTION_VERSION).includes(devcfg.encryptionVersion)) ?
...(devcfg.encryptionVersion && !Object.values(ENCRYPTION_VERSION).includes(devcfg.encryptionVersion) ?
{ encryptionVersion: DEFAULT_DEVICE_CONFIG.encryptionVersion } : {}),
};
if (deviceConfig.minimumTargetTemperature && deviceConfig.maximumTargetTemperature &&
deviceConfig.minimumTargetTemperature > deviceConfig.maximumTargetTemperature) {
deviceConfig.minimumTargetTemperature =
Math.min(DEFAULT_DEVICE_CONFIG.minimumTargetTemperature, DEFAULT_DEVICE_CONFIG.maximumTargetTemperature);
deviceConfig.maximumTargetTemperature =
Math.max(DEFAULT_DEVICE_CONFIG.minimumTargetTemperature, DEFAULT_DEVICE_CONFIG.maximumTargetTemperature);
this.log.warn('Warning: Invalid minimum and maximum target temperature values detected ->',
`Accessory ${deviceInfo.mac} is using default values instead of the configured ones`);
}
// assign customized default to missing parameters
Object.entries(this.config.devices?.find((item) => item.mac?.toLowerCase() === 'default' && !item.disabled) || {})
.forEach(([key, value]) => {
if (!['mac', 'name', 'ip', 'port', 'disabled'].includes(key) && deviceConfig[key] === undefined) {
deviceConfig[key] = value;
}
});
// try to assign temperatureStepSize from Homebridge UI if missing in configuration
if (deviceConfig.temperatureStepSize === undefined && this.tempUnit === 'c') {
deviceConfig.temperatureStepSize = TEMPERATURE_STEPS.celsius;
}
Expand All @@ -226,19 +228,52 @@ export class GreeACPlatform implements DynamicPlatformPlugin {
`Accessory ${deviceInfo.mac} is using default value (0.5) instead of the configured one`);
delete deviceConfig.temperatureStepSize;
}
// assign customized default to missing parameters
Object.entries(this.config.devices?.find((item) => item.mac?.toLowerCase() === 'default' && !item.disabled) || {})
.forEach(([key, value]) => {
if (!['mac', 'name', 'ip', 'port'].includes(key) && deviceConfig[key] === undefined) {
deviceConfig[key] = value;
}
});
// assign plugin default to missing parameters
Object.entries(DEFAULT_DEVICE_CONFIG).forEach(([key, value]) => {
if (deviceConfig[key] === undefined) {
deviceConfig[key] = value;
}
});
// check parameters and fix incorrect values (some of them are repeated checks because default device may also be incorrect)
if ((deviceConfig.speedSteps && deviceConfig.speedSteps !== 3 && deviceConfig.speedSteps !== 5) || deviceConfig.speedSteps === 0) {
deviceConfig.speedSteps = DEFAULT_DEVICE_CONFIG.speedSteps;
}
if (deviceConfig.temperatureSensor && Object.values(TS_TYPE).includes((deviceConfig.temperatureSensor as string).toLowerCase())) {
deviceConfig.temperatureSensor = (deviceConfig.temperatureSensor as string).toLowerCase();
} else {
deviceConfig.temperatureSensor = DEFAULT_DEVICE_CONFIG.temperatureSensor;
}
if (deviceConfig.minimumTargetTemperature &&
(deviceConfig.minimumTargetTemperature < Math.min(TEMPERATURE_LIMITS.coolingMinimum, TEMPERATURE_LIMITS.heatingMinimum) ||
deviceConfig.minimumTargetTemperature > Math.max(TEMPERATURE_LIMITS.coolingMaximum, TEMPERATURE_LIMITS.heatingMaximum))) {
deviceConfig.minimumTargetTemperature = DEFAULT_DEVICE_CONFIG.minimumTargetTemperature;
}
if (deviceConfig.maximumTargetTemperature &&
(deviceConfig.maximumTargetTemperature < Math.min(TEMPERATURE_LIMITS.coolingMinimum, TEMPERATURE_LIMITS.heatingMinimum) ||
deviceConfig.maximumTargetTemperature > Math.max(TEMPERATURE_LIMITS.coolingMaximum, TEMPERATURE_LIMITS.heatingMaximum))) {
deviceConfig.maximumTargetTemperature = DEFAULT_DEVICE_CONFIG.maximumTargetTemperature;
}
if (deviceConfig.minimumTargetTemperature && deviceConfig.maximumTargetTemperature &&
deviceConfig.minimumTargetTemperature > deviceConfig.maximumTargetTemperature) {
deviceConfig.minimumTargetTemperature =
Math.min(DEFAULT_DEVICE_CONFIG.minimumTargetTemperature, DEFAULT_DEVICE_CONFIG.maximumTargetTemperature);
deviceConfig.maximumTargetTemperature =
Math.max(DEFAULT_DEVICE_CONFIG.minimumTargetTemperature, DEFAULT_DEVICE_CONFIG.maximumTargetTemperature);
this.log.warn('Warning: Invalid minimum and maximum target temperature values detected ->',
`Accessory ${deviceInfo.mac} is using default values instead of the configured ones`);
}
if (deviceConfig.defaultVerticalSwing && ![commands.swingVertical.value.default, commands.swingVertical.value.fixedHighest,
commands.swingVertical.value.fixedHigher, commands.swingVertical.value.fixedMiddle, commands.swingVertical.value.fixedLower,
commands.swingVertical.value.fixedLowest].includes(deviceConfig.defaultVerticalSwing)) {
deviceConfig.defaultVerticalSwing = DEFAULT_DEVICE_CONFIG.defaultVerticalSwing;
}
if (deviceConfig.overrideDefaultVerticalSwing &&
!Object.values(OVERRIDE_DEFAULT_SWING).includes(deviceConfig.overrideDefaultVerticalSwing)) {
deviceConfig.overrideDefaultVerticalSwing = DEFAULT_DEVICE_CONFIG.overrideDefaultVerticalSwing;
}
if (deviceConfig.encryptionVersion && !Object.values(ENCRYPTION_VERSION).includes(deviceConfig.encryptionVersion)) {
deviceConfig.encryptionVersion = DEFAULT_DEVICE_CONFIG.encryptionVersion;
}
if (deviceConfig.port !== undefined && (typeof deviceConfig.port !== 'number' || deviceConfig.port !== deviceConfig.port ||
(typeof deviceConfig.port === 'number' && (deviceConfig.port < 1025 || deviceConfig.port > 65535)))) {
this.log.warn('Warning: Port is misconfigured (Valid port values: 1025~65535 or leave port empty to auto select) - ' +
Expand All @@ -250,6 +285,7 @@ export class GreeACPlatform implements DynamicPlatformPlugin {
deviceInfo.encryptionVersion = deviceConfig.encryptionVersion;
this.log.debug(`Accessory ${deviceInfo.mac} encryption version forced:`, deviceInfo.encryptionVersion);
}

let accessory: MyPlatformAccessory | undefined = this.devices[deviceInfo.mac];
let accessory_ts: MyPlatformAccessory | undefined = this.devices[deviceInfo.mac + '_ts'];

Expand Down Expand Up @@ -306,7 +342,7 @@ export class GreeACPlatform implements DynamicPlatformPlugin {
}

// create temperaturesensor accessory if configured as separate and not loaded from cache
const tsDeviceName = 'Temperature Sensor - ' + (deviceConfig?.name ?? (deviceInfo.name || deviceInfo.mac));
const tsDeviceName = 'Temperature Sensor ' + (deviceConfig?.name ?? (deviceInfo.name || deviceInfo.mac));
if (!accessory_ts && deviceConfig.temperatureSensor === TS_TYPE.separate) {
this.log.debug(`Creating new accessory ${deviceInfo.mac}_ts with name ${tsDeviceName} ...`);
const uuid = this.api.hap.uuid.generate(deviceInfo.mac + '_ts');
Expand Down
4 changes: 2 additions & 2 deletions src/platformAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ export class GreeAirConditioner {
if (this.deviceConfig.temperatureSensor === TS_TYPE.child) {
this.platform.log.debug(`[${this.getDeviceLabel()}] Add Temperature Sensor child service`);
this.TemperatureSensor = this.accessory.getService(this.platform.Service.TemperatureSensor) ||
this.accessory.addService(this.platform.Service.TemperatureSensor, 'Temperature Sensor - ' + this.accessory.displayName, undefined);
this.TemperatureSensor.displayName = 'Temperature Sensor - ' + this.accessory.displayName;
this.accessory.addService(this.platform.Service.TemperatureSensor, 'Temperature Sensor ' + this.accessory.displayName, undefined);
this.TemperatureSensor.displayName = 'Temperature Sensor ' + this.accessory.displayName;
} else {
const ts = this.accessory.getService(this.platform.Service.TemperatureSensor);
this.platform.log.debug(`[${this.getDeviceLabel()}] Temperature Sensor child service not allowed`,
Expand Down

0 comments on commit 42411b6

Please sign in to comment.