rudders / homebridge-http

HTTP Plugin for Homebridge
Apache License 2.0
178 stars 110 forks source link

Issue With status_on Parameter #68

Closed JonnyBoy333 closed 7 years ago

JonnyBoy333 commented 7 years ago

I'm having trouble getting the custom on status parameter to work in the config file. My config file looks like this:

    {
        "accessory": "Http",
        "name": "Bedroom Music",
        "switchHandling": "realtime",
        "http_method": "GET",
        "on_url": "http://localhost:5005/preset/bedroom",
        "off_url": "http://localhost:5005/pauseall",
        "status_url": "http://localhost:3000/status",
        "status_on": "ON",
      "status_off": "OFF",
        "service": "Light",
        "brightnessHandling": "yes",
        "brightness_url": "http://localhost:5005/groupVolume/%b",
        "brightnesslvl_url": "http://localhost:5005/state-volume",
        "sendimmediately": "",
        "username" : "",
        "password" : ""
      },

The status server is an ultra basic node server used for testing purposes that just sends 'ON' as a response.

const express = require('express')
let app = express();

app.get('/status', function (req, res) {
  res.set('Content-Type', 'text/html');
  res.status(200).send('ON');
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
})

But whenever I turn on homebridge I get the error Light received power http://localhost:3000/status state is currently NaN. I've even looked into the index.js and made sure that custom status piece is in there:

this.httpRequest(url, "", "GET", this.username, this.password, this.sendimmediately, function(error, response, responseBody) {
    if (error) {
        this.log('HTTP get power function failed: %s', error.message);
        callback(error);
    } else {
        var binaryState;
        this.log('Status Config On', this.status_on);
        if (this.status_on && this.status_off) {    //Check if custom status checks are set
              var customStatusOn = this.status_on;
              var customStatusOff = this.status_off;
              var statusOn = responseBody.includes(customStatusOn);
              var statusOff = responseBody.includes(customStatusOff);
              this.log('Status On', statusOn);
                  if (statusOn || statusOff) { //check if one of the custom status was true
                 if (statusOn) binaryState = 1;
                 if (statusOff) binaryState = 0;
              }
      } else {
          binaryState = parseInt(responseBody.replace(/\D/g,""));
      }
           var powerOn = binaryState > 0;
           this.log("Power state is currently hello world %s", binaryState);
           callback(null, powerOn);
    }
    }.bind(this));
  }

Is there a way to make it so I can see the the logs when I start up homebridge so I can actually see what the http plugin is receiving from my server? It's incredibly hard to debug when I can't see the logs.

NovaGL commented 7 years ago

Can you try 0 and 1 for on off I didn't do the custom implementation

Also not sure how you setup your home bridge so it might be in global logs. Look in the general homebridge repo for help on that

JonnyBoy333 commented 7 years ago

Yes, both 1 and 0 work fine for on and off stats. I need more flexibility for my on state though because I'm having multiple accessories hit the same status endpoint, so the on state can be more than just 1 or 0. The issue seems to be that it's still calling parseInt on the response body even though the status_on and status_off variables are set in the config file. This if (this.status_on && this.status_off) is not resulting in a true statement. I'll see if I can find the logs on the homebridge github.

JonnyBoy333 commented 7 years ago

So in order to make the custom statuses work I had to modify the statusemitter function to also use the custom status like this:

statusemitter.on("statuspoll", function(data) {
            var binaryState;
            that.log('Data', data);
            if (that.status_on && that.status_off) {    //Check if custom status checks are set
                        var customStatusOn = that.status_on;
                        var customStatusOff = that.status_off;
                        var statusOn = data.includes(customStatusOn);
                        var statusOff = data.includes(customStatusOff);
                        that.log('Status On', statusOn);
                        if (statusOn || statusOff) {                //check if one of the custum status was true
                                if (statusOn) binaryState = 1;
                                if (statusOff) binaryState = 0;
                        }
                } else {
                        binaryState = parseInt(data.replace(/\D/g,""));
                }
...

I'm not sure if this was omitted intentionally but without it the custom statuses don't work.

NovaGL commented 7 years ago

Hi, can you do a pull request so its fixed for others and I'll merge it

JonnyBoy333 commented 7 years ago

@NovaGL Alright well I modified the file a decent amount (there were a lot of formatting inconsistencies that I couldn't help but fix). I also added a second feature on my fork that allows for a user to specify not only text as a value for status_on but also a JSON object.

I'm my use case I'm controlling speakers that have many more properties than just "ON" or "OFF" and I need to check multiple things to see if the speaker is in what I would consider an "ON" state. To do this I put an object in for the value of the status_on config property and then when my speaker sends a JSON response in the getPowerState function it checks whether the config properties match.

I'll submit a PR so you can take a look and see if it's something you like. The readme is updated with instructions and examples.

NovaGL commented 7 years ago

As long as you can still do it the old way then its fine

JonnyBoy333 commented 7 years ago

Yeah, either way works. If the value starts with a "{" than it assumes it's a JSON object, otherwise it uses the old way.