Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ruizmarc committed Dec 28, 2023
1 parent 7a3105d commit 4643932
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"curly": ["warn", "all"],
"brace-style": ["warn"],
"prefer-arrow-callback": ["warn"],
"max-len": ["warn", 140],
"max-len": ["warn", 180],
"no-console": ["warn"], // use the provided Homebridge log method instead
"no-non-null-assertion": ["off"],
"comma-spacing": ["error"],
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[![GitHub pull requests](https://img.shields.io/github/issues-pr/ruizmarc/homebridge-intelliclima)](https://github.com/ruizmarc/homebridge-intelliclima/pulls)
[![GitHub issues](https://img.shields.io/github/issues/ruizmarc/homebridge-intelliclima)](https://github.com/ruizmarc/homebridge-intelliclima/issues)

Homebridge plugin for WiFi Thermostats manufactured by Mistsubishi and connected to IntelliClima.
Homebridge plugin for WiFi Thermostats manufactured by Fantini Cosmi and connected to IntelliClima. More devices can be added in the future if they are compatible with the IntelliClima API.

</span>

Expand Down Expand Up @@ -46,3 +46,11 @@ Homebridge plugin for WiFi Thermostats manufactured by Mistsubishi and connected
| `password` | Your password will not be shared, it will be only used it to authenticate with IntelliClima API. It is the same you use in your IntelliClima App |
| `temperatureSensor` | This enable extra temperature sensor to use with automations in HomeKit app |
| `humiditySensor` | This enables extra humidity sensor to use with automations in HomeKit app |

### Caveats

Fantini Cosmi do not provide any open/public API to interact with their devices. This plugin uses the same API that the official IntelliClima App uses and there is not documentation on how to interact with it, but just observing how the App behaves. This means that if Fantini Cosmi changes their API, this plugin might stop working.

Currently, this plugin fully supports C800WiFi thermostats as it is the device I own. If you have a different device a huge part of the plugin will probably work, but some features might be broken. If you have a different device and you want to add support for it, please open an issue and I will do my best to add support for it with your support to test the device.

IntelliClima Homebridge is a hobby project of mine, provided as-is, with no warranty whatsoever. I'm running it successfully at home since I created it, but your mileage might vary.
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"private": true,
"displayName": "IntelliClima Homebridge",
"name": "homebridge-intelliclima",
"version": "1.0.0",
"description": "A homebridge plugin for IntelliClima App from Fantini Cosmi.",
"homepage": "https://github.com/ruizmarc/homebridge-intelliclima#readme",
"license": "Apache-2.0",
"author": "ruizmarc",
"repository": {
"type": "git",
"url": "https://github.com/ruizmarc/homebridge-intelliclima.git"
"url": "git+https://github.com/ruizmarc/homebridge-intelliclima.git"
},
"bugs": {
"url": "https://github.com/ruizmarc/homebridge-intelliclima/issues"
Expand All @@ -31,6 +31,12 @@
"fantini cosmi",
"C800"
],
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ruizmarc"
}
],
"dependencies": {
"axios": "^1.6.2"
},
Expand Down
37 changes: 27 additions & 10 deletions src/accessories/ThermostatAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ export class ThermostatAccesory {
};
}

public static fromCelsiusToFahrenheit(celsius: number): number {
return ((celsius * 1.8) + 32);
}

public static fromFahrenheitToCelsius(fahrenheit: number): number {
return ((fahrenheit - 32) / 1.8);
}

get platformAccessoryId(): string {
return this.platformAccessory?.UUID ?? this.api.hap.uuid.generate(this.id);
}
Expand Down Expand Up @@ -198,8 +206,7 @@ export class ThermostatAccesory {
*/
handleCurrentTemperatureGet() {
this.log.debug('Triggered GET CurrentTemperature');
const actualTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? this.currentTemperature : ((this.currentTemperature * 1.8) + 32);
return actualTemperature;
return this.temperatureDisplayUnits === 'CELSIUS' ? this.currentTemperature : ThermostatAccesory.fromCelsiusToFahrenheit(this.currentTemperature);
}

/**
Expand All @@ -216,15 +223,14 @@ export class ThermostatAccesory {
*/
handleTargetTemperatureGet() {
this.log.debug('Triggered GET TargetTemperature');
const actualTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? this.targetTemperature : ((this.targetTemperature * 1.8) + 32);
return actualTemperature;
return this.temperatureDisplayUnits === 'CELSIUS' ? this.targetTemperature : ThermostatAccesory.fromCelsiusToFahrenheit(this.targetTemperature);
}

/**
* Handle requests to set the "Target Temperature" characteristic
*/
async handleTargetTemperatureSet(value) {
const actualTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? value : ((value - 32) / 1.8);
const actualTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? value : ThermostatAccesory.fromFahrenheitToCelsius(value);
this.log.debug('Triggered SET TargetTemperature:', actualTemperature);
await this.intelliclimaAPIConsumer.setDeviceTargetTemperature(this, actualTemperature);
}
Expand Down Expand Up @@ -257,6 +263,8 @@ export class ThermostatAccesory {

private registerService() {

this.log.info('Initializing thermostat:', this.name);

this.thermostatService = this.platformAccessory?.getService(this.Service.Thermostat) ||
this.platformAccessory?.addService(this.Service.Thermostat);

Expand Down Expand Up @@ -290,17 +298,19 @@ export class ThermostatAccesory {
.onSet(this.handleTemperatureDisplayUnitsSet.bind(this));

if (this.config.temperatureSensor) {
this.log.info('Initializing temperature sensor:', this.name);
this.temperatureSensorService = this.platformAccessory?.getService(this.Service.TemperatureSensor) ||
this.platformAccessory?.addService(this.Service.TemperatureSensor);
this.temperatureSensorService?.setCharacteristic(this.Characteristic.Name, this.name);
this.temperatureSensorService?.setCharacteristic(this.Characteristic.Name, `${this.name} Temperature Sensor`);
this.temperatureSensorService?.getCharacteristic(this.Characteristic.CurrentTemperature)
.onGet(this.handleCurrentTemperatureGet.bind(this));
}

if (this.config.humiditySensor) {
this.log.info('Initializing humidity sensor:', this.name);
this.humiditySensorService = this.platformAccessory?.getService(this.Service.HumiditySensor) ||
this.platformAccessory?.addService(this.Service.HumiditySensor);
this.humiditySensorService?.setCharacteristic(this.Characteristic.Name, this.name);
this.humiditySensorService?.setCharacteristic(this.Characteristic.Name, `${this.name} Humidity Sensor`);
this.humiditySensorService?.getCharacteristic(this.Characteristic.CurrentRelativeHumidity)
.onGet(this.handleCurrentRelativeHumidity.bind(this));
}
Expand All @@ -323,27 +333,34 @@ export class ThermostatAccesory {
this.subscriptionInterval = setInterval(async () => {
await this.sync();
if (this.currentStatus !== prevStatus) {
this.log.info(`Updating ${this.name} CurrentHeatingCoolingState to ${this.currentStatus} from ${prevStatus}`);
this.thermostatService?.updateCharacteristic(this.Characteristic.CurrentHeatingCoolingState, this.currentStatus);
prevStatus = this.currentStatus;
}
if (this.targetStatus !== prevTargetStatus) {
this.log.info(`Updating ${this.name} TargetHeatingCoolingState to ${this.targetStatus} from ${prevTargetStatus}`);
this.thermostatService?.updateCharacteristic(this.Characteristic.TargetHeatingCoolingState, this.targetStatus);
prevTargetStatus = this.targetStatus;
}
if (this.currentHumidity !== prevHumidity) {
this.log.info(`Updating ${this.name} CurrentRelativeHumidity to ${this.currentHumidity} from ${prevHumidity}`);
this.thermostatService?.updateCharacteristic(this.Characteristic.CurrentRelativeHumidity, this.currentHumidity);
this.humiditySensorService?.updateCharacteristic(this.Characteristic.CurrentRelativeHumidity, this.currentHumidity);
prevHumidity = this.currentHumidity;
}
if (this.currentTemperature !== prevTemperature) {
const actualTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? this.currentTemperature :
((this.currentTemperature * 1.8) + 32);
const actualTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? this.currentTemperature : ThermostatAccesory.fromCelsiusToFahrenheit(this.currentTemperature);
const actualPrevTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? prevTemperature : ThermostatAccesory.fromCelsiusToFahrenheit(prevTemperature);
this.log.info(`Updating ${this.name} CurrentTemperature to ${actualTemperature} from ${actualPrevTemperature}`);
this.thermostatService?.updateCharacteristic(this.Characteristic.CurrentTemperature, actualTemperature);
this.temperatureSensorService?.updateCharacteristic(this.Characteristic.CurrentTemperature, actualTemperature);
prevTemperature = this.currentTemperature;
}
if (this.targetTemperature !== prevTargetTemperature) {
this.thermostatService?.updateCharacteristic(this.Characteristic.TargetTemperature, this.targetTemperature);
const actualTargetTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? this.targetTemperature : ThermostatAccesory.fromCelsiusToFahrenheit(this.targetTemperature);
const actualPrevTargetTemperature = this.temperatureDisplayUnits === 'CELSIUS' ? prevTargetTemperature : ThermostatAccesory.fromCelsiusToFahrenheit(prevTargetTemperature);
this.log.info(`Updating ${this.name} TargetTemperature to ${actualTargetTemperature} from ${actualPrevTargetTemperature}`);
this.thermostatService?.updateCharacteristic(this.Characteristic.TargetTemperature, actualTargetTemperature);
prevTargetTemperature = this.targetTemperature;
}
}, 5000);
Expand Down
4 changes: 4 additions & 0 deletions src/platform/IntelliClimaPlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export class IntelliClimaPlatform implements DynamicPlatformPlugin {

for (const device of devices) {
const thermostatInfo = ThermostatAccesory.mapIntelliClimaDeviceResponseToThermostatInfo(device);
if (thermostatInfo.model !== 'C800WiFi') {
this.log.warn(`Detected device with unsupported model ${thermostatInfo.model} named ${thermostatInfo.name}. Skipping...`);
continue;
}
const thermostatAccessoryStatus = ThermostatAccesory.mapIntelliClimaDeviceResponseToThermostatAccesoryStatus(device);
const thermostatAccessory = new ThermostatAccesory(
thermostatInfo.id,
Expand Down

0 comments on commit 4643932

Please sign in to comment.