• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mcallegari / qlcplus / 13633248611

03 Mar 2025 02:31PM UTC coverage: 31.871% (+0.4%) from 31.5%
13633248611

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/plugins/interfaces/rdmprotocol.cpp
1
/*
2
  Q Light Controller Plus
3
  rdmprotocol.cpp
4

5
  Copyright (c) Massimo Callegari
6

7
  Licensed under the Apache License Version 2.0 (the "License");
8
  you may not use this file except in compliance with the License.
9
  You may obtain a copy of the License at
10

11
      http://www.apache.org/licenses/LICENSE-2.0.txt
12

13
  Unless required by applicable law or agreed to in writing software
14
  distributed under the License is distributed on an "AS IS" BASIS
15
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
16
  See the License for the specific language governing permissions and
17
  limitations under the License.
18
*/
19

20
#include <QDebug>
21

22
#include "rdmprotocol.h"
23

24
RDMProtocol::RDMProtocol()
×
25
    : m_estaID(QLCPLUS_ESTA_ID)
×
26
    , m_deviceID(QLCPLUS_DEVICE_ID)
×
27
    , m_transactionNum(0x01)
×
28
{
29
}
×
30

31
void RDMProtocol::setEstaID(quint16 id)
×
32
{
33
    m_estaID = id;
×
34
}
×
35

36
void RDMProtocol::setDeviceId(quint32 id)
×
37
{
38
    m_deviceID = id;
×
39
}
×
40

41
bool RDMProtocol::packetizeCommand(ushort command, QVariantList params, bool startCode, QByteArray &buffer)
×
42
{
43
    buffer.clear();
×
44

45
    if (startCode)
×
46
        buffer.append(char(RDM_START_CODE));
×
47

48
    buffer.append(char(RDM_SC_SUB_MESSAGE));
×
49

50
    // temporary length. Fixed at the end
51
    buffer.append(char(0x00));
×
52

53
    if (params.length() == 0)
×
54
        return false;
55

56
    // destination UID
57
    buffer.append(QByteArray::fromHex(params.at(0).toString().toUtf8()));
×
58

59
    // source UID
60
    buffer.append(UIDToByteArray(m_estaID, m_deviceID));
×
61

62
    // transaction number
63
    buffer.append(char(m_transactionNum));
×
64

65
    // Port ID
66
    buffer.append(char(0x01));
×
67

68
    // message count
69
    buffer.append(char(0x00));
×
70

71
    // SUB device
72
    buffer.append(char(0x00));
×
73
    buffer.append(char(0x00));
×
74

75
    // Command
76
    buffer.append(char(command));
×
77

78
    switch (command)
×
79
    {
80
        case DISCOVERY_COMMAND:
81
        {
82
            if (params.length() < 2)
×
83
                return false;
84

85
            quint16 pid = params.at(1).toUInt();
×
86
            buffer.append(shortToByteArray(pid));
×
87

88
            // check if this is a mute/unmute command
89
            if (pid == PID_DISC_MUTE || pid == PID_DISC_UN_MUTE)
×
90
            {
91
                buffer.append(char(0x00)); // no payload
×
92
            }
93
            else
94
            {
95
                buffer.append(char(0x0C)); // PDL
×
96
                qulonglong start = params.at(2).toULongLong();
×
97
                qulonglong end = params.at(3).toULongLong();
×
98

99
                buffer.append(UIDToByteArray(start >> 32, start & 0x00000000FFFFFFFF)); // Lower bound UID
×
100
                buffer.append(UIDToByteArray(end >> 32, end & 0x00000000FFFFFFFF)); // Upper bound UID
×
101
            }
102
        }
103
        break;
104
        case GET_COMMAND:
105
        {
106
            if (params.length() < 2)
×
107
                return false;
108

109
            quint16 pid = params.at(1).toUInt();
×
110
            buffer.append(shortToByteArray(pid));
×
111

112
            if (params.length() > 3)
×
113
            {
114
                uchar size = params.at(2).toUInt();
×
115
                buffer.append(size); // add PDL
×
116
                switch (size)
117
                {
118
                case 1:
119
                    buffer.append(uchar(params.at(3).toUInt()));
×
120
                    break;
×
121
                case 2:
122
                    buffer.append(shortToByteArray(params.at(3).toUInt()));
×
123
                    break;
×
124
                case 4:
125
                    buffer.append(longToByteArray(params.at(3).toUInt()));
×
126
                    break;
×
127
                default:
128
                    break;
129
                }
130
            }
131
            else
132
            {
133
                buffer.append(char(0));
×
134
            }
135
        }
136
        break;
137
        case SET_COMMAND:
138
        {
139
            if (params.length() < 2)
×
140
                return false;
141

142
            quint16 pid = params.at(1).toUInt();
×
143
            buffer.append(shortToByteArray(pid));
×
144
            int pdlPosition = buffer.length();
145

146
            // Temporarily add a zero PDL.
147
            // Will be fixed after parameters append
148
            buffer.append(char(0));
×
149

150
            for (int i = 0; i < params.length(); i += 2)
×
151
            {
152
                int size = params.at(i).toInt();
×
153

154
                // special case for byte arrays
155
                if (size == 99)
×
156
                {
157
                    QByteArray ba = params.at(i + 1).toByteArray();
×
158
                    buffer.append(ba);
×
159
                    break;
160
                }
×
161

162
                switch (size)
163
                {
164
                    case 1:
×
165
                        buffer.append(uchar(params.at(i + 1).toUInt()));
×
166
                    break;
×
167
                    case 2:
×
168
                        buffer.append(shortToByteArray(params.at(i + 1).toUInt()));
×
169
                    break;
×
170
                    case 4:
×
171
                        buffer.append(longToByteArray(params.at(i + 1).toUInt()));
×
172
                    break;
×
173
                    default:
174
                    break;
175
                }
176
            }
177

178
            int pdl = buffer.length() - pdlPosition - 1;
×
179
            buffer[pdlPosition] = pdl;
×
180
        }
181
        break;
×
182
        default:
183
        break;
184
    }
185

186
    // set the correct length
187
    buffer[startCode ? 2 : 1] = buffer.length() + (startCode ? 0 : 1);
×
188

189
    // append checksum
190
    buffer.append(shortToByteArray(calculateChecksum(startCode, buffer, buffer.length())));
×
191

192
    m_transactionNum++;
×
193

194
    return true;
×
195
}
196

197
bool RDMProtocol::parseDiscoveryReply(const QByteArray &buffer, QVariantMap &values)
×
198
{
199
    if (buffer.length() < 24)
×
200
        return false;
201

202
    int i = 0;
203

204
    // check preamble
205
    if (buffer.at(i) != char(0xFE) ||
×
206
        buffer.at(i + 1) != char(0xFE) ||
×
207
        buffer.at(i + 2) != char(0xFE) ||
×
208
        buffer.at(i + 3) != char(0xFE) ||
×
209
        buffer.at(i + 4) != char(0xFE) ||
×
210
        buffer.at(i + 5) != char(0xFE) ||
×
211
        buffer.at(i + 6) != char(0xFE))
212
            return false;
213

214
    i += 7;
215
    // check separator
216
    if (buffer.at(i++) != char(0xAA))
×
217
        return false;
218

219
    quint8 mMSB = quint8(buffer.at(i)) & quint8(buffer.at(i + 1));
220
    quint8 mLSB = quint8(buffer.at(i + 2)) & quint8(buffer.at(i + 3));
221
    i += 4;
222

223
    quint8 dMSB3 = quint8(buffer.at(i)) & quint8(buffer.at(i + 1));
224
    quint8 dMSB2 = quint8(buffer.at(i + 2)) & quint8(buffer.at(i + 3));
225
    quint8 dMSB1 = quint8(buffer.at(i + 4)) & quint8(buffer.at(i + 5));
226
    quint8 dLSB  = quint8(buffer.at(i + 6)) & quint8(buffer.at(i + 7));
227
    i += 8;
228

229
    quint16 ESTAId;
230
    quint32 deviceId;
231
    QByteArray ba;
232
    ba.append(mMSB);
×
233
    ba.append(mLSB);
×
234
    ba.append(dMSB3);
×
235
    ba.append(dMSB2);
×
236
    ba.append(dMSB1);
×
237
    ba.append(dLSB);
×
238

239
    QString UID = byteArrayToUID(ba, ESTAId, deviceId);
×
240

241
    // calculate checksum
242
    quint8 cMSB = quint8(buffer.at(i)) & quint8(buffer.at(i + 1));
×
243
    quint8 cLSB = quint8(buffer.at(i + 2)) & quint8(buffer.at(i + 3));
×
244
    quint16 readCS = (cMSB << 8) | cLSB;
×
245
    quint16 calcCS = calculateChecksum(true, buffer.mid(8), 12);
×
246

247
    if (readCS != calcCS)
×
248
    {
249
        qDebug().nospace().noquote() << "ERROR: Read checksum 0x" << QString::number(readCS, 16)
250
                                     << ", calculated 0x"<< QString::number(calcCS, 16);
251
        return false;
252
    }
253

254
    qDebug() << "[RDM] Detected UID:" << UID;
255
    values.insert("DISCOVERY_COUNT", 1);
×
256
    values.insert("UID-0", UID);
×
257

258
    return true;
×
259
}
×
260

261
bool RDMProtocol::parsePacket(const QByteArray &buffer, QVariantMap &values)
×
262
{
263
    int i = 0;
264
    bool startCode = false;
265

266
#ifdef DEBUG_RDM
267
    qDebug() << "[RDM] Packet payload:" << buffer.toHex(',');
268
#endif
269

270
    if (buffer.length() == 0)
×
271
        return false;
272

273
    // check first bytes
274
    if (buffer.at(i) == char(RDM_START_CODE))
×
275
    {
276
        startCode = true;
277
        i++;
278
    }
279

280
    if (buffer.at(i++) != char(RDM_SC_SUB_MESSAGE))
×
281
        return false;
282

283
    // Data length
284
    quint8 length = quint8(buffer.at(i++));
×
285

286
    // Destination UID and source UID
287
    quint16 ESTAId;
288
    quint32 deviceId;
289
    QString destUID = byteArrayToUID(buffer.mid(i, 6), ESTAId, deviceId);
×
290
    i += 6;
×
291
    QString sourceUID = byteArrayToUID(buffer.mid(i, 6), ESTAId, deviceId);
×
292
    i += 6;
293

294
    // check if we are reading our own request
295
    if (ESTAId == m_estaID && deviceId == m_deviceID)
×
296
        return false;
297

298
    values.insert("UID_INFO", sourceUID);
×
299

300
    // transaction number
301
    quint8 transactionNum = quint8(buffer.at(i++));
×
302

303
    // Response type
304
    quint8 responseType = quint8(buffer.at(i++));
×
305
    values.insert("Response", responseToString(responseType));
×
306

307
    if (responseType != RESPONSE_TYPE_ACK)
×
308
        qWarning() << "[RDM] bad response type" << responseType;
×
309

310
    // message count
311
    quint8 messageCount = quint8(buffer.at(i++));
×
312

313
    // sub device
314
    quint16 subDevice = byteArrayToShort(buffer, i);
×
315
    i+=2;
316

317
    // command class
318
    quint8 commandClass = quint8(buffer.at(i++));
×
319

320
    // Parameter ID
321
    quint16 PID = byteArrayToShort(buffer, i);
×
322
    values.insert("PID", PID);
×
323
    i += 2;
×
324

325
    // Parameter data length
326
    quint8 PDL = quint8(buffer.at(i++));
×
327

328
#ifdef DEBUG_RDM
329
    qDebug().nospace().noquote() <<
330
        "[RDM] Data length: " << QString::number(length) <<
331
        ", source UID: " << sourceUID << ", destination UID: " << destUID <<
332
        ", transaction number: " << QString::number(transactionNum) <<
333
        ", Response type: " << QString::number(responseType) <<
334
        ", Message count: " << QString::number(messageCount) <<
335
        ", Sub-device: " << QString::number(subDevice) <<
336
        ", Command class: 0x" << QString::number(commandClass, 16) <<
337
        ", Parameter ID: 0x" << QString::number(PID, 16) <<
338
        ", Parameter data length: " << QString::number(PDL);
339
#else
340
    Q_UNUSED(length)
341
    Q_UNUSED(transactionNum)
342
    Q_UNUSED(messageCount)
343
    Q_UNUSED(subDevice)
344
    Q_UNUSED(commandClass)
345
#endif
346

347
    switch (PID)
×
348
    {
349
        case PID_SUPPORTED_PARAMETERS:
350
        {
351
            QVector<quint16> pidList;
352
#ifdef DEBUG_RDM
353
            QDebug out = qDebug();
354
            out.nospace().noquote() << "Supported PIDs list: ";
355
#endif
356
            for (int n = 0; n < PDL; n += 2)
×
357
            {
358
                quint16 pid = byteArrayToShort(buffer, i + n);
×
359
                pidList.append(pid);
×
360
#ifdef DEBUG_RDM
361
                out << "0x" << QString::number(pid, 16) << ", ";
362
#endif
363
            }
364
            values.insert("PID_LIST", QVariant::fromValue(pidList));
×
365
        }
×
366
        break;
×
367
        case PID_DEVICE_INFO:
×
368
        {
369
            values.insert("RDM version", byteArrayToShort(buffer, i));
×
370
            values.insert("Device model ID", byteArrayToShort(buffer, i + 2));
×
371
            values.insert("TYPE", categoryToString(byteArrayToShort(buffer, i + 4)));
×
372
            values.insert("Software version", byteArrayToLong(buffer, i + 6));
×
373
            values.insert("DMX_CHANNELS", byteArrayToShort(buffer, i + 10));
×
374
            values.insert("Current personality", quint8(buffer.at(i + 12)));
×
375
            values.insert("Number of personalities", quint8(buffer.at(i + 13)));
×
376
            values.insert("DMX_START_ADDRESS", byteArrayToShort(buffer, i + 14));
×
377
            values.insert("Sub-device count", byteArrayToShort(buffer, i + 16));
×
378
            values.insert("Number of sensors", quint8(buffer.at(i + 20)));
×
379
        }
380
        break;
×
381
        case PID_DEVICE_MODEL_DESCRIPTION:
×
382
        {
383
            values.insert("MODEL_NAME", QString(buffer.mid(i, PDL)));
×
384
        }
385
        break;
×
386
        case PID_MANUFACTURER_LABEL:
×
387
        {
388
            values.insert("MANUFACTURER", QString(buffer.mid(i, PDL)));
×
389
        }
390
        break;
×
391
        case PID_PARAMETER_DESCRIPTION:
×
392
        {
393
            if (PDL < 20)
×
394
                break;
395

396
            values.insert("PID_INFO", byteArrayToShort(buffer, i));
×
397
            values.insert("PDL Size", quint8(buffer.at(i + 2)));
×
398
            values.insert("Data type", quint8(buffer.at(i + 3)));
×
399
            values.insert("Command class", quint8(buffer.at(i + 4)));
×
400
            values.insert("Type", quint8(buffer.at(i + 5)));
×
401
            values.insert("Unit", quint8(buffer.at(i + 6)));
×
402
            values.insert("Prefix", quint8(buffer.at(i + 7)));
×
403
            values.insert("Min Valid Value", byteArrayToLong(buffer, i + 8));
×
404
            values.insert("Max Valid Value", byteArrayToLong(buffer, i + 12));
×
405
            values.insert("Default Value", byteArrayToLong(buffer, i + 16));
×
406
            values.insert("PID_DESC", QString(buffer.mid(i + 20, PDL - 20)));
×
407
        }
408
        break;
×
409
        case PID_DMX_PERSONALITY:
410
        {
411
            values.insert("PERS_CURRENT", quint8(buffer.at(i)));
×
412
            values.insert("PERS_COUNT", quint8(buffer.at(i + 1)));
×
413
        }
414
        break;
×
415
        case PID_DMX_PERSONALITY_DESCRIPTION:
416
        {
417
            values.insert("PERS_INDEX", quint8(buffer.at(i)));
×
418
            values.insert("PERS_CHANNELS", byteArrayToShort(buffer, i + 1));
×
419
            values.insert("PERS_DESC", QString(buffer.mid(i + 3, PDL - 3)));
×
420
        }
421
        break;
×
422
        case PID_DMX_START_ADDRESS:
×
423
        {
424
            values.insert("DMX_START_ADDRESS", byteArrayToShort(buffer, i));
×
425
        }
426
        break;
×
427
        case PID_SLOT_INFO:
428
        {
429
            QVector<quint16> slotList;
430

431
            for (int n = 0; n < PDL; n += 5)
×
432
            {
433
                quint16 slotId = byteArrayToShort(buffer, i + n);
×
434
                slotList.append(slotId);
×
435
                //qDebug().nospace().noquote() << "SLOT ID: " << QString::number(slotId);
436
            }
437
            values.insert("SLOT_LIST", QVariant::fromValue(slotList));
×
438
        }
×
439
        break;
×
440
        case PID_SLOT_DESCRIPTION:
×
441
        {
442
            values.insert("SLOT_ID", byteArrayToShort(buffer, i));
×
443
            values.insert("SLOT_DESC", QString(buffer.mid(i + 2, PDL - 2)));
×
444
        }
445
        break;
×
446
        default:
447
        break;
448
    }
449

450
    if (PDL)
×
451
    {
452
        QByteArray data = buffer.mid(i, PDL);
×
453
        QByteArray hexData = data.toHex(',');
×
454
        values.insert("RAW_DATA", hexData);
×
455
        QString dString;
456
        for (int c = 0; c < data.length(); c++)
×
457
        {
458
            if (data.at(c) < 0x20)
×
459
                dString.append("#");
×
460
            else
461
                dString.append(data.at(c));
×
462
        }
463
        values.insert("RAW_DATA_STRING", dString);
×
464
    }
×
465

466
    i += PDL;
×
467

468
    quint16 csFromData = byteArrayToShort(buffer, i);
×
469
    quint16 csElapsed = calculateChecksum(startCode, buffer, i);
×
470

471
    if (csFromData != csElapsed)
×
472
    {
473
        qDebug() << "Checksum ERROR. Got:" << QString::number(csFromData, 16) << ", calculated:" << QString::number(csElapsed, 16);
474
        return false;
×
475
    }
476

477
    return true;
478
}
×
479

