Skip to content

Instantly share code, notes, and snippets.

@btemperli
Created February 16, 2021 13:28
Show Gist options
  • Select an option

  • Save btemperli/5783f2ab3aefd38886dab222fe6714e9 to your computer and use it in GitHub Desktop.

Select an option

Save btemperli/5783f2ab3aefd38886dab222fe6714e9 to your computer and use it in GitHub Desktop.
<?php
namespace App\Http\Controllers;
use App\Model\LoraEntryIncoming;
use Illuminate\Http\Response;
/**
* Controller of the LUMEN-Framework for handling incoming Lora-Entries.
*
* - This works with the V2 of TTN
* - It saves the incoming data into a database
*/
class LoraIncomingEntryController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Add a new entry to the internal lora database.
*
* @return Response
*/
public function apiLoraAdd()
{
$content = $this->addEntry();
return (new Response(json_encode($content), 200))
->header('Content-Type', 'json');
}
private function addEntry()
{
$entry = [
'payload' => false,
'app_id' => false,
'counter' => false,
'dev_id' => false,
'hardware_serial' => false,
'payload_raw' => false,
'downlink_url' => false,
'port' => false,
'content_raw' => false,
'timestamp' => time(),
];
$postdata_raw = file_get_contents('php://input');
$postdata = json_decode($postdata_raw);
foreach ($entry as $key => &$item) {
if (property_exists($postdata, $key)) {
$item = $postdata->$key;
}
}
// entry payload
$entry['payload'] = base64_decode($postdata->payload_raw);
// metadata entries
if (property_exists($postdata, 'metadata')) {
$metakeys = [
'time',
'frequency',
'modulation',
'coding_rate',
'data_rate',
];
foreach ($metakeys as $key) {
if (property_exists($postdata->metadata, $key)) {
$entry['meta_' . $key] = $postdata->metadata->$key;
}
}
if (property_exists($postdata->metadata, 'gateways')) {
$gatewaykeys = [
'gtw_id',
'latitude',
'longitude',
'altitude',
'channel',
'rssi',
'snr',
'rf_chain',
];
$gateway = $postdata->metadata->gateways[0];
foreach ($gatewaykeys as $key) {
$entry['gw_' . $key] = $gateway->$key;
}
}
}
$entry['content_raw'] = $postdata_raw;
// save entry
LoraEntryIncoming::create($entry);
$this->checkLastEntry($entry);
return $entry;
}
/**
* Check last incoming Lora Entry. If it was "sync", send a call back via the Lorawan.
* Think at your limits: 10 downlinks a day in the TTN V2.
*/
private function checkLastEntry(array $entry)
{
$payload = $entry['payload'];
if ($payload === 'sync') {
$url = $entry['downlink_url'];
$payload_string = 'fc:' . $entry['counter'];
$payload_base64 = base64_encode($payload_string);
$content = [
'dev_id' => $entry['dev_id'],
'port' => 1,
'confirmed' => false,
'payload_raw' => $payload_base64,
];
$content_json = json_encode($content);
$this->callTTNDownlink($url, $content_json);
}
}
/**
* Make the call to the TTN, send a downlink.
*/
private function callTTNDownlink($url, $json) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
$result = curl_exec ($ch);
$info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment