MQTT garage door homekit switch

Hope someone can help, I am working on an MQTT Arduino, Raspberry pi, Hap-Node homekit solution for my automated driveway gate. Have been able to configure code to enable the gate to open and close using Homekit (garage) with the help of everyone around, however am having difficulty getting the Homekit to recognise when the gate triggers an actual open or close status. I have this status being read by the MQTT broker as a “1” and “0” but cant figure out the accessory.js code to be able to communicate with homekit to switch the open or close status on the IPhone (ie if I manually use a remote to open the gate etc)… any help would be greatly appreciated as I am not very good at coding.

Code below

//START SETUP
var garageName = ‘Gate’;
var uuidTag = ‘garage’;
//END SETUP

var Accessory = require(’…/’).Accessory;
var Service = require(’…/’).Service;
var Characteristic = require(’…/’).Characteristic;
var uuid = require(’…/’).uuid;
var MQTT_IP = ‘192.168.0.21’

var mqtt_topic = ‘/Home/Gate’

//MQTT Setup

var mqtt = require(‘mqtt’);

var options = {
port: 1883,
host: MQTT_IP,
clientId: ‘cdfadgbhK343’
};

var client = mqtt.connect(options);

client.on(‘message’, function(topic, message) {

});

var garageUUID = uuid.generate(‘hap-nodejs:accessories:’+uuidTag);
var garage = exports.accessory = new Accessory(garageName, garageUUID);

var GARAGE_DOOR = {
opened: false,
open: function() {
console.log(“Opening the Garage!”);
client.publish(mqtt_topic, ‘1’);
GARAGE_DOOR.opened = true;

},
close: function() {
console.log(“Closing the Garage!”);
client.publish(mqtt_topic, ‘0’);
GARAGE_DOOR.opened = false;
},
identify: function() {
console.log(“Identify the Garage”);
}
};

// Add properties for publishing (in case we’re using Core.js and not BridgedCore.js)
garage.username = “C1:5D:3F:F2:5E:FA”; //edit this if you use Core.js
garage.pincode = “031-45-154”;

garage
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Manufacturer, “Liftmaster”)
.setCharacteristic(Characteristic.Model, “Rev-1”)
.setCharacteristic(Characteristic.SerialNumber, “TW000165”);

garage.on(‘identify’, function(paired, callback) {
GARAGE_DOOR.identify();
callback();
});

garage
.addService(Service.GarageDoorOpener, “Garage Door”)
.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) // force initial state to CLOSED
.getCharacteristic(Characteristic.TargetDoorState)
.on(‘set’, function(value, callback) {

if (value == Characteristic.TargetDoorState.CLOSED) {
  GARAGE_DOOR.close();
 callback();    
 garage
    .getService(Service.GarageDoorOpener)
    .setCharacteristic(Characteristic.CurrentDoorState, Characteristic.CurrentDoorState.CLOSED);

}
else if (value == Characteristic.TargetDoorState.OPEN) {
  GARAGE_DOOR.open();
  Service.GarageDoorOpener.LockCurrentState=false;
  Service.GarageDoorOpener.LockTargetState=false

  garage
    .getService(Service.GarageDoorOpener)
    .setCharacteristic(Characteristic.CurrentDoorState, Characteristic.CurrentDoorState.OPEN);

callback();

}

});

garage
.getService(Service.GarageDoorOpener)
.getCharacteristic(Characteristic.CurrentDoorState)
.on(‘get’, function(callback) {

var err = null;

if (GARAGE_DOOR.opened) {
  console.log("Query: Is Garage Open? Yes.");
  callback(err, Characteristic.CurrentDoorState.OPEN);
}
else {
  console.log("Query: Is Garage Open? No.");
  callback(err, Characteristic.CurrentDoorState.CLOSED);
}

});

It will be easier for others to help if you can format all of your code as code. Can you fix this up in your post? :slight_smile:

Hi Lindsay, yes apologies I am a little hopeless with the code. Have changed my tact and am now trying MQTT Homebridge - garagedoor with arduino - all tests are working pretty well but still cant quite get the system to recognise the correct state when the gate is opened or closed outside of homekit. The index.js code is as follows:

    -// MQTT Garage Accessory plugin for HomeBridge
//
// Remember to add accessory to config.json. Example:
// "accessories": [
//     {
//            "accessory": "mqttswitch",
//            "name": "PUT THE NAME OF YOUR SWITCH HERE",
//            "url": "PUT URL OF THE BROKER HERE",
//			  "username": "PUT USERNAME OF THE BROKER HERE",
//            "password": "PUT PASSWORD OF THE BROKER HERE"
// 			  "caption": "PUT THE LABEL OF YOUR SWITCH HERE",
// 			  "topics": {
// 				"statusCurrent": 	"PUT THE MQTT TOPIC FOR THE GETTING THE STATUS OF YOUR SWITCH HERE",
// 				"statusTarget": 	"PUT THE MQTT TOPIC FOR THE SETTING THE STATUS OF YOUR SWITCH HERE"
// 			  }
//     }
// ],
//
// When you attempt to add a device, it will ask for a "PIN code".
// The default code for all HomeBridge accessories is 031-45-154.

