Skip to content

Commit

Permalink
Fix supporting comfort mode & eco mode
Browse files Browse the repository at this point in the history
  • Loading branch information
bimusiek committed Apr 8, 2024
1 parent b8fb03b commit e371ff5
Show file tree
Hide file tree
Showing 8 changed files with 413 additions and 105 deletions.
7 changes: 7 additions & 0 deletions src/accessories/thermostatAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,13 @@ export class ThermostatAccessory extends Accessory<DeviceContext> {
});
return targetTempSet;
}
if(targetTempMin === undefined || temperatureNow === undefined || targetTempMax === undefined || targetTempSet === undefined) {
this.platform.log.error(
`updateTargetTemperaturePropsAndReturnCurrentTemp got wrong readings:
${JSON.stringify({ targetTempMin, targetTempMax, targetTempSet, temperatureNow })}
`);
return 100; // fake big value to indicate the issue in homekit
}
const tempMin = Math.floor(targetTempMin) + Math.floor(temperatureNow);
const tempMax = Math.ceil(targetTempMax) + Math.ceil(temperatureNow);
const tempCurrent = Math.round(targetTempSet + temperatureNow);
Expand Down
3 changes: 3 additions & 0 deletions src/api/panasonicApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ export class PanasonicApi {
validateStatus: () => true,
});

if(response3.status !== 200) {
throw new Error(`Wrong response for usernamepassword/login: ${response3.status}. Most probably wrong credentials.`);
}
const actionUrl = response3.data.match(/action="(.+?)"/i)?.[1];
const inputs = response3.data.match(/<input([^\0]+?)>/ig) ?? [];
const formData:Record<string, string> = {};
Expand Down
107 changes: 2 additions & 105 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PLATFORM_NAME, PLUGIN_NAME } from './settings';
import { PanasonicApi } from './api/panasonicApi';
import { AccessoryType, accessoryTypeClases, DeviceContext, DeviceDetails } from './types';
import { Accessory } from './accessories/accessory';
import { parsePanasonicDetails } from './utils/parsePanasonicDetails';

export class PanasonicHeatPumpHomebridgePlatform implements DynamicPlatformPlugin {
public readonly Service: typeof Service = this.api.hap.Service;
Expand Down Expand Up @@ -148,111 +149,7 @@ export class PanasonicHeatPumpHomebridgePlatform implements DynamicPlatformPlugi
return;
}
const details = await this.panasonicApi.loadDeviceDetails(deviceId);

const operationalZone = details.zoneStatus.find(z => z.temparatureNow !== null);
const temperatureNow = operationalZone?.temparatureNow;

const isActive = details.operationStatus === 1;
const direction = details.direction;
const isWholeHeaterOff = details.operationStatus === 0 || operationalZone.operationStatus === 0;

// What is currently being heated (so if both water tank and heater are on, what is currently being provided with heat)
const isHeatingOn = direction === 1;
const isTankOn = direction === 2;

// if you need to return an error to show the device as "Not Responding" in the Home app:
// throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
const operationMode = details.operationMode;
const heatingCoolingState = (() => {
if(!isHeatingOn || isWholeHeaterOff) {
return this.Characteristic.CurrentHeatingCoolingState.OFF;
}
if(operationMode === 1) {
return this.Characteristic.CurrentHeatingCoolingState.HEAT;
}
if(operationMode === 2) {
return this.Characteristic.CurrentHeatingCoolingState.COOL;
}
if(operationMode === 3) {
// AUTO
return this.Characteristic.CurrentHeatingCoolingState.HEAT;
}
if(operationMode === 4) {
// AUTO
return this.Characteristic.CurrentHeatingCoolingState.COOL;
}
return this.Characteristic.CurrentHeatingCoolingState.OFF;
})();
const targetHeatingCoolingState = (() => {
if(details.operationStatus === 0 || operationalZone.operationStatus === 0) {
return this.Characteristic.TargetHeatingCoolingState.OFF;
}
switch (operationMode) {
case 1:
return this.Characteristic.TargetHeatingCoolingState.HEAT;
case 2:
return this.Characteristic.TargetHeatingCoolingState.COOL;
case 3:
case 4:
return this.Characteristic.TargetHeatingCoolingState.AUTO;
}
return this.Characteristic.TargetHeatingCoolingState.OFF;
})();
const ecoModeIsActive = details.specialStatus.find(s => s.specialMode === 1).operationStatus === 1;
const comfortModeIsActive = details.specialStatus.find(s => s.specialMode === 2).operationStatus === 1;
const outdoorTemperatureNow = details.outdoorNow;
const tankTemperatureNow = details.tankStatus[0].temparatureNow;
const tankTemperatureSet = details.tankStatus[0].heatSet;
const tankIsActive = details.tankStatus[0].operationStatus === 1;
const tankHeatingCoolingState = (() => {
if (!isTankOn || !isActive || !tankIsActive) {
return this.Characteristic.CurrentHeatingCoolingState.OFF;
}
return this.Characteristic.CurrentHeatingCoolingState.HEAT;
})();
const tankTargetHeatingCoolingState = (() => {
if (!tankIsActive || !isActive) {
return this.Characteristic.TargetHeatingCoolingState.OFF;
}
return this.Characteristic.TargetHeatingCoolingState.HEAT;
})();


const tempType: 'heat' | 'cool' | 'eco' | 'comfort' = (() => {
if(ecoModeIsActive) {
return 'eco';
}
if(comfortModeIsActive) {
return 'comfort';
}
if(operationMode === 1 || operationMode === 3) {

return 'heat';
}
if(operationMode === 2 || operationMode === 4) {
return 'cool';
}
return 'heat';
})();
return {
temperatureNow,
heatingCoolingState,
targetHeatingCoolingState,
outdoorTemperatureNow,
tankTemperatureNow,
tankTemperatureSet,
tankHeatingCoolingState,
tankTargetHeatingCoolingState,
isActive,
ecoModeIsActive,
comfortModeIsActive,
tankTemperatureMax: details.tankStatus[0].heatMax,
tankTemperatureMin: details.tankStatus[0].heatMin,
targetTempSet: operationalZone[`${tempType}Set`],
targetTempMin: operationalZone[`${tempType}Min`],
targetTempMax: operationalZone[`${tempType}Max`],
tempType,
};
return parsePanasonicDetails(details, this.Characteristic);
};
try {
const details = await loadReadings();
Expand Down
68 changes: 68 additions & 0 deletions src/utils/examplePanasonicData/example1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export const example1 = {
deiceStatus: 0,
operationStatus: 1,
modelSeriesSelection: 2,
multiOdConnection: 0,
specialStatus: [
{ specialMode: 1, operationStatus: 0 },
{ specialMode: 2, operationStatus: 0 },
],
waterPressure: '0.00',
cnCntErrorStatus: 0,
zoneStatus: [
{
operationStatus: 1,
ecoHeat: -5,
coolMin: -5,
heatMin: -5,
comfortCool: -5,
temparatureNow: 20,
coolSet: -1,
zoneId: 1,
comfortHeat: 5,
heatMax: 5,
coolMax: 5,
ecoCool: 5,
heatSet: -5,
},
{
operationStatus: 0,
ecoHeat: 0,
coolMin: null,
heatMin: null,
comfortCool: 0,
temparatureNow: null,
coolSet: 0,
zoneId: 2,
comfortHeat: 0,
heatMax: null,
coolMax: null,
ecoCool: 0,
heatSet: 0,
},
],
outdoorNow: 22,
operationMode: 1,
holidayTimer: 0,
powerful: 0,
electricAnode: null,
deviceGuid: '',
bivalent: 0,
tankStatus: [
{
operationStatus: 1,
temparatureNow: 50,
heatMax: 65,
heatMin: 40,
heatSet: 52,
},
],
informationMessage: 1,
pumpDuty: 0,
quietMode: 0,
forceHeater: 0,
tank: 1,
forceDHW: 0,
pendingUser: 0,
direction: 2,
};
69 changes: 69 additions & 0 deletions src/utils/examplePanasonicData/example2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// comfort mode
export const example2 = {
deiceStatus: 0,
operationStatus: 1,
modelSeriesSelection: 2,
multiOdConnection: 0,
specialStatus: [
{ specialMode: 1, operationStatus: 0 },
{ specialMode: 2, operationStatus: 1 },
],
waterPressure: '0.00',
cnCntErrorStatus: 0,
zoneStatus: [
{
operationStatus: 1,
ecoHeat: -5,
coolMin: -5,
heatMin: -5,
comfortCool: -5,
temparatureNow: 20,
coolSet: -1,
zoneId: 1,
comfortHeat: 5,
heatMax: 5,
coolMax: 5,
ecoCool: 5,
heatSet: -5,
},
{
operationStatus: 0,
ecoHeat: 0,
coolMin: null,
heatMin: null,
comfortCool: 0,
temparatureNow: null,
coolSet: 0,
zoneId: 2,
comfortHeat: 0,
heatMax: null,
coolMax: null,
ecoCool: 0,
heatSet: 0,
},
],
outdoorNow: 22,
operationMode: 1,
holidayTimer: 0,
powerful: 0,
electricAnode: null,
deviceGuid: '',
bivalent: 0,
tankStatus: [
{
operationStatus: 1,
temparatureNow: 50,
heatMax: 65,
heatMin: 40,
heatSet: 52,
},
],
informationMessage: 1,
pumpDuty: 0,
quietMode: 0,
forceHeater: 0,
tank: 1,
forceDHW: 0,
pendingUser: 0,
direction: 2,
};
69 changes: 69 additions & 0 deletions src/utils/examplePanasonicData/example3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// eco mode
export const example3 = {
deiceStatus: 0,
operationStatus: 1,
modelSeriesSelection: 2,
multiOdConnection: 0,
specialStatus: [
{ specialMode: 1, operationStatus: 1 },
{ specialMode: 2, operationStatus: 0 },
],
waterPressure: '0.00',
cnCntErrorStatus: 0,
zoneStatus: [
{
operationStatus: 1,
ecoHeat: -5,
coolMin: -5,
heatMin: -5,
comfortCool: -5,
temparatureNow: 20,
coolSet: -1,
zoneId: 1,
comfortHeat: 5,
heatMax: 5,
coolMax: 5,
ecoCool: 5,
heatSet: -5,
},
{
operationStatus: 0,
ecoHeat: 0,
coolMin: null,
heatMin: null,
comfortCool: 0,
temparatureNow: null,
coolSet: 0,
zoneId: 2,
comfortHeat: 0,
heatMax: null,
coolMax: null,
ecoCool: 0,
heatSet: 0,
},
],
outdoorNow: 22,
operationMode: 1,
holidayTimer: 0,
powerful: 0,
electricAnode: null,
deviceGuid: '',
bivalent: 0,
tankStatus: [
{
operationStatus: 1,
temparatureNow: 50,
heatMax: 65,
heatMin: 40,
heatSet: 52,
},
],
informationMessage: 1,
pumpDuty: 0,
quietMode: 0,
forceHeater: 0,
tank: 1,
forceDHW: 0,
pendingUser: 0,
direction: 2,
};
Loading

0 comments on commit e371ff5

Please sign in to comment.