weatherflow

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2023 License: MIT Imports: 10 Imported by: 2

README

weatherflow

weatherflow is a Go module for streaming rapid observations from the WeatherFlow Tempest API.

Installation

go get -u github.com/tris/weatherflow

Example

import (
	"fmt"
	"log"
	"github.com/tris/weatherflow"
)

func main() {
	client := weatherflow.NewClient("your-token-here", nil, log.Printf)

	client.AddDevice(12345)

	client.Start(func(msg weatherflow.Message) {
		switch m := msg.(type) {
		case *weatherflow.MessageObsSt:
			fmt.Printf("Observation: %+v\n", m)
		case *weatherflow.MessageRapidWind:
			fmt.Printf("Rapid wind: %+v\n", m)
		}
	})

	time.Sleep(30 * time.Second)

	client.Stop()
}

Limitations

  • Only Tempest and Rapid Wind observations are passed:
    • Acknowledgement (ack)
    • Rain Start Event (evt_precip)
    • Lightning Strike Event (evt_strike)
    • Device Online Event (evt_device_online)
    • Device Offline Event (evt_device_offline)
    • Station Online Event (evt_station_online)
    • Station Offline Event (evt_station_online)
    • Rapid Wind (3 sec) (rapid_wind)
    • Observation (Air) (obs_air)
    • Observation (Sky) (obs_sky)
    • Observation (Tempest) (obs_st)

Known issues

  • obs_st messages are unreliable. In particular, if you issue listen_start for the same device on two separate WebSocket connections, both will reply with ack but only the first connection will receive any obs_st messages, save for an initial reading from cache.

    You can verify this behavior using wscat (run two copies):

    wscat -c wss://ws.weatherflow.com/swd/data?token=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -x '{"type":"listen_start","device_id":123456,"id":""}' -w 180
    

    This does not seem to be an issue for rapid_wind messages.

    Note that Add() will issue both listen_start and listen_rapid_start; there is currently no way to listen only to one type. (I may change this in the future if WeatherFlow says the aforementioned behavior is intentional.)

    Further details: WebSocket API issue with obs_st messages

Credit

I took a bit of inspiration from the excellent goweatherflow module, which you should use instead if your Tempest is on the same LAN.

Documentation

Overview

Package weatherflow provides a client for accessing WeatherFlow's Smart Weather API over a WebSocket connection.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client represents a client for the WeatherFlow Smart Weather API.

func NewClient

func NewClient(token string, timeout *time.Duration, logf Logf) *Client

NewClient creates a new Client with the given API token, optional connection timeout, and an optional log function (if nil, logs will be discarded).

func (*Client) AddDevice added in v0.2.0

func (c *Client) AddDevice(id int)

AddDevice subscribes to wind events for a device ID.

func (*Client) DeviceCount added in v0.2.0

func (c *Client) DeviceCount() int

DeviceCount returns a count of monitored devices.

func (*Client) RemoveDevice added in v0.2.0

func (c *Client) RemoveDevice(id int)

RemoveDevice unsubscribes from wind events for a device ID.

func (*Client) SetURL

func (c *Client) SetURL(url string)

SetURL overrides the server URL (for testing).

func (*Client) Start

func (c *Client) Start(onMessage func(Message))

Start initiates a WebSocket connection to the WeatherFlow server and processes incoming messages.

func (*Client) Stop

func (c *Client) Stop()

type Logf

type Logf func(format string, args ...interface{})

Logf is a function type for logging messages in the WeatherFlowClient. This is compatible with e.g. log.Printf.

type Message

type Message interface {
	GetType() string
	GetDeviceID() (int, bool)
}

func UnmarshalMessage

func UnmarshalMessage(data []byte) (Message, error)

type MessageAck added in v0.3.0

type MessageAck struct {
	ID   string `json:"id"`
	Type string `json:"type"`
}

func (*MessageAck) GetDeviceID added in v0.3.1

func (w *MessageAck) GetDeviceID() (int, bool)

func (*MessageAck) GetType added in v0.3.0

func (w *MessageAck) GetType() string

type MessageConnectionOpened added in v0.3.0

type MessageConnectionOpened struct {
	Type string `json:"type"`
}

func (*MessageConnectionOpened) GetDeviceID added in v0.3.1

func (w *MessageConnectionOpened) GetDeviceID() (int, bool)

func (*MessageConnectionOpened) GetType added in v0.3.0

func (w *MessageConnectionOpened) GetType() string

type MessageObsSt

type MessageObsSt struct {
	Status   ObsStStatus  `json:"status"`
	DeviceID int          `json:"device_id"`
	Type     string       `json:"type"`
	Source   string       `json:"source"`
	Summary  ObsStSummary `json:"summary"`
	Obs      []ObsStData  `json:"obs"`
}

func (*MessageObsSt) GetDeviceID

func (w *MessageObsSt) GetDeviceID() (int, bool)

func (*MessageObsSt) GetType

func (w *MessageObsSt) GetType() string

type MessageRapidWind

type MessageRapidWind struct {
	DeviceID     int           `json:"device_id"`
	SerialNumber string        `json:"serial_number"`
	Type         string        `json:"type"`
	HubSN        string        `json:"hub_sn"`
	Ob           RapidWindData `json:"ob"`
}

func (*MessageRapidWind) GetDeviceID

func (w *MessageRapidWind) GetDeviceID() (int, bool)

func (*MessageRapidWind) GetType

func (w *MessageRapidWind) GetType() string

type ObsStData

type ObsStData struct {
	TimeEpoch                       int      `json:"time_epoch"`
	WindLull                        float64  `json:"wind_lull"`
	WindAvg                         float64  `json:"wind_avg"`
	WindGust                        float64  `json:"wind_gust"`
	WindDirection                   int      `json:"wind_direction"`
	WindSampleInterval              int      `json:"wind_sample_interval"`
	StationPressure                 float64  `json:"station_pressure"`
	AirTemperature                  *float64 `json:"air_temperature"`
	RelativeHumidity                *float64 `json:"relative_humidity"`
	Illuminance                     int      `json:"illuminance"`
	UV                              int      `json:"uv"`
	SolarRadiation                  int      `json:"solar_radiation"`
	RainAccumulated                 float64  `json:"rain_accumulated"`
	PrecipitationType               int      `json:"precipitation_type"`
	LightningStrikeAvgDistance      int      `json:"lightning_strike_avg_distance"`
	LightningStrikeCount            int      `json:"lightning_strike_count"`
	Battery                         float64  `json:"battery"`
	ReportInterval                  int      `json:"report_interval"`
	LocalDailyRainAccumulation      float64  `json:"local_daily_rain_accumulation"`
	RainAccumulatedFinal            float64  `json:"rain_accumulated_final"`
	LocalDailyRainAccumulationFinal float64  `json:"local_daily_rain_accumulation_final"`
	PrecipitationAnalysisType       int      `json:"precipitation_analysis_type"`
}

func (*ObsStData) UnmarshalJSON

func (obs *ObsStData) UnmarshalJSON(data []byte) error

type ObsStStatus

type ObsStStatus struct {
	StatusCode    int    `json:"status_code"`
	StatusMessage string `json:"status_message"`
}

type ObsStSummary

type ObsStSummary struct {
	PressureTrend                  string  `json:"pressure_trend"`
	StrikeCount1h                  int     `json:"strike_count_1h"`
	StrikeCount3h                  int     `json:"strike_count_3h"`
	PrecipTotal1h                  float64 `json:"precip_total_1h"`
	StrikeLastDist                 int     `json:"strike_last_dist"`
	StrikeLastEpoch                int     `json:"strike_last_epoch"`
	PrecipAccumLocalYesterday      float64 `json:"precip_accum_local_yesterday"`
	PrecipAccumLocalYesterdayFinal float64 `json:"precip_accum_local_yesterday_final"`
	PrecipAnalysisTypeYesterday    int     `json:"precip_analysis_type_yesterday"`
	RainingMinutes                 []int   `json:"raining_minutes"`
	PrecipMinutesLocalDay          int     `json:"precip_minutes_local_day"`
	PrecipMinutesLocalYesterday    int     `json:"precip_minutes_local_yesterday"`
}

type RapidWindData

type RapidWindData struct {
	TimeEpoch     int     `json:"time_epoch"`
	WindSpeed     float64 `json:"wind_speed"`
	WindDirection int     `json:"wind_direction"`
}

func (*RapidWindData) UnmarshalJSON

func (rw *RapidWindData) UnmarshalJSON(data []byte) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL