Add support for NFC tag writing and reading
parent
621bfaed91
commit
c36000c1e9
|
|
@ -30,6 +30,7 @@ SOURCES += \
|
|||
../nymea-app/stylecontroller.cpp \
|
||||
../nymea-app/platformhelper.cpp \
|
||||
../nymea-app/nfchelper.cpp \
|
||||
../nymea-app/nfcthingactionwriter.cpp \
|
||||
../nymea-app/platformintegration/android/platformhelperandroid.cpp \
|
||||
service_main.cpp
|
||||
|
||||
|
|
@ -40,6 +41,7 @@ HEADERS += \
|
|||
../nymea-app/stylecontroller.h \
|
||||
../nymea-app/platformhelper.h \
|
||||
../nymea-app/nfchelper.h \
|
||||
../nymea-app/nfcthingactionwriter.h \
|
||||
../nymea-app/platformintegration/android/platformhelperandroid.h \
|
||||
|
||||
DISTFILES += \
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "../nymea-app/stylecontroller.h"
|
||||
#include "../nymea-app/platformhelper.h"
|
||||
#include "../nymea-app/nfchelper.h"
|
||||
#include "../nymea-app/nfcthingactionwriter.h"
|
||||
#include "../nymea-app/platformintegration/android/platformhelperandroid.h"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
|
|
@ -41,7 +42,8 @@ DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QAp
|
|||
registerQmlTypes();
|
||||
qmlRegisterSingletonType<PlatformHelper>("Nymea", 1, 0, "PlatformHelper", platformHelperProvider);
|
||||
qmlRegisterSingletonType(QUrl("qrc:///ui/utils/NymeaUtils.qml"), "Nymea", 1, 0, "NymeaUtils" );
|
||||
qmlRegisterType<NfcHelper>("Nymea", 1, 0, "NfcHelper");
|
||||
qmlRegisterType<NfcThingActionWriter>("Nymea", 1, 0, "NfcThingActionWriter");
|
||||
qmlRegisterSingletonType<NfcHelper>("Nymea", 1, 0, "NfcHelper", NfcHelper::nfcHelperProvider);
|
||||
|
||||
StyleController *styleController = new StyleController(this);
|
||||
m_qmlEngine->rootContext()->setContextProperty("styleController", styleController);
|
||||
|
|
@ -168,6 +170,11 @@ void DeviceControlApplication::runNfcAction()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (parts.count() > 2) {
|
||||
// The parameters might contain a #, let's merge them again
|
||||
parts[1] = parts.mid(1).join('#');
|
||||
}
|
||||
|
||||
QString actionTypeName = parts.at(0);
|
||||
ActionType *actionType = thing->thingClass()->actionTypes()->findByName(actionTypeName);
|
||||
if (!actionType) {
|
||||
|
|
@ -188,6 +195,8 @@ void DeviceControlApplication::runNfcAction()
|
|||
}
|
||||
}
|
||||
|
||||
qDebug() << "Parameters in NFC uri:" << paramsInUri;
|
||||
|
||||
QVariantList params;
|
||||
for (int j = 0; j < actionType->paramTypes()->rowCount(); j++) {
|
||||
ParamType *paramType = actionType->paramTypes()->get(j);
|
||||
|
|
@ -201,6 +210,8 @@ void DeviceControlApplication::runNfcAction()
|
|||
params.append(param);
|
||||
}
|
||||
|
||||
qDebug() << "Action parameters:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
|
||||
|
||||
m_engine->thingManager()->executeAction(thingId, actionType->id(), params);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "applogcontroller.h"
|
||||
#include "ruletemplates/messages.h"
|
||||
#include "nfchelper.h"
|
||||
#include "nfcthingactionwriter.h"
|
||||
|
||||
QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
|
|
@ -67,7 +68,6 @@ QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
|
|
@ -125,7 +125,8 @@ int main(int argc, char *argv[])
|
|||
QQmlApplicationEngine *engine = new QQmlApplicationEngine();
|
||||
|
||||
qmlRegisterSingletonType<PlatformHelper>("Nymea", 1, 0, "PlatformHelper", platformHelperProvider);
|
||||
qmlRegisterType<NfcHelper>("Nymea", 1, 0, "NfcHelper");
|
||||
qmlRegisterSingletonType<NfcHelper>("Nymea", 1, 0, "NfcHelper", NfcHelper::nfcHelperProvider);
|
||||
qmlRegisterType<NfcThingActionWriter>("Nymea", 1, 0, "NfcThingActionWriter");
|
||||
|
||||
PushNotifications::instance()->connectClient();
|
||||
qmlRegisterSingletonType<PushNotifications>("Nymea", 1, 0, "PushNotifications", PushNotifications::pushNotificationsProvider);
|
||||
|
|
|
|||
|
|
@ -1,181 +1,28 @@
|
|||
#include "nfchelper.h"
|
||||
#include "types/deviceclass.h"
|
||||
#include "types/statetype.h"
|
||||
#include "types/ruleaction.h"
|
||||
#include "types/ruleactionparams.h"
|
||||
#include "types/ruleactionparam.h"
|
||||
|
||||
#include <QNearFieldManager>
|
||||
#include <QNdefMessage>
|
||||
#include <QDebug>
|
||||
#include <QNdefNfcUriRecord>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
NfcHelper::NfcHelper(QObject *parent):
|
||||
QObject(parent),
|
||||
m_manager(new QNearFieldManager(this)),
|
||||
m_actions(new RuleActions(this))
|
||||
NfcHelper::NfcHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
connect(m_manager, &QNearFieldManager::targetDetected, this, &NfcHelper::targetDetected);
|
||||
connect(m_manager, &QNearFieldManager::targetLost, this, &NfcHelper::targetLost);
|
||||
|
||||
connect(m_actions, &RuleActions::countChanged, this, &NfcHelper::updateContent);
|
||||
|
||||
m_manager->startTargetDetection();
|
||||
|
||||
}
|
||||
|
||||
NfcHelper::~NfcHelper()
|
||||
NfcHelper *NfcHelper::instance()
|
||||
{
|
||||
m_manager->stopTargetDetection();
|
||||
}
|
||||
|
||||
Engine *NfcHelper::engine() const
|
||||
{
|
||||
return m_engine;
|
||||
}
|
||||
|
||||
void NfcHelper::setEngine(Engine *engine)
|
||||
{
|
||||
if (m_engine != engine) {
|
||||
m_engine = engine;
|
||||
emit engineChanged();
|
||||
updateContent();
|
||||
static NfcHelper *thiz = nullptr;
|
||||
if (!thiz) {
|
||||
thiz = new NfcHelper();
|
||||
}
|
||||
return thiz;
|
||||
}
|
||||
|
||||
Device *NfcHelper::thing() const
|
||||
QObject *NfcHelper::nfcHelperProvider(QQmlEngine */*engine*/, QJSEngine */*scriptEngine*/)
|
||||
{
|
||||
return m_thing;
|
||||
return instance();
|
||||
}
|
||||
|
||||
void NfcHelper::setThing(Device *thing)
|
||||
bool NfcHelper::isAvailable() const
|
||||
{
|
||||
if (m_thing != thing) {
|
||||
m_thing = thing;
|
||||
emit thingChanged();
|
||||
updateContent();
|
||||
}
|
||||
QNearFieldManager manager;
|
||||
return manager.isAvailable();
|
||||
}
|
||||
|
||||
RuleActions *NfcHelper::actions() const
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
int NfcHelper::messageSize() const
|
||||
{
|
||||
return m_currentMessage.toByteArray().size();
|
||||
int ret = 0;
|
||||
for (int i = 0; i < m_currentMessage.size(); i++) {
|
||||
ret += m_currentMessage.at(i).payload().size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
NfcHelper::TagStatus NfcHelper::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
void NfcHelper::updateContent()
|
||||
{
|
||||
qDebug() << "Updating" << m_engine << m_thing;
|
||||
|
||||
// Creating an URI type record with this format:
|
||||
// nymea://<nymeaId>
|
||||
// ? t=<thingId>
|
||||
// & a[0]=<actionTypeName>
|
||||
// & a[1]=<actionTypeName>#<paramName1>:<paramValue>
|
||||
// & a[2]=<actionTypeName>#<paramName1>:<paramValue>+<paramName2>:<paramValue>
|
||||
// & ...
|
||||
|
||||
// NOTE: We're using actionType and paramType *name* instead of the ID because NFC tags are
|
||||
// small and normally names are shorter than ids so we save some space.
|
||||
|
||||
// NOTE: param values are percentage encoded to prevent messing with the parsing if they
|
||||
// contain + or :
|
||||
|
||||
QUrl url;
|
||||
url.setScheme("nymea");
|
||||
if (!m_engine || !m_thing) {
|
||||
return;
|
||||
}
|
||||
url.setHost(m_engine->jsonRpcClient()->currentHost()->uuid().toString().remove(QRegExp("[{}]")));
|
||||
|
||||
QUrlQuery query;
|
||||
|
||||
query.addQueryItem("t", m_thing->id().toString().remove(QRegExp("[{}]")));
|
||||
|
||||
for (int i = 0; i < m_actions->rowCount(); i++) {
|
||||
RuleAction *action = m_actions->get(i);
|
||||
QStringList params;
|
||||
ActionType *at = m_thing->thingClass()->actionTypes()->getActionType(action->actionTypeId());
|
||||
if (!at) {
|
||||
qWarning() << "ActionType not found in thing" << action->actionTypeId();
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < action->ruleActionParams()->rowCount(); j++) {
|
||||
RuleActionParam *param = action->ruleActionParams()->get(j);
|
||||
ParamType *pt = at->paramTypes()->getParamType(param->paramTypeId());
|
||||
if (!pt) {
|
||||
qWarning() << "ParamType not found in thing";
|
||||
continue;
|
||||
}
|
||||
params.append(pt->name() + ":" + param->value().toByteArray().toPercentEncoding());
|
||||
}
|
||||
QString actionString = at->name();
|
||||
if (params.length() > 0) {
|
||||
actionString += "#" + params.join("+");
|
||||
}
|
||||
query.addQueryItem(QString("a[%1]").arg(i), actionString);
|
||||
}
|
||||
url.setQuery(query);
|
||||
qDebug() << "writing message" << url;
|
||||
|
||||
QNdefNfcUriRecord record;
|
||||
record.setUri(url);
|
||||
QNdefMessage message;
|
||||
message.append(record);
|
||||
|
||||
m_currentMessage = message;
|
||||
emit messageSizeChanged();
|
||||
|
||||
}
|
||||
|
||||
void NfcHelper::targetDetected(QNearFieldTarget *target)
|
||||
{
|
||||
QDateTime startTime = QDateTime::currentDateTime();
|
||||
qDebug() << "target detected";
|
||||
connect(target, &QNearFieldTarget::error, this, [=](QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id){
|
||||
qDebug() << "Tag error:" << error;
|
||||
m_status = TagStatusFailed;
|
||||
emit statusChanged();
|
||||
});
|
||||
connect(target, &QNearFieldTarget::ndefMessagesWritten, this, [=](){
|
||||
qDebug() << "Tag written in" << startTime.msecsTo(QDateTime::currentDateTime());
|
||||
m_status = TagStatusWritten;
|
||||
emit statusChanged();
|
||||
});
|
||||
|
||||
QNearFieldTarget::RequestId m_request = target->writeNdefMessages(QList<QNdefMessage>() << m_currentMessage);
|
||||
if (!m_request.isValid()) {
|
||||
qDebug() << "Error writing tag";
|
||||
m_status = TagStatusFailed;
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
m_status = TagStatusWriting;
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
void NfcHelper::targetLost(QNearFieldTarget *target)
|
||||
{
|
||||
qDebug() << "Target lost" << target;
|
||||
m_status = TagStatusWaiting;
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,70 +2,22 @@
|
|||
#define NFCHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QNearFieldManager>
|
||||
#include <QNdefMessage>
|
||||
|
||||
#include "types/device.h"
|
||||
#include "engine.h"
|
||||
#include "types/ruleactions.h"
|
||||
#include <QQmlEngine>
|
||||
|
||||
class NfcHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Engine *engine READ engine WRITE setEngine NOTIFY engineChanged)
|
||||
Q_PROPERTY(Device *thing READ thing WRITE setThing NOTIFY thingChanged)
|
||||
Q_PROPERTY(RuleActions *actions READ actions CONSTANT)
|
||||
Q_PROPERTY(int messageSize READ messageSize NOTIFY messageSizeChanged)
|
||||
Q_PROPERTY(TagStatus status READ status NOTIFY statusChanged)
|
||||
|
||||
Q_PROPERTY(bool isAvailable READ isAvailable CONSTANT)
|
||||
|
||||
public:
|
||||
enum TagStatus {
|
||||
TagStatusWaiting,
|
||||
TagStatusWriting,
|
||||
TagStatusWritten,
|
||||
TagStatusFailed
|
||||
};
|
||||
Q_ENUM(TagStatus)
|
||||
static NfcHelper* instance();
|
||||
static QObject *nfcHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine);
|
||||
|
||||
explicit NfcHelper(QObject *parent = nullptr);
|
||||
~NfcHelper();
|
||||
|
||||
Engine *engine() const;
|
||||
void setEngine(Engine *engine);
|
||||
|
||||
Device *thing() const;
|
||||
void setThing(Device *thing);
|
||||
|
||||
RuleActions *actions() const;
|
||||
|
||||
int messageSize() const;
|
||||
|
||||
TagStatus status() const;
|
||||
|
||||
signals:
|
||||
void engineChanged();
|
||||
void thingChanged();
|
||||
|
||||
void messageSizeChanged();
|
||||
void statusChanged();
|
||||
|
||||
private slots:
|
||||
void updateContent();
|
||||
|
||||
void targetDetected(QNearFieldTarget *target);
|
||||
void targetLost(QNearFieldTarget *target);
|
||||
bool isAvailable() const;
|
||||
|
||||
private:
|
||||
QNearFieldManager *m_manager = nullptr;
|
||||
Engine *m_engine = nullptr;
|
||||
Device *m_thing = nullptr;
|
||||
RuleActions* m_actions;
|
||||
|
||||
TagStatus m_status = TagStatusWaiting;
|
||||
|
||||
QNdefMessage m_currentMessage;
|
||||
|
||||
explicit NfcHelper(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif // NFCHELPER_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
#include "nfcthingactionwriter.h"
|
||||
#include "types/deviceclass.h"
|
||||
#include "types/statetype.h"
|
||||
#include "types/ruleaction.h"
|
||||
#include "types/ruleactionparams.h"
|
||||
#include "types/ruleactionparam.h"
|
||||
|
||||
#include <QNearFieldManager>
|
||||
#include <QNdefMessage>
|
||||
#include <QDebug>
|
||||
#include <QNdefNfcUriRecord>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
NfcThingActionWriter::NfcThingActionWriter(QObject *parent):
|
||||
QObject(parent),
|
||||
m_manager(new QNearFieldManager(this)),
|
||||
m_actions(new RuleActions(this))
|
||||
{
|
||||
connect(m_manager, &QNearFieldManager::targetDetected, this, &NfcThingActionWriter::targetDetected);
|
||||
connect(m_manager, &QNearFieldManager::targetLost, this, &NfcThingActionWriter::targetLost);
|
||||
|
||||
connect(m_actions, &RuleActions::countChanged, this, &NfcThingActionWriter::updateContent);
|
||||
|
||||
m_manager->startTargetDetection();
|
||||
|
||||
}
|
||||
|
||||
NfcThingActionWriter::~NfcThingActionWriter()
|
||||
{
|
||||
m_manager->stopTargetDetection();
|
||||
}
|
||||
|
||||
bool NfcThingActionWriter::isAvailable() const
|
||||
{
|
||||
return m_manager->isAvailable();
|
||||
}
|
||||
|
||||
Engine *NfcThingActionWriter::engine() const
|
||||
{
|
||||
return m_engine;
|
||||
}
|
||||
|
||||
void NfcThingActionWriter::setEngine(Engine *engine)
|
||||
{
|
||||
if (m_engine != engine) {
|
||||
m_engine = engine;
|
||||
emit engineChanged();
|
||||
updateContent();
|
||||
}
|
||||
}
|
||||
|
||||
Device *NfcThingActionWriter::thing() const
|
||||
{
|
||||
return m_thing;
|
||||
}
|
||||
|
||||
void NfcThingActionWriter::setThing(Device *thing)
|
||||
{
|
||||
if (m_thing != thing) {
|
||||
m_thing = thing;
|
||||
emit thingChanged();
|
||||
updateContent();
|
||||
}
|
||||
}
|
||||
|
||||
RuleActions *NfcThingActionWriter::actions() const
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
int NfcThingActionWriter::messageSize() const
|
||||
{
|
||||
return m_currentMessage.toByteArray().size();
|
||||
int ret = 0;
|
||||
for (int i = 0; i < m_currentMessage.size(); i++) {
|
||||
ret += m_currentMessage.at(i).payload().size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
NfcThingActionWriter::TagStatus NfcThingActionWriter::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
void NfcThingActionWriter::updateContent()
|
||||
{
|
||||
qDebug() << "Updating" << m_engine << m_thing;
|
||||
|
||||
// Creating an URI type record with this format:
|
||||
// nymea://<nymeaId>
|
||||
// ? t=<thingId>
|
||||
// & a[0]=<actionTypeName>
|
||||
// & a[1]=<actionTypeName>#<paramName1>:<paramValue>
|
||||
// & a[2]=<actionTypeName>#<paramName1>:<paramValue>+<paramName2>:<paramValue>
|
||||
// & ...
|
||||
|
||||
// NOTE: We're using actionType and paramType *name* instead of the ID because NFC tags are
|
||||
// small and normally names are shorter than ids so we save some space.
|
||||
|
||||
// NOTE: param values are percentage encoded to prevent messing with the parsing if they
|
||||
// contain + or :
|
||||
|
||||
QUrl url;
|
||||
url.setScheme("nymea");
|
||||
if (!m_engine || !m_thing) {
|
||||
return;
|
||||
}
|
||||
url.setHost(m_engine->jsonRpcClient()->currentHost()->uuid().toString().remove(QRegExp("[{}]")));
|
||||
|
||||
QUrlQuery query;
|
||||
|
||||
query.addQueryItem("t", m_thing->id().toString().remove(QRegExp("[{}]")));
|
||||
|
||||
for (int i = 0; i < m_actions->rowCount(); i++) {
|
||||
RuleAction *action = m_actions->get(i);
|
||||
QStringList params;
|
||||
ActionType *at = m_thing->thingClass()->actionTypes()->getActionType(action->actionTypeId());
|
||||
if (!at) {
|
||||
qWarning() << "ActionType not found in thing" << action->actionTypeId();
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < action->ruleActionParams()->rowCount(); j++) {
|
||||
RuleActionParam *param = action->ruleActionParams()->get(j);
|
||||
ParamType *pt = at->paramTypes()->getParamType(param->paramTypeId());
|
||||
if (!pt) {
|
||||
qWarning() << "ParamType not found in thing";
|
||||
continue;
|
||||
}
|
||||
params.append(pt->name() + ":" + param->value().toByteArray().toPercentEncoding());
|
||||
}
|
||||
QString actionString = at->name();
|
||||
if (params.length() > 0) {
|
||||
actionString += "#" + params.join("+");
|
||||
}
|
||||
query.addQueryItem(QString("a[%1]").arg(i), actionString);
|
||||
}
|
||||
url.setQuery(query);
|
||||
qDebug() << "writing message" << url;
|
||||
|
||||
QNdefNfcUriRecord record;
|
||||
record.setUri(url);
|
||||
QNdefMessage message;
|
||||
message.append(record);
|
||||
|
||||
m_currentMessage = message;
|
||||
emit messageSizeChanged();
|
||||
|
||||
}
|
||||
|
||||
void NfcThingActionWriter::targetDetected(QNearFieldTarget *target)
|
||||
{
|
||||
QDateTime startTime = QDateTime::currentDateTime();
|
||||
qDebug() << "target detected";
|
||||
connect(target, &QNearFieldTarget::error, this, [=](QNearFieldTarget::Error error, const QNearFieldTarget::RequestId &id){
|
||||
qDebug() << "Tag error:" << error;
|
||||
m_status = TagStatusFailed;
|
||||
emit statusChanged();
|
||||
});
|
||||
connect(target, &QNearFieldTarget::ndefMessagesWritten, this, [=](){
|
||||
qDebug() << "Tag written in" << startTime.msecsTo(QDateTime::currentDateTime());
|
||||
m_status = TagStatusWritten;
|
||||
emit statusChanged();
|
||||
});
|
||||
|
||||
QNearFieldTarget::RequestId m_request = target->writeNdefMessages(QList<QNdefMessage>() << m_currentMessage);
|
||||
if (!m_request.isValid()) {
|
||||
qDebug() << "Error writing tag";
|
||||
m_status = TagStatusFailed;
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
m_status = TagStatusWriting;
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
void NfcThingActionWriter::targetLost(QNearFieldTarget *target)
|
||||
{
|
||||
qDebug() << "Target lost" << target;
|
||||
m_status = TagStatusWaiting;
|
||||
emit statusChanged();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef NFCTHINGACTIONWRITER_H
|
||||
#define NFCTHINGACTIONWRITER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QNearFieldManager>
|
||||
#include <QNdefMessage>
|
||||
|
||||
#include "types/device.h"
|
||||
#include "engine.h"
|
||||
#include "types/ruleactions.h"
|
||||
|
||||
class NfcThingActionWriter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool isAvailable READ isAvailable CONSTANT)
|
||||
Q_PROPERTY(Engine *engine READ engine WRITE setEngine NOTIFY engineChanged)
|
||||
Q_PROPERTY(Device *thing READ thing WRITE setThing NOTIFY thingChanged)
|
||||
Q_PROPERTY(RuleActions *actions READ actions CONSTANT)
|
||||
Q_PROPERTY(int messageSize READ messageSize NOTIFY messageSizeChanged)
|
||||
Q_PROPERTY(TagStatus status READ status NOTIFY statusChanged)
|
||||
|
||||
|
||||
public:
|
||||
enum TagStatus {
|
||||
TagStatusWaiting,
|
||||
TagStatusWriting,
|
||||
TagStatusWritten,
|
||||
TagStatusFailed
|
||||
};
|
||||
Q_ENUM(TagStatus)
|
||||
|
||||
static NfcThingActionWriter *instance();
|
||||
|
||||
explicit NfcThingActionWriter(QObject *parent = nullptr);
|
||||
~NfcThingActionWriter();
|
||||
|
||||
bool isAvailable() const;
|
||||
|
||||
Engine *engine() const;
|
||||
void setEngine(Engine *engine);
|
||||
|
||||
Device *thing() const;
|
||||
void setThing(Device *thing);
|
||||
|
||||
RuleActions *actions() const;
|
||||
|
||||
int messageSize() const;
|
||||
|
||||
TagStatus status() const;
|
||||
|
||||
signals:
|
||||
void engineChanged();
|
||||
void thingChanged();
|
||||
|
||||
void messageSizeChanged();
|
||||
void statusChanged();
|
||||
|
||||
private slots:
|
||||
void updateContent();
|
||||
|
||||
void targetDetected(QNearFieldTarget *target);
|
||||
void targetLost(QNearFieldTarget *target);
|
||||
|
||||
private:
|
||||
QNearFieldManager *m_manager = nullptr;
|
||||
Engine *m_engine = nullptr;
|
||||
Device *m_thing = nullptr;
|
||||
RuleActions* m_actions;
|
||||
|
||||
TagStatus m_status = TagStatusWaiting;
|
||||
|
||||
QNdefMessage m_currentMessage;
|
||||
|
||||
};
|
||||
|
||||
#endif // NFCTHINGACTIONWRITER_H
|
||||
|
|
@ -15,6 +15,7 @@ PRE_TARGETDEPS += ../libnymea-app
|
|||
HEADERS += \
|
||||
mainmenumodel.h \
|
||||
nfchelper.h \
|
||||
nfcthingactionwriter.h \
|
||||
platformintegration/generic/raspberrypihelper.h \
|
||||
stylecontroller.h \
|
||||
pushnotifications.h \
|
||||
|
|
@ -26,6 +27,7 @@ HEADERS += \
|
|||
SOURCES += main.cpp \
|
||||
mainmenumodel.cpp \
|
||||
nfchelper.cpp \
|
||||
nfcthingactionwriter.cpp \
|
||||
platformintegration/generic/raspberrypihelper.cpp \
|
||||
stylecontroller.cpp \
|
||||
pushnotifications.cpp \
|
||||
|
|
@ -171,3 +173,5 @@ contains(ANDROID_TARGET_ARCH,) {
|
|||
arm64-v8a
|
||||
}
|
||||
|
||||
ANDROID_ABIS = armeabi-v7a arm64-v8a
|
||||
|
||||
|
|
|
|||
|
|
@ -112,14 +112,19 @@ Page {
|
|||
}))
|
||||
}
|
||||
|
||||
thingMenu.addItem(menuEntryComponent.createObject(thingMenu,
|
||||
{
|
||||
text: qsTr("Write NFC tag"),
|
||||
iconSource: "../images/nfc.svg",
|
||||
functionName: "writeNfcTag"
|
||||
print("*** creating menu")
|
||||
print("NFC", NfcHelper.isAvailable)
|
||||
if (NfcHelper.isAvailable) {
|
||||
thingMenu.addItem(menuEntryComponent.createObject(thingMenu,
|
||||
{
|
||||
text: qsTr("Write NFC tag"),
|
||||
iconSource: "../images/nfc.svg",
|
||||
functionName: "writeNfcTag"
|
||||
|
||||
}));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function openDeviceMagicPage() {
|
||||
pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,10 @@ Page {
|
|||
}
|
||||
|
||||
|
||||
NfcHelper {
|
||||
id: nfcHelper
|
||||
NfcThingActionWriter {
|
||||
id: nfcWriter
|
||||
engine: _engine
|
||||
thing: root.thing
|
||||
|
||||
}
|
||||
// nfcHelper.writeThingStates(engine, root.thing)
|
||||
|
||||
|
|
@ -66,14 +65,14 @@ Page {
|
|||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: {
|
||||
switch (nfcHelper.status) {
|
||||
case NfcHelper.TagStatusWaiting:
|
||||
switch (nfcWriter.status) {
|
||||
case NfcThingActionWriter.TagStatusWaiting:
|
||||
return qsTr("Tap an NFC tag to link it to %1.").arg(root.thing.name)
|
||||
case NfcHelper.TagStatusWriting:
|
||||
case NfcThingActionWriter.TagStatusWriting:
|
||||
return qsTr("Writing NFC tag...")
|
||||
case NfcHelper.TagStatusWritten:
|
||||
case NfcThingActionWriter.TagStatusWritten:
|
||||
return qsTr("NFC tag linked to %1.").arg(root.thing.name)
|
||||
case NfcHelper.TagStatusFailed:
|
||||
case NfcThingActionWriter.TagStatusFailed:
|
||||
return qsTr("Failed linking the NFC tag to %1.").arg(root.thing.name)
|
||||
}
|
||||
}
|
||||
|
|
@ -83,7 +82,7 @@ Page {
|
|||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Required tag size: %1 bytes").arg(nfcHelper.messageSize)
|
||||
text: qsTr("Required tag size: %1 bytes").arg(nfcWriter.messageSize)
|
||||
font.pixelSize: app.smallFont
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
enabled: false
|
||||
|
|
@ -118,7 +117,7 @@ Page {
|
|||
width: app.iconSize * 2
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: - app.iconSize * 2
|
||||
visible: nfcHelper.status == NfcHelper.TagStatusWaiting
|
||||
visible: nfcWriter.status == NfcThingActionWriter.TagStatusWaiting
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
@ -128,7 +127,7 @@ Page {
|
|||
scale: 1.5
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: app.iconSize * 2
|
||||
visible: nfcHelper.status == NfcHelper.TagStatusWaiting
|
||||
visible: nfcWriter.status == NfcThingActionWriter.TagStatusWaiting
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
|
@ -154,15 +153,15 @@ Page {
|
|||
color: app.backgroundColor
|
||||
border.width: 4
|
||||
border.color: app.foregroundColor
|
||||
opacity: nfcHelper.status == NfcHelper.TagStatusWaiting ? 0 : 1
|
||||
opacity: nfcWriter.status == NfcThingActionWriter.TagStatusWaiting ? 0 : 1
|
||||
Behavior on opacity { NumberAnimation { duration: 300 } }
|
||||
|
||||
property bool shown: nfcHelper.status == NfcHelper.TagStatusWritten || nfcHelper.status == NfcHelper.TagStatusFailed
|
||||
property bool shown: nfcWriter.status == NfcThingActionWriter.TagStatusWritten || nfcWriter.status == NfcThingActionWriter.TagStatusFailed
|
||||
|
||||
BusyIndicator {
|
||||
anchors.fill: parent
|
||||
running: visible
|
||||
visible: nfcHelper.status == NfcHelper.TagStatusWriting
|
||||
visible: nfcWriter.status == NfcThingActionWriter.TagStatusWriting
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
@ -176,8 +175,8 @@ Page {
|
|||
y: (tick.height - height) / 2
|
||||
height: app.iconSize * 4
|
||||
width: app.iconSize * 4
|
||||
name: nfcHelper.status == NfcHelper.TagStatusFailed ? "../images/close.svg" : "../images/tick.svg"
|
||||
color: nfcHelper.status == NfcHelper.TagStatusFailed ? "red" : "green"
|
||||
name: nfcWriter.status == NfcThingActionWriter.TagStatusFailed ? "../images/close.svg" : "../images/tick.svg"
|
||||
color: nfcWriter.status == NfcThingActionWriter.TagStatusFailed ? "red" : "green"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -191,12 +190,12 @@ Page {
|
|||
ListView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
model: nfcHelper.actions
|
||||
model: nfcWriter.actions
|
||||
clip: true
|
||||
delegate: RuleActionDelegate {
|
||||
ruleAction: nfcHelper.actions.get(index)
|
||||
ruleAction: nfcWriter.actions.get(index)
|
||||
width: parent.width
|
||||
onRemoveRuleAction: nfcHelper.actions.removeRuleAction(index)
|
||||
onRemoveRuleAction: nfcWriter.actions.removeRuleAction(index)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,11 +204,11 @@ Page {
|
|||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
onClicked: {
|
||||
var action = nfcHelper.actions.createNewRuleAction()
|
||||
var action = nfcWriter.actions.createNewRuleAction()
|
||||
action.thingId = root.thing.id
|
||||
var page = pageStack.push("SelectRuleActionPage.qml", {ruleAction: action});
|
||||
page.done.connect(function() {
|
||||
nfcHelper.actions.addRuleAction(action);
|
||||
nfcWriter.actions.addRuleAction(action);
|
||||
pageStack.pop();
|
||||
})
|
||||
page.backPressed.connect(function() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue