From bf844972aad8839d430be88b14097fd4cdaec059 Mon Sep 17 00:00:00 2001 From: Igor Pashev Date: Wed, 12 May 2021 16:34:03 +0200 Subject: Show absolute humidity --- cmd/Print.hs | 10 +++ lib/Web/OpenWeatherMap/Formulas.hs | 37 +++++++++++ openweathermap.cabal | 123 ++++++++++++++++++++----------------- 3 files changed, 112 insertions(+), 58 deletions(-) create mode 100644 lib/Web/OpenWeatherMap/Formulas.hs diff --git a/cmd/Print.hs b/cmd/Print.hs index dd97c45..7a87023 100644 --- a/cmd/Print.hs +++ b/cmd/Print.hs @@ -6,7 +6,9 @@ module Print import Data.List (intercalate) import Data.Time.Clock.POSIX (posixSecondsToUTCTime) import Data.Time.LocalTime (TimeZone, minutesToTimeZone, utcToZonedTime) +import Text.Printf (printf) +import Web.OpenWeatherMap.Formulas (absoluteHumidity) import qualified Web.OpenWeatherMap.Types.City as City import qualified Web.OpenWeatherMap.Types.Coord as Coord import qualified Web.OpenWeatherMap.Types.CurrentWeather as CW @@ -26,6 +28,7 @@ printCurrectWeather cw = ", " [ w , showHumidity mainw + , showAbsoluteHumidity mainw , showPressure mainw , showTemp mainw , showWind wind @@ -52,6 +55,7 @@ showForecast tz fc = ", " [ showWeather (FC.weather fc) , showHumidity mainw + , showAbsoluteHumidity mainw , showPressure mainw , showTemp mainw , showWind (FC.wind fc) @@ -86,6 +90,12 @@ showHumidity m = "H " ++ show hm ++ " %" hm :: Int hm = round . Main.humidity $ m +showAbsoluteHumidity :: Main.Main -> String +showAbsoluteHumidity m = "ρ " ++ rho ++ " g/m³" + where + r = absoluteHumidity m + rho = maybe "??" (printf "%0.2f") r + -- https://en.wikipedia.org/wiki/Millimeter_of_mercury showPressure :: Main.Main -> String showPressure m = "P " ++ show p ++ " mmHg" diff --git a/lib/Web/OpenWeatherMap/Formulas.hs b/lib/Web/OpenWeatherMap/Formulas.hs new file mode 100644 index 0000000..f63bc9f --- /dev/null +++ b/lib/Web/OpenWeatherMap/Formulas.hs @@ -0,0 +1,37 @@ +{-# LANGUAGE NamedFieldPuns #-} + +module Web.OpenWeatherMap.Formulas + ( absoluteHumidity + ) where + +import Web.OpenWeatherMap.Types.Main + +{-- | Calculate absolute humidity (g/m³) + +Returns 'Nothing' if the temperature is out of range (−30°C, +35°C). + +-} +absoluteHumidity :: Main -> Maybe Double +absoluteHumidity Main {temp, humidity} + | tC > -30 && tC < 35 = Just $ ahBolton1980 temp humidity + | otherwise = Nothing + where + tC = k2c temp + +{-- | Calculate absolute humidity (g/m³) + +Ref.: Bolton D. "The Computation of Equivalent Potential Temperature", +Monthly Weather Review, 1980, 108(7):1046–1053. + +-} +ahBolton1980 :: + Double -- ^ Temperature in Kelvins + -> Double -- ^ Relative humidity in % + -> Double +ahBolton1980 temp humidity = + 13.25 * humidity * exp (17.67 * tC / (tC + 243.5)) / temp + where + tC = k2c temp + +k2c :: Double -> Double +k2c t = t - 273.15 diff --git a/openweathermap.cabal b/openweathermap.cabal index 2138576..f410d5e 100644 --- a/openweathermap.cabal +++ b/openweathermap.cabal @@ -1,67 +1,74 @@ -name: openweathermap -version: 0.2.0 -synopsis: Access data at OpenWeatherMap -description: Client library and command-line utility to access - OpenWeatherMap https://openweathermap.org -license: PublicDomain -license-file: LICENSE -author: Igor Pashev -maintainer: Igor Pashev -copyright: 2017, Igor Pashev -category: Web -build-type: Simple -extra-source-files: README.md ChangeLog.md -cabal-version: 1.20 +cabal-version: 1.20 +name: openweathermap +version: 0.2.0 +license: PublicDomain +license-file: LICENSE +copyright: 2017, Igor Pashev +maintainer: Igor Pashev +author: Igor Pashev +synopsis: Access data at OpenWeatherMap +description: + Client library and command-line utility to access + OpenWeatherMap https://openweathermap.org + +category: Web +build-type: Simple +extra-source-files: + README.md + ChangeLog.md source-repository head - type: git - location: https://github.com/ip1981/openweathermap.git + type: git + location: https://github.com/ip1981/openweathermap.git flag cmd - description: Build a command-line utility. - default: True + description: Build a command-line utility. library - default-language: Haskell2010 - ghc-options: -Wall - hs-source-dirs: lib - build-depends: - base >= 4.9 && < 5 - , aeson - , http-api-data - , http-client - , servant - , servant-client >= 0.16 - , servant-client-core - exposed-modules: - Web.OpenWeatherMap.API - Web.OpenWeatherMap.Client - Web.OpenWeatherMap.Types.City - Web.OpenWeatherMap.Types.Clouds - Web.OpenWeatherMap.Types.Coord - Web.OpenWeatherMap.Types.CurrentWeather - Web.OpenWeatherMap.Types.Forecast - Web.OpenWeatherMap.Types.ForecastWeather - Web.OpenWeatherMap.Types.Location - Web.OpenWeatherMap.Types.Main - Web.OpenWeatherMap.Types.Sys - Web.OpenWeatherMap.Types.Weather - Web.OpenWeatherMap.Types.Wind + exposed-modules: + Web.OpenWeatherMap.API + Web.OpenWeatherMap.Client + Web.OpenWeatherMap.Formulas + Web.OpenWeatherMap.Types.City + Web.OpenWeatherMap.Types.Clouds + Web.OpenWeatherMap.Types.Coord + Web.OpenWeatherMap.Types.CurrentWeather + Web.OpenWeatherMap.Types.Forecast + Web.OpenWeatherMap.Types.ForecastWeather + Web.OpenWeatherMap.Types.Location + Web.OpenWeatherMap.Types.Main + Web.OpenWeatherMap.Types.Sys + Web.OpenWeatherMap.Types.Weather + Web.OpenWeatherMap.Types.Wind -executable openweathermap - default-language: Haskell2010 - ghc-options: -Wall -static - hs-source-dirs: cmd - main-is: Main.hs - other-modules: Print - if flag(cmd) + hs-source-dirs: lib + default-language: Haskell2010 + ghc-options: -Wall build-depends: - base >= 4.9 && < 5 - , directory - , openweathermap - , optparse-applicative >= 0.13.0.0 - , time - , xdg-basedir - else - buildable: False + base >=4.9 && <5, + aeson -any, + http-api-data -any, + http-client -any, + servant -any, + servant-client >=0.16, + servant-client-core -any + +executable openweathermap + main-is: Main.hs + hs-source-dirs: cmd + other-modules: Print + default-language: Haskell2010 + ghc-options: -Wall -static + + if flag(cmd) + build-depends: + base >=4.9 && <5, + directory -any, + openweathermap -any, + optparse-applicative >=0.13.0.0, + time -any, + xdg-basedir -any + + else + buildable: False -- cgit v1.2.3