480
QByteArray RDMProtocol::UIDToByteArray(quint16 manufacturer, quint32 deviceId)
×
481
{
482
    QByteArray ba;
483

484
    ba.append(char(manufacturer >> 8));
×
485
    ba.append(char(manufacturer & 0x00FF));
×
486

487
    ba.append(char((deviceId >> 24) & 0x00FF));
×
488
    ba.append(char((deviceId >> 16) & 0x00FF));
×
489
    ba.append(char((deviceId >> 8) & 0x00FF));
×
490
    ba.append(char(deviceId & 0x00FF));
×
491

492
    return ba;
×
493
}
×
494

495
QString RDMProtocol::byteArrayToUID(QByteArray buffer, quint16 &ESTAId, quint32 &deviceId)
×
496
{
497
    int i = 0;
498
    ESTAId = quint8(buffer.at(i)) << 8 | quint8(buffer.at(i + 1));
×
499
    i += 2;
500

501
    deviceId  = quint8(buffer.at(i++)) << 24;
×
502
    deviceId |= quint8(buffer.at(i++)) << 16;
×
503
    deviceId |= quint8(buffer.at(i++)) << 8;
×
504
    deviceId |= quint8(buffer.at(i++));
×
505

506
    return QString("%1%2")
×
507
            .arg(ESTAId, 4, 16, QLatin1Char('0'))
×
508
            .arg(deviceId, 8, 16, QLatin1Char('0')).toUpper();
×
509
}
510