'use strict';

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

function MqttGarageAccessory(log, config) {
  	this.log          	= log;
  	this.name 			= config["name"];
  	this.url 			= config["url"];
	this.client_Id 		= 'mqttjs_' + Math.random().toString(16).substr(2, 8);
	this.options = {
	    keepalive: 10,
    	clientId: this.client_Id,
	    protocolId: 'MQTT',
    	protocolVersion: 4,
    	clean: true,
    	reconnectPeriod: 1000,
    	connectTimeout: 30 * 1000,
		will: {
			topic: 'WillMsg',
			payload: 'Connection Closed abnormally..!',
			qos: 0,
			retain: false
		},
	    username: config["username"],
	    password: config["password"],
    	rejectUnauthorized: false
	};
	this.caption		= config["caption"];
	this.topicStatusCurrent	= config["topics"].statusCurrent; // the target value sent to HomeKit
	this.topicStatusTarget	= config["topics"].statusTarget; // the actual value for door state

	this.CachedGarageDoorState = null; // Characteristic.CurrentDoorState.CLOSED; // Closed = closed
	this.CachedGarageTargetDoorState = null; //Characteristic.CurrentDoorState.CLOSED; // 1 = closed   
    
	this.service = new Service.GarageDoorOpener(this.name);
    
    this.service.getCharacteristic( Characteristic.CurrentDoorState ).on(    'get', this.getDoorPositionState.bind(this) );
    this.service.getCharacteristic( Characteristic.TargetDoorState ).on(     'get', this.getDoorTargetPositionState.bind(this) );
    this.service.getCharacteristic( Characteristic.ObstructionDetected ).on( 'get', this.getObstructionDetected.bind(this) );
    this.service.getCharacteristic( Characteristic.TargetDoorState ).on(     'set', this.setDoorTargetPosition.bind(this) );
	
	// connect to MQTT broker
	this.client = mqtt.connect(this.url, this.options);
	var that = this;
	this.client.on('error', function () {
		that.log('Error event on MQTT');
	});

	this.client.on('message', function (topic, message) {
        that.log( "Got MQTT! garage" );
		if (topic == that.topicStatusCurrent) { // actual value changed
			var status = parseInt(message);
			that.CachedGarageDoorState = status;
            that.service.getCharacteristic(Characteristic.CurrentDoorState).setValue(status, undefined, 'fromSetValue');
            }
        if (topic == that.topicStatusTarget) { // target value changed
			var status = parseInt(message);
          if (that.CachedGarageTargetDoorState != status) { // avoid loopback from own changes
			that.CachedGarageTargetDoorState = status;
          that.service.getCharacteristic(Characteristic.TargetDoorState).setValue(status, undefined, 'fromSetValue');
        }
		}
	});
    this.client.subscribe(this.topicStatusCurrent);
//    this.client.subscribe(this.topicStatusTarget);
}

module.exports = function(homebridge) {
  	Service = homebridge.hap.Service;
  	Characteristic = homebridge.hap.Characteristic;
  
  	homebridge.registerAccessory("homebridge-mqttgarage", "Mqttgarage", MqttGarageAccessory);
}

MqttGarageAccessory.prototype.getDoorPositionState = function(callback) {
    this.log("getDoorPosition");
    callback(null, this.CachedGarageDoorState);
}

MqttGarageAccessory.prototype.getDoorTargetPositionState = function(callback) {
    this.log("getDoorTargetPosition");
    callback(null, this.CachedGarageTargetDoorState);
}

MqttGarageAccessory.prototype.setDoorTargetPosition = function(status, callback, context) {
    this.log("setDoorTargetPosition");
    this.CachedGarageTargetDoorState = status;
	this.client.publish(this.topicStatusTarget, String(status) ); // send MQTT packet for new state
	callback();
}

MqttGarageAccessory.prototype.getObstructionDetected = function(callback) {
    this.log("getObstructionDetected");
    callback(null, false); // no sensor, always false
}

MqttGarageAccessory.prototype.getServices = function() {
  return [this.service];
}

Also I have the Arduino code receiving via MQTT “ẗopic” (statusTarget) a 1 or 0 for open and closed to activate the gate and when the gate hits a status öpen or closed it activates an input pin sending a 1 or 0 for open and close via the alternate “topic2” (statusCurrent) this part is sending ans receiving correctly but when the gate is opened outside of the homkit (ie via RF remote) the homekit indicates “closing” or “opening”(usually the same as the previous state ie if the gate was closed in homekit it will indicate closing even through the gate is actually opening) instead of "open"or “closed”. I may have not made this clear but I cant work it out and have been using the below code in Arduino for currentstatus message delivery: any help would be greatly appreciated:

///// Evaluate input D15 and send a message if the value changes

if (digitalRead(15) != vInp15)

{

vInp15 = digitalRead(15);

if (vInp15 == HIGH)


{

  delay(11000);

  client.publish(mqtt_topic2, "0");


  Serial.println("TX: DoorOpen");

}

else

  if (vInp15 == LOW)
  { 

    delay(10200);

    client.publish(mqtt_topic2, "1");

    Serial.println("TX: DoorClosed");

  }

}