Dawarichでトライ
この記事を見て、そのとおりdockerでやってみた。
qiita.com
もしリバースプロキシ or Cloudflare Tunnelなどで外部公開する場合、ホスト名を明示的に許可しないと接続を拒否されます。
と書いてあったが、普通のポート開放では不要なのかと思ってスルーしてたら引っかかってしまった。
で、動くようになったんだが、不満点は2つ。
- クライアントのタイムゾーンがGMT
x.comDawarichのサーバがGMTになっている。settingsに該当する項目がないけど、環境変数TIME_ZONEを設定したらええんかな。とりあえず設定してリブート。https://t.co/3C6xGGzpKU
— 泥山田@チーム泥んこプロレス (@doroyamada) 2025年2月16日
x.comあかんかった。
— 泥山田@チーム泥んこプロレス (@doroyamada) 2025年2月16日
送信、受信はJMTになっとるけど、ウェブサーバとしての表示(フィルタリング)がGMT扱いになっとる。2月8日でフィルタリングしてもJMT2月9日の9時のデータまでひっかかる。 pic.twitter.com/xGUyd3I6aw
設定をいろいろみてもそれらしき項目はなし。原点に戻ってdock-composer.ymlを見たらタイム設定があった。
x.comできた。docker-compose.ymlの中にタイムゾーン設定があった。書き換えてdocker compose up -d。サーバ停めなくてもいけた。 pic.twitter.com/3BVSXAvcAy
— 泥山田@チーム泥んこプロレス (@doroyamada) 2025年2月16日
- 動作が遅い
なにがボトルネックかわからんので、対応しようがない。
対策
データは家でしか見ないので、ローカルファイルでええんちゃうか。だとしたらgpxファイルにしてgpspruneで見たらええんちゃうか。
ということで、webサーバでデータを受けて、1日1回データをgpxに書き出せばええやん。
できたもの
公式サイトにphp+mysqlのスクリプトサンプルがある。
owntracks.org
これをsqliteで書き換えてみた。シンプルそうなので興味があった。RDBを扱うのは初めて。できあいのスクリプトもあるけど、多機能すぎた(friend機能とは不要)のでパス。
<?php header("Content-type: application/json"); $payload = file_get_contents("php://input"); $logfile = __DIR__ . "/log/" . date("YmdHis") . ".json"; file_put_contents($logfile,$payload); $data = @json_decode($payload, true); $db = new SQLite3('../../database/tracks.sqlite'); $db->exec('CREATE TABLE IF NOT EXISTS entries(time INTEGER,tid TEXT,lat REAL,lon REAL,alt INTEGER, posted INTEGER,received INTEGER)'); if ($data['_type'] == 'location') { $stmt = $db->prepare('INSERT INTO entries VALUES(:time,:tid,:lat,:lon,:alt,:posted,:received)'); $stmt->bindValue(':time',$data['tst'],SQLITE3_INTEGER); $stmt->bindValue(':tid',$data['tid'],SQLITE3_TEXT); $stmt->bindValue(':lat',$data['lat'],SQLITE3_FLOAT); $stmt->bindValue(':lon',$data['lon'],SQLITE3_FLOAT); $stmt->bindValue(':alt',$data['alt'],SQLITE3_INTEGER); $stmt->bindValue(':posted',$data['created_at'],SQLITE3_INTEGER); $stmt->bindValue(':received',time(),SQLITE3_INTEGER); $result = $stmt->execute(); $stmt->close(); $response = array(); print json_encode($response); }else{ echo "This is not location\n"; } ?>
データを見ると、測位時刻、送信時刻を持っていたので、さらに受信時刻も加えてみた。これをBASIC認証を掛けたディレクトリに置いて、owntracksアプリを設定。
これをgpxに書き換えるスクリプト。引数なしで実行すると全日の記録を、引数があるとその日(strtotime関数に依存)のデータを書き出す。
<?php error_reporting(E_ALL); chdir(__DIR__); if(isset($argv[1])){ if(!($epoc_yesterday = strtotime($argv[1]))){ die("format error! : $argv[1]\n"); } }else{ $epoc_yesterday = strtotime("yesterday"); } $epoc_today = $epoc_yesterday + 60*60*24; $db = new SQLite3('/home/kazz/web/default/database/tracks.sqlite'); $result_list = $db->query("SELECT * FROM entries WHERE tid = 'AS' AND posted >= $epoc_yesterday AND posted < $epoc_today"); $template_track = file_get_contents("trkpt.txt"); $array_template = array("%%lat%%","%%lon%%","%%alt%%","%%time%%"); $data_gpx = ""; while ($row = $result_list->fetchArray(SQLITE3_ASSOC)){ $time_gpx = str_replace("+00:00","Z",gmdate(DATE_ATOM,$row['posted'])); $array_data = array($row['lat'],$row['lon'],$row['alt'],$time_gpx); $data_gpx .= str_replace($array_template,$array_data,$template_track); } if($data_gpx){ $body = str_replace(array("%%time%%","%%data%%\n"),array($time_gpx,$data_gpx),file_get_contents("gpx.txt")); file_put_contents("gpx/" . date("Ymd",$epoc_yesterday).".gpx",$body); }else{ die("No data\n"); } ?>
あとは古いデータを削除するスクリプトを仕込むことになるけど、データが溜まってからやる。しかしこの程度ならcsvファイルでも十分行けたかもしれない。なんならこの状態でログとして保存しているJSONファイルでもいける。