bluos: Add Qt6 support

This commit is contained in:
Simon Stürz 2025-08-07 15:08:47 +02:00
parent 68d8cf1c40
commit 259e0c7d1d
5 changed files with 77 additions and 75 deletions

View File

@ -38,9 +38,9 @@
BluOS::BluOS(NetworkAccessManager *networkmanager, QHostAddress hostAddress, int port, QObject *parent) :
QObject(parent),
m_networkManager(networkmanager),
m_hostAddress(hostAddress),
m_port(port),
m_networkManager(networkmanager)
m_port(port)
{
}
@ -121,7 +121,7 @@ QUuid BluOS::setVolume(uint volume)
int volume = 0;
bool mute = false;
if (xml.readNextStartElement()) {
if (xml.name() == "volume") {
if (xml.name() == QString("volume")) {
if(xml.attributes().hasAttribute("mute")) {
mute = xml.attributes().value("mute").toInt();
}
@ -277,7 +277,7 @@ QUuid BluOS::setRepeat(RepeatMode repeatMode)
return;
}
if (xml.readNextStartElement()) {
if (xml.name() == "playlist") {
if (xml.name() == QString("playlist")) {
if (xml.attributes().hasAttribute("repeat")) {
RepeatMode mode = RepeatMode(xml.attributes().value("repeat").toInt());
emit repeatModeReceived(mode);
@ -323,9 +323,9 @@ QUuid BluOS::listPresets()
}
QList<Preset> presetList;
if (xml.readNextStartElement()) {
if (xml.name() == "presets") {
if (xml.name() == QString("presets")) {
while(xml.readNextStartElement()){
if(xml.name() == "preset"){
if(xml.name() == QString("preset")){
Preset preset;
if (xml.attributes().hasAttribute("id")) {
preset.Id = xml.attributes().value("id").toInt();
@ -417,9 +417,9 @@ QUuid BluOS::getSources()
}
QList<Source> sourceList;
if (xml.readNextStartElement()) {
if (xml.name() == "browse") {
if (xml.name() == QString("browse")) {
while(xml.readNextStartElement()){
if(xml.name() == "item"){
if(xml.name() == QString("item")){
Source source;
if (xml.attributes().hasAttribute("text")) {
source.Text = xml.attributes().value("text").toString();
@ -483,9 +483,9 @@ QUuid BluOS::browseSource(const QString &key)
}
QList<Source> sourceList;
if (xml.readNextStartElement()) {
if (xml.name() == "browse") {
if (xml.name() == QString("browse")) {
while(xml.readNextStartElement()){
if(xml.name() == "item"){
if(xml.name() == QString("item")){
Source source;
if (xml.attributes().hasAttribute("text")) {
source.Text = xml.attributes().value("text").toString();
@ -648,23 +648,23 @@ bool BluOS::parseState(const QByteArray &state)
StatusResponse statusResponse;
if (xml.readNextStartElement()) {
if (xml.name() == "status") {
if (xml.name() == QString("status")) {
while(xml.readNextStartElement()){
if(xml.name() == "artist"){
if(xml.name() == QString("artist")){
statusResponse.Artist = xml.readElementText();
} else if(xml.name() == "album"){
} else if(xml.name() == QString("album")){
statusResponse.Album = xml.readElementText();
} else if(xml.name() == "name"){
} else if(xml.name() == QString("name")){
statusResponse.Name = xml.readElementText();
} else if(xml.name() == "service"){
} else if(xml.name() == QString("service")){
statusResponse.Service = xml.readElementText();
} else if(xml.name() == "serviceIcon"){
} else if(xml.name() == QString("serviceIcon")){
statusResponse.ServiceIcon = xml.readElementText();
} else if(xml.name() == "shuffle"){
} else if(xml.name() == QString("shuffle")){
statusResponse.Shuffle = xml.readElementText().toInt();
} else if(xml.name() == "repeat"){
} else if(xml.name() == QString("repeat")){
statusResponse.Shuffle = xml.readElementText().toInt();
} else if(xml.name() == "state"){
} else if(xml.name() == QString("state")){
QString playback = xml.readElementText();
if (playback == "play") {
statusResponse.State = PlaybackState::Playing;
@ -680,15 +680,15 @@ bool BluOS::parseState(const QByteArray &state)
statusResponse.State = PlaybackState::Stopped;
qCWarning(dcBluOS()) << "State response, unhandled playback mode" << playback;
}
} else if(xml.name() == "volume"){
} else if(xml.name() == QString("volume")){
statusResponse.Volume = xml.readElementText().toInt();
} else if(xml.name() == "mute"){
} else if(xml.name() == QString("mute")){
statusResponse.Mute = xml.readElementText().toInt();
} else if(xml.name() == "image") {
} else if(xml.name() == QString("image")) {
statusResponse.Image = xml.readElementText();
} else if(xml.name() == "title1") {
} else if(xml.name() == QString("title1")) {
statusResponse.Title = xml.readElementText();
} else if(xml.name() == "group") {
} else if(xml.name() == QString("group")) {
statusResponse.Group = xml.readElementText();
} else {
xml.skipCurrentElement();

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -31,13 +31,13 @@
#ifndef BLUOS_H
#define BLUOS_H
#include <QObject>
#include <QTimer>
#include <QHostAddress>
#include <QUuid>
#include <QTimer>
#include <QObject>
#include <QHostAddress>
#include "network/networkaccessmanager.h"
#include "integrations/thing.h"
#include <integrations/thing.h>
#include <network/networkaccessmanager.h>
class BluOS : public QObject
{
@ -67,20 +67,20 @@ public:
};
struct StatusResponse {
QString Album;
QString Artist;
QString Name;
QString Title;
QString Service;
QUrl ServiceIcon;
PlaybackState State;
QUrl StationUrl;
int Volume;
bool Mute;
RepeatMode Repeat;
bool Shuffle;
QUrl Image;
QString Group;
QString Album;
QString Artist;
QString Name;
QString Title;
QString Service;
QUrl ServiceIcon;
PlaybackState State;
QUrl StationUrl;
int Volume;
bool Mute;
RepeatMode Repeat;
bool Shuffle;
QUrl Image;
QString Group;
};
struct Preset {
@ -98,6 +98,7 @@ public:
};
explicit BluOS(NetworkAccessManager *networkManager, QHostAddress hostAddress, int port, QObject *parent = nullptr);
int port();
QHostAddress hostAddress();
@ -130,24 +131,24 @@ public:
QUuid removeGroupPlayer(QHostAddress address, int port);
private:
NetworkAccessManager *m_networkManager = nullptr;
QHostAddress m_hostAddress;
int m_port;
NetworkAccessManager *m_networkManager = nullptr;
QUuid playBackControl(PlaybackCommand command);
bool parseState(const QByteArray &state);
signals:
void connectionChanged(bool connected);
void actionExecuted(QUuid actionId, bool success);
void actionExecuted(const QUuid &actionId, bool success);
void statusReceived(const StatusResponse &status);
void statusReceived(const BluOS::StatusResponse &status);
void volumeReceived(int volume, bool mute);
void shuffleStateReceived(bool state);
void repeatModeReceived(RepeatMode mode);
void repeatModeReceived(BluOS::RepeatMode mode);
void presetsReceived(QUuid requestId, const QList<Preset> &presets);
void sourcesReceived(QUuid requestId, const QList<Source> &sources);
void browseResultReceived(QUuid requestId, const QList<Source> &sources);
void presetsReceived(const QUuid &requestId, const QList<BluOS::Preset> &presets);
void sourcesReceived(const QUuid &requestId, const QList<BluOS::Source> &sources);
void browseResultReceived(const QUuid &requestId, const QList<BluOS::Source> &sources);
};
#endif // BLUOS_H

View File

@ -1,6 +1,6 @@
include(../plugins.pri)
QT += network
QT *= network
SOURCES += \
integrationpluginbluos.cpp \

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -31,10 +31,10 @@
#include "integrationpluginbluos.h"
#include "plugininfo.h"
#include "integrations/thing.h"
#include "network/networkaccessmanager.h"
#include "types/mediabrowseritem.h"
#include "types/browseritem.h"
#include <integrations/thing.h>
#include <types/mediabrowseritem.h>
#include <types/browseritem.h>
#include <QDebug>
#include <QStringList>
@ -158,42 +158,42 @@ void IntegrationPluginBluOS::executeAction(ThingActionInfo *info)
qCWarning(dcBluOS()) << "Unhandled Playback mode";
}
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerPlayActionTypeId) {
QUuid requestId = bluos->play();
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerPauseActionTypeId) {
QUuid requestId = bluos->pause();
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerStopActionTypeId) {
QUuid requestId = bluos->stop();
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerSkipNextActionTypeId) {
QUuid requestId = bluos->skip();
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerSkipBackActionTypeId) {
QUuid requestId = bluos->back();
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerVolumeActionTypeId) {
uint volume = action.param(bluosPlayerVolumeActionVolumeParamTypeId).value().toUInt();
QUuid requestId = bluos->setVolume(volume);
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerMuteActionTypeId) {
bool mute = action.param(bluosPlayerMuteActionMuteParamTypeId).value().toBool();
QUuid requestId = bluos->setMute(mute);
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerShuffleActionTypeId) {
bool shuffle = action.param(bluosPlayerShuffleActionShuffleParamTypeId).value().toBool();
QUuid requestId = bluos->setShuffle(shuffle);
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerRepeatActionTypeId) {
QString repeat = action.param(bluosPlayerRepeatActionRepeatParamTypeId).value().toString();
QUuid requestId;
@ -207,17 +207,17 @@ void IntegrationPluginBluOS::executeAction(ThingActionInfo *info)
qCWarning(dcBluOS()) << "Unhandled Repeat Mode";
}
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerIncreaseVolumeActionTypeId) {
uint step = action.param(bluosPlayerIncreaseVolumeActionStepParamTypeId).value().toUInt();
QUuid requestId = bluos->setVolume(qMin<uint>(100, thing->stateValue(bluosPlayerVolumeStateTypeId).toUInt() + step));
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else if (action.actionTypeId() == bluosPlayerDecreaseVolumeActionTypeId) {
uint step = action.param(bluosPlayerDecreaseVolumeActionStepParamTypeId).value().toUInt();
QUuid requestId = bluos->setVolume(qMax<uint>(0, thing->stateValue(bluosPlayerVolumeStateTypeId).toUInt() - step));
m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [this, requestId] {m_asyncActions.remove(requestId);});
connect(info, &ThingActionInfo::aborted, this, [this, requestId] {m_asyncActions.remove(requestId);});
} else {
qCWarning(dcBluOS()) << "Execute Action, unhandled action type id" << action.actionTypeId();
return info->finish(Thing::ThingErrorThingClassNotFound);
@ -414,7 +414,7 @@ void IntegrationPluginBluOS::onActionExecuted(QUuid requestId, bool success)
} else {
info->finish(Thing::ThingErrorHardwareFailure);
}
m_pluginTimer->timeout(); // get a status update
emit m_pluginTimer->timeout(); // get a status update
}
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -33,10 +33,10 @@
#include "bluos.h"
#include "integrations/integrationplugin.h"
#include "platform/platformzeroconfcontroller.h"
#include "network/zeroconf/zeroconfservicebrowser.h"
#include "plugintimer.h"
#include <integrations/integrationplugin.h>
#include <platform/platformzeroconfcontroller.h>
#include <network/zeroconf/zeroconfservicebrowser.h>
#include <plugintimer.h>
#include <QUdpSocket>
#include <QNetworkAccessManager>
@ -86,5 +86,6 @@ private slots:
void onPresetsReceived(QUuid requestId, const QList<BluOS::Preset> &presets);
void onSourcesReceived(QUuid requestId, const QList<BluOS::Source> &sources);
void onBrowseResultReceived(QUuid requestId, const QList<BluOS::Source> &sources);
};
#endif // INTEGRATIONPLUGINBLUOS_H