mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-04-24 06:48:24 -05:00
Add MQTT condition and action
This commit is contained in:
parent
cab50e0922
commit
027a3e9074
|
|
@ -774,9 +774,11 @@ AdvSceneSwitcher.condition.streamDeck.stopListen="Stop listening"
|
|||
AdvSceneSwitcher.condition.streamDeck.pluginDownload="<html><head/><body><p>The Stream Deck plugin can be found <a href=\"https://github.com/WarmUpTill/advanced-scene-switcher-streamdeck-plugin/releases\"><span style=\" text-decoration: underline; color:#268bd2;\">here on GitHub</span></a>.</p></body></html>"
|
||||
AdvSceneSwitcher.condition.gameCapture="Game capture"
|
||||
AdvSceneSwitcher.condition.gameCapture.entry="{{sources}}hooked a game."
|
||||
|
||||
AdvSceneSwitcher.condition.screenshot="Screenshot"
|
||||
AdvSceneSwitcher.condition.screenshot.entry="A screenshot was taken"
|
||||
AdvSceneSwitcher.condition.mqtt="MQTT"
|
||||
AdvSceneSwitcher.condition.mqtt.layout.match="Message was received from{{connection}} which matches{{regex}}:"
|
||||
AdvSceneSwitcher.condition.mqtt.layout.listen="Set message selection to incoming message:{{listenButton}}"
|
||||
|
||||
# Macro Actions
|
||||
AdvSceneSwitcher.action.unknown="Unknown action"
|
||||
|
|
@ -1208,6 +1210,11 @@ AdvSceneSwitcher.action.window.entry="{{actions}}{{windows}}{{regex}}"
|
|||
AdvSceneSwitcher.action.log="Log"
|
||||
AdvSceneSwitcher.action.log.placeholder="My log message!"
|
||||
AdvSceneSwitcher.action.log.entry="Write to OBS log:{{logMessage}}"
|
||||
AdvSceneSwitcher.action.mqtt="MQTT"
|
||||
AdvSceneSwitcher.action.mqtt.topic="Topic:"
|
||||
AdvSceneSwitcher.action.mqtt.qos="QoS:"
|
||||
AdvSceneSwitcher.action.mqtt.retain="Retained message:"
|
||||
AdvSceneSwitcher.action.mqtt.layout="Send message to{{connection}}"
|
||||
|
||||
# Hotkey
|
||||
AdvSceneSwitcher.hotkey.startSwitcherHotkey="Start the Advanced Scene Switcher"
|
||||
|
|
@ -1364,6 +1371,35 @@ AdvSceneSwitcher.osc.message.type.false="False"
|
|||
AdvSceneSwitcher.osc.message.type.infinity="Infinitum"
|
||||
AdvSceneSwitcher.osc.message.type.null="Nil"
|
||||
|
||||
AdvSceneSwitcher.mqttConnection.startListen="Start listening"
|
||||
AdvSceneSwitcher.mqttConnection.stopListen="Stop listening"
|
||||
AdvSceneSwitcher.mqttConnection.select="--select connection--"
|
||||
AdvSceneSwitcher.mqttConnection.add="Add new connection"
|
||||
AdvSceneSwitcher.mqttConnection.configure="Configure connection settings"
|
||||
AdvSceneSwitcher.mqttConnection.invalid="Invalid connection selection"
|
||||
AdvSceneSwitcher.mqttConnection.name="Name:"
|
||||
AdvSceneSwitcher.mqttConnection.address="Address:"
|
||||
AdvSceneSwitcher.mqttConnection.username="Username:"
|
||||
AdvSceneSwitcher.mqttConnection.password="Password:"
|
||||
AdvSceneSwitcher.mqttConnection.reconnect="Reconnect automatically:"
|
||||
AdvSceneSwitcher.mqttConnection.reconnectDelay="Automatically reconnect after:"
|
||||
AdvSceneSwitcher.mqttConnection.connectOnStart="Connect on startup:"
|
||||
AdvSceneSwitcher.mqttConnection.test="Test connection"
|
||||
AdvSceneSwitcher.mqttConnection.status.connected="Connected!"
|
||||
AdvSceneSwitcher.mqttConnection.status.connecting="Connecting ..."
|
||||
AdvSceneSwitcher.mqttConnection.status.disconnected="Could not connect!"
|
||||
AdvSceneSwitcher.mqttConnection.topic="Topic"
|
||||
AdvSceneSwitcher.mqttConnection.qos="QoS"
|
||||
AdvSceneSwitcher.mqttConnection.topics="Topic subscriptions:"
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.emptyTopic="Topic cannot be empty."
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.emptyTopic.title="Input Error"
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.duplicateTopic="This topic already exists."
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.duplicateTopic.title="Duplicate Topic"
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.qosRange="QoS must be 0, 1, or 2."
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.qosRange.title="Invalid QoS"
|
||||
AdvSceneSwitcher.mqttConnection.add.layout="Add topic subscription{{topic}}with QoS{{QoS}}"
|
||||
AdvSceneSwitcher.mqttConnection.add.title="Add MQTT Topic Subscription"
|
||||
|
||||
AdvSceneSwitcher.twitchToken.name="Account name:"
|
||||
AdvSceneSwitcher.twitchToken.nameNotAvailable="Account already in use"
|
||||
AdvSceneSwitcher.twitchToken.select="--select Twitch connection--"
|
||||
|
|
@ -2066,6 +2102,8 @@ AdvSceneSwitcher.tempVar.http.body="Message body"
|
|||
AdvSceneSwitcher.tempVar.http.error="Error"
|
||||
AdvSceneSwitcher.tempVar.http.error.description="Empty when no error occurred.\nOther possible values:\n\n * Could not establish connection\n * Failed to bind IP address\n * Failed to read connection\n * Failed to write connection\n * Maximum redirect count exceeded\n * Connection handling canceled\n * SSL connection failed\n * SSL certificate loading failed\n * SSL server verification failed\n * Unsupported HTTP multipart boundary characters\n * Compression failed\n * Connection timed out\n * Proxy connection failed\n * Unknown"
|
||||
|
||||
AdvSceneSwitcher.tempVar.mqtt.message="Message"
|
||||
|
||||
AdvSceneSwitcher.selectScene="--select scene--"
|
||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ install_advss_plugin_dependency(...)
|
|||
|
||||
add_plugin(http)
|
||||
add_plugin(midi)
|
||||
add_plugin(mqtt)
|
||||
add_plugin(openvr)
|
||||
add_plugin(stream-deck)
|
||||
add_plugin(twitch)
|
||||
|
|
|
|||
202
plugins/mqtt/macro-action-mqtt.cpp
Normal file
202
plugins/mqtt/macro-action-mqtt.cpp
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
#include "macro-action-mqtt.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "mqtt-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroActionMqtt::id = "mqtt";
|
||||
|
||||
bool MacroActionMqtt::_registered = MacroActionFactory::Register(
|
||||
MacroActionMqtt::id,
|
||||
{MacroActionMqtt::Create, MacroActionMqttEdit::Create,
|
||||
"AdvSceneSwitcher.action.mqtt"});
|
||||
|
||||
bool MacroActionMqtt::PerformAction()
|
||||
{
|
||||
auto connection = _connection.lock();
|
||||
if (!connection) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int qos = _qos;
|
||||
if (qos > 2 || qos < 0) {
|
||||
qos = 1;
|
||||
blog(LOG_WARNING,
|
||||
"%s: use QoS 1 isntead of invalid QoS value %d", __func__,
|
||||
(int)_qos);
|
||||
}
|
||||
|
||||
(void)connection->SendMessage(_topic, _message, qos, _retain);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroActionMqtt::LogAction() const
|
||||
{
|
||||
ablog(LOG_INFO,
|
||||
"send MQTT message to \"%s\" (topic: \"%s\" - payload: \"%s\" - qos: %d - retain: %d)",
|
||||
GetWeakMqttConnectionName(_connection).c_str(), _topic.c_str(),
|
||||
_message.c_str(), (int)_qos, _retain);
|
||||
}
|
||||
|
||||
bool MacroActionMqtt::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_string(obj, "connection",
|
||||
GetWeakMqttConnectionName(_connection).c_str());
|
||||
_message.Save(obj, "message");
|
||||
_topic.Save(obj, "topic");
|
||||
_qos.Save(obj, "qos");
|
||||
obs_data_set_bool(obj, "retain", _retain);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroActionMqtt::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
SetConnection(obs_data_get_string(obj, "connection"));
|
||||
_message.Load(obj, "message");
|
||||
_topic.Load(obj, "topic");
|
||||
_qos.Load(obj, "qos");
|
||||
_retain = obs_data_get_bool(obj, "retain");
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroActionMqtt::SetConnection(const std::string &name)
|
||||
{
|
||||
_connection = GetWeakMqttConnectionByName(name);
|
||||
}
|
||||
|
||||
std::weak_ptr<MqttConnection> MacroActionMqtt::GetConnection() const
|
||||
{
|
||||
return _connection;
|
||||
}
|
||||
|
||||
std::string MacroActionMqtt::GetShortDesc() const
|
||||
{
|
||||
return GetWeakMqttConnectionName(_connection);
|
||||
}
|
||||
|
||||
void MacroActionMqtt::ResolveVariablesToFixedValues()
|
||||
{
|
||||
_message.ResolveVariables();
|
||||
_topic.ResolveVariables();
|
||||
_qos.ResolveVariables();
|
||||
}
|
||||
|
||||
std::shared_ptr<MacroAction> MacroActionMqtt::Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroActionMqtt>(m);
|
||||
}
|
||||
|
||||
std::shared_ptr<MacroAction> MacroActionMqtt::Copy() const
|
||||
{
|
||||
return std::make_shared<MacroActionMqtt>(*this);
|
||||
}
|
||||
|
||||
MacroActionMqttEdit::MacroActionMqttEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionMqtt> entryData)
|
||||
: QWidget(parent),
|
||||
_connection(new MqttConnectionSelection(this)),
|
||||
_message(new VariableTextEdit(this, 5, 1, 1)),
|
||||
_topic(new VariableLineEdit(this)),
|
||||
_qos(new VariableSpinBox(this)),
|
||||
_retain(new QCheckBox(this))
|
||||
{
|
||||
_qos->setMinimum(0);
|
||||
_qos->setMaximum(2);
|
||||
|
||||
QWidget::connect(_connection, SIGNAL(SelectionChanged(const QString &)),
|
||||
this,
|
||||
SLOT(ConnectionSelectionChanged(const QString &)));
|
||||
QWidget::connect(_message, SIGNAL(textChanged()), this,
|
||||
SLOT(MqttMessageChanged()));
|
||||
QWidget::connect(_topic, SIGNAL(editingFinished()), this,
|
||||
SLOT(MqttTopicChanged()));
|
||||
QWidget::connect(
|
||||
_qos,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(QoSChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_retain, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(RetainChanged(int)));
|
||||
|
||||
auto sendLayout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.mqtt.layout"),
|
||||
sendLayout, {{"{{connection}}", _connection}});
|
||||
|
||||
int row = 0;
|
||||
auto grid = new QGridLayout;
|
||||
grid->addWidget(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.action.mqtt.topic")),
|
||||
row, 0);
|
||||
grid->addWidget(_topic, row, 1);
|
||||
row++;
|
||||
grid->addWidget(
|
||||
new QLabel(obs_module_text("AdvSceneSwitcher.action.mqtt.qos")),
|
||||
row, 0);
|
||||
grid->addWidget(_qos, row, 1);
|
||||
row++;
|
||||
grid->addWidget(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.action.mqtt.retain")),
|
||||
row, 0);
|
||||
grid->addWidget(_retain, row, 1);
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(sendLayout);
|
||||
mainLayout->addWidget(_message);
|
||||
mainLayout->addLayout(grid);
|
||||
setLayout(mainLayout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroActionMqttEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_connection->SetConnection(_entryData->GetConnection());
|
||||
_message->setPlainText(_entryData->_message);
|
||||
_topic->setText(_entryData->_topic);
|
||||
_qos->SetValue(_entryData->_qos);
|
||||
_retain->setChecked(_entryData->_retain);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionMqttEdit::ConnectionSelectionChanged(const QString &connection)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->SetConnection(connection.toStdString());
|
||||
emit(HeaderInfoChanged(connection));
|
||||
}
|
||||
|
||||
void MacroActionMqttEdit::MqttMessageChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_message = _message->toPlainText().toStdString();
|
||||
}
|
||||
|
||||
void MacroActionMqttEdit::MqttTopicChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_topic = _topic->text().toStdString();
|
||||
}
|
||||
|
||||
void MacroActionMqttEdit::QoSChanged(const IntVariable &value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_qos = value;
|
||||
}
|
||||
|
||||
void MacroActionMqttEdit::RetainChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_retain = value;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
73
plugins/mqtt/macro-action-mqtt.hpp
Normal file
73
plugins/mqtt/macro-action-mqtt.hpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "mqtt-helpers.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroActionMqtt : public MacroAction {
|
||||
public:
|
||||
MacroActionMqtt(Macro *m) : MacroAction(m, true) {}
|
||||
bool PerformAction();
|
||||
void LogAction() const;
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
void SetConnection(const std::string &name);
|
||||
std::weak_ptr<MqttConnection> GetConnection() const;
|
||||
std::string GetShortDesc() const;
|
||||
void ResolveVariablesToFixedValues();
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroAction> Create(Macro *m);
|
||||
std::shared_ptr<MacroAction> Copy() const;
|
||||
|
||||
StringVariable _message = "payload";
|
||||
StringVariable _topic = "/topic";
|
||||
IntVariable _qos = 1;
|
||||
bool _retain = false;
|
||||
|
||||
private:
|
||||
std::weak_ptr<MqttConnection> _connection;
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroActionMqttEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroActionMqttEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroActionMqtt> entryData = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroAction> action)
|
||||
{
|
||||
return new MacroActionMqttEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroActionMqtt>(action));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ConnectionSelectionChanged(const QString &);
|
||||
void MqttMessageChanged();
|
||||
void MqttTopicChanged();
|
||||
void QoSChanged(const NumberVariable<int> &value);
|
||||
void RetainChanged(int value);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
MqttConnectionSelection *_connection;
|
||||
VariableTextEdit *_message;
|
||||
VariableLineEdit *_topic;
|
||||
VariableSpinBox *_qos;
|
||||
QCheckBox *_retain;
|
||||
|
||||
std::shared_ptr<MacroActionMqtt> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
268
plugins/mqtt/macro-condition-mqtt.cpp
Normal file
268
plugins/mqtt/macro-condition-mqtt.cpp
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
#include "macro-condition-mqtt.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "macro-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroConditionMqtt::id = "mqtt";
|
||||
|
||||
bool MacroConditionMqtt::_registered = MacroConditionFactory::Register(
|
||||
MacroConditionMqtt::id,
|
||||
{MacroConditionMqtt::Create, MacroConditionMqttEdit::Create,
|
||||
"AdvSceneSwitcher.condition.mqtt"});
|
||||
|
||||
bool MacroConditionMqtt::CheckCondition()
|
||||
{
|
||||
if (!_messageBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool macroWasPausedSinceLastCheck =
|
||||
MacroWasPausedSince(GetMacro(), _lastCheck);
|
||||
_lastCheck = std::chrono::high_resolution_clock::now();
|
||||
if (macroWasPausedSinceLastCheck) {
|
||||
_messageBuffer->Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto messageMatches = [this](const std::string &message) -> bool {
|
||||
if (_regex.Enabled()) {
|
||||
return _regex.Matches(message, _message);
|
||||
}
|
||||
return message != std::string(_message);
|
||||
};
|
||||
|
||||
while (!_messageBuffer->Empty()) {
|
||||
auto message = _messageBuffer->ConsumeMessage();
|
||||
if (!message) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!messageMatches(*message)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SetTempVarValue("message", *message);
|
||||
if (_clearBufferOnMatch) {
|
||||
_messageBuffer->Clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionMqtt::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
_message.Save(obj, "message");
|
||||
_regex.Save(obj);
|
||||
obs_data_set_string(obj, "connection",
|
||||
GetWeakMqttConnectionName(_connection).c_str());
|
||||
obs_data_set_bool(obj, "clearBufferOnMatch", _clearBufferOnMatch);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionMqtt::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_message.Load(obj, "message");
|
||||
_regex.Load(obj);
|
||||
_clearBufferOnMatch = obs_data_get_bool(obj, "clearBufferOnMatch");
|
||||
SetConnection(obs_data_get_string(obj, "connection"));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionMqtt::GetShortDesc() const
|
||||
{
|
||||
return GetWeakMqttConnectionName(_connection);
|
||||
}
|
||||
|
||||
void MacroConditionMqtt::SetConnection(const std::string &name)
|
||||
{
|
||||
_connection = GetWeakMqttConnectionByName(name);
|
||||
auto connection = _connection.lock();
|
||||
if (!connection) {
|
||||
return;
|
||||
}
|
||||
_messageBuffer = connection->RegisterForEvents();
|
||||
}
|
||||
|
||||
std::weak_ptr<MqttConnection> MacroConditionMqtt::GetConnection() const
|
||||
{
|
||||
return _connection;
|
||||
}
|
||||
|
||||
void MacroConditionMqtt::SetupTempVars()
|
||||
{
|
||||
MacroCondition::SetupTempVars();
|
||||
AddTempvar("message",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.mqtt.message"));
|
||||
}
|
||||
|
||||
MacroConditionMqttEdit::MacroConditionMqttEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionMqtt> entryData)
|
||||
: QWidget(parent),
|
||||
_connection(new MqttConnectionSelection(this)),
|
||||
_message(new VariableTextEdit(this, 5, 1, 1)),
|
||||
_regex(new RegexConfigWidget(parent)),
|
||||
_listen(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.mqttConnection.startListen"))),
|
||||
_clearBufferOnMatch(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.clearBufferOnMatch")))
|
||||
{
|
||||
QWidget::connect(_message, SIGNAL(textChanged()), this,
|
||||
SLOT(MqttMessageChanged()));
|
||||
QWidget::connect(_regex,
|
||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
||||
SLOT(RegexChanged(const RegexConfig &)));
|
||||
QWidget::connect(_connection, SIGNAL(SelectionChanged(const QString &)),
|
||||
this,
|
||||
SLOT(ConnectionSelectionChanged(const QString &)));
|
||||
QWidget::connect(_listen, SIGNAL(clicked()), this,
|
||||
SLOT(ToggleListen()));
|
||||
QWidget::connect(_clearBufferOnMatch, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(ClearBufferOnMatchChanged(int)));
|
||||
QWidget::connect(&_listenTimer, SIGNAL(timeout()), this,
|
||||
SLOT(SetMessageSelectionToLastReceived()));
|
||||
|
||||
auto entryLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.mqtt.layout.match"),
|
||||
entryLayout,
|
||||
{{"{{connection}}", _connection}, {"{{regex}}", _regex}});
|
||||
auto listenLayout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.mqtt.layout.listen"),
|
||||
listenLayout, {{"{{listenButton}}", _listen}});
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(entryLayout);
|
||||
mainLayout->addWidget(_message);
|
||||
mainLayout->addLayout(listenLayout);
|
||||
mainLayout->addWidget(_clearBufferOnMatch);
|
||||
setLayout(mainLayout);
|
||||
|
||||
_listenTimer.setInterval(100);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
MacroConditionMqttEdit::~MacroConditionMqttEdit()
|
||||
{
|
||||
EnableListening(false);
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_message->setPlainText(_entryData->_message);
|
||||
_connection->SetConnection(_entryData->GetConnection());
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
_clearBufferOnMatch->setChecked(_entryData->_clearBufferOnMatch);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::ConnectionSelectionChanged(
|
||||
const QString &connection)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->SetConnection(connection.toStdString());
|
||||
emit(HeaderInfoChanged(connection));
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::MqttMessageChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_message = _message->toPlainText().toStdString();
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::ClearBufferOnMatchChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_clearBufferOnMatch = value;
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::RegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_regex = conf;
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::EnableListening(bool enable)
|
||||
{
|
||||
if (_currentlyListening == enable) {
|
||||
return;
|
||||
}
|
||||
if (enable) {
|
||||
auto connectionItem = _connection->GetCurrentItem();
|
||||
if (!connectionItem) {
|
||||
return;
|
||||
}
|
||||
auto weakConnection = GetWeakMqttConnectionByQString(
|
||||
QString::fromStdString(connectionItem->Name()));
|
||||
auto connection = weakConnection.lock();
|
||||
if (!connection) {
|
||||
return;
|
||||
}
|
||||
_messageBuffer = connection->RegisterForEvents();
|
||||
_listenTimer.start();
|
||||
} else {
|
||||
_messageBuffer.reset();
|
||||
_listenTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::ToggleListen()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_listen->setText(
|
||||
_currentlyListening
|
||||
? obs_module_text(
|
||||
"AdvSceneSwitcher.mqttConnection.startListen")
|
||||
: obs_module_text(
|
||||
"AdvSceneSwitcher.mqttConnection.stopListen"));
|
||||
EnableListening(!_currentlyListening);
|
||||
_currentlyListening = !_currentlyListening;
|
||||
_message->setDisabled(_currentlyListening);
|
||||
}
|
||||
|
||||
void MacroConditionMqttEdit::SetMessageSelectionToLastReceived()
|
||||
{
|
||||
auto lock = LockContext();
|
||||
if (!_entryData || !_messageBuffer || _messageBuffer->Empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::optional<std::string> message;
|
||||
while (!_messageBuffer->Empty()) {
|
||||
message = _messageBuffer->ConsumeMessage();
|
||||
if (!message) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QSignalBlocker blocker(_message);
|
||||
_message->setPlainText(*message);
|
||||
_entryData->_message = *message;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
86
plugins/mqtt/macro-condition-mqtt.hpp
Normal file
86
plugins/mqtt/macro-condition-mqtt.hpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "mqtt-helpers.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroConditionMqtt : public MacroCondition {
|
||||
public:
|
||||
MacroConditionMqtt(Macro *m) : MacroCondition(m, true) {}
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetShortDesc() const;
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroConditionMqtt>(m);
|
||||
}
|
||||
|
||||
void SetConnection(const std::string &);
|
||||
std::weak_ptr<MqttConnection> GetConnection() const;
|
||||
|
||||
StringVariable _message;
|
||||
RegexConfig _regex;
|
||||
bool _clearBufferOnMatch = true;
|
||||
|
||||
private:
|
||||
void SetupTempVars();
|
||||
|
||||
std::weak_ptr<MqttConnection> _connection;
|
||||
MqttMessageBuffer _messageBuffer;
|
||||
std::chrono::high_resolution_clock::time_point _lastCheck{};
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroConditionMqttEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroConditionMqttEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroConditionMqtt> cond = nullptr);
|
||||
virtual ~MacroConditionMqttEdit();
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroCondition> cond)
|
||||
{
|
||||
return new MacroConditionMqttEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroConditionMqtt>(cond));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ConnectionSelectionChanged(const QString &);
|
||||
void MqttMessageChanged();
|
||||
void ClearBufferOnMatchChanged(int);
|
||||
void RegexChanged(const RegexConfig &conf);
|
||||
void ToggleListen();
|
||||
void SetMessageSelectionToLastReceived();
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
void EnableListening(bool);
|
||||
|
||||
MqttConnectionSelection *_connection;
|
||||
VariableTextEdit *_message;
|
||||
RegexConfigWidget *_regex;
|
||||
QPushButton *_listen;
|
||||
QCheckBox *_clearBufferOnMatch;
|
||||
|
||||
std::shared_ptr<MacroConditionMqtt> _entryData;
|
||||
QTimer _listenTimer;
|
||||
MqttMessageBuffer _messageBuffer;
|
||||
bool _currentlyListening = false;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
Loading…
Reference in New Issue
Block a user