question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[PLUGIN DEVELOPMENT] Centralising HTTP plugins

See original GitHub issue

Hi there,

As the title suggests, I am currently in the process of working on some ‘HTTP type’ plugins for homebridge. More specifically, I’ve recently done a fair bit of work on the homebridge-thermostat plugin attempting to streamline it. However, I’ve run into an issue which stretches a bit further than my JavaScipt knowledge, despite all my attempts!

Here is a snippet of example code taken from the original index.js:

  _httpRequest: function (url, body, method, callback) {
      request({
          url: url,
          body: body,
          method: this.http_method,
          timeout: this.timeout,
          rejectUnauthorized: false,
          auth: this.auth
      },
          function (error, response, body) {
              callback(error, response, body);
          });
  },
  
  getTargetTemperature: function(callback) {
    this.log("[+] getTargetTemperature from:", this.apiroute+"/status");
    var url = this.apiroute+"/status";
    this._httpRequest(url, '', 'GET', function (error, response, responseBody) {
        if (error) {
          this.log("[!] Error getting targetTemperature: %s", error.message);
  	  callback(error);
        } else {
  	  var json = JSON.parse(responseBody);
  	  this.targetTemperature = parseFloat(json.targetTemperature);
  	  this.log("[*] targetTemperature: %s", this.targetTemperature);
  	  callback(null, this.targetTemperature);
        }
    }.bind(this));
  },

  setTargetTemperature: function(value, callback) {
    this.log("[+] setTargetTemperature from %s to %s", this.targetTemperature, value);
    var url = this.apiroute+"/targetTemperature/"+value;
    this._httpRequest(url, '', 'GET', function (error, response, responseBody) {
        if (error) {
          this.log("[!] Error setting targetTemperature", error.message);
  	  callback(error);
        } else {
          this.log("[*] Sucessfully set targetTemperature to %s", value);
  	  callback();
        }
    }.bind(this));
  },

As you can see, for the sake of simplicity, I have removed numerous get and set functions but have kept two (getTargetTemperature and setTargetTemperature) for the sake of illustrating my point.

To summarise the what happens with the Thermostat: When the state is refreshed (by opening the Home app), numerous (4-6) get functions are called, all of which contact the HTTP device simultaneously and attempt to retrieve the same JSON (containing data like the target temperature, current state etc.), they then proceed to extract just 1 field each; meaning that whilst the JSON only needs to be retrieved once, it is retrieved multiple times, which is extremely wasteful and can cause Homebridge to hang while this takes place. It is also worth noting that the set functions are not an issue because they are only called individually once you update a field like the target temperature.

I have tried seeking a solution to the issue. My first thought was creating a centralised function called something like _getStatuses which would be called by each of the get functions. If it was being called for the first time in a while, it would request the JSON once, parse each of the fields and store them ready for the other incoming requests, reducing the number of requests greatly.

However, the problem is that I have tried multiple approaches to this problem and none of them have worked to a satisfactory level for a variety of reasons, including the fact that JavaScript is asynchronous and makes it hard to work step-by-step. Thus, I am hoping that someone may have an idea or solution which will solve the problem. I would be really grateful if someone could provide an idea, some sample code or a pre-existing plugin which relates to the issue.

Thank you in advance for your help,

Kind regards, Tom

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:23 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
NorthernMan54commented, Dec 10, 2019

My rant against .on(‘get’

  1. Using .on(‘get’ causes the home app to behave slow on loading, as homebridge needs to get current status from the device, rather than using the cached value.

  2. Using automations with .on(‘get’ will not work as the status is not updated in real time, and only update when looking at the page in the home app

  3. Device status does not change in real time when viewing in the home app, a change in room is required to update the status

On Dec 10, 2019, at 9:26 AM, graanco notifications@github.com wrote:

I see you had the same issue as I am having… And I see that you decide to do a interval poll instead of using .on(‘get’. The reason why I am going after on get is I don’t want to use the polling (which does work). I would rather have the system only call when the user does. I this the wrong thought? And if I do it with on get instead of polling will this cause an issue with automation services with Homekit.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

1reaction
NorthernMan54commented, Feb 22, 2019

@ebaauw Tks for your input on this and if you want to take a look at the final result take a look at this

https://github.com/Tommrodrigues/homebridge-web-thermostat

In the final design, we went with a 1 minute polling loop, removed all .on(‘get’ and used updateValue for everything

Read more comments on GitHub >

github_iconTop Results From Across the Web

[PLUGIN DEVELOPMENT] Centralising HTTP plugins #2160
Hi there, As the title suggests, I am currently in the process of working on some 'HTTP type' plugins for homebridge.
Read more >
Tools and Plugins Enhancing Front-end Development - Medium
Tools and Plugins Enhancing Front-end Development · Gulp · Git · SVG Sprite · Fastclick · Hammer JS · jQuery Validation · jQuery...
Read more >
Introduction to Plugin Development
Welcome to the Plugin Developer Handbook. ... WordPress plugins can be as simple or as complicated as you need them to be, depending...
Read more >
Centralized Authentication with Apache APISIX Plugins
Apache APISIX basic-auth plugin is an authentication plugin that works with the consumer object. In the context of an HTTP transaction, ...
Read more >
WordPress Plugin Development [closed] - Stack Overflow
Reading through other developer's plugins is also a good way to learn, as you can see how ... http://codex.wordpress.org/Plugin_API#Filters.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found