Created
February 16, 2021 13:28
-
-
Save btemperli/5783f2ab3aefd38886dab222fe6714e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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