Skip to content

MikeManzo/AmbientWeatherSocket

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AmbientWeather

A Swift package for real-time WebSocket connectivity to Ambient Weather personal weather stations. Receive live weather observations directly in your iOS and macOS apps via the Ambient Weather Realtime API.

Features

  • Real-time WebSocket streaming — Connects to rt2.ambientweather.net for live weather data pushed to your app as it arrives
  • SwiftUI-readyObservableObject conformance with @Published properties for seamless SwiftUI integration
  • Automatic reconnection — Handles disconnects gracefully with configurable retry intervals and heartbeat keep-alive
  • Comprehensive data model — Decodes 100+ sensor data points covering temperature, humidity, wind, rain, lightning, soil, air quality, and more
  • Built-in unit conversions — Temperature (F/C/K), pressure (inHg/mb/kPa/hPa), wind speed (MPH/KPH/Knots), rainfall (in/cm/mm)
  • Sensor discovery — Automatically detects which sensors are active and groups them by category
  • Connection status indicator — Drop-in SwiftUI view showing connection state (green/orange/red)
  • Structured logging — Uses OSLog for organized, filterable debug output
  • Multi-station support — Subscribe to multiple weather stations with separate API keys

Requirements

Platform Minimum Version
iOS 16.0
macOS 15.0
Swift 6.1

Installation

Swift Package Manager

Add AmbientWeather to your project via Xcode:

  1. Go to File > Add Package Dependencies...
  2. Enter the repository URL:
    https://github.com/MikeManzo/AmbientWeatherSocket.git
    
  3. Select the version rule and add the package

Or add it directly to your Package.swift:

dependencies: [
    .package(url: "https://github.com/MikeManzo/AmbientWeatherSocket.git", from: "1.0.0")
]

Then add the dependency to your target:

.target(
    name: "YourApp",
    dependencies: ["AmbientWeather"]
)

Getting Started

1. Obtain API Keys

You'll need an Application Key and one or more API Keys from the Ambient Weather Dashboard.

2. Connect to Your Station

import AmbientWeather

// Create the WebSocket controller
let weather = AmbientWebSocket(applicationKey: "your-application-key")

// Connect to your station(s)
weather.connectStations(apiKeys: ["your-api-key"])

3. Use in SwiftUI

import SwiftUI
import AmbientWeather

struct WeatherView: View {
    @StateObject private var weather = AmbientWebSocket(applicationKey: "your-app-key")

    var body: some View {
        VStack {
            HStack {
                Text("Station Status")
                weather.connectionIndicator
            }

            if let data = weather.weatherData {
                Text("Station: \(data.info.name)")
                Text("Temperature: \(data.observation.tempF ?? 0, specifier: "%.1f")°F")
                Text("Humidity: \(data.observation.humidity ?? 0)%")
                Text("Wind: \(data.observation.windSpeedMPH ?? 0, specifier: "%.1f") MPH \(data.observation.cardinalWindDirection ?? "")")
                Text("Last Updated: \(data.observation.observationDateFormatted)")
            } else {
                ProgressView("Waiting for data...")
            }
        }
        .onAppear {
            weather.connectStations(apiKeys: ["your-api-key"])
        }
    }
}

Data Model

AmbientWeatherData

The top-level object received for each station update:

Property Type Description
observation AmbientLastData Latest sensor readings
stationID String Station MAC address
info AmbientStationInfo Station name, location, and coordinates
availableSensors [String: Any] Dictionary of all sensors currently reporting

Sensor Categories

Sensor data is organized into categories via the SensorCategory enum, each with an associated SF Symbol icon:

Category Icon Example Sensors
Temperature thermometer.high tempF, tempInF, feelsLike
Humidity & Dew Point humidity humidity, dewPoint, humidityIn
Atmospheric Pressure gauge baromAbsIn, baromRelIn
Wind wind windSpeedMPH, windGustMPH, windDir
Rain/Precipitation cloud.rain dailyRainIn, weeklyRainIn, yearlyRainIn
Solar & UV sun.max solarRadiation, uv
Lightning bolt lightningHour, lightningDistance
Soil Temperature thermometer.and.liquid.waves soiltemp1f through soiltemp10f
Soil Moisture water.waves soilhum1 through soilhum10
Air Quality air.purifier pm25, co2
Leak Detection water.waves.and.arrow.trianglehead.down leak1 through leak4
Battery Status battery.100percent.bolt battIn, battOut, battRain

Unit Conversions

Built-in computed properties provide instant unit conversions:

let data = weather.weatherData?.observation

// Temperature
data?.tempC          // Celsius
data?.tempK          // Kelvin

// Wind
data?.windSpeedKPH   // Kilometers per hour
data?.windSpeedKnots // Knots
data?.cardinalWindDirection // "N", "NNE", "NE", etc.

// Pressure
data?.baromRelMb     // Millibars
data?.baromRelkPa    // Kilopascals
data?.baromRelhPa    // Hectopascals

// Rain
data?.dailyRainCm    // Centimeters
data?.dailyRainMm    // Millimeters

Configuration

Heartbeat Interval

Keep the WebSocket connection alive (default: 30 seconds):

weather.setHeartBeatInterval(60.0) // Ping every 60 seconds

Reconnect Interval

Time to wait before reconnecting after a disconnect (default: 2 seconds):

weather.setReconnectInterval(5.0) // Wait 5 seconds before reconnecting

Disconnect

weather.disconnectStations()

Supported Weather Stations

This package works with any Ambient Weather station that reports data through the Ambient Weather API, including:

  • WS-5000 series
  • WS-2902 series
  • And other compatible stations

The data model follows the official Device Data Specs.

Dependencies

  • Starscream (4.0.8+) — WebSocket client library

License

See LICENSE for details.

Acknowledgements

About

A Swift package for real-time WebSocket connectivity to Ambient Weather personal weather stations

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages