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 build_scripts/msw/xSchedule_64bit.iss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "D
Source: "../../xSchedule/x64/Release/xSchedule.exe"; DestDir: "{app}"
Source: "../../xlights/include/xSchedule64.ico"; DestDir: "{app}"; Flags: "ignoreversion"
Source: "../../bin/xScheduleWeb\*.*"; DestDir: "{app}/xScheduleWeb"; Flags: ignoreversion recursesubdirs
Source: "../../xlights/controllers\*.xcontroller"; DestDir: "{app}/controllers"; Flags: ignoreversion

; xSMSDaemon
Source: "../../xSchedule/xSMSDaemon/x64/Release/xSMSDaemon.dll"; DestDir: "{app}"
Expand Down
16 changes: 15 additions & 1 deletion xSchedule/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ PluginManager::PluginState::PluginState(wxDynamicLibrary* dl, const std::string&
PluginManager::PluginState::~PluginState()
{
if (_dl) {
spdlog::debug("PluginState destructor unloading dynamic library '{}'.", _filename);
///_dl->Detach(); ????
delete _dl;
spdlog::debug("PluginState destructor unloaded dynamic library '{}'.", _filename);
}
}

Expand Down Expand Up @@ -151,6 +153,7 @@ void PluginManager::DoUnload(const std::string& plugin)
if (fn != nullptr) {
spdlog::debug("Unloading plugin {}", plugin);
fn();
spdlog::debug("Unloaded plugin {}", plugin);
}
}

Expand Down Expand Up @@ -353,6 +356,8 @@ void PluginManager::RegisterStaticPlugins() {

void PluginManager::Initialise(const std::string& showDir)
{
spdlog::debug("PluginManager::Initialise starting for show dir '{}'.", showDir);

// scan xSchedule folder first

wxFileName fi(wxStandardPaths::Get().GetExecutablePath().ToStdString());
Expand All @@ -364,10 +369,14 @@ void PluginManager::Initialise(const std::string& showDir)

// then add anything that is statically compiled in
RegisterStaticPlugins();

for (auto it : _plugins) {
spdlog::debug("PluginManager::Initialise loading plugin '{}'.", it.first);
DoLoad(it.first, (char*)showDir.c_str());
spdlog::debug("PluginManager::Initialise loaded plugin '{}'.", it.first);
}

spdlog::debug("PluginManager::Initialise complete. {} plugin(s).", _plugins.size());
}

bool PluginManager::StartPlugin(const std::string& plugin, const std::string& showDir, const std::string& xScheduleURL)
Expand Down Expand Up @@ -416,12 +425,17 @@ void PluginManager::WipeSettings()

void PluginManager::Uninitialise()
{
spdlog::debug("PluginManager::Uninitialise starting. {} plugin(s).", _plugins.size());
for (auto it : _plugins)
{
spdlog::debug("PluginManager::Uninitialise unloading plugin '{}'.", it.first);
DoUnload(it.first);
spdlog::debug("PluginManager::Uninitialise unloaded plugin '{}'. Deleting plugin state.", it.first);
delete it.second;
spdlog::debug("PluginManager::Uninitialise deleted plugin state for '{}'.", it.first);
}
_plugins.clear();
spdlog::debug("PluginManager::Uninitialise complete.");
}

std::vector<std::string> PluginManager::GetPlugins() const
Expand Down
104 changes: 63 additions & 41 deletions xSchedule/RemoteFalcon/RemoteFalconMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include <wx/dirdlg.h>
#include <wx/url.h>

#include "../../xlights/xLights/xLightsVersion.h"
#include "../xScheduleVersion.h"
#include "RemoteFalconMain.h"
#include "RemoteFalconSettingsDialog.h"
#include "RemoteFalconOptions.h"
Expand All @@ -50,6 +50,20 @@ static bool IsHttpErrorCode(int responseCode)
return responseCode != 0 && (responseCode < 200 || responseCode >= 300);
}

// Remote Falcon has been observed returning some fields (eg queuelength, leftms)
// as native JSON numbers rather than strings depending on the account/backend
// version. nlohmann's val.value(key, std::string()) still throws type_error.302
// in that case, so pull the value out ourselves and stringify whatever we find.
static std::string JsonAsString(const nlohmann::json& val, const std::string& key, const std::string& def = "")
{
if (!val.is_object()) return def;
auto it = val.find(key);
if (it == val.end() || it->is_null()) return def;
if (it->is_string()) return it->get<std::string>();
if (it->is_boolean()) return it->get<bool>() ? "true" : "false";
return it->dump();
}

enum wxbuildinfoformat {
short_f, long_f };

Expand Down Expand Up @@ -135,10 +149,11 @@ void RemoteFalconFrame::DoSendPlaylists() {
try {
nlohmann::json const val = nlohmann::json::parse(res);

if (!val.is_null() && !val["message"].is_null() && val["message"].get<std::string>() == "Success") {
std::string message = JsonAsString(val, "message");
if (!val.is_null() && message == "Success") {
_oldSteps = plsteps;
} else if (!val.is_null() && !val["message"].is_null()) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "ERROR: " + val["message"].get<std::string>());
} else if (!val.is_null() && !message.empty()) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "ERROR: " + message);
} else if (val.is_null()) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "ERROR: uploading playlist to remote falcon.");
}
Expand All @@ -162,6 +177,23 @@ void RemoteFalconFrame::AddMessage(MESSAGE_LEVEL msgLevel, const std::string& ms
}
}

void RemoteFalconFrame::LogViewerControlResponse(const std::string& res)
{
try {
nlohmann::json const val = nlohmann::json::parse(res);
std::string message = JsonAsString(val, "message");
if (!message.empty() && message != "Success") {
AddMessage(MESSAGE_LEVEL::ML_ERROR, " ERROR: " + message);
} else {
AddMessage(MESSAGE_LEVEL::ML_DEBUG, " OK.");
}
} catch (const nlohmann::json::exception& ex) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, " ERROR: " + std::string(ex.what()));
} catch (const std::exception& ex) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, " ERROR: " + std::string(ex.what()));
}
}

RemoteFalconFrame::RemoteFalconFrame(wxWindow* parent, const std::string& showDir, const std::string& xScheduleURL, p_xSchedule_Action action, wxWindowID id)
{
_toProcess = 0;
Expand Down Expand Up @@ -233,7 +265,7 @@ RemoteFalconFrame::RemoteFalconFrame(wxWindow* parent, const std::string& showDi
// only start the timer when we start the service
Timer_UpdatePlaylist.Stop();

SetTitle("Remote Falcon " + GetDisplayVersionString());
SetTitle("Remote Falcon " + GetXScheduleDisplayVersionString());

xSchedule::Initialise(action);

Expand Down Expand Up @@ -284,10 +316,11 @@ RemoteFalconFrame::RemoteFalconFrame(wxWindow* parent, const std::string& showDi
try {
nlohmann::json const val = nlohmann::json::parse(res);

if (!val.is_null() && !val["message"].is_null() && val["message"].get<std::string>() == "Success") {
std::string message = JsonAsString(val, "message");
if (!val.is_null() && message == "Success") {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Cleared remote falcon list of songs.");
} else if (!val.is_null() && !val["message"].is_null()) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "Error: " + val["message"].get<std::string>());
} else if (!val.is_null() && !message.empty()) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "Error: " + message);
} else {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "Error: " + res);
}
Expand Down Expand Up @@ -337,7 +370,7 @@ void RemoteFalconFrame::OnQuit(wxCommandEvent& event)

void RemoteFalconFrame::OnAbout(wxCommandEvent& event)
{
auto about = wxString::Format(wxT("RemoteFalcon v%s."), GetDisplayVersionString());
auto about = wxString::Format(wxT("RemoteFalcon v%s."), GetXScheduleDisplayVersionString());
wxMessageBox(about, _("Welcome to..."));
}

Expand Down Expand Up @@ -463,7 +496,7 @@ void RemoteFalconFrame::Start()

if (_options.IsEnableDisable()) {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Asking remote falcon to enable viewer control.");
AddMessage(MESSAGE_LEVEL::ML_INFO, " " + _remoteFalcon->EnableViewerControl(true));
LogViewerControlResponse(_remoteFalcon->EnableViewerControl(true));
_viewerControlEnabled = true;
}

Expand All @@ -477,7 +510,7 @@ void RemoteFalconFrame::Stop(bool suppressMessage)

if (_options.IsEnableDisable()) {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Asking remote falcon to disable viewer control.");
AddMessage(MESSAGE_LEVEL::ML_INFO, " " + _remoteFalcon->EnableViewerControl(false));
LogViewerControlResponse(_remoteFalcon->EnableViewerControl(false));
_viewerControlEnabled = false;
}

Expand Down Expand Up @@ -526,14 +559,11 @@ void RemoteFalconFrame::GetMode()
try {
nlohmann::json const val = nlohmann::json::parse(res);
if (!val.is_null()) {
if (!val["viewerControlMode"].is_null()) {
_mode = val["viewerControlMode"].get<std::string>();
}
if (!val["remoteSubdomain"].is_null()) {
_subdomain = val["remoteSubdomain"].get<std::string>();
}
if (!val["message"].is_null()) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "ERROR: " + val["message"].get<std::string>());
_mode = JsonAsString(val, "viewerControlMode");
_subdomain = JsonAsString(val, "remoteSubdomain");
std::string message = JsonAsString(val, "message");
if (!message.empty()) {
AddMessage(MESSAGE_LEVEL::ML_ERROR, "ERROR: " + message);
}
}

Expand Down Expand Up @@ -591,14 +621,10 @@ void RemoteFalconFrame::GetAndPlaySong(const std::string& playing)
std::string nextSong;
if (!val.is_null()) {
if (_mode == "voting") {
if (!val["winningPlaylist"].is_null()) {
nextSong = val["winningPlaylist"].get<std::string>();
}
nextSong = JsonAsString(val, "winningPlaylist");
}
else {
if (!val["nextPlaylist"].is_null()) {
nextSong = val["nextPlaylist"].get<std::string>();
}
nextSong = JsonAsString(val, "nextPlaylist");
}
}

Expand Down Expand Up @@ -660,13 +686,9 @@ void RemoteFalconFrame::GetAndPlayEffect() {
std::string nextSong;
if (!val.is_null()) {
if (_mode == "voting") {
if (!val["winningPlaylist"].is_null()) {
nextSong = val["winningPlaylist"].get<std::string>();
}
nextSong = JsonAsString(val, "winningPlaylist");
} else {
if (!val["nextPlaylist"].is_null()) {
nextSong = val["nextPlaylist"].get<std::string>();
}
nextSong = JsonAsString(val, "nextPlaylist");
}
}

Expand Down Expand Up @@ -706,29 +728,29 @@ void RemoteFalconFrame::DoNotifyStatus(const std::string& status)
if (effects.size() > 0)
playing = effects.front();
} else {
playing = val.value("step", std::string());
playing = JsonAsString(val, "step");
}

if (_lastPlaying != playing) {
SendPlayingSong(playing);
_lastPlaying = playing;
}

auto trigger = val.value("trigger", std::string());
auto trigger = JsonAsString(val, "trigger");

// Only play songs if a schedule is playing
if (trigger == "scheduled" || trigger == "queued") {
int queueLength = wxAtoi(val.value("queuelength", std::string()));
auto lefts = wxAtol(val.value("leftms", std::string())) / 1000;
_playingPlaylist = val.value("playlist", std::string());
int queueLength = wxAtoi(JsonAsString(val, "queuelength"));
auto lefts = wxAtol(JsonAsString(val, "leftms")) / 1000;
_playingPlaylist = JsonAsString(val, "playlist");

// we can only play a song if the playlist playing allows
if (_options.IsPlayDuring(_playingPlaylist) || _playingPlaylist == "Song Queue") {

if (!_viewerControlEnabled) {
if (_options.IsEnableDisable()) {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Asking remote falcon to enable viewer control.");
AddMessage(MESSAGE_LEVEL::ML_INFO, " " + _remoteFalcon->EnableViewerControl(true));
LogViewerControlResponse(_remoteFalcon->EnableViewerControl(true));
_viewerControlEnabled = true;
}
}
Expand All @@ -749,7 +771,7 @@ void RemoteFalconFrame::DoNotifyStatus(const std::string& status)
if (_viewerControlEnabled) {
if (_options.IsEnableDisable()) {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Asking remote falcon to disable viewer control.");
AddMessage(MESSAGE_LEVEL::ML_INFO, " " + _remoteFalcon->EnableViewerControl(false));
LogViewerControlResponse(_remoteFalcon->EnableViewerControl(false));
_viewerControlEnabled = false;
}
}
Expand All @@ -760,7 +782,7 @@ void RemoteFalconFrame::DoNotifyStatus(const std::string& status)
if (_viewerControlEnabled) {
if (_options.IsEnableDisable()) {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Asking remote falcon to disable viewer control.");
AddMessage(MESSAGE_LEVEL::ML_INFO, " " + _remoteFalcon->EnableViewerControl(false));
LogViewerControlResponse(_remoteFalcon->EnableViewerControl(false));
_viewerControlEnabled = false;
}
}
Expand Down Expand Up @@ -841,12 +863,12 @@ bool RemoteFalconFrame::SendCommand(const std::string& command, const std::strin
else if (command == "viewer_control") {
if (parameters == "start") {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Asking remote falcon to enable viewer control.");
AddMessage(MESSAGE_LEVEL::ML_INFO, " " + _remoteFalcon->EnableViewerControl(true));
LogViewerControlResponse(_remoteFalcon->EnableViewerControl(true));
_viewerControlEnabled = true;
return true;
} else if (parameters == "stop") {
AddMessage(MESSAGE_LEVEL::ML_INFO, "Asking remote falcon to disable viewer control.");
AddMessage(MESSAGE_LEVEL::ML_INFO, " " + _remoteFalcon->EnableViewerControl(false));
LogViewerControlResponse(_remoteFalcon->EnableViewerControl(false));
_viewerControlEnabled = false;
return true;
} else {
Expand Down
1 change: 1 addition & 0 deletions xSchedule/RemoteFalcon/RemoteFalconMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class RemoteFalconFrame : public wxFrame
void ValidateWindow();
void AddMessage(MESSAGE_LEVEL lvl, const std::string& msg);
void DoAddMessage(const std::string& msg);
void LogViewerControlResponse(const std::string& res);
void DoNotifyStatus(const std::string& status);
void DoSendPlayingSong(const std::string& playing);
void SendPlayingSong(const std::string& playing);
Expand Down
8 changes: 8 additions & 0 deletions xSchedule/ScheduleManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,27 +342,34 @@ int ScheduleManager::DoSync(const std::string& filename, long ms) {
}

ScheduleManager::~ScheduleManager() {
spdlog::debug("ScheduleManager destructor starting.");
AllOff();
spdlog::debug("ScheduleManager destructor: stopping output.");
_outputManager->StopOutput();
SetConfigBool("OutputActive", false);
#ifdef __WXMSW__
::SetPriorityClass(::GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
#endif
spdlog::debug("ScheduleManager destructor: stopping virtual matrices.");
StopVirtualMatrices();
ManageBackground();
spdlog::info("Stopped outputting to lights.");

if (IsDirty()) {
spdlog::debug("ScheduleManager destructor: schedule is dirty, prompting to save.");
if (wxMessageBox("Unsaved changes to the schedule. Save now?", "Unsaved changes", wxYES_NO) == wxYES) {
Save();
}
}

spdlog::debug("ScheduleManager destructor: stopping sync manager.");
_syncManager->Stop(GetForceLocalIP());

if (_listenerManager != nullptr) {
spdlog::debug("ScheduleManager destructor: stopping listener manager.");
_listenerManager->Stop();
delete _listenerManager;
spdlog::debug("ScheduleManager destructor: listener manager stopped.");
}

while (_overlayData.size() > 0) {
Expand Down Expand Up @@ -436,6 +443,7 @@ ScheduleManager::~ScheduleManager() {
#endif

spdlog::info("Closed schedule.");
spdlog::debug("ScheduleManager destructor complete.");
}

std::list<PlayListItem*> ScheduleManager::GetPlayListIps() const {
Expand Down
6 changes: 3 additions & 3 deletions xSchedule/xSMSDaemon/xSMSDaemonMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include <wx/dirdlg.h>
#include <wx/url.h>

#include "../../xlights/xLights/xLightsVersion.h"
#include "../xScheduleVersion.h"
#include "xSMSDaemonMain.h"

#include "../../xlights/include/xLights.xpm"
Expand Down Expand Up @@ -197,7 +197,7 @@ xSMSDaemonFrame::xSMSDaemonFrame(wxWindow* parent, const std::string& showDir, c
//Timer_Second.SetName("xSMSDaemon second timer");
//SendTimer.SetName("xSMSDaemon send timer");

SetTitle("xLights SMS Daemon " + GetDisplayVersionString());
SetTitle("xLights SMS Daemon " + GetXScheduleDisplayVersionString());

wxIconBundle icons;
icons.AddIcon(wxIcon(xlights_16_xpm));
Expand Down Expand Up @@ -383,7 +383,7 @@ void xSMSDaemonFrame::OnQuit(wxCommandEvent& event)

void xSMSDaemonFrame::OnAbout(wxCommandEvent& event)
{
auto about = wxString::Format(wxT("xSMSDaemon v%s."), GetDisplayVersionString());
auto about = wxString::Format(wxT("xSMSDaemon v%s."), GetXScheduleDisplayVersionString());
wxMessageBox(about, _("Welcome to..."));
}

Expand Down
Loading
Loading