Skip to content

Commit

Permalink
Merge pull request #606 from WildernessLabs/v2.0.1.2
Browse files Browse the repository at this point in the history
Release 2.0.1.2
  • Loading branch information
jorgedevs authored Jan 19, 2025
2 parents fecdddc + 6def1e6 commit fe53e39
Show file tree
Hide file tree
Showing 84 changed files with 2,926 additions and 855 deletions.
18 changes: 9 additions & 9 deletions .github/workflows/develop-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,57 +15,57 @@ jobs:
steps:

- name: Checkout Meadow.Logging
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: WildernessLabs/Meadow.Logging
path: Meadow.Logging
ref: develop

- name: Checkout Meadow.Units
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: WildernessLabs/Meadow.Units
path: Meadow.Units
ref: develop

- name: Checkout Meadow.Contracts
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: WildernessLabs/Meadow.Contracts
path: Meadow.Contracts
ref: develop

- name: Checkout Meadow.Modbus
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: WildernessLabs/Meadow.Modbus
path: Meadow.Modbus
ref: develop

- name: Checkout Meadow.Foundation
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: WildernessLabs/Meadow.Foundation
path: Meadow.Foundation
ref: develop

- name: Checkout MQTTnet fork
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: WildernessLabs/MQTTnet
path: MQTTnet
ref: develop

- name: Checkout Meadow.Core
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: Meadow.Core

- name: Setup .NET SDK
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version:
7.0.x
8.0.x

- name: Install MAUI Workload
run: dotnet workload install maui --ignore-failed-sources
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
steps:

- name: Checkout Meadow.Core
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: Meadow.Core

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nuget-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set VERSION variable from tag
run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nuget-f7.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set VERSION variable from tag
run: echo "VERSION=0.98.0" >> $GITHUB_ENV

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nuget-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set VERSION variable from tag
run: echo "VERSION=0.98.0" >> $GITHUB_ENV

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nuget-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set VERSION variable from tag
run: echo "VERSION=0.98.0" >> $GITHUB_ENV

Expand Down
5 changes: 5 additions & 0 deletions source/Meadow.Core.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Simulation", "implementations\simulation\Meadow.Simulation\Meadow.Simulation.csproj", "{5543D2D5-FA80-43CE-8844-40510A7DBED6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "linux", "linux", "{B187C117-A16E-4A75-B862-3CA7DCA464B8}"
ProjectSection(SolutionItems) = preProject
implementations\linux\beaglebone.md = implementations\linux\beaglebone.md
implementations\linux\raspberrypi.md = implementations\linux\raspberrypi.md
implementations\linux\README.md = implementations\linux\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Linux", "implementations\linux\Meadow.Linux\Meadow.Linux.csproj", "{4DEA563C-50EE-4729-ACA4-C77A251655BC}"
EndProject
Expand Down
5 changes: 0 additions & 5 deletions source/Meadow.Core/Cloud/MeadowCloudConnectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,6 @@ private void LogAndRaiseOnErrorOccurredEvent(string message, Exception? ex = nul

var raisedException = new MeadowCloudException(message, ex);

if (ex != null && ex.HResult == -76)
{
ReportFatalErrorToReliabilityService(raisedException);
}

ErrorOccurred?.Invoke(this, raisedException);
}

Expand Down
50 changes: 33 additions & 17 deletions source/Meadow.Core/Cloud/MeadowCloudUpdateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ private async Task DownloadProc(UpdateMessage message)
if (!string.IsNullOrEmpty(message.OsVersion)
&& Resolver.Device.PlatformOS.OSVersion != message.OsVersion)
{
Resolver.Log.Trace($"This OTA requires an OS update.");
destination = message.MpakWithOsDownloadUrl;
}

Expand Down Expand Up @@ -230,31 +231,46 @@ private async Task DownloadProc(UpdateMessage message)
// Note: this is infrequently called, so we don't want to follow the advice of "use one instance for all calls"
using (var httpClient = new HttpClient())
{
if (_connectionService.Settings.UseAuthentication)
using (var request = new HttpRequestMessage(HttpMethod.Get, destination))
{
httpClient.DefaultRequestHeaders.Authorization = _connectionService.CreateAuthenticationHeaderValue();
}
if (_connectionService.Settings.UseAuthentication)
{
request.Headers.Authorization = _connectionService.CreateAuthenticationHeaderValue();
}

// Configure the HTTP range header to indicate resumption of partial download, starting from
// the 'totalBytesDownloaded' byte position and extending to the end of the content.
httpClient.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(totalBytesDownloaded, null);
// Configure the HTTP range header to indicate resumption of partial download, starting from
// the 'totalBytesDownloaded' byte position and extending to the end of the content.
request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(totalBytesDownloaded, null);

using (var stream = await httpClient.GetStreamAsync(destination))
{
using (var fileStream = Store.GetUpdateFileStream(message.ID))
// Get the actual update file size, which might be larger than the expected
// if this OTA requires an OS update
var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var contentLength = response.Content.Headers.ContentLength;
if (contentLength.HasValue && retryCount == 0)
{
byte[] buffer = new byte[1024 * 64]; // TODO: make this configurable/platform dependent
int bytesRead;
// Content-Length indicates the remaining bytes to download, as the Range header may change after retries.
// Then, to determine the total file size, the Content-Length from the first download attempt is used.
message.FileSize = contentLength.Value;
Resolver.Log.Trace($"Starting download... File size: {message.FileSize.ToString("N0")} bytes.");
}

while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
using (var stream = await response.Content.ReadAsStreamAsync())
{
using (var fileStream = Store.GetUpdateFileStream(message.ID))
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesDownloaded += bytesRead;
byte[] buffer = new byte[1024 * 64]; // TODO: make this configurable/platform dependent
int bytesRead;

while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesDownloaded += bytesRead;

message.DownloadProgress = totalBytesDownloaded;
message.DownloadProgress = totalBytesDownloaded;

RetrieveProgress?.Invoke(this, message);
Resolver.Log.Trace($"Download progress: {totalBytesDownloaded:N0} bytes downloaded");
RetrieveProgress?.Invoke(this, message);
Resolver.Log.Trace($"Download progress: {totalBytesDownloaded:N0} bytes downloaded");
}
}
}
}
Expand Down
27 changes: 26 additions & 1 deletion source/Meadow.Core/Gateways/Bluetooth/Definitions/Definition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ public class Definition : IDefinition
/// </summary>
public string DeviceName { get; }

/// <summary>
/// Gets the company ID.
/// </summary>
public ushort? CompanyId { get; }

/// <summary>
/// Gets the collection of services associated with this device definition.
/// </summary>
Expand All @@ -23,6 +28,21 @@ public class Definition : IDefinition
public Definition(string deviceName, params IService[] services)
{
DeviceName = deviceName;
CompanyId = null;
Services = new ServiceCollection();
Services.AddRange(services);
}

/// <summary>
/// Initializes a new instance of the <see cref="Definition"/> class with the specified device name and services.
/// </summary>
/// <param name="companyId">The company ID (assigned number).</param>
/// <param name="deviceName">The name of the device.</param>
/// <param name="services">The services associated with the device.</param>
public Definition(ushort companyId, string deviceName, params IService[] services)
{
DeviceName = deviceName;
CompanyId = companyId;
Services = new ServiceCollection();
Services.AddRange(services);
}
Expand All @@ -38,6 +58,11 @@ public string ToJson()
""deviceName"":""{DeviceName}""
";

if (CompanyId != null)
{
json += $@", ""companyIdentifier"":{CompanyId}";
}

if (Services != null && Services.Count > 0)
{
json += ", \"services\": [";
Expand All @@ -58,4 +83,4 @@ public string ToJson()
json += "}";
return json;
}
}
}
9 changes: 3 additions & 6 deletions source/Meadow.Core/Hardware/BiDirectionalInterruptPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,10 @@ private void OnInterrupt(IPin pin, bool state)
{
if (pin == this.Pin)
{
var capturedLastTime = LastEventTime; // note: doing this for latency reasons. kind of. sort of. bad time good time. all time.
this.LastEventTime = DateTime.Now;
// BC 2021.05.21 b5.0: Changed this to the new result type.
// assuming that old state is just an inversion of the new state, yeah?
var capturedLastTime = LastEventTime;
this.LastEventTime = DateTime.UtcNow;
RaiseChangedAndNotify(new DigitalPortResult(new DigitalState(state, this.LastEventTime), new DigitalState(!state, capturedLastTime)));
//RaiseChangedAndNotify(new DigitalInputPortChangeResult(state, this.LastEventTime, capturedLastTime));
}
}
}
}
}
3 changes: 2 additions & 1 deletion source/Meadow.Core/Hardware/Counter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ public class Counter : ICounter, IDisposable
/// Enables or disables the counter
/// </summary>
public bool Enabled { get; set; }

/// <summary>
/// Returns the current Counter value
/// </summary>
public long Count => count;
public ulong Count => (uint)count;

/// <summary>
/// Creates a Counter instance
Expand Down
35 changes: 28 additions & 7 deletions source/Meadow.Core/Hardware/DigitalInterruptPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class DigitalInterruptPort : DigitalInterruptPortBase
private DigitalPortResult _interruptResult = new DigitalPortResult();
private DigitalState _newState = new DigitalState(false, DateTime.MinValue);
private DigitalState _oldState = new DigitalState(false, DateTime.MinValue);
private InterruptMode? _interruptMode;

/// <inheritdoc/>
protected IMeadowIOController IOController { get; set; }
Expand All @@ -38,7 +39,7 @@ protected DigitalInterruptPort(
ResistorMode resistorMode,
TimeSpan debounceDuration,
TimeSpan glitchDuration
) : base(pin, channel, interruptMode)
) : base(pin, channel)
{
// DEVELOPER NOTE:
// Debounce recognizes the first state transition and then ignores anything after that for a period of time.
Expand All @@ -61,10 +62,7 @@ TimeSpan glitchDuration
{
// make sure the pin is configured as a digital input with the proper state
ioController.ConfigureInput(pin, resistorMode, interruptMode, debounceDuration, glitchDuration);
if (interruptMode != InterruptMode.None)
{
IOController.WireInterrupt(pin, interruptMode, resistorMode, debounceDuration, glitchDuration);
}
InterruptMode = interruptMode;
}
else
{
Expand Down Expand Up @@ -127,6 +125,29 @@ public override ResistorMode Resistor
}
}

/// <inheritdoc/>
public override InterruptMode InterruptMode
{
get => _interruptMode ?? InterruptMode.None;
set
{
if (InterruptMode == value) { return; }

if (InterruptMode != InterruptMode.None)
{
// if we're already set up for an interrupt, disable all interrupts and reconnect
IOController.WireInterrupt(Pin, InterruptMode.None, Resistor, DebounceDuration, GlitchDuration);
}

// don't call WireInterrupt if it's no interrupt and we're coming from the ctor
if (_interruptMode != null || value != InterruptMode.None)
{
IOController.WireInterrupt(Pin, value, Resistor, DebounceDuration, GlitchDuration);
}
_interruptMode = value;
}
}

private void OnInterrupt(IPin pin, bool state)
{
if (pin == this.Pin)
Expand All @@ -135,7 +156,7 @@ private void OnInterrupt(IPin pin, bool state)
{
// this is all to prevent new-ing up (and thereby preventing GC stuff)
_oldState.Time = LastEventTime; // note: doing this for latency reasons. kind of. sort of. bad time good time. all time.
_newState.Time = this.LastEventTime = DateTime.Now;
_newState.Time = LastEventTime = DateTime.UtcNow;
_oldState.State = !state;
_newState.State = state;
_interruptResult.Old = (LastEventTime == DateTime.MinValue) ? null : _oldState;
Expand Down Expand Up @@ -226,4 +247,4 @@ public override TimeSpan GlitchDuration
this.IOController.WireInterrupt(Pin, InterruptMode, _resistorMode, _debounceDuration, _glitchDuration);
}
}
}
}
13 changes: 7 additions & 6 deletions source/Meadow.Core/Meadow.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@
<ItemGroup>
<None Include="..\icon.png" Link="icon.png" Pack="true" PackagePath="" />
<None Include="Cloud\MeadowCloudConnectionService.cs" />
<PackageReference Include="Meadow.Contracts" Version="1.12.8" />
<PackageReference Include="Meadow.Foundation.Serialization.MicroJson" Version="1.12.8" />
<PackageReference Include="Meadow.Modbus" Version="1.12.8" />
<PackageReference Include="Meadow.MQTT" Version="1.12.8" />
<PackageReference Include="System.IO.Hashing" Version="8.0.0" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.2.0" />
<PackageReference Include="Meadow.Contracts" Version="2.0.1.2" />
<PackageReference Include="Meadow.Foundation.Serialization.MicroJson" Version="2.0.1.2" />
<PackageReference Include="Meadow.Modbus" Version="2.0.1.2" />
<PackageReference Include="Meadow.MQTT" Version="2.0.1.2" />
<PackageReference Include="System.IO.Hashing" Version="9.0.0" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.1.0" />
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions source/Meadow.Core/MeadowOS.FileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ public static string UserFileSystemRoot
/// <summary>
/// Gets the full path to the file used to store crash reports from unhandled runtime exceptions
/// </summary>
public static string RuntimeCrashFile => Path.Combine(CrashReportDirectory, "meadow.error");
public static string RuntimeCrashFile => Path.Combine(CrashReportDirectory, "mono_error.txt");
}
}
}
Loading

0 comments on commit fe53e39

Please sign in to comment.