daily compression of InfluxDB

InfluxDB is an open source time series database built by InfluxData and used in e.g. Openhab for data persistance.
For small computers like raspi’s it is a best practice to compress the database regurlarly.

Why not using cron ?

Well, it works.. the only (security)-drawback is to grant /bin/bash to the influx-user:

cat /etc/cron.daily/00influx:

#!/bin/bash
#execute
/home/pi/1_influxrepair.sh


cat /home/pi/1_influxrepair.sh:

#!/bin/bash
service influxdb stop
echo "before su"
su influxdb -c /home/pi/1_subscript.sh
echo "after su"
whoami
service influxdb start

cat /home/pi/1_subscript.sh:

#!/bin/bash
echo "now in sub shell"
whoami
cd /var/lib/influxdb
influx_inspect buildtsi -compact-series-file -datadir ./data -waldir ./wal
exit
echo "exiting sub shell"

cat /etc/passwd|grep infl:

modify influxdb:/bin/bash

done!

Netatmo API : How do I get the access_token ?

curl:

curl --location --request POST "https://api.netatmo.com/oauth2/token" \
  --form "grant_type=password" \
  --form "client_id=5a*******21175d8b45ec" \
  --form "client_secret=NR*******bYylIAigYvaO" \
  --form "username=be*******eb.de" \
  --form "password=***111***"

jQuery:

var form = new FormData();
form.append("grant_type", "password");
form.append("client_id", "5a*******21175d8b45ec");
form.append("client_secret", "NR*******bYylIAigYvaO");
form.append("username", "be*******eb.de");
form.append("password", "***111***");

var settings = {
  "url": "https://api.netatmo.com/oauth2/token",
  "method": "POST",
  "timeout": 0,
  "processData": false,
  "mimeType": "multipart/form-data",
  "contentType": false,
  "data": form
};

$.ajax(settings).done(function (response) {
  console.log(response);
});

Ruby:

require "uri"
require "net/http"

url = URI("https://api.netatmo.com/oauth2/token")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)
request["content-type"] = 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
request.body = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"grant_type\"\r\n\r\npassword\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"client_id\"\r\n\r\n5a*******21175d8b45ec\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"client_secret\"\r\n\r\nNR*******bYylIAigYvaO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"username\"\r\n\r\nbe*******eb.de\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n***111***\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"

response = https.request(request)
puts response.read_body

Python

import requests
url = 'https://api.netatmo.com/oauth2/token'
payload = {'grant_type': 'password',
'client_id': '5a*******21175d8b45ec',
'client_secret': 'NR*******bYylIAigYvaO',
'username': 'be*******eb.de',
'password': '***111***'}
files = {}
headers = {}
response = requests.request('POST', url, headers = headers, data = payload, files = files, allow_redirects=False, timeout=undefined, allow_redirects=false)
print(response.text)

Node

var https = require('https');

var options = {
  'method': 'POST',
  'hostname': 'api.netatmo.com',
  'path': '/oauth2/token',
  'headers': {
  }
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"grant_type\"\r\n\r\npassword\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"client_id\"\r\n\r\n5a*******21175d8b45ec\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"client_secret\"\r\n\r\nNR*******bYylIAigYvaO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"username\"\r\n\r\nbe*******eb.de\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n***111***\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--";

req.setHeader('content-type', 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW');

req.write(postData);

req.end();

PHP:

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://api.netatmo.com/oauth2/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => false,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => array('grant_type' => 'password','client_id' => '5a*******21175d8b45ec','client_secret' => 'NR*******bYylIAigYvaO','username' => 'be*******eb.de','password' => '***111***'),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
} ?>

Build a RESTful API in Go using AWS Lambda | Java Code Geeks – 2018

Interested to learn about RESTful API? Check this article from javacodegeeks explaining how to design, build, and deploy a RESTful API in Go using AWS Lambda.

Source: Build a RESTful API in Go using AWS Lambda | Java Code Geeks – 2018

Change the Originaldate parameter with exiftool

Um das Originaldatum der Datei SIMG0011.jpg anzupassen:

exiftool -DateTimeOriginal=”2003:05:26 10:51:00″ SIMG0011.jpg