mirror of
https://github.com/cagnulein/qdomyos-zwift.git
synced 2026-02-18 00:17:41 +01:00
Compare commits
33 Commits
dircon_nat
...
dircon-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26ce3da489 | ||
|
|
fa5677d550 | ||
|
|
489dd20cc7 | ||
|
|
64da80add0 | ||
|
|
090bb8ec95 | ||
|
|
0216ce1170 | ||
|
|
0f2c9a7c6b | ||
|
|
882b3779a0 | ||
|
|
26430cf970 | ||
|
|
388fedb727 | ||
|
|
4b9ce8a74f | ||
|
|
8e39da88a2 | ||
|
|
b251b23d78 | ||
|
|
bbc930dc7c | ||
|
|
00d1a691b5 | ||
|
|
2a3a08380a | ||
|
|
064dfbf5fb | ||
|
|
8fac949eba | ||
|
|
9921796b6c | ||
|
|
90d5db2e92 | ||
|
|
699695e4fd | ||
|
|
ac7b5a136f | ||
|
|
e408d89847 | ||
|
|
9c25c90758 | ||
|
|
51183bd6ed | ||
|
|
9d924e7199 | ||
|
|
ee4ec2df89 | ||
|
|
d36c16f87f | ||
|
|
c5ee3355ac | ||
|
|
1d6b7c0db1 | ||
|
|
4ae7550144 | ||
|
|
f502ccf2a5 | ||
|
|
c29a5d394c |
@@ -41,6 +41,8 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc
|
||||
this->innerTemplateManager =
|
||||
TemplateInfoSenderBuilder::getInstance(innerId, QStringList({QStringLiteral(":/inner_templates/")}), this);
|
||||
|
||||
serialdircon.open("/dev/ttyUSB0", 1000);
|
||||
|
||||
#ifdef TEST
|
||||
schwinnIC4Bike = (schwinnic4bike *)new bike();
|
||||
userTemplateManager->start(schwinnIC4Bike);
|
||||
@@ -901,8 +903,8 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) {
|
||||
(b.name().toUpper().startsWith("MKSM")) || // MKSM3600036
|
||||
(b.name().toUpper().startsWith("WAHOO KICKR")) || (b.name().toUpper().startsWith("B94")) ||
|
||||
(b.name().toUpper().startsWith("STAGES BIKE")) || (b.name().toUpper().startsWith("SUITO")) ||
|
||||
(b.name().toUpper().startsWith("D2RIDE")) ||
|
||||
(b.name().toUpper().startsWith("DIRETO XR")) || (b.name().toUpper().startsWith("SMB1"))) &&
|
||||
(b.name().toUpper().startsWith("D2RIDE")) || (b.name().toUpper().startsWith("DIRETO XR")) ||
|
||||
(b.name().toUpper().startsWith("SMB1"))) &&
|
||||
!ftmsBike && !snodeBike && !fitPlusBike && !stagesBike && filter) {
|
||||
discoveryAgent->stop();
|
||||
ftmsBike = new ftmsbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain);
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
#include "wahookickrsnapbike.h"
|
||||
#include "yesoulbike.h"
|
||||
|
||||
#include "serialdircon.h"
|
||||
|
||||
class bluetooth : public QObject, public SignalHandler {
|
||||
|
||||
Q_OBJECT
|
||||
@@ -217,6 +219,8 @@ class bluetooth : public QObject, public SignalHandler {
|
||||
bool eliteSterzoSmartAvaiable();
|
||||
bool fitmetria_fanfit_isconnected(QString name);
|
||||
|
||||
serialDircon serialdircon;
|
||||
|
||||
signals:
|
||||
void deviceConnected(QBluetoothDeviceInfo b);
|
||||
void deviceFound(QString name);
|
||||
|
||||
@@ -2,6 +2,9 @@ QT += bluetooth widgets xml positioning quick networkauth websockets
|
||||
|
||||
QT+= charts
|
||||
|
||||
windows: QT += serialport
|
||||
unix:!android: QT += serialport
|
||||
|
||||
unix:android: QT += androidextras gui-private
|
||||
qtHaveModule(httpserver) {
|
||||
QT += httpserver
|
||||
@@ -169,6 +172,7 @@ SOURCES += \
|
||||
rower.cpp \
|
||||
schwinnic4bike.cpp \
|
||||
screencapture.cpp \
|
||||
serialdircon.cpp \
|
||||
sessionline.cpp \
|
||||
shuaa5treadmill.cpp \
|
||||
signalhandler.cpp \
|
||||
@@ -553,6 +557,7 @@ HEADERS += \
|
||||
rower.h \
|
||||
schwinnic4bike.h \
|
||||
screencapture.h \
|
||||
serialdircon.h \
|
||||
sessionline.h \
|
||||
shuaa5treadmill.h \
|
||||
signalhandler.h \
|
||||
|
||||
187
src/serialdircon.cpp
Normal file
187
src/serialdircon.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
#include "serialdircon.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTime>
|
||||
|
||||
serialDircon::serialDircon(QObject *parent) : QThread(parent) {}
|
||||
|
||||
serialDircon::~serialDircon() {
|
||||
m_mutex.lock();
|
||||
m_quit = true;
|
||||
m_mutex.unlock();
|
||||
wait();
|
||||
}
|
||||
|
||||
void serialDircon::open(const QString &portName, int waitTimeout) {
|
||||
const QMutexLocker locker(&m_mutex);
|
||||
m_portName = portName;
|
||||
m_waitTimeout = waitTimeout;
|
||||
if (!isRunning())
|
||||
start();
|
||||
}
|
||||
|
||||
void serialDircon::write(const uint8_t *buffer, int len, QString info) {
|
||||
qDebug() << "serial >> " << QByteArray((const char *)buffer, len).toHex(' ') << "//" << info;
|
||||
qint64 o = serial.write(QByteArray((const char *)buffer, len));
|
||||
qDebug() << "serial byte written" << o;
|
||||
}
|
||||
|
||||
void serialDircon::run() {
|
||||
|
||||
const uint8_t init0[] = {0x02, 0x81, 0x01, 0x00, 0x80, 0x03};
|
||||
const uint8_t init1[] = {0x02, 0x01, 0x01, 0x00, 0x00, 0x03};
|
||||
const uint8_t init2[] = {0x02, 0x01, 0x10, 0x03, 0x0C, 0x01, 0x2A, 0x00, 0x01, 0x01,
|
||||
0x00, 0x00, 0x00, 0x08, 0x01, 0x07, 0x10, 0x03, 0x28, 0x03};
|
||||
const uint8_t init3[] = {0x02, 0x68, 0x06, 0x26, 0xB4, 0x6F, 0x2D, 0x00, 0x04, 0x4b, 0x34, 0x32, 0x32, 0x30, 0x35,
|
||||
0x30, 0x30, 0x30, 0x31, 0x38, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x03};
|
||||
const uint8_t init4[] = {0x02, 0x68, 0x04, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x03};
|
||||
const uint8_t init5[] = {0x02, 0x68, 0x01, 0x10, 0x03, 0x00, 0x08, 0x00, 0x62, 0x03};
|
||||
const uint8_t init6[] = {0x02, 0x68, 0x10, 0x02, 0x10, 0x03, 0x00, 0x0A, 0x00, 0x63, 0x03};
|
||||
const uint8_t init7[] = {0x02, 0x68, 0x10, 0x02, 0x10, 0x03, 0x00, 0x14, 0x00, 0x7D, 0x03};
|
||||
const uint8_t init8[] = {0x02, 0x68, 0x10, 0x02, 0x10, 0x03, 0x00, 0x17, 0x00, 0x7E, 0x03};
|
||||
const uint8_t init9[] = {0x02, 0x68, 0x50, 0x01, 0x00, 0x39, 0x03};
|
||||
const uint8_t init10[] = {0x02, 0x68, 0x10, 0x03, 0x01, 0x00, 0x6A, 0x03};
|
||||
const uint8_t init11[] = {0x02, 0x68, 0x20, 0x01, 0x00, 0x49, 0x03};
|
||||
|
||||
const uint8_t run1[] = {0x02, 0x68, 0x04, 0x09, 0x08, 0x00, 0x17, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x10, 0x03, 0x78, 0x03};
|
||||
|
||||
// const uint8_t run1[] = {0x02, 0x68, 0x04, 0x09, 0x08, 0x00, 0x17, 0x00, 0x01, 0x01, 0x00, 0x00, 0x13, 0x69,
|
||||
// 0x03}; const uint8_t run2[] = {0x02, 0x68, 0x50, 0x01, 0x00, 0x39, 0x03, 0x02, 0x68, 0x50, 0x01, 0x00, 0x39,
|
||||
// 0x03};
|
||||
|
||||
const uint8_t force[] = {0x02, 0xe8, 0x60, 0x09, 0x0f, 0x00, 0x11, 0x00, 0x00, 0xd7, 0xff, 0x28, 0x33, 0xac, 0x03};
|
||||
|
||||
bool initRequest = true;
|
||||
uint8_t phase = 0;
|
||||
|
||||
bool currentPortNameChanged = false;
|
||||
|
||||
m_mutex.lock();
|
||||
|
||||
QString currentPortName;
|
||||
if (currentPortName != m_portName) {
|
||||
currentPortName = m_portName;
|
||||
currentPortNameChanged = true;
|
||||
}
|
||||
|
||||
int currentWaitTimeout = m_waitTimeout;
|
||||
m_mutex.unlock();
|
||||
|
||||
while (!m_quit) {
|
||||
if (currentPortNameChanged) {
|
||||
serial.close();
|
||||
serial.setPortName(currentPortName);
|
||||
serial.setBaudRate(QSerialPort::Baud115200);
|
||||
|
||||
if (!serial.open(QIODevice::ReadWrite)) {
|
||||
qDebug() << tr("Can't open %1, error code %2").arg(m_portName).arg(serial.error());
|
||||
emit error(tr("Can't open %1, error code %2").arg(m_portName).arg(serial.error()));
|
||||
return;
|
||||
}
|
||||
qDebug() << "Serial port" << currentPortName << "opened";
|
||||
}
|
||||
|
||||
if (serial.isOpen()) {
|
||||
if (initRequest) {
|
||||
switch (phase) {
|
||||
case 0:
|
||||
write(init0, sizeof(init0), "init0");
|
||||
break;
|
||||
case 1:
|
||||
write(init1, sizeof(init1), "init1");
|
||||
break;
|
||||
case 2:
|
||||
write(init2, sizeof(init2), "init2");
|
||||
break;
|
||||
case 3:
|
||||
write(init3, sizeof(init3), "init3");
|
||||
break;
|
||||
case 4:
|
||||
write(init4, sizeof(init4), "init4");
|
||||
break;
|
||||
case 5:
|
||||
write(init5, sizeof(init5), "init5");
|
||||
break;
|
||||
case 6:
|
||||
write(init6, sizeof(init6), "init6");
|
||||
break;
|
||||
case 7:
|
||||
write(init7, sizeof(init7), "init7");
|
||||
break;
|
||||
case 8:
|
||||
write(init8, sizeof(init8), "init8");
|
||||
break;
|
||||
case 9:
|
||||
write(init9, sizeof(init9), "init9");
|
||||
break;
|
||||
case 10:
|
||||
write(init10, sizeof(init10), "init10");
|
||||
break;
|
||||
case 11:
|
||||
write(init11, sizeof(init11), "init11");
|
||||
break;
|
||||
default:
|
||||
initRequest = false;
|
||||
phase = 0;
|
||||
}
|
||||
}
|
||||
if (!initRequest) { /*
|
||||
switch (phase) {
|
||||
case 0:*/
|
||||
write(run1, sizeof(run1), "run1");
|
||||
// break;
|
||||
/*case 1:
|
||||
write(run2, sizeof(run2), "run2");
|
||||
break;*/
|
||||
/*case 1:
|
||||
write(force, sizeof(force), "force");
|
||||
break;
|
||||
default:
|
||||
phase = 0;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
if (serial.waitForReadyRead(currentWaitTimeout)) {
|
||||
QByteArray requestData = serial.readAll();
|
||||
while (serial.waitForReadyRead(1))
|
||||
requestData += serial.readAll();
|
||||
qDebug() << "serial << " << requestData.toHex(' ');
|
||||
|
||||
if (requestData.at(0) == 0x02 && requestData.length() >= 6) {
|
||||
if (!initRequest || (initRequest && phase != 9))
|
||||
phase++;
|
||||
if (requestData.at(0) == init1[0] && requestData.at(1) == init1[1] && requestData.at(2) == init1[2] &&
|
||||
requestData.at(3) == init1[3] && requestData.at(4) == init1[4] && requestData.at(5) == init1[5])
|
||||
write(init1, sizeof(init1), "init1");
|
||||
// 02 68 10 03 80 57 ....
|
||||
else if (requestData.at(0) == 0x02 && requestData.at(1) == 0x68 && requestData.at(2) == 0x10 &&
|
||||
requestData.at(3) == 0x03 && (uint8_t)requestData.at(4) == 0x80 && requestData.at(5) == 0x57 &&
|
||||
initRequest && phase == 9)
|
||||
phase = 10;
|
||||
}
|
||||
|
||||
if (requestData.at(0) == 0x02 && requestData.at(1) == 0x68 && requestData.at(2) == 0x50 &&
|
||||
requestData.at(3) == 0x0b && requestData.at(4) == 0x11 && requestData.length() >= 17) {
|
||||
uint16_t convertedData = (requestData.at(10) << 8) | ((uint8_t)requestData.at(9));
|
||||
double speed = ((double)convertedData) / 100.0;
|
||||
convertedData = (requestData.at(8) << 8) | ((uint8_t)requestData.at(7));
|
||||
double cadence = ((double)convertedData) / 2.0;
|
||||
uint16_t watt = (requestData.at(14) << 8) | ((uint8_t)requestData.at(13));
|
||||
|
||||
qDebug() << "Metrics FROM Serial: Speed" << speed << "Cadence" << cadence << "Watt" << watt;
|
||||
}
|
||||
}
|
||||
m_mutex.lock();
|
||||
if (currentPortName != m_portName) {
|
||||
currentPortName = m_portName;
|
||||
currentPortNameChanged = true;
|
||||
} else {
|
||||
currentPortNameChanged = false;
|
||||
}
|
||||
currentWaitTimeout = m_waitTimeout;
|
||||
m_mutex.unlock();
|
||||
}
|
||||
}
|
||||
34
src/serialdircon.h
Normal file
34
src/serialdircon.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef SERIALDIRCON_H
|
||||
#define SERIALDIRCON_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QSerialPort>
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
|
||||
class serialDircon : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit serialDircon(QObject *parent = nullptr);
|
||||
~serialDircon();
|
||||
|
||||
void open(const QString &portName, int waitTimeout);
|
||||
|
||||
signals:
|
||||
void request(const QString &s);
|
||||
void error(const QString &s);
|
||||
void timeout(const QString &s);
|
||||
|
||||
private:
|
||||
void run() override;
|
||||
void write(const uint8_t *buffer, int len, QString info);
|
||||
QSerialPort serial;
|
||||
|
||||
QString m_portName;
|
||||
int m_waitTimeout = 1000;
|
||||
QMutex m_mutex;
|
||||
bool m_quit = false;
|
||||
};
|
||||
|
||||
#endif // SERIALDIRCON_H
|
||||
Reference in New Issue
Block a user