aboutsummaryrefslogtreecommitdiffstats
path: root/src/Xpl2Client.h
blob: 44edb6532b8b9920e46f52e038a2a37579b742d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/**
 * @file   Xpl2Client.h
 * @brief  TCP client for the Alchemie XPL2 printhead protocol.
 */
#pragma once

#include "Xpl2JcStatus.h"
#include "Xpl2PhStatus.h"
#include "Xpl2Protocol.h"

#include <QHash>
#include <QObject>
#include <QQmlEngine>
#include <QTcpServer>

#include <functional>

class QTcpSocket;

class Xpl2Client : public QObject
{
  Q_OBJECT
  QML_ELEMENT
  QML_SINGLETON

  Q_PROPERTY (bool listening READ isListening NOTIFY listeningChanged)
  Q_PROPERTY (bool connected READ isConnected NOTIFY connectedChanged)
  Q_PROPERTY (int controllerId READ controllerId NOTIFY jcVersionReceived)
  Q_PROPERTY (
      QString firmwareVersion READ firmwareVersion NOTIFY jcVersionReceived)
  Q_PROPERTY (
      QString hardwareVersion READ hardwareVersion NOTIFY jcVersionReceived)
  Q_PROPERTY (int printheadCount READ printheadCount NOTIFY jcVersionReceived)

public:
  explicit Xpl2Client (QObject *parent = nullptr);

  bool isListening () const;
  bool isConnected () const;

  int controllerId () const;
  QString firmwareVersion () const;
  QString hardwareVersion () const;
  int printheadCount () const;

  static void enableWireDebug ();

  Q_INVOKABLE void startListening ();
  Q_INVOKABLE void stopListening ();
  /** Get the just connected Jetting Controller ID and Software Version. */
  Q_INVOKABLE void getJcVersion ();
  /** Query the specified printhead's version info. */
  Q_INVOKABLE void getPhVersion (int printheadId);

  /* -- CN_ Control commands ----------------------------------------- */

  /** Switch jetting on for all printheads. */
  Q_INVOKABLE void jettingAllOn ();
  /** Switch jetting on for all printheads with a per-nozzle mask (180 chars).
   */
  Q_INVOKABLE void jettingOn (const QString &jettingMask);
  /** Switch jetting off for all printheads. */
  Q_INVOKABLE void jettingOff ();
  /** Switch jetting on for one printhead with a per-nozzle mask (12 chars). */
  Q_INVOKABLE void phJettingOn (int printheadId, const QString &jettingMask);
  /** Switch jetting off for one printhead. */
  Q_INVOKABLE void phJettingOff (int printheadId);
  /** Switch the JC identification LED on. */
  Q_INVOKABLE void jcIdLedOn ();
  /** Switch the JC identification LED off. */
  Q_INVOKABLE void jcIdLedOff ();
  /** Switch a printhead's identification LED on. */
  Q_INVOKABLE void phIdLedOn (int printheadId);
  /** Switch a printhead's identification LED off. */
  Q_INVOKABLE void phIdLedOff (int printheadId);
  /** Run calibration on all printheads. */
  Q_INVOKABLE void jcCalibration ();
  /** Run calibration on one printhead. */
  Q_INVOKABLE void phCalibration (int printheadId);
  /** Get nozzle calibration data for one printhead (48 floats). */
  Q_INVOKABLE void phCalibrationData (int printheadId);
  /** Get raw nozzle calibration data for one printhead (48 floats). */
  Q_INVOKABLE void phCalibrationRawData (int printheadId);
  /** Get the calibrated base frequency and active base frequency. */
  Q_INVOKABLE void phCalibratedBaseFrequency (int printheadId);
  /** Start sending JC status messages at the given level and interval. */
  Q_INVOKABLE void jcStatusMessagingStart (int statusLevel,
                                           int sendIntervalMs);
  /** Stop sending JC status messages. */
  Q_INVOKABLE void jcStatusMessagingStop ();
  /** Start sending PH status messages at the given level and interval. */
  Q_INVOKABLE void phStatusMessagingStart (int statusLevel,
                                           int sendIntervalMs);
  /** Stop sending PH status messages. */
  Q_INVOKABLE void phStatusMessagingStop ();
  /** Reset fault codes for all printheads on the controller. */
  Q_INVOKABLE void jcResetFaultCodes ();
  /** Reset fault codes for one printhead. */
  Q_INVOKABLE void phResetFaultCodes (int printheadId);
  /** Disable nozzles on one printhead using a 12-char mask. */
  Q_INVOKABLE void phNozzlesDisabled (int printheadId, const QString &mask);

  /* -- CF_ Configuration commands ----------------------------------- */

  /** Set the printhead ID. */
  Q_INVOKABLE void phSetId (int printheadId);
  /** De-assign the printhead ID. */
  Q_INVOKABLE void phDeassignId ();
  /** Set jetting parameters for all printheads on the controller. */
  Q_INVOKABLE void jcSetJettingParams (int dutyCycle, int pwmFreq, int drive,
                                       int nozzleDriveFreq,
                                       int nozzleDriveDutyCycle);
  /** Set jetting parameters for one printhead. */
  Q_INVOKABLE void phSetJettingParams (int printheadId, int dutyCycle,
                                       int pwmFreq, int drive,
                                       int nozzleDriveFreq,
                                       int nozzleDriveDutyCycle);
  /** Get jetting parameters from one printhead. */
  Q_INVOKABLE void phGetJettingParams (int printheadId);
  /** Save calibration for all printheads. */
  Q_INVOKABLE void jcSaveCalibration ();
  /** Save calibration for one printhead. */
  Q_INVOKABLE void phSaveCalibration (int printheadId);
  /** Reset calibration for all printheads. */
  Q_INVOKABLE void jcResetCalibration ();
  /** Reset calibration for one printhead. */
  Q_INVOKABLE void phResetCalibration (int printheadId);
  /** Set purge settings for all printheads on the controller. */
  Q_INVOKABLE void jcSetPurgeSettings (int purgeIntervalMs, int purgeTimeMs);
  /** Switch off purge for all printheads on the controller. */
  Q_INVOKABLE void jcSwitchOffPurge ();
  /** Set a JC setting by setter ID. */
  Q_INVOKABLE void jcSetter (bool saveNewValue, int setterId,
                             const QString &newValue);
  /** Set a PH setting by setter ID. */
  Q_INVOKABLE void phSetter (int printheadId, bool saveNewValue, int setterId,
                             const QString &newValue);
  /** Get a JC setting by getter ID. */
  Q_INVOKABLE void jcGetter (bool getSavedValue, int getterId);
  /** Get a PH setting by getter ID. */
  Q_INVOKABLE void phGetter (int printheadId, bool getSavedValue,
                             int getterId);
  /** Reset settings for all printheads on the controller. */
  Q_INVOKABLE void jcResetSettingsAllPrintheads ();
  /** Reset all settings for one printhead. */
  Q_INVOKABLE void phResetAllSettings (int printheadId);
  /** Reboot all printheads on the controller. */
  Q_INVOKABLE void jcRebootAllPrintheads ();
  /** Reboot one printhead. */
  Q_INVOKABLE void phReboot (int printheadId);
  /** Reset the Jetting Controller software. */
  Q_INVOKABLE void jcResetControllerSoftware ();
  /** Restart the Jetting Controller. */
  Q_INVOKABLE void jcRestart ();
  /** Shut down the Jetting Controller. */
  Q_INVOKABLE void jcShutdown ();
  /** Save settings for all printheads on the controller. */
  Q_INVOKABLE void jcSaveAllPrintheadSettings ();
  /** Save settings for one printhead. */
  Q_INVOKABLE void phSaveSettings (int printheadId);

  /* -- Imaging (m/n) commands --------------------------------------- */

  /** Start imaging at the given speed. */
  Q_INVOKABLE void imagingStart (double speed);
  /** Stop imaging. */
  Q_INVOKABLE void imagingStop ();
  /** Send image mask start (front of formatted message, 180 chars). */
  Q_INVOKABLE void imageMaskStart (const QString &mask);
  /** Send image mask end (triggers transmission to JC). */
  Q_INVOKABLE void imageMaskEnd (const QString &tail);
  /** Send duty cycle mask start (hex, 2 chars per PH). */
  Q_INVOKABLE void dutyCycleMaskStart (const QString &mask);
  /** Send duty cycle mask end (triggers transmission to JC). */
  Q_INVOKABLE void dutyCycleMaskEnd (const QString &tail);
  /** Check remaining image line count. */
  Q_INVOKABLE void imageCount ();

signals:
  void listeningChanged ();
  void connectedChanged ();
  void errorOccurred (const QString &error);
  void statusMessage (const QString &message);
  void jcVersionReceived ();
  void phVersionReceived (int controllerId, int printheadId,
                          const QString &mcuFirmwareVersion,
                          const QString &mcuHardwareVersion,
                          const QString &mcuFirmwareVariant,
                          const QString &fpgaFirmwareVersion,
                          const QString &fpgaHardwareVersion,
                          const QString &bootloaderVersion);

  /* CN_ response signals */
  void jettingAllOnResult (int controllerId, bool success);
  void jettingOnResult (int controllerId, bool success);
  void jettingOffResult (int controllerId, bool success);
  void phJettingOnResult (int controllerId, int printheadId, bool success);
  void phJettingOffResult (int controllerId, int printheadId, bool success);
  void jcIdLedOnResult (int controllerId, bool success);
  void jcIdLedOffResult (int controllerId, bool success);
  void phIdLedOnResult (int controllerId, int printheadId, bool success);
  void phIdLedOffResult (int controllerId, int printheadId, bool success);
  void jcCalibrationResult (int controllerId, bool success);
  void phCalibrationResult (int controllerId, int printheadId, bool success);
  void phCalibrationDataReceived (int controllerId, int printheadId,
                                  const QVariantList &frequencies);
  void phCalibrationRawDataReceived (int controllerId, int printheadId,
                                     const QVariantList &frequencies);
  void phCalibratedBaseFrequencyReceived (int controllerId, int printheadId,
                                          double baseFrequency,
                                          double activeBaseFrequency);
  void jcStatusMessagingStartResult (int controllerId, int statusLevel,
                                     int sendIntervalMs, bool success);
  void jcStatusMessagingStopResult (int controllerId, bool success);
  void phStatusMessagingStartResult (int controllerId, int statusLevel,
                                     int sendIntervalMs, bool success);
  void phStatusMessagingStopResult (int controllerId, bool success);
  void jcResetFaultCodesResult (int controllerId, bool success);
  void phResetFaultCodesResult (int controllerId, int printheadId,
                                bool success);
  void phNozzlesDisabledResult (int controllerId, int printheadId,
                                bool success);

  /* CF_ response signals */
  void phSetIdResult (int controllerId, int printheadId, bool success);
  void phDeassignIdResult (int controllerId, bool success);
  void jcSetJettingParamsResult (int controllerId, int dutyCycle, int pwmFreq,
                                 int drive, int nozzleDriveFreq,
                                 int nozzleDriveDutyCycle,
                                 Xpl2Protocol::JettingParamsResult result);
  void phSetJettingParamsResult (int controllerId, int printheadId,
                                 int dutyCycle, int pwmFreq, int drive,
                                 int nozzleDriveFreq, int nozzleDriveDutyCycle,
                                 Xpl2Protocol::JettingParamsResult result);
  void phGetJettingParamsResult (int controllerId, int printheadId,
                                 int dutyCycle, int pwmFreq, int drive,
                                 int nozzleDriveFreq, int nozzleDriveDutyCycle,
                                 Xpl2Protocol::JettingParamsResult result);
  void jcSaveCalibrationResult (int controllerId, bool success);
  void phSaveCalibrationResult (int controllerId, int printheadId,
                                bool success);
  void jcResetCalibrationResult (int controllerId, bool success);
  void phResetCalibrationResult (int controllerId, int printheadId,
                                 bool success);
  void jcSetPurgeSettingsResult (int controllerId, int purgeIntervalMs,
                                 int purgeTimeMs, bool success);
  void jcSwitchOffPurgeResult (int controllerId, bool success);
  void jcSetterResult (int controllerId, bool saveNewValue, int setterId,
                       const QString &newValue,
                       Xpl2Protocol::SetterResult result);
  void phSetterResult (int controllerId, int printheadId, bool saveNewValue,
                       int setterId, const QString &newValue,
                       Xpl2Protocol::SetterResult result);
  void jcGetterResult (int controllerId, bool savedValue, int getterId,
                       const QString &currentValue, bool success);
  void phGetterResult (int controllerId, int printheadId, bool savedValue,
                       int getterId, const QString &currentValue,
                       bool success);
  void jcResetSettingsAllPrintheadsResult (int controllerId, bool success);
  void phResetAllSettingsResult (int controllerId, int printheadId,
                                 bool success);
  void jcRebootAllPrintheadsResult (int controllerId, bool success);
  void phRebootResult (int controllerId, int printheadId, bool success);
  void jcResetControllerSoftwareResult (int controllerId, bool success);
  void jcRestartResult (int controllerId, bool success);
  void jcShutdownResult (int controllerId, bool success);
  void jcSaveAllPrintheadSettingsResult (int controllerId, bool success);
  void phSaveSettingsResult (int controllerId, int printheadId, bool success);

  /* EV_ event signals */
  void shuttingDown ();
  void phConnectionChanged (int controllerId, int printheadId, bool connected);
  void jcErrorCode (int controllerId, int errorCode,
                    const QStringList &params);
  void phErrorCode (int controllerId, int printheadId, int errorCode,
                    const QStringList &params);
  void imgErrorCode (int controllerId, int errorCode,
                     const QStringList &params);
  void statusErrorCode (int controllerId, int errorCode,
                        const QStringList &params);
  void jcStatusReceived (const Xpl2JcStatus &status);
  void phStatusReceived (const Xpl2PhStatus &status);

  /* Imaging response signals */
  void imagingReply (int imageLines);
  void imagingStopResult (bool success);

private slots:
  void onNewConnection ();
  void onSocketDisconnected ();
  void onSocketMessageReady ();
  void onSocketError (QAbstractSocket::SocketError error);

private:
  void setupServer (QTcpServer &server, quint16 port);
  QTcpSocket *&socketForServer (QTcpServer *server);
  void sendCommand (QTcpSocket *socket, const QByteArray &command,
                    const QVariantList &params = {});
  void dispatchCommandMessage (const Xpl2Protocol::ParsedMessage &msg);
  void dispatchImagingMessage (const Xpl2Protocol::ParsedMessage &msg);
  void dispatchStatusMessage (const Xpl2Protocol::ParsedMessage &msg);
  void handleKaPing (QTcpSocket *socket);
  void handleGsJcVersion (const QVariantList &params);
  void handleGsPhVersion (const QVariantList &params);
  enum class ResponseShape
  {
    JcSuccess,
    PhSuccess,
    CalData,
    BaseFreq,
    StatusStart,
    PurgeSettings,
    JcJettingParams,
    PhJettingParams,
    JcSetter,
    PhSetter,
    JcGetter,
    PhGetter,
    PhConnectionChanged,
    ErrorCode,
    PhErrorCode
  };

  struct ResponseEntry
  {
    ResponseShape shape;
    int minParams;
    std::function<void (Xpl2Client *, const QVariantList &)> emitter;
  };

  static const QHash<QByteArray, ResponseEntry> s_responseTable;

  bool dispatchResponse (const QByteArray &command, const QVariantList &params,
                         const QTcpSocket *socket);
  void handleEvStatusMsgJc (const QVariantList &params);
  void handleEvStatusMsgPh (const QVariantList &params);
  void updateConnectedState ();
  QString logTag (const QTcpSocket *socket) const;

  QTcpServer m_commandServer;
  QTcpServer m_imagingServer;
  QTcpServer m_statusServer;
  QTcpSocket *m_commandSocket = nullptr;
  QTcpSocket *m_imagingSocket = nullptr;
  QTcpSocket *m_statusSocket = nullptr;
  quint16 m_commandPort = 9110;
  quint16 m_imagingPort = 9111;
  quint16 m_statusPort = 9112;
  bool m_listening = false;
  bool m_connected = false;
  static bool s_wireDebug;
  int m_controllerId = 0;
  QString m_firmwareVersion;
  QString m_hardwareVersion;
  int m_printheadCount = 0;
};