Skip to content
This repository was archived by the owner on Oct 26, 2024. It is now read-only.

Commit bb836f2

Browse files
committed
Switched all the weather references to use OpenWeatherMap.org
1 parent f8528f6 commit bb836f2

File tree

9 files changed

+288
-133
lines changed

9 files changed

+288
-133
lines changed

WeatherPlugin/App.config

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<configuration>
33
<runtime>
44
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
@@ -8,7 +8,7 @@
88
</dependentAssembly>
99
<dependentAssembly>
1010
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
11-
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
11+
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
1212
</dependentAssembly>
1313
<dependentAssembly>
1414
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />

WeatherPlugin/Commands/WeatherCommand.cs

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
namespace Loupedeck.WeatherPlugin.Commands
22
{
33
using System;
4+
using System.Collections.Concurrent;
45
using System.Collections.Generic;
6+
using System.Data;
7+
using System.IO;
58
using System.Linq;
69
using System.Text;
710
using System.Threading;
811
using System.Timers;
912

1013
using Timer = System.Timers.Timer;
1114

12-
public class WeatherCommand : PluginDynamicCommand
15+
public sealed class WeatherCommand : PluginDynamicCommand
1316
{
14-
private readonly Services.WeatherApiService weatherApiService = new Services.WeatherApiService();
17+
private CancellationToken _instanceCancellation = new CancellationToken();
18+
19+
private readonly Services.WeatherApiService _weatherApiService;
1520
private readonly static WeatherPlugin Parent = WeatherPlugin.Instance;
16-
private System.Timers.Timer Timer = new Timer(TimeSpan.FromMinutes(5).TotalMilliseconds) { Enabled = false, AutoReset = true };
21+
private readonly Timer Timer = new Timer(TimeSpan.FromMinutes(15).TotalMilliseconds) { Enabled = false, AutoReset = true };
22+
23+
static internal ConcurrentDictionary<string, Data> DataCache = new ConcurrentDictionary<string, Data>();
1724

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

2026
internal class Data
2127
{
@@ -30,9 +36,11 @@ internal class Data
3036

3137
public WeatherCommand() : base("Locations", "Weather Locations", "Weather Locations")
3238
{
33-
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");
39+
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");
3440
this.Timer.Elapsed += this.OnTimerElapse;
3541
this.Timer.Enabled = true;
42+
43+
this._weatherApiService = new Services.WeatherApiService();
3644
}
3745

3846
protected override Boolean OnLoad()
@@ -42,29 +50,38 @@ protected override Boolean OnLoad()
4250

4351
private void OnTimerElapse(object sender, ElapsedEventArgs e)
4452
{
45-
foreach (var ap in this.DataCache.Keys)
53+
foreach (var ap in DataCache.Keys)
4654
{
47-
this.RetrieveData(ap);
55+
this.RetrieveData(ap, this._instanceCancellation);
4856
this.ActionImageChanged(ap);
57+
DataCache.TryRemove(ap, out var _);
4958
}
59+
5060
this.Timer.AutoReset = true;
5161
this.Timer.Enabled = true;
62+
this._instanceCancellation = new CancellationToken(false);
5263
}
5364

5465
protected override BitmapImage GetCommandImage(String actionParameter, PluginImageSize imageSize)
5566
{
5667
if (string.IsNullOrEmpty(actionParameter))
68+
{
5769
return null;
70+
}
5871

5972
Data data = this.GetData(actionParameter);
6073
if (!data.IsValid)
74+
{
6175
return null;
76+
}
6277

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

6681
if (data.Icon != null)
82+
{
6783
iconBuilder.DrawImage(data.Icon);
84+
}
6885

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

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

77-
iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.Black, fontSize: 17);
78-
iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.White);
94+
if(data.Temperature.C != data.Temperature.F)
95+
{
96+
iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.Black, fontSize: 17);
97+
iconBuilder.DrawText($"{locationName}{Math.Round(data.Temperature.C)}°C/{Math.Round(data.Temperature.F)}°F", color: BitmapColor.White);
98+
}
99+
else
100+
{
101+
iconBuilder.DrawText($"PARAMETER\nERROR", color: BitmapColor.Black, fontSize: 17);
102+
iconBuilder.DrawText($"PARAMETER\nERROR", color: BitmapColor.White);
103+
}
79104

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

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

88-
private async void RetrieveData(string actionParameter)
113+
private async void RetrieveData(string actionParameter, CancellationToken cancellationToken)
89114
{
90115
if (string.IsNullOrEmpty(actionParameter))
116+
{
91117
return;
118+
}
92119

93120
Data data = this.GetData(actionParameter);
94121

95122
if (data.IsLoading)
123+
{
96124
return;
125+
}
97126

98127
data.IsLoading = true;
99128

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

111-
Models.Weather weather = null;
112-
try
113-
{
114-
weather = await this.weatherApiService.GetCurrentWeather(locationQuery, apiKey);
115-
}
116-
catch (Exception ex)
140+
var weather = await this._weatherApiService.GetCurrentWeather(locationQuery, apiKey, cancellationToken);
141+
if (weather == null)
117142
{
143+
// Data is from an older version, clearing.
144+
data.Name = "ERR";
145+
data.Temperature = (C: 0, F: 0);
118146
return;
119147
}
120148

121-
data.Name = weather.location.name;
122-
data.Temperature = (C: weather.current.temp_c, F: weather.current.temp_f);
123-
124-
var iconBytes = await this.weatherApiService.GetIconBytes(weather);
125-
data.Icon = BitmapImage.FromBase64String(Convert.ToBase64String(iconBytes));
149+
data.Name = weather.name;
150+
data.Temperature = (C: weather.main.celsius, F: weather.main.fahrenheit);
126151

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

136162
private Data GetData(string actionParameter)
137163
{
138-
if (this.DataCache.TryGetValue(actionParameter, out var data))
164+
if (DataCache.TryGetValue(actionParameter, out var data))
165+
{
139166
return data;
167+
}
140168

141169
data = new Data();
142-
this.DataCache.Add(actionParameter, data);
143-
144-
this.RetrieveData(actionParameter);
170+
DataCache.TryAdd(actionParameter, data);
171+
172+
this.RetrieveData(actionParameter, this._instanceCancellation);
145173

146174
return data;
147175
}

WeatherPlugin/Models/Weather.cs

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
namespace Loupedeck.WeatherPlugin.Models
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
public sealed class WeatherResponse
11+
{
12+
public Coord coord { get; set; }
13+
public Weather[] weather { get; set; }
14+
public string _base { get; set; }
15+
public Main main { get; set; }
16+
public int visibility { get; set; }
17+
public Wind wind { get; set; }
18+
public Clouds clouds { get; set; }
19+
public int dt { get; set; }
20+
public Sys sys { get; set; }
21+
public int timezone { get; set; }
22+
public int id { get; set; }
23+
public string name { get; set; }
24+
public int cod { get; set; }
25+
}
26+
27+
public sealed class Coord
28+
{
29+
public float lon { get; set; }
30+
public float lat { get; set; }
31+
}
32+
33+
public sealed class Main
34+
{
35+
public float temp { get; set; }
36+
public float feels_like { get; set; }
37+
public float temp_min { get; set; }
38+
public float temp_max { get; set; }
39+
public int pressure { get; set; }
40+
public int humidity { get; set; }
41+
public float celsius => (float)(this.temp - 273.15);
42+
public float fahrenheit => (float)((this.temp - 273.15) * 9 / 5 + 32);
43+
}
44+
45+
public sealed class Wind
46+
{
47+
public float speed { get; set; }
48+
public int deg { get; set; }
49+
public float gust { get; set; }
50+
}
51+
52+
public sealed class Clouds
53+
{
54+
public int all { get; set; }
55+
}
56+
57+
public sealed class Sys
58+
{
59+
public int type { get; set; }
60+
public int id { get; set; }
61+
public string country { get; set; }
62+
public int sunrise { get; set; }
63+
public int sunset { get; set; }
64+
}
65+
66+
public sealed class Weather
67+
{
68+
public int id { get; set; }
69+
public string main { get; set; }
70+
public string description { get; set; }
71+
public string icon { get; set; }
72+
73+
public byte[] iconBytes { get; set; }
74+
}
75+
76+
}

0 commit comments

Comments
 (0)