Harmony Hub

Thanks for the pointers; my main problem now is getting it to communicate with MQTT. I use CloudMQTT and harmony-api currently doesn’t support username/pw/port so I’m not sure what to do next. I’ve asked if you can run two MQTT instances in HA with the idea of running the embedded MQTT just for harmony but I haven’t gotten any response from the forum or reddit on it.

I suppose I could use http communication but not sure how to use that in my automations to do things like turn on a light scene when a harmony activity fires…

I have fallen at this hurdle too. I have a local mqtt broker running on port 1883 with no auth and cant seem to get harmony-api to talk to it. No errors are reported but nothing is getting published onto the topics i’m watching and the switches I have configured in HA do nothing :anguished:

Actually just got this working and talking to HA. All you have to do is edit the app.js file and the line that has mqtt.connect & change it to
mqtt.connect(config.mqtt_host, {username: 'username', password: 'password', port: 1883})

I’m using mosquito on my local box and it is using protocol 3.1. mqtt on npm uses v4 so just add the following to your connection
var mqttClient = mqtt.connect('mqtt://127.0.0.1',{protocolId: 'MQIsdp', protocolVersion: 3 });
that issue is detailed here
Once i did that it all started working perfectly

1 Like

Well it appears we’ve helped each other through this because I just went to my CloudMQTT dashboard and saw my Harmony state messages!!! :tada:

It’s funny, because I tried to do the same using the code from the one pull request here and just added another variable for the port but I coudln’t make it work. Your solution is so straightforward and worked for me as soon as I restarted.

I’m so happy we could help each other out to get this running and hopefully we’ll help a lot of users get to this point by what we discovered and documented. Thanks again for your assistance!!

Could any of you kindly post a slightly more detailed post on the actual steps you took to get the Harmony Hub, MQTT and HA working together?

Downloaded the harmony-api and copied it to home/pi/harmony-api-master - Thanks to @maddox for the great interface!

@mrtrimble gave me the following commands to install apt-get working and install nodejs npm

    $ sudo apt-get update
    $ sudo apt-get upgrade
    $ sudo apt-get install nodejs npm

I used that to install forever, which was one of the requirements

    sudo npm install forever -g

Updated npm, because the version installed wasn’t the 3.0.0 or greater, which is why my script/bootstrap wasn’t installing the api correctly.

    sudo npm install npm -g

Ran the installer script/bootstrap according to the directions in the readme
Altered the config file with my broker information and then started the server with script/server
Confirmed it worked and then edited my crontab file as I mentioned above to run on reboot
Finally, altered the code as suggested by @beanian to allow me to use CloudMQTT

That’s not counting curses, many cigarettes, a few cups of coffee and feelings of inadequacy. But hopefully this will save you some of that.

EDIT: Gee it seems a lot easier when I look at it now, but it wasn’t. Thanks to those listed for their help!

4 Likes

Thanks for this! I’m going to give it a shot. The idea behind this knowledge share is that it will be easier for future generations to built upon.

100% agree, and you’ll see that if you read my other posts. I was actually planning on documenting this but your request pushed me to get it done sooner. Thanks! Hopefully I didn’t leave anything out, but let me know if you have any issues and I’ll do my best to help.

I got this sort-of working. Harmony API is running (apparently) but I can’t see it posting updates to my MQTT broker which is running on the same box. Its configured as the default config.json of the api as:

{
“mqtt_host”: “127.0.0.1”
}

However, subscribing to the harmony-api topic in MQTT returns no status updates.

Are you using the HA embedded broker with the default configuration and port?

I had this exact same issue. Are you using mosquito as your broker?
If so you need to change the app.js file to include the following
var mqttClient = mqtt.connect('mqtt://127.0.0.1',{protocolId: 'MQIsdp', protocolVersion: 3 });

I’m using MQTT. I tried adding the line: [quote=“beanian, post:30, topic:978”]
var mqttClient = mqtt.connect(‘mqtt://127.0.0.1’,{protocolId: ‘MQIsdp’, protocolVersion: 3 });
[/quote] to my app.js with no luck.

MQTT is the protocol. Which broker are you using? Mosquito? The HA embedded broker? Some other mqtt broker?

Oh sorry, Mosquito.

Thanks; did you change the default port on your Mosquito setup? Are you using a username and password? Maybe you need to set it up like the example @beanian gave me; that got me connected to CloudMQTT.

Harmony Hub

Might be easier if you post your app.js file (or the relevant portion of it) up here. I had the exact same issue as you so the line of code I gave you should have resolved it.

Hey guys,

I’ve been watching this thread, in the hopes of this being added in as official support.

While I wait for that to happen, the MQTT approach above gave me an idea. Over the weekend, I was able to use harmonyhubjs-client for NodeJS, and create a webserver which Home Assistant polls to get the current status of my Harmony Hub.

At the moment I’m just using REST switches, which seems to do the job well.

If anyone is interested in the code, let me know.

1 Like

Would this replace the need for Maddox harmony-api? If so I’m totally interested as I had it running but now it’s not working anymore.

Yeah, it looks like the Maddox Harmony API is very similar. Maddox looks like it creates a whole NodeJS Restful server for you to use. I’ve basically done the same thing, but created my own endpoints to use with Home Assistant.

Here is my app.js/index.js file that I’m using

var harmony = require('harmonyhubjs-client');
    express = require('express');
    bodyParser = require('body-parser');
    multer = require('multer');
    app = express();

app.use(bodyParser.raw({
    extended: false
}));

console.log("Connecting to Harmony Hub...");
harmony('192.168.1.5').then(function(harmonyClient) {
  console.log("Connected");
  console.log("Getting Activities");
  var activities = {};
  harmonyClient.getActivities().then(function(harmony_activities) {
    harmony_activities.some(function(a){
      activities[a.id] = a.label;
    });

    //Now that activities have been built, open a server
    console.log("Activities cached");

    console.log("Adding POST listeners");
    app.post("/*", function(req, res) {
      var activity = false;
      if (req.params) {
        // console.log(req.url);
        activity = req.params[0];
      }
      if (!activity || activity.length < 1)
        return; //Do nothing

      var a = false;
      for (id in activities) {
        if (activities[id] == activity) {
          a = id;
          break;
        }
      }
      if (!a || a.length < 1) {
        console.log("Could not turn on Activity " + activity + " as it is not cached. You may need to re-start this service");
        return;
      }
      req.on('data', function(chunk) {
          if (chunk.toString() === "ON") {
            console.log("Requested to turn on Activity: " + activity);

            harmonyClient.startActivity(a);
            console.log("Command sent");
          } else {
            console.log("Requested to turn off Activity: " + activity);

            harmonyClient.turnOff();

            console.log("Command sent");
          }
      });
      res.send("OK");
    });

    console.log("Adding GET listeners");
    app.get('/*', function(req, res) {
      var activity = false;
      if (req.params) {
        // console.log(req.url);
        activity = req.params[0];
      }
      if (!activity || activity.length < 1)
        return; //Do nothing

      if (activity == "current_activity") {
        harmonyClient.getCurrentActivity().then(function(c){
          var _current_activity = activities[c];
          if (activities[c] == "PowerOff")
            _current_activity = "Off";

          res.json({current_activity: _current_activity});
        });
      }

      //If we are a get request, check the status of the activity
      harmonyClient.isOff()
        .then(function(off) {
          if(off) {
            //Everything is off, respond with off
            res.send('OFF');
            return;
          }

          //An activity is on, is it this activity?
          var a = false;
          for (id in activities) {
            if (activities[id] == activity) {
              a = id;
              break;
            }
          }
          harmonyClient.getCurrentActivity().then(function(c){
            if (a === c) {
              res.send("ON");
              return;
            } else {
              res.send('OFF');
            }
          });
        });
    });

    var server = app.listen(3000, function(){
      console.log("express server listening");
    });

  });
});

The in Home Assistant, I have my switches setup like this in my configuration.yaml file.

switch:
  - platform: rest
    resource: http://127.0.0.1:8120/Watch Netflix
    name: "Netflix"
    body_on: "ON"
    body_off: "OFF"
  - platform: rest
    resource: http://127.0.0.1:8120/Watch TV
    name: "Live TV"
    body_on: "ON"
    body_off: "OFF"
  - platform: rest
    resource: http://127.0.0.1:8120/Watch Plex
    name: "Plex"
    body_on: "ON"
    body_off: "OFF"

I have the nodeJS run in a Docker on my Synology NAS so I don’t need to have a PC running somewhere for the server side of things to work. Just replace Watch TV Watch Netflix with the activity name that appears on your Harmony Remote.

Well, had to completely delete my harmony-api instance and everything associated with it and do a new git clone, but I got it back up and running. At this point, I’m not sure if I want to chance trying anything else. :sweat_smile: