Skip to content

Commit e0616c7

Browse files
committed
Merge remote-tracking branch 'origin/master' into fix_deadlock_using_rxmessage_queue
2 parents 92fb568 + 570a646 commit e0616c7

File tree

10 files changed

+232
-88
lines changed

10 files changed

+232
-88
lines changed

hardware/LogitechMediaServer.cpp

Lines changed: 132 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ bool CLogitechMediaServer::StartHardware()
105105

106106
StartHeartbeatThread();
107107

108-
ReloadNodes();
109-
110108
//Start worker thread
111109
m_stoprequested = false;
112110
m_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CLogitechMediaServer::Do_Work, this)));
@@ -282,9 +280,12 @@ void CLogitechMediaServer::Do_Node_Work(const LogitechMediaServerNode &Node)
282280
if (sYear == "0") sYear = "";
283281
if (sYear != "")
284282
sYear = " (" + sYear + ")";
283+
284+
sLabel = sArtist + " - " + sTitle + sYear;
285285
}
286+
else
287+
sLabel = "(empty playlist)";
286288

287-
sLabel = sArtist + " - " + sTitle + sYear;
288289
sStatus = sLabel;
289290
}
290291
}
@@ -308,6 +309,9 @@ void CLogitechMediaServer::Do_Work()
308309

309310
_log.Log(LOG_STATUS, "Logitech Media Server: Worker started...");
310311

312+
ReloadNodes();
313+
ReloadPlaylists();
314+
311315
while (!m_stoprequested)
312316
{
313317
sleep_milliseconds(500);
@@ -509,26 +513,23 @@ bool CLogitechMediaServer::WriteToHardware(const char *pdata, const unsigned cha
509513
{
510514
case light2_sOn:
511515
case light2_sGroupOn:
512-
SendCommand(itt->ID, "PowerOn");
513-
return true;
516+
return SendCommand(itt->ID, "PowerOn");
514517
case light2_sOff:
515518
case light2_sGroupOff:
516-
SendCommand(itt->ID, "PowerOff");
517-
return true;
519+
return SendCommand(itt->ID, "PowerOff");
518520
case gswitch_sPlay:
519521
SendCommand(itt->ID, "NowPlaying");
520-
SendCommand(itt->ID, "Play");
521-
return true;
522+
return SendCommand(itt->ID, "Play");
523+
case gswitch_sPlayPlaylist:
524+
sParam = GetPlaylistByRefID(iParam);
525+
return SendCommand(itt->ID, "PlayPlaylist", sParam);
522526
case gswitch_sStop:
523-
SendCommand(itt->ID, "Stop");
524-
return true;
527+
return SendCommand(itt->ID, "Stop");
525528
case gswitch_sPause:
526-
SendCommand(itt->ID, "Pause");
527-
return true;
529+
return SendCommand(itt->ID, "Pause");
528530
case gswitch_sSetVolume:
529531
sParam = boost::lexical_cast<std::string>(iParam);
530-
SendCommand(itt->ID, "SetVolume", sParam);
531-
return true;
532+
return SendCommand(itt->ID, "SetVolume", sParam);
532533
default:
533534
return true;
534535
}
@@ -576,7 +577,44 @@ void CLogitechMediaServer::ReloadNodes()
576577
_log.Log(LOG_ERROR, "Logitech Media Server: No player-switches found.");
577578
}
578579

579-
void CLogitechMediaServer::SendCommand(const int ID, const std::string &command, const std::string &param)
580+
void CLogitechMediaServer::ReloadPlaylists()
581+
{
582+
m_playlists.clear();
583+
584+
std::string sPostdata = "{\"id\":1,\"method\":\"slim.request\",\"params\":[\"\",[\"playlists\",0,999]]}";
585+
Json::Value root = Query(m_IP, m_Port, sPostdata);
586+
587+
int totPlaylists = root["count"].asInt();
588+
if (totPlaylists > 0) {
589+
_log.Log(LOG_STATUS, "Logitech Media Server: %i playlist(s) found.", totPlaylists);
590+
for (int ii = 0; ii < totPlaylists; ii++)
591+
{
592+
LMSPlaylistNode pnode;
593+
594+
pnode.ID = root["playlists_loop"][ii]["id"].asInt();
595+
pnode.Name = root["playlists_loop"][ii]["playlist"].asString();
596+
pnode.refID = pnode.ID % 256;
597+
598+
m_playlists.push_back(pnode);
599+
}
600+
}
601+
else
602+
_log.Log(LOG_STATUS, "Logitech Media Server: No playlists found.");
603+
}
604+
605+
std::string CLogitechMediaServer::GetPlaylistByRefID(const int ID)
606+
{
607+
std::vector<CLogitechMediaServer::LMSPlaylistNode>::const_iterator itt;
608+
609+
for (itt = m_playlists.begin(); itt != m_playlists.end(); ++itt) {
610+
if (itt->refID == ID) return itt->Name;
611+
}
612+
613+
_log.Log(LOG_ERROR, "Logitech Media Server: Playlist ID %d not found.", ID);
614+
return "";
615+
}
616+
617+
bool CLogitechMediaServer::SendCommand(const int ID, const std::string &command, const std::string &param)
580618
{
581619
std::vector<std::vector<std::string> > result;
582620
std::string sPlayerId = "";
@@ -640,6 +678,10 @@ void CLogitechMediaServer::SendCommand(const int ID, const std::string &command,
640678
else if (command == "Play") {
641679
sLMSCmnd = "\"button\", \"play.single\"";
642680
}
681+
else if (command == "PlayPlaylist") {
682+
if (param == "") return false;
683+
sLMSCmnd = "\"playlist\", \"play\", \"" + param + "\"";
684+
}
643685
else if (command == "Pause") {
644686
sLMSCmnd = "\"button\", \"pause.single\"";
645687
}
@@ -653,22 +695,51 @@ void CLogitechMediaServer::SendCommand(const int ID, const std::string &command,
653695
sLMSCmnd = "\"power\", \"0\"";
654696
}
655697
else if (command == "SetVolume") {
698+
if (param == "") return false;
656699
sLMSCmnd = "\"mixer\", \"volume\", \"" + param + "\"";
657700
}
658701

659702
if (sLMSCmnd != "")
660703
{
661704
std::string sPostdata = "{\"id\":1,\"method\":\"slim.request\",\"params\":[\"" + sPlayerId + "\",[" + sLMSCmnd + "]]}";
662705
Json::Value root = Query(m_IP, m_Port, sPostdata);
706+
707+
sPostdata = "{\"id\":1,\"method\":\"slim.request\",\"params\":[\"" + sPlayerId + "\",[\"status\",\"-\",1,\"tags:uB\"]]}";
708+
root = Query(m_IP, m_Port, sPostdata);
709+
710+
if (root["player_connected"].asString() == "1")
711+
{
712+
std::string sPower = root["power"].asString();
713+
std::string sMode = root["mode"].asString();
714+
715+
if (command == "Stop")
716+
return sMode == "stop";
717+
else if (command == "Pause")
718+
return sMode == "pause";
719+
else if (command == "Play")
720+
return sMode == "play";
721+
else if (command == "PlayPlaylist")
722+
return sMode == "play";
723+
else if (command == "PowerOn")
724+
return sPower == "1";
725+
else if (command == "PowerOff")
726+
return sPower == "0";
727+
else
728+
return false;
729+
}
730+
else
731+
return false;
663732
}
664733
else
665734
{
666735
_log.Log(LOG_ERROR, "Logitech Media Server: (%s) Command: '%s'. Unknown command.", result[0][0].c_str(), command.c_str());
736+
return false;
667737
}
668738
}
669739
else
670740
{
671741
_log.Log(LOG_ERROR, "Logitech Media Server: (%d) Command: '%s'. Device not found.", ID, command.c_str());
742+
return false;
672743
}
673744
}
674745

@@ -686,6 +757,23 @@ void CLogitechMediaServer::SendText(const std::string &playerIP, const std::stri
686757
}
687758
}
688759

760+
std::vector<CLogitechMediaServer::LMSPlaylistNode> CLogitechMediaServer::GetPlaylists()
761+
{
762+
return m_playlists;
763+
}
764+
765+
int CLogitechMediaServer::GetPlaylistRefID(const std::string &name)
766+
{
767+
std::vector<CLogitechMediaServer::LMSPlaylistNode>::const_iterator itt;
768+
769+
for (itt = m_playlists.begin(); itt != m_playlists.end(); ++itt) {
770+
if (itt->Name == name) return itt->refID;
771+
}
772+
773+
_log.Log(LOG_ERROR, "Logitech Media Server: Playlist '%s' not found.", name.c_str());
774+
return 0;
775+
}
776+
689777
//Webserver helpers
690778
namespace http {
691779
namespace server {
@@ -757,6 +845,34 @@ namespace http {
757845
}
758846
}
759847

848+
void CWebServer::Cmd_LMSGetPlaylists(WebEmSession & session, const request& req, Json::Value &root)
849+
{
850+
std::string hwid = request::findValue(&req, "idx");
851+
if (hwid == "")
852+
return;
853+
int iHardwareID = atoi(hwid.c_str());
854+
CDomoticzHardwareBase *pBaseHardware = m_mainworker.GetHardware(iHardwareID);
855+
if (pBaseHardware == NULL)
856+
return;
857+
if (pBaseHardware->HwdType != HTYPE_LogitechMediaServer)
858+
return;
859+
CLogitechMediaServer *pHardware = (CLogitechMediaServer*)pBaseHardware;
860+
861+
root["status"] = "OK";
862+
root["title"] = "Cmd_LMSGetPlaylists";
863+
864+
std::vector<CLogitechMediaServer::LMSPlaylistNode> m_nodes = pHardware->GetPlaylists();
865+
std::vector<CLogitechMediaServer::LMSPlaylistNode>::const_iterator itt;
866+
867+
int ii = 0;
868+
for (itt = m_nodes.begin(); itt != m_nodes.end(); ++itt) {
869+
root["result"][ii]["id"] = itt->ID;
870+
root["result"][ii]["refid"] = itt->refID;
871+
root["result"][ii]["Name"] = itt->Name;
872+
ii++;
873+
}
874+
}
875+
760876
void CWebServer::Cmd_LMSMediaCommand(WebEmSession & session, const request& req, Json::Value &root)
761877
{
762878
std::string sIdx = request::findValue(&req, "idx");

hardware/LogitechMediaServer.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ class CLogitechMediaServer : public CDomoticzHardwareBase
2121
std::string sShortStatus;
2222
};
2323
public:
24+
struct LMSPlaylistNode
25+
{
26+
int ID;
27+
int refID;
28+
std::string Name;
29+
};
30+
2431
CLogitechMediaServer(const int ID, const std::string IPAddress, const int Port, const int PollIntervalsec, const int PingTimeoutms);
2532
CLogitechMediaServer(const int ID, const std::string IPAddress, const int Port);
2633
CLogitechMediaServer(const int ID);
@@ -32,8 +39,10 @@ class CLogitechMediaServer : public CDomoticzHardwareBase
3239
void RemoveAllNodes();
3340
void SetSettings(const int PollIntervalsec, const int PingTimeoutms);
3441
void Restart();
35-
void SendCommand(const int ID, const std::string &command, const std::string &param = "");
42+
bool SendCommand(const int ID, const std::string &command, const std::string &param = "");
3643
void SendText(const std::string &playerIP, const std::string &subject, const std::string &text, const int duration);
44+
std::vector<LMSPlaylistNode> GetPlaylists();
45+
int GetPlaylistRefID(const std::string &name);
3746
private:
3847
_eNotificationTypes NotificationType(_eMediaStatus nStatus);
3948
void Do_Work();
@@ -46,8 +55,11 @@ class CLogitechMediaServer : public CDomoticzHardwareBase
4655
void Do_Node_Work(const LogitechMediaServerNode &Node);
4756
void UpdateNodeStatus(const LogitechMediaServerNode &Node, const _eMediaStatus nStatus, const std::string sStatus, const bool bPingOK);
4857
void ReloadNodes();
58+
void ReloadPlaylists();
59+
std::string GetPlaylistByRefID(const int ID);
4960

5061
std::vector<LogitechMediaServerNode> m_nodes;
62+
std::vector<LMSPlaylistNode> m_playlists;
5163

5264
int m_iThreadsRunning;
5365
int m_iPollInterval;

hardware/hardwaretypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
#define gswitch_sPause 0x13
139139
#define gswitch_sPlay 0x14
140140
#define gswitch_sSetVolume 0x15
141+
#define gswitch_sPlayPlaylist 0x16
141142
//--------------
142143

143144
#define pTypeLux 0xF6

main/EventSystem.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "SQLHelper.h"
77
#include "Logger.h"
88
#include "../hardware/hardwaretypes.h"
9+
#include "../hardware/LogitechMediaServer.h"
910
#include <iostream>
1011
#include "../httpclient/HTTPClient.h"
1112
#include "localtime_r.h"
@@ -2705,7 +2706,7 @@ bool CEventSystem::ScheduleEvent(std::string deviceName, const std::string &Acti
27052706
std::vector<std::vector<std::string> > result;
27062707

27072708
if (isScene) {
2708-
result = m_sql.safe_query("SELECT ID FROM Scenes WHERE (Name == '%q')",
2709+
result = m_sql.safe_query("SELECT ID FROM Scenes WHERE (Name == '%q')",
27092710
deviceName.c_str());
27102711
}
27112712
else {
@@ -2776,6 +2777,19 @@ bool CEventSystem::ScheduleEvent(int deviceID, std::string Action, bool isScene,
27762777
Action = Action.substr(0, 10);
27772778
}
27782779

2780+
if (Action.find("Play Playlist") == 0)
2781+
{
2782+
CDomoticzHardwareBase *pBaseHardware = m_mainworker.GetHardwareByType(HTYPE_LogitechMediaServer);
2783+
if (pBaseHardware == NULL) return false;
2784+
CLogitechMediaServer *pHardware = (CLogitechMediaServer*)pBaseHardware;
2785+
2786+
int iPlaylistID = pHardware->GetPlaylistRefID(Action.substr(14).c_str());
2787+
if (iPlaylistID == 0) return false;
2788+
2789+
_level = iPlaylistID;
2790+
Action = Action.substr(0, 13);
2791+
}
2792+
27792793
int DelayTime = 1;
27802794

27812795
if (randomTimer > 0) {

main/RFXNames.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,6 +2012,11 @@ bool GetLightCommand(
20122012
cmd = gswitch_sPlay;
20132013
return true;
20142014
}
2015+
else if (switchcmd == "Play Playlist")
2016+
{
2017+
cmd = gswitch_sPlayPlaylist;
2018+
return true;
2019+
}
20152020
else if (switchcmd == "Set Volume")
20162021
{
20172022
cmd = gswitch_sSetVolume;

main/WebServer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ namespace http {
386386

387387
RegisterCommandCode("lmssetmode", boost::bind(&CWebServer::Cmd_LMSSetMode, this, _1, _2, _3));
388388
RegisterCommandCode("lmsgetnodes", boost::bind(&CWebServer::Cmd_LMSGetNodes, this, _1, _2, _3));
389+
RegisterCommandCode("lmsgetplaylists", boost::bind(&CWebServer::Cmd_LMSGetPlaylists, this, _1, _2, _3));
389390
RegisterCommandCode("lmsmediacommand", boost::bind(&CWebServer::Cmd_LMSMediaCommand, this, _1, _2, _3));
390391

391392
RegisterCommandCode("savefibarolinkconfig", boost::bind(&CWebServer::Cmd_SaveFibaroLinkConfig, this, _1, _2, _3));

main/WebServer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class CWebServer : public session_store
116116
void Cmd_KodiMediaCommand(WebEmSession & session, const request& req, Json::Value &root);
117117
void Cmd_LMSSetMode(WebEmSession & session, const request& req, Json::Value &root);
118118
void Cmd_LMSGetNodes(WebEmSession & session, const request& req, Json::Value &root);
119+
void Cmd_LMSGetPlaylists(WebEmSession & session, const request& req, Json::Value &root);
119120
void Cmd_LMSMediaCommand(WebEmSession & session, const request& req, Json::Value &root);
120121
void Cmd_SaveFibaroLinkConfig(WebEmSession & session, const request& req, Json::Value &root);
121122
void Cmd_GetFibaroLinkConfig(WebEmSession & session, const request& req, Json::Value &root);

main/mainworker.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9669,8 +9669,10 @@ bool MainWorker::SwitchLightInt(const std::vector<std::string> &sd, std::string
96699669
}
96709670
else if (switchtype == STYPE_Media)
96719671
{
9672-
level = (level < 0) ? 0 : level;
9673-
level = (level > 100) ? 100 : level;
9672+
if (switchcmd == "Set Volume") {
9673+
level = (level < 0) ? 0 : level;
9674+
level = (level > 100) ? 100 : level;
9675+
}
96749676
}
96759677
else
96769678
level = (level > 15) ? 15 : level;
@@ -9699,9 +9701,6 @@ bool MainWorker::SwitchLightInt(const std::vector<std::string> &sd, std::string
96999701
}
97009702

97019703
if (!IsTesting) {
9702-
//Skip for LMS SetVolume
9703-
if ((pHardware->HwdType == HTYPE_LogitechMediaServer) && (lcmd.LIGHTING2.cmnd == gswitch_sSetVolume))
9704-
return true;
97059704
//send to internal for now (later we use the ACK)
97069705
PushAndWaitRxMessage(m_hardwaredevices[hindex],(const unsigned char *)&lcmd);
97079706
}

0 commit comments

Comments
 (0)