seikan / homebridge-mi-air-purifier

A Xiaomi Mi air purifier plugin for Homebridge.
Other
172 stars 65 forks source link

Ios11 air purifier support #7

Closed Guoer-xz closed 7 years ago

Guoer-xz commented 7 years ago

Hello, I at home you do a little change in the plug-in can be correctly identified as IOS 11 air purifier, correct response work and operation can get equipment, but I have no basis in this field, now is not the right power state feedback, interface button state home.app update is not correct no, do not know if you have time and plan for an upgrade to your this great plugin

The following is my modified version of index.js may have many unreasonable places, laughed————————————————————————

var miio = require('miio'); var Accessory, Service, Characteristic; var devices = [];

module.exports = function(homebridge) { Accessory = homebridge.platformAccessory; Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic;

homebridge.registerAccessory('homebridge-mi-air-purifier', 'MiAirPurifier', MiAirPurifier);

}

function MiAirPurifier(log, config) { this.log = log; this.name = config.name || 'Air Purifier'; this.showAirQuality = config.showAirQuality || false; this.showTemperature = config.showTemperature || false; this.showHumidity = config.showTemperature || false; this.ip = config.ip; this.token = config.token; this.device = null;

if(!this.ip)
    throw new Error('Your must provide IP address of the airpurifier.');

if(!this.token)
    throw new Error('Your must provide token of the airpurifier.');

this.services = [];

// Modes supported
this.modes = [
    [0, 'idle'], [60, 'auto'], [80, 'silent'], [100, 'favorite']
];

// Air purifier is not available in Homekit yet, register as Fan
this.AirPurifierService = new Service.AirPurifier(this.name);

this.AirPurifierService
    .getCharacteristic(Characteristic.Active)
    .on('get', this.getPowerState.bind(this))
    .on('set', this.setPowerState.bind(this));

this.AirPurifierService
    .getCharacteristic(Characteristic.RotationSpeed)
    .on('get', this.getRotationSpeed.bind(this))
    .on('set', this.setRotationSpeed.bind(this));

this.services.push(this.AirPurifierService);

this.serviceInfo = new Service.AccessoryInformation();

this.serviceInfo
    .setCharacteristic(Characteristic.Manufacturer, 'Xiaomi')
    .setCharacteristic(Characteristic.Model, 'Air Purifier');

this.services.push(this.serviceInfo);

if(this.showAirQuality){
    this.airQualitySensorService = new Service.AirQualitySensor('Air Quality Sensor');

    this.airQualitySensorService
        .getCharacteristic(Characteristic.AirQuality)
        .on('get', this.getAirQuality.bind(this));

    this.services.push(this.airQualitySensorService);
}

if(this.showTemperature){
    this.temperatureSensorService = new Service.TemperatureSensor('Temperature');

    this.temperatureSensorService
        .getCharacteristic(Characteristic.CurrentTemperature)
        .on('get', this.getCurrentTemperature.bind(this));

    this.services.push(this.temperatureSensorService);
}

if(this.showHumidity){
    this.humiditySensorService = new Service.HumiditySensor('Humidity');

    this.humiditySensorService
        .getCharacteristic(Characteristic.CurrentRelativeHumidity)
        .on('get', this.getCurrentRelativeHumidity.bind(this));

    this.services.push(this.humiditySensorService);
}

this.discover();

}

MiAirPurifier.prototype = { discover: function(){ var accessory = this; var log = this.log;

    log.debug('Discovering Mi air purifier devices...');

this.device = miio.createDevice({ address: this.ip, token: this.token, model: 'zhimi.airpurifier.m1' });

    this.device.init()
        .then(function(){
            log.debug('State: ' + accessory.device.state);
            log.debug('speed: ' + accessory.device.speed);
        })
        .catch(function(err){
            log.debug(err);
            throw new Error('Not able to initialize air purifier.');
        });
},

getPowerState: function(callback) {
    if(!this.device){
        callback(null, false);
        return;
    }

    callback(null, this.device.power);
},

setPowerState: function(state, callback) {
    if(!this.device){
        callback(new Error('No air purifier is discovered.'));
        return;
    }

    this.device.setPower(state);
    callback();
},

getCurrentRelativeHumidity: function(callback) {
    if(!this.device){
        callback(null, 0);
        return;
    }

    callback(null, this.device.humidity);
},

getRotationSpeed: function(callback) {
    if(!this.device){
        callback(null, 0);
        return;
    }

    for(var item of this.modes){
        if(this.device.mode == item[1]){
            callback(null, item[0]);
            return;
        }
    }
},

setRotationSpeed: function(speed, callback) {
    if(!this.device){
        callback(new Error('No air purifier is discovered.'));
        return;
    }

    for(var item of this.modes){
        if(speed <= item[0]){
            this.log.debug('Set mode: ' + item[1]);
            this.device.setMode(item[1]);
            break;
        }
    }

    callback();
},

getAirQuality: function(callback) {
    if(!this.device){
        callback(null, Characteristic.AirQuality.UNKNOWN);
        return;
    }

    var levels = [
        [200, Characteristic.AirQuality.POOR],
        [150, Characteristic.AirQuality.INFERIOR],
        [100, Characteristic.AirQuality.FAIR],
        [50, Characteristic.AirQuality.GOOD],
        [0, Characteristic.AirQuality.EXCELLENT],
    ];

    var quality = Characteristic.AirQuality.UNKNOWN;

    for(var item of levels){
        if(this.device.aqi > item[0]){
            quality = item[1];
            break;
        }
    }

    callback(null, quality);
},

getCurrentTemperature: function(callback) {
    if(!this.device){
        callback(null, 0);
        return;
    }

    callback(null, this.device.temperature);
},

identify: function(callback) {
    callback();
},

getServices: function() {
    return this.services;
}

};

seikan commented 7 years ago

Thanks for the feedback. I will change the service type once iOS 11 is officially launched.