Skip to content

Commit 6d8db67

Browse files
committed
fix semaphore handling
1 parent 7e2fe40 commit 6d8db67

File tree

1 file changed

+124
-124
lines changed
  • src/automatica.drivers/automatica.driver.nuki/P3.Driver.Nuki.Driver

1 file changed

+124
-124
lines changed
Lines changed: 124 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,124 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Net.Http;
5-
using System.Threading;
6-
using System.Threading.Tasks;
7-
using Automatica.Core.Driver;
8-
using Microsoft.Extensions.Logging;
9-
using Newtonsoft.Json;
10-
using P3.Driver.Nuki.Driver.Model;
11-
using Timer = System.Threading.Timer;
12-
13-
namespace P3.Driver.Nuki.Driver
14-
{
15-
internal class NukiDriver : DriverNoneAttributeBase
16-
{
17-
private Timer _timer;
18-
19-
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
20-
private readonly ILogger _logger;
21-
private int _pollTime;
22-
private readonly List<NukiSmartLock> _smartLocks = new();
23-
24-
private string _bridgeAddress;
25-
private string _token;
26-
27-
private HttpClient _httpClient = new();
28-
29-
public NukiDriver(IDriverContext driverContext) : base(driverContext)
30-
{
31-
_logger = driverContext.Logger;
32-
}
33-
34-
public override Task<bool> Init(CancellationToken token = default)
35-
{
36-
var pollTime = GetPropertyValueInt("poll");
37-
_pollTime = pollTime;
38-
39-
_bridgeAddress = $"http://{GetPropertyValueString("ip")}:{GetPropertyValueInt("port")}";
40-
_token = GetPropertyValueString("token");
41-
return base.Init(token);
42-
}
43-
44-
private async void TimeElapsed(object state)
45-
{
46-
try
47-
{
48-
if (await _semaphore.WaitAsync(TimeSpan.FromSeconds(1)))
49-
{
50-
await ReadValues();
51-
}
52-
}
53-
catch (Exception ex)
54-
{
55-
DriverContext.Logger.LogError(ex, "Error read values...");
56-
}
57-
finally
58-
{
59-
_semaphore.Release();
60-
}
61-
}
62-
63-
public override async Task<bool> Start(CancellationToken token = default)
64-
{
65-
_timer = new Timer(TimeElapsed, this, _pollTime * 1000, _pollTime * 1000);
66-
67-
_logger.LogInformation($"Start polling every {_pollTime}s");
68-
await ReadValues(token);
69-
70-
return await base.Start(token);
71-
}
72-
73-
74-
protected override async Task<bool> Read(IReadContext readContext, CancellationToken token = new CancellationToken())
75-
{
76-
await ReadValues(token);
77-
return true;
78-
}
79-
80-
private async Task ReadValues(CancellationToken token = default)
81-
{
82-
_logger.LogDebug($"Poll values...");
83-
84-
var listResponse = await _httpClient.GetAsync($"{_bridgeAddress}/list?token={_token}", token);
85-
86-
var response = await listResponse.Content.ReadAsStringAsync(token);
87-
_logger.LogDebug($"Response: {response}");
88-
89-
if (!listResponse.IsSuccessStatusCode)
90-
{
91-
_logger.LogError($"Error reading values: {listResponse.StatusCode}");
92-
return;
93-
}
94-
95-
var listResponseObj = JsonConvert.DeserializeObject<List<NukiObject>>(response);
96-
97-
foreach (var nuki in listResponseObj)
98-
{
99-
var nukiDriver = _smartLocks.FirstOrDefault(x => x.NukiId == nuki.NukiId);
100-
101-
if (nukiDriver != null)
102-
{
103-
nukiDriver.UpdateState(nuki);
104-
}
105-
}
106-
107-
}
108-
109-
public override Task<bool> Stop(CancellationToken token = default)
110-
{
111-
_timer.Dispose();
112-
return base.Stop(token);
113-
}
114-
115-
public override IDriverNode CreateDriverNode(IDriverContext ctx)
116-
{
117-
var smartLock = new NukiSmartLock(ctx);
118-
119-
_smartLocks.Add(smartLock);
120-
121-
return smartLock;
122-
}
123-
}
124-
}
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Net.Http;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Automatica.Core.Driver;
8+
using Microsoft.Extensions.Logging;
9+
using Newtonsoft.Json;
10+
using P3.Driver.Nuki.Driver.Model;
11+
using Timer = System.Threading.Timer;
12+
13+
namespace P3.Driver.Nuki.Driver
14+
{
15+
internal class NukiDriver : DriverNoneAttributeBase
16+
{
17+
private Timer _timer;
18+
19+
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
20+
private readonly ILogger _logger;
21+
private int _pollTime;
22+
private readonly List<NukiSmartLock> _smartLocks = new();
23+
24+
private string _bridgeAddress;
25+
private string _token;
26+
27+
private HttpClient _httpClient = new();
28+
29+
public NukiDriver(IDriverContext driverContext) : base(driverContext)
30+
{
31+
_logger = driverContext.Logger;
32+
}
33+
34+
public override Task<bool> Init(CancellationToken token = default)
35+
{
36+
var pollTime = GetPropertyValueInt("poll");
37+
_pollTime = pollTime;
38+
39+
_bridgeAddress = $"http://{GetPropertyValueString("ip")}:{GetPropertyValueInt("port")}";
40+
_token = GetPropertyValueString("token");
41+
return base.Init(token);
42+
}
43+
44+
private async void TimeElapsed(object state)
45+
{
46+
if (await _semaphore.WaitAsync(TimeSpan.FromSeconds(1)))
47+
{
48+
try
49+
{
50+
await ReadValues();
51+
}
52+
catch (Exception ex)
53+
{
54+
DriverContext.Logger.LogError(ex, "Error read values...");
55+
}
56+
finally
57+
{
58+
_semaphore.Release();
59+
}
60+
}
61+
}
62+
63+
public override async Task<bool> Start(CancellationToken token = default)
64+
{
65+
_timer = new Timer(TimeElapsed, this, _pollTime * 1000, _pollTime * 1000);
66+
67+
_logger.LogInformation($"Start polling every {_pollTime}s");
68+
await ReadValues(token);
69+
70+
return await base.Start(token);
71+
}
72+
73+
74+
protected override async Task<bool> Read(IReadContext readContext, CancellationToken token = new CancellationToken())
75+
{
76+
await ReadValues(token);
77+
return true;
78+
}
79+
80+
private async Task ReadValues(CancellationToken token = default)
81+
{
82+
_logger.LogDebug($"Poll values...");
83+
84+
var listResponse = await _httpClient.GetAsync($"{_bridgeAddress}/list?token={_token}", token);
85+
86+
var response = await listResponse.Content.ReadAsStringAsync(token);
87+
_logger.LogDebug($"Response: {response}");
88+
89+
if (!listResponse.IsSuccessStatusCode)
90+
{
91+
_logger.LogError($"Error reading values: {listResponse.StatusCode}");
92+
return;
93+
}
94+
95+
var listResponseObj = JsonConvert.DeserializeObject<List<NukiObject>>(response);
96+
97+
foreach (var nuki in listResponseObj)
98+
{
99+
var nukiDriver = _smartLocks.FirstOrDefault(x => x.NukiId == nuki.NukiId);
100+
101+
if (nukiDriver != null)
102+
{
103+
nukiDriver.UpdateState(nuki);
104+
}
105+
}
106+
107+
}
108+
109+
public override Task<bool> Stop(CancellationToken token = default)
110+
{
111+
_timer.Dispose();
112+
return base.Stop(token);
113+
}
114+
115+
public override IDriverNode CreateDriverNode(IDriverContext ctx)
116+
{
117+
var smartLock = new NukiSmartLock(ctx);
118+
119+
_smartLocks.Add(smartLock);
120+
121+
return smartLock;
122+
}
123+
}
124+
}

0 commit comments

Comments
 (0)