|
// Set this to your personal WeatherFlow API key. |
|
const CONFIG_API_KEY = "YOUR API KEY GOES HERE" |
|
|
|
// Set this to your station id. |
|
const CONFIG_STATION_ID = 12345 |
|
|
|
// Set this to true to vary the background color of the widget based on the temperature. |
|
const CONFIG_DYNAMIC_BACKGROUND = false |
|
|
|
// Set this to true to vary the color of the temperature text based on the temperature. |
|
const CONFIG_DYNAMIC_TEMPERATURE = true |
|
|
|
let jsonData = await requestStationData(CONFIG_API_KEY, CONFIG_STATION_ID) |
|
let widget = await createWidget(jsonData) |
|
|
|
if(!config.runsInWidget) { |
|
await widget.presentSmall(); |
|
} |
|
|
|
Script.setWidget(widget) |
|
Script.complete() |
|
|
|
function createWidget(data) { |
|
let w = new ListWidget() |
|
w.spacing = 1 |
|
|
|
w.addSpacer() |
|
|
|
let stationLine = w.addText(data.station_name) |
|
stationLine.font = Font.boldSystemFont(12) |
|
stationLine.textColor = Color.white() |
|
stationLine.centerAlignText() |
|
|
|
let temperature = convertTemperature(data.obs[0].air_temperature, data.station_units.units_temp) |
|
|
|
if(CONFIG_DYNAMIC_BACKGROUND) { |
|
let bgColor = new LinearGradient() |
|
bgColor.colors = [new Color("#000000"), new Color(temperature["color"])] |
|
bgColor.locations = [0.0, 1.0] |
|
w.backgroundGradient = bgColor |
|
} else { |
|
w.backgroundColor = Color.black() |
|
} |
|
|
|
let temperatureLine = w.addText(temperature["display"] + temperature["unit"]) |
|
temperatureLine.font = Font.boldSystemFont(28)//regularSystemFont(30) |
|
|
|
if(CONFIG_DYNAMIC_TEMPERATURE) { |
|
temperatureLine.textColor = new Color(temperature["color"]) |
|
} else { |
|
temperatureLine.textColor = Color.white() |
|
} |
|
|
|
temperatureLine.centerAlignText() |
|
|
|
let humidityLine = w.addText(data.obs[0].relative_humidity + "%") |
|
humidityLine.font = Font.regularSystemFont(12) |
|
humidityLine.textColor = Color.white() |
|
|
|
let precip = convertPrecipitation(data.obs[0].precip_accum_local_day, data.station_units.units_precip) |
|
let precipLine = w.addText(precip["display"] + " " + precip["unit"]) |
|
precipLine.font = Font.regularSystemFont(12) |
|
precipLine.textColor = Color.white() |
|
|
|
wind = convertWindSpeed(data.obs[0].wind_avg, data.station_units.units_wind) |
|
|
|
if(wind == 0) { |
|
displayWind = "Calm" |
|
} else { |
|
windDirection = convertWindDirection(data.obs[0].wind_direction, data.station_units.units_direction) |
|
displayWind = windDirection["display"] + "" + windDirection["unit"] + " " + wind["display"] + " " + wind["unit"] |
|
} |
|
|
|
let windLine = w.addText(displayWind) |
|
windLine.font = Font.regularSystemFont(12) |
|
windLine.textColor = Color.white() |
|
|
|
let pressure = convertPressure(data.obs[0].sea_level_pressure, data.station_units.units_pressure) |
|
let pressureLine = w.addText(pressure["display"] + " " + pressure["unit"] + " " + pressureTrendEmoji(data.obs[0].pressure_trend)) |
|
pressureLine.font = Font.regularSystemFont(12) |
|
pressureLine.textColor = Color.white() |
|
|
|
let lightningLine = w.addText("⚡️" + data.obs[0].lightning_strike_count_last_3hr) |
|
lightningLine.font = Font.regularSystemFont(12) |
|
lightningLine.textColor = Color.white() |
|
|
|
let date = new Date() |
|
let dateFormatter = new DateFormatter() |
|
dateFormatter.useShortTimeStyle() |
|
|
|
let strDate = dateFormatter.string(date) |
|
|
|
let timeStamp = w.addText(strDate) |
|
timeStamp.font = Font.lightSystemFont(10) |
|
timeStamp.textColor = Color.white() |
|
timeStamp.rightAlignText() |
|
|
|
w.addSpacer() |
|
|
|
return w |
|
} |
|
|
|
async function requestStationData(key, id) { |
|
|
|
let url = "https://swd.weatherflow.com/swd/rest/observations/station/" + id + "?api_key=" + key |
|
let req = new Request(url) |
|
let json = await req.loadJSON() |
|
|
|
|
|
return json |
|
} |
|
|
|
function convertTemperature(temperatureValue, targetTemperatureUnit) { |
|
switch(targetTemperatureUnit) { |
|
case "c": // API default |
|
var temperature = temperatureValue |
|
var displayTemperature = temperatureValue.toFixed(1) |
|
var temperatureUnit = "°C" |
|
var temperatureBackgroundColor = temperatureColor(targetTemperatureUnit, temperature) |
|
break |
|
|
|
case "f": |
|
var temperature = (Math.round(((temperatureValue * 9 / 5 + 32) + Number.EPSILON) * 10) / 10) |
|
var displayTemperature = temperature.toFixed(1) |
|
var temperatureUnit = "°F" |
|
var temperatureBackgroundColor = temperatureColor(targetTemperatureUnit, temperature) |
|
break |
|
} |
|
|
|
return {"value": temperature, "display": displayTemperature, "unit": temperatureUnit, "color": temperatureBackgroundColor} |
|
} |
|
|
|
function convertPressure(pressureValue, targetPressureUnit) { |
|
switch(targetPressureUnit) { |
|
case "mb": // API default |
|
var pressure = pressureValue |
|
var displayPressure = pressure.toFixed(1) |
|
var pressureUnit = "mb" |
|
break |
|
|
|
case "inhg": |
|
var pressure = (Math.round(((0.0295301 * pressureValue) + Number.EPSILON) * 100) / 100) |
|
var displayPressure = pressure.toFixed(2) |
|
var pressureUnit = "inHg" |
|
break |
|
|
|
case "mmhg": |
|
var pressure = (Math.round(((0.750062 * pressureValue) + Number.EPSILON) * 100) / 100) |
|
var displayPressure = pressure.toFixed(2) |
|
var pressureUnit = "mmHg" |
|
break |
|
|
|
case "hpa": |
|
var pressure = pressureValue |
|
var displayPressure = pressure.toFixed(1) |
|
var pressureUnit = "hPa" |
|
break |
|
} |
|
|
|
return {"value": pressure, "display": displayPressure, "unit": pressureUnit} |
|
} |
|
|
|
function convertPrecipitation(precipValue, targetPrecipUnit) { |
|
switch(targetPrecipUnit) { |
|
case "mm": // API default |
|
var precip = (Math.round(((precipValue) + Number.EPSILON) * 100) / 100) |
|
var displayPrecip = precip.toFixed(2) |
|
var precipUnit = "mm" |
|
break |
|
|
|
case "in": |
|
var precip = (Math.round(((precipValue * 0.0393701) + Number.EPSILON) * 100) / 100) |
|
var displayPrecip = precip.toFixed(2) |
|
var precipUnit = "in" |
|
break |
|
|
|
case "cm": |
|
var precip = (Math.round(((precipValue * .1) + Number.EPSILON) * 100) / 100) |
|
var displayPrecip = precip.toFixed(2) |
|
var precipUnit = "cm" |
|
break |
|
} |
|
return {"value": precip, "display": displayPrecip, "unit": precipUnit} |
|
} |
|
|
|
function convertWindDirection(windDirectionValue, targetWindUnit) { |
|
switch(targetWindUnit) { |
|
case "degrees": // API default |
|
var displayWindDirection = windDirectionValue |
|
var windDirectionUnit = "°" |
|
break |
|
|
|
case "cardinal": |
|
let compassDirections = ["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","N"] |
|
let index = Math.round((windDirectionValue % 360) / 22.5 ) |
|
|
|
var displayWindDirection = compassDirections[index] |
|
var windDirectionUnit = "" |
|
break |
|
} |
|
|
|
return {"value": windDirectionValue, "display": displayWindDirection, "unit": windDirectionUnit} |
|
} |
|
|
|
function convertWindSpeed(windValue, targetWindUnit) { |
|
switch(targetWindUnit) { |
|
case "mps": // API default |
|
var wind = windValue |
|
var displayWind = wind.toFixed(1) |
|
var windUnit = "m/s" |
|
break |
|
|
|
case "mph": |
|
var wind = (Math.round(((windValue * 2.2369362920544) + Number.EPSILON) * 10) / 10) |
|
var displayWind = wind.toFixed(1) |
|
var windUnit = "mph" |
|
break |
|
|
|
case "kts": |
|
var wind = (Math.round(((windValue * 1.943844) + Number.EPSILON) * 10) / 10) |
|
var displayWind = wind.toFixed(1) |
|
var windUnit = "kts" |
|
break |
|
|
|
case "kph": |
|
var wind = (Math.round(((windValue / (5/18)) + Number.EPSILON) * 10) / 10) |
|
var displayWind = wind.toFixed(1) |
|
var windUnit = "km/h" |
|
break |
|
|
|
case "bft": |
|
var wind = convertBeaufort(windValue) |
|
var displayWind = wind.toFixed(1) |
|
var windUnit = "bft" |
|
break |
|
|
|
case "lfm": |
|
var wind = (Math.round(((windValue * 196.850393700787) + Number.EPSILON) * 10) / 10) |
|
var displayWind = wind.toFixed(1) |
|
var windUnit = "lfm" |
|
break |
|
} |
|
|
|
return {"value": wind, "display": displayWind, "unit": windUnit} |
|
} |
|
|
|
function convertBeaufort(windValue) { |
|
let beaufort = windValue < .3 ? 0 : windValue < 1.6 ? 1 : windValue < 3.5 ? 2 : windValue < 5.5 ? 3 : windValue < 8 ? 4 : windValue < 10.8 ? 5 : windValue < 13.9 ? 6 : windValue < 17.2 ? 7 : windValue < 20.8 ? 8 : windValue < 24.5 ? 9 : windValue < 28.5 ? 10 : windValue < 32.7 ? 11 : windValue >= 32.7 ? 12 : 0; |
|
return beaufort |
|
} |
|
|
|
function temperatureColor(temperatureUnit,temperature) |
|
{ |
|
if(temperatureUnit == "c") { |
|
if ( temperature >= 49 ) { |
|
color = "#af3190" |
|
} else if( temperature >= 46 && temperature < 49) { |
|
color = "#bd2f82" |
|
} else if( temperature >= 43 && temperature < 46) { |
|
color = "#cb2e73" |
|
} else if( temperature >= 41 && temperature < 43) { |
|
color = "#d82d6e" |
|
} else if( temperature >= 38 && temperature < 40) { |
|
color = "#e62c51" |
|
} else if( temperature >= 35 && temperature < 38) { |
|
color = "#ff2e1f" |
|
} else if( temperature >= 32 && temperature < 35) { |
|
color = "#ff6e35" |
|
} else if( temperature >= 30 && temperature < 32) { |
|
color = "#f3934e" |
|
} else if( temperature >= 27 && temperature < 30) { |
|
color = "#f3ad63" |
|
} else if( temperature >= 24 && temperature < 27) { |
|
color = "#eaca73" |
|
} else if( temperature >= 21 && temperature < 24) { |
|
color = "#f4e376" |
|
} else if( temperature >= 18 && temperature < 21) { |
|
color = "#fcf574" |
|
} else if( temperature >= 16 && temperature < 18) { |
|
color = "#deec62" |
|
} else if( temperature >= 13 && temperature < 16) { |
|
color = "#b1ea3e" |
|
} else if( temperature >= 10 && temperature < 13) { |
|
color = "#20e93b" |
|
} else if( temperature >= 7 && temperature < 10) { |
|
color = "#18eca5" |
|
} else if( temperature >= 5 && temperature < 7) { |
|
color = "#11e1be" |
|
} else if( temperature >= 2 && temperature < 5) { |
|
color = "#06d8d8" |
|
} else if( temperature >= -1 && temperature < 2) { |
|
color = "#29cff0" |
|
} else if( temperature >= -4 && temperature < -1) { |
|
color = "#4fb2ef" |
|
} else if( temperature >= -7 && temperature < -4) { |
|
color = "#4e99ee" |
|
} else if( temperature >= -9 && temperature < -7) { |
|
color = "#4b6bf9" |
|
} else if( temperature >= -12 && temperature < -9) { |
|
color = "#8e4cf9" |
|
} else if( temperature >= -15 && temperature < -12) { |
|
color = "#a051e1" |
|
} else if( temperature >= -18 && temperature < -15) { |
|
color = "#ae4fd4" |
|
} else if( temperature >= -21 && temperature < -18) { |
|
color = "#bd4dc7" |
|
} else if( temperature >= -23 && temperature < -21) { |
|
color = "#ae61ba" |
|
} else if( temperature >= -26 && temperature < -23) { |
|
color = "#a07aad" |
|
} else if( temperature >= -29 && temperature < -26) { |
|
color = "#9286a0" |
|
} else if( temperature >= -32 && temperature < -29) { |
|
color = "#8f819e" |
|
} else if( temperature >= -34 && temperature < -32) { |
|
color = "#afa4bc" |
|
} else if( temperature >= -37 && temperature < -34) { |
|
color = "#bdb2ca" |
|
} else if( temperature >= -40 && temperature < -37) { |
|
color = "#d2c3d1" |
|
} else if( temperature >= -43 && temperature < -40) { |
|
color = "#e3dbe2" |
|
} else if( temperature >= -46 && temperature < -43) { |
|
color = "#e4e4eb" |
|
} else if( temperature < -46 ) { |
|
color = "#eaeaea" |
|
} |
|
} else if(temperatureUnit == "f") { |
|
if ( temperature >= 120 ) { |
|
color = "#af3190" |
|
} else if( temperature >= 115 && temperature < 120) { |
|
color = "#bd2f82" |
|
} else if( temperature >= 110 && temperature < 115) { |
|
color = "#cb2e73" |
|
} else if( temperature >= 105 && temperature < 110) { |
|
color = "#d82d6e" |
|
} else if( temperature >= 100 && temperature < 105) { |
|
color = "#e62c51" |
|
} else if( temperature >= 95 && temperature < 100) { |
|
color = "#ff2e1f" |
|
} else if( temperature >= 90 && temperature < 95) { |
|
color = "#ff6e35" |
|
} else if( temperature >= 85 && temperature < 90) { |
|
color = "#f3934e" |
|
} else if( temperature >= 80 && temperature < 85) { |
|
color = "#f3ad63" |
|
} else if( temperature >= 75 && temperature < 80) { |
|
color = "#eaca73" |
|
} else if( temperature >= 70 && temperature < 75) { |
|
color = "#f4e376" |
|
} else if( temperature >= 65 && temperature < 70) { |
|
color = "#fcf574" |
|
} else if( temperature >= 60 && temperature < 65) { |
|
color = "#deec62" |
|
} else if( temperature >= 55 && temperature < 60) { |
|
color = "#b1ea3e" |
|
} else if( temperature >= 50 && temperature < 55) { |
|
color = "#20e93b" |
|
} else if( temperature >= 45 && temperature < 50) { |
|
color = "#18eca5" |
|
} else if( temperature >= 40 && temperature < 45) { |
|
color = "#11e1be" |
|
} else if( temperature >= 35 && temperature < 40) { |
|
color = "#06d8d8" |
|
} else if( temperature >= 30 && temperature < 35) { |
|
color = "#29cff0" |
|
} else if( temperature >= 25 && temperature < 30) { |
|
color = "#4fb2ef" |
|
} else if( temperature >= 20 && temperature < 25) { |
|
color = "#4e99ee" |
|
} else if( temperature >= 15 && temperature < 20) { |
|
color = "#4b6bf9" |
|
} else if( temperature >= 10 && temperature < 15) { |
|
color = "#8e4cf9" |
|
} else if( temperature >= 5 && temperature < 10) { |
|
color = "#a051e1" |
|
} else if( temperature >= 0 && temperature < 5) { |
|
color = "#ae4fd4" |
|
} else if( temperature >= -5 && temperature < 0) { |
|
color = "#bd4dc7" |
|
} else if( temperature >= -10 && temperature < -5) { |
|
color = "#ae61ba" |
|
} else if( temperature >= -15 && temperature < -10) { |
|
color = "#a07aad" |
|
} else if( temperature >= -20 && temperature < -15) { |
|
color = "#9286a0" |
|
} else if( temperature >= -25 && temperature < -20) { |
|
color = "#8f819e" |
|
} else if( temperature >= -30 && temperature < -25) { |
|
color = "#afa4bc" |
|
} else if( temperature >= -35 && temperature < -30) { |
|
color = "#bdb2ca" |
|
} else if( temperature >= -40 && temperature < -35) { |
|
color = "#d2c3d1" |
|
} else if( temperature >= -45 && temperature < -40) { |
|
color = "#e3dbe2" |
|
} else if( temperature >= -50 && temperature < -45) { |
|
color = "#e4e4eb" |
|
} else if( temperature < -50 ) { |
|
color = "#eaeaea" |
|
} |
|
} |
|
|
|
return color |
|
} |
|
|
|
function pressureTrendEmoji(trend) { |
|
var pTrend = { "falling": "↓", "rising": "↑", "steady": "" } |
|
return pTrend[trend] |
|
} |
|
|
This is awesome, thanks for doing it. One suggested change: Weatherflow is sending down the timestamp of the observation, which IMO is technically the more correct time to display in the Widget. You can use it by changing line 87 to: