22#if defined( Q_OS_ANDROID ) || defined( Q_OS_LINUX )
23#include <sys/socket.h>
32 mIODevice.reset( device );
42 return mIODevice.get();
57 , mTcpSocket( new QTcpSocket() )
59 connect( mTcpSocket, &QAbstractSocket::stateChanged,
this, &QgsTcpSocketSensor::socketStateChanged );
60 connect( mTcpSocket, qOverload<QAbstractSocket::SocketError>( &QAbstractSocket::errorOccurred ),
this, &QgsTcpSocketSensor::handleError );
72 return QLatin1String(
"tcp_socket" );
103 if ( mHostName.isEmpty() || mPort == 0 )
109 mTcpSocket->connectToHost( mHostName, mPort, QTcpSocket::ReadOnly );
117void QgsTcpSocketSensor::handleError( QAbstractSocket::SocketError error )
121 case QAbstractSocket::HostNotFoundError:
124 case QAbstractSocket::NetworkError:
125 mErrorString = tr(
"Attempt to read or write from socket returned an error" );
127 case QAbstractSocket::ConnectionRefusedError:
128 mErrorString = tr(
"The connection was refused by the remote host" );
131 mErrorString = tr(
"%1" ).arg( QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey( error ) );
138void QgsTcpSocketSensor::socketStateChanged(
const QAbstractSocket::SocketState socketState )
140 switch ( socketState )
142 case QAbstractSocket::ConnectedState:
147 case QAbstractSocket::UnconnectedState:
159 element.setAttribute( QStringLiteral(
"hostName" ), mHostName );
160 element.setAttribute( QStringLiteral(
"port" ), QString::number( mPort ) );
167 mHostName = element.attribute( QStringLiteral(
"hostName" ) );
168 mPort = element.attribute( QStringLiteral(
"port" ) ).toInt();
177 , mUdpSocket( std::make_unique<QUdpSocket>() )
178 , mBuffer( new QBuffer() )
180#if defined( Q_OS_ANDROID ) || defined( Q_OS_LINUX )
181 int sockfd = socket( AF_INET, SOCK_DGRAM, 0 );
183 setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR,
184 (
void * ) &optval,
sizeof( optval ) );
185 mUdpSocket->setSocketDescriptor( sockfd, QUdpSocket::UnconnectedState );
188 connect( mUdpSocket.get(), &QAbstractSocket::stateChanged,
this, &QgsUdpSocketSensor::socketStateChanged );
189 connect( mUdpSocket.get(), &QUdpSocket::readyRead,
this, [
this]()
192 while ( mUdpSocket->hasPendingDatagrams() )
194 datagram.resize( int( mUdpSocket->pendingDatagramSize() ) );
195 mUdpSocket->readDatagram( datagram.data(), datagram.size() );
197 mBuffer->buffer().clear();
199 mBuffer->write( datagram );
204 connect( mUdpSocket.get(), qOverload<QAbstractSocket::SocketError>( &QAbstractSocket::errorOccurred ),
this, &QgsUdpSocketSensor::handleError );
206 initIODevice( mBuffer );
216 return QLatin1String(
"udp_socket" );
247 if ( mHostName.isEmpty() || mPort == 0 )
253 mBuffer->open( QIODevice::ReadWrite );
254 mUdpSocket->bind( QHostAddress( mHostName ), mPort, QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint );
255 mUdpSocket->joinMulticastGroup( QHostAddress( mHostName ) );
264void QgsUdpSocketSensor::handleError( QAbstractSocket::SocketError error )
268 case QAbstractSocket::HostNotFoundError:
271 case QAbstractSocket::NetworkError:
272 mErrorString = tr(
"Attempt to read or write from socket returned an error" );
274 case QAbstractSocket::ConnectionRefusedError:
275 mErrorString = tr(
"The connection was refused by the remote host" );
278 mErrorString = tr(
"%1" ).arg( QMetaEnum::fromType<QAbstractSocket::SocketError>().valueToKey( error ) );
285void QgsUdpSocketSensor::socketStateChanged(
const QAbstractSocket::SocketState socketState )
287 switch ( socketState )
289 case QAbstractSocket::ConnectedState:
290 case QAbstractSocket::BoundState:
295 case QAbstractSocket::UnconnectedState:
307 element.setAttribute( QStringLiteral(
"hostName" ), mHostName );
308 element.setAttribute( QStringLiteral(
"port" ), QString::number( mPort ) );
315 mHostName = element.attribute( QStringLiteral(
"hostName" ) );
316 mPort = element.attribute( QStringLiteral(
"port" ) ).toInt();
323#if defined( HAVE_QTSERIALPORT )
324QgsSerialPortSensor::QgsSerialPortSensor( QObject *parent )
326 , mSerialPort( new QSerialPort() )
328 connect( mSerialPort, qOverload<QSerialPort::SerialPortError>( &QSerialPort::errorOccurred ),
this, &QgsSerialPortSensor::handleError );
333QgsSerialPortSensor *QgsSerialPortSensor::create( QObject *parent )
335 return new QgsSerialPortSensor( parent );
338QString QgsSerialPortSensor::type()
const
340 return QLatin1String(
"serial_port" );
343QString QgsSerialPortSensor::portName()
const
348void QgsSerialPortSensor::setPortName(
const QString &portName )
350 if ( mPortName == portName )
353 mPortName = portName;
356QSerialPort::BaudRate QgsSerialPortSensor::baudRate()
const
361void QgsSerialPortSensor::setBaudRate(
const QSerialPort::BaudRate &baudRate )
363 if ( mBaudRate == baudRate )
366 mBaudRate = baudRate;
369QByteArray QgsSerialPortSensor::delimiter()
const
374void QgsSerialPortSensor::setDelimiter(
const QByteArray &delimiter )
376 if ( mDelimiter == delimiter )
379 mDelimiter = delimiter;
383void QgsSerialPortSensor::parseData()
385 if ( !mDelimiter.isEmpty() )
387 if ( mFirstDelimiterHit )
389 mDataBuffer += mSerialPort->readAll();
390 const auto lastIndex = mDataBuffer.lastIndexOf( mDelimiter );
391 if ( lastIndex > -1 )
394 data.
lastValue = mDataBuffer.mid( 0, lastIndex );
395 mDataBuffer = mDataBuffer.mid( lastIndex + mDelimiter.size() );
402 QByteArray data = mSerialPort->readAll();
403 const auto lastIndex = data.lastIndexOf( mDelimiter );
404 if ( lastIndex > -1 )
406 mFirstDelimiterHit =
true;
407 mDataBuffer = data.mid( lastIndex + mDelimiter.size() );
420void QgsSerialPortSensor::handleConnect()
422 mSerialPort->setPortName( mPortName );
423 mSerialPort->setBaudRate( mBaudRate );
424 mFirstDelimiterHit =
false;
426 if ( mSerialPort->open( QIODevice::ReadOnly ) )
436void QgsSerialPortSensor::handleDisconnect()
438 mSerialPort->close();
441void QgsSerialPortSensor::handleError( QSerialPort::SerialPortError error )
443 if ( error == QSerialPort::NoError )
450 case QSerialPort::DeviceNotFoundError:
451 mErrorString = tr(
"Could not find the serial port device" );
453 case QSerialPort::ReadError:
454 mErrorString = tr(
"Attempt to read from the serial port returned an error" );
456 case QSerialPort::PermissionError:
457 mErrorString = tr(
"The connection was refused due to not having enough permission" );
460 mErrorString = tr(
"%1" ).arg( QMetaEnum::fromType<QSerialPort::SerialPortError>().valueToKey( error ) );
464 emit errorOccurred( mErrorString );
467bool QgsSerialPortSensor::writePropertiesToElement( QDomElement &element, QDomDocument & )
const
469 element.setAttribute( QStringLiteral(
"portName" ), mPortName );
470 element.setAttribute( QStringLiteral(
"baudRate" ),
static_cast<int>( mBaudRate ) );
471 element.setAttribute( QStringLiteral(
"delimiter" ), QString( mDelimiter ) );
475bool QgsSerialPortSensor::readPropertiesFromElement(
const QDomElement &element,
const QDomDocument & )
477 mPortName = element.attribute( QStringLiteral(
"portName" ) );
478 mBaudRate =
static_cast< QSerialPort::BaudRate
>( element.attribute( QStringLiteral(
"baudRate" ) ).toInt() );
479 mDelimiter = element.attribute( QStringLiteral(
"delimiter" ) ).toLocal8Bit();
@ Connected
Device is successfully connected.
@ Disconnected
Device is disconnected.
QgsAbstractSensor::SensorData data() const
Returns the latest captured data from the sensor.
void setStatus(Qgis::DeviceConnectionStatus status)
Sets the current sensor status.
void errorOccurred(const QString &errorString)
Emitted when an error has occurred. The errorString describes the error.
void setData(const QgsAbstractSensor::SensorData &data)
Sets the latest captured data from the sensor.
An abstract class QIODevice-based sensor classes.
void initIODevice(QIODevice *device)
Initiates the I/O device.
virtual void parseData()
Parses the data read from the device when available.
QIODevice * iODevice() const
Returns the I/O device.
~QgsIODeviceSensor() override
A TCP socket sensor class.
QgsTcpSocketSensor(QObject *parent=nullptr)
Constructor for a TCP socket sensor, bound to the specified parent.
void setHostName(const QString &hostName)
Sets the host name the socket connects to.
int port() const
Returns the port the socket connects to.
void handleConnect() override
Handles the connection to the sensor.
QString type() const override
Returns the sensor type.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document) const override
Write specific sensor type properties into a DOM element.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document) override
Restores specific sensor type properties from a DOM element.
void handleDisconnect() override
Handles the disconnection from the sensor.
static QgsTcpSocketSensor * create(QObject *parent)
Returns a new TCP socket sensor.
void setPort(int port)
Sets the port the socket connects to.
QString hostName() const
Returns the host name the socket connects to.
A UDP socket sensor class.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document) override
Restores specific sensor type properties from a DOM element.
static QgsUdpSocketSensor * create(QObject *parent)
Returns a new UDP socket sensor.
QString type() const override
Returns the sensor type.
void handleDisconnect() override
Handles the disconnection from the sensor.
QgsUdpSocketSensor(QObject *parent=nullptr)
Constructor for a UDP socket sensor, bound to the specified parent.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document) const override
Write specific sensor type properties into a DOM element.
void setHostName(const QString &hostName)
Sets the host name the socket connects to.
int port() const
Returns the port the socket connects to.
void handleConnect() override
Handles the connection to the sensor.
void setPort(int port)
Sets the port the socket connects to.
QString hostName() const
Returns the host name the socket connects to.
Contains details of a sensor data capture.
QVariant lastValue
Last captured sensor value stored as a QVariant.
QDateTime lastTimestamp
Timestamp of last captured sensor value.