Agent, PHP resquest

Hi,
I wont got into much detail about the code of my device, but here the idea

Here are what i'm trying to do:

1 - Device reboot
2 - Device notify the agent that he need his configuration json
3 - Agent do a POST to my website
4 - my website receive the POST from the agent and dig into my DB to get the configuration for that device
5 - my website compose a json with whats in the DB and send it back to the agent
6 - my agent validate that the json is in the correct format and send it to the device

Everyone is happy.

I have a website that, when I visit it with a web browser, it does step 4-5-6
I have an device/agent that does step 1-2

I'm not able to do step 3, let say my website is : potato.com

when I use Chrome and go to Potato, the php script on Potato do what it have to doo

but how can I use the AGENT to do like if its visiting potato.com ?

Comments

  • When you go to your website using your browser, do you need to give it any other variables?
    Example: www.potato.com/?c=123

    And also give us an example of the JSON that the PHP is outputting (the config data).
  • imp command would be http.post(URL, headers, body)

    Note what "headers" you are using, for example {"Content-Type": "application/json"}.

    If you plan to use json application header then need to implement the following in your php script to read the POST data by creating an array etc. (well I found this worked for me anyway):


    if(isset($_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) {
    $_POST = array_merge($_POST, (array) json_decode( trim( file_get_contents( 'php://input')), true));

    $param1 = stripslashes($_POST[' ---- whatever your key is ----']);
    }


    Hope that helps.
  • The php code is :
    <?php
    require_once('session.php');
    require_once('functions.php');

    ?>
    <?php

    try {
    $x = $_SESSION['node'];
    $sql = "SELECT *
    FROM node_config
    WHERE node_id = '$x'
    ORDER BY script_ts DESC LIMIT 1
    ";

    $stmt = $conn->prepare($sql);
    $stmt->execute();
    $config = $stmt->fetch();

    }
    catch(PDOException $e)
    {
    echo "<br>Connection failed: " . $e->getMessage();
    }



    $data_string = json_encode($config);

    $ch = curl_init('https://agent.electricimp.com/'.$_SESSION['nodeurl']);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data_string))
    );


    $result = curl_exec($ch);

    ?>



    the Agent function that is called when the device want his configuration


    function AskForConfig() {
    server.log("Device requested for his configuration");


    local json = {"NodeUrl":agentURL}
    local url = "http://min-max.ca/beta/postreply.php";
    local headers = { "Content-Type": "application/json" };
    local body = http.jsonencode(json);

    // send data to your web service

    local x = http.post(url, headers, body).sendsync();


    server.log("meh : ");

    return "nothing";
    }


    basicaly what I want is the content of $config to be returned by AskForConfig()
  • Your agent code looks fine. If you want to see what response you get back I would add:

    server.log("HTTPResponse: " + x.statuscode + " - " + x.body);

    Then as explained in your "postreply.php" file you would have:

    <?php
    if(isset($_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) {
    $_POST = array_merge($_POST, (array) json_decode( trim( file_get_contents( 'php://input')), true));

    $NodeUrl= $_POST['NodeUrl']; //ignore stripslashes for now

    // you now have agent URL stored in $NodeUrl
    // Strip what you need
    // Now insert your SQL code

    // don't forget to respond back to the agent
    // In general I usually do the following:

    $payload = array();
    $payload['result'] = "blah blah blah";
    $payload['error'] = "none";

    echo json_encode($payload);

    }
    ?>
  • Ok, then

    function AskForConfig() {
    server.log("Device requested for his configuration");
    RefreshData(agentURL,"MSG","AGENT","Requested configuration from database",moment);

    local json = {"NodeUrl":agentURL}
    local url = "http://min-max.ca/beta/get_config.php";
    local headers = { "Content-Type": "application/json" };
    local body = http.jsonencode(json);

    // send data to your web service

    local x = http.post(url, headers, body).sendsync();

    server.log("HTTPResponse: " + x.statuscode + " - " + x.body);
    RefreshData(agentURL,"MSG","AGENT","Received configuration from database",moment);
    return x.body;
    }


    and

    device.send("CONFIG",AskForConfig())

    on the device side now :
    agent.on("CONFIG",function(data){

    SendNewData("MSG","NODE","Received configuration from agent");

    //server.log("P1 offset" + data.P1_offset);

    })


    in my db, a variable was P1_offset

    should be in the config, then in the x.body, ....but when its no into the device, i mean, "data" in the agent.on function...what format is that, how to access each variable ?
  • If you plan to return json encoded data as suggested from your php script, you would now need to add this at the bottom of your agent code. That will then send the right data to your device:


    local data = http.jsondecode(x.body);
    // Now return the right data
    if ("P1_offset" in data) return data.P1_offset;
    else return 0;



  • got it

    its offcourse a json
    #require "JSONParser.class.nut:1.0.0"

    json <- JSONParser.parse(data);
    server.log(json.P1_offset);
  • The way I'm understanding this is, the device needs the configuration. So it asks the Agent to get the configuration from your website. The Agent executes, or POSTS to your PHP script, and the script gives it the configuration JSON. So it's the Agent that determines when it needs the configuration?

    So your PHP script doesn't need CURL. It only needs to return a JSON response when the API is executed. When your Agent does the POST to the PHP script, it could send an API key that the PHP script verifies before echoing back the JSON. That would keep anyone else from running your PHP script (example, from their browser).

    After all of these previous posts, is that what is happening now? You are no longer doing the PHP CURL, but instead, simply returning the JSON when the Agent wants it?



  • mlseim you are right, the problem is that I was doing the Curl thing, it was not necessary.

    I'm passing the json in the http response and it work fine. :D
  • Keep that Curl thing in your pile of "snippets". You'll have a time when the PHP script needs to contact the Agent, and that is how you will do it.
Sign In or Register to comment.