Skip to content

Commit

Permalink
Switched all the weather references to use OpenWeatherMap.org
Browse files Browse the repository at this point in the history
  • Loading branch information
steinerd committed Oct 3, 2022
1 parent f8528f6 commit bb836f2
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 133 deletions.
4 changes: 2 additions & 2 deletions WeatherPlugin/App.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
Expand All @@ -8,7 +8,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
Expand Down
78 changes: 53 additions & 25 deletions WeatherPlugin/Commands/WeatherCommand.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
namespace Loupedeck.WeatherPlugin.Commands
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Timers;

using Timer = System.Timers.Timer;

public class WeatherCommand : PluginDynamicCommand
public sealed class WeatherCommand : PluginDynamicCommand
{
private readonly Services.WeatherApiService weatherApiService = new Services.WeatherApiService();
private CancellationToken _instanceCancellation = new CancellationToken();

private readonly Services.WeatherApiService _weatherApiService;
private readonly static WeatherPlugin Parent = WeatherPlugin.Instance;
private System.Timers.Timer Timer = new Timer(TimeSpan.FromMinutes(5).TotalMilliseconds) { Enabled = false, AutoReset = true };
private readonly Timer Timer = new Timer(TimeSpan.FromMinutes(15).TotalMilliseconds) { Enabled = false, AutoReset = true };

static internal ConcurrentDictionary<string, Data> DataCache = new ConcurrentDictionary<string, Data>();

internal IDictionary<string, Data> DataCache = new Dictionary<string, Data>();

internal class Data
{
Expand All @@ -30,9 +36,11 @@ internal class Data

public WeatherCommand() : base("Locations", "Weather Locations", "Weather Locations")
{
this.MakeProfileAction("text;Use Zip, City Name, Postal Code, or even IP address to help get location. The input must be 'Location:API Key[:HideName]' Example: Paris:6dc3123b6e844f9e9580b205552a8c");
this.MakeProfileAction("text;Use zip then 2-letter ISO Country Code.\n\tThe input must look like 'Zip,ISOCountryCode:API Key[:HideName]'\n\tExample: 14220,US:6dc3123b6e844f9e9580b205552a8c");
this.Timer.Elapsed += this.OnTimerElapse;
this.Timer.Enabled = true;

this._weatherApiService = new Services.WeatherApiService();
}

protected override Boolean OnLoad()
Expand All @@ -42,29 +50,38 @@ protected override Boolean OnLoad()

private void OnTimerElapse(object sender, ElapsedEventArgs e)
{
foreach (var ap in this.DataCache.Keys)
foreach (var ap in DataCache.Keys)
{
this.RetrieveData(ap);
this.RetrieveData(ap, this._instanceCancellation);
this.ActionImageChanged(ap);
DataCache.TryRemove(ap, out var _);
}

this.Timer.AutoReset = true;
this.Timer.Enabled = true;
this._instanceCancellation = new CancellationToken(false);
}

protected override BitmapImage GetCommandImage(String actionParameter, PluginImageSize imageSize)
{
if (string.IsNullOrEmpty(actionParameter))
{
return null;
}

Data data = this.GetData(actionParameter);
if (!data.IsValid)
{
return null;
}

var iconBuilder = new BitmapBuilder(imageSize);
iconBuilder.Clear(BitmapColor.Black);

if (data.Icon != null)
{
iconBuilder.DrawImage(data.Icon);
}

iconBuilder.FillRectangle(0, 0, iconBuilder.Width, iconBuilder.Height, new BitmapColor(0, 0, 0, 128));

Expand All @@ -74,8 +91,16 @@ protected override BitmapImage GetCommandImage(String actionParameter, PluginIma
locationName = $"{data.Name}\n\u00a0\n";
}

iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.Black, fontSize: 17);
iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.White);
if(data.Temperature.C != data.Temperature.F)
{
iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.Black, fontSize: 17);
iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.White);
}
else
{
iconBuilder.DrawText($"PARAMETER\nERROR", color: BitmapColor.Black, fontSize: 17);
iconBuilder.DrawText($"PARAMETER\nERROR", color: BitmapColor.White);
}

