#!/usr/bin/env guile3.0 !# (use-modules (web client) (json) (rnrs bytevectors) (ice-9 receive)) (define api-key "99631af2d6db903d1f689c7d2cb13764") (define city-id "5809844") (define units "metric") ;; Construct the openweathermap URL with API token, city ID, and unit of measurement (define weather-url (format #f "http://api.openweathermap.org/data/2.5/weather?id=~a&units=~a&appid=~a" city-id units api-key)) ;; Define weather icons as an association list (define weather-icons '(("clear sky" . "☀️") ("few clouds" . "🌤️") ("scattered clouds" . "🌥️") ("broken clouds" . "☁️") ("overcast clouds" . "☁️") ("shower rain" . "🌦️") ("light rain" . "🌧️") ("light intensity drizzle" . "🌧️") ("rain" . "🌧️") ("moderate rain" . "🌧️") ("thunderstorm" . "⛈️") ("snow" . "❄️") ("mist" . "🌫️") ("haze" . "🌫️") ("smoke" . "🌫️") ("fog" . "🌫️"))) ;; Convert Celsius to Fahrenheit (define (celsius-to-fahrenheit celsius) (+ (* celsius (/ 9 5)) 32)) ;; Get weather icon based on description (define (get-weather-icon description) (or (assoc-ref weather-icons description) "❓")) ;; Parse and extract weather data from JSON (define (extract-weather-data json-data) (let* ((main (assoc "main" json-data)) (temp-c (and main (cdr (assoc "temp" (cdr main))))) ;; Round and convert to exact integer (temp-c-value (and temp-c (inexact->exact (round temp-c)))) (weather-description (cdr (assoc "description" (vector-ref (cdr (assoc "weather" json-data)) 0))))) ;; Return temperature (C, F), description, and icon (values temp-c-value (and temp-c-value (inexact->exact (round (celsius-to-fahrenheit temp-c-value)))) weather-description (get-weather-icon weather-description)))) ;; Fetch and display weather data (define (get-weather) ;; Request and parse the data (receive (response-status response-body) (http-request weather-url) (let ((json-data (json-string->scm (utf8->string response-body)))) (call-with-values (lambda () (extract-weather-data json-data)) (lambda (temp-c temp-f description icon) ;; For debugging ;;(format #t "Description: ~a ~%" description) ;; Display the weather information (if temp-c (format #t "~a ~d°C / ~d°F~%" icon temp-c temp-f) (display "Error: Temperature data not available.\n"))))))) (get-weather)