511
QString RDMProtocol::broadcastAddress()
×
512
{
513
    return QString("%1%2")
×
514
            .arg(BROADCAST_ESTA_ID, 4, 16)
×
515
            .arg(BROADCAST_DEVICE_ID, 6, 16);
×
516
}
517

518
QByteArray RDMProtocol::shortToByteArray(quint16 data)
×
519
{
520
    QByteArray ba;
521

522
    ba.append(char(data >> 8));
×
523
    ba.append(char(data & 0x00FF));
×
524

525
    return ba;
×
526
}
×
527

528
QByteArray RDMProtocol::longToByteArray(quint32 data)
×
529
{
530
    QByteArray ba;
531

532
    ba.append(char((data >> 24) & 0x00FF));
×
533
    ba.append(char((data >> 16) & 0x00FF));
×
534
    ba.append(char((data >> 8) & 0x00FF));
×
535
    ba.append(char(data & 0x00FF));
×
536

537

538
    return ba;
×
539
}
×
540

541
quint16 RDMProtocol::byteArrayToShort(const QByteArray &buffer, int index)
×
542
{
543
    if (buffer.length() < index + 2)
×
544
        return 0;
545

546
    quint16 value = quint8(buffer.at(index)) << 8 |
×
547
                    quint8(buffer.at(index + 1));
×
548
    return value;
×
549
}
550

551
quint32 RDMProtocol::byteArrayToLong(const QByteArray &buffer, int index)
×
552
{
553
    if (buffer.length() < index + 4)
×
554
        return 0;
555

556
    quint32 value = quint8(buffer.at(index)) << 24 |
×
557
                    quint8(buffer.at(index + 1)) << 16 |
×
558
                    quint8(buffer.at(index + 2)) << 8  |
×
559
                    quint8(buffer.at(index + 3));
×
560
    return value;
×
561
}
562

563
quint16 RDMProtocol::calculateChecksum(bool startCode, const QByteArray &ba, int len)
×
564
{
565
    ushort cs = startCode ? 0 : RDM_START_CODE;
×
566

567
    for (int i = 0; i < len; i++)
×
568
        cs += uchar(ba.at(i));
×
569

570
    return cs;
×
571
}
572

573
QString RDMProtocol::responseToString(quint8 response)
×
574
{
575
    switch (response)
×
576
    {
577
        case RESPONSE_TYPE_ACK: return "ACK";
×
578
        case RESPONSE_TYPE_ACK_TIMER: return "TIMEOUT";
×
579
        case RESPONSE_TYPE_NACK_REASON: return "NACK";
×
580
        case RESPONSE_TYPE_ACK_OVERFLOW: return "OVERFLOW";
×
581
        default: return "UNKNOWN";
×
582
    }
583
}
584

585
QString RDMProtocol::categoryToString(quint16 category)
×
586
{
587
    switch (category)
×
588
    {
589
        case 0x0000: return "Not Declared";
×
590
        case 0x0100: return "Fixture";
×
591
        case 0x0101: return "Fixture Fixed";
×
592
        case 0x0102: return "Fixture Moving Yoke";
×
593
        case 0x0103: return "Fixture Moving Mirror";
×
594
        case 0x01FF: return "Fixture Other";
×
595
        case 0x0200: return "Fixture Accessory";
×
596
        case 0x0201: return "Fixture Accessory Color";
×
597
        case 0x0202: return "Fixture Accessory Yoke";
×
598
        case 0x0203: return "Fixture Accessory Mirror";
×
599
        case 0x0204: return "Fixture Accessory Effect";
×
600
        case 0x0205: return "Fixture Accessory Beam";
×
601
        case 0x02FF: return "Fixture Accessory Other";
×
602
        case 0x0300: return "Projector";
×
603
        case 0x0301: return "Projector Fixed";
×
604
        case 0x0302: return "Projector Moving Yoke";
×
605
        case 0x0303: return "Projector Moving Mirror";
×
606
        case 0x03FF: return "Projector Other";
×
607
        case 0x0400: return "Atmospheric";
×
608
        case 0x0401: return "Atmospheric Effect";
×
609
        case 0x0402: return "Atmospheric Pyro";
×
610
        case 0x04FF: return "Atmospheric Other";
×
611
        case 0x0500: return "Dimmer";
×
612
        case 0x0501: return "Dimmer AC Incandescent";
×
613
        case 0x0502: return "Dimmer AC Fluorescent";
×
614
        case 0x0503: return "Dimmer AC Cold Cathode";
×
615
        case 0x0504: return "Dimmer AC non-dim";
×
616
        case 0x0505: return "Dimmer AC ELV";
×
617
        case 0x0506: return "Dimmer AC Other";
×
618
        case 0x0507: return "Dimmer DC Level";
×
619
        case 0x0508: return "Dimmer DC PWM";
×
620
        case 0x0509: return "Dimmer CS LED";
×
621
        case 0x05FF: return "Dimmer Other";
×
622
        case 0x0600: return "Power";
×
623
        case 0x0601: return "Power Control";
×
624
        case 0x0602: return "Power Source";
×
625
        case 0x06FF: return "Power Other";
×
626
        case 0x0700: return "Scenic";
×
627
        case 0x0701: return "Scenic Drive";
×
628
        case 0x07FF: return "Scenic Other";
×
629
        case 0x0800: return "Data";
×
630
        case 0x0801: return "Data Distribution";
×
631
        case 0x0802: return "Data Conversion";
×
632
        case 0x08FF: return "Data Other";
×
633
        case 0x0900: return "AV";
×
634
        case 0x0901: return "AV Audio";
×
635
        case 0x0902: return "AV Video";
×
636
        case 0x09FF: return "AV Other";
×
637
        case 0x0A00: return "Monitor";
×
638
        case 0x0A01: return "Monitor AC Line Power";
×
639
        case 0x0A02: return "Monitor DC Power";
×
640
        case 0x0A03: return "Monitor Environmental";
×
641
        case 0x0AFF: return "Monitor Other";
×
642
        case 0x7000: return "Control";
×
643
        case 0x7001: return "Control Controller";
×
644
        case 0x7002: return "Control Backup Device";
×
645
        case 0x70FF: return "Control Other";
×
646
        case 0x7100: return "Test";
×
647
        case 0x7101: return "Test Equipment";
×
648
        case 0x71FF: return "Test Equipment Other";
×
649
        case 0x7FFF: return "Other";
×
650
        default: return "Unknown";
×
651
    }
652
}
653

654
QString RDMProtocol::pidToString(quint16 pid)
×
655
{
656
    switch (pid)
×
657
    {
658
        case PID_DISC_UNIQUE_BRANCH: return "PID_DISC_UNIQUE_BRANCH";
×
659
        case PID_DISC_MUTE: return "PID_DISC_MUTE";
×
660
        case PID_DISC_UN_MUTE: return "PID_DISC_UN_MUTE";
×
661
        case PID_PROXIED_DEVICES: return "PID_PROXIED_DEVICES";
×
662
        case PID_PROXIED_DEVICE_COUNT: return "PID_PROXIED_DEVICE_COUNT";
×
663
        case PID_COMMS_STATUS: return "PID_COMMS_STATUS";
×
664
        case PID_QUEUED_MESSAGE: return "PID_QUEUED_MESSAGE";
×
665
        case PID_STATUS_MESSAGES: return "PID_STATUS_MESSAGES";
×
666
        case PID_STATUS_ID_DESCRIPTION: return "PID_STATUS_ID_DESCRIPTION";
×
667
        case PID_CLEAR_STATUS_ID: return "PID_CLEAR_STATUS_ID";
×
668
        case PID_SUB_DEVICE_STATUS_REPORT_THRESHOLD: return "PID_SUB_DEVICE_STATUS_REPORT_THRESHOLD";
×
669
        case PID_SUPPORTED_PARAMETERS: return "PID_SUPPORTED_PARAMETERS";
×
670
        case PID_PARAMETER_DESCRIPTION: return "PID_PARAMETER_DESCRIPTION";
×
671
        case PID_DEVICE_INFO: return "PID_DEVICE_INFO";
×
672
        case PID_PRODUCT_DETAIL_ID_LIST: return "PID_PRODUCT_DETAIL_ID_LIST";
×
673
        case PID_DEVICE_MODEL_DESCRIPTION: return "PID_DEVICE_MODEL_DESCRIPTION";
×
674
        case PID_MANUFACTURER_LABEL: return "PID_MANUFACTURER_LABEL";
×
675
        case PID_DEVICE_LABEL: return "PID_DEVICE_LABEL";
×
676
        case PID_FACTORY_DEFAULTS: return "PID_FACTORY_DEFAULTS";
×
677
        case PID_LANGUAGE_CAPABILITIES: return "PID_LANGUAGE_CAPABILITIES";
×
678
        case PID_LANGUAGE: return "PID_LANGUAGE";
×
679
        case PID_SOFTWARE_VERSION_LABEL: return "PID_SOFTWARE_VERSION_LABEL";
×
680
        case PID_BOOT_SOFTWARE_VERSION_ID: return "PID_BOOT_SOFTWARE_VERSION_ID";
×
681
        case PID_BOOT_SOFTWARE_VERSION_LABEL: return "PID_BOOT_SOFTWARE_VERSION_LABEL";
×
682
        case PID_DMX_PERSONALITY: return "PID_DMX_PERSONALITY";
×
683
        case PID_DMX_PERSONALITY_DESCRIPTION: return "PID_DMX_PERSONALITY_DESCRIPTION";
×
684
        case PID_DMX_START_ADDRESS: return "PID_DMX_START_ADDRESS";
×
685
        case PID_SLOT_INFO: return "PID_SLOT_INFO";
×
686
        case PID_SLOT_DESCRIPTION: return "PID_SLOT_DESCRIPTION";
×
687
        case PID_DEFAULT_SLOT_VALUE: return "PID_DEFAULT_SLOT_VALUE";
×
688
        case PID_SENSOR_DEFINITION: return "PID_SENSOR_DEFINITION";
×
689
        case PID_SENSOR_VALUE: return "PID_SENSOR_VALUE";
×
690
        case PID_RECORD_SENSORS: return "PID_RECORD_SENSORS";
×
691
        case PID_DEVICE_HOURS: return "PID_DEVICE_HOURS";
×
692
        case PID_LAMP_HOURS: return "PID_LAMP_HOURS";
×
693
        case PID_LAMP_STRIKES: return "PID_LAMP_STRIKES";
×
694
        case PID_LAMP_STATE: return "PID_LAMP_STATE";
×
695
        case PID_LAMP_ON_MODE: return "PID_LAMP_ON_MODE";
×
696
        case PID_DEVICE_POWER_CYCLES: return "PID_DEVICE_POWER_CYCLES";
×
697
        case PID_DISPLAY_INVERT: return "PID_DISPLAY_INVERT";
×
698
        case PID_DISPLAY_LEVEL: return "PID_DISPLAY_LEVEL";
×
699
        case PID_PAN_INVERT: return "PID_PAN_INVERT";
×
700
        case PID_TILT_INVERT: return "PID_TILT_INVERT";
×
701
        case PID_PAN_TILT_SWAP: return "PID_PAN_TILT_SWAP";
×
702
        case PID_REAL_TIME_CLOCK: return "PID_REAL_TIME_CLOCK";
×
703
        case PID_IDENTIFY_DEVICE: return "PID_IDENTIFY_DEVICE";
×
704
        case PID_RESET_DEVICE: return "PID_RESET_DEVICE";
×
705
        case PID_POWER_STATE: return "PID_POWER_STATE";
×
706
        case PID_PERFORM_SELFTEST: return "PID_PERFORM_SELFTEST";
×
707
        case PID_SELF_TEST_DESCRIPTION: return "PID_SELF_TEST_DESCRIPTION";
×
708
        case PID_CAPTURE_PRESET: return "PID_CAPTURE_PRESET";
×
709
        case PID_PRESET_PLAYBACK: return "PID_PRESET_PLAYBACK";
×
710
        case PID_DMX_BLOCK_ADDRESS: return "PID_DMX_BLOCK_ADDRESS";
×
711
        case PID_DMX_FAIL_MODE: return "PID_DMX_FAIL_MODE";
×
712
        case PID_DMX_STARTUP_MODE: return "PID_DMX_STARTUP_MODE";
×
713
        case PID_DIMMER_INFO: return "PID_DIMMER_INFO";
×
714
        case PID_MINIMUM_LEVEL: return "PID_MINIMUM_LEVEL";
×
715
        case PID_MAXIMUM_LEVEL: return "PID_MAXIMUM_LEVEL";
×
716
        case PID_CURVE: return "PID_CURVE";
×
717
        case PID_CURVE_DESCRIPTION: return "PID_CURVE_DESCRIPTION";
×
718
        case PID_OUTPUT_RESPONSE_TIME: return "PID_OUTPUT_RESPONSE_TIME";
×
719
        case PID_OUTPUT_RESPONSE_TIME_DESCRIPTION: return "PID_OUTPUT_RESPONSE_TIME_DESCRIPTION";
×
720
        case PID_MODULATION_FREQUENCY: return "PID_MODULATION_FREQUENCY";
×
721
        case PID_MODULATION_FREQUENCY_DESCRIPTION: return "PID_MODULATION_FREQUENCY_DESCRIPTION";
×
722
        case PID_BURN_IN: return "PID_BURN_IN";
×
723
        case PID_LOCK_PIN: return "PID_LOCK_PIN";
×
724
        case PID_LOCK_STATE: return "PID_LOCK_STATE";
×
725
        case PID_LOCK_STATE_DESCRIPTION: return "PID_LOCK_STATE_DESCRIPTION";
×
726
        case PID_IDENTIFY_MODE: return "PID_IDENTIFY_MODE";
×
727
        case PID_PRESET_INFO: return "PID_PRESET_INFO";
×
728
        case PID_PRESET_STATUS: return "PID_PRESET_STATUS";
×
729
        case PID_PRESET_MERGEMODE: return "PID_PRESET_MERGEMODE";
×
730
        case PID_POWER_ON_SELF_TEST: return "PID_POWER_ON_SELF_TEST";
×
731
        default: return "";
×
732
    }
733
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc