Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ dotnet_diagnostic.CC0009.severity = error
dotnet_diagnostic.CC0010.severity = error


dotnet_diagnostic.IDE0028.severity = error
dotnet_diagnostic.IDE0290.severity = none
dotnet_diagnostic.IDE0305.severity = error
dotnet_diagnostic.IDE0028.severity = error # Use collection initializer
dotnet_diagnostic.IDE0290.severity = none # Use 'var' when variable type is apparent
dotnet_diagnostic.IDE0305.severity = error # Use 'var' when variable type is apparent


dotnet_diagnostic.CS0144.severity = error
dotnet_diagnostic.CS8632.severity = error
dotnet_diagnostic.CS0144.severity = error # The body of 'method' cannot be an iterator block because 'type' does not implement 'IEnumerable' or 'IEnumerator'
dotnet_diagnostic.CS8632.severity = error # nullable reference types


dotnet_diagnostic.CA1822.severity = error
dotnet_diagnostic.CA1822.severity = error # mark members as static
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,6 @@ StaticElectrics/__vm/
/SmartFuseBox/__vm/.SmartFuseBox.vsarduino.h
/LocalOnly
/.github/copilot-instructions.md
/PowerControlHubApp/pch-release-key.keystore
/directory.props.build
/BuildPlayStoreApp.txt
51 changes: 20 additions & 31 deletions PowerControlHubApp/AppShell.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,31 @@
xmlns:views="clr-namespace:PowerControlHubApp.Views"
xmlns:localization="clr-namespace:PowerControlHubApp.Resources.Localization"
Title="PowerControlHub"
FlyoutBehavior="Flyout"
Shell.NavBarIsVisible="False">

<ShellContent
x:Name="DashboardPage"
Title="{x:Static localization:AppResources.Dashboard}"
Route="DashboardPage"
ContentTemplate="{DataTemplate views:DashboardPage}" />
<FlyoutItem Title="{x:Static localization:AppResources.Dashboard}" Route="DashboardPage">
<ShellContent x:Name="DashboardPage" ContentTemplate="{DataTemplate views:DashboardPage}" />
</FlyoutItem>

<ShellContent
x:Name="RelayConfigPage"
Title="{x:Static localization:AppResources.Relays}"
Route="RelayConfigPage"
ContentTemplate="{DataTemplate views:RelayConfigPage}" />
<FlyoutItem Title="{x:Static localization:AppResources.Relays}" Route="RelayConfigPage">
<ShellContent x:Name="RelayConfigPage" ContentTemplate="{DataTemplate views:RelayConfigPage}" />
</FlyoutItem>

<ShellContent
x:Name="SensorConfigPage"
Title="{x:Static localization:AppResources.LocalSensorsTitle}"
Route="SensorConfigPage"
ContentTemplate="{DataTemplate views:LocalSensorConfigPage}" />
<FlyoutItem Title="{x:Static localization:AppResources.LocalSensorsTitle}" Route="SensorConfigPage">
<ShellContent x:Name="SensorConfigPage" ContentTemplate="{DataTemplate views:LocalSensorConfigPage}" />
</FlyoutItem>

<ShellContent
x:Name="ExternalSensorConfigPage"
Title="{x:Static localization:AppResources.ExternalSensors}"
Route="ExternalSensorConfigPage"
ContentTemplate="{DataTemplate views:ExternalSensorConfigPage}" />
<FlyoutItem Title="{x:Static localization:AppResources.ExternalSensors}" Route="ExternalSensorConfigPage">
<ShellContent x:Name="ExternalSensorConfigPage" ContentTemplate="{DataTemplate views:ExternalSensorConfigPage}" />
</FlyoutItem>

<ShellContent
x:Name="SettingsPage"
Title="{x:Static localization:AppResources.Settings}"
Route="SettingsPage"
ContentTemplate="{DataTemplate views:SettingsPage}" />
<FlyoutItem Title="{x:Static localization:AppResources.Settings}" Route="SettingsPage">
<ShellContent x:Name="SettingsPage" ContentTemplate="{DataTemplate views:SettingsPage}" />
</FlyoutItem>

<ShellContent
x:Name="SystemPage"
Title="{x:Static localization:AppResources.SystemTitle}"
Route="SystemPage"
ContentTemplate="{DataTemplate views:SystemPage}" />
<FlyoutItem Title="{x:Static localization:AppResources.SystemTitle}" Route="SystemPage">
<ShellContent x:Name="SystemPage" ContentTemplate="{DataTemplate views:SystemPage}" />
</FlyoutItem>

</Shell>
</Shell>
4 changes: 3 additions & 1 deletion PowerControlHubApp/Internal/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ internal static class Constants
#endif
public const string ApplicationNameWithIcon = IconWarning + SingleSpace + ApplicationName;
public const string ApplicationName = "Power Control Hub";
public const string AndroidLogTag = "PowerControlHub";
public const string UnknownExceptionMessage = "Unknown exception";
public const string SummarySeparator = ";";
public const string IconTimePrefix = "🕐";
public const string IconExternalSensor = "📡";
Expand All @@ -28,7 +30,7 @@ internal static class Constants
public const string IconLocalSensor = "🔌";
public const string IconRelaySymbol = "⚡";
public const string IconRemove = "🗑";
public const string NavBack = "...";
public const string NavBack = "..";
public const string FailSeparator = ";";
public const string ColorAsHex1 = "#44cc44";
public const string ColorError = "#cc4444";
Expand Down
3 changes: 2 additions & 1 deletion PowerControlHubApp/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public static MauiApp CreateMauiApp()
PowerHubService service = new PowerHubService(
sp.GetRequiredService<IDashboardConnection>(),
sp.GetRequiredService<IConfigConnection>(),
sp.GetRequiredService<IMessageBus>());
sp.GetRequiredService<IMessageBus>(),
sp.GetRequiredService<IDashboardProvider>());

return service;
});
Expand Down
2 changes: 1 addition & 1 deletion PowerControlHubApp/Platforms/Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true" android:usesCleartextTraffic="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
35 changes: 33 additions & 2 deletions PowerControlHubApp/Platforms/Android/MainApplication.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Android.App;
using Android.Runtime;
using PowerControlHubApp.Internal;
using System;
using System.Threading.Tasks;

namespace PowerControlHubApp
{
Expand All @@ -11,6 +14,34 @@ public MainApplication(IntPtr handle, JniHandleOwnership ownership)
{
}

protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
protected override MauiApp CreateMauiApp()
{
AndroidEnvironment.UnhandledExceptionRaiser += OnAndroidUnhandledException;
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;

return MauiProgram.CreateMauiApp();
}

private static void OnAndroidUnhandledException(object sender, RaiseThrowableEventArgs e)
{
LogException(e.Exception);
}

private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
LogException(e.ExceptionObject as Exception);
}

private static void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
LogException(e.Exception);
e.SetObserved();
}

private static void LogException(Exception exception)
{
Android.Util.Log.Error(Constants.AndroidLogTag, exception?.ToString() ?? Constants.UnknownExceptionMessage);
}
}
}
}
23 changes: 20 additions & 3 deletions PowerControlHubApp/PowerControlHubApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFrameworks>net10.0-android</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('linux'))">$(TargetFrameworks);net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('linux'))">$(TargetFrameworks);net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>

<!-- Note for MacCatalyst:
Expand Down Expand Up @@ -33,7 +33,7 @@
<ApplicationTitle>PowerControlHubApp</ApplicationTitle>

<!-- App Identifier -->
<ApplicationId>com.companyname.powercontrolhubapp</ApplicationId>
<ApplicationId>pch.si.carter.powercontrolhubapp</ApplicationId>

<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
Expand All @@ -47,14 +47,31 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<AndroidSigningKeyStore>pch-release-key.keystore</AndroidSigningKeyStore>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net10.0-android|AnyCPU'">
<AndroidUseAapt2>True</AndroidUseAapt2>
<AndroidKeyStore>True</AndroidKeyStore>
<AndroidApkSignerAdditionalArguments>--v2-signing-enabled true</AndroidApkSignerAdditionalArguments>
<AndroidSigningStorePass></AndroidSigningStorePass>
<AndroidCreatePackagePerAbi>True</AndroidCreatePackagePerAbi>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net10.0-android|AnyCPU'">
<AndroidUseAapt2>True</AndroidUseAapt2>
<AndroidKeyStore>True</AndroidKeyStore>
<AndroidApkSignerAdditionalArguments>--v2-signing-enabled true</AndroidApkSignerAdditionalArguments>
<AndroidCreatePackagePerAbi>True</AndroidCreatePackagePerAbi>
</PropertyGroup>

<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />

<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#000000" BaseSize="128,128" />

<!-- Images -->
<MauiImage Include="Resources\Images\*" />
Expand Down
Binary file added PowerControlHubApp/Resources/Splash/splash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 99 additions & 8 deletions PowerControlHubApp/Resources/Splash/splash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 9 additions & 3 deletions PowerControlHubApp/Services/ConfigConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,15 @@ private static SocketsHttpHandler CreateHandler()
NoDelay = true
};
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, SecondsTen);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, SecondsFive);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveRetryCount, SecondsThree);
try
{
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, SecondsTen);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, SecondsFive);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveRetryCount, SecondsThree);
}
catch
{
}
await socket.ConnectAsync(context.DnsEndPoint, ct);
return new NetworkStream(socket, ownsSocket: true);
}
Expand Down
12 changes: 9 additions & 3 deletions PowerControlHubApp/Services/DashboardConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,15 @@ private static SocketsHttpHandler CreateHandler()
NoDelay = true
};
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, SecondsTen);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, SecondsFive);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveRetryCount, SecondsThree);
try
{
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, SecondsTen);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, SecondsFive);
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveRetryCount, SecondsThree);
}
catch
{
}
await socket.ConnectAsync(context.DnsEndPoint, ct);
return new NetworkStream(socket, ownsSocket: true);
}
Expand Down
7 changes: 6 additions & 1 deletion PowerControlHubApp/Services/PowerHubService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ public class PowerHubService
{
private readonly IDashboardConnection _dashboardConnection;
private readonly IConfigConnection _configConnection;
private readonly IDashboardProvider _dashboardProvider;

public PowerHubService(IDashboardConnection dashboardConnection,
IConfigConnection configConnection,
IMessageBus messageBus)
IMessageBus messageBus,
IDashboardProvider dashboardProvider)
{
_dashboardConnection = dashboardConnection ?? throw new ArgumentNullException(nameof(dashboardConnection));
_configConnection = configConnection ?? throw new ArgumentNullException(nameof(configConnection));
_dashboardProvider = dashboardProvider ?? throw new ArgumentNullException(nameof(dashboardProvider));

messageBus.Subscribe<AuthConfigChanged>(OnAuthConfigChanged);
}
Expand All @@ -40,6 +43,8 @@ public PowerHubService(IDashboardConnection dashboardConnection,

public string BaseUrl => _dashboardConnection is DashboardConnection dc ? dc.BaseUrl : string.Empty;

public IndexModel CurrentIndex => _dashboardProvider?.CurrentIndex;

public void Configure(string ipAddress, int port, string apiKey = "", string hmacKey = "")
{
if (_dashboardConnection is DashboardConnection dc)
Expand Down
Loading
Loading