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

mcallegari / qlcplus / 7307414152

23 Dec 2023 09:18AM UTC coverage: 32.067%. Remained the same
7307414152

push

github

web-flow
Merge pull request #1493 from yestalgia/readme

Update Readme

15169 of 47304 relevant lines covered (32.07%)

23733.74 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() > 2)
×
113
            {
114
                switch(pid)
×
115
                {
116
                    case PID_DMX_PERSONALITY_DESCRIPTION:
×
117
                    default:
118
                        buffer.append(char(1)); // append PDL
×
119
                        buffer.append(char(params.at(2).toUInt()));
×
120
                    break;
×
121
                    case PID_PARAMETER_DESCRIPTION:
×
122
                    case PID_SLOT_DESCRIPTION:
123
                        buffer.append(char(2)); // append PDL
×
124
                        buffer.append(shortToByteArray(params.at(2).toUInt()));
×
125
                    break;
×
126
                }
127
            }
128
            else
129
            {
130
                buffer.append(char(0));
×
131
            }
132
        }
133
        break;
×
134
        case SET_COMMAND:
×
135
        {
136
            if (params.length() < 2)
×
137
                return false;
×
138

139
            quint16 pid = params.at(1).toUInt();
×
140
            buffer.append(shortToByteArray(pid));
×
141
            int pdlPosition = buffer.length();
×
142

143
            // Temporarily add a zero PDL.
144
            // Will be fixed after parameters append
145
            buffer.append(char(0));
×
146

147
            for (int i = 0; i < params.length(); i += 2)
×
148
            {
149
                int size = params.at(i).toInt();
×
150

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

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

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

183
    // set the correct length
184
    buffer[startCode ? 2 : 1] = buffer.length() + (startCode ? 0 : 1);
×
185

186
    // append checksum
187
    buffer.append(shortToByteArray(calculateChecksum(startCode, buffer, buffer.length())));
×
188

189
    m_transactionNum++;
×
190

191
    return true;
×
192
}
193

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

199
    int i = 0;
×
200

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

211
    i += 7;
×
212
    // check separator
213
    if (buffer.at(i++) != char(0xAA))
×
214
        return false;
×
215

216
    quint8 mMSB = quint8(buffer.at(i)) & quint8(buffer.at(i + 1));
×
217
    quint8 mLSB = quint8(buffer.at(i + 2)) & quint8(buffer.at(i + 3));
×
218
    i += 4;
×
219

220
    quint8 dMSB3 = quint8(buffer.at(i)) & quint8(buffer.at(i + 1));
×
221
    quint8 dMSB2 = quint8(buffer.at(i + 2)) & quint8(buffer.at(i + 3));
×
222
    quint8 dMSB1 = quint8(buffer.at(i + 4)) & quint8(buffer.at(i + 5));
×
223
    quint8 dLSB  = quint8(buffer.at(i + 6)) & quint8(buffer.at(i + 7));
×
224
    i += 8;
×
225

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

236
    QString UID = byteArrayToUID(ba, ESTAId, deviceId);
×
237

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

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

251
    qDebug() << "[RDM] Detected UID:" << UID;
×
252
    values.insert("DISCOVERY_COUNT", 1);
×
253
    values.insert("UID-0", UID);
×
254

255
    return true;
×
256
}
257

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

263
#ifdef DEBUG_RDM
264
    qDebug() << "[RDM] Packet payload:" << buffer.toHex(',');
265
#endif
266

267
    if (buffer.length() == 0)
×
268
        return false;
×
269

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

277
    if (buffer.at(i++) != char(RDM_SC_SUB_MESSAGE))
×
278
        return false;
×
279

280
    // Data length
281
    quint8 length = quint8(buffer.at(i++));
×
282

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

291
    // check if we are reading our own request
292
    if (ESTAId == m_estaID && deviceId == m_deviceID)
×
293
        return false;
×
294

295
    values.insert("UID_INFO", sourceUID);
×
296

297
    // transaction number
298
    quint8 transactionNum = quint8(buffer.at(i++));
×
299

300
    // Response type
301
    quint8 responseType = quint8(buffer.at(i++));
×
302
    values.insert("Response", responseToString(responseType));
×
303

304
    if (responseType != RESPONSE_TYPE_ACK)
×
305
        qWarning() << "[RDM] bad response type" << responseType;
×
306

307
    // message count
308
    quint8 messageCount = quint8(buffer.at(i++));
×
309

310
    // sub device
311
    quint16 subDevice = byteArrayToShort(buffer, i);
×
312
    i+=2;
×
313

314
    // command class
315
    quint8 commandClass = quint8(buffer.at(i++));
×
316

317
    // Parameter ID
318
    quint16 PID = byteArrayToShort(buffer, i);
×
319
    values.insert("PID", PID);
×
320
    i += 2;
×
321

322
    // Parameter data length
323
    quint8 PDL = quint8(buffer.at(i++));
×
324

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

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

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

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

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

463
    i += PDL;
×
464

465
    quint16 csFromData = byteArrayToShort(buffer, i);
×
466
    quint16 csElapsed = calculateChecksum(startCode, buffer, i);
×
467

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

474
    return true;
×
475
}
476

477
QByteArray RDMProtocol::UIDToByteArray(quint16 manufacturer, quint32 deviceId)
×
478
{
479
    QByteArray ba;
×
480

481
    ba.append(char(manufacturer >> 8));
×
482
    ba.append(char(manufacturer & 0x00FF));
×
483

484
    ba.append(char((deviceId >> 24) & 0x00FF));
×
485
    ba.append(char((deviceId >> 16) & 0x00FF));
×
486
    ba.append(char((deviceId >> 8) & 0x00FF));
×
487
    ba.append(char(deviceId & 0x00FF));
×
488

489
    return ba;
×
490
}
491

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

498
    deviceId  = quint8(buffer.at(i++)) << 24;
×
499
    deviceId |= quint8(buffer.at(i++)) << 16;
×
500
    deviceId |= quint8(buffer.at(i++)) << 8;
×
501
    deviceId |= quint8(buffer.at(i++));
×
502

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

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

515
QByteArray RDMProtocol::shortToByteArray(quint16 data)
×
516
{
517
    QByteArray ba;
×
518

519
    ba.append(char(data >> 8));
×
520
    ba.append(char(data & 0x00FF));
×
521

522
    return ba;
×
523
}
524

525
QByteArray RDMProtocol::longToByteArray(quint32 data)
×
526
{
527
    QByteArray ba;
×
528

529
    ba.append(char((data >> 24) & 0x00FF));
×
530
    ba.append(char((data >> 16) & 0x00FF));
×
531
    ba.append(char((data >> 8) & 0x00FF));
×
532
    ba.append(char(data & 0x00FF));
×
533

534

535
    return ba;
×
536
}
537

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

543
    quint16 value = quint8(buffer.at(index)) << 8 |
×
544
                    quint8(buffer.at(index + 1));
×
545
    return value;
×
546
}
547

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

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

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

564
    for (int i = 0; i < len; i++)
×
565
        cs += uchar(ba.at(i));
×
566

567
    return cs;
×
568
}
569

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

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

651
QString RDMProtocol::pidToString(quint16 pid)
×
652
{
653
    switch (pid)
×
654
    {
655
        case PID_DISC_UNIQUE_BRANCH: return "PID_DISC_UNIQUE_BRANCH";
×
656
        case PID_DISC_MUTE: return "PID_DISC_MUTE";
×
657
        case PID_DISC_UN_MUTE: return "PID_DISC_UN_MUTE";
×
658
        case PID_PROXIED_DEVICES: return "PID_PROXIED_DEVICES";
×
659
        case PID_PROXIED_DEVICE_COUNT: return "PID_PROXIED_DEVICE_COUNT";
×
660
        case PID_COMMS_STATUS: return "PID_COMMS_STATUS";
×
661
        case PID_QUEUED_MESSAGE: return "PID_QUEUED_MESSAGE";
×
662
        case PID_STATUS_MESSAGES: return "PID_STATUS_MESSAGES";
×
663
        case PID_STATUS_ID_DESCRIPTION: return "PID_STATUS_ID_DESCRIPTION";
×
664
        case PID_CLEAR_STATUS_ID: return "PID_CLEAR_STATUS_ID";
×
665
        case PID_SUB_DEVICE_STATUS_REPORT_THRESHOLD: return "PID_SUB_DEVICE_STATUS_REPORT_THRESHOLD";
×
666
        case PID_SUPPORTED_PARAMETERS: return "PID_SUPPORTED_PARAMETERS";
×
667
        case PID_PARAMETER_DESCRIPTION: return "PID_PARAMETER_DESCRIPTION";
×
668
        case PID_DEVICE_INFO: return "PID_DEVICE_INFO";
×
669
        case PID_PRODUCT_DETAIL_ID_LIST: return "PID_PRODUCT_DETAIL_ID_LIST";
×
670
        case PID_DEVICE_MODEL_DESCRIPTION: return "PID_DEVICE_MODEL_DESCRIPTION";
×
671
        case PID_MANUFACTURER_LABEL: return "PID_MANUFACTURER_LABEL";
×
672
        case PID_DEVICE_LABEL: return "PID_DEVICE_LABEL";
×
673
        case PID_FACTORY_DEFAULTS: return "PID_FACTORY_DEFAULTS";
×
674
        case PID_LANGUAGE_CAPABILITIES: return "PID_LANGUAGE_CAPABILITIES";
×
675
        case PID_LANGUAGE: return "PID_LANGUAGE";
×
676
        case PID_SOFTWARE_VERSION_LABEL: return "PID_SOFTWARE_VERSION_LABEL";
×
677
        case PID_BOOT_SOFTWARE_VERSION_ID: return "PID_BOOT_SOFTWARE_VERSION_ID";
×
678
        case PID_BOOT_SOFTWARE_VERSION_LABEL: return "PID_BOOT_SOFTWARE_VERSION_LABEL";
×
679
        case PID_DMX_PERSONALITY: return "PID_DMX_PERSONALITY";
×
680
        case PID_DMX_PERSONALITY_DESCRIPTION: return "PID_DMX_PERSONALITY_DESCRIPTION";
×
681
        case PID_DMX_START_ADDRESS: return "PID_DMX_START_ADDRESS";
×
682
        case PID_SLOT_INFO: return "PID_SLOT_INFO";
×
683
        case PID_SLOT_DESCRIPTION: return "PID_SLOT_DESCRIPTION";
×
684
        case PID_DEFAULT_SLOT_VALUE: return "PID_DEFAULT_SLOT_VALUE";
×
685
        case PID_SENSOR_DEFINITION: return "PID_SENSOR_DEFINITION";
×
686
        case PID_SENSOR_VALUE: return "PID_SENSOR_VALUE";
×
687
        case PID_RECORD_SENSORS: return "PID_RECORD_SENSORS";
×
688
        case PID_DEVICE_HOURS: return "PID_DEVICE_HOURS";
×
689
        case PID_LAMP_HOURS: return "PID_LAMP_HOURS";
×
690
        case PID_LAMP_STRIKES: return "PID_LAMP_STRIKES";
×
691
        case PID_LAMP_STATE: return "PID_LAMP_STATE";
×
692
        case PID_LAMP_ON_MODE: return "PID_LAMP_ON_MODE";
×
693
        case PID_DEVICE_POWER_CYCLES: return "PID_DEVICE_POWER_CYCLES";
×
694
        case PID_DISPLAY_INVERT: return "PID_DISPLAY_INVERT";
×
695
        case PID_DISPLAY_LEVEL: return "PID_DISPLAY_LEVEL";
×
696
        case PID_PAN_INVERT: return "PID_PAN_INVERT";
×
697
        case PID_TILT_INVERT: return "PID_TILT_INVERT";
×
698
        case PID_PAN_TILT_SWAP: return "PID_PAN_TILT_SWAP";
×
699
        case PID_REAL_TIME_CLOCK: return "PID_REAL_TIME_CLOCK";
×
700
        case PID_IDENTIFY_DEVICE: return "PID_IDENTIFY_DEVICE";
×
701
        case PID_RESET_DEVICE: return "PID_RESET_DEVICE";
×
702
        case PID_POWER_STATE: return "PID_POWER_STATE";
×
703
        case PID_PERFORM_SELFTEST: return "PID_PERFORM_SELFTEST";
×
704
        case PID_SELF_TEST_DESCRIPTION: return "PID_SELF_TEST_DESCRIPTION";
×
705
        case PID_CAPTURE_PRESET: return "PID_CAPTURE_PRESET";
×
706
        case PID_PRESET_PLAYBACK: return "PID_PRESET_PLAYBACK";
×
707
        case PID_DMX_BLOCK_ADDRESS: return "PID_DMX_BLOCK_ADDRESS";
×
708
        case PID_DMX_FAIL_MODE: return "PID_DMX_FAIL_MODE";
×
709
        case PID_DMX_STARTUP_MODE: return "PID_DMX_STARTUP_MODE";
×
710
        case PID_DIMMER_INFO: return "PID_DIMMER_INFO";
×
711
        case PID_MINIMUM_LEVEL: return "PID_MINIMUM_LEVEL";
×
712
        case PID_MAXIMUM_LEVEL: return "PID_MAXIMUM_LEVEL";
×
713
        case PID_CURVE: return "PID_CURVE";
×
714
        case PID_CURVE_DESCRIPTION: return "PID_CURVE_DESCRIPTION";
×
715
        case PID_OUTPUT_RESPONSE_TIME: return "PID_OUTPUT_RESPONSE_TIME";
×
716
        case PID_OUTPUT_RESPONSE_TIME_DESCRIPTION: return "PID_OUTPUT_RESPONSE_TIME_DESCRIPTION";
×
717
        case PID_MODULATION_FREQUENCY: return "PID_MODULATION_FREQUENCY";
×
718
        case PID_MODULATION_FREQUENCY_DESCRIPTION: return "PID_MODULATION_FREQUENCY_DESCRIPTION";
×
719
        case PID_BURN_IN: return "PID_BURN_IN";
×
720
        case PID_LOCK_PIN: return "PID_LOCK_PIN";
×
721
        case PID_LOCK_STATE: return "PID_LOCK_STATE";
×
722
        case PID_LOCK_STATE_DESCRIPTION: return "PID_LOCK_STATE_DESCRIPTION";
×
723
        case PID_IDENTIFY_MODE: return "PID_IDENTIFY_MODE";
×
724
        case PID_PRESET_INFO: return "PID_PRESET_INFO";
×
725
        case PID_PRESET_STATUS: return "PID_PRESET_STATUS";
×
726
        case PID_PRESET_MERGEMODE: return "PID_PRESET_MERGEMODE";
×
727
        case PID_POWER_ON_SELF_TEST: return "PID_POWER_ON_SELF_TEST";
×
728
        default: return "";
×
729
    }
730
}
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