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.

setState and context

See original GitHub issue

Hi, I need some help, as I am a bit confused. I developed a lock plugin some time ago and it always worked. For some days now, I need to add a new feature and stumble about the “context” that is passed to the setState function.

I have two lock services and they need to be in sync with its open state. So in the setState function I do something like the following:

function(homeKitState, callback, context) {
	...
	var myLockActionCallback = function() {
		//update lock service A
		this.lockServiceA.getCharacteristic(Characteristic.LockTargetState).updateValue(newHomeKitStateTarget, undefined, null);
		this.lockServiceA.getCharacteristic(Characteristic.LockCurrentState).updateValue(newHomeKitStateCurrent, undefined, null);
		
		//update lock service B
		this.lockServiceB.getCharacteristic(Characteristic.LockTargetState).updateValue(newHomeKitStateTarget, undefined, "myContextString");
		this.lockServiceB.getCharacteristic(Characteristic.LockCurrentState).updateValue(newHomeKitStateCurrent, undefined, "myContextString");
		
		callback(...);
	}
	...
	if(context === "myContextString") {
		//only call callback as characteristic already has corret state
		callback(...);
	}
	else {
		execLockAction(..., myLockActionCallback);
	}
	...
}

I once used the “context” like this, as the “setState” function gets called for “lockServiceB”,too. Otherwise it would also call execLockAction for “lockServiceB”. Now the problem is, that today I dont receive a string as “context” in setState method but some object like this:

{ 
  request: [Function: bound ],                                                      
  encrypt: [Function: bound ],                                                                    
  decrypt: [Function: bound ],                                                                    
  close: [Function: bound ],                                                                      
  keepalive: true,                                                                                
  '86.10': true
  ...
}

What am I doing wrong? Did something change and I missed the migration?

Thanks

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
Superegcommented, Oct 5, 2019

I will try to test this setup without a homebridge instance only using hap-nodejs instance from my fork. There are some changes which adds support to the latest protocol version v1.1.0. In this version HomeKit seems to send a /prepare request first before it sends the actual update request for a lock service. I’m curious how this might affect anything.

1reaction
Superegcommented, Oct 5, 2019

Okay so I tested some stuff and can only validate this issue. I did some modifications to your plugin (only the lock accessory). It is now more readable and straightforward in my opinion and is restricted to the relevant parts (https://github.com/Supereg/homebridge-lock-test).

Here the a log output with HAP-NodeJS debug messages:

  EventedHTTPServer [::ffff:192.168.178.70] HTTP request: /characteristics +7s
  HAPServer [AC:72:E6:6D:1D:83] HAP Request: PUT /characteristics +0ms
  Accessory [Testbridge] Processing characteristic set: [{"aid":2,"iid":11,"value":0}] +0ms
  Accessory [Testbridge] Setting Characteristic "Lock Target State" to value 0 +1ms
[5.10.2019, 22:43:48] [TestLock] S E T S T A T E: service=someLockName A; SECURING=false
  EventedHTTPServer [::ffff:192.168.178.70] Muting event '2.11' notification for this connection since it originated here. +1ms        // lockA LockTargetState
  EventedHTTPServer [::ffff:192.168.178.70] Sending HTTP event '2.10' with data: {"characteristics":[{"aid":2,"iid":10,"value":0}]} +0ms        // lockA LockCurrentState
  EventedHTTPServer [::ffff:192.168.178.70] Sending HTTP event '2.15' with data: {"characteristics":[{"aid":2,"iid":15,"value":0}]} +0ms        // lockB LockTargetState
  EventedHTTPServer [::ffff:192.168.178.70] Sending HTTP event '2.14' with data: {"characteristics":[{"aid":2,"iid":14,"value":0}]} +0ms        // lockB LockCurrentState
  EventedHTTPServer [::ffff:192.168.178.70] HTTP Response is finished +1ms
  EventedHTTPServer [::ffff:192.168.178.70] Writing pending HTTP event data +0ms
  EventedHTTPServer [::ffff:192.168.178.70] HTTP request: /characteristics +375ms
  HAPServer [AC:72:E6:6D:1D:83] HAP Request: PUT /characteristics +0ms
  Accessory [Testbridge] Processing characteristic set: [{"aid":2,"iid":15,"value":0}] +0ms
  Accessory [Testbridge] Setting Characteristic "Lock Target State" to value 0 +0ms
[5.10.2019, 22:43:48] [TestLock] S E T S T A T E: service=someLockName B; SECURING=false
  EventedHTTPServer [::ffff:192.168.178.70] HTTP Response is finished +2ms

This seems to be an issue with the new grouping panel (although I can’t really confirm since I cannot validate it in the HomeKit source lol). Lock A gets switched by hand. Then a notification for lock B gets sent to the requesting iOS device (I did also tried delaying the state change for lock B, makes no difference). Every time (but only if a third lock service is attached to the same accessory) the requesting iOS sends a PUT /characteristics request for Lock B and sets the state again. This issue does also exist on the new Home App in the macOS Catalina GM. I have sadly no old devices to test this with. Also I can confirm if you initiate all steps via the device -> settings -> devices panel the second request is not sent

@KhaosT @hassankhan any ideas what’s happening here?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Managing React state with Context - remarkablemark
If your components talk to one another and lifting state becomes cumbersome, then Context is a native way to deal with your application...
Read more >
React Context - setState with onClick inside Consumer
I have implemented React Context API and I am trying to update the state defined inside the Provider via an onClick function inside...
Read more >
Context - React
Context. Context provides a way to pass data through the component tree without having to pass props down manually at every level.
Read more >
How to manage state in a React app with just Context and ...
setState in class components); useContext — This hook takes in a context object and returns whatever is passed in as a value prop...
Read more >
How to use React Context like a pro - Devtrium
React Context can be a very powerful tool, and there are several tricks to using it effectively. Several patterns can be used to...
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