feat: Parse command-line arguments

This commit is contained in:
Alexander Kobjolke 2025-01-04 23:16:18 +01:00
parent 6603e65131
commit 3376e24fc4
3 changed files with 54 additions and 31 deletions

View file

@ -11,9 +11,6 @@ extra-source-files:
dependencies:
- base >= 4.13 && < 5
- time
- directory
- containers
- net-mqtt
- network-uri
- req
@ -21,7 +18,7 @@ dependencies:
- aeson
- text
- bytestring
- process
- optparse-applicative
ghc-options:
- -Wall
@ -66,3 +63,5 @@ tests:
source-dirs:
- test/doctest
build-tools: doctest
dependencies:
- process

View file

@ -1,4 +1,5 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module TK2MQTT
( runTK2MQTT,
@ -10,24 +11,50 @@ import Control.Exception (catch)
import Control.Monad (void)
import Control.Monad.IO.Class
import Data.Aeson
import Data.List qualified as L
import Data.Maybe (fromMaybe)
import Data.Text qualified as T
import Network.HTTP.Req
import Network.MQTT.Client qualified as MQTT
import Network.URI (URI, parseURI)
import System.Environment qualified as Env
import Network.MQTT.Topic (mkTopic)
import Network.URI (URI, parseURI, pathSegments)
import Options.Applicative (eitherReader, (<**>))
import Options.Applicative qualified as O
import System.IO
newtype APIKey = APIKey String
data Config = Config
{ apiKey :: !String,
stationId :: !String,
brokerUrl :: !URI
}
deriving (Show)
newtype StationID = StationID String
uriReader :: O.ReadM URI
uriReader = eitherReader $ \arg ->
case parseURI arg of
Nothing -> Left ("Cannot parse URI: " <> arg)
Just uri -> Right uri -- "mqtt://100.101.208.5"
runTK2MQTT :: URI -> APIKey -> StationID -> IO ()
runTK2MQTT uri (APIKey apikey) (StationID stationId) = do
mc <- MQTT.connectURI MQTT.mqttConfig uri
pConfig :: O.Parser Config
pConfig =
Config
<$> O.strOption (O.long "api-key" <> O.metavar "APIKEY" <> O.help "Tankerkönig API key")
<*> O.strOption (O.long "station-id" <> O.metavar "STATION" <> O.help "ID of the station to query the prices for")
<*> O.option uriReader (O.long "broker" <> O.metavar "URL" <> O.help "URL of the MQTT broker, e.g. mqtt://127.0.0.1:1883")
runTK2MQTT :: Config -> IO ()
runTK2MQTT Config {..} = do
mc <- MQTT.connectURI MQTT.mqttConfig brokerUrl
result <- runReq defaultHttpConfig $ do
r <- req GET (https "creativecommons.tankerkoenig.de" /: "json" /: "prices.php") NoReqBody jsonResponse ("apikey" =: apikey <> "ids" =: stationId)
r <- req GET (https "creativecommons.tankerkoenig.de" /: "json" /: "prices.php") NoReqBody jsonResponse ("apikey" =: apiKey <> "ids" =: stationId)
pure (responseBody r :: Value)
void $ liftIO $ MQTT.publish mc "tmp/fuel/diesel" (encode result) True
void $ liftIO $ MQTT.publish mc topic (encode result) True
void $ liftIO $ print topic
void $ liftIO $ print $ encode result
where
topic = fromMaybe "home/fuel" $ case L.intercalate "/" (pathSegments brokerUrl) of
"" -> Nothing
t -> mkTopic (T.pack t)
handleError :: IOError -> IO ()
handleError e = do
@ -35,6 +62,14 @@ handleError e = do
defaultMain :: IO ()
defaultMain = do
[apikey, stationId] <- Env.getArgs
let (Just uri) = parseURI "mqtt://hm.felis-halfmoon.ts.net"
runTK2MQTT uri (APIKey apikey) (StationID stationId) `catch` handleError
config <- O.execParser opts
-- [apiKey, stationId] <- Env.getArgs
-- let (Just brokerUrl) = parseURI "mqtt://100.101.208.5"
-- config = Config{..}
runTK2MQTT config `catch` handleError
where
opts :: O.ParserInfo Config
opts =
O.info
(pConfig <**> O.helper)
(O.fullDesc <> O.progDesc "Retrieve fuel prices from tankerkönig and publish them to MQTT")

View file

@ -32,15 +32,12 @@ library
aeson
, base >=4.13 && <5
, bytestring
, containers
, directory
, effectful
, net-mqtt
, network-uri
, process
, optparse-applicative
, req
, text
, time
default-language: GHC2021
executable tk2mqtt
@ -58,15 +55,12 @@ executable tk2mqtt
aeson
, base >=4.13 && <5
, bytestring
, containers
, directory
, effectful
, net-mqtt
, network-uri
, process
, optparse-applicative
, req
, text
, time
, tk2mqtt
default-language: GHC2021
@ -88,15 +82,13 @@ test-suite doctest
aeson
, base >=4.13 && <5
, bytestring
, containers
, directory
, effectful
, net-mqtt
, network-uri
, optparse-applicative
, process
, req
, text
, time
default-language: Haskell2010
test-suite spec
@ -120,16 +112,13 @@ test-suite spec
, aeson
, base >=4.13 && <5
, bytestring
, containers
, directory
, effectful
, hspec
, net-mqtt
, network-uri
, process
, optparse-applicative
, quickcheck-instances
, req
, text
, time
, tk2mqtt
default-language: GHC2021