27 m_retryTimer(new QTimer(this))
29 setObjectName(
"ZMClient");
46 QString zmserver_host;
52 if (zmserver_host.isEmpty() || zmserver_port == -1)
54 LOG(VB_GENERAL, LOG_INFO,
"ZMClient: no valid IP or port found for mythzmserver");
74 LOG(VB_GENERAL, LOG_INFO,
75 QString(
"Connecting to zm server: %1:%2 (try %3 of 2)")
106 "Have you set the correct IP and port in the settings?"));
125 QStringList origStrList = strList;
133 LOG(VB_GENERAL, LOG_NOTICE,
"Connection to mythzmserver lost");
137 LOG(VB_GENERAL, LOG_ERR,
"Re-connection to mythzmserver failed");
142 strList = origStrList;
154 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
159 if (strList[0] ==
"UNKNOWN_COMMAND")
161 LOG(VB_GENERAL, LOG_ERR,
"Somethings is getting passed to the server "
162 "that it doesn't understand");
167 if (strList[0].startsWith(
"ERROR"))
169 LOG(VB_GENERAL, LOG_ERR,
170 QString(
"The server failed to process the command. "
171 "The error was:- \n\t\t\t%1").arg(strList[0]));
176 return strList[0] ==
"OK";
183 QStringList strList(
"HELLO");
186 LOG(VB_GENERAL, LOG_ERR, QString(
"Server didn't respond to 'HELLO'!!"));
188 ShowOkPopup(tr(
"The mythzmserver didn't respond to our request "
189 "to get the protocol version!!"));
194 if (strList.size() < 2)
196 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
202 LOG(VB_GENERAL, LOG_ERR,
203 QString(
"Protocol version mismatch (plugin=%1, mythzmserver=%2)")
206 ShowOkPopup(QString(
"The mythzmserver uses protocol version %1, "
207 "but this client only understands version %2. "
208 "Make sure you are running compatible versions of "
209 "both the server and plugin.")
214 LOG(VB_GENERAL, LOG_INFO,
260 QStringList strList(
"GET_SERVER_STATUS");
265 if (strList.size() < 4)
267 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
272 cpuStat = strList[2];
273 diskStat = strList[3];
280 QStringList strList(
"GET_MONITOR_STATUS");
285 if (strList.size() < 2)
287 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
292 int monitorCount = strList[1].toInt(&bOK);
295 LOG(VB_GENERAL, LOG_ERR,
296 "ZMClient received bad int in getMonitorStatus()");
302 for (
int x = 0; x < monitorCount; x++)
304 int monID = strList[(x * 7) + 2].toInt();
309 mon->
name = strList[(x * 7) + 3];
312 mon->
events = strList[(x * 7) + 6].toInt();
313 mon->
function = strList[(x * 7) + 7];
314 mon->
enabled = (strList[(x * 7) + 8].toInt() != 0);
321 QString result =
"UNKNOWN";
351 QStringList strList(
"GET_ALARM_STATES");
356 if (strList.size() < 2)
358 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
363 int monitorCount = strList[1].toInt(&bOK);
366 LOG(VB_GENERAL, LOG_ERR,
367 "ZMClient received bad int in getAlarmStates()");
373 bool changed =
false;
374 for (
int x = 0; x < monitorCount; x++)
376 int monID = strList[(x * 2) + 2].toInt();
377 auto state = (
State)strList[(x * 2) + 3].toInt();
382 if (mon->
state != state)
385 LOG(VB_GENERAL, LOG_DEBUG,
386 QString(
"ZMClient monitor %1 changed state from %2 to %3")
399 const QString &date,
bool includeContinuous,
400 std::vector<Event*> *eventList)
406 QStringList strList(
"GET_EVENT_LIST");
407 strList << monitorName << (oldestFirst ?
"1" :
"0") ;
409 strList << (includeContinuous ?
"1" :
"0") ;
415 if (strList.size() < 2)
417 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
422 int eventCount = strList[1].toInt(&bOK);
425 LOG(VB_GENERAL, LOG_ERR,
"ZMClient received bad int in getEventList()");
430 if ((strList.size() - 2) / 6 != eventCount)
432 LOG(VB_GENERAL, LOG_ERR,
433 "ZMClient got a mismatch between the number of events and "
434 "the expected number of stringlist items in getEventList()");
438 QStringList::Iterator it = strList.begin();
440 for (
int x = 0; x < eventCount; x++)
442 eventList->push_back(
454 QStringList &dateList)
460 QStringList strList(
"GET_EVENT_DATES");
461 strList << monitorName << (oldestFirst ?
"1" :
"0") ;
467 if (strList.size() < 2)
469 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
474 int dateCount = strList[1].toInt(&bOK);
477 LOG(VB_GENERAL, LOG_ERR,
478 "ZMClient received bad int in getEventDates()");
483 if ((strList.size() - 3) != dateCount)
485 LOG(VB_GENERAL, LOG_ERR,
486 "ZMClient got a mismatch between the number of dates and "
487 "the expected number of stringlist items in getEventDates()");
491 QStringList::Iterator it = strList.begin();
493 for (
int x = 0; x < dateCount; x++)
495 dateList.append(*it++);
505 QStringList strList(
"GET_FRAME_LIST");
506 strList << QString::number(eventID);
511 if (strList.size() < 2)
513 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
518 int frameCount = strList[1].toInt(&bOK);
521 LOG(VB_GENERAL, LOG_ERR,
"ZMClient received bad int in getFrameList()");
526 if ((strList.size() - 2) / 2 != frameCount)
528 LOG(VB_GENERAL, LOG_ERR,
529 "ZMClient got a mismatch between the number of frames and "
530 "the expected number of stringlist items in getFrameList()");
534 QStringList::Iterator it = strList.begin();
536 for (
int x = 0; x < frameCount; x++)
538 auto *item =
new Frame;
540 item->delta = (*it++).toDouble();
541 frameList->push_back(item);
549 QStringList strList(
"DELETE_EVENT");
550 strList << QString::number(eventID);
559 QStringList strList(
"DELETE_EVENT_LIST");
561 std::vector<Event*>::iterator it;
562 for (it = eventList->begin(); it != eventList->end(); ++it)
564 strList << QString::number((*it)->eventID());
569 strList = QStringList(
"DELETE_EVENT_LIST");
578 strList = QStringList(
"RUN_ZMAUDIT");
585 std::chrono::milliseconds errmsgtime { 0ms };
603 LOG(VB_GENERAL, LOG_ERR,
"readData: Error, readBlock");
609 LOG(VB_GENERAL, LOG_ERR,
610 "readData: Error, socket went unconnected");
616 std::chrono::milliseconds elapsed = timer.
elapsed();
619 if ((elapsed - errmsgtime) > 10s)
621 errmsgtime = elapsed;
622 LOG(VB_GENERAL, LOG_ERR,
623 QString(
"m_socket->: Waiting for data: %1 %2")
624 .arg(
read).arg(dataSize));
630 LOG(VB_GENERAL, LOG_ERR,
"Error, readData timeout (readBlock)");
649 QStringList strList(
"GET_EVENT_FRAME");
650 strList << QString::number(event->
monitorID());
651 strList << QString::number(event->
eventID());
652 strList << QString::number(frameNo);
653 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
654 strList <<
event->startTime(Qt::LocalTime).toString(
"yy/MM/dd/hh/mm/ss");
656 static const QTimeZone localtime(QTimeZone::LocalTime);
657 strList <<
event->startTime(localtime).toString(
"yy/MM/dd/hh/mm/ss");
663 if (strList.size() < 2)
665 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
670 int imageSize = strList[1].toInt();
673 auto *data =
new unsigned char[imageSize];
676 LOG(VB_GENERAL, LOG_ERR,
677 "ZMClient::getEventFrame(): Failed to get image data");
686 if (!(*image)->loadFromData(data, imageSize,
"JPEG"))
688 LOG(VB_GENERAL, LOG_ERR,
689 "ZMClient::getEventFrame(): Failed to load image from data");
699 QStringList strList(
"GET_ANALYSE_FRAME");
700 strList << QString::number(event->
monitorID());
701 strList << QString::number(event->
eventID());
702 strList << QString::number(frameNo);
703 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
704 strList <<
event->startTime(Qt::LocalTime).toString(
"yy/MM/dd/hh/mm/ss");
706 static const QTimeZone localtime(QTimeZone::LocalTime);
707 strList <<
event->startTime(localtime).toString(
"yy/MM/dd/hh/mm/ss");
716 if (strList.size() < 2)
718 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
723 int imageSize = strList[1].toInt();
726 auto *data =
new unsigned char[imageSize];
729 LOG(VB_GENERAL, LOG_ERR,
730 "ZMClient::getAnalyseFrame(): Failed to get image data");
736 if (!image.loadFromData(data, imageSize,
"JPEG"))
738 LOG(VB_GENERAL, LOG_ERR,
739 "ZMClient::getAnalyseFrame(): Failed to load image from data");
751 QStringList strList(
"GET_LIVE_FRAME");
752 strList << QString::number(monitorID);
757 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
763 if (strList[0].startsWith(
"WARNING"))
772 if (strList.size() < 4)
774 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
782 size_t imageSize = strList[3].toInt();
784 if (buffer.size() < imageSize)
786 LOG(VB_GENERAL, LOG_ERR,
787 "ZMClient::getLiveFrame(): Live frame buffer is too small!");
795 if (!
readData(buffer.data(), imageSize))
797 LOG(VB_GENERAL, LOG_ERR,
798 "ZMClient::getLiveFrame(): Failed to get image data");
811 QStringList strList(
"GET_CAMERA_LIST");
816 if (strList.size() < 2)
818 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
823 int cameraCount = strList[1].toInt(&bOK);
826 LOG(VB_GENERAL, LOG_ERR,
827 "ZMClient received bad int in getCameraList()");
832 if (strList.size() < cameraCount + 2)
834 LOG(VB_GENERAL, LOG_ERR, QString(
835 "ZMClient got a mismatch between the number of cameras (%1) and "
836 "the expected number of stringlist items (%2) in getCameraList()")
837 .arg(cameraCount).arg(strList.size()));
841 for (
int x = 0; x < cameraCount; x++)
843 cameraList.append(strList[x + 2]);
884 QStringList strList(
"GET_MONITOR_LIST");
889 if (strList.size() < 2)
891 LOG(VB_GENERAL, LOG_ERR,
"ZMClient response too short");
896 int monitorCount = strList[1].toInt(&bOK);
899 LOG(VB_GENERAL, LOG_ERR,
900 "ZMClient received bad int in getMonitorList()");
905 if ((strList.size() - 2) / 5 != monitorCount)
907 LOG(VB_GENERAL, LOG_ERR,
908 "ZMClient got a mismatch between the number of monitors and "
909 "the expected number of stringlist items in getMonitorList()");
915 QStringList notificationMonitors = s.split(
",");
917 for (
int x = 0; x < monitorCount; x++)
920 item->
id = strList[(x * 5) + 2].toInt();
921 item->name = strList[(x * 5) + 3];
922 item->width = strList[(x * 5) + 4].toInt();
923 item->height = strList[(x * 5) + 5].toInt();
924 item->bytes_per_pixel = strList[(x * 5) + 6].toInt();
925 item->zmcStatus =
"";
926 item->zmaStatus =
"";
929 item->showNotifications = notificationMonitors.contains(QString::number(item->id));
934 LOG(VB_GENERAL, LOG_NOTICE,
935 QString(
"Monitor: %1 (%2) is using %3 bytes per pixel")
936 .arg(item->name).arg(item->id).arg(item->bytes_per_pixel));
944 QStringList strList(
"SET_MONITOR_FUNCTION");
945 strList << QString::number(monitorID);
947 strList << QString::number(static_cast<int>(enabled));
963 s += QString(
",%1").arg(mon->
id);
965 s = QString(
"%1").arg(mon->
id);
976 auto *me =
dynamic_cast<MythEvent*
>(event);
980 if (me->Message().startsWith(
"ZONEMINDER_NOTIFICATION"))
982 QStringList list = me->
Message().simplified().split(
' ');
987 int monID = list[1].toInt();
992 QObject::customEvent(event);
1004 miniPlayer->setAlarmMonitor(monitorID);
1006 if (miniPlayer->Create())