SmartThings Integration

If you don’t want to wait for Tempest, are a couple of solutions available from the SmartThings community. An Edge Driver was written that can utilize the Tempest API to get data from your station. It does require you to run a basic bridge server to act as a mediary between the driver and Tempest.

Another option is to run MQTT Integration Solutions using MQTT - Devices & Integrations - SmartThings Community which can be integrated. Here is a Python program I wrote that updates devices I created in SmartThings with the MQTT Edge Driver through the Tempest websocket. I use this to display all of my info on a wall mounted tablet, its shows the windspeed and direction in real time.

#!/bin/python3
from datetime import datetime
import websocket 
import json
import requests
import sys
import time
import paho.mqtt.client as mqtt
import logging
from logging.handlers import TimedRotatingFileHandler
from logging import Formatter
from websockets.exceptions import ConnectionClosed

logger = logging.getLogger(__name__)
handler = TimedRotatingFileHandler(filename='mqttwebsocket.log', when='midnight', interval=1, backupCount=10, encoding='utf-8', delay=False)
formatter = Formatter(fmt='%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

ws = websocket.WebSocket()
broker = "localhost"
gustList = []

def connect_mqtt():
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            logger.info("Connected to MQTT Broker!")
        else:
            logger.warning("Failed to connect, return code %d\n", rc)
    client = mqtt.Client("websocketClient")
    client.username_pw_set("username", "password")
    client.on_connect = on_connect
    client.connect(broker)
    return client

try:
    client = connect_mqtt()
    client.loop_start()

    while True:
        try:
            ws.connect("wss://ws.weatherflow.com/swd/data?token=myToken")
        except Exception as e:
            exec_tye, exec_obj, exec_tb = sys.exc_info()
            logger.error("Exception on line " + str(exc_tb.tb_lineno) + ": " + str(e))
            time.sleep(5)
            continue
        logger.info("Connected to Weatherflow websocket")
        ws.send('{"type":"listen_start", "device_id":device_id, "id": "Tempest"}')
        logger.info("Listen_start sent to websocket")
        while True:
            try:
                data = ws.recv()
                d = json.loads(data)
            except (ConnectionClosed):
                logger.warning("Websocket Connection closed")
                time.sleep(1)
                break
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                logger.error("Excpetion on line " + str(exc_tb.tb_lineno) + ": " + str(e))
                ws.close()
                time.sleep(1)
                break
            try:
                if d['type'] == "obs_st":
                    windAvg = d['obs'][0][2] * 2.23694
                    windGust = d['obs'][0][3] * 2.23694
                    humidity = d['obs'][0][8]
                    illuminance = d['obs'][0][9]
                    uv = d['obs'][0][10]
                    rainToday = str(round(d['obs'][0][18] * .0393701, 2)) + "\""
                    strike1hr = d['summary']['strike_count_1h']
                    strikeDist = d['summary']['strike_last_dist']
                    feelsLike = d['summary']['feels_like']
            
                    if len(gustList) >= 10:
                        gustList.pop(0)
                    gustList.append(windGust)

                    client.publish("tempest/windavg", windAvg)
                    logger.info("Published wind avg: " + str(windAvg))
                    client.publish("tempest/windgust", windGust)
                    logger.info("Published wind gust: " + str(windGust))
                    client.publish("tempest/maxgust", max(gustList))
                    logger.info("Published max gust: " + str(max(gustList)))
                    client.publish("tempest/humidity", humidity)
                    logger.info("Published humidity: " + str(humidity))
                    client.publish("tempest/lux", illuminance)
                    logger.info("Published illuminance: " + str(illuminance))
                    client.publish("tempest/uv", uv)
                    logger.info("Published uv: " + str(uv))
                    client.publish("tempest/rain", rainToday)
                    logger.info("Published rainfall: " + str(rainToday))
                    client.publish("tempest/strike1hr", strike1hr)
                    logger.info("Published strikes last hour: " + str(strike1hr))
                    client.publish("tempest/strikedist", strikeDist)
                    logger.info("Published strike dist: " + str(strikeDist))
                    client.publish("tempest/feelslike", feelsLike)
                    logger.info("Published feels like: " + str(feelsLike))
            except Exception as e:
                exc_type, exc_obj, exc_tb = sys.exc_info()
                logger.error("Excpetion on line " + str(exc_tb.tb_lineno) + ": " + str(e))
                ws.close()
                time.sleep(1)
                break
except KeyboardInterrupt:
    logger.info("Keyboard Interrupt. Exiting")
    ws.send('{"type":"listen_stop", "device_id":device_id, "id": "Tempest"}')
    ws.close()
    exit()
except Exception as e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    logger.critical("Excpetion on line " + str(exc_tb.tb_lineno) + ": " + str(e))
1 Like