Skip to content

Commit d8189d9

Browse files
committed
2 parents 40e816c + 1d94d91 commit d8189d9

File tree

2 files changed

+75
-26
lines changed

2 files changed

+75
-26
lines changed

hardware/Kodi.cpp

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ void CKodiNode::handleMessage(std::string& pMessage)
194194
}
195195
else if (root["error"].empty() != true)
196196
{
197-
/* e.g {"error":{"code":-32100,"message":"Failed to execute method."},"id":1,"jsonrpc":"2.0"} */
197+
/* e.g {"error":{"code":-32100,"message":"Failed to execute method."},"id":1001,"jsonrpc":"2.0"} */
198198
_log.Log(LOG_ERROR, "Kodi: (%s) Code %d Text '%s' ID '%d' Request '%s'", m_Name.c_str(), root["error"]["code"].asInt(), root["error"]["message"].asCString(), root["id"].asInt(), m_sLastMessage.c_str());
199199
}
200200
else
@@ -235,7 +235,7 @@ void CKodiNode::handleMessage(std::string& pMessage)
235235

236236
if (m_CurrentStatus.PlayerID() != "") // if we now have a player id then request more details
237237
{
238-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetItem\",\"id\":3,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"artist\",\"album\",\"year\",\"channel\",\"showtitle\",\"season\",\"episode\",\"title\"]}}";
238+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetItem\",\"id\":1003,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"artist\",\"album\",\"year\",\"channel\",\"showtitle\",\"season\",\"episode\",\"title\"]}}";
239239
handleWrite(sMessage);
240240
}
241241
}
@@ -247,9 +247,9 @@ void CKodiNode::handleMessage(std::string& pMessage)
247247
else if (root["method"] == "Player.OnSeek")
248248
{
249249
if (m_CurrentStatus.PlayerID() != "")
250-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetProperties\",\"id\":2,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"live\",\"percentage\",\"speed\"]}}";
250+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetProperties\",\"id\":1002,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"live\",\"percentage\",\"speed\"]}}";
251251
else
252-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetActivePlayers\",\"id\":5}";
252+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetActivePlayers\",\"id\":1005}";
253253
handleWrite(sMessage);
254254
}
255255
else if ((root["method"] == "Player.OnQuit") || (root["method"] == "Player.OnSleep"))
@@ -258,6 +258,15 @@ void CKodiNode::handleMessage(std::string& pMessage)
258258
m_CurrentStatus.Status(MSTAT_OFF);
259259
UpdateStatus();
260260
}
261+
else if (root["method"] == "Application.OnVolumeChanged")
262+
{
263+
if (DEBUG_LOGGING)
264+
{
265+
float iVolume = root["params"]["data"]["volume"].asFloat();
266+
bool bMuted = root["params"]["data"]["muted"].asBool();
267+
_log.Log(LOG_NORM, "Kodi: (%s) Volume changed to %3.5f, Muted: %s.", m_Name.c_str(), iVolume, bMuted?"true":"false");
268+
}
269+
}
261270
else if (DEBUG_LOGGING) _log.Log(LOG_NORM, "Kodi: (%s) Message warning, unhandled method: '%s'", m_Name.c_str(), root["method"].asCString());
262271
}
263272
else _log.Log(LOG_ERROR, "Kodi: (%s) Message error, params but no method: '%s'", m_Name.c_str(), pMessage.c_str());
@@ -276,7 +285,7 @@ void CKodiNode::handleMessage(std::string& pMessage)
276285
int iMessageID = root["id"].asInt();
277286
switch (iMessageID)
278287
{
279-
case 1: //Ping response
288+
case 1001: //Ping response
280289
if (root["result"] == "pong")
281290
{
282291
m_iMissedPongs = 0;
@@ -285,7 +294,7 @@ void CKodiNode::handleMessage(std::string& pMessage)
285294
UpdateStatus();
286295
}
287296
break;
288-
case 2: //Poll response
297+
case 1002: //Poll response
289298
if (root["result"].isMember("live"))
290299
{
291300
m_CurrentStatus.Live(root["result"]["live"].asBool());
@@ -301,7 +310,7 @@ void CKodiNode::handleMessage(std::string& pMessage)
301310
}
302311
UpdateStatus();
303312
break;
304-
case 3: //OnPlay media details response
313+
case 1003: //OnPlay media details response
305314
if (root["result"].isMember("item"))
306315
{
307316
if (root["result"]["item"].isMember("type")) m_CurrentStatus.Type(root["result"]["item"]["type"].asCString());
@@ -344,12 +353,12 @@ void CKodiNode::handleMessage(std::string& pMessage)
344353
if ((m_CurrentStatus.PlayerID() != "") && (m_CurrentStatus.Type() != "picture")) // request final details
345354
{
346355
std::string sMessage;
347-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetProperties\",\"id\":2,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"live\",\"percentage\",\"speed\"]}}";
356+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetProperties\",\"id\":1002,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"live\",\"percentage\",\"speed\"]}}";
348357
handleWrite(sMessage);
349358
}
350359
}
351360
break;
352-
case 4: //Shutdown details response
361+
case 1004: //Shutdown details response
353362
{
354363
m_Stoppable = false;
355364
std::string sAction = "Nothing";
@@ -374,25 +383,25 @@ void CKodiNode::handleMessage(std::string& pMessage)
374383
if (sAction != "Nothing")
375384
{
376385
m_Stoppable = true;
377-
std::string sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"System." + sAction + "\",\"id\":8}";
386+
std::string sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"System." + sAction + "\",\"id\":1008}";
378387
handleWrite(sMessage);
379388
}
380389
}
381390
break;
382-
case 5: //GetPlayers response, normally requried when Domoticz starts up and media is already streaming
391+
case 1005: //GetPlayers response, normally requried when Domoticz starts up and media is already streaming
383392
if (root["result"][0].isMember("playerid"))
384393
{
385394
m_CurrentStatus.PlayerID(root["result"][0]["playerid"].asInt());
386-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetItem\",\"id\":3,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"artist\",\"album\",\"year\",\"channel\",\"showtitle\",\"season\",\"episode\",\"title\"]}}";
395+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetItem\",\"id\":1003,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"artist\",\"album\",\"year\",\"channel\",\"showtitle\",\"season\",\"episode\",\"title\"]}}";
387396
handleWrite(sMessage);
388397
}
389398
break;
390-
case 6: //Remote Control response
399+
case 1006: //Remote Control response
391400
if (root["result"] != "OK")
392401
_log.Log(LOG_ERROR, "Kodi: (%s) Send Command Failed: '%s'", m_Name.c_str(), root["result"].asCString());
393402
break;
394-
case 7: //Can Shutdown response (after connect)
395-
handleWrite(std::string("{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetActivePlayers\",\"id\":5}"));
403+
case 1007: //Can Shutdown response (after connect)
404+
handleWrite(std::string("{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetActivePlayers\",\"id\":1005}"));
396405
if (root["result"].isMember("canshutdown"))
397406
{
398407
bCanShutdown = root["result"]["canshutdown"].asBool();
@@ -407,10 +416,13 @@ void CKodiNode::handleMessage(std::string& pMessage)
407416
}
408417
m_Stoppable = (bCanShutdown || bCanHibernate || bCanSuspend);
409418
break;
410-
case 8: //Shutdown response
419+
case 1008: //Shutdown response
411420
if (root["result"] == "OK")
412421
_log.Log(LOG_NORM, "Kodi: (%s) Shutdown command accepted.", m_Name.c_str());
413422
break;
423+
case 1009: //SetVolume response
424+
_log.Log(LOG_NORM, "Kodi: (%s) Volume set to %d.", m_Name.c_str(), root["result"].asInt());
425+
break;
414426
default:
415427
_log.Log(LOG_ERROR, "Kodi: (%s) Message error, unknown ID found: '%s'", m_Name.c_str(), pMessage.c_str());
416428
}
@@ -485,7 +497,7 @@ void CKodiNode::handleConnect()
485497
}
486498
m_Socket->async_read_some(boost::asio::buffer(m_Buffer, sizeof m_Buffer),
487499
boost::bind(&CKodiNode::handleRead, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
488-
handleWrite(std::string("{\"jsonrpc\":\"2.0\",\"method\":\"System.GetProperties\",\"params\":{\"properties\":[\"canhibernate\",\"cansuspend\",\"canshutdown\"]},\"id\":7}"));
500+
handleWrite(std::string("{\"jsonrpc\":\"2.0\",\"method\":\"System.GetProperties\",\"params\":{\"properties\":[\"canhibernate\",\"cansuspend\",\"canshutdown\"]},\"id\":1007}"));
489501
}
490502
else
491503
{
@@ -592,13 +604,13 @@ void CKodiNode::Do_Work()
592604
if (m_CurrentStatus.IsStreaming())
593605
{ // Update percentage if playing media (required because Player.OnPropertyChanged never get received as of Kodi 'Helix')
594606
if (m_CurrentStatus.PlayerID() != "")
595-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetProperties\",\"id\":2,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"live\",\"percentage\",\"speed\"]}}";
607+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetProperties\",\"id\":1002,\"params\":{\"playerid\":" + m_CurrentStatus.PlayerID() + ",\"properties\":[\"live\",\"percentage\",\"speed\"]}}";
596608
else
597-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetActivePlayers\",\"id\":5}";
609+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"Player.GetActivePlayers\",\"id\":1005}";
598610
}
599611
else
600612
{
601-
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"JSONRPC.Ping\",\"id\":1}";
613+
sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"JSONRPC.Ping\",\"id\":1001}";
602614
if (m_iMissedPongs++ > m_iTimeoutCnt)
603615
{
604616
_log.Log(LOG_NORM, "Kodi: (%s) Missed %d pings, assumed off.", m_Name.c_str(), m_iTimeoutCnt);
@@ -657,10 +669,10 @@ void CKodiNode::SendCommand(const std::string &command)
657669
if (sKodiCall.length())
658670
{
659671
// http://kodi.wiki/view/JSON-RPC_API/v6#Input.Action
660-
// { "jsonrpc": "2.0", "method": "Input.ExecuteAction", "params": { "action": "stop" }, "id": 6 }
672+
// { "jsonrpc": "2.0", "method": "Input.ExecuteAction", "params": { "action": "stop" }, "id": 1006 }
661673
std::string sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"" + sKodiCall + "\",\"params\":{";
662674
if (sKodiParam.length()) sMessage += "\"action\":\"" + sKodiParam + "\"";
663-
sMessage += "},\"id\":6}";
675+
sMessage += "},\"id\":1006}";
664676

665677
if (m_Socket != NULL)
666678
{
@@ -678,9 +690,39 @@ void CKodiNode::SendCommand(const std::string &command)
678690
}
679691
}
680692

693+
void CKodiNode::SendCommand(const std::string &command, const int iValue)
694+
{
695+
std::stringstream ssMessage;
696+
std::string sMessage;
697+
std::string sKodiCall;
698+
if (command == "setvolume")
699+
{
700+
sKodiCall = "Set Volume";
701+
ssMessage << "{\"jsonrpc\":\"2.0\",\"method\":\"Application.SetVolume\",\"params\":{\"volume\":" << iValue << "},\"id\":1009}";
702+
sMessage = ssMessage.str();
703+
}
704+
705+
if (sMessage.length())
706+
{
707+
if (m_Socket != NULL)
708+
{
709+
handleWrite(sMessage);
710+
_log.Log(LOG_NORM, "Kodi: (%s) Sent command: '%s'.", m_Name.c_str(), sKodiCall.c_str());
711+
}
712+
else
713+
{
714+
_log.Log(LOG_NORM, "Kodi: (%s) Command not sent, Kodi is not connected: '%s'.", m_Name.c_str(), sKodiCall.c_str());
715+
}
716+
}
717+
else
718+
{
719+
_log.Log(LOG_ERROR, "Kodi: (%s) Command: '%s'. Unknown command.", m_Name.c_str(), command.c_str());
720+
}
721+
}
722+
681723
bool CKodiNode::SendShutdown()
682724
{
683-
std::string sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"System.GetProperties\",\"params\":{\"properties\":[\"canhibernate\",\"cansuspend\",\"canshutdown\"]},\"id\":4}";
725+
std::string sMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"System.GetProperties\",\"params\":{\"properties\":[\"canhibernate\",\"cansuspend\",\"canshutdown\"]},\"id\":1004}";
684726
handleWrite(sMessage);
685727

686728
if (m_Stoppable) _log.Log(LOG_NORM, "Kodi: (%s) Shutdown requested and is supported.", m_Name.c_str());
@@ -806,9 +848,6 @@ void CKodi::Restart()
806848

807849
bool CKodi::WriteToHardware(const char *pdata, const unsigned char length)
808850
{
809-
// http://<ip_address>:8080/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22System.GetProperties%22,%22params%22:{%22properties%22:[%22canreboot%22,%22canhibernate%22,%22cansuspend%22,%22canshutdown%22]},%22id%22:1}
810-
// {"id":1,"jsonrpc":"2.0","result":{"canhibernate":false,"canreboot":false,"canshutdown":false,"cansuspend":false}}
811-
812851
tRBUF *pSen = (tRBUF*)pdata;
813852

814853
unsigned char packettype = pSen->ICMND.packettype;
@@ -823,6 +862,7 @@ bool CKodi::WriteToHardware(const char *pdata, const unsigned char length)
823862
{
824863
if ((*itt)->m_DevID == DevID)
825864
{
865+
int iParam = pSen->LIGHTING2.level;
826866
switch (pSen->LIGHTING2.cmnd)
827867
{
828868
case light2_sOff:
@@ -834,6 +874,14 @@ bool CKodi::WriteToHardware(const char *pdata, const unsigned char length)
834874
case gswitch_sPause:
835875
(*itt)->SendCommand("playpause");
836876
return true;
877+
case gswitch_sSetVolume:
878+
(*itt)->SendCommand("setvolume", iParam);
879+
return true;
880+
/*
881+
case gswitch_sPlayPlaylist:
882+
sParam = GetPlaylistByRefID(iParam);
883+
return SendCommand(itt->ID, "PlayPlaylist", sParam);
884+
*/
837885
default:
838886
return true;
839887
}

hardware/Kodi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class CKodiNode : public boost::enable_shared_from_this<CKodiNode>
7272
~CKodiNode(void);
7373
void Do_Work();
7474
void SendCommand(const std::string&);
75+
void SendCommand(const std::string&, const int iValue);
7576
bool SendShutdown();
7677
void StopRequest() { m_stoprequested = true; };
7778
bool IsBusy() { return m_Busy; };

0 commit comments

Comments
 (0)