2023-04-18 14:14:46 +08:00
# include "ctrlhdmipanel.h"
# include "gutil/qgui.h"
2023-05-15 16:06:10 +08:00
# include "gutil/qnetwork.h"
2023-04-18 14:14:46 +08:00
# include "tools.h"
# include "globaldefine.h"
2023-10-23 15:08:45 +08:00
# include "gutil/qwaitingdlg.h"
2023-04-18 14:14:46 +08:00
# include <QMessageBox>
# include <QButtonGroup>
# include <QTimeEdit>
# include <QJsonArray>
2023-05-15 16:06:10 +08:00
# include <QSettings>
# include "devicepanel.h"
2023-04-18 14:14:46 +08:00
2023-05-15 16:06:10 +08:00
CtrlHdmiPanel : : CtrlHdmiPanel ( ) {
2023-04-18 14:14:46 +08:00
auto vBox = new QVBoxLayout ( this ) ;
2023-10-23 15:08:45 +08:00
vBox - > setContentsMargins ( 6 , 6 , 6 , 0 ) ;
2023-04-18 14:14:46 +08:00
lbHdmiCfg = new QLabel ;
2023-10-23 15:08:45 +08:00
auto ft = lbHdmiCfg - > font ( ) ;
ft . setPixelSize ( 16 ) ;
ft . setBold ( true ) ;
lbHdmiCfg - > setFont ( ft ) ;
2023-04-18 14:14:46 +08:00
lbHdmiCfg - > setAlignment ( Qt : : AlignCenter ) ;
vBox - > addWidget ( lbHdmiCfg ) ;
2023-10-23 15:08:45 +08:00
vBox - > addSpacing ( 9 ) ;
2023-04-18 14:14:46 +08:00
2023-10-23 15:08:45 +08:00
auto hBox = new HBox ( vBox ) ;
2023-04-18 14:14:46 +08:00
hBox - > addStretch ( ) ;
fdManual = new QRadioButton ;
hBox - > addWidget ( fdManual ) ;
hBox - > addSpacing ( 40 ) ;
fdSchedule = new QRadioButton ;
hBox - > addWidget ( fdSchedule ) ;
hBox - > addStretch ( ) ;
2023-05-15 16:06:10 +08:00
auto stacked = new QStackedLayout ( vBox ) ;
2023-04-18 14:14:46 +08:00
{
auto vBox = new VBox ( stacked ) ;
vBox - > addSpacing ( 20 ) ;
auto hBox = new HBox ( vBox ) ;
hBox - > addStretch ( ) ;
fdAsync = new QRadioButton ;
hBox - > addWidget ( fdAsync ) ;
hBox - > addSpacing ( 20 ) ;
fdHdmi = new QRadioButton ( " HDMI " ) ;
hBox - > addWidget ( fdHdmi ) ;
hBox - > addSpacing ( 20 ) ;
fdHdmi2 = new QRadioButton ( " HDMI 2 " ) ;
hBox - > addWidget ( fdHdmi2 ) ;
hBox - > addStretch ( ) ;
auto btnGroup = new QButtonGroup ( this ) ;
btnGroup - > addButton ( fdAsync , 0 ) ;
btnGroup - > addButton ( fdHdmi , 1 ) ;
btnGroup - > addButton ( fdHdmi2 , 2 ) ;
2023-04-27 15:06:24 +08:00
vBox - > addSpacing ( 20 ) ;
hBox = new HBox ( vBox ) ;
hBox - > addStretch ( ) ;
btnSyncSet = new QPushButton ;
btnSyncSet - > setMinimumSize ( 60 , 30 ) ;
btnSyncSet - > setProperty ( " ssType " , " progManageTool " ) ;
connect ( btnSyncSet , & QPushButton : : clicked , this , [ = ] {
2023-05-15 16:06:10 +08:00
if ( gSelCards . isEmpty ( ) ) {
2023-05-11 11:47:00 +08:00
QMessageBox : : information ( this , tr ( " Tip " ) , tr ( " NoSelectedController " ) ) ;
2023-04-18 14:14:46 +08:00
return ;
}
2023-04-27 15:06:24 +08:00
auto id = btnGroup - > checkedId ( ) ;
2023-04-18 14:14:46 +08:00
QJsonObject json ;
json . insert ( " _id " , " SyncSwitch " ) ;
json . insert ( " _type " , " SyncSwitch " ) ;
json . insert ( " switchOn " , ( bool ) id ) ;
if ( id ) json . insert ( " number " , id ) ;
2023-05-15 16:06:10 +08:00
if ( gSelCards . count ( ) = = 1 ) {
2023-04-27 15:06:24 +08:00
auto waitingDlg = new WaitingDlg ( this , id ? tr ( " SyncSwitch " ) : tr ( " AnSyncSwitch " ) ) ;
2023-04-18 14:14:46 +08:00
Def_CtrlReqPre
2023-05-11 11:47:00 +08:00
connect ( reply , & QNetworkReply : : finished , this , [ = ] {
2023-04-18 14:14:46 +08:00
Def_CtrlSetReqAfter
} ) ;
} else {
2023-05-15 16:06:10 +08:00
foreach ( auto card , gSelCards ) {
2023-04-27 15:06:24 +08:00
if ( id ) {
2023-04-18 14:14:46 +08:00
Def_CtrlSetMulti ( tr ( " SyncSwitch " ) )
} else {
Def_CtrlSetMulti ( tr ( " AnSyncSwitch " ) )
}
}
}
} ) ;
2023-04-27 15:06:24 +08:00
hBox - > addWidget ( btnSyncSet ) ;
hBox - > addSpacing ( 20 ) ;
2023-04-18 14:14:46 +08:00
2023-04-27 15:06:24 +08:00
btnSyncGet = new QPushButton ;
btnSyncGet - > setMinimumSize ( 60 , 30 ) ;
btnSyncGet - > setProperty ( " ssType " , " progManageTool " ) ;
connect ( btnSyncGet , & QPushButton : : clicked , this , [ this ] {
2023-05-15 16:06:10 +08:00
if ( gSelCards . isEmpty ( ) ) {
2023-05-11 11:47:00 +08:00
QMessageBox : : information ( this , tr ( " Tip " ) , tr ( " NoSelectedController " ) ) ;
2023-04-18 14:14:46 +08:00
return ;
}
QJsonObject json ;
json . insert ( " _id " , " IsSync " ) ;
json . insert ( " _type " , " IsSync " ) ;
2023-05-15 16:06:10 +08:00
if ( gSelCards . count ( ) = = 1 ) {
2023-04-18 14:14:46 +08:00
auto waitingDlg = new WaitingDlg ( this , tr ( " IsSync " ) ) ;
Def_CtrlReqPre
connect ( reply , & QNetworkReply : : finished , this , [ this , reply , waitingDlg ] {
Def_CtrlSingleGetReply
waitingDlg - > success ( ) ;
auto switchOn = json [ " switchOn " ] ;
if ( switchOn . isUndefined ( ) ) switchOn = json [ " result " ] ;
if ( ! switchOn . toBool ( ) ) fdAsync - > setChecked ( true ) ;
else if ( json [ " number " ] . toInt ( ) = = 2 ) fdHdmi2 - > setChecked ( true ) ;
else fdHdmi - > setChecked ( true ) ;
} ) ;
} else {
2023-05-15 16:06:10 +08:00
foreach ( auto card , gSelCards ) {
auto reply = NetReq ( " http:// " + card . ip + " :2016/settings " ) . timeout ( 120000 ) . post ( json ) ;
auto cardId = card . id ;
2023-04-18 14:14:46 +08:00
connect ( reply , & QNetworkReply : : finished , this , [ reply , cardId ] {
QJsonDocument json ;
QString err = checkReplyForJson ( reply , & json ) ;
if ( err . isEmpty ( ) ) {
auto switchOn = json [ " switchOn " ] ;
if ( switchOn . isUndefined ( ) ) switchOn = json [ " result " ] ;
if ( ! switchOn . toBool ( ) ) err = tr ( " Async " ) ;
else {
err = " HDMI " ;
auto number = json [ " number " ] . toInt ( ) ;
if ( number ) err + = " " + QString : : number ( number ) ;
}
}
gFdResInfo - > append ( cardId + " " + err ) ;
} ) ;
}
}
} ) ;
2023-04-27 15:06:24 +08:00
hBox - > addWidget ( btnSyncGet ) ;
2023-04-18 14:14:46 +08:00
hBox - > addStretch ( ) ;
vBox - > addStretch ( ) ;
}
{
auto vBox = new VBox ( stacked ) ;
auto hBox = new HBox ( vBox ) ;
hBox - > setSpacing ( 10 ) ;
2023-10-23 15:08:45 +08:00
tableSche = new TableWidget {
2023-04-18 14:14:46 +08:00
{ " start " , " " , 100 } ,
{ " end " , " " , 100 } ,
{ " 0 " , " " , 60 } ,
{ " 1 " , " " , 60 } ,
{ " 2 " , " " , 60 } ,
{ " 3 " , " " , 60 } ,
{ " 4 " , " " , 60 } ,
{ " 5 " , " " , 60 } ,
{ " 6 " , " " , 60 }
2023-10-23 15:08:45 +08:00
} ;
2023-04-18 14:14:46 +08:00
tableSche - > setDefs ( ) ;
btnScheAdd = new QPushButton ;
btnScheAdd - > setMinimumSize ( QSize ( 60 , 30 ) ) ;
btnScheAdd - > setProperty ( " ssType " , " progManageTool " ) ;
connect ( btnScheAdd , & QPushButton : : clicked , this , [ this ] {
int row = tableSche - > appendRow ( ) ;
auto timeEdit = new QTimeEdit ( QTime ( 0 , 0 ) ) ;
timeEdit - > setDisplayFormat ( " HH:mm " ) ;
timeEdit - > setAlignment ( Qt : : AlignCenter ) ;
tableSche - > setCellWidget ( row , " start " , timeEdit ) ;
timeEdit = new QTimeEdit ( QTime ( 1 , 0 ) ) ;
timeEdit - > setDisplayFormat ( " HH:mm " ) ;
timeEdit - > setAlignment ( Qt : : AlignCenter ) ;
tableSche - > setCellWidget ( row , " end " , timeEdit ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
auto fd = new QCheckBox ;
fd - > setChecked ( true ) ;
tableSche - > setCellWidget ( row , QString : : number ( i ) , fd ) ;
}
} ) ;
hBox - > addWidget ( btnScheAdd ) ;
btnScheDel = new QPushButton ;
btnScheDel - > setMinimumSize ( QSize ( 60 , 30 ) ) ;
btnScheDel - > setProperty ( " ssType " , " progManageTool " ) ;
connect ( btnScheDel , & QPushButton : : clicked , this , [ this ] {
auto selected = tableSche - > selectedRanges ( ) ;
if ( ! selected . isEmpty ( ) ) tableSche - > model ( ) - > removeRows ( selected [ 0 ] . topRow ( ) , selected [ 0 ] . rowCount ( ) ) ;
} ) ;
hBox - > addWidget ( btnScheDel ) ;
btnScheClear = new QPushButton ;
btnScheClear - > setMinimumSize ( QSize ( 60 , 30 ) ) ;
btnScheClear - > setProperty ( " ssType " , " progManageTool " ) ;
2023-10-23 15:08:45 +08:00
connect ( btnScheClear , & QPushButton : : clicked , tableSche , & TableWidget : : clearRows ) ;
2023-04-18 14:14:46 +08:00
hBox - > addWidget ( btnScheClear ) ;
hBox - > addStretch ( ) ;
btnScheImport = new QPushButton ;
btnScheImport - > setMinimumSize ( QSize ( 0 , 30 ) ) ;
btnScheImport - > setProperty ( " ssType " , " progManageTool " ) ;
connect ( btnScheImport , & QPushButton : : clicked , this , [ this ] {
auto dir = QSettings ( ) . value ( " CtrlScheduleDir " ) . toString ( ) ;
if ( dir . isEmpty ( ) ) dir = " / " ;
QString scheFile = QFileDialog : : getOpenFileName ( this , tr ( " Import File " ) , dir , tr ( " Sync Schedule " ) + " (*.syncs) " ) ;
if ( scheFile . isEmpty ( ) ) return ;
QFile scheQFile ( scheFile ) ;
if ( ! scheQFile . open ( QIODevice : : ReadOnly ) ) return ;
auto data = scheQFile . readAll ( ) ;
scheQFile . close ( ) ;
restoreScheduleJson ( QJsonDocument : : fromJson ( data ) . object ( ) ) ;
} ) ;
hBox - > addWidget ( btnScheImport ) ;
btnScheExport = new QPushButton ;
btnScheExport - > setMinimumSize ( QSize ( 0 , 30 ) ) ;
btnScheExport - > setProperty ( " ssType " , " progManageTool " ) ;
connect ( btnScheExport , & QPushButton : : clicked , this , [ this ] {
QSettings settings ;
auto dir = settings . value ( " CtrlScheduleDir " ) . toString ( ) ;
if ( dir . isEmpty ( ) ) dir = " / " ;
QString scheFile = QFileDialog : : getSaveFileName ( this , tr ( " Save File " ) , dir , tr ( " Sync Schedule " ) + " (*.syncs) " ) ;
if ( scheFile . isEmpty ( ) ) return ;
settings . setValue ( " CtrlScheduleDir " , QFileInfo ( scheFile ) . absolutePath ( ) ) ;
QFile scheQFile ( scheFile ) ;
if ( ! scheQFile . open ( QIODevice : : WriteOnly ) ) return ;
scheQFile . write ( QJsonDocument ( getScheduleJson ( ) ) . toJson ( ) ) ;
scheQFile . close ( ) ;
} ) ;
hBox - > addWidget ( btnScheExport ) ;
labelSyncScheduleTip = new QLabel ;
labelSyncScheduleTip - > setWordWrap ( true ) ;
vBox - > addWidget ( labelSyncScheduleTip ) ;
vBox - > addWidget ( tableSche ) ;
hBox = new HBox ( vBox ) ;
hBox - > addStretch ( ) ;
btnScheSet = new QPushButton ;
btnScheSet - > setProperty ( " ssType " , " progManageTool " ) ;
btnScheSet - > setMinimumSize ( QSize ( 60 , 30 ) ) ;
connect ( btnScheSet , & QPushButton : : clicked , this , [ this ] {
2023-05-15 16:06:10 +08:00
if ( gSelCards . isEmpty ( ) ) {
2023-05-11 11:47:00 +08:00
QMessageBox : : information ( this , tr ( " Tip " ) , tr ( " NoSelectedController " ) ) ;
2023-04-18 14:14:46 +08:00
return ;
}
QJsonObject json ;
json . insert ( " _id " , " SetTimingHdmiInTask " ) ;
json . insert ( " _type " , " SetTimingHdmiInTask " ) ;
2023-05-15 16:06:10 +08:00
if ( gSelCards . count ( ) = = 1 ) {
2023-04-18 14:14:46 +08:00
json . insert ( " HdmiInTask " , getScheduleJson ( ) ) ;
auto waitingDlg = new WaitingDlg ( this , tr ( " SetTimingHdmiInTask " ) ) ;
Def_CtrlReqPre ;
2023-05-11 11:47:00 +08:00
connect ( reply , & QNetworkReply : : finished , this , [ = ] {
2023-04-18 14:14:46 +08:00
Def_CtrlSetReqAfter
} ) ;
} else {
2023-05-15 16:06:10 +08:00
foreach ( auto card , gSelCards ) {
2023-04-18 14:14:46 +08:00
json . insert ( " HdmiInTask " , getScheduleJson ( ) ) ;
Def_CtrlSetMulti ( tr ( " SetTimingHdmiInTask " ) )
}
}
} ) ;
hBox - > addWidget ( btnScheSet ) ;
hBox - > addStretch ( ) ;
btnScheGet = new QPushButton ;
btnScheGet - > setMinimumSize ( QSize ( 0 , 30 ) ) ;
btnScheGet - > setProperty ( " ssType " , " progManageTool " ) ;
connect ( btnScheGet , & QPushButton : : clicked , this , [ this ] {
2023-05-15 16:06:10 +08:00
if ( gSelCards . isEmpty ( ) ) {
2023-05-11 11:47:00 +08:00
QMessageBox : : information ( this , tr ( " Tip " ) , tr ( " NoSelectedController " ) ) ;
2023-04-18 14:14:46 +08:00
return ;
}
QJsonObject json ;
json . insert ( " _id " , " GetTimingHdmiInTask " ) ;
json . insert ( " _type " , " GetTimingHdmiInTask " ) ;
2023-05-15 16:06:10 +08:00
if ( gSelCards . count ( ) = = 1 ) {
2023-04-18 14:14:46 +08:00
auto waitingDlg = new WaitingDlg ( this , tr ( " GetTimingHdmiInTask " ) ) ;
Def_CtrlReqPre
connect ( reply , & QNetworkReply : : finished , this , [ this , reply , waitingDlg ] {
Def_CtrlSingleGetReply
waitingDlg - > success ( ) ;
restoreScheduleJson ( json [ " creenTask " ] . toObject ( ) ) ;
} ) ;
}
} ) ;
hBox - > addWidget ( btnScheGet ) ;
hBox - > addStretch ( ) ;
}
2023-05-15 16:06:10 +08:00
connect ( fdSchedule , & QRadioButton : : toggled , stacked , & QStackedLayout : : setCurrentIndex ) ;
2023-04-18 14:14:46 +08:00
fdManual - > setChecked ( true ) ;
connect ( gDevicePanel , & DevicePanel : : sigSelectedDeviceList , this , [ this ] {
if ( isVisible ( ) ) init ( ) ;
} ) ;
transUi ( ) ;
}
void CtrlHdmiPanel : : showEvent ( QShowEvent * event ) {
QWidget : : showEvent ( event ) ;
init ( ) ;
}
void CtrlHdmiPanel : : init ( ) {
2023-05-15 16:06:10 +08:00
bool isSingle = gSelCards . count ( ) = = 1 ;
2023-04-18 14:14:46 +08:00
btnScheGet - > setEnabled ( isSingle ) ;
if ( ! isSingle ) {
fdHdmi2 - > setVisible ( true ) ;
return ;
}
2023-05-15 16:06:10 +08:00
auto card = gSelCards [ 0 ] ;
fdHdmi2 - > setVisible ( card . id . startsWith ( " m8s " , Qt : : CaseInsensitive ) ) ;
2023-04-18 14:14:46 +08:00
QJsonObject json ;
json . insert ( " _id " , " IsSync " ) ;
json . insert ( " _type " , " IsSync " ) ;
2023-05-15 16:06:10 +08:00
auto reply = NetReq ( " http:// " + card . ip + " :2016/settings " ) . timeout ( 120000 ) . post ( json ) ;
2023-04-18 14:14:46 +08:00
connect ( reply , & QNetworkReply : : finished , this , [ this , reply ] {
QJsonDocument json ;
QString err = checkReplyForJson ( reply , & json ) ;
if ( ! err . isEmpty ( ) ) return ;
auto switchOn = json [ " switchOn " ] ;
if ( switchOn . isUndefined ( ) ) switchOn = json [ " result " ] ;
if ( ! switchOn . toBool ( ) ) fdAsync - > setChecked ( true ) ;
else if ( json [ " number " ] . toInt ( ) = = 2 ) fdHdmi2 - > setChecked ( true ) ;
else fdHdmi - > setChecked ( true ) ;
} ) ;
}
void CtrlHdmiPanel : : changeEvent ( QEvent * event ) {
QWidget : : changeEvent ( event ) ;
if ( event - > type ( ) = = QEvent : : LanguageChange ) transUi ( ) ;
}
void CtrlHdmiPanel : : transUi ( ) {
lbHdmiCfg - > setText ( tr ( " HDMI Configuration " ) ) ;
fdManual - > setText ( tr ( " Manual " ) ) ;
fdSchedule - > setText ( tr ( " Schedule " ) ) ;
fdAsync - > setText ( tr ( " Async " ) ) ;
2023-04-27 15:06:24 +08:00
btnSyncSet - > setText ( tr ( " Set " ) ) ;
btnSyncGet - > setText ( tr ( " Readback " ) ) ;
2023-04-18 14:14:46 +08:00
tableSche - > setHeaderText ( " start " , tr ( " Start Time " ) ) ;
tableSche - > setHeaderText ( " end " , tr ( " End Time " ) ) ;
tableSche - > setHeaderText ( " 0 " , tr ( " SUN " ) ) ;
tableSche - > setHeaderText ( " 1 " , tr ( " MON " ) ) ;
tableSche - > setHeaderText ( " 2 " , tr ( " TUE " ) ) ;
tableSche - > setHeaderText ( " 3 " , tr ( " WED " ) ) ;
tableSche - > setHeaderText ( " 4 " , tr ( " THU " ) ) ;
tableSche - > setHeaderText ( " 5 " , tr ( " FRI " ) ) ;
tableSche - > setHeaderText ( " 6 " , tr ( " SAT " ) ) ;
btnScheAdd - > setText ( tr ( " Add " ) ) ;
btnScheSet - > setText ( tr ( " Apply " ) ) ;
btnScheClear - > setText ( tr ( " Clear " ) ) ;
btnScheDel - > setText ( tr ( " Delete " ) ) ;
btnScheImport - > setText ( tr ( " Import " ) ) ;
btnScheExport - > setText ( tr ( " Export " ) ) ;
labelSyncScheduleTip - > setText ( tr ( " By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period " ) ) ;
btnScheSet - > setText ( tr ( " Apply " ) ) ;
btnScheGet - > setText ( tr ( " Readback " ) ) ;
}
void CtrlHdmiPanel : : restoreScheduleJson ( QJsonObject oTaskSync ) {
tableSche - > setRowCount ( 0 ) ;
auto oSchedules = oTaskSync [ " schedules " ] . toArray ( ) ;
2023-04-19 14:42:06 +08:00
foreach ( QJsonValue oSchedule , oSchedules ) {
2023-04-18 14:14:46 +08:00
int row = tableSche - > rowCount ( ) ;
tableSche - > insertRow ( row ) ;
auto timeEdit = new QTimeEdit ( QTime : : fromString ( oSchedule [ " startTime " ] . toString ( ) + " :00 " ) ) ;
timeEdit - > setDisplayFormat ( " HH:mm " ) ;
timeEdit - > setAlignment ( Qt : : AlignCenter ) ;
tableSche - > setCellWidget ( row , " start " , timeEdit ) ;
timeEdit = new QTimeEdit ( QTime : : fromString ( oSchedule [ " endTime " ] . toString ( ) + " :00 " ) ) ;
timeEdit - > setDisplayFormat ( " HH:mm " ) ;
timeEdit - > setAlignment ( Qt : : AlignCenter ) ;
tableSche - > setCellWidget ( row , " end " , timeEdit ) ;
if ( oSchedule [ " filterType " ] . toString ( ) = = " None " ) for ( int i = 0 ; i < 7 ; i + + ) {
auto fd = new QCheckBox ;
fd - > setChecked ( true ) ;
tableSche - > setCellWidget ( row , QString : : number ( i ) , fd ) ;
} else if ( oSchedule [ " filterType " ] . toString ( ) = = " Week " ) {
auto weekFilter = oSchedule [ " weekFilter " ] . toArray ( ) ;
for ( int i = 0 ; i < 7 ; i + + ) {
auto fd = new QCheckBox ;
if ( weekFilter . contains ( i ) ) fd - > setChecked ( true ) ;
tableSche - > setCellWidget ( row , QString : : number ( i ) , fd ) ;
}
}
}
}
QJsonObject CtrlHdmiPanel : : getScheduleJson ( ) {
QJsonArray schedules ;
for ( int i = 0 ; i < tableSche - > rowCount ( ) ; i + + ) {
QJsonObject schedule ;
schedule [ " timeType " ] = " Range " ;
schedule [ " startTime " ] = static_cast < QTimeEdit * > ( tableSche - > cellWidget ( i , " start " ) ) - > text ( ) ;
schedule [ " endTime " ] = static_cast < QTimeEdit * > ( tableSche - > cellWidget ( i , " end " ) ) - > text ( ) ;
schedule [ " dateType " ] = " All " ;
schedule [ " monthFilter " ] = QJsonArray ( ) ;
QJsonArray weekFilter ;
for ( int d = 0 ; d < 7 ; d + + ) if ( static_cast < QCheckBox * > ( tableSche - > cellWidget ( i , QString : : number ( d ) ) ) - > isChecked ( ) ) weekFilter . append ( d ) ;
if ( weekFilter . size ( ) > = 7 ) {
schedule [ " filterType " ] = " None " ;
weekFilter = QJsonArray ( ) ;
} else schedule [ " filterType " ] = " Week " ;
schedule [ " weekFilter " ] = weekFilter ;
schedules . append ( schedule ) ;
}
return QJsonObject {
{ " createBy " , " alahover " } ,
2023-05-15 16:06:10 +08:00
{ " name " , " TimingHdmi " } ,
2023-04-18 14:14:46 +08:00
{ " schedules " , schedules }
} ;
}