Make the connection establishment non blocking
This commit is contained in:
parent
3bc92633ab
commit
e9c345cc8b
@ -24,18 +24,18 @@ RESOURCES += controlviews/controlviews.qrc \
|
|||||||
INCLUDEPATH += ../nymea-app/
|
INCLUDEPATH += ../nymea-app/
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
androidbinder.cpp \
|
|
||||||
controlviews/devicecontrolapplication.cpp \
|
controlviews/devicecontrolapplication.cpp \
|
||||||
nymeaappservice/nymeaappservice.cpp \
|
nymeaappservice/nymeaappservice.cpp \
|
||||||
|
nymeaappservice/androidbinder.cpp \
|
||||||
../nymea-app/stylecontroller.cpp \
|
../nymea-app/stylecontroller.cpp \
|
||||||
../nymea-app/platformhelper.cpp \
|
../nymea-app/platformhelper.cpp \
|
||||||
../nymea-app/platformintegration/android/platformhelperandroid.cpp \
|
../nymea-app/platformintegration/android/platformhelperandroid.cpp \
|
||||||
service_main.cpp
|
service_main.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
androidbinder.h \
|
|
||||||
controlviews/devicecontrolapplication.h \
|
controlviews/devicecontrolapplication.h \
|
||||||
nymeaappservice/nymeaappservice.h \
|
nymeaappservice/nymeaappservice.h \
|
||||||
|
nymeaappservice/androidbinder.h \
|
||||||
../nymea-app/stylecontroller.h \
|
../nymea-app/stylecontroller.h \
|
||||||
../nymea-app/platformhelper.h \
|
../nymea-app/platformhelper.h \
|
||||||
../nymea-app/platformintegration/android/platformhelperandroid.h \
|
../nymea-app/platformintegration/android/platformhelperandroid.h \
|
||||||
|
|||||||
@ -37,6 +37,8 @@ DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QAp
|
|||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
NymeaDiscovery *discovery = new NymeaDiscovery(this);
|
NymeaDiscovery *discovery = new NymeaDiscovery(this);
|
||||||
|
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
|
||||||
|
discovery->setAwsClient(AWSClient::instance());
|
||||||
|
|
||||||
NymeaHost *host = discovery->nymeaHosts()->find(lastConnected);
|
NymeaHost *host = discovery->nymeaHosts()->find(lastConnected);
|
||||||
qDebug() << "**** Tab settings" << lastConnected << host;
|
qDebug() << "**** Tab settings" << lastConnected << host;
|
||||||
|
|||||||
@ -24,6 +24,7 @@ bool AndroidBinder::onTransact(int code, const QAndroidParcel &data, const QAndr
|
|||||||
case 0: { // Status request
|
case 0: { // Status request
|
||||||
qDebug() << "Engine is:" << m_engine->jsonRpcClient()->connected();
|
qDebug() << "Engine is:" << m_engine->jsonRpcClient()->connected();
|
||||||
bool isReady = m_engine->jsonRpcClient()->connected() && !m_engine->thingManager()->fetchingData();
|
bool isReady = m_engine->jsonRpcClient()->connected() && !m_engine->thingManager()->fetchingData();
|
||||||
|
isReady = false;
|
||||||
reply.handle().callMethod<void>("writeBoolean", "(Z)V", isReady);
|
reply.handle().callMethod<void>("writeBoolean", "(Z)V", isReady);
|
||||||
if (isReady) {
|
if (isReady) {
|
||||||
reply.handle().callMethod<void>("writeString", "(Ljava/lang/String;)V", QAndroidJniObject::fromString(m_engine->jsonRpcClient()->currentHost()->name()).object<jstring>());
|
reply.handle().callMethod<void>("writeString", "(Ljava/lang/String;)V", QAndroidJniObject::fromString(m_engine->jsonRpcClient()->currentHost()->name()).object<jstring>());
|
||||||
@ -34,7 +35,7 @@ bool AndroidBinder::onTransact(int code, const QAndroidParcel &data, const QAndr
|
|||||||
for (int i = 0; i < m_engine->thingManager()->things()->rowCount(); i++) {
|
for (int i = 0; i < m_engine->thingManager()->things()->rowCount(); i++) {
|
||||||
Device *thing = m_engine->thingManager()->things()->get(i);
|
Device *thing = m_engine->thingManager()->things()->get(i);
|
||||||
QVariantMap thingMap;
|
QVariantMap thingMap;
|
||||||
thingMap.insert("id", thing->id().toString());
|
thingMap.insert("id", thing->id());
|
||||||
thingMap.insert("name", thing->name());
|
thingMap.insert("name", thing->name());
|
||||||
thingMap.insert("className", thing->thingClass()->displayName());
|
thingMap.insert("className", thing->thingClass()->displayName());
|
||||||
thingMap.insert("interfaces", thing->thingClass()->interfaces());
|
thingMap.insert("interfaces", thing->thingClass()->interfaces());
|
||||||
@ -42,7 +43,7 @@ bool AndroidBinder::onTransact(int code, const QAndroidParcel &data, const QAndr
|
|||||||
for (int j = 0; j < thing->states()->rowCount(); j++) {
|
for (int j = 0; j < thing->states()->rowCount(); j++) {
|
||||||
State *state = thing->states()->get(j);
|
State *state = thing->states()->get(j);
|
||||||
QVariantMap stateMap;
|
QVariantMap stateMap;
|
||||||
stateMap.insert("stateTypeId", state->stateTypeId().toString());
|
stateMap.insert("stateTypeId", state->stateTypeId());
|
||||||
stateMap.insert("name", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->name());
|
stateMap.insert("name", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->name());
|
||||||
stateMap.insert("displayName", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->displayName());
|
stateMap.insert("displayName", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->displayName());
|
||||||
stateMap.insert("value", state->value());
|
stateMap.insert("value", state->value());
|
||||||
@ -53,7 +54,7 @@ bool AndroidBinder::onTransact(int code, const QAndroidParcel &data, const QAndr
|
|||||||
for (int j = 0; j < thing->thingClass()->actionTypes()->rowCount(); j++) {
|
for (int j = 0; j < thing->thingClass()->actionTypes()->rowCount(); j++) {
|
||||||
ActionType *actionType = thing->thingClass()->actionTypes()->get(j);
|
ActionType *actionType = thing->thingClass()->actionTypes()->get(j);
|
||||||
QVariantMap actionMap;
|
QVariantMap actionMap;
|
||||||
actionMap.insert("actionTypeId", actionType->id().toString());
|
actionMap.insert("actionTypeId", actionType->id());
|
||||||
actionMap.insert("name", actionType->name());
|
actionMap.insert("name", actionType->name());
|
||||||
actionMap.insert("displayName", actionType->displayName());
|
actionMap.insert("displayName", actionType->displayName());
|
||||||
actions.append(actionMap);
|
actions.append(actionMap);
|
||||||
@ -4,40 +4,61 @@
|
|||||||
#include <QtAndroid>
|
#include <QtAndroid>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "connection/discovery/nymeadiscovery.h"
|
#include "connection/discovery/nymeadiscovery.h"
|
||||||
#include "connection/nymeahosts.h"
|
#include "connection/nymeahosts.h"
|
||||||
|
|
||||||
NymeaAppService::NymeaAppService(int argc, char **argv):
|
NymeaAppService::NymeaAppService(int argc, char **argv):
|
||||||
QAndroidService(argc, argv, [=](const QAndroidIntent &) {
|
QAndroidService(argc, argv, [=](const QAndroidIntent &) {
|
||||||
qDebug() << "Android service onBind()";
|
|
||||||
return new AndroidBinder{m_engine};
|
return new AndroidBinder{m_engine};
|
||||||
}),
|
})
|
||||||
m_engine(new Engine(this))
|
|
||||||
{
|
{
|
||||||
setApplicationName("nymea-app");
|
setApplicationName("nymea-app");
|
||||||
setOrganizationName("nymea");
|
setOrganizationName("nymea");
|
||||||
|
|
||||||
|
m_engine = new Engine(this);
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup("tabSettings0");
|
settings.beginGroup("tabSettings0");
|
||||||
QUuid lastConnected = settings.value("lastConnectedHost").toUuid();
|
QUuid lastConnected = settings.value("lastConnectedHost").toUuid();
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
NymeaDiscovery *discovery = new NymeaDiscovery();
|
NymeaDiscovery *discovery = new NymeaDiscovery(this);
|
||||||
|
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
|
||||||
|
discovery->setAwsClient(AWSClient::instance());
|
||||||
|
|
||||||
NymeaHost *host = discovery->nymeaHosts()->find(lastConnected);
|
NymeaHost *host = discovery->nymeaHosts()->find(lastConnected);
|
||||||
qDebug() << "**** Tab settings" << lastConnected << host;
|
|
||||||
if (host) {
|
if (host) {
|
||||||
m_engine->jsonRpcClient()->connectToHost(host);
|
m_engine->jsonRpcClient()->connectToHost(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect(m_engine->thingManager(), &DeviceManager::thingStateChanged, [=](const QUuid &thingId, const QUuid &stateTypeId, const QVariant &value){
|
QObject::connect(m_engine->thingManager(), &DeviceManager::thingStateChanged, [=](const QUuid &thingId, const QUuid &stateTypeId, const QVariant &value){
|
||||||
// qDebug() << "**** State changed" << thingId << stateTypeId << value;
|
QVariantMap params;
|
||||||
QtAndroid::androidService().callMethod<void>("sendBroadcast", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
params.insert("thingId", thingId);
|
||||||
QAndroidJniObject::fromString(thingId.toString()).object<jstring>(),
|
params.insert("stateTypeId", stateTypeId);
|
||||||
QAndroidJniObject::fromString(stateTypeId.toString()).object<jstring>(),
|
params.insert("value", value);
|
||||||
QAndroidJniObject::fromString(value.toString()).object<jstring>());
|
sendNotification("ThingStateChanged", params);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(m_engine->thingManager(), &DeviceManager::fetchingDataChanged, [=]() {
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("isReady", !m_engine->thingManager()->fetchingData());
|
||||||
|
if (m_engine->jsonRpcClient()->connected()) {
|
||||||
|
params.insert("systemName", m_engine->jsonRpcClient()->currentHost()->name());
|
||||||
|
}
|
||||||
|
sendNotification("ReadyStateChanged", params);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void NymeaAppService::sendNotification(const QString ¬ification, const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
QVariantMap data;
|
||||||
|
data.insert("notification", notification);
|
||||||
|
data.insert("params", params);
|
||||||
|
QString payload = QJsonDocument::fromVariant(data).toJson();
|
||||||
|
QtAndroid::androidService().callMethod<void>("sendBroadcast",
|
||||||
|
"(Ljava/lang/String;)V",
|
||||||
|
QAndroidJniObject::fromString(payload).object<jstring>());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,10 @@ class NymeaAppService : public QAndroidService
|
|||||||
public:
|
public:
|
||||||
explicit NymeaAppService(int argc, char** argv);
|
explicit NymeaAppService(int argc, char** argv);
|
||||||
|
|
||||||
signals:
|
private:
|
||||||
|
void sendNotification(const QString ¬ification, const QVariantMap ¶ms);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Engine *m_engine = nullptr;
|
Engine *m_engine = nullptr;
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package io.guh.nymeaapp;
|
package io.guh.nymeaapp;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class Action {
|
public class Action {
|
||||||
public String typeId;
|
public UUID typeId;
|
||||||
public String name;
|
public String name;
|
||||||
public String displayName;
|
public String displayName;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import java.util.concurrent.Flow.Publisher;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import io.reactivex.Flowable;
|
import io.reactivex.Flowable;
|
||||||
import io.reactivex.processors.ReplayProcessor;
|
import io.reactivex.processors.ReplayProcessor;
|
||||||
@ -46,8 +47,9 @@ public class NymeaAppControlService extends ControlsProviderService {
|
|||||||
@Override public void onReady() {
|
@Override public void onReady() {
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
@Override public void onUpdate(String thingId) {
|
@Override public void onUpdate(UUID thingId) {
|
||||||
if (m_updatePublisher != null && m_activeControlIds.contains(thingId)) {
|
Log.d(TAG, "onUpdate()");
|
||||||
|
if (m_updatePublisher != null && m_activeControlIds.contains(thingId.toString())) {
|
||||||
Thing thing = m_serviceConnection.getThing(thingId);
|
Thing thing = m_serviceConnection.getThing(thingId);
|
||||||
Log.d(TAG, "Updating publisher for thing: " + thing.name + " id: " + thing.id);
|
Log.d(TAG, "Updating publisher for thing: " + thing.name + " id: " + thing.id);
|
||||||
m_updatePublisher.onNext(thingToControl(thing));
|
m_updatePublisher.onNext(thingToControl(thing));
|
||||||
@ -79,7 +81,7 @@ public class NymeaAppControlService extends ControlsProviderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_updatePublisher != null) {
|
if (m_updatePublisher != null) {
|
||||||
if (m_activeControlIds.contains(thing.id)) {
|
if (m_activeControlIds.contains(thing.id.toString())) {
|
||||||
Log.d(TAG, "Adding stateful");
|
Log.d(TAG, "Adding stateful");
|
||||||
m_updatePublisher.onNext(thingToControl(thing));
|
m_updatePublisher.onNext(thingToControl(thing));
|
||||||
}
|
}
|
||||||
@ -123,14 +125,14 @@ public class NymeaAppControlService extends ControlsProviderService {
|
|||||||
//// pendingAction.consumer = consumer;
|
//// pendingAction.consumer = consumer;
|
||||||
//// m_pendingActions.put(
|
//// m_pendingActions.put(
|
||||||
|
|
||||||
Thing thing = m_serviceConnection.getThing(controlId);
|
Thing thing = m_serviceConnection.getThing(UUID.fromString(controlId));
|
||||||
if (thing == null) {
|
if (thing == null) {
|
||||||
Log.d(TAG, "Thing not found for id: " + controlId);
|
Log.d(TAG, "Thing not found for id: " + controlId);
|
||||||
consumer.accept(ControlAction.RESPONSE_FAIL);
|
consumer.accept(ControlAction.RESPONSE_FAIL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String actionTypeId;
|
UUID actionTypeId;
|
||||||
String param;
|
String param;
|
||||||
if (thing.interfaces.contains("dimmablelight") && action instanceof FloatAction) {
|
if (thing.interfaces.contains("dimmablelight") && action instanceof FloatAction) {
|
||||||
actionTypeId = thing.stateByName("brightness").typeId;
|
actionTypeId = thing.stateByName("brightness").typeId;
|
||||||
@ -165,7 +167,7 @@ public class NymeaAppControlService extends ControlsProviderService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashMap<String, Integer> m_intents = new HashMap<String, Integer>();
|
private HashMap<UUID, Integer> m_intents = new HashMap<UUID, Integer>();
|
||||||
|
|
||||||
private Control thingToControl(Thing thing) {
|
private Control thingToControl(Thing thing) {
|
||||||
// Log.d(TAG, "Creating control for thing: " + thing.name + " id: " + thing.id);
|
// Log.d(TAG, "Creating control for thing: " + thing.name + " id: " + thing.id);
|
||||||
@ -182,23 +184,23 @@ public class NymeaAppControlService extends ControlsProviderService {
|
|||||||
Context context = getBaseContext();
|
Context context = getBaseContext();
|
||||||
Intent intent = new Intent(context, NymeaAppControlsActivity.class);
|
Intent intent = new Intent(context, NymeaAppControlsActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||||
intent.putExtra("thingId", thing.id);
|
intent.putExtra("thingId", thing.id.toString());
|
||||||
pi = PendingIntent.getActivity(context, intentId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
pi = PendingIntent.getActivity(context, intentId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
Log.d(TAG, "Created pendingintent for " + thing.name + " with id " + intentId + " and extra " + thing.id);
|
Log.d(TAG, "Created pendingintent for " + thing.name + " with id " + intentId + " and extra " + thing.id);
|
||||||
|
|
||||||
Control.StatefulBuilder builder = new Control.StatefulBuilder(thing.id, pi)
|
Control.StatefulBuilder builder = new Control.StatefulBuilder(thing.id.toString(), pi)
|
||||||
.setTitle(thing.name)
|
.setTitle(thing.name)
|
||||||
.setSubtitle(thing.className)
|
.setSubtitle(thing.className)
|
||||||
.setStructure(m_serviceConnection.nymeaName());
|
.setStructure(m_serviceConnection.nymeaName());
|
||||||
|
|
||||||
if (thing.interfaces.contains("impulsebasedgaragedoor")) {
|
if (thing.interfaces.contains("impulsebasedgaragedoor")) {
|
||||||
builder.setDeviceType(DeviceTypes.TYPE_GARAGE);
|
builder.setDeviceType(DeviceTypes.TYPE_GARAGE);
|
||||||
builder.setControlTemplate(new StatelessTemplate(thing.id));
|
builder.setControlTemplate(new StatelessTemplate(thing.id.toString()));
|
||||||
} else if (thing.interfaces.contains("statefulgaragedoor")) {
|
} else if (thing.interfaces.contains("statefulgaragedoor")) {
|
||||||
builder.setDeviceType(DeviceTypes.TYPE_GARAGE);
|
builder.setDeviceType(DeviceTypes.TYPE_GARAGE);
|
||||||
State stateState = thing.stateByName("state");
|
State stateState = thing.stateByName("state");
|
||||||
ControlButton controlButton = new ControlButton(stateState.value.equals("open"), stateState.displayName);
|
ControlButton controlButton = new ControlButton(stateState.value.equals("open"), stateState.displayName);
|
||||||
builder.setControlTemplate(new ToggleTemplate(thing.id, controlButton));
|
builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton));
|
||||||
|
|
||||||
// } else if (thing.interfaces.contains("extendedstatefulgaragedoor")) {
|
// } else if (thing.interfaces.contains("extendedstatefulgaragedoor")) {
|
||||||
// builder.setDeviceTyoe(DeviceTypes.TYPE_GARAGE);
|
// builder.setDeviceTyoe(DeviceTypes.TYPE_GARAGE);
|
||||||
@ -210,16 +212,16 @@ public class NymeaAppControlService extends ControlsProviderService {
|
|||||||
|
|
||||||
if (thing.interfaces.contains("dimmablelight")) {
|
if (thing.interfaces.contains("dimmablelight")) {
|
||||||
State brightnessState = thing.stateByName("brightness");
|
State brightnessState = thing.stateByName("brightness");
|
||||||
RangeTemplate rangeTemplate = new RangeTemplate(thing.id, 0, 100, Float.parseFloat(brightnessState.value), 1, brightnessState.displayName);
|
RangeTemplate rangeTemplate = new RangeTemplate(thing.id.toString(), 0, 100, Float.parseFloat(brightnessState.value), 1, brightnessState.displayName);
|
||||||
builder.setControlTemplate(new ToggleRangeTemplate(thing.id, controlButton, rangeTemplate));
|
builder.setControlTemplate(new ToggleRangeTemplate(thing.id.toString(), controlButton, rangeTemplate));
|
||||||
} else {
|
} else {
|
||||||
builder.setControlTemplate(new ToggleTemplate(thing.id, controlButton));
|
builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton));
|
||||||
}
|
}
|
||||||
} else if (thing.interfaces.contains("powersocket")) {
|
} else if (thing.interfaces.contains("powersocket")) {
|
||||||
builder.setDeviceType(DeviceTypes.TYPE_OUTLET);
|
builder.setDeviceType(DeviceTypes.TYPE_OUTLET);
|
||||||
State powerState = thing.stateByName("power");
|
State powerState = thing.stateByName("power");
|
||||||
ControlButton controlButton = new ControlButton(powerState.value.equals("true"), powerState.displayName);
|
ControlButton controlButton = new ControlButton(powerState.value.equals("true"), powerState.displayName);
|
||||||
builder.setControlTemplate(new ToggleTemplate(thing.id, controlButton));
|
builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton));
|
||||||
} else if (thing.interfaces.contains("mediaplayer")) {
|
} else if (thing.interfaces.contains("mediaplayer")) {
|
||||||
if (thing.stateByName("playerType").value == "video") {
|
if (thing.stateByName("playerType").value == "video") {
|
||||||
builder.setDeviceType(DeviceTypes.TYPE_TV);
|
builder.setDeviceType(DeviceTypes.TYPE_TV);
|
||||||
@ -229,7 +231,7 @@ public class NymeaAppControlService extends ControlsProviderService {
|
|||||||
}
|
}
|
||||||
if (thing.interfaces.contains("extendedvolumecontroller")) {
|
if (thing.interfaces.contains("extendedvolumecontroller")) {
|
||||||
State volumeState = thing.stateByName("volume");
|
State volumeState = thing.stateByName("volume");
|
||||||
RangeTemplate rangeTemplate = new RangeTemplate(thing.id, 0, 100, Float.parseFloat(volumeState.value), 1, volumeState.displayName);
|
RangeTemplate rangeTemplate = new RangeTemplate(thing.id.toString(), 0, 100, Float.parseFloat(volumeState.value), 1, volumeState.displayName);
|
||||||
builder.setControlTemplate(rangeTemplate);
|
builder.setControlTemplate(rangeTemplate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import org.qtproject.qt5.android.bindings.QtService;
|
|||||||
|
|
||||||
public class NymeaAppService extends QtService
|
public class NymeaAppService extends QtService
|
||||||
{
|
{
|
||||||
public static final String BROADCAST_STATE_CHANGE = "io.guh.nymeaapp.NymeaAppService.broadcast.stateChanged";
|
public static final String NYMEA_APP_BROADCAST = "io.guh.nymeaapp.NymeaAppService.broadcast";
|
||||||
|
|
||||||
private static final String TAG = "nymea-app: NymeaAppService";
|
private static final String TAG = "nymea-app: NymeaAppService";
|
||||||
|
|
||||||
@ -40,13 +40,10 @@ public class NymeaAppService extends QtService
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendBroadcast(String thingId, String stateTypeId, String value) {
|
public void sendBroadcast(String payload) {
|
||||||
Intent sendToUiIntent = new Intent();
|
Intent sendToUiIntent = new Intent();
|
||||||
sendToUiIntent.setAction(BROADCAST_STATE_CHANGE);
|
sendToUiIntent.setAction(NYMEA_APP_BROADCAST);
|
||||||
sendToUiIntent.putExtra("name", "io.guh.nymeaapp.NymeaAppService");
|
sendToUiIntent.putExtra("data", payload);
|
||||||
sendToUiIntent.putExtra("thingId", thingId);
|
|
||||||
sendToUiIntent.putExtra("stateTypeId", stateTypeId);
|
|
||||||
sendToUiIntent.putExtra("value", value);
|
|
||||||
// Log.d(TAG, "Service sending broadcast");
|
// Log.d(TAG, "Service sending broadcast");
|
||||||
sendBroadcast(sendToUiIntent);
|
sendBroadcast(sendToUiIntent);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package io.guh.nymeaapp;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
final public ArrayList<Thing> getThings() {
|
final public ArrayList<Thing> getThings() {
|
||||||
return m_things;
|
return m_things;
|
||||||
}
|
}
|
||||||
final public Thing getThing(String thingId) {
|
final public Thing getThing(UUID thingId) {
|
||||||
for (int i = 0; i < m_things.size(); i++) {
|
for (int i = 0; i < m_things.size(); i++) {
|
||||||
if (m_things.get(i).id.equals(thingId)) {
|
if (m_things.get(i).id.equals(thingId)) {
|
||||||
return m_things.get(i);
|
return m_things.get(i);
|
||||||
@ -70,13 +71,13 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
|
|
||||||
public void onReady() {}
|
public void onReady() {}
|
||||||
public void onError() {}
|
public void onError() {}
|
||||||
public void onUpdate(String thingId) {}
|
public void onUpdate(UUID thingId) {}
|
||||||
|
|
||||||
final public void executeAction(String thingId, String actionTypeId, String param) {
|
final public void executeAction(UUID thingId, UUID actionTypeId, String param) {
|
||||||
try {
|
try {
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
parcel.writeByteArray(thingId.getBytes());
|
parcel.writeByteArray(thingId.toString().getBytes());
|
||||||
parcel.writeByteArray(actionTypeId.getBytes());
|
parcel.writeByteArray(actionTypeId.toString().getBytes());
|
||||||
parcel.writeByteArray(param.getBytes());
|
parcel.writeByteArray(param.getBytes());
|
||||||
Parcel retParcel = Parcel.obtain();
|
Parcel retParcel = Parcel.obtain();
|
||||||
m_service.transact(2, parcel, retParcel, 0);
|
m_service.transact(2, parcel, retParcel, 0);
|
||||||
@ -90,29 +91,87 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
Log.d(TAG, "Connected to NymeaAppService");
|
Log.d(TAG, "Connected to NymeaAppService");
|
||||||
m_service = service;
|
m_service = service;
|
||||||
|
|
||||||
|
registerServiceBroadcastReceiver();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
boolean ready = false;
|
Parcel parcel = Parcel.obtain();
|
||||||
Log.d(TAG, "Waiting for service to be connected to nymea...");
|
Parcel retParcel = Parcel.obtain();
|
||||||
do {
|
m_service.transact(0, parcel, retParcel, 0);
|
||||||
Parcel parcel = Parcel.obtain();
|
m_isReady = retParcel.readBoolean();
|
||||||
Parcel retParcel = Parcel.obtain();
|
if (!m_isReady) {
|
||||||
m_service.transact(0, parcel, retParcel, 0);
|
m_nymeaName = retParcel.readString();
|
||||||
ready = retParcel.readBoolean();
|
m_isConnectedToNymea = true;
|
||||||
if (!ready) {
|
Log.d(TAG, "Service is ready!");
|
||||||
Thread.sleep(100);
|
fetchThings();
|
||||||
} else {
|
} else {
|
||||||
m_nymeaName = retParcel.readString();
|
Log.d(TAG, "Service is not ready yet!");
|
||||||
}
|
}
|
||||||
} while (!ready);
|
|
||||||
Log.d(TAG, "Service connected to nymea!");
|
|
||||||
m_isConnectedToNymea = true;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG, "Error while waiting for service to be connected to nymea");
|
Log.d(TAG, "Error while waiting for service to be connected to nymea");
|
||||||
m_service = null;
|
m_service = null;
|
||||||
onError();
|
onError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void onServiceDisconnected(ComponentName arg0) {
|
||||||
|
m_service = null;
|
||||||
|
m_isConnectedToNymea = false;
|
||||||
|
m_isReady = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerServiceBroadcastReceiver() {
|
||||||
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(NymeaAppService.NYMEA_APP_BROADCAST);
|
||||||
|
m_context.registerReceiver(serviceMessageReceiver, intentFilter);
|
||||||
|
Log.d(TAG, "Registered broadcast receiver");
|
||||||
|
}
|
||||||
|
|
||||||
|
private BroadcastReceiver serviceMessageReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
// Log.d(TAG, "In OnReceive broadcast receiver");
|
||||||
|
if (NymeaAppService.NYMEA_APP_BROADCAST.equals(intent.getAction())) {
|
||||||
|
String payload = intent.getStringExtra("data");
|
||||||
|
try {
|
||||||
|
processBroadcast(payload);
|
||||||
|
} catch(JSONException e) {
|
||||||
|
Log.d(TAG, "Error parsing broadcast JSON: " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void processBroadcast(String payload) throws JSONException
|
||||||
|
{
|
||||||
|
JSONObject data = new JSONObject(payload);
|
||||||
|
JSONObject params = data.getJSONObject("params");
|
||||||
|
Log.d(TAG, "Broadcast received from NymeaAppService: " + data.getString("notification"));
|
||||||
|
|
||||||
|
if (data.getString("notification").equals("ThingStateChanged")) {
|
||||||
|
UUID thingId = UUID.fromString(params.getString("thingId"));
|
||||||
|
UUID stateTypeId = UUID.fromString(params.getString("stateTypeId"));
|
||||||
|
String value = params.getString("value");
|
||||||
|
Log.d(TAG, "Thing state changed: " + thingId + " stateTypeId: " + stateTypeId + " value: " + value);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_things.size(); i++) {
|
||||||
|
if (m_things.get(i).id.equals(thingId)) {
|
||||||
|
m_things.get(i).stateById(stateTypeId).value = value;
|
||||||
|
onUpdate(thingId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.getString("notification").equals("ReadyStateChanged")) {
|
||||||
|
m_isReady = params.getBoolean("isReady");
|
||||||
|
if (m_isReady) {
|
||||||
|
m_nymeaName = params.getString("systemName");
|
||||||
|
fetchThings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchThings() {
|
||||||
String thingsList;
|
String thingsList;
|
||||||
try {
|
try {
|
||||||
Log.d(TAG, "Fetching things");
|
Log.d(TAG, "Fetching things");
|
||||||
@ -135,7 +194,7 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
for (int i = 0; i < arr.length(); i++) {
|
for (int i = 0; i < arr.length(); i++) {
|
||||||
JSONObject entry = arr.getJSONObject(i);
|
JSONObject entry = arr.getJSONObject(i);
|
||||||
Thing thing = new Thing();
|
Thing thing = new Thing();
|
||||||
thing.id = entry.getString("id");
|
thing.id = UUID.fromString(entry.getString("id"));
|
||||||
thing.name = entry.getString("name");
|
thing.name = entry.getString("name");
|
||||||
thing.className = entry.getString("className");
|
thing.className = entry.getString("className");
|
||||||
JSONArray ifaces = entry.getJSONArray("interfaces");
|
JSONArray ifaces = entry.getJSONArray("interfaces");
|
||||||
@ -146,7 +205,7 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
for (int j = 0; j < states.length(); j++) {
|
for (int j = 0; j < states.length(); j++) {
|
||||||
JSONObject stateMap = states.getJSONObject(j);
|
JSONObject stateMap = states.getJSONObject(j);
|
||||||
State s = new State();
|
State s = new State();
|
||||||
s.typeId = stateMap.getString("stateTypeId");
|
s.typeId = UUID.fromString(stateMap.getString("stateTypeId"));
|
||||||
s.name = stateMap.getString("name");
|
s.name = stateMap.getString("name");
|
||||||
s.displayName = stateMap.getString("displayName");
|
s.displayName = stateMap.getString("displayName");
|
||||||
s.value = stateMap.getString("value");
|
s.value = stateMap.getString("value");
|
||||||
@ -156,7 +215,7 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
for (int j = 0; j < actions.length(); j++) {
|
for (int j = 0; j < actions.length(); j++) {
|
||||||
JSONObject actionMap = actions.getJSONObject(j);
|
JSONObject actionMap = actions.getJSONObject(j);
|
||||||
Action a = new Action();
|
Action a = new Action();
|
||||||
a.typeId = actionMap.getString("actionTypeId");
|
a.typeId = UUID.fromString(actionMap.getString("actionTypeId"));
|
||||||
a.name = actionMap.getString("name");
|
a.name = actionMap.getString("name");
|
||||||
a.displayName = actionMap.getString("displayName");
|
a.displayName = actionMap.getString("displayName");
|
||||||
thing.actions.add(a);
|
thing.actions.add(a);
|
||||||
@ -165,7 +224,7 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d(TAG, "Error parsing JSON from NymeaAppService: " + thingsList);
|
Log.d(TAG, "Error parsing JSON from NymeaAppService: " + e.toString());
|
||||||
m_service = null;
|
m_service = null;
|
||||||
m_isConnectedToNymea = false;
|
m_isConnectedToNymea = false;
|
||||||
onError();
|
onError();
|
||||||
@ -175,40 +234,5 @@ public class NymeaAppServiceConnection implements ServiceConnection {
|
|||||||
Log.d(TAG, "Fetched things");
|
Log.d(TAG, "Fetched things");
|
||||||
m_isReady = true;
|
m_isReady = true;
|
||||||
onReady();
|
onReady();
|
||||||
|
|
||||||
registerServiceBroadcastReceiver();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onServiceDisconnected(ComponentName arg0) {
|
|
||||||
m_service = null;
|
|
||||||
m_isConnectedToNymea = false;
|
|
||||||
m_isReady = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerServiceBroadcastReceiver() {
|
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
|
||||||
intentFilter.addAction(NymeaAppService.BROADCAST_STATE_CHANGE);
|
|
||||||
m_context.registerReceiver(serviceMessageReceiver, intentFilter);
|
|
||||||
Log.d(TAG, "Registered broadcast receiver");
|
|
||||||
}
|
|
||||||
private BroadcastReceiver serviceMessageReceiver = new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
// Log.d(TAG, "In OnReceive broadcast receiver");
|
|
||||||
if (NymeaAppService.BROADCAST_STATE_CHANGE.equals(intent.getAction())) {
|
|
||||||
String name = intent.getStringExtra("name");
|
|
||||||
String thingId = intent.getStringExtra("thingId");
|
|
||||||
String stateTypeId = intent.getStringExtra("stateTypeId");
|
|
||||||
String value = intent.getStringExtra("value");
|
|
||||||
// Log.d(TAG, "Thing state changed: " + thingId + " stateTypeId: " + stateTypeId + " value: " + value);
|
|
||||||
|
|
||||||
for (int i = 0; i < m_things.size(); i++) {
|
|
||||||
if (m_things.get(i).id.equals(thingId)) {
|
|
||||||
m_things.get(i).stateById(stateTypeId).value = value;
|
|
||||||
onUpdate(thingId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package io.guh.nymeaapp;
|
package io.guh.nymeaapp;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class State {
|
public class State {
|
||||||
public String typeId;
|
public UUID typeId;
|
||||||
public String name;
|
public String name;
|
||||||
public String displayName;
|
public String displayName;
|
||||||
public String value;
|
public String value;
|
||||||
|
|||||||
@ -4,10 +4,12 @@ import android.util.Log;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
public class Thing {
|
public class Thing {
|
||||||
static final public String TAG = "nymea-app: Thing";
|
static final public String TAG = "nymea-app: Thing";
|
||||||
public String id;
|
public UUID id;
|
||||||
public String name;
|
public String name;
|
||||||
public String className;
|
public String className;
|
||||||
public List interfaces = new ArrayList<State>();
|
public List interfaces = new ArrayList<State>();
|
||||||
@ -24,7 +26,7 @@ public class Thing {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public State stateById(String stateTypeId) {
|
public State stateById(UUID stateTypeId) {
|
||||||
for (int i = 0; i < states.size(); i++) {
|
for (int i = 0; i < states.size(); i++) {
|
||||||
if (states.get(i).typeId.equals(stateTypeId)) {
|
if (states.get(i).typeId.equals(stateTypeId)) {
|
||||||
return states.get(i);
|
return states.get(i);
|
||||||
@ -43,7 +45,7 @@ public class Thing {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action actionById(String actionTypeId) {
|
public Action actionById(UUID actionTypeId) {
|
||||||
for (int i = 0; i < actions.size(); i++) {
|
for (int i = 0; i < actions.size(); i++) {
|
||||||
if (actions.get(i).typeId.equals(actionTypeId)) {
|
if (actions.get(i).typeId.equals(actionTypeId)) {
|
||||||
return actions.get(i);
|
return actions.get(i);
|
||||||
|
|||||||
Reference in New Issue
Block a user