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
1 change: 1 addition & 0 deletions PowerControlHub/PowerControlHubApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ void PowerControlHubApp::setup(RemoteSensor** remoteSensors, uint8_t remoteSenso

#if defined(OTA_AUTO_UPDATE) && defined(ESP32) && defined(WIFI_SUPPORT)
_systemCommandHandler.setOtaManager(&_otaManager);
_systemNetworkHandler.setOtaManager(&_otaManager);
_otaManager.begin();
#endif

Expand Down
126 changes: 126 additions & 0 deletions PowerControlHub/SystemNetworkHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include "SystemFunctions.h"
#include "FirmwareVersion.h"

#if defined(OTA_AUTO_UPDATE) && defined(ESP32) && defined(WIFI_SUPPORT)
#include "OtaManager.h"
#endif

#if defined(SD_CARD_SUPPORT)
#include "MicroSdDriver.h"
#endif
Expand Down Expand Up @@ -84,6 +88,128 @@ CommandResult SystemNetworkHandler::handleRequest(const char* method,

return CommandResult::ok();
}
#if defined(OTA_AUTO_UPDATE) && defined(ESP32) && defined(WIFI_SUPPORT)
else if (SystemFunctions::commandMatches(command, SystemCheckForUpdate))
{
if (!_otaManager)
{
snprintf(responseBuffer, bufferSize, "\"success\":false,\"error\":\"OTA not available\"");
return CommandResult::ok();
}

const char* applyStr = nullptr;

for (uint8_t i = 0; i < paramCount; ++i)
{
if (strcmp(params[i].key, "apply") == 0)
{
applyStr = params[i].value;
break;
}
}

bool applyNow = applyStr && (applyStr[0] == '1');
_otaManager->triggerCheck(applyNow);

const char* stateStr = "idle";

switch (_otaManager->getState())
{
case OtaState::Idle:
stateStr = "triggered";
break;

case OtaState::Checking:
stateStr = "checking";
break;

case OtaState::UpdateAvailable:
stateStr = "available";
break;

case OtaState::Downloading:
stateStr = "downloading";
break;

case OtaState::Rebooting:
stateStr = "rebooting";
break;

case OtaState::Failed:
stateStr = "failed";
break;

case OtaState::UpToDate:
stateStr = "uptodate";
break;
}

snprintf(responseBuffer, bufferSize,
"\"success\":true,\"command\":\"%s\",\"v\":\"v%u.%u.%u.%u\",\"av\":\"%s\",\"s\":\"%s\"",
command,
FirmwareMajor, FirmwareMinor, FirmwarePatch, FirmwareBuild,
_otaManager->getAvailableVersion(),
stateStr);

return CommandResult::ok();
}
else if (SystemFunctions::commandMatches(command, SystemOtaStatus))
{
const char* stateStr = "disabled";
const char* avVersion = "";
char autoApply = '0';

if (_otaManager)
{
switch (_otaManager->getState())
{
case OtaState::Idle:
stateStr = "idle";
break;

case OtaState::Checking:
stateStr = "checking";
break;

case OtaState::UpdateAvailable:
stateStr = "available";
break;

case OtaState::Downloading:
stateStr = "downloading";
break;

case OtaState::Rebooting:
stateStr = "rebooting";
break;

case OtaState::Failed:
stateStr = "failed";
break;

case OtaState::UpToDate:
stateStr = "uptodate";
break;
}

avVersion = _otaManager->getAvailableVersion();

SystemHeader* hdr = ConfigManager::getHeaderPtr();
if (hdr && (hdr->reserved[0] & OtaFlagAutoApply))
autoApply = '1';
}

snprintf(responseBuffer, bufferSize,
"\"success\":true,\"command\":\"%s\",\"v\":\"v%u.%u.%u.%u\",\"av\":\"%s\",\"s\":\"%s\",\"auto\":\"%c\"",
command,
FirmwareMajor, FirmwareMinor, FirmwarePatch, FirmwareBuild,
avVersion,
stateStr,
autoApply);

return CommandResult::ok();
}
#endif // OTA_AUTO_UPDATE
else
{
return CommandResult::error(InvalidCommandParameters);
Expand Down
14 changes: 14 additions & 0 deletions PowerControlHub/SystemNetworkHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "SdCardLogger.h"
#endif

#if defined(OTA_AUTO_UPDATE) && defined(ESP32) && defined(WIFI_SUPPORT)
class OtaManager;
#endif

class SystemNetworkHandler : public INetworkCommandHandler
{
Expand All @@ -35,6 +38,10 @@ class SystemNetworkHandler : public INetworkCommandHandler
SdCardLogger* _sdCardLogger;
#endif

#if defined(OTA_AUTO_UPDATE) && defined(ESP32) && defined(WIFI_SUPPORT)
OtaManager* _otaManager{ nullptr };
#endif

public:
explicit SystemNetworkHandler(WifiController* wifiController);

Expand All @@ -45,6 +52,13 @@ class SystemNetworkHandler : public INetworkCommandHandler
}
#endif

#if defined(OTA_AUTO_UPDATE) && defined(ESP32) && defined(WIFI_SUPPORT)
void setOtaManager(OtaManager* otaManager)
{
_otaManager = otaManager;
}
#endif

const char* getRoute() const override { return "/api/system"; }

void formatWifiStatusJson(IWifiClient* client) override;
Expand Down
5 changes: 5 additions & 0 deletions PowerControlHubApp/Internal/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ internal static class Constants
public const string MessageDeviceUnreachable = "Device unreachable";
public const string MessageToggleFailed = "Toggle failed — see log";
public const string LogOtaTrigger = "OTA: triggering firmware install…";
public const string OtaTriggerFailed = "OTA trigger failed";
public const string OtaDialogTitle = "Install Firmware";
public const string OtaDialogMessage = "An OTA update to {0} is available. Download and install now?";
public const string OtaDialogAccept = "Install";
public const int RelayCount = 8;
public const int UnconfiguredPin = 255;
// Dashboard poller log messages
Expand Down Expand Up @@ -195,6 +199,7 @@ internal static class Constants
public const string UserAgentValue = "PowerControlHub/1.0";
public const string PowerHubNotConfigured = "PowerHubService is not configured. Call Configure() first.";
public const string ErrorKey = "error";
public const char QuoteChar = '"';
public const string PreferenceKey = "app_theme";
public const string ThemeLight = "Light";
public const string ThemeDark = "Dark";
Expand Down
12 changes: 7 additions & 5 deletions PowerControlHubApp/ViewModels/DashboardViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using PowerControlHubApp.Models;
using PowerControlHubApp.Models.Json;
using PowerControlHubApp.Services;
using Microsoft.Maui.Controls;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -36,6 +37,7 @@ public class DashboardViewModel : INotifyPropertyChanged
public ICommand RefreshCommand { get; }
public ICommand ToggleRelayCommand { get; }
public ICommand InstallUpdateCommand { get; }
public ICommand FirmwareLabelTappedCommand { get; }

/// <summary>True when the firmware reported an update is available.</summary>
public bool UpdateAvailable => _otaStatus?.UpdateAvailable == true;
Expand Down Expand Up @@ -90,7 +92,6 @@ private set
{
_systemTime = value;
OnPropertyChanged();
OnPropertyChanged(nameof(SystemFirmwareAndTime));
}
}

Expand All @@ -102,7 +103,6 @@ private set
{
_systemFirmware = value;
OnPropertyChanged();
OnPropertyChanged(nameof(SystemFirmwareAndTime));
}
}

