5

I am trying to modify the homebridge-wink3 code to add a variable so I can track the state in. I have 5 shades in my house, so each instance of the variable needs to be unique.

In the shade.js file, it has;

exports.default = ({ Characteristic, Service }) => {
  return {
    type: "shade",
    group: "shades",
    services: [{
      service: Service.WindowCovering,
      characteristics: [{
        characteristic: Characteristic.TargetPosition,
        get: (state, desired_state) => desired_state.position * 100,

I'd like to change the get (and set elsewhere in the code) so it uses a local variable lastState to track state.

    get: (state, desired_state) => { 
                if (desired_state.position != null) {
                        lastState = desired_state.position * 100;
                }
                else if (lastState != undefined) {
                        desired_state.position = lastState / 100;
                }
                return lastState;

I've spent hours trying to work out how to have the code maintain individual variables per shade (object instance), but they always seem to be sharing the same instance of the lastState variable.

What do I need to do here?

See https://github.com/sibartlett/homebridge-wink3/blob/master/src/devices/shade.js for the code.

4
  • Where do you have defined the lastState variable? Commented Nov 2, 2017 at 9:45
  • @JorgeFuentesGonzález Nowhere yet. That is what my question is asking. Where and how do I declare it? The code is written in ES7, and the original exports.default appears to return a bunch of parameters (type, group, services[]). I need to have the get parameter/function have access to a local variable (in my example; lastState) that can be set by the set parameter/function. Commented Nov 2, 2017 at 16:38
  • 1
    I'm not a homebridge-wink3 user, but I would do my best to help. The problem is that I don't know what have you tried so far and I don't want to waste time trying to do the same thing you have tried for hours. My thinking about this is usually what the rest of StackOverflow members thinks, so, what have you tried so far? Commented Nov 2, 2017 at 19:17
  • When I declare lastState outside of exports.default it appears all of the devices (or 'objects' for want of a better word) use the same variable. I need each object to point to a unique instance of lastState and be able to reference that within the exports.default return statement. Perhaps take a look at the code - specifically that file I linked to. Consider what you would do if you needed to add a local variable to the get and set statements, that was unique to each device/object created. Commented Nov 3, 2017 at 6:44

2 Answers 2

1

Important: What I understand to your question is that you want to clone an object (lastState or the object with the get and set method).

Suppose I have an object A like this:

var A = {
      aVariable: "Panem et circencem",
      aMethod: function () {
        return (["Veni", "vidi", "vici"]);
      }
    };

Now, suppose that I want to clone the object A to an object B.

function clone(obj) {
  if (null == obj || "object" != typeof obj) return obj;
  var copy = obj.constructor();
  for (var attr in obj) {
    if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
  }
  return copy;
}

var B = clone(A);

This is a sample example:

    
var A = {
  aVariable: "Panem et circencem",
  aMethod: function () {
    return (["Veni", "vidi", "vici"]);
  }
};
function clone(obj) {
  if (null == obj || "object" != typeof obj) return obj;
  var copy = obj.constructor();
  for (var attr in obj) {
    if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
  }
  return copy;
}

var B = clone(A);
B.aVariable = "Ad gloriam";
console.log(B);
console.log (A);

Then, you can clone/copy all your object in order to have some distinctives properties in your objects or clone the lastState in your code. I do not understood this part of your question, excuse me.

Note: this question try to answer the question. If I do not understood the question, please tell me a comment.

Also notice: If I do not answer the question, your are free to use the code poste above and copy my post in order to answer the question.

Likewise note: If you have a question, tell me a comment.

Sign up to request clarification or add additional context in comments.

4 Comments

I don't want to clone. The issue is the use of exports.default (I think). Your code looks like commonJS (??) which might not directly tie in to this ES7 code. The best thing to do, in order to answer the question, is to open the link I have listed in my question. You should be able to work out what is calling this shade.js file, how the object/module/device is instantiated and then how I would track state in a local variable (lastState) for each of these instantiated objects.
The exports.default means it is a function. The function (shown in my question) is simply a return function that returns a list of parameters. In ES6, and in this function, how can I add a variable that will persist for the life of the object/module/device?
@mriksman, What do you mean by persist for the life of the object?
I worry that my attempts at creating the lastState variable isn't working because it is being created when the module loads, but then is somehow being trashed. The variable should exist as long as the device/object exists (I have 5 'shade' devices in my house, so the code will load 5 of these objects/modules). Some attempts appear to have all or some of these devices sharing the lastState variable (if I open one shade, another shade reports as open; so somehow my attempt has them sharing lastState). I am not familiar with ES6 or ES7 - only the old style of JS.
1

You can declare lastState just above the return statement,

let lastState;
return {
  type: "shade",
  group: "shades",

or above the export statement,

let lastState;
export default ({ Characteristic, Service }) => {

if you declare lastState in the same scope as where you create the 5 instances then they will all share the same lastState.

3 Comments

The first one depends a lot on how homebridge-wink3 works. Maybe it runs the export one time and then cache the return, sharing the same scope all the time. Also, the second one will share the same scope for sure, as the code is ran only 1 time in node.js, and then the export is cached, so what is outside the export is the same scope for everything inside the export.
I'm sure a quick look at the code on github from someone who understands 'scopes' and ES6 and ES7 and ... would be able to quickly determine the issue. My skill-set simply isn't up to scratch with this export and scope stuff. I was barely capable with commonJS, but this is all new to me...
Did you try the suggested answer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.