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

Cannot setOn with POST #21

Open
skytoastar opened this issue Apr 27, 2020 · 4 comments
Open

Cannot setOn with POST #21

skytoastar opened this issue Apr 27, 2020 · 4 comments

Comments

@skytoastar
Copy link

I have a "light bulb" I'm hoping to control through Homebridge. It's an ESP8266 running a basic web server to control a light strip. It's running code found in this project. It exposes URLs to POST data to to be able to control it.

I can control it from the ESP8266's built-in web app. I can even control it from this basic python script running on my computer:

import requests
url = "http://10.54.236.84/power"
data = {'value':1}  # 1:on, 0:off
r = requests.post(url = url, data = data) 

For the life of me I can't seem to find the right mapping value to get it to work from this plugin. I stepped through the python code to see the body of the request is 'value=1'. I've tried the following:

"setOn": {
    "url" : "http://10.54.236.84/power",
    "httpMethod" : "POST",
    "body" : "{value}",
    "mappers": [{
        "type": "static",
        "parameters": {
            "mapping": {
                "true": {"value":"1"},
                "false": {"value":"0"}
            }
        }
    }]
}
"setOn": {
    "url" : "http://10.54.236.84/power",
    "httpMethod" : "POST",
    "body" : "{value}",
    "mappers": [{
        "type": "static",
        "parameters": {
            "mapping": {
                "true": "1",
                "false": "0"
            }
        }
    }]
}
"setOn": {
    "url" : "http://10.54.236.84/power",
    "httpMethod" : "POST",
    "body" : "{value}",
    "mappers": [{
        "type": "static",
        "parameters": {
            "mapping": {
                "true": "value=1",
                "false": "value=0"
            }
        }
    }]
}

I added some debugging prints to index.js to know that the mapping is actually working and adding the mapped value to body before calling httpRequest.

But none successfully turn the light on. Also unusual is that when the light actually is on, whatever mapping value I send to turn it off will turn it off. I just can't turn it on.

@staromeste
Copy link
Owner

staromeste commented Apr 28, 2020 via email

@staromeste
Copy link
Owner

staromeste commented Apr 28, 2020 via email

@skytoastar
Copy link
Author

Neither of the above worked.

So I decided to compare payloads using Wireshark and I found that I could correctly construct the 7-byte payload using Python or this plugin. Those seven bytes are 'value=1'. But only in the python case did it turn the light on. The python-sent payload was specifying the payload as a form of type application/x-www-form-urlencoded whereas the plugin was not.

So I hacked this into the index.js file of this plugin to make request send the data as form data:

    httpRequest : function(url, body, httpMethod, callback) {
        if (httpMethod == 'POST')
        {
            this.debugLog("entering POST");
            request.post({url: url,
                          form: {'value':body}}, // hard coded key of 'value' :(
                         function(error, response, body) {
                             callback(error, response, body)
                         });
        }
        else
        {
        // rest of the original httpRequest body
        }

Then I used the following for "setOn" in the config file:

"setOn": {
    "url" : "http://10.54.236.84/power",
    "httpMethod" : "POST",
    "body" : "{value}",
    "mappers": [{
        "type": "static",
        "parameters": {
            "mapping": {
                "true": "1",
                "false": "0"
            }
        }
    }]
}

And it worked!

That being said, my code probably isn't the right way to specify form key/val pairs in the config file given my hard-coded key.

@shanemcw
Copy link

shanemcw commented Apr 6, 2021

@skytoastar I had a similar issue using non-form POST, as outlined here with PHP as an example:

If you want to receive application/json post data in your script you can not use $_POST. $_POST does only handle form data.
Read from php://input instead. You can use fopen or file_get_contents.

Example:

<?php
// Get the JSON contents
$json = file_get_contents('php://input');

// decode the json data
$data = json_decode($json);
?>

which would explain your success with your "form" code.

I solved it by the above technique (reading the received POST raw and decoding manually) that works with non-form POST (I am able to as I am author of the code that gets and processes the received POST).

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

No branches or pull requests

3 participants