Expand All @@ -116,14 +116,13 @@ private set
{
_systemUptime = value;
OnPropertyChanged();
OnPropertyChanged(nameof(SystemFirmwareAndTime));
}
}

/// <summary>
/// Combined firmware and time display used by the status bar.
/// Colour for the firmware label in the status bar. Changes when update available.
/// </summary>
public string SystemFirmwareAndTime => $"FW: {SystemFirmware} • {SystemUptime}";
public Color SystemFirmwareColor => UpdateAvailable ? Color.FromArgb(ColorWarning) : Color.FromArgb(ColorAsHex1);

/// <summary>Label shown in the update banner.</summary>
public string OtaBannerLabel => _otaStatus?.BannerLabel ?? string.Empty;
Expand Down Expand Up @@ -212,6 +211,7 @@ public DashboardViewModel(PowerHubService service, LogService log, RelayStore re
RefreshCommand = new Command(async () => await RefreshAsync());
ToggleRelayCommand = new Command<RelayViewModel>(async relay => await ToggleRelayAsync(relay));
InstallUpdateCommand = new Command(async () => await InstallUpdateAsync(), () => CanInstallUpdate);
FirmwareLabelTappedCommand = new Command(async () => await Shell.Current.GoToAsync(RouteSettingsPage));

_relayStore.Relays.CollectionChanged += (_, _) =>
{
Expand Down Expand Up @@ -393,6 +393,7 @@ private void NotifyOtaProperties()
OnPropertyChanged(nameof(OtaBannerLabel));
OnPropertyChanged(nameof(ShowOtaBanner));
OnPropertyChanged(nameof(OtaBannerColor));
OnPropertyChanged(nameof(SystemFirmwareColor));
OnPropertyChanged(nameof(CanInstallUpdate));
((Command)InstallUpdateCommand).ChangeCanExecute();
}
Expand All @@ -404,6 +405,7 @@ private void UpdateSystem(SystemModel system)
// Populate firmware and uptime so the status bar can show them
SystemFirmware = string.IsNullOrEmpty(system.Fw) ? DoubleDash : system.Fw;
SystemUptime = string.IsNullOrEmpty(system.Uptime) ? DoubleDash : system.Uptime;
OnPropertyChanged(nameof(SystemFirmwareColor));
}

private void UpdateRelays(IReadOnlyList<RelayModel> incoming)
Expand Down
Loading
Loading