var renderedImage = iconBuilder.ToImage();
iconBuilder.Dispose();
Expand All @@ -85,15 +110,19 @@ protected override BitmapImage GetCommandImage(String actionParameter, PluginIma

protected override void RunCommand(String actionParameter) => System.Diagnostics.Process.Start($"weather:{actionParameter.Split(':')[0]}");

private async void RetrieveData(string actionParameter)
private async void RetrieveData(string actionParameter, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(actionParameter))
{
return;
}

Data data = this.GetData(actionParameter);

if (data.IsLoading)
{
return;
}

data.IsLoading = true;

Expand All @@ -108,22 +137,19 @@ private async void RetrieveData(string actionParameter)
data.HideName = bool.Parse(paramArgs[2] ?? "false");
}

Models.Weather weather = null;
try
{
weather = await this.weatherApiService.GetCurrentWeather(locationQuery, apiKey);
}
catch (Exception ex)
var weather = await this._weatherApiService.GetCurrentWeather(locationQuery, apiKey, cancellationToken);
if (weather == null)
{
// Data is from an older version, clearing.
data.Name = "ERR";
data.Temperature = (C: 0, F: 0);
return;
}

data.Name = weather.location.name;
data.Temperature = (C: weather.current.temp_c, F: weather.current.temp_f);

var iconBytes = await this.weatherApiService.GetIconBytes(weather);
data.Icon = BitmapImage.FromBase64String(Convert.ToBase64String(iconBytes));
data.Name = weather.name;
data.Temperature = (C: weather.main.celsius, F: weather.main.fahrenheit);

data.Icon = BitmapImage.FromBase64String(Convert.ToBase64String(weather.weather[0].iconBytes));
}
finally
{
Expand All @@ -135,13 +161,15 @@ private async void RetrieveData(string actionParameter)

private Data GetData(string actionParameter)
{
if (this.DataCache.TryGetValue(actionParameter, out var data))
if (DataCache.TryGetValue(actionParameter, out var data))
{
return data;
}

data = new Data();
this.DataCache.Add(actionParameter, data);

this.RetrieveData(actionParameter);
DataCache.TryAdd(actionParameter, data);
this.RetrieveData(actionParameter, this._instanceCancellation);

return data;
}
Expand Down
64 changes: 0 additions & 64 deletions WeatherPlugin/Models/Weather.cs

This file was deleted.

76 changes: 76 additions & 0 deletions WeatherPlugin/Models/WeatherResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
namespace Loupedeck.WeatherPlugin.Models
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public sealed class WeatherResponse
{
public Coord coord { get; set; }
public Weather[] weather { get; set; }
public string _base { get; set; }
public Main main { get; set; }
public int visibility { get; set; }
public Wind wind { get; set; }
public Clouds clouds { get; set; }
public int dt { get; set; }
public Sys sys { get; set; }
public int timezone { get; set; }
public int id { get; set; }
public string name { get; set; }
public int cod { get; set; }
}

public sealed class Coord
{
public float lon { get; set; }
public float lat { get; set; }
}

public sealed class Main
{
public float temp { get; set; }
public float feels_like { get; set; }
public float temp_min { get; set; }
public float temp_max { get; set; }
public int pressure { get; set; }
public int humidity { get; set; }
public float celsius => (float)(this.temp - 273.15);
public float fahrenheit => (float)((this.temp - 273.15) * 9 / 5 + 32);
}

public sealed class Wind
{
public float speed { get; set; }
public int deg { get; set; }
public float gust { get; set; }
}

public sealed class Clouds
{
public int all { get; set; }
}

public sealed class Sys
{
public int type { get; set; }
public int id { get; set; }
public string country { get; set; }
public int sunrise { get; set; }
public int sunset { get; set; }
}

public sealed class Weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }

public byte[] iconBytes { get; set; }
}

}
Loading

0 comments on commit bb836f2

Please sign in to comment.