commit 41a0e352cc99ccfb918af7a5316842fb37b1fd4f
Author: Leah (ctucx) <git@ctu.cx>
Date: Tue, 13 Dec 2022 14:21:28 +0100
Author: Leah (ctucx) <git@ctu.cx>
Date: Tue, 13 Dec 2022 14:21:28 +0100
initial commit
5 files changed, 211 insertions(+), 0 deletions(-)
A
|
99
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/departures2mqtt.nimble b/departures2mqtt.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Leah (ctucx)" +description = "Send kvg-kiel bus departures to mqtt" +license = "MIT" +srcDir = "src" +bin = @["departures2mqtt"] + + +# Dependencies + +requires "nim >= 1.4.8"
diff --git a/flake.lock b/flake.lock @@ -0,0 +1,43 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1670772952, + "narHash": "sha256-b7V3cGtMNcQ5c6hwRqqX+eIuNUj+O3orsb64BKPR9yc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "dfef2e61107dc19c211ead99a5a61374ad8317f4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +}
diff --git a/flake.nix b/flake.nix @@ -0,0 +1,54 @@ +{ + description = "Send kvg-kiel bus departures to mqtt"; + + inputs = { + flake-utils.url = "github:numtide/flake-utils"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; + }; + + outputs = { self, nixpkgs, flake-utils }: { + + overlay = final: prev: { + + departures2mqtt = ( + let + nmqtt = final.fetchFromGitHub { + owner = "zevv"; + repo = "nmqtt"; + rev = "v1.0.4"; + sha256 = "1by0xyqz754dny19lf8rpkg42passnj0rs6rk3jr763m1zr803mc"; + }; + + in final.nimPackages.buildNimPackage { + name = "departures2mqtt"; + src = self; + + buildInputs = [ nmqtt ]; + + nimBinOnly = true; + nimRelease = true; + } + ); + + }; + + } // (flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ self.overlay ]; + }; + + in rec { + + packages.default = pkgs.departures2mqtt; + packages.departures2mqtt = pkgs.departures2mqtt; + + apps.default = { + type = "app"; + program = "${pkgs.departures2mqtt}/bin/departures2mqtt"; + }; + + } + )); +}+ \ No newline at end of file
diff --git a/src/departures2mqtt.nim b/src/departures2mqtt.nim @@ -0,0 +1,99 @@ +import std/asyncdispatch +import std/[strutils, strtabs] +import std/[os, parseopt, httpclient] +import std/[json, times] + +import nmqtt + +var p = initOptParser(commandLineParams()) +var stations : seq[string] +var host : string +var port : int +var user : string +var pass : string +var topic : string + +while true: + p.next() + case p.kind + of cmdEnd: break + of cmdArgument: break + of cmdShortOption, cmdLongOption: + case p.key: + of "stations": + if p.val == "": + quit("option 'stations' can't be empty!", 1) + else: + stations = p.val.split(",") + of "mqtt-host": + if p.val == "": + quit("option 'mqtt-host' can't be empty!", 1) + else: + host = p.val + of "mqtt-port": + if p.val == "": + quit("option 'mqtt-port' can't be empty!", 1) + else: + port = p.val.parseInt + of "mqtt-user": + if p.val == "": + quit("option 'mqtt-user' can't be empty!", 1) + else: + user = p.val + of "mqtt-pass": + if p.val == "": + quit("option 'mqtt-pass' can't be empty!", 1) + else: + pass = p.val + of "mqtt-topic": + if p.val == "": + quit("option 'mqtt-topic' can't be empty!", 1) + else: + topic = p.val + else: + quit("unknown option: '" & $p.key & "'", 1) + + +if (stations.len == 0): + quit("You need to specify at least one station!", 1) + +if (host == ""): + quit("You need to specify an mqtt-host!", 1) + +if (port == 0): + port = 1883 + +if (topic == ""): + quit("You need to specify a mqtt-topic!", 1) + + +let client = newHttpClient() +var data = newJObject() +data.add("lastUpdated", newJInt(getTime().toUnix())) +data.add("departures", newJObject()) + +for id in stations: + let jsonData = parseJson(client.getContent("https://www.kvg-kiel.de/internetservice/services/passageInfo/stopPassages/stop?stop=" & $id & "&mode=departure&language=en")) + var departures = newJArray() + + for entry in jsonData{"actual"}: + departures.add(%* { + "line": entry{"patternText"}, + "direction": entry{"direction"}, + "departure_in": entry{"mixedTime"}.getStr.replace(" %UNIT_MIN%", "") + }) + + data["departures"].add(jsonData{"stopName"}.getStr, departures) + +let mqtt = newMqttCtx("departures2mqtt") +mqtt.set_verbosity(1) +mqtt.set_host(host, port) + +if (user != "" and pass != ""): + mqtt.set_auth(user, pass) + +waitFor mqtt.connect() +waitFor sleepAsync 500 +waitFor mqtt.publish(topic, $data, 2, true) +waitFor sleepAsync 500 +waitFor mqtt.disconnect()