Newer
Older
powermon_manager_sw / gui / gui_stats.cpp
@Razvan Turiac Razvan Turiac on 8 Jul 8 KB Initial import
/* Copyright (C) 2020 - 2024, Thornwave Labs Inc
 * Written by Razvan Turiac <razvan.turiac@thornwave.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
 * documentation files (the “Software”), to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 
 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * Attribution shall be given to Thornwave Labs Inc. and shall be made visible to the final user. 
 * 
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <gui_stats.h>


GuiStats::GuiStats(wxWindow *parent, const wxString &title, Powermon &powermon): wxDialog(parent, wxID_ANY, title), mPowermon(powermon)
{
	const size_t BORDER_SIZE = FromDIP(6);

	mSecondsSinceOnText = new wxStaticText(this, wxID_ANY, wxT(""));
	mVoltage1MaxText = new wxStaticText(this, wxID_ANY, wxT(""));
	mVoltage1MinText = new wxStaticText(this, wxID_ANY, wxT(""));
	mVoltage2MaxText = new wxStaticText(this, wxID_ANY, wxT(""));
	mVoltage2MinText = new wxStaticText(this, wxID_ANY, wxT(""));
	mPeakChargeCurrentText = new wxStaticText(this, wxID_ANY, wxT(""));
	mPeakDischargeCurrentText = new wxStaticText(this, wxID_ANY, wxT(""));
	mTemperatureMaxText = new wxStaticText(this, wxID_ANY, wxT(""));
	mTemperatureMinText = new wxStaticText(this, wxID_ANY, wxT(""));

	mResetButton = new wxButton(this, ID_BUTTON_RESET, wxT("Reset"), wxDefaultPosition, FromDIP(wxSize(110, 40)));
	mCloseButton = new wxButton(this, wxID_CANCEL, wxT("Close"), wxDefaultPosition, FromDIP(wxSize(110, 40)));

	//main window sizer
	wxBoxSizer*	main_sizer = new wxBoxSizer(wxVERTICAL);
	SetSizer(main_sizer);

	wxBoxSizer*	h_sizer;
	
	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Time Since Powered On:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mSecondsSinceOnText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Minimum Voltage 1:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mVoltage1MinText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Maximum Voltage 1:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mVoltage1MaxText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Minimum Voltage 2:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mVoltage2MinText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Maximum Voltage 2:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mVoltage2MaxText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Peak Discharge Current:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mPeakDischargeCurrentText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Peak Charge Current:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mPeakChargeCurrentText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Minimum Temperature:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mTemperatureMinText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(new wxStaticText(this, wxID_ANY, wxT("Maximum Temperature:")), 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	h_sizer->Add(mTemperatureMaxText, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);

	h_sizer = new wxBoxSizer(wxHORIZONTAL);
	h_sizer->Add(mResetButton, 0, wxALIGN_CENTER | wxALL, BORDER_SIZE);
	h_sizer->Add(mCloseButton, 0, wxALIGN_CENTER | wxALL, BORDER_SIZE);
	main_sizer->Add(h_sizer, 0, wxALL | wxALIGN_CENTER, BORDER_SIZE);

	main_sizer->SetSizeHints(this);
	Centre();

	mStatsTimer = new wxTimer(this, ID_STATS_TIMER);
}


GuiStats::~GuiStats()
{
	delete mStatsTimer;
}

bool GuiStats::Show(bool show)
{
	if (show)
	{
		mStatsTimer->Start(1000);
		updateStats();
	}
	else
	{
		mStatsTimer->Stop();
	}

	return wxDialog::Show(show);
}


void GuiStats::OnGuiEvent(GuiEvent &event)
{
	event.process();
}


void GuiStats::OnButtonResetClicked(wxCommandEvent &event)
{
	wxMessageDialog msg(this, wxT("Reset the power meter statistics ?"), wxT("Confirmation"), wxOK | wxCANCEL | wxICON_QUESTION | wxSTAY_ON_TOP | wxCENTRE);
	if (msg.ShowModal() == wxID_OK)
	{
		mPowermon.requestResetStatistics([this](uint16_t status)
		{
			wxQueueEvent(this, new GuiEvent([this, status](const GuiEvent &event)
			{
				checkDeviceError(this, status);
			}));
		});
	}
}


void GuiStats::OnStatsTimerEvent(wxTimerEvent &event)
{
	updateStats();
}


void GuiStats::updateStats(void)
{
	mPowermon.requestGetStatistics([this](uint16_t status, const Powermon::MonitorStatistics &stats)
	{
		wxQueueEvent(this, new GuiEvent([this, status, stats](const GuiEvent &event)
		{
			if (status == Powermon::RSP_SUCCESS)
			{
				wxString str;

				uint32_t seconds = stats.seconds_since_on;

				uint32_t days = seconds / (3600 * 24);
				seconds -= days * 3600 * 24;

				uint32_t hours = seconds / 3600;
				seconds -= hours * 3600;

				uint32_t minutes = seconds / 60;
				seconds -= minutes * 60;

				if (days)
					str.Printf(wxT("%ud %uh %um"), days, hours, minutes);
				else if (hours)
					str.Printf(wxT("%uh %um %us"), hours, minutes, seconds);
				else
					str.Printf(wxT("%um %us"), minutes, seconds);

				mSecondsSinceOnText->SetLabel(str);

				str.Printf(wxT("%6.3f V"), stats.voltage1_min);
				mVoltage1MinText->SetLabel(str);
				str.Printf(wxT("%6.3f V"), stats.voltage1_max);
				mVoltage1MaxText->SetLabel(str);

				if (!isnan(stats.voltage2_min))
				{
					str.Printf(wxT("%6.3f V"), stats.voltage2_min);
					mVoltage2MinText->SetLabel(str);
				}
				else
				{
					mVoltage2MinText->SetLabel(wxT("n/a"));
				}

				if (!isnan(stats.voltage2_max))
				{
					str.Printf(wxT("%6.3f V"), stats.voltage2_max);
					mVoltage2MaxText->SetLabel(str);
				}
				else
				{
					mVoltage2MaxText->SetLabel(wxT("n/a"));
				}
				
				str.Printf(wxT("%6.2f A"), stats.peak_charge_current);
				mPeakChargeCurrentText->SetLabel(str);

				str.Printf(wxT("%6.2f A"), stats.peak_discharge_current);
				mPeakDischargeCurrentText->SetLabel(str);

				str.Printf(wxT("%3.0f \u00B0C"), stats.temperature_min);
				mTemperatureMinText->SetLabel(str);
				str.Printf(wxT("%3.0f \u00B0C"), stats.temperature_max);
				mTemperatureMaxText->SetLabel(str);

				Refresh();	
			}
		}));
	});
}


void GuiStats::OnClose(wxCloseEvent &event)
{
	mStatsTimer->Stop();
	Hide();
}


void GuiStats::OnButtonCloseClicked(wxCommandEvent &event)
{
	Close();
}


BEGIN_EVENT_TABLE(GuiStats, wxDialog)
EVT_CLOSE(GuiStats::OnClose)
GUI_EVT(GuiStats::OnGuiEvent)

EVT_BUTTON(wxID_CANCEL, GuiStats::OnButtonCloseClicked)
EVT_BUTTON(ID_BUTTON_RESET, GuiStats::OnButtonResetClicked)

EVT_TIMER(ID_STATS_TIMER, GuiStats::OnStatsTimerEvent)

END_EVENT_TABLE()