Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NO ISSUE: Support for uncalibrated blinds #14

Open
Tyraenor opened this issue Jan 3, 2021 · 0 comments
Open

NO ISSUE: Support for uncalibrated blinds #14

Tyraenor opened this issue Jan 3, 2021 · 0 comments

Comments

@Tyraenor
Copy link

Tyraenor commented Jan 3, 2021

Hi,

I had the issue, that I cannot calibrate one of my blinds, so I searched for a possibility to integrate it in HomeKit anyway.

Now I found a solution in your plugin, but I needed to change the code a little bit. Maybe you want to look into it, so maybe you are able to deliver an official solution for people like me who cannot calibrate their blinds.

Thank you so much for your work! You saved my day.

var mqtt = require("mqtt");
var Service, Characteristic;

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

    homebridge.registerAccessory("homebridge-mqtt-blinds", "BlindsMQTT", BlindsMQTTAccessory);
}

function BlindsMQTTAccessory(log, config) {
    // GLOBAL vars
    this.log = log;

    // CONFIG vars
    this.name = config["name"];
    this.manufacturer = config['manufacturer'] || "";
        this.model = config['model'] || "";
        this.serialNumberMAC = config['serialNumberMAC'] || "";

    // MQTT vars
    this.mqttUrl = config["mqttBrokerUrl"];
    this.mqttUsername = config["mqttUsername"];
    this.mqttPassword = config["mqttPassword"];
    this.mqttClientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8);

    this.mqttMainTopic = config["mqttMainTopic"]+"/";
    this.mqttGetTopics = config["mqttGetTopics"];
    this.mqttSetTopics = config["mqttSetTopics"];

    // Array for PositionStateValues (DEC, INC, STOP)
    this.mqttPositionStateValues = config["mqttPositionStateValues"];

    // manual controls in setup?
    this.useManualControls = config["useManualControls"];

    // MQTT options
    this.mqttOptions = {
      keepalive: 10,
      clientId: this.mqttClientId,
      protocolId: 'MQTT',
      protocolVersion: 4,
      clean: true,
      reconnectPeriod: 1000,
      connectTimeout: 30 * 1000,
      will: {
        topic: 'WillMsg',
        payload: 'Connection Closed abnormally..!',
        qos: 0,
        retain: false
      },
      username: this.mqttUsername,
      password: this.mqttPassword,
      rejectUnauthorized: false
    };

    // STATE vars
    this.lastPosition = 100; // last known position of the blinds, open by default
    this.currentPositionState = 2; // stopped by default
    this.currentTargetPosition = 100; // open by default
    this.lastAction = 0; // opening by default (0 = opening, 1 = closing)

    // MQTT handling
    this.mqttClient = mqtt.connect(this.mqttUrl, this.mqttOptions);
    var that = this;
        this.mqttClient.on('error', function() {
                that.log('Error event on MQTT');
        });

        this.mqttClient.on('connect', function() {
      that.log('MQTT is running');
        });

    this.mqttClient.on('message', function(topic, message) {
      switch (topic) {
        case that.mqttMainTopic + that.mqttGetTopics.currentPosition:
          var payload = parseInt(message);
          if (payload >= 0 && payload <= 100) {
            that.lastPosition = payload;
            that.service.getCharacteristic(Characteristic.CurrentPosition).updateValue(that.lastPosition);
            that.log("Updated CurrentPosition: %s", that.lastPosition);
          }
          if(that.useManualControls) {
            if(that.currentPositionState == 2 && that.lastAction == 0) {
              that.lastPosition = 100;
              that.service.getCharacteristic(Characteristic.CurrentPosition).updateValue(that.lastPosition);
              that.log("Updated CurrentPosition: %s", that.lastPosition);
            }
            else if(that.currentPositionState == 2 && that.lastAction == 1) {
              that.lastPosition = 0;
              that.service.getCharacteristic(Characteristic.CurrentPosition).updateValue(that.lastPosition);
              that.log("Updated CurrentPosition: %s", that.lastPosition);
            }
          }
          break;
        case that.mqttMainTopic + that.mqttGetTopics.positionState:
          // map the position state (open = 0 = DECREASING, close = 1 = INCREASING, stop = 2 = STOPPED)
          var payload = message.toString();
          switch(payload) {
            case that.mqttPositionStateValues[0]:
              that.currentPositionState = 0;
              if(that.useManualControls) {
                that.lastAction = 0;
                that.currentTargetPosition = 100;
                that.service.getCharacteristic(Characteristic.TargetPosition).updateValue(that.currentTargetPosition);
                            that.log("Simulated TargetPosition: %s", that.currentTargetPosition);
              }
              that.service.getCharacteristic(Characteristic.PositionState).updateValue(that.currentPositionState);
              that.log("Updated PositionState: %s", that.currentPositionState);
              break;
            case that.mqttPositionStateValues[1]:
              that.currentPositionState = 1;
              if(that.useManualControls) {
                that.lastAction = 1;
                that.currentTargetPosition = 0;
                that.service.getCharacteristic(Characteristic.TargetPosition).updateValue(that.currentTargetPosition);
                            that.log("Simulated TargetPosition: %s", that.currentTargetPosition);
              }
              that.service.getCharacteristic(Characteristic.PositionState).updateValue(that.currentPositionState);
              that.log("Updated PositionState: %s", that.currentPositionState);
              break;
            case that.mqttPositionStateValues[2]:
              that.currentPositionState = 2;
              that.currentTargetPosition = that.lastPosition;
              that.service.getCharacteristic(Characteristic.PositionState).updateValue(that.currentPositionState);
              that.service.getCharacteristic(Characteristic.TargetPosition).updateValue(that.currentTargetPosition);
              that.log("Updated PositionState: %s", that.currentPositionState);
              break;
            default:
              that.log("Unknown PositionState: %s", payload);
          }
          break;
        case that.mqttMainTopic + that.mqttGetTopics.targetPosition:
          var payload = parseInt(message);
          if (payload >= 0 && payload <= 100) {
            that.currentTargetPosition = parseInt(message);
            that.service.getCharacteristic(Characteristic.TargetPosition).updateValue(that.currentTargetPosition);
            that.log("Updated TargetPosition: %s", that.currentTargetPosition);
          }
          break;
      }
    });

    // MQTT subscribed
    this.mqttClient.subscribe(that.mqttMainTopic + that.mqttGetTopics.currentPosition);
    this.mqttClient.subscribe(that.mqttMainTopic + that.mqttGetTopics.positionState);
    this.mqttClient.subscribe(that.mqttMainTopic + that.mqttGetTopics.targetPosition);

    // register the service and provide the functions
    this.service = new Service.WindowCovering(this.name);

    // the current position (0-100%)
    this.service
        .getCharacteristic(Characteristic.CurrentPosition)
        .on('get', this.getCurrentPosition.bind(this));

    // the position state (0 = DECREASING, 1 = INCREASING, 2 = STOPPED)
    this.service
        .getCharacteristic(Characteristic.PositionState)
        .on('get', this.getPositionState.bind(this));

    // the target position (0-100%)
    this.service
        .getCharacteristic(Characteristic.TargetPosition)
        .on('get', this.getTargetPosition.bind(this))
        .on('set', this.setTargetPosition.bind(this));
}

