diff --git a/README.md b/README.md
index 2cd7e0b..f443cc5 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,30 @@
# humiditycalc
+BOTH slow- every req talks to api
+
## ENV
MODES: CALC, WEATHER, BOTH
BOTH is standard
-OPENWEATHERMAP_API_KEY is required in WEATHER and BOTH mode
\ No newline at end of file
+OPENWEATHERMAP_API_KEY is required in WEATHER and BOTH mode
+
+DEFAULT:
+MODE=CALC
+
+Standalone:
+MODE=BOTH
+OPENWEATHERMAP_API_KEY=yourkey
+LATITUDE=
+LONGITUDE=
+
+WEATHER:
+MODE=WEATHER
+OPENWEATHERMAP_API_KEY=yourkey
+DB_HOST=
+DB_PORT=
+DB_NAME=
+DB_PASSWORD=
+DB=
+
+OPTINAL:
+PORT=80
\ No newline at end of file
diff --git a/internal/weather.go b/internal/weather.go
index 5bf0569..ad6d162 100644
--- a/internal/weather.go
+++ b/internal/weather.go
@@ -1 +1,68 @@
package internal
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+)
+
+func Weather(env map[string]string) (humidity float64, temperature float64) {
+ // Get API key from environment variables
+ apiKey := env["OPENWEATHERMAP_API_KEY"]
+
+ // Get latitude and longitude from environment variables
+ latitude := env["LATITUDE"]
+ longitude := env["LONGITUDE"]
+
+ // Check if latitude and longitude are set
+ if latitude == "" || longitude == "" {
+ fmt.Println("Latitude and longitude are not set")
+ os.Exit(1)
+ }
+
+ // Get data from API
+ data := getData(apiKey, latitude, longitude)
+
+ // Parse data
+ humidity, temperature = parseData(data)
+
+ // Convert to Celsius
+ temperature = temperature - 273.15
+
+ return humidity, temperature
+
+}
+
+func getData(apiKey string, latitude string, longitude string) string {
+ // Get data from API
+ url := fmt.Sprintf("https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&appid=%s", latitude, longitude, apiKey)
+ resp, err := http.Get(url)
+ if err != nil {
+ fmt.Println("Error getting data from API")
+ }
+ defer resp.Body.Close()
+
+ // Read response body
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ fmt.Println("Error reading response body")
+ }
+
+ // Convert body to string
+ return string(body)
+}
+
+func parseData(data string) (humidity float64, temperature float64) {
+ // Parse data from API
+
+ m := make(map[string]interface{})
+ err := json.Unmarshal([]byte(data), &m)
+ if err != nil {
+ fmt.Println("Error parsing data")
+ }
+ n := m["main"].(map[string]interface{})
+
+ return n["humidity"].(float64), n["temp"].(float64)
+}
diff --git a/main.go b/main.go
index 0896e87..26bbc51 100644
--- a/main.go
+++ b/main.go
@@ -14,14 +14,17 @@ func main() {
if val, ok := env["MODE"]; ok {
if strings.ToLower(val) == "both" {
checkEnv(env)
- server.Run()
+ server.Run(env)
} else if strings.ToLower(val) == "weather" {
checkEnv(env)
// weather.Run()
} else if strings.ToLower(val) == "calc" {
// calc.Run()
- server.Run()
+ server.Run(env)
}
+ } else {
+ // calc.Run()
+ server.Run(env)
}
}
@@ -42,7 +45,6 @@ func loadEnv() map[string]string {
func checkEnv(env map[string]string) {
// Is there an API key for openweathermap?
if val, ok := env["OPENWEATHERMAP_API_KEY"]; ok {
- fmt.Println(val)
if val == "" {
print("OPENWEATHERMAP_API_KEY is not set")
os.Exit(1)
diff --git a/models/cache.go b/models/cache.go
new file mode 100644
index 0000000..57e8c27
--- /dev/null
+++ b/models/cache.go
@@ -0,0 +1,36 @@
+package models
+
+import (
+ "fmt"
+ "time"
+)
+
+type WeatherCache struct {
+ Humidity float64 // relative humidity in percentage
+ Temperature float64 // temperature in Celsius
+ timestamp time.Time // timestamp of last update
+ duration int16 // duration in seconds
+}
+
+func (w *WeatherCache) IsExpired() bool {
+ fmt.Println(time.Since(w.timestamp), time.Duration(w.duration)*time.Second)
+ return time.Since(w.timestamp) > time.Duration(w.duration)*time.Second
+}
+
+func (w *WeatherCache) SetData(humidity float64, temperature float64) {
+ w.Humidity = humidity
+ w.Temperature = temperature
+ w.timestamp = time.Now()
+ w.duration = 60
+}
+
+func (w *WeatherCache) GetData() (float64, float64) {
+ if w.IsExpired() {
+ return 0, 0
+ }
+ return w.Humidity, w.Temperature
+}
+
+func NewWeatherCache() *WeatherCache {
+ return &WeatherCache{}
+}
diff --git a/server/server.go b/server/server.go
index f6aaf07..784e5a6 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1,19 +1,33 @@
package server
import (
+ "fmt"
"html/template"
"net/http"
"strconv"
+ "strings"
"github.com/LeRoid-hub/humiditycalc/internal"
+ "github.com/LeRoid-hub/humiditycalc/models"
)
type result struct {
- AbsoluteHumidity float64
+ AbsoluteHumidity string
+ WeatherData WeatherData
+}
+
+type WeatherData struct {
+ Temperature string
+ RelativeHumidity string
+ AbsoluteHumidity string
}
// Run starts the HTTP server.
-func Run() {
+func Run(env map[string]string) {
+ // Cache weather data
+ var cacheWeather = models.NewWeatherCache()
+
+ // Load HTML template
tmpl := template.Must(template.ParseFiles("./web/templates/index.html"))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
@@ -39,10 +53,44 @@ func Run() {
// Calculate absolute humidity
absoluteHumidity := internal.AbsoluteHumidity(temp, rh)
+ var absoluteWeatherHumidity float64
+ var temperature, humidity float64
+
+ // Check if cache is expired or empty
+ if cacheWeather.IsExpired() || cacheWeather.Humidity == 0 || cacheWeather.Temperature == 0 {
+ // Get Weather data
+ humidity, temperature := internal.Weather(env)
+
+ // Calculate absolute weather humidity
+ absoluteWeatherHumidity = internal.AbsoluteHumidity(temperature, humidity)
+
+ // Update cache
+ cacheWeather.SetData(humidity, temperature)
+ } else {
+ // Use cached data
+ humidity, temperature := cacheWeather.GetData()
+ absoluteWeatherHumidity = internal.AbsoluteHumidity(temperature, humidity)
+ }
+
+ // Create response
+ WData := WeatherData{Temperature: FormatFloat(temperature, 2), RelativeHumidity: FormatFloat(humidity, 4), AbsoluteHumidity: FormatFloat(absoluteWeatherHumidity, 4)}
+
+ re := result{AbsoluteHumidity: FormatFloat(absoluteHumidity, 4), WeatherData: WData}
+
// Write response
- tmpl.Execute(w, result{AbsoluteHumidity: absoluteHumidity})
+ tmpl.Execute(w, re)
})
http.ListenAndServe(":8080", nil)
}
+
+func FormatFloat(num float64, prc int) string {
+ var (
+ zero, dot = "0", "."
+
+ str = fmt.Sprintf("%."+strconv.Itoa(prc)+"f", num)
+ )
+
+ return strings.TrimRight(strings.TrimRight(str, zero), dot)
+}
diff --git a/web/templates/index.html b/web/templates/index.html
index 337664c..deca291 100644
--- a/web/templates/index.html
+++ b/web/templates/index.html
@@ -14,7 +14,15 @@
+
+ {{ if .WeatherData }}
+
Temperature: {{ .WeatherData.Temperature }}°C
+Relative Humidity: {{ .WeatherData.RelativeHumidity }}%
+Absolute Humidity: {{ .WeatherData.AbsoluteHumidity }} g/m³
+ {{ end }} {{ if .AbsoluteHumidity }} +Absolute Humidity: {{ .AbsoluteHumidity }} g/m³
{{ end }}