sean9keenan / homebridge-bigAssFans

A Homebridge plugin for Big Ass Fans
MIT License
28 stars 15 forks source link

Service.OccupancySensor #3

Open pedroserano opened 8 years ago

pedroserano commented 8 years ago

I'm thinking a good feature enhancement, given recent trigger support for sensors in iOS, would be to add the Haiku occupancy sensor as it's own service with Service.OccupancySensor. I will play with this when I have a chance, but thoughts?

sean9keenan commented 8 years ago

That's a good idea! I tried to get it working on this line: https://github.com/sean9keenan/homebridge-bigAssFans/blob/master/index.js#L166

You can comment it in - but I remember for some reason it wasn't working as expected :/

My first priority is to get issues #1 and #2 fixed, but I still haven't gotten to them

pedroserano commented 8 years ago

Yes definitely low priority compared to other issues. After looking at it briefly it may have to do with the OccupancySensor Service being a read-only characteristic creating an error when using the function that both reads and sets values? I will try to investigate more.

sean9keenan commented 8 years ago

Haha, well it's really only one other issue πŸ˜… .

I don't think that it being read only is the issue here - but maybe. Here you can see that it won't bind the setter method unless setOutputMapping is non-null and here we make it null. So... Not sure πŸ˜„

Thanks for willing to help out on this!

pedroserano commented 8 years ago

I forked this homebridge plugin and got it to accurately reflect occupancy status when homebridge starts up, but it still has some issue I don't quite follow with accurately updating sensor status.

Any help is greatly appreciated.

To get this to run, I had to break out the motion sensor portion of the Haiku fan in the BigAssApi.js lines 267-271: ...

    this.motion = new BigAssProperty('motion', this);
    this.motion.createGetField('isOccupied', ['SNSROCC', 'STATUS'], true, undefined, 'OCCUPIED', 'UNOCCUPIED');
    this.motion.createGetField('minTimeout', ['SNSROCC', 'TIMEOUT'], true, 'MIN'); // Seconds (ie 3600000 is 60 min)
    this.motion.createGetField('maxTimeout', ['SNSROCC', 'TIMEOUT'], true, 'MAX'); // Seconds
    this.motion.createGetField('timeout', ['SNSROCC', 'TIMEOUT'], true, 'CURR');   // Seconds

    this.sensor = new BigAssProperty('sensor', this);
    this.sensor = new BigAssProperty('smartmode', this);

...

pedroserano commented 8 years ago

Update, I was able to get it to query for updates using an occupancySetWrapper function.

I'm still only getting a value of 'Occupancy Detected' returned to me in homekit, even when no one is in the room and I set the occupancy timeout on the fan to 1 minute.

pedroserano commented 7 years ago

@sean9keenan I just realized something. When I telnet into both the fan and wall controller, the wall controller is the device that is actually reporting occupancy, not the fan. This makes sense because on the L series the wall controller is the device with the motion sensor, not the fan (my understanding is the other series may have an onboard motion sensor?). This is what the wall controller is outputting in response to motion or after it timeout period: (Wall Control;SNSROCC;STATUS;OCCUPIED) or (Wall Control;SNSROCC;STATUS;UNOCCUPIED).

If I'm not mistaken currently the API code is skipping any and all wall controllers. Would you have time to help me add code for the wall controller to be added as a BigAssFan device in the plugin and assign it the motion sensor functions?

pedroserano commented 7 years ago

@sean9keenan Sorry ignore that last comment, but I finally figured it out and it is now working!!!

It requires accepting pull request #13 in homebridge-bigAssFans and accepting pull request 8 in the BigAssAPI.

pedroserano commented 7 years ago

Before accepting the homebridge plugin pull request, can you let me know if the occupancy sensor in the homebridge plugin is updating properly?

Mine is not, but I worry it's deeper than the homebridge plugin. I tested by opening one terminal and using telnet to monitor my fan's updates directly. A second terminal window is running a modified version of the simple example in the BigAssAPI examples to only read and output isOccupied, and registers a callback update for isOccupied, but when I watch the telnet update the occupancy status, the simple example does not update. Here is the code for the modified simple example:

var bigAssApi = require("../BigAssApi");
var myMaster = new bigAssApi.FanMaster(1); // Expect only one fan in my setup
myMaster.onFanFullyUpdated = function(myBigAss){
console.log("Initial Big Ass Motion value: " + myBigAss.sensor.isOccupied);
// Register for an update callback (say if the phone updates the property)
myBigAss.sensor.registerUpdateCallback("isOccupied", function (newValue) {
    console.log("Updated motion value: " + myBigAss.sensor.isOccupied); // or newValue
});
myBigAss.sensor.update("isOccupied");  // Forces an update to motion
};
sean9keenan commented 7 years ago

Sorry that I've been MIA from this repo - I feel a bit bad πŸ˜….

Thanks for the sample code - I pulled your repo and confirmed that it works (at least that it can read the occupancy sensor), and that the update callback doesn't get called when motion status changes. It's possible that the fan just doesn't broadcast whenever motions "stops" being detected. And in fact might only tell you that motion was detected if some other status changes as well (like the light turning on). One way to kind of solve this would be to poll it, but that would require a bit more code somewhere.

pedroserano commented 7 years ago

Sorry about the multiple changes in the pull requests - I'm a git n00b so I will try to clean that up this evening.

The good news regarding updates is the fan itself broadcasts any updates on occupancy status - but the bad news is it doesn't get picked up by the plugin - it seems like the home bridge plugin is not listening for it. I think you're spot on that the plugin just needs a bit of code to do some kind of polling - long polling? websocket?

I'm afraid I'm at the limits of my knowledge on this. Do you know if this could be easily done?

sean9keenan commented 7 years ago

No worries! Please let me know if my suggestions on how to rebase make sense - this is a great chance to learn how to become better at git!

The easiest way to get updates on the occupancy status would be to update the BigAssAPI to support it, as long as we are given some trigger whenever the status changes. Because then whenever that trigger happens - if it doesn't contain the new occupancy status already - we can immediately check "what is the occupancy status".

Otherwise if we can't rely on the fan on to broadcast anything on occupancy changes the best we can do is just regular ol' polling, and by that I mean just asking the fan every X seconds "do you have any update?" (we would want to use long polling or websockets if the fan supported it - but those don't apply here as far as I know unfortunately)

pedroserano commented 7 years ago

The occupancy sensor status does get broadcast by the fan as soon as the timeout period elapses, like this:

(Haiku Fan;SNSROCC;STATUS;UNOCCUPIED)

So doesn't BigAssAPI listen for an update with this.registerUpdateCallback?

In the homekit plugin it seems like the property registers an update callback (in code block) when the getOutputMapping is invoked with the setCharacteristicOnService(this.occupancyService, Characteristic.OccupancyDetected, "sensor", "isOccupied", occupancyGetWrapper, null)

  // Register for updates outside of the homekit system
  this.myBigAss[propertyToWrap].registerUpdateCallback(subProperty, function(newValue) {
    if (thisChar.emit) {
      // Emit this change to the homekit system
      // oldValue : Grabs the old cached value for this characterisitic
      // newValue : The value we just recieved
      // context  : Gives context so that whoever requested the update doesn't recieve it.
      //            In this case we need everyone to get the update
      thisChar.emit('change', { 
          oldValue:thisChar.value, 
          newValue:getOutputMapping(newValue), 
          context:null });
    }
  });
djfatal commented 7 years ago

So Occupancy Sensor doesn't work yet? Is there a way to leave it out when adding devices until it is working?

pponce commented 7 years ago

@pedroserano @sean9keenan Do we know what seems to be the issue with the occupancy sensor?

pedroserano commented 7 years ago

Yes we need a function for long polling the occupancy sensor. It is a quick fix but hoping @sean9keenan might have a quick minute to add - I'm afraid if I try it will not be very elegant.

djfatal commented 7 years ago

Being hopeful that this is still being worked on. Good news is BigAssFans looks to be bringing support for HomeKit in the near future. Hoping it will work with existing fans when it does come around.

pponce commented 6 years ago

me too. even if BigAssFans brings support for the fan functions i bet the occupancy sensor and switches won't get much love. which would make this plugin still useful.

brandonlevasseur commented 6 years ago

@djfatal I second that. I'm hoping to use these sensors for other things as triggers rather buy other sensors.

djfatal commented 6 years ago

I thought @pedroserano had a reply. I was just looking for it but don't see it. Have you figured it out? Can't wait to give it a try.

pponce commented 6 years ago

I thought so too. Would be awesome to have the sensors working.

pponce commented 6 years ago

@pedroserano i tried changing this line in the code: occupancyGetWrapper, null)

to

boolGetWrapper, null)

But that did not seem to work for me. Occupancy seems to always be "not occupied" and never changes. Before it was always triggered.

Was that the only change you made?

pedroserano commented 6 years ago

I have no idea, hoping @sean9keenan can help solve this. It seems so close to a solution, but maybe not.

pponce commented 6 years ago

@djfatal and I thought you had figured it out when we got the recent note about not needing a special getWrapper function for it. Oh well. Hope @sean9keenan can take a look some time.

djfatal commented 6 years ago

I'm not sure what it is lately. I've been losing the light control and the only way to get it back for me is to delete cache and persist then reboot.

davidvanvo commented 6 years ago

@djfatal curious, are your lights and fans still accessible through the haiku app? mine has been spotty on the app too so i assumed it was the haiku and not homebridge.

djfatal commented 6 years ago

@davidvanvo The Haiku app's been working fine for me. Maybe a bit of a longer delay than before since when I launch the app my fan shows as "no response". But once the app shows my fan connected then I have control.

pponce commented 6 years ago

No issues for me. All seems to be working fine with latest updates to the fan and latest app. both in app and via homebridge/homekit. Still hoping @sean9keenan will have time some day to look into the occupancy sensors issue.

mriksman commented 6 years ago

I have an L-series, with WiFi module but WITHOUT Wall Control. Is my assumption that the Wall Control has the motion sensor and NOT the fan correct? My Homebridge has created an Occupancy Sensor, but it is always showing triggered. I'm pretty sure the fan itself doesn't have an Occupancy Sensor...?

davidvanvo commented 6 years ago

@mriksman the Occupancy Sensor doesn't even work right now and will always show triggered. I too have a a fan without a wall controller and everything works fine. Ideally, the Occupancy Sensor should not be exposed, but its there and should not effect your Fan use.

dsully commented 5 years ago

It appears this project is abandoned given the lack of response from the author. That said, if he’s still around, +1 on getting this fixed.

veresov commented 5 years ago

The problem with the occupancy value is always true is that the occupancy value is a string, no a number. So, occupancyGetWrapper should be:

250   var occupancyGetWrapper = function(value) {
251     return (value == "OCCUPIED" ? Characteristic.OccupancyDetected.OCCUPANCY_DETECTED : Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED)
252   }

No how the updates should work? Does the fan send the notification or should we poll it?

veresov commented 5 years ago

To answer my question.. We have to poll it, I don't see any packets from the fan. The problem actually is not only with the sensor, but with any property. If updated by the fan's schedule, or the phone app we will not notice it unless we update it.

veresov commented 5 years ago

I have it kind of working here if people are interested: https://github.com/veresov/homebridge-bigAssFans/commit/623370d8da7bc6836935ef5c01cdcdb381853480

barkmadley commented 4 years ago

Wish I had read this full thread before going on my debugging adventure https://github.com/sean9keenan/homebridge-bigAssFans/pull/32

@veresov Is the polling still required? It might be good to restrict the polling to only the sensor unless there is a reason to poll everything?

veresov commented 4 years ago

If you look at the last commit in my fork, I ended up with different polling intervals for the sensor state and the rest of the state. The fans are a bit weird when it comes to the sensor though. I think if you're in the night mode, the sensor is always "occupied". Another problem is that turning the light on/off may trigger the sensor to on forcing the automation into a feedback loop. Anyways, I ended up using sensors from the ecobee thermostats that I have to drive my automations.