BlindsMQTTAccessory.prototype.getCurrentPosition = function(callback) {
    this.log("Requested CurrentPosition: %s", this.lastPosition);
    callback(null, this.lastPosition);
}

BlindsMQTTAccessory.prototype.getPositionState = function(callback) {
    this.log("Requested PositionState: %s", this.currentPositionState);
    callback(null, this.currentPositionState);
}

BlindsMQTTAccessory.prototype.getTargetPosition = function(callback) {
    this.log("Requested TargetPosition: %s", this.lastPosition);
    callback(null, this.lastPosition);
}

BlindsMQTTAccessory.prototype.setTargetPosition = function(pos, callback) {
    this.log("Set TargetPosition: %s", pos);
    this.currentTargetPosition = pos;
    if(this.useManualControls) {
      if(pos >= 51) {
          spos = "open";
      }
      else if(pos <= 50) {
          spos = "close";
      }
      this.mqttClient.publish(this.mqttMainTopic + this.mqttSetTopics.targetPosition, spos.toString(), this.mqttOptions);
    }
    else {
      this.mqttClient.publish(this.mqttMainTopic + this.mqttSetTopics.targetPosition, pos.toString(), this.mqttOptions);
    }
    callback(null);
}

BlindsMQTTAccessory.prototype.getServices = function() {
  var informationService = new Service.AccessoryInformation();

  informationService
    .setCharacteristic(Characteristic.Name, this.name)
    .setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
    .setCharacteristic(Characteristic.Model, this.model)
    .setCharacteristic(Characteristic.SerialNumber, this.serialNumberMAC);

  return [informationService, this.service];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant