diff --git a/PWSPublish/ambientproxy.py b/PWSPublish/ambientproxy.py new file mode 100644 index 0000000..7ae37e2 --- /dev/null +++ b/PWSPublish/ambientproxy.py @@ -0,0 +1,20 @@ +import asyncio +import json +import websockets + +class Proxy: + def __init__(self, host="ambient-proxy", port=8080, method="ws", verbose=False): + self.uri = f"{method}://{host}:{port}" + self.verbose = verbose + + async def run_loop(self, callback): + if self.verbose: + print(f"ambient-proxy: connecting to {self.uri}") + async with websockets.connect(self.uri) as websocket: + if self.verbose: + print(f"ambient-proxy: connected to {self.uri}") + while 1: + data = await websocket.recv() + if self.verbose: + print(f"ambient-proxy: received data - {data}") + callback(json.loads(data)) \ No newline at end of file diff --git a/README.md b/README.md index bc7a3c6..00b2cea 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,29 @@ Your Wunderground API key is found under [member settings](https://www.wundergro Create an API key and Application Key under your [Ambient Weather account](https://ambientweather.net/account) -You will need to have either `--wunderground` or `--ambient-weather` as arguments, or it won't connect to either. +You will need to have either `--wunderground`, `--ambient-weather`, `--ambient-proxy` as arguments, or it won't connect to anything. + +## Ambient Proxy + +[ambient-proxy](https://github.com/drakeapps/ambient-proxy) is a simple node websocket server that's just replaying the data received from the Ambient Weather Realtime API. I have continuously had issues with the Ambient Weather socket-io API, but have had zero issues with the node one. + +This is a way to use the Node library but maintain all the + +There is a docker-compose target, `publish-ambient-proxy`, that will pull and run the proxy. This uses the same environment variables as the normal Ambient Weather container. ## Command Line Arguments ``` -python main.py -h -usage: main.py [-h] [--wunderground] --api-key API_KEY --station-id STATION_ID - [--ambient-weather] [--application-key APPLICATION_KEY] - [--influx] [--influx-host INFLUX_HOST] - [--influx-port INFLUX_PORT] [--influx-db INFLUX_DB] +python main.py -h +usage: main.py [-h] [--wunderground] [--api-key API_KEY] + [--station-id STATION_ID] [--ambient-weather] + [--ambient-api-key AMBIENT_API_KEY] + [--application-key APPLICATION_KEY] [--ambient-proxy] + [--ambient-proxy-host AMBIENT_PROXY_HOST] + [--ambient-proxy-port AMBIENT_PROXY_PORT] + [--ambient-proxy-method AMBIENT_PROXY_METHOD] [--influx] + [--influx-host INFLUX_HOST] [--influx-port INFLUX_PORT] + [--influx-db INFLUX_DB] [--influx-measurement INFLUX_MEASUREMENT] [--websocket] [--websocket-host WEBSOCKET_HOST] [--websocket-port WEBSOCKET_PORT] [--mqtt] @@ -28,12 +41,22 @@ Wunderground/Ambient Weather PWS Publisher optional arguments: -h, --help show this help message and exit --wunderground enable wunderground api polling - --api-key API_KEY wunderground/ambient weather api key + --api-key API_KEY wunderground weather api key --station-id STATION_ID wunderground station id --ambient-weather enable ambient weather api stream + --ambient-api-key AMBIENT_API_KEY + ambient weather api key --application-key APPLICATION_KEY ambient weather application key + --ambient-proxy enable ambient weather api stream using a separate + ambient websocket proxy + --ambient-proxy-host AMBIENT_PROXY_HOST + ambient weather proxy host + --ambient-proxy-port AMBIENT_PROXY_PORT + ambient weather proxy port + --ambient-proxy-method AMBIENT_PROXY_METHOD + ambient weather proxy method (ws or wss) --influx publish to influxdb --influx-host INFLUX_HOST InfluxDB Host diff --git a/docker-compose.yml b/docker-compose.yml index 9b310ff..59ce278 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,5 +18,22 @@ services: ports: - 6789:6789 env_file: .env - command: --ambient-api-key ${AMBIENT_API_KEY} --station-id ${STATION_ID} --application-key ${APPLICATION_KEY}--ambient-weather --mqtt --mqtt-broker mqtt.xrho.com --websocket --refresh-rate 60 --influx-host o.xrho.com --verbose --mqtt-prefix ambientWeather --influx --influx-db ambient-weather + command: --ambient-api-key ${AMBIENT_API_KEY} --station-id ${STATION_ID} --application-key ${APPLICATION_KEY} --ambient-weather --mqtt --mqtt-broker mqtt.xrho.com --websocket --websocket-host 0.0.0.0 --refresh-rate 60 --influx-host o.xrho.com --verbose --mqtt-prefix ambientWeather --influx --influx-db ambient-weather + ambient-proxy: + image: ghcr.io/drakeapps/ambient-proxy + restart: unless-stopped + env_file: .env + expose: + - 8080 + publish-ambient-proxy: + image: ghcr.io/drakeapps/pws-publish + restart: unless-stopped + build: + context: . + ports: + - 6789:6789 + env_file: .env + depends_on: + - ambient-proxy + command: --station-id ${STATION_ID} --ambient-proxy --ambient-proxy-host ambient-proxy --ambient-proxy-port 8080 --mqtt --mqtt-broker mqtt.xrho.com --websocket --websocket-host 0.0.0.0 --refresh-rate 60 --influx-host o.xrho.com --verbose --mqtt-prefix ambientWeather --influx --influx-db ambient-weather diff --git a/main.py b/main.py index b34416a..0600fab 100644 --- a/main.py +++ b/main.py @@ -4,6 +4,7 @@ from PWSPublish import wunderground from PWSPublish import ambient +from PWSPublish import ambientproxy from PWSPublish import mqtt from PWSPublish import websocket from PWSPublish import influxdb @@ -19,6 +20,11 @@ parser.add_argument('--ambient-api-key', help="ambient weather api key") parser.add_argument('--application-key', help="ambient weather application key") +parser.add_argument('--ambient-proxy', help="enable ambient weather api stream using a separate ambient websocket proxy", action='store_true') +parser.add_argument('--ambient-proxy-host', help="ambient weather proxy host", default="ambient-proxy") +parser.add_argument('--ambient-proxy-port', help="ambient weather proxy port", type=int, default=8080) +parser.add_argument('--ambient-proxy-method', help="ambient weather proxy method (ws or wss)", default="ws") + parser.add_argument('--influx', help='publish to influxdb', action='store_true') parser.add_argument("--influx-host", help="InfluxDB Host", default="localhost") parser.add_argument("--influx-port", help="InfluxDB Port", type=int, default=8086) @@ -44,15 +50,26 @@ args = parser.parse_args() if args.wunderground: + if args.verbose: + print(f"Wunderground enabled") wunderground_api = wunderground.API(args.api_key, args.station_id, units=args.units, verbose=args.verbose) else: wunderground_api = None if args.ambient_weather: + if args.verbose: + print(f"Ambient Weather enabled") ambient_weather_api = ambient.Stream(args.api_key, args.application_key, device=args.station_id, verbose=args.verbose) else: ambient_weather_api = None +if args.ambient_proxy: + if args.verbose: + print(f"Ambient Weather proxy enabled") + ambient_proxy = ambientproxy.Proxy(host=args.ambient_proxy_host, port=args.ambient_proxy_port, method=args.ambient_proxy_method, verbose=args.verbose) +else: + ambient_proxy = None + if args.mqtt: if args.verbose: print(f"MQTT enabled") @@ -114,6 +131,9 @@ async def main(): task = asyncio.create_task(ambient_weather_api.run_loop(publish_data)) tasks.add(task) + if ambient_proxy: + task = asyncio.create_task(ambient_proxy.run_loop(publish_data)) + await asyncio.gather(*tasks)