Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

local_smarthome path replaced by the original smarthome path #265

Merged
merged 6 commits into from
Mar 3, 2022
Merged

local_smarthome path replaced by the original smarthome path #265

merged 6 commits into from
Mar 3, 2022

Conversation

ckhmer1
Copy link
Contributor

@ckhmer1 ckhmer1 commented Feb 23, 2022

Reading the Local fulfillment documentation I've read the sentence "No modification of your hardware is expected to integrate local fulfillment.".
In the Add local fulfillment to your smart home Action documentation the SYNC response custom data contains the authToken.
Why don't use the authToken field to deliver the access token and use the original smart-home path?
In this way, we have no authenticated path where everyone can send commands to the smart home.

I've added auth token for the local request, this token is updated every time a sync request is received.

Unfortunately, I'm not able to test it completely, because I'm still not able to make the local execution work.
Is someone able to test it?

Thanks

@FireWizard52
Copy link
Contributor

Hello @ckhmer1

Unfortunately, I'm not able to test it completely, because I'm still not able to make the local execution work.
Is someone able to test it?

Of course I want to help you .

Can you exactly explain, what has to be done and which test you would like to see?

One other thing.
If you look into the documentation and specifically the second link, you will see under:
Set up the scan config information

Screenshot_scan_information

@rockstar2020 mentioned this in his post today in topic #258

A Name is required and currently it is not in the documentation and I do not use it.
Will that improve stability?
See: https://www.home-assistant.io/integrations/google_assistant/#enable-local-fulfillment
See: point 4.4

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 23, 2022

Hello @FireWizard52,
Thanks for your help.
You have to apply the fix, upload the new app.js, restart Node-RED and Google device and see if it is working

Regarding the name in the mDNS config, in my opinion we should add also it in both places, in the Google configuration as well as in the Node-RED configuration, together with the service name.
I don't want to do all changes once, but introduced them gradually, also because I'm not able to test it, but my Node-RED is inside a container.

@FireWizard52
Copy link
Contributor

@ckhmer1,

I can apply the fix. Is #265 sufficient? I do not see a new app,js.

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 24, 2022

If You check in the commits, there are changes for the App.js. The new app version is 2.1.

@FireWizard52
Copy link
Contributor

Hello @ckhmer1

Thanks, I noticed it, by inspecting

I tried to patch, but got errors.
I did the following:

cd .node-red/node_modules/node-red-contrib-google-smarthome wget https://github.com/mikejac/node-red-contrib-google-smarthome/pull/265.diff git apply 265.diff

I did this before as indicated by Paul Reed (#128)

I got:

265.diff:486: trailing whitespace. httpPath, httpPort, httpLocalPort, nodeRedUsesHttps, ssloffload, publicKey, privateKey, jwtkey, clientid, 265.diff:536: trailing whitespace. // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled. 265.diff:541: trailing whitespace. this.app.use(helmet({ 265.diff:603: trailing whitespace. // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled. 265.diff:668: trailing whitespace. // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled. error: patch failed: README.md:330 error: README.md: patch does not apply error: patch failed: lib/HttpActions.js:38 error: lib/HttpActions.js: patch does not apply error: patch failed: lib/SmartHome.js:326 error: lib/SmartHome.js: patch does not apply
What did I do wrong?

Regards

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 24, 2022

Hi,
are You sure that You haven't modified some files manually?
I applied the patch manually, like You, getting only the following warning

git apply 265.diff
265.diff:486: trailing whitespace.
httpPath, httpPort, httpLocalPort, nodeRedUsesHttps, ssloffload, publicKey, privateKey, jwtkey, clientid,
265.diff:536: trailing whitespace.
// httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled.
265.diff:541: trailing whitespace.
this.app.use(helmet({
265.diff:603: trailing whitespace.
// httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled.
265.diff:668: trailing whitespace.
// httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled.
warning: 5 lines add whitespace errors.

My suggestion is to reinstall the node using:

npm uninstall node-red-contrib-google-smarthome
npm install node-red-contrib-google-smarthome

and then apply the patch.

@FireWizard52
Copy link
Contributor

hello @ckhmer1,

I previously patched with 259, but that was 13 days ago. After that I installed 0.2.10. So in my opinion it is the original 0.2.10.
If I uninstall and reinstall later, I will lose my config, which I do not like. Or do I make a mistake?

@Paul-Reed
Copy link
Contributor

If I uninstall and reinstall later, I will lose my config

No don't uninstall, just reinstall from your user directory (.node-red) and it will overwrite what you have currently installed, leaving your configuration intact, just like when you do an update.
npm install node-red-contrib-google-smarthome

@Paul-Reed
Copy link
Contributor

Paul-Reed commented Feb 24, 2022

Same as you @FireWizard52 I can't apply the patch either;

pi@raspberrypi:~/.node-red/node_modules/node-red-contrib-google-smarthome $ git apply 265.patch
265.patch:564: trailing whitespace.
        httpPath, httpPort, httpLocalPort, nodeRedUsesHttps, ssloffload, publicKey, privateKey, jwtkey, clientid,
265.patch:614: trailing whitespace.
        // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled.
265.patch:619: trailing whitespace.
                this.app.use(helmet({
265.patch:681: trailing whitespace.
        // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled.
265.patch:746: trailing whitespace.
        // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled.
error: patch failed: README.md:330
error: README.md: patch does not apply
error: patch failed: lib/HttpActions.js:38
error: lib/HttpActions.js: patch does not apply
error: patch failed: lib/SmartHome.js:326
error: lib/SmartHome.js: patch does not apply

But, it could be installed directly from Claudios repo like this;
npm install ckhmer1/node-red-contrib-google-smarthome#enhancement --save which will again overwrite what is currently installed and leave your config intact.

I'll also give it a try shortly...

@FireWizard52
Copy link
Contributor

I took the following steps:

  1. Stopped Node-RED (node-red-stop)
  2. Followed Paul's recommendation (npm install node-red-contrib-google-smarthome)
  3. Checked app.js (version 2.0) It is not necessary but to be sure. that it indicates version 2.0.
  4. Applied the patch
  5. Result:

265.diff:486: trailing whitespace. httpPath, httpPort, httpLocalPort, nodeRedUsesHttps, ssloffload, publicKey, privateKey, jwtkey, clientid, 265.diff:536: trailing whitespace. // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled. 265.diff:541: trailing whitespace. this.app.use(helmet({ 265.diff:603: trailing whitespace. // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled. 265.diff:668: trailing whitespace. // httpNodeRoot is the root url for nodes that provide HTTP endpoints. If set to false, all node-based HTTP endpoints are disabled. error: patch failed: README.md:330 error: README.md: patch does not apply error: patch failed: lib/HttpActions.js:38 error: lib/HttpActions.js: patch does not apply error: patch failed: lib/SmartHome.js:326 error: lib/SmartHome.js: patch does not apply

So it failed again.

@Paul-Reed
Copy link
Contributor

@FireWizard52 If you install it direct from @ckhmer1 repo using the command in my last post, it install fine. (but not currently working for local execution!)
NOTE: Make sure that you don't have any old redundant 'smarthome' nodes hiding in your flows, as they have now been removed from Claudio's repo (as they will be shortly in the main repo) and you will get 'missing nodes' errors, like I did!

Installed Claudio's branch, updated app.js to (v2.1), restarted node-RED, restarted all devices...

Although it is working fine with cloud execution, I'm getting a 404 error POST /local_smarthome 404 2.318 ms - 155
and also 24 Feb 17:21:37 - [error] HttpActions:httpActionsRegister(/smarthome): no accessToken found.

I'm going to leave it while, and see if it sorts itself out...

@FireWizard52
Copy link
Contributor

FireWizard52 commented Feb 24, 2022

@ckhmer1 and @Paul-Reed,

Paul

I was a few minutes behind you. Your message came in, while I was rebooting
I installed it also succesfully from @ckhmer1 's repo and indeed it installs fine and the app.js has been updated to 2.1

I had no issues with old nodes, as I already replaced these some time ago.

At the moment, when I restarted my Google Home device (Google Nest Hub) I got the following in the Node RED Debug pane:

Screenshot_Local_fulfillment_http_actions

Looking to Chrome Inspect gives me:

Screenshot_Local_fulfillment_http_actions2

So this looks very identical, as what @Paul-Reed got. Cloud execution works fine here too
I do not believe that it will sorts itself out, but will give it a try, before I reinstall 0.2.10

@FireWizard52
Copy link
Contributor

@ckhmer1 ,

Should we test again or should we wait?

@FireWizard52
Copy link
Contributor

@ckhmer1

I decided not to wait and to test your latest commit.

The result is POSITIVE.

No errors in the Node-RED Debug pane, as shown previously.

Google Chrome (Inspect Console) did not show any error and Local fulfillment is working again.

Good job! Thanks

@rockstar2020
Copy link

@FireWizard52 ,
It's great to hear that the changes worked for you.
Did you finally add any "Name" field in Google Actions Console for local fulfilment settings?
I was just following the conversations but kind of lost track of what was changed on your side.
I also like to give it a try so would appreciate if you could summarise what I need to do to implement the new changes.

Thanks

@FireWizard52
Copy link
Contributor

FireWizard52 commented Feb 25, 2022

Hello @rockstar2020,

You asked:

Did you finally add any "Name" field in Google Actions Console for local fulfillment settings?

No, I did not. So currently I do not have any name configured in the Google Actions Console.

I tried it in order to see, if it would make any difference. It did not, but at that moment I was not aware of the error in the IP Address (127.0.1.1 instead of 127.0.0.1, what it should have been)
But as Google indicates that it is required (see in this thread, 2 days ago) I mentioned it to Claudio.

He does not want to change more than one issue at the time. I fully understand that.

So I got it working as soon as I corrected the error with the IP Address in my /etc/hosts file. At that moment It was directly discovered by the mDNS Discovery app. I also found that the "/etc/hostname" should only contain the host name and NOT the domain name.
An example is shown at my last post in #128

So I got it working and I offered my support to test the new commit by Claudio.
The first version did not function correctly but the commit released this morning was okay and restored local fulfillment.

To try it, you have the install @ckhmer1 's version from his repo.

Do it as follows:

  1. Stop Node-RED > node-red-stop
  2. Go to your Node RED directory > cd .node-red (probably)
  3. Install @ckhmer1 's version > npm install ckhmer1/node-red-contrib-google-smarthome#enhancement --save
  4. Check the app.js file, located in: /home/pi/.node-red/node_modules/node-red-contrib-google-smarthome/local-execution
  5. It should indicate: `const version = '2.1'
  6. If this is okay, @ckhmer1 's version is correctly installed.
  7. Copy this app.js file to the Google actions console

Screenshot_Local_Fulfillment

  1. Start Node-RED > node-red-start
  2. Restart your Google Home devices.
  3. Test

Regards

@rockstar2020
Copy link

Thanks a lot @FireWizard52 for your detailed explanation.

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 25, 2022

Hi all,
Thanks you for trying it, I was not able to answer because I was busy with my work
I'm happy to read that it is working now.
If all confirm that it is ok, @Caprico85 may merge it.

@Paul-Reed
Copy link
Contributor

Paul-Reed commented Feb 25, 2022

@FireWizard52 @ckhmer1
I also did the same and updated over breakfast, but been out all day until now.
Initially, I din't think that local execution was working, because the entries in my node-RED log only refer to /smarthome and no mention of /local_smarthome whatsoever.
For example - POST /smarthome 200 10.126 ms - 5815
However, looking at the SH nodes, I'm getting a circle below the nodes instead of a solid, which suggests that commands are being executed locally.

My node-RED log (in debug) also suggests LE is working OK;

25 Feb 19:51:41 - [debug] SmartHome:Start(): registered routes:
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /oauth registered for get
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /oauth registered for post
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /token registered for all
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /smarthome registered for post
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /check registered for get
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /smarthome registered for options
25 Feb 19:51:41 - [debug] SmartHome:Start(listen): starting local fulfillment
25 Feb 19:51:41 - [debug] SmartHome:Start(): local registered routes:
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /smarthome registered for post
25 Feb 19:51:41 - [debug] SmartHome:Start(): url /smarthome registered for options
25 Feb 19:51:41 - [debug] SmartHome:Start(): dnssd-ad: port:8880

So not sure why my log is showing /smarthome instead of local_smarthome after a voice command??

@FireWizard52
Copy link
Contributor

@Paul-Reed,

Good, that it is working for you too.
The answer on your question is in the title of this thread, as you told me in #258

@Paul-Reed
Copy link
Contributor

The answer on your question is in the title of this thread....

AAAAAAaaaahhhh !!
Of course!
In that case, yes all good here as well

@FireWizard52
Copy link
Contributor

Dear all,

We have now more than 1 path to control the Google Home device.

  1. Local fulfillment shows a green/red circle for ON/OFF.
  2. Google cloud servers shows a green/red dot for ON/OFF,
  3. Input to the Google Device node by sending ON/OFF,

Option 3 shows also a green/red dot.

Is it an idea to use a different color, e.g. blue dot, to see the difference?
Your opinion?

@rockstar2020
Copy link

Unfortunately local fulfilment still does not work for me.
I don't get any errors in nodered but if I don't put any name field in Google Actions Console for local fulfilment I get an error like this in my chrome://inspect log window, which as it looks like it is related to authentication or something.

image

Now I understand why I don't get any errors if I put a name. I think it's because Google device is looking for the name I indicated and since there's no such name in my network it doesn't spit any errors. But if there's no name it scans the network and when it tries to authenticate it gives above errors.
At the same time as you see in the screen shot, after the errors still the IDENTIFY command works.
I soft rebooted and hard rebooted my Google devices many times but no luck yet!

@FireWizard52
Copy link
Contributor

@Paul-Reed ,

You wrote:

Is it an idea to use a different color, e.g. blue dot, to see the difference?

Wouldn't the 'blue dot' be immediately replaced by the green/red circle/dot as it was fulfilled. (ie the blue dot would only be visible for 5 or 6 milliseconds?

No, this input data is only a status update to the Google Device node. It does not activate e.g. a switch.
It only informs the node that e.g a switch has been operated, so that you can query the device.

Currently, if a switch has been operated by local fulfillment, I see the green/red circle. If, because some external automations, updates the switch, I see a green/red dot.

But is this caused by an external automation or single action or a voice command, using the Google cloud server?
I cannot see the difference

@FireWizard52
Copy link
Contributor

Hello @rockstar2020,

I looked in detail to your post and then specifically the error.
Did you notice the first line?

Screenshot_Local_fulfillment_wrong_object

It expects "nodered-google" but it got "googlecast"

Is your Google actions configuration correct and does it state nodered-google?
If so, what other applications or nodes do you use with your Google Device?

@rockstar2020
Copy link

Yes @FireWizard52 , that's why I think when I add a "Name" field it doesn't look for Google Cast devices in my network and hence it doesn't throw any errors.
Can you please check the logs in your chrome://inspect and let me know if the path indicated below is correct?
How does the Google device know what the end point IP of Node Red is?

image

@FireWizard52
Copy link
Contributor

@rockstar2020

Detailed info, you will find here: https://developers.google.com/assistant/smarthome/concepts/local

As far as I understand.

The app.js is uploaded to the Google server. During reboot of your Google Device this app is loaded into a "sandbox" on your Google device, so that it is able to communicate directly with Smart Home node in Node RED.

But If I'm wrong, please correct me.

How does the Google device know what the end point IP of Node Red is?

The Google Device runs the app.js

If you search in the app.js for "nodered-google", you will find:

if (deviceToIdentify.mdnsScanData.type != "nodered-google") { console.error(request.requestId, "Not Node Red Google Smarthome type. expected: 'nodered-google' got: '" + deviceToIdentify.mdnsScanData.type + "'"); return createResponse(request, {});

This is the error you get.

By means of mDNS (multicast DNS) the Google device will find your IP Address. (Similar as the mDNS Discovery app)

You asked also:

Can you please check the logs in your chrome://inspect and let me know if the path indicated below is correct?

Yes it is correct. See my logging below. I really think your issue is that mDNS discovers "googlecast" and not "nodered-google".

Screenshot_Local_fulfillment_check path

@rockstar2020
Copy link

Thanks @FireWizard52 , you are exactly right about how the app.js gets loaded onto the Google Device. That is also my understanding.
The thing is my device discovers both node-red and googlecast. What I get in the log is a mix of errors and correct discoveries.
But the bottomline is that I can't make local execution work.

@FireWizard52
Copy link
Contributor

@ckhmer1

I discovered 1 issue.

I updated one node in Node-RED, which had nothing to do with Smart Home (it was the Worldmap node I use for some application). Therefore I had to restart Node Red and after NR had started again, local fulfillment did not work.

Chrome inspect, shows:

Screenshot_Local_fulfillment_error2

A restart from my Google Device solved this issue.

I do not hope that every update of NR or one of its nodes, also require to restart the Google Device.

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 26, 2022

I'm not sure that it depends on this PR, I'll try to reproduce it.

@Paul-Reed
Copy link
Contributor

I've tried, but can't replicate the problem here @FireWizard52
I've just updated 5 nodes, one at a time, and after each one I've restarted node-RED, and then checked if local execution was still working.
It worked OK every time for me, although I don't use Worldmap.

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 26, 2022

Thanks @Paul-Reed for the feedback.
I've released an update allowing to refresh the Auth token this morning. Did you apply also it?

@Paul-Reed
Copy link
Contributor

I've released an update allowing to refresh the Auth token this morning. Did you apply also it?

Yes, I applied your update first.
It seems very stable now, and I now get Local Execution on every voice command.
You have done a great job 👍

@FireWizard52
Copy link
Contributor

Hello @ckhmer1,

I applied the update this morning and it functions well, as I would expect. Local fulfillment is working on all switches.

But I wonder, should it also work on sensors, thermostat and other devices? I don't see it, yet.

What is the intended functionality/use of allowing to refresh the Auth token?

@Paul-Reed ,

Thanks for your reporting, while updating some of your NR nodes. I will monitor it, but it might have been a single incident

@Paul-Reed
Copy link
Contributor

But I wonder, should it also work on sensors

Yes, I noticed that, but wondered if it is was because the sensor data is stored in the google Homegraph, and not locally, and therefore needs to be expedited via the cloud??

@FireWizard52
Copy link
Contributor

FireWizard52 commented Feb 27, 2022

Thanks for your response.

Yes, I noticed that, but wondered if it is was because the sensor data is stored in the google Homegraph, and not locally, and therefore needs to be expedited via the cloud?

If that is the case, then it is normal, that I see as status indicator a dot and not a circle under the device.

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 27, 2022

Hello @ckhmer1,

I applied the update this morning and it functions well, as I would expect. Local fulfillment is working on all switches.

But I wonder, should it also work on sensors, thermostat and other devices? I don't see it, yet.

What is the intended functionality/use of allowing to refresh the Auth token?

@Paul-Reed ,

Thanks for your reporting, while updating some of your NR nodes. I will monitor it, but it might have been a single incident

The local fulfillment is in the common code, it should work for every device except the one configured with the second authentication, of I remember well.

The refresh token is for increase security, updating the token as soon as possible.

@FireWizard52
Copy link
Contributor

#Thanks Claudio, @ckhmer1 for your explanation.

The local fulfillment is in the common code, it should work for every device except the one configured with the second authentication, of I remember well.

This makes it more interesting, if you were be able to see the difference between "Cloud fulfillment" and the input from an external source.

The refresh token is for increase security, updating the token as soon as possible.

Is a user action required? E.g. do we have to create a flow for it?

Thanks for all your efforts. Great job.

Regards

@Paul-Reed
Copy link
Contributor

Paul-Reed commented Feb 27, 2022

it should work for every device except the one configured with the second authentication

I've just asked for a sensor temperature reading, and found the node-RED log entry, which suggests that it was in fact executed locally (despite the node only showing a dot, and not a ring).

27 Feb 16:51:05 - [debug] HttpActions:httpActionsRegister(/smarthome): user: local execution
27 Feb 16:51:05 - [debug] HttpActions:httpActionsRegister(/smarthome): QUERY
27 Feb 16:51:05 - [debug] HttpActions:_query()
27 Feb 16:51:05 - [debug] Device:getStates(): deviceIds = ["a683a0adb382ed0d"]
27 Feb 16:51:05 - [debug] Device:getStates(with-deviceIds): deviceId = "a683a0adb382ed0d"
27 Feb 16:51:05 - [debug] Device:getStates(with-deviceIds): states[deviceId] = {"online":true,"temperatureAmbientCelsius":10}
27 Feb 16:51:05 - [debug] HttpActions:_query(): deviceStates = {"requestId":"9808763051778319889","payload":{"devices":{"a683a0adb382ed0d":{"online":true,"temperatureAmbientCelsius":10}}}}
POST /smarthome 200 6.816 ms - 125

@ckhmer1
Copy link
Contributor Author

ckhmer1 commented Feb 27, 2022

Do you think having the info that a request is coming from a local fulfillment in the output message is useful?

You don't need a flow for refreshing the Auth code, is all in the common code.

@FireWizard52
Copy link
Contributor

@ckhmer1,

Do you think having the info that a request is coming from a local fulfillment in the output message is useful?

For me it is okay, as it is today.
A status indication under the device node.

Is it useful to have that info also in the output message?
I don't think I will use it, but perhaps others.
I have to think about an useful application.

It would be nice if e.g. the sensor node also can indicate that the query has been fulfilled locally.
Today, as @Paul-Reed says, it is a dot and not a ring.
This would indicate that it was "cloud fulfillment", which
wasn' t. Was it overruled, because data has been received at the input?

@Paul-Reed
Copy link
Contributor

Paul-Reed commented Feb 27, 2022

Was it overruled, because data has been received at the input?

No, the sensor node only receives an input every 10 minutes, and that did not coincide with the query.

@Caprico85 Caprico85 merged commit 49541fd into mikejac:master Mar 3, 2022
@Caprico85
Copy link
Collaborator

Finally had the time to test it. For me, local fulfillment works too with Claudio's changes. Therefore merged! Thank you!

I think the problem with the sensor node is because the status icon is only set on EXEC requests. EXEC requests only happen when Google sends a new state value for a device. Asking for the sensor sends a QUERY request instead. QUERY only asks for the current state, but it does not set a new state. Without a change to the state of a device, there was no need to alter the status icon and text (at least before local fulfillment was implemented). So the device nodes simply keep their old icon (which usually is the filled circle they got when you injected a value). To show a ring icon for sensors, we would have to update the status icon on QUERY requests too (PRs welcome!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants