HTTP integration

Hi!

I have a question about how ACK messages (Device->Cloud) in the case of confirmed transmission (initiated in direction Cloud->Device) could be seen by our application via HTTP integration.

We send confirmed messages, but looks like TTN doesn’t send the ACK messages to our HTTP endpoint, or maybe we are logging the input messages incorrectly. We don’t see them due to that.

We are logging all HTTP input on our HTTP endpoint
(by HTTP endpoint, I refer to path which is being called by TTN once a message is received).

Thanks & cheers!

I did samething as you did except put my own url which is
https://integrations.thethingsnetwork.org/ttn-eu/api/v2/down/kwloratest1/especial_http?key=ttn-account-v2.uvH4zcJhiVuOTbECDfAcfuLTDEbarx_Dtd98HJhR4-g

but i only got
-> {“dev_id”:“arduino_lora_test2”,“payload_raw”:“AAE=”}
Errorcode:
and no data on ttn

I’m trying to looking for downlink please help me (sorry for my bad english ㅠㅠ)

I solve my problem!

I just thought “dev_id” is no important data so, I remainded as “hrmansenuno”
after i changed into my own dev_id it works!

1 Like

Hi,

Sorry to bring up a new issue on an older form. I have tried absolutely everywhere online, and I still can’t seem to get uplink data from TTN sent to my website to work. In the TTN HTTP integration fields, I have used the default access key, my website with the PHP file on the end (e.g. http://websitename.com/file.php - obviously websitename is different) and the method as POST. On the PHP side, I have tried using MYSQL and writing to text files but I get absolutely nothing. When looking at the devices accessing my website I can clearly see TTN sending data. To simplify the code to find the root of the problem, I have used this code in by ‘file.php’ from the posts above (slightly modified):

<?php

//Make sure that it is a POST request.
if(strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0){
    throw new Exception('Request method must be POST!');
}
 
//Make sure that the content type of the POST request has been set to application/json
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if(strcasecmp($contentType, 'application/json') != 0){
    throw new Exception('Content type must be: application/json');
}
 
//Receive the RAW post data.
$content = trim(file_get_contents("php://input"));
 
//Attempt to decode the incoming RAW post data from JSON.
$decoded = json_decode($content, true);
 
//If json_decode failed, the JSON is invalid.
if(!is_array($decoded)){
    throw new Exception('Received content contained invalid JSON!');
}

//Process the JSON.

echo $decoded; // Can I simply echo the decoded?

?>

When I try to see if it works, I go to the website URL directly (http://websitename.com/file.php) and then simulate an uplink in TTN console. It only displays the thrown error ‘Request method must be POST!’ or if I remove this, then nothing. What am I doing wrong? Should I have any other files in my website directory which has code relevant to file.php? Could it have something to do with my hosting, which is GoDaddy? Let me know if I can make it clearer in any way or try anything.

Thanks

Where do you expect the output to go to? The HTTP integration is a server-to-server interface; when TTN connects to your server, it’s not going to handle the response you’re sending using the line above. Rather than echo-ing the request back to TTN, you’ll need to store it somewhere.

It doesn’t make sense that you’re going to that URL: even when TTN also goes to that URL at exactly the very same time (unlikely), there’s nothing in your code to make you (the human) show whatever TTN sent to that URL. Each request is a standalone request; nothing is shared with others who happen to know the same URL.

As a bare minimum without any security, this example from Parsing HTTP integration data in PHP might help:

Thank you so much. I failed to mention that I am a complete novice to PHP and I was thinking in terms of C++ and getting it simply to display data it receives. I feel very silly right now.

Thanks again.

Hello!

Im also trying to receive data on my Apache server. Im using wampserver (localhost). Can you give me some advices how to receive the data from the devices on my application. Maybe the steps you did…

Thank you very much!

@rego21: you need a server accessible through the web at some address. If you have it at home on an ADSL line, in principle you could, but if you do not know already how to do it, it is too much effort, it is easier to just use some free PHP hosting.

Ok i understand. Can you point me one free PHP hosting? Thank you for the help!

I do not use a specific platform, having my own server. Just google for PHP free hosting, or maybe wait for some other user suggestion. If what you have to do is simple, you might also use some already available platform (check those in the Integrations tab).

All php guru’s, are there perl supporters in the room? :disappointed_relieved:

According to statistics, maybe one will answer, sooner or later :slight_smile:
Apart from that, it should not be too difficult to adapt the small storage script to Perl, if you are a Perl programmer, and on the other side, if you are not, just use PHP.

1 Like

I’m not a PHP programmer, not a PERL programmer, actually not a programmer at all :thinking:

In PHP it now works to log payload fields in a file (thanks for your hints). My problem in Perl is to get the $content. In my CGI scripts I use something like:

use CGI qw(param);
my $Surname = param(“Surname”);

What param I have to use to get the whole JSON info?

CGI parameters are those you can find appended to the URL, so in this case they are not needed/useful.
Since your are not a Perl programmer, just create another PHP script that reads the log file and uses the contents, which are still JSON strings to be converted to PHP objects.
E.g., somewhat brutally:

$log=file('log.txt');
foreach($log as $r) {
	$data=json_decode($r);
 // print_r($data) //uncomment this to inspect the packet structure
	$dev_id=$data->dev_id;
	$HW=$data->hardware_serial;
	$raw=$data->payload_raw;
	$time=$data->metadata->time;
        ...
}

was already so far…

<?php

//Make sure that it is a POST request.
if(strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0){
    throw new Exception('Request method must be POST!');
}
 
//Make sure that the content type of the POST request has been set to application/json
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if(strcasecmp($contentType, 'application/json') != 0){
    throw new Exception('Content type must be: application/json');
}
 
//Receive the RAW post data.
$content = trim(file_get_contents("php://input"));
 
//Attempt to decode the incoming RAW post data from JSON.
$decoded = json_decode($content, true);
 
//If json_decode failed, the JSON is invalid.
if(!is_array($decoded)){
    throw new Exception('Received content contained invalid JSON!');
}

//decode and save JSON data
$Time			= $decoded['metadata']['time'];
$Battery	= $decoded['payload_fields']['battery'];
$Counter	= $decoded['payload_fields']['counter'];

$myfile		= fopen("data/5935br27abp.data", "a") or die("Unable to open file!");

fwrite($myfile, "Time    = " . $Time . "\n");
fwrite($myfile, "Battery = " . $Battery . "\n");
fwrite($myfile, "Counter = " . $Counter . "\n" );

fclose($myfile);

?>

I was just curious how it would look in PERL, specific how to get the JSON without a reference to a param. I thought a POST works always via params.

OK, for the time being a polyglot implementation: get, decode and save the POST data with PHP, the rest with PERL :grinning:

Thanks…

Grrr. How to make a nice listing…

1 Like

see FORMAT

If you POST a form, yes, but the JSON is a text file attached in the body, so you have to read it in some way (it is the “php://input” trick in PHP, which just takes the body of request). I never used Perl, but my friend StackOverflow apparently suggests this:

my $data = $query->param(‘POSTDATA’);

(to be then decoded).

@UdLoRa Thank you for the hint, it works perfect. First in PHP, now in PERL. “According to statistics, maybe one will read it, sooner or later” :wink:

#!/usr/bin/perl -w

use strict;
use warnings;

use CGI::Simple;
use JSON qw( decode_json );

#--------------
# get POSTDATA
#--------------
my $Query = new CGI::Simple;
my $Data  = $Query->param('POSTDATA');

#-------------
# decode JSON
#-------------
my $Json = decode_json($Data);

my $Battery	   = $Json->{'payload_fields'}{'battery'};
my $Counter	   = $Json->{'payload_fields'}{'counter'};
my $STimeStamp = $Json->{'metadata'}{'time'};
my $Frequency  = $Json->{'metadata'}{'frequency'};
my $Gateways   = $Json->{'metadata'}{'gateways'};               # Array of gateways (not only mine)
my $GtwId      = $Json->{'metadata'}{'gateways'}[0]{'gtw_id'};  # Gateway ID
my $GTimeStamp = $Json->{'metadata'}{'gateways'}[0]{'time'};    # Gateway date/time
my $Channel    = $Json->{'metadata'}{'gateways'}[0]{'channel'}; #
my $Rssi       = $Json->{'metadata'}{'gateways'}[0]{'rssi'};    #
my $Snr        = $Json->{'metadata'}{'gateways'}[0]{'snr'};     #

my $SDate		  = substr($STimeStamp, 0, 10) . " " . substr($STimeStamp, 11, 8);
my $GDate		  = substr($STimeStamp, 0, 10) . " " . substr($STimeStamp, 11, 8); # Gate time is empty???

#-----------------
# update CSV file
#-----------------
my $CsvFile = "5935br27abp.csv";

local *CsvFile;

open(CsvFile, ">> $CsvFile");

print CsvFile $GDate.",".$Battery.",".$Counter."\n";
close(CsvFile);

Only no MYSQL but a simple CSV log-file and Dygraph, see: Dygraph test-3

1 Like

FYI: I see that I can not access requestb.in but it does work using https://requestbin.fullcontact.com/