summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevron Rees <tripzero.kev@gmail.com>2014-10-20 08:18:12 -0700
committerKevron Rees <tripzero.kev@gmail.com>2014-10-20 08:18:12 -0700
commit5051c66de77c5e939c141c90056120c694446696 (patch)
treec696f1b970c6bd0596641e5a9e485b24cec8ea4a
parentdd8c4aa58c18868fba3c0864100a30419ff766cb (diff)
parentdc11e75d65586128e34dc7df69cb6cdc947f7087 (diff)
downloadautomotive-message-broker-5051c66de77c5e939c141c90056120c694446696.tar.gz
Merge pull request #26 from tripzero/master
bluemonkey features
-rw-r--r--ambd/core.cpp18
-rw-r--r--ambd/core.h21
-rw-r--r--ambd/pluginloader.h2
-rw-r--r--examples/bluemonkey/bluemonkeyconfig18
-rw-r--r--examples/bluemonkey/bluemonkeyconfig.in6
-rw-r--r--lib/abstractpropertytype.h122
-rw-r--r--lib/asyncqueue.hpp9
-rw-r--r--lib/listplusplus.h36
-rw-r--r--plugins/bluemonkey/CMakeLists.txt20
-rw-r--r--plugins/bluemonkey/bluemonkey.cpp107
-rw-r--r--plugins/bluemonkey/bluemonkey.h13
-rw-r--r--plugins/bluemonkey/irccoms.cpp17
-rw-r--r--plugins/bluemonkey/irccoms.h2
-rw-r--r--plugins/dbus/dbusplugin.cpp3
-rw-r--r--plugins/dbus/environmentproperties.h2
-rw-r--r--plugins/dbus/maintenance.h2
-rw-r--r--plugins/dbus/varianttype.cpp4
-rw-r--r--plugins/obd2plugin/obd2source.cpp9
-rw-r--r--plugins/obd2plugin/obd2source.h3
-rw-r--r--plugins/websocket/websocketsource.cpp94
-rw-r--r--plugins/websocket/websocketsource.h9
-rw-r--r--plugins/wheel/wheelplugin.cpp7
22 files changed, 367 insertions, 157 deletions
diff --git a/ambd/core.cpp b/ambd/core.cpp
index 9911cc10..277ba5a6 100644
--- a/ambd/core.cpp
+++ b/ambd/core.cpp
@@ -157,11 +157,29 @@ void Core::updateProperty(AbstractPropertyType *value, const string & uuid)
if(value->priority == AbstractPropertyType::Instant)
updateProperty(value);
else if(value->priority == AbstractPropertyType::High)
+ {
+ value->destroyed.push_back([this](AbstractPropertyType* v)
+ {
+ updatePropertyQueueHigh.remove(v);
+ });
updatePropertyQueueHigh.append(value);
+ }
else if(value->priority == AbstractPropertyType::Normal)
+ {
+ value->destroyed.push_back([this](AbstractPropertyType* v)
+ {
+ updatePropertyQueue.remove(v);
+ });
updatePropertyQueue.append(value);
+ }
else if(value->priority == AbstractPropertyType::Low)
+ {
+ value->destroyed.push_back([this](AbstractPropertyType* v)
+ {
+ updatePropertyQueueLow.remove(v);
+ });
updatePropertyQueueLow.append(value);
+ }
}
void Core::updateProperty(AbstractPropertyType * value)
diff --git a/ambd/core.h b/ambd/core.h
index 4ff68ef7..7bdcc886 100644
--- a/ambd/core.h
+++ b/ambd/core.h
@@ -29,27 +29,6 @@
#include <unordered_set>
#include <map>
-namespace amb
-{
-
-struct PropertyCompare
-{
- bool operator()(AbstractPropertyType* const & lhs, AbstractPropertyType* & rhs) const
- {
- if (lhs->name == rhs->name
- && lhs->sourceUuid == rhs->sourceUuid
- && lhs->zone == rhs->zone)
- {
- return true;
- }
-
- return false;
- }
-
-};
-
-}
-
class Core: public AbstractRoutingEngine
{
diff --git a/ambd/pluginloader.h b/ambd/pluginloader.h
index e92dfb38..cdc6e8f7 100644
--- a/ambd/pluginloader.h
+++ b/ambd/pluginloader.h
@@ -74,7 +74,7 @@ private: ///methods:
if(f_create)
{
void* obj = f_create(routingEngine, config);
- return static_cast<T>( obj );
+ return static_cast<T>(obj);
}
return nullptr;
diff --git a/examples/bluemonkey/bluemonkeyconfig b/examples/bluemonkey/bluemonkeyconfig
deleted file mode 100644
index fb0080c8..00000000
--- a/examples/bluemonkey/bluemonkeyconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "mainloop" : "/usr/lib/i386-linux-gnu/automotive-message-broker/automotive-message-broker/qtmainloopplugin.so",
-
- "sources" : [
- {
- "path" : "/usr/lib/i386-linux-gnu/automotive-message-broker/automotive-message-broker/bluemonkeyplugin.so",
- "config" : "/etc/ambd/bluemonkey/config.js"
- }
- ],
-
- "sinks" : [
-
- {
- "path" : "/usr/lib/i386-linux-gnu/automotive-message-broker/automotive-message-broker/examplesinkplugin.so"
- }
- ]
-}
-
diff --git a/examples/bluemonkey/bluemonkeyconfig.in b/examples/bluemonkey/bluemonkeyconfig.in
index 434651bd..64f299c3 100644
--- a/examples/bluemonkey/bluemonkeyconfig.in
+++ b/examples/bluemonkey/bluemonkeyconfig.in
@@ -1,9 +1,9 @@
{
- "mainloop" : "@PLUGIN_INSTALL_PATH@/automotive-message-broker/qtmainloopplugin.so",
+ "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so",
"sources" : [
{
- "path" : "@PLUGIN_INSTALL_PATH@/automotive-message-broker/bluemonkeyplugin.so",
+ "path" : "@PLUGIN_INSTALL_PATH@/bluemonkeyplugin.so",
"config" : "/etc/ambd/bluemonkey/config.js"
}
],
@@ -11,7 +11,7 @@
"sinks" : [
{
- "path" : "@PLUGIN_INSTALL_PATH@/automotive-message-broker/examplesinkplugin.so"
+ "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so"
}
]
}
diff --git a/lib/abstractpropertytype.h b/lib/abstractpropertytype.h
index decc456a..c13cb41d 100644
--- a/lib/abstractpropertytype.h
+++ b/lib/abstractpropertytype.h
@@ -24,6 +24,7 @@
#include <stdexcept>
#include <vector>
#include <iostream>
+#include <memory>
#include <boost/any.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/utility.hpp>
@@ -74,27 +75,55 @@ public:
*/
enum Priority
{
- Normal = 0,
- Low,
- High,
- Instant
+ Normal = 0, /*!< normal priority. This is default */
+ Low, /*!< Low priority. */
+ High, /*!< High priority*/
+ Instant /*!< Instant. Using this priority is not thread safe. This is typically used for
+ * Properties that need to be deterministic.
+ */
};
- AbstractPropertyType(std::string property): name(property), timestamp(amb::currentTime()), sequence(-1), zone(Zone::None), priority(Normal)
+ AbstractPropertyType(std::string property)
+ : name(property), timestamp(amb::currentTime()), sequence(-1), zone(Zone::None), priority(Normal)
{
void*(name);
}
- virtual ~AbstractPropertyType() { }
+ virtual ~AbstractPropertyType()
+ {
+ for(auto i : destroyed)
+ {
+ if(i) i(this);
+ }
+ }
+ /**
+ * @brief toString
+ * @return strigified value
+ */
virtual std::string toString() const = 0;
+ /**
+ * @brief fromString converts from string value
+ */
virtual void fromString(std::string)= 0;
+ /**
+ * @brief toVariant
+ * @return GVariant representation of value. Caller must unref the returned GVariant
+ */
virtual GVariant* toVariant() = 0;
+ /**
+ * @brief fromVariant converts GVariant value into compatible native value. Caller owns
+ * GVariant argument.
+ */
virtual void fromVariant(GVariant*) = 0;
+ /**
+ * @brief copy
+ * @return a copy of the AbstractPropertyType
+ */
virtual AbstractPropertyType* copy() = 0;
/**
@@ -126,14 +155,33 @@ public:
return one != two;
}
+ /**
+ * @brief name Property name. @see VehicleProperty for built-in supported property names
+ */
std::string name;
+ /**
+ * @brief timestamp. Timestamp when the value was last updated by the system. This is updated automatically
+ * any time setValue() is called
+ * @see amb::currentTime()
+ * @see setValue()
+ */
double timestamp;
+ /**
+ * @brief sequence internal counter. Useful as a unique indentifier. values is -1 if not used (default).
+ */
int32_t sequence;
+ /**
+ * @brief sourceUuid uuid of the source that produced this property. This is set by the routingengine
+ * if left unmodified.
+ */
std::string sourceUuid;
+ /**
+ * @brief zone that the property is situated in.
+ */
Zone::Type zone;
/*!
@@ -144,29 +192,68 @@ public:
*/
Priority priority;
+ /**
+ * @brief setValue
+ * @param val boost::any value. NOTE: boost::any does not accept type coercion. Types must match exactly
+ * with native type. (ie, don't use "int" if the native type is "uint")
+ */
virtual void setValue(boost::any val)
{
mValue = val;
timestamp = amb::currentTime();
}
+ /**
+ * \brief value() native value. Does not use type coercion. Will throw if types do not match.
+ */
template <typename T>
T value() const
{
return boost::any_cast<T>(mValue);
}
+ /**
+ * @brief anyValue
+ * @return boost::any value
+ */
boost::any anyValue()
{
return mValue;
}
+ /**
+ * @brief destroyed is called if this property is destroyed.
+ */
+ std::vector<std::function<void(AbstractPropertyType*)>> destroyed;
+
protected:
boost::any mValue;
};
+namespace amb
+{
+
+struct PropertyCompare
+{
+ bool operator()(AbstractPropertyType* const & lhs, AbstractPropertyType* & rhs) const
+ {
+ if (lhs->name == rhs->name
+ && lhs->sourceUuid == rhs->sourceUuid
+ && lhs->zone == rhs->zone)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+};
+
+}
+
+
template <typename T>
class GVS;
@@ -319,7 +406,13 @@ public:
}
};
-
+/**
+ * \brief BasicPropertyType is a typed property type. Most internal types are derived from this class
+ * \example
+ * std::unique_ptr<BasicPropertyType<int>> boostPSI = new BasicPropertyType<int>("BoostPSI",5);
+ * boostPSI->priority = AbstractPropertyType::Instant; //set instant because we clean up right after.
+ * routingEngine->updateProperty(boostPSI.get(), sourceUuid());
+ */
template <typename T>
class BasicPropertyType: public AbstractPropertyType
{
@@ -406,16 +499,6 @@ public:
mValue = T();
}
- /*BasicPropertyType(std::string val)
- :AbstractPropertyType("")
- {
- if(!val.empty() && val != "")
- {
- serialize<T>(val);
- }
- else setValue(T());
- }*/
-
AbstractPropertyType* copy()
{
return new BasicPropertyType<T>(*this);
@@ -448,6 +531,11 @@ public:
setValue(deserializeVariant<T>(v));
}
+ /**
+ * @brief basicValue
+ * @return Typed version of value. Slightly more useful than @see AbstractPropertyType::value()
+ */
+
T basicValue()
{
return value<T>();
diff --git a/lib/asyncqueue.hpp b/lib/asyncqueue.hpp
index ce2c1f72..42447b4e 100644
--- a/lib/asyncqueue.hpp
+++ b/lib/asyncqueue.hpp
@@ -19,6 +19,7 @@
#include <glib.h>
#include <abstractpropertytype.h>
+#include "listplusplus.h"
#include <mutex>
#include <unordered_set>
@@ -66,9 +67,15 @@ public:
mQueue.insert(item);
}
+ void remove(T item)
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ removeOne(&mQueue, item);
+ }
+
protected:
std::mutex mutex;
- std::unordered_set<T,std::hash<T>, Pred> mQueue;
+ std::unordered_set<T, std::hash<T>, Pred> mQueue;
};
template <typename T, class Pred = std::equal_to<T> >
diff --git a/lib/listplusplus.h b/lib/listplusplus.h
index 60ebf913..23826df4 100644
--- a/lib/listplusplus.h
+++ b/lib/listplusplus.h
@@ -1,19 +1,19 @@
/*
- Copyright (C) 2012 Intel Corporation
+ Copyright (C) 2012 Intel Corporation
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -30,6 +30,18 @@ bool contains(const T & iteratable, V value)
}
template <class T, class V>
+bool contains(const T & iteratable, V value, std::function<bool(V,V)> comparator)
+{
+ for(auto i : iteratable)
+ {
+ if(comparator(value, i))
+ return true;
+ }
+
+ return false;
+}
+
+template <class T, class V>
void removeOne(T * iteratable, V value)
{
typename T::iterator itr = std::find(iteratable->begin(), iteratable->end(), value);
diff --git a/plugins/bluemonkey/CMakeLists.txt b/plugins/bluemonkey/CMakeLists.txt
index 0e710e27..76727386 100644
--- a/plugins/bluemonkey/CMakeLists.txt
+++ b/plugins/bluemonkey/CMakeLists.txt
@@ -14,9 +14,21 @@ if(Qt5Core_FOUND)
endif(Qt5Core_FOUND)
set(CMAKE_AUTOMOC ON)
-#set(communi_INCLUDE_DIRS /usr/include/qt5/Communi)
-#set(communi_LIBRARIES -lCommuni)
-#add_definitions(-DCOMMUNI_SHARED)
+
+find_library(communi NAMES Communi)
+
+if(communi)
+ message(STATUS "enabling irc bluemonkey module")
+ set(communi_INCLUDE_DIRS /usr/include/qt5/Communi)
+ set(communi_LIBRARIES -lCommuni)
+ add_definitions(-DCOMMUNI_SHARED)
+
+ add_library(bluemonkeyIrcModule MODULE irccoms.cpp)
+ set_target_properties(bluemonkeyIrcModule PROPERTIES PREFIX "")
+ target_link_libraries(bluemonkeyIrcModule ${link_libraries} ${QT_LIBRARIES} ${communi_LIBRARIES})
+ install(TARGETS bluemonkeyIrcModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH})
+endif(communi)
+
include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${communi_INCLUDE_DIRS} ${QT_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common)
@@ -25,7 +37,7 @@ set(bluemonkeyplugin_sources bluemonkey.cpp authenticate.cpp)
add_library(bluemonkeyplugin MODULE ${bluemonkeyplugin_sources})
set_target_properties(bluemonkeyplugin PROPERTIES PREFIX "")
-target_link_libraries(bluemonkeyplugin amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${QT_LIBRARIES} ${communi_LIBRARIES} amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common)
+target_link_libraries(bluemonkeyplugin dl amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${QT_LIBRARIES} ${communi_LIBRARIES} amb-plugins-common -L${CMAKE_CURRENT_BINARY_DIR}/plugins/common)
set(config_files ${CMAKE_CURRENT_SOURCE_DIR}/config.js)
diff --git a/plugins/bluemonkey/bluemonkey.cpp b/plugins/bluemonkey/bluemonkey.cpp
index 11b12afc..a7f0785c 100644
--- a/plugins/bluemonkey/bluemonkey.cpp
+++ b/plugins/bluemonkey/bluemonkey.cpp
@@ -30,8 +30,12 @@
#include <QTimer>
#include <QtQml>
+#include <dlfcn.h>
+
#define foreach Q_FOREACH
+typedef std::map<std::string, QObject*> create_bluemonkey_module_t(std::map<std::string, std::string> config, QObject* parent);
+
extern "C" AbstractSource * create(AbstractRoutingEngine* routingengine, map<string, string> config)
{
auto plugin = new AmbPlugin<BluemonkeySink>(routingengine, config);
@@ -98,42 +102,6 @@ BluemonkeySink::BluemonkeySink(AbstractRoutingEngine* e, map<string, string> con
auth = new Authenticate(config, this);
qmlRegisterType<QTimer>("", 1, 0, "QTimer");
-
-/* connect(irc, &IrcCommunication::message, [&](QString sender, QString prefix, QString codes ) {
-
- if(codes.startsWith("authenticate"))
- {
-
- int i = codes.indexOf("authenticate");
- QString pin = codes.mid(i+13);
- pin = pin.trimmed();
-
-
- if(!auth->authorize(prefix, pin))
- irc->respond(sender,"failed");
- qDebug()<<sender;
-
- }
- else if(codes.startsWith("bluemonkey"))
- {
- if(!auth->isAuthorized(prefix))
- {
- if(!mSilentMode)
- irc->respond(sender, "denied");
- return;
- }
-
- QString bm("bluemonkey");
-
- codes = codes.mid(bm.length()+1);
-
- QString response = engine->evaluate(codes).toString();
-
- if(!mSilentMode || response != "undefined" )
- irc->respond(sender, response);
- }
- });
-*/
}
@@ -164,14 +132,20 @@ int BluemonkeySink::supportedOperations()
QObject *BluemonkeySink::subscribeTo(QString str)
{
- return new Property(str.toStdString(), "", routingEngine, this);
+ return new Property(str.toStdString(), "", routingEngine, Zone::None, this);
}
QObject *BluemonkeySink::subscribeToSource(QString str, QString srcFilter)
{
- return new Property(str.toStdString(), srcFilter, routingEngine, this);
+ return new Property(str.toStdString(), srcFilter, routingEngine, Zone::None, this);
}
+QObject* BluemonkeySink::subscribeToZone(QString str, int zone)
+{
+ return new Property(str.toStdString(), "", routingEngine, zone, this);
+}
+
+
QStringList BluemonkeySink::sourcesForProperty(QString property)
{
std::list<std::string> list = routingEngine->sourcesForProperty(property.toStdString());
@@ -222,6 +196,37 @@ void BluemonkeySink::loadConfig(QString str)
DebugOut()<<val.toString().toStdString()<<endl;
}
+bool BluemonkeySink::loadModule(QString path)
+{
+ void* handle = dlopen(path.toUtf8().data(), RTLD_LAZY);
+
+ if(!handle)
+ {
+ DebugOut(DebugOut::Warning) << "bluemonkey load module failed: " << dlerror() << endl;
+ return false;
+ }
+
+ void* c = dlsym(handle, "create");
+
+ if(!c)
+ {
+ DebugOut(DebugOut::Warning) << "bluemonkey load module failed: " << path.toStdString() << " " << dlerror() << endl;
+ return false;
+ }
+
+ create_bluemonkey_module_t* create = (create_bluemonkey_module_t*)(c);
+
+ std::map<std::string, QObject*> exports = create(configuration, this);
+
+ for(auto i : exports)
+ {
+ QJSValue val = engine->newQObject(i.second);
+ engine->globalObject().setProperty(i.first.c_str(), val);
+ }
+
+ return true;
+}
+
void BluemonkeySink::reloadEngine()
{
if(engine)
@@ -317,7 +322,7 @@ void BluemonkeySink::getHistory(QStringList properties, QDateTime begin, QDateTi
routingEngine->getRangePropertyAsync(request);
}
-void BluemonkeySink::createCustomProperty(QString name, QJSValue defaultValue)
+void BluemonkeySink::createCustomProperty(QString name, QJSValue defaultValue, Zone::Type zone = Zone::None)
{
auto create = [defaultValue, name]() -> AbstractPropertyType*
@@ -342,7 +347,7 @@ void BluemonkeySink::createCustomProperty(QString name, QJSValue defaultValue)
return nullptr;
};
- addPropertySupport(Zone::None, create);
+ addPropertySupport(zone, create);
routingEngine->updateSupported(supported(), PropertyList(), &source);
}
@@ -425,8 +430,8 @@ void Property::getHistory(QDateTime begin, QDateTime end, QJSValue cbFunction)
routingEngine->getRangePropertyAsync(request);
}
-Property::Property(VehicleProperty::Property prop, QString srcFilter, AbstractRoutingEngine* re, QObject *parent)
- :QObject(parent), AbstractSink(re, std::map<std::string,std::string>()),mValue(nullptr), mUuid(amb::createUuid())
+Property::Property(VehicleProperty::Property prop, QString srcFilter, AbstractRoutingEngine* re, Zone::Type zone, QObject *parent)
+ :QObject(parent), AbstractSink(re, std::map<std::string,std::string>()),mValue(nullptr), mUuid(amb::createUuid()), mZone(zone)
{
setType(prop.c_str());
}
@@ -463,6 +468,9 @@ void Property::setType(QString t)
void Property::propertyChanged(AbstractPropertyType *value)
{
+ if(value->zone != mZone)
+ return;
+
if(mValue)
{
delete mValue;
@@ -471,3 +479,18 @@ void Property::propertyChanged(AbstractPropertyType *value)
changed(gvariantToQVariant(mValue->toVariant()));
}
+
+
+QVariant BluemonkeySink::zonesForProperty(QString prop, QString src)
+{
+ PropertyInfo info = routingEngine->getPropertyInfo(prop.toStdString(), src.toStdString());
+
+ QVariantList list;
+
+ for(auto i : info.zones())
+ {
+ list << i;
+ }
+
+ return list;
+}
diff --git a/plugins/bluemonkey/bluemonkey.h b/plugins/bluemonkey/bluemonkey.h
index a8df6bad..13ee9bae 100644
--- a/plugins/bluemonkey/bluemonkey.h
+++ b/plugins/bluemonkey/bluemonkey.h
@@ -49,9 +49,10 @@ class Property: public QObject, public AbstractSink
Q_OBJECT
Q_PROPERTY(QString type READ type)
Q_PROPERTY(QVariant value READ value WRITE setValue)
+ Q_PROPERTY(int zone READ zone)
public:
- Property(VehicleProperty::Property, QString srcFilter, AbstractRoutingEngine* re, QObject *parent = 0);
+ Property(VehicleProperty::Property, QString srcFilter, AbstractRoutingEngine* re, Zone::Type zone = Zone::None, QObject *parent = 0);
QString type();
void setType(QString t);
@@ -70,6 +71,9 @@ public:
void setValue(QVariant v);
void getHistory(QDateTime begin, QDateTime end, QJSValue cbFunction);
+
+ Zone::Type zone() { return mZone; }
+
Q_SIGNALS:
void changed(QVariant val);
@@ -77,6 +81,7 @@ Q_SIGNALS:
private:
AbstractPropertyType* mValue;
const std::string mUuid;
+ Zone::Type mZone;
};
@@ -104,8 +109,10 @@ public Q_SLOTS:
QObject* subscribeTo(QString str);
QObject* subscribeToSource(QString str, QString srcFilter);
+ QObject* subscribeToZone(QString str, int zone);
QStringList sourcesForProperty(QString property);
+ QVariant zonesForProperty(QString property, QString src);
QStringList supportedProperties();
@@ -113,7 +120,7 @@ public Q_SLOTS:
void loadConfig(QString str);
- void loadModule(QString path);
+ bool loadModule(QString path);
void reloadEngine();
@@ -130,7 +137,7 @@ public Q_SLOTS:
mSilentMode = m;
}
- void createCustomProperty(QString name, QJSValue defaultValue);
+ void createCustomProperty(QString name, QJSValue defaultValue, Zone::Type zone);
private:
QStringList configsToLoad;
diff --git a/plugins/bluemonkey/irccoms.cpp b/plugins/bluemonkey/irccoms.cpp
index f07d8d65..3d0eaa47 100644
--- a/plugins/bluemonkey/irccoms.cpp
+++ b/plugins/bluemonkey/irccoms.cpp
@@ -7,9 +7,18 @@
#include <QFile>
#include <QNetworkProxy>
#include <QTimer>
-#include <QScriptEngine>
+#include <QJSEngine>
#include <debugout.h>
+extern "C" std::map<std::string, QObject*> create(std::map<std::string, std::string> config, QObject* parent)
+{
+ std::map<std::string, QObject*> moduleInstances;
+
+ moduleInstances["irc"] = new IrcCommunication(config, parent);
+
+ return moduleInstances;
+}
+
#define foreach Q_FOREACH
IrcCommunication::IrcCommunication(std::map<std::string, std::string> config, QObject* parent)
@@ -29,9 +38,9 @@ IrcCommunication::IrcCommunication(std::map<std::string, std::string> config, QO
QObject::connect(this,SIGNAL(socketError(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError)));
QObject::connect(this,SIGNAL(messageReceived(IrcMessage*)),this,SLOT(onMessageReceived(IrcMessage*)));
- QScriptEngine *engine = new QScriptEngine(this);
+ QJSEngine *engine = new QJSEngine(this);
- QScriptValue eventEngineValue = engine->newQObject(this);
+ QJSValue eventEngineValue = engine->newQObject(this);
engine->globalObject().setProperty("irc", eventEngineValue);
QString str = config["ircSettings"].c_str();
@@ -47,7 +56,7 @@ IrcCommunication::IrcCommunication(std::map<std::string, std::string> config, QO
file.close();
- QScriptValue response = engine->evaluate(script);
+ QJSValue response = engine->evaluate(script);
DebugOut()<<response.toString().toStdString()<<endl;
diff --git a/plugins/bluemonkey/irccoms.h b/plugins/bluemonkey/irccoms.h
index 3ce016b8..0adc53ca 100644
--- a/plugins/bluemonkey/irccoms.h
+++ b/plugins/bluemonkey/irccoms.h
@@ -30,6 +30,8 @@ public Q_SLOTS:
void setIgnoreInvalidCert(bool ignore);
void join(QString channel);
+ void debugMessage(QString v) { qDebug()<<v; }
+
void reconnect();
private Q_SLOTS:
diff --git a/plugins/dbus/dbusplugin.cpp b/plugins/dbus/dbusplugin.cpp
index b936e4a4..3e9fc86a 100644
--- a/plugins/dbus/dbusplugin.cpp
+++ b/plugins/dbus/dbusplugin.cpp
@@ -71,9 +71,6 @@ void DBusSink::supportedChanged(const PropertyList &supportedProperties)
void DBusSink::propertyChanged(AbstractPropertyType *value)
{
- if(!isRegistered())
- return;
-
VehicleProperty::Property property = value->name;
if( value->zone != zoneFilter)
diff --git a/plugins/dbus/environmentproperties.h b/plugins/dbus/environmentproperties.h
index 40655a15..10db753c 100644
--- a/plugins/dbus/environmentproperties.h
+++ b/plugins/dbus/environmentproperties.h
@@ -196,7 +196,7 @@ public:
{
wantPropertyVariant(VehicleProperty::AirflowDirectionW3C, "AirflowDirection", AbstractProperty::ReadWrite);
- wantPropertyVariant(VehicleProperty::FanSpeed, "FanSpeed", AbstractProperty::ReadWrite);
+ wantPropertyVariant(VehicleProperty::FanSpeed, "FanSpeedLevel", AbstractProperty::ReadWrite);
wantPropertyVariant(VehicleProperty::TargetTemperature, "TargetTemperature", AbstractProperty::ReadWrite);
diff --git a/plugins/dbus/maintenance.h b/plugins/dbus/maintenance.h
index 97bc187f..6f1cd941 100644
--- a/plugins/dbus/maintenance.h
+++ b/plugins/dbus/maintenance.h
@@ -101,7 +101,7 @@ public:
**/
wantPropertyVariant(VehicleProperty::BatteryCurrent, "Current", AbstractProperty::Read);
- wantPropertyVariant(VehicleProperty::BatteryCurrent, "ChargeLevel", AbstractProperty::Read);
+ wantPropertyVariant(VehicleProperty::BatteryChargeLevel, "ChargeLevel", AbstractProperty::Read);
}
};
diff --git a/plugins/dbus/varianttype.cpp b/plugins/dbus/varianttype.cpp
index 730ed59c..933eccad 100644
--- a/plugins/dbus/varianttype.cpp
+++ b/plugins/dbus/varianttype.cpp
@@ -36,7 +36,7 @@ void VariantType::initialize()
/// do not request if not supported:
PropertyList proplist = routingEngine->supported();
- if(contains(proplist,mAmbPropertyName))
+ if(contains(proplist, mAmbPropertyName))
routingEngine->getPropertyAsync(request);
}
@@ -55,7 +55,7 @@ GVariant *VariantType::toGVariant()
void VariantType::fromGVariant(GVariant *val)
{
AbstractPropertyType *v = VehicleProperty::getPropertyTypeForPropertyNameValue(mAmbPropertyName);
- v->fromVariant( val );
+ v->fromVariant(val);
AsyncSetPropertyRequest request;
request.property = mAmbPropertyName;
diff --git a/plugins/obd2plugin/obd2source.cpp b/plugins/obd2plugin/obd2source.cpp
index 1032ab3b..c95bda20 100644
--- a/plugins/obd2plugin/obd2source.cpp
+++ b/plugins/obd2plugin/obd2source.cpp
@@ -463,14 +463,13 @@ static int updateProperties( gpointer data)
StatusMessage *reply = (StatusMessage*)retval;
if (reply->statusStr == "disconnected")
{
- OBD2Source::Obd2ConnectType val(Obd2Connected,false);
- src->updateProperty(&val);
+ src->obd2Connected.setValue(false);
+ src->updateProperty(&src->obd2Connected);
}
else if (reply->statusStr == "connected")
{
- OBD2Source::Obd2ConnectType val(Obd2Connected, true);
- val.priority = OBD2Source::Obd2ConnectType::Instant;
- src->updateProperty(&val);
+ src->obd2Connected.setValue(false);
+ src->updateProperty(&src->obd2Connected);
}
else if (reply->statusStr == "error:nodata" || reply->statusStr == "error:timeout")
{
diff --git a/plugins/obd2plugin/obd2source.h b/plugins/obd2plugin/obd2source.h
index 39774807..ba8cc2bf 100644
--- a/plugins/obd2plugin/obd2source.h
+++ b/plugins/obd2plugin/obd2source.h
@@ -187,12 +187,13 @@ public:
GThread *m_gThread;
typedef BasicPropertyType<bool> Obd2ConnectType;
+ Obd2ConnectType obd2Connected;
private:
PropertyList m_supportedProperties;
std::map<VehicleProperty::Property, AbstractPropertyType*> oldValueMap;
GMutex *threadQueueMutex;
- Obd2ConnectType obd2Connected;
+
};
diff --git a/plugins/websocket/websocketsource.cpp b/plugins/websocket/websocketsource.cpp
index 01c2d028..8b8de3d9 100644
--- a/plugins/websocket/websocketsource.cpp
+++ b/plugins/websocket/websocketsource.cpp
@@ -24,6 +24,7 @@
#include <glib.h>
#include <sstream>
#include <listplusplus.h>
+#include <memory>
#include <timestamp.h>
#include "uuidhelper.h"
@@ -33,6 +34,7 @@
#include "debugout.h"
#include "common.h"
+#include "superptr.hpp"
#define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
libwebsocket_context *context = NULL;
@@ -44,6 +46,71 @@ double totalTime=0;
double numUpdates=0;
double averageLatency=0;
+class UniquePropertyCache
+{
+public:
+ bool hasProperty(std::string name, std::string source, Zone::Type zone)
+ {
+ for(auto i : properties)
+ {
+ if(i->name == name &&
+ i->sourceUuid == source &&
+ i->zone == zone)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ std::shared_ptr<AbstractPropertyType> append(std::string name, std::string source, Zone::Type zone)
+ {
+ for(auto i : properties)
+ {
+ if(i->name == name &&
+ i->sourceUuid == source &&
+ i->zone == zone)
+ {
+ return i;
+ }
+ }
+
+ auto t = VehicleProperty::getPropertyTypeForPropertyNameValue(name);
+
+ if(!t)
+ {
+ throw std::runtime_error(name + "name is not a known type");
+ }
+
+ t->sourceUuid = source;
+ t->zone = zone;
+
+ properties.emplace_back(t);
+
+ return property(name, source, zone);
+ }
+
+ std::shared_ptr<AbstractPropertyType> property(std::string name, std::string source, Zone::Type zone)
+ {
+ for(auto i : properties)
+ {
+ if(i->name == name &&
+ i->sourceUuid == source &&
+ i->zone == zone)
+ {
+ return i;
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::shared_ptr<AbstractPropertyType>> properties;
+};
+
+UniquePropertyCache properties;
+
static int callback_http_only(libwebsocket_context *context,struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason,void *user, void *in, size_t len);
static struct libwebsocket_protocols protocols[] = {
{
@@ -126,7 +193,7 @@ void WebSocketSource::setConfiguration(map<string, string> config)
else
{
m_sslEnabled = false;
- }
+ }
}
}
//printf("Connecting to websocket server at %s port %i\n",ip.c_str(),port);
@@ -139,7 +206,7 @@ void WebSocketSource::setConfiguration(map<string, string> config)
}
clientsocket = libwebsocket_client_connect(context, ip.c_str(), port, sslval,"/", "localhost", "websocket",protocols[0].name, -1);
-
+
}
@@ -223,7 +290,6 @@ static int checkTimeouts(gpointer data)
static int callback_http_only(libwebsocket_context *context, struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len)
{
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING];
- int l;
DebugOut() << __SMALLFILE__ << ":" << __LINE__ << reason << "callback_http_only" << endl;
switch (reason)
{
@@ -317,15 +383,19 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket
string value = data["value"].toString().toStdString();
double timestamp = data["timestamp"].toDouble();
int sequence = data["sequence"].toInt();
+ Zone::Type zone = data["zone"].toInt();
DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Value changed:" << name << value << endl;
try
{
- AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(name,value);
+ auto type = properties.append(name, source->uuid(), zone);
+
type->timestamp = timestamp;
type->sequence = sequence;
- m_re->updateProperty(type, source->uuid());
+ type->fromString(value);
+
+ m_re->updateProperty(type.get(), source->uuid());
double currenttime = amb::currentTime();
/** This is now the latency between when something is available to read on the socket, until
@@ -339,8 +409,6 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket
averageLatency = totalTime / numUpdates;
DebugOut(2)<<"Average parse latency: "<<averageLatency<<endl;
-
- delete type;
}
catch (exception ex)
{
@@ -404,7 +472,7 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket
}
else if (name == "get")
{
-
+
DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Got \"GET\" event:" << pairdata.size()<<endl;
if (source->uuidReplyMap.find(id) != source->uuidReplyMap.end())
{
@@ -414,10 +482,12 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket
std::string value = obj["value"].toString().toStdString();
double timestamp = obj["timestamp"].toDouble();
int sequence = obj["sequence"].toInt();
-
- AbstractPropertyType* v = VehicleProperty::getPropertyTypeForPropertyNameValue(property,value);
+ Zone::Type zone = obj["zone"].toInt();
+
+ AbstractPropertyType* v = VehicleProperty::getPropertyTypeForPropertyNameValue(property, value);
v->timestamp = timestamp;
v->sequence = sequence;
+ v->zone = zone;
if (source->uuidReplyMap.find(id) != source->uuidReplyMap.end() && source->uuidReplyMap[id]->error != AsyncPropertyReply::Timeout)
{
@@ -438,7 +508,7 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket
{
DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "GET Method Reply INVALID! Multiple properties detected, only single are supported!!!" << "\n";
}
-
+
//data will contain a property/value map.
}
@@ -464,7 +534,7 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket
g_io_add_watch(chan,GIOCondition(G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP),(GIOFunc)gioPollingFunc,0);
g_io_channel_set_close_on_unref(chan,true);
g_io_channel_unref(chan); //Pass ownership of the GIOChannel to the watch.
-
+
break;
}
return 0;
diff --git a/plugins/websocket/websocketsource.h b/plugins/websocket/websocketsource.h
index 98d5478e..4a318955 100644
--- a/plugins/websocket/websocketsource.h
+++ b/plugins/websocket/websocketsource.h
@@ -21,14 +21,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef WEBSOCKETSOURCE_H
#define WEBSOCKETSOURCE_H
-
-
#include <abstractsource.h>
#include <string>
#include <libwebsockets.h>
#include <QByteArray>
-
class WebSocketSource : public AbstractSource
{
@@ -58,8 +55,8 @@ public:
//map<VehicleProperty::Property,AsyncRangePropertyReply*> rangedPropertyReplyMap;
std::map<std::string,AsyncPropertyReply*> uuidReplyMap;
std::map<std::string,double> uuidTimeoutMap;
- std::map<std::string,AsyncRangePropertyReply*> uuidRangedReplyMap;
-
+ std::map<std::string, AsyncRangePropertyReply*> uuidRangedReplyMap;
+
int partialMessageIndex;
QByteArray incompleteMessage;
int expectedMessageFrames;
@@ -67,7 +64,7 @@ public:
PropertyInfo getPropertyInfo(VehicleProperty::Property property);
private:
- PropertyList m_supportedProperties;
+ PropertyList m_supportedProperties;
};
diff --git a/plugins/wheel/wheelplugin.cpp b/plugins/wheel/wheelplugin.cpp
index f6ebdbb6..0ddfd799 100644
--- a/plugins/wheel/wheelplugin.cpp
+++ b/plugins/wheel/wheelplugin.cpp
@@ -99,6 +99,7 @@ private:
VehicleProperty::EngineOilPressureType *oilPSI;
VehicleProperty::EngineCoolantTemperatureType *coolantTemp;
VehicleProperty::SteeringWheelAngleType *steeringAngle;
+ VehicleProperty::SteeringWheelAngleW3CType *steeringAngleW3C;
VehicleProperty::ThrottlePositionType *throttle;
VehicleProperty::ClutchStatusType *clutch;
VehicleProperty::WheelBrakeType *brake;
@@ -162,6 +163,7 @@ PropertyList WheelSourcePlugin::supported()
props.push_back(VehicleProperty::ThrottlePosition);
props.push_back(VehicleProperty::WheelBrake);
props.push_back(VehicleProperty::SteeringWheelAngle);
+ props.push_back(VehicleProperty::SteeringWheelAngleW3C);
props.push_back(VehicleProperty::TurnSignal);
props.push_back(VehicleProperty::ClutchStatus);
props.push_back(VehicleProperty::EngineOilPressure);
@@ -208,6 +210,7 @@ WheelPrivate::WheelPrivate(WheelSourcePlugin *parent, AbstractRoutingEngine *rou
engineSpeed(new VehicleProperty::EngineSpeedType(0)),
vehicleSpeed(new VehicleProperty::VehicleSpeedType(0)),
steeringAngle(new VehicleProperty::SteeringWheelAngleType(0)),
+ steeringAngleW3C(new VehicleProperty::SteeringWheelAngleW3CType(0)),
clutch(new VehicleProperty::ClutchStatusType(false)),
brake(new VehicleProperty::WheelBrakeType(false)),
tempButton(new VehicleProperty::ButtonEventType(ButtonEvents::NoButton)),
@@ -308,6 +311,8 @@ AbstractPropertyType *WheelPrivate::getProperty(VehicleProperty::Property propTy
return this->brake;
else if (propType == VehicleProperty::SteeringWheelAngle)
return this->steeringAngle;
+ else if (propType == VehicleProperty::SteeringWheelAngleW3C)
+ return this->steeringAngleW3C;
else if (propType == VehicleProperty::TurnSignal)
return this->turnSignal;
else if (propType == VehicleProperty::ClutchStatus)
@@ -536,7 +541,9 @@ void WheelPrivate::changeCoolantTemp(bool increase)
void WheelPrivate::changeSteeringAngle(int val)
{
*steeringAngle = (((double)val/(double)32767.0) + (double)1.0) * (double)180.0;
+ *steeringAngleW3C = (((double)val/(double)32767.0) + (double)1.0) * (double)180.0;
this->re->updateProperty(steeringAngle, mParent->uuid());
+ this->re->updateProperty(steeringAngleW3C, mParent->uuid());
}
void WheelPrivate::changeClutch(int val)