added a plugin to detect wifi devices in range
This commit is contained in:
parent
9e3f55ab21
commit
822f63861a
1
Hive.pro
1
Hive.pro
@ -4,4 +4,3 @@ SUBDIRS += libhive server plugins
|
||||
|
||||
server.depends = libhive plugins
|
||||
plugins.depends = libhive
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "device.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
Device::Device(const QUuid &pluginId, const QUuid &id, const QUuid &deviceClassId, QObject *parent):
|
||||
QObject(parent),
|
||||
m_id(id),
|
||||
@ -75,12 +77,16 @@ QVariant Device::stateValue(const QUuid &stateTypeId) const
|
||||
|
||||
void Device::setStateValue(const QUuid &stateTypeId, const QVariant &value)
|
||||
{
|
||||
qDebug() << "setting state for id" << stateTypeId;
|
||||
for (int i = 0; i < m_states.count(); ++i) {
|
||||
qDebug() << "got state id" << m_states.at(i).stateTypeId();
|
||||
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
||||
State newState(stateTypeId, m_id);
|
||||
newState.setValue(value);
|
||||
m_states[i] = newState;
|
||||
qDebug() << "set state for device" << value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
qDebug() << "failed setting state" << value;
|
||||
}
|
||||
|
||||
@ -15,13 +15,15 @@
|
||||
Q_IMPORT_PLUGIN(DevicePluginElro)
|
||||
Q_IMPORT_PLUGIN(DevicePluginIntertechno)
|
||||
Q_IMPORT_PLUGIN(DevicePluginMeisterAnker)
|
||||
Q_IMPORT_PLUGIN(DevicePluginWifiDetector)
|
||||
|
||||
|
||||
DeviceManager::DeviceManager(QObject *parent) :
|
||||
QObject(parent)
|
||||
QObject(parent),
|
||||
m_radio433(0)
|
||||
{
|
||||
m_radio433 = new Radio433(this);
|
||||
connect(m_radio433, &Radio433::dataReceived, this, &DeviceManager::radio433SignalReceived);
|
||||
m_pluginTimer.setInterval(15000);
|
||||
connect(&m_pluginTimer, &QTimer::timeout, this, &DeviceManager::timerEvent);
|
||||
|
||||
QMetaObject::invokeMethod(this, "loadPlugins", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "loadConfiguredDevices", Qt::QueuedConnection);
|
||||
@ -66,7 +68,12 @@ DeviceManager::DeviceError DeviceManager::addConfiguredDevice(const QUuid &devic
|
||||
Device *device = new Device(plugin->pluginId(), deviceClassId, this);
|
||||
device->setName(deviceClass.name());
|
||||
device->setParams(params);
|
||||
m_configuredDevices.append(device);
|
||||
if (setupDevice(device)) {
|
||||
m_configuredDevices.append(device);
|
||||
} else {
|
||||
qWarning() << "Failed to set up device.";
|
||||
return DeviceErrorSetupFailed;
|
||||
}
|
||||
|
||||
storeConfiguredDevices();
|
||||
|
||||
@ -160,6 +167,9 @@ void DeviceManager::loadConfiguredDevices()
|
||||
device->setName(settings.value("devicename").toString());
|
||||
device->setParams(settings.value("params").toMap());
|
||||
settings.endGroup();
|
||||
|
||||
setupDevice(device);
|
||||
|
||||
m_configuredDevices.append(device);
|
||||
qDebug() << "found stored device" << device->name() << idString;
|
||||
}
|
||||
@ -183,8 +193,50 @@ void DeviceManager::radio433SignalReceived(QList<int> rawData)
|
||||
foreach (Device *device, m_configuredDevices) {
|
||||
DeviceClass deviceClass = m_supportedDevices.value(device->deviceClassId());
|
||||
DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId());
|
||||
if (plugin->requiredHardware() == HardwareResourceRadio433) {
|
||||
plugin->receiveData(rawData);
|
||||
if (plugin->requiredHardware().testFlag(HardwareResourceRadio433)) {
|
||||
plugin->radioData(rawData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::timerEvent()
|
||||
{
|
||||
foreach (Device *device, m_configuredDevices) {
|
||||
DeviceClass deviceClass = m_supportedDevices.value(device->deviceClassId());
|
||||
DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId());
|
||||
if (plugin->requiredHardware().testFlag(HardwareResourceTimer)) {
|
||||
plugin->hiveTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceManager::setupDevice(Device *device)
|
||||
{
|
||||
DeviceClass deviceClass = findDeviceClass(device->deviceClassId());
|
||||
DevicePlugin *plugin = m_devicePlugins.value(deviceClass.pluginId());
|
||||
|
||||
QList<State> states;
|
||||
foreach (const StateType &stateType, deviceClass.states()) {
|
||||
State state(stateType.id(), device->id());
|
||||
state.setValue(stateType.defaultValue());
|
||||
states.append(state);
|
||||
}
|
||||
device->setStates(states);
|
||||
|
||||
if (plugin->requiredHardware().testFlag(HardwareResourceRadio433)) {
|
||||
if (!m_radio433) {
|
||||
m_radio433 = new Radio433();
|
||||
connect(m_radio433, &Radio433::dataReceived, this, &DeviceManager::radio433SignalReceived);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin->requiredHardware().testFlag(HardwareResourceTimer)) {
|
||||
if (!m_pluginTimer.isActive()) {
|
||||
m_pluginTimer.start();
|
||||
// Additionally fire off one event to initialize stuff
|
||||
QTimer::singleShot(0, this, SLOT(timerEvent()));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "action.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
class Device;
|
||||
class DevicePlugin;
|
||||
@ -16,16 +17,20 @@ class DeviceManager : public QObject
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum HardwareResource {
|
||||
HardwareResourceNone = 0x00,
|
||||
HardwareResourceRadio433 = 0x01,
|
||||
HardwareResourceRadio868 = 0x02
|
||||
HardwareResourceRadio868 = 0x02,
|
||||
HardwareResourceTimer = 0x04
|
||||
};
|
||||
Q_DECLARE_FLAGS(HardwareResources, HardwareResource)
|
||||
|
||||
enum DeviceError {
|
||||
DeviceErrorNoError,
|
||||
DeviceErrorDeviceNotFound,
|
||||
DeviceErrorDeviceClassNotFound,
|
||||
DeviceErrorMissingParameter,
|
||||
DeviceErrorPluginNotFound
|
||||
DeviceErrorPluginNotFound,
|
||||
DeviceErrorSetupFailed
|
||||
};
|
||||
|
||||
explicit DeviceManager(QObject *parent = 0);
|
||||
@ -54,16 +59,22 @@ private slots:
|
||||
void storeConfiguredDevices();
|
||||
|
||||
void radio433SignalReceived(QList<int> rawData);
|
||||
void timerEvent();
|
||||
|
||||
private:
|
||||
bool setupDevice(Device *device);
|
||||
|
||||
QHash<QUuid, DeviceClass> m_supportedDevices;
|
||||
QList<Device*> m_configuredDevices;
|
||||
|
||||
QHash<QUuid, DevicePlugin*> m_devicePlugins;
|
||||
|
||||
// Hardware Resources
|
||||
Radio433* m_radio433;
|
||||
QTimer m_pluginTimer;
|
||||
|
||||
friend class DevicePlugin;
|
||||
};
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(DeviceManager::HardwareResources)
|
||||
|
||||
#endif // DEVICEMANAGER_H
|
||||
|
||||
@ -26,16 +26,18 @@ public:
|
||||
virtual QUuid pluginId() const = 0;
|
||||
|
||||
virtual QList<DeviceClass> supportedDevices() const = 0;
|
||||
virtual DeviceManager::HardwareResource requiredHardware() const = 0;
|
||||
virtual DeviceManager::HardwareResources requiredHardware() const = 0;
|
||||
|
||||
// Hardware input
|
||||
virtual void receiveData(QList<int> rawData) = 0;
|
||||
virtual void radioData(QList<int> rawData) {Q_UNUSED(rawData)}
|
||||
virtual void hiveTimer() {}
|
||||
|
||||
virtual QVariantMap configuration() const;
|
||||
virtual void setConfiguration(const QVariantMap &configuration);
|
||||
|
||||
public slots:
|
||||
virtual void executeAction(Device *device, const Action &action) = 0;
|
||||
virtual void executeAction(Device *device, const Action &action) {Q_UNUSED(device) Q_UNUSED(action)}
|
||||
|
||||
|
||||
signals:
|
||||
void emitTrigger(const Trigger &trigger);
|
||||
|
||||
@ -29,3 +29,13 @@ void StateType::setType(const QVariant::Type &type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
QVariant StateType::defaultValue() const
|
||||
{
|
||||
return m_defaultValue;
|
||||
}
|
||||
|
||||
void StateType::setDefaultValue(const QVariant &defaultValue)
|
||||
{
|
||||
m_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@ -17,10 +17,14 @@ public:
|
||||
QVariant::Type type() const;
|
||||
void setType(const QVariant::Type &type);
|
||||
|
||||
QVariant defaultValue() const;
|
||||
void setDefaultValue(const QVariant &defaultValue);
|
||||
|
||||
private:
|
||||
QUuid m_id;
|
||||
QString m_name;
|
||||
QVariant::Type m_type;
|
||||
QVariant m_defaultValue;
|
||||
};
|
||||
|
||||
#endif // STATETYPE_H
|
||||
|
||||
@ -139,7 +139,7 @@ QList<DeviceClass> DevicePluginElro::supportedDevices() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResource DevicePluginElro::requiredHardware() const
|
||||
DeviceManager::HardwareResources DevicePluginElro::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceRadio433;
|
||||
}
|
||||
@ -249,7 +249,7 @@ void DevicePluginElro::executeAction(Device *device, const Action &action)
|
||||
transmitData(rawData);
|
||||
}
|
||||
|
||||
void DevicePluginElro::receiveData(QList<int> rawData)
|
||||
void DevicePluginElro::radioData(QList<int> rawData)
|
||||
{
|
||||
// filter right here a wrong signal length
|
||||
if(rawData.length() != 49){
|
||||
|
||||
@ -14,12 +14,12 @@ public:
|
||||
explicit DevicePluginElro();
|
||||
|
||||
QList<DeviceClass> supportedDevices() const override;
|
||||
DeviceManager::HardwareResource requiredHardware() const override;
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
|
||||
QString pluginName() const;
|
||||
QUuid pluginId() const;
|
||||
QString pluginName() const override;
|
||||
QUuid pluginId() const override;
|
||||
|
||||
void receiveData(QList<int> rawData);
|
||||
void radioData(QList<int> rawData) override;
|
||||
|
||||
public slots:
|
||||
void executeAction(Device *device, const Action &action) override;
|
||||
|
||||
@ -176,7 +176,7 @@ QList<DeviceClass> DevicePluginIntertechno::supportedDevices() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResource DevicePluginIntertechno::requiredHardware() const
|
||||
DeviceManager::HardwareResources DevicePluginIntertechno::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceRadio433;
|
||||
}
|
||||
@ -315,7 +315,7 @@ void DevicePluginIntertechno::executeAction(Device *device, const Action &action
|
||||
|
||||
}
|
||||
|
||||
void DevicePluginIntertechno::receiveData(QList<int> rawData)
|
||||
void DevicePluginIntertechno::radioData(QList<int> rawData)
|
||||
{
|
||||
|
||||
|
||||
|
||||
@ -14,12 +14,12 @@ public:
|
||||
explicit DevicePluginIntertechno();
|
||||
|
||||
QList<DeviceClass> supportedDevices() const override;
|
||||
DeviceManager::HardwareResource requiredHardware() const override;
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
|
||||
QString pluginName() const;
|
||||
QUuid pluginId() const;
|
||||
QString pluginName() const override;
|
||||
QUuid pluginId() const override;
|
||||
|
||||
void receiveData(QList<int> rawData);
|
||||
void radioData(QList<int> rawData) override;
|
||||
|
||||
public slots:
|
||||
void executeAction(Device *device, const Action &action) override;
|
||||
|
||||
@ -83,7 +83,7 @@ QList<DeviceClass> DevicePluginMeisterAnker::supportedDevices() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResource DevicePluginMeisterAnker::requiredHardware() const
|
||||
DeviceManager::HardwareResources DevicePluginMeisterAnker::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceRadio433;
|
||||
}
|
||||
@ -103,7 +103,7 @@ void DevicePluginMeisterAnker::executeAction(Device *device, const Action &actio
|
||||
|
||||
}
|
||||
|
||||
void DevicePluginMeisterAnker::receiveData(QList<int> rawData)
|
||||
void DevicePluginMeisterAnker::radioData(QList<int> rawData)
|
||||
{
|
||||
// filter right here a wrong signal length
|
||||
if(rawData.length() != 49){
|
||||
|
||||
@ -15,12 +15,12 @@ public:
|
||||
explicit DevicePluginMeisterAnker();
|
||||
|
||||
QList<DeviceClass> supportedDevices() const override;
|
||||
DeviceManager::HardwareResource requiredHardware() const override;
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
|
||||
QString pluginName() const;
|
||||
QUuid pluginId() const;
|
||||
QString pluginName() const override;
|
||||
QUuid pluginId() const override;
|
||||
|
||||
void receiveData(QList<int> rawData);
|
||||
void radioData(QList<int> rawData) override;
|
||||
|
||||
public slots:
|
||||
void executeAction(Device *device, const Action &action) override;
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS += devicepluginelro devicepluginintertechno devicepluginmeisteranker
|
||||
SUBDIRS += devicepluginelro devicepluginintertechno devicepluginmeisteranker devicepluginwifidetector
|
||||
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
#include "devicepluginwifidetector.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "devicemanager.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
|
||||
QUuid pluginUuid = QUuid("8e0f791e-b273-4267-8605-b7c2f55a68ab");
|
||||
QUuid detectorId = QUuid("bd216356-f1ec-4324-9785-6982d2174e17");
|
||||
QUuid inRangeStateTypeId = QUuid("cb43e1b5-4f61-4538-bfa2-c33055c542cf");
|
||||
QUuid inRangeTriggerTypeId = QUuid("7cae711a-a0af-41b4-b3bf-38d3e23b41ba");
|
||||
|
||||
DevicePluginWifiDetector::DevicePluginWifiDetector()
|
||||
{
|
||||
}
|
||||
|
||||
QList<DeviceClass> DevicePluginWifiDetector::supportedDevices() const
|
||||
{
|
||||
QList<DeviceClass> ret;
|
||||
|
||||
DeviceClass deviceClassWifiDetector(pluginId(), detectorId);
|
||||
deviceClassWifiDetector.setName("WiFi Device");
|
||||
|
||||
QVariantList detectorParams;
|
||||
QVariantMap macParam;
|
||||
macParam.insert("name", "mac");
|
||||
macParam.insert("type", "string");
|
||||
detectorParams.append(macParam);
|
||||
|
||||
deviceClassWifiDetector.setParams(detectorParams);
|
||||
|
||||
QList<StateType> detectorStates;
|
||||
|
||||
StateType inRangeState(inRangeStateTypeId);
|
||||
inRangeState.setName("inRange");
|
||||
inRangeState.setType(QVariant::Bool);
|
||||
inRangeState.setDefaultValue(false);
|
||||
detectorStates.append(inRangeState);
|
||||
|
||||
deviceClassWifiDetector.setStates(detectorStates);
|
||||
|
||||
QList<TriggerType> detectorTriggers;
|
||||
|
||||
QVariantList detectorTriggerParams;
|
||||
QVariantMap paramInRange;
|
||||
paramInRange.insert("name", "inRange");
|
||||
paramInRange.insert("type", "bool");
|
||||
detectorTriggerParams.append(paramInRange);
|
||||
|
||||
TriggerType inRangeTrigger(inRangeTriggerTypeId);
|
||||
inRangeTrigger.setName("inRange");
|
||||
inRangeTrigger.setParameters(detectorTriggerParams);
|
||||
detectorTriggers.append(inRangeTrigger);
|
||||
|
||||
deviceClassWifiDetector.setTriggers(detectorTriggers);
|
||||
ret.append(deviceClassWifiDetector);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DeviceManager::HardwareResources DevicePluginWifiDetector::requiredHardware() const
|
||||
{
|
||||
return DeviceManager::HardwareResourceTimer;
|
||||
}
|
||||
|
||||
QString DevicePluginWifiDetector::pluginName() const
|
||||
{
|
||||
return "WiFi Detector";
|
||||
}
|
||||
|
||||
QUuid DevicePluginWifiDetector::pluginId() const
|
||||
{
|
||||
return pluginUuid;
|
||||
}
|
||||
|
||||
void DevicePluginWifiDetector::hiveTimer()
|
||||
{
|
||||
QProcess *p = new QProcess(this);
|
||||
connect(p, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)));
|
||||
p->start(QStringLiteral("arp-scan"), QStringList() << "--localnet" << "-I" << "eth2" );
|
||||
}
|
||||
|
||||
void DevicePluginWifiDetector::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
QProcess *p = static_cast<QProcess*>(sender());
|
||||
p->deleteLater();
|
||||
|
||||
QList<Device*> watchedDevices = deviceManager()->findConfiguredDevices(supportedDevices().first().id());
|
||||
if (watchedDevices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList foundDevices;
|
||||
while(p->canReadLine()) {
|
||||
QString result = QString::fromLatin1(p->readLine());
|
||||
QStringList lineParts = result.split('\t');
|
||||
if (lineParts.count() > 1) {
|
||||
QString addr = lineParts.at(1);
|
||||
foundDevices << addr;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Device *device, watchedDevices) {
|
||||
bool wasInRange = device->stateValue(inRangeStateTypeId).toBool();
|
||||
bool wasFound = foundDevices.contains(device->params().value("mac").toString());
|
||||
if (wasInRange != wasFound) {
|
||||
device->setStateValue(inRangeStateTypeId, wasFound);
|
||||
|
||||
QVariantMap params;
|
||||
params.insert("inRange", wasFound);
|
||||
Trigger trigger(inRangeTriggerTypeId, device->id(), params);
|
||||
|
||||
qDebug() << "Device" << device->name() << QStringLiteral("is now ") + (wasFound ? "in" : "out of") + " range";
|
||||
emit emitTrigger(trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
#ifndef DEVICEPLUGINWIFIDETECTOR_H
|
||||
#define DEVICEPLUGINWIFIDETECTOR_H
|
||||
|
||||
#include "deviceplugin.h"
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
class DevicePluginWifiDetector : public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "org.hiveyourhome.DevicePlugin" FILE "devicepluginwifidetector.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
public:
|
||||
explicit DevicePluginWifiDetector();
|
||||
|
||||
QList<DeviceClass> supportedDevices() const override;
|
||||
DeviceManager::HardwareResources requiredHardware() const override;
|
||||
|
||||
QString pluginName() const override;
|
||||
QUuid pluginId() const override;
|
||||
|
||||
void hiveTimer() override;
|
||||
|
||||
private slots:
|
||||
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINWIFIDETECTOR_H
|
||||
@ -0,0 +1 @@
|
||||
{}
|
||||
@ -0,0 +1,11 @@
|
||||
include(../../plugins.pri)
|
||||
|
||||
TARGET = $$qtLibraryTarget(hive_devicepluginwifidetector)
|
||||
|
||||
SOURCES += \
|
||||
devicepluginwifidetector.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginwifidetector.h
|
||||
|
||||
|
||||
@ -105,6 +105,9 @@ void JsonRPCServer::handleDevicesMessage(int clientId, int commandId, const QStr
|
||||
case DeviceManager::DeviceErrorMissingParameter:
|
||||
sendErrorResponse(clientId, commandId, "Error creating device. Missing parameter.");
|
||||
break;
|
||||
case DeviceManager::DeviceErrorSetupFailed:
|
||||
sendErrorResponse(clientId, commandId, "Error creating device. Device setup failed.");
|
||||
break;
|
||||
default:
|
||||
sendErrorResponse(clientId, commandId, "Unknown error.");
|
||||
}
|
||||
|
||||
@ -28,3 +28,4 @@ HEADERS += hivecore.h \
|
||||
LIBS += -L../plugins/deviceplugins/devicepluginelro/ -lhive_devicepluginelro
|
||||
LIBS += -L../plugins/deviceplugins/devicepluginintertechno/ -lhive_devicepluginintertechno
|
||||
LIBS += -L../plugins/deviceplugins/devicepluginmeisteranker/ -lhive_devicepluginmeisteranker
|
||||
LIBS += -L../plugins/deviceplugins/devicepluginwifidetector/ -lhive_devicepluginwifidetector
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
if [ -z $1 ]; then
|
||||
echo "usage $0 host device"
|
||||
elif [ $1 == "list" ]; then
|
||||
echo "elroremote elroswitch intertechnoremote meisteranker"
|
||||
echo "elroremote elroswitch intertechnoremote meisteranker wifidetector"
|
||||
elif [ -z $2 ]; then
|
||||
echo "usage $0 host device"
|
||||
else
|
||||
@ -20,5 +20,8 @@ else
|
||||
elif [ $2 == "meisteranker" ]; then
|
||||
# Adds an intertechno remote control
|
||||
(echo '{"id":1, "method":"Devices.AddConfiguredDevice", "params":{"deviceClass": "{e37e9f34-95b9-4a22-ae4f-e8b874eec871}","params":{"id":"1"}}}'; sleep 1) | nc $1 1234
|
||||
elif [ $2 == "wifidetector" ]; then
|
||||
# Adds a WiFi detector
|
||||
(echo '{"id":1, "method":"Devices.AddConfiguredDevice", "params":{"deviceClass": "{bd216356-f1ec-4324-9785-6982d2174e17}","params":{"mac":"90:cf:15:1b:ce:bb"}}}'; sleep 1) | nc $1 1234
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user