diff options
author | Kevron Rees <tripzero.kev@gmail.com> | 2014-12-29 08:53:13 -0800 |
---|---|---|
committer | Kevron Rees <tripzero.kev@gmail.com> | 2014-12-29 08:53:13 -0800 |
commit | d35ef7fbd8a766d2fa23141378cccd9077f1de6b (patch) | |
tree | 3a64c57e2a598812eefe5d9bad8cc9133d8c2dba | |
parent | 2bdd66ead71810213900523cac7d3b4abd1592db (diff) | |
parent | 5507408d3d2481ad78a1d5eb64b80bbadffb3fdf (diff) | |
download | automotive-message-broker-d35ef7fbd8a766d2fa23141378cccd9077f1de6b.tar.gz |
Merge pull request #37 from tripzero/master0.12.902
0.12.902 - Documentation improvements/updates.
45 files changed, 982 insertions, 251 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index fbbc5afc..2e488d6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,8 @@ set(CMAKE_BUILD_TYPE, Debug) include(FindPkgConfig) set(PROJECT_NAME "automotive-message-broker") -set(PROJECT_VERSION "0.12.901") +set(PROJECT_PRETTY_NAME "Automotive Message Broker") +set(PROJECT_VERSION "0.12.902") set(PROJECT_CODENAME "agera") set(PROJECT_QUALITY "beta") @@ -46,34 +47,22 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpie -pie -std=c++1y") if(opencvlux_plugin) - message(STATUS "OpenCV Lux plugin enabled") + message(STATUS "OpenCV Lux plugin enabled") endif(opencvlux_plugin) include (CMakeForceCompiler) if (enable_icecc) - find_program(ICECC /usr/lib/icecc/bin/g++) - if (ICECC) - message(STATUS "icecc will be used for distributed compiling") - cmake_force_cxx_compiler(${ICECC} icecc) - else(ICECC) - message(STATUS "Not using icecc") - endif(ICECC) + find_program(ICECC /usr/lib/icecc/bin/g++) + if (ICECC) + message(STATUS "icecc will be used for distributed compiling") + cmake_force_cxx_compiler(${ICECC} icecc) + else(ICECC) + message(STATUS "Not using icecc") + endif(ICECC) endif(enable_icecc) -# add a target to generate API documentation with Doxygen -if(enable_docs) -message(STATUS "doxygen doc generation enabled") -find_package(Doxygen) -if(DOXYGEN_FOUND) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.idl.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.idl @ONLY) - add_custom_target(all ALL ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/docs/amb COMMENT "Generating API documentation with Doxygen" VERBATIM) - add_custom_target(idl ALL ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.idl WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/docs/dbus COMMENT "Generating DBus API documentation with Doxygen" VERBATIM) -endif(DOXYGEN_FOUND) -endif(enable_docs) - find_package(Boost REQUIRED) @@ -86,34 +75,34 @@ set(include_dirs ${libtool_INCLUDE_DIR} ${glib_INCLUDE_DIRS} ${gio_INCLUDE_DIRS} set(link_libraries -lamb ${glib_LIBRARIES} ${json_LIBRARIES} -L${CMAKE_CURRENT_BINARY_DIR}/lib) if(qtmainloop) - message(STATUS "using Qt mainloop") - - find_package(Qt5Core) - if(Qt5Core_FOUND) - message(STATUS "using Qt5") - set(QT_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS}) - set(QT_LIBRARIES ${Qt5Core_LIBRARIES}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") - # if(CMAKE_SIZEOF_VOID_P MATCHES "8") - # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=large") - # endif(CMAKE_SIZEOF_VOID_P MATCHES "8") - add_definitions(${Qt5Core_DEFINITIONS}) - else(Qt5Core_FOUND) - message(STATUS "using Qt4") - find_package( Qt4 REQUIRED ) - include(${QT_USE_FILE}) - - endif(Qt5Core_FOUND) - - set(include_dirs ${include_dirs} ${QT_INCLUDE_DIRS}) - set(link_libraries ${link_libraries} ${QT_LIBRARIES}) - - add_definitions(-DQT_NO_KEYWORDS) - add_definitions(-DUSE_QT_CORE) + message(STATUS "using Qt mainloop") + + find_package(Qt5Core) + if(Qt5Core_FOUND) + message(STATUS "using Qt5") + set(QT_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS}) + set(QT_LIBRARIES ${Qt5Core_LIBRARIES}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") + # if(CMAKE_SIZEOF_VOID_P MATCHES "8") + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=large") + # endif(CMAKE_SIZEOF_VOID_P MATCHES "8") + add_definitions(${Qt5Core_DEFINITIONS}) + else(Qt5Core_FOUND) + message(STATUS "using Qt4") + find_package( Qt4 REQUIRED ) + include(${QT_USE_FILE}) + + endif(Qt5Core_FOUND) + + set(include_dirs ${include_dirs} ${QT_INCLUDE_DIRS}) + set(link_libraries ${link_libraries} ${QT_LIBRARIES}) + + add_definitions(-DQT_NO_KEYWORDS) + add_definitions(-DUSE_QT_CORE) endif(qtmainloop) if(usebluez5) - add_definitions(-DUSE_BLUEZ5) + add_definitions(-DUSE_BLUEZ5) endif(usebluez5) @@ -150,6 +139,7 @@ add_subdirectory(ambd) add_subdirectory(plugins) add_subdirectory(docs) add_subdirectory(tests) +add_subdirectory(tools) add_subdirectory(examples) add_subdirectory(xwalk) add_subdirectory(packaging) @@ -6,6 +6,7 @@ New features: - [OpenCV plugin] driver drowsiness detection test code - [Bluemonkey plugin] support for zones in JS API. - [Bluemonkey plugin] database module. +- [tools] new ambctl. replaces amb-get, amb-set, etc Changes: - OpenCV plugin experimental options for cuda and kinect are removed @@ -1,14 +1,10 @@ - Refactor obd2 plugin with AsyncQueue. Use thread safe-update property. -- update json protocol to support rangerequests with PropertyList instead of a signel property (Verify) -- update database to support zone column -- general support for source and zone filtering in database plugin +- update json protocol to support rangerequests with PropertyList instead of a singel property (Verify) +- source export from database plugin does not reflect the source in the database - no reason for pluginloader to track sources. core already does it. - create docs for all plugins (README) - handle badly formed messages properly (ie not crash) in websocketsink -- GetHistory must filter on source - grep all the TODOs in the code and do them - investigate and enable use of provisioning in ssl websockets - enable ambd/plugins.d/ -- finish implementing openxc plugin (needs testing) -- Document internal source/sink plugin API diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 4f5b0c00..2ebb4879 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,9 +1,32 @@ if(enable_docs) - install (DIRECTORY amb DESTINATION ${DOC_INSTALL_DIR} COMPONENT Docs) - install (DIRECTORY dbus DESTINATION ${DOC_INSTALL_DIR} COMPONENT Docs) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/amb.fidl DESTINATION ${DOC_INSTALL_DIR}/dbus/html/ COMPONENT Docs) - add_custom_target(doc_idl ALL mkdir -p ${CMAKE_CURRENT_SOURCE_DIR}/dbus/html/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/amb.fidl ${CMAKE_CURRENT_SOURCE_DIR}/dbus/html/amb.fidl WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Moving amb.fidl" VERBATIM) + install (DIRECTORY amb DESTINATION ${DOC_INSTALL_DIR} COMPONENT Docs) + install (DIRECTORY dbus DESTINATION ${DOC_INSTALL_DIR} COMPONENT Docs) + install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/amb.fidl DESTINATION ${DOC_INSTALL_DIR}/dbus/html/ COMPONENT Docs) + add_custom_target(doc_idl ALL mkdir -p ${CMAKE_CURRENT_SOURCE_DIR}/dbus/html/ && cp ${CMAKE_CURRENT_SOURCE_DIR}/amb.fidl ${CMAKE_CURRENT_SOURCE_DIR}/dbus/html/amb.fidl WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Moving amb.fidl" VERBATIM) + +# add a target to generate API documentation with Doxygen +message(STATUS "doxygen doc generation enabled") +find_package(Doxygen) +if(DOXYGEN_FOUND) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.idl.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.idl @ONLY) + add_custom_target(libamb_docs ALL ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/amb COMMENT "Generating API documentation with Doxygen" VERBATIM) + add_custom_target(idl ALL ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.idl WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/dbus COMMENT "Generating DBus API documentation with Doxygen" VERBATIM) + + #generate mappings documentation + configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libamb.in ${CMAKE_CURRENT_BINARY_DIR}/libamb.h @ONLY) + + add_custom_target(genmappings_libamb + python ${CMAKE_SOURCE_DIR}/tools/genmapping --output ${CMAKE_CURRENT_BINARY_DIR}/ambdbusmappings.idl ${dbus_mapping_headers} + COMMENT "running genmapping") + add_dependencies(libamb_docs genmappings_libamb) + add_dependencies(idl genmappings_libamb) + +endif(DOXYGEN_FOUND) + endif(enable_docs) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb.in.idl ${CMAKE_CURRENT_SOURCE_DIR}/amb.fidl @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/dbus.idl ${CMAKE_CURRENT_SOURCE_DIR}/dbus.idl @ONLY) + diff --git a/docs/Doxyfile.idl.in b/docs/Doxyfile.idl.in new file mode 100644 index 00000000..cf05b696 --- /dev/null +++ b/docs/Doxyfile.idl.in @@ -0,0 +1,3 @@ +PROJECT_NAME = @PROJECT_NAME@ +PROJECT_NUMBER = @PROJECT_VERSION@ +INPUT = @CMAKE_CURRENT_SOURCE_DIR@ @CMAKE_CURRENT_BINARY_DIR@/ambdbusmappings.idl diff --git a/Doxyfile.idl.in b/docs/Doxyfile.in index 435603d1..ae6369e0 100644 --- a/Doxyfile.idl.in +++ b/docs/Doxyfile.in @@ -1,3 +1,3 @@ PROJECT_NAME = @PROJECT_NAME@ PROJECT_NUMBER = @PROJECT_VERSION@ -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/docs +INPUT = @CMAKE_SOURCE_DIR@/lib/ @CMAKE_CURRENT_BINARY_DIR@/ diff --git a/docs/dbus.idl b/docs/dbus.idl index 29cb4683..519ef9f1 100644 --- a/docs/dbus.idl +++ b/docs/dbus.idl @@ -11,7 +11,8 @@ * * The interfaces and data types are documented in <a href="amb.fidl">amb.fidl</a>. Franca IDL * tools can be used to generate DBus introspection xml which can be used to generate bindings -* for your language of choice. +* for your language of choice. These interfaces types map to internal AMB properties. To understand the mappings, +* see the <a href="ambdbusmappings_8idl.html">mapping documentation</a> * * \section basic_usage Basic Recommended Usage * diff --git a/lib/libamb.h b/docs/libamb.in index 7a23034a..ace28a9e 100644 --- a/lib/libamb.h +++ b/docs/libamb.in @@ -1,14 +1,27 @@ /** \mainpage Automotive Message Broker Library Documentation - + \version @PROJECT_VERSION@ \section intro Introduction - AMB Library documentation outlines the internal classes and structures for building + Automotive Message Broker (AMB) Library documentation outlines the internal classes and structures for building plugins for AMB. \section architecture General Architecture AMB has 3 main parts. Source plugins which provide data, a routing engine that routes data and sink plugins that consume the data. + \section properties Properties + AMB defines a number of properties itself. These properties are defined in vehicleproperty.h. The DBus plugin + will take many of these properties and combine them in DBus interfaces. The mappings of AMB internal properties + to DBus Interface properties can be found in the <a href="ambdbusmappings_8idl.html">mappings documentation</a>. This file will come in handy when you want to + implement a particular AMB DBus interface in your source plugin. + + By default, for any property not explicitly + included in a DBus interface, the DBus plugin will generate a custom interface. The pattern is as follows: + + CustomProperty = "org.automotive.CustomProperty.CustomProperty" + + "org.automotive.CustomProperty is the DBus interface and CustomProperty is a DBus property in that interface. + \section plugins Plugins There are two types of plugins: plugins that provide data, called "sources" (AbstractSource) and plugins that consume data, called "sinks" (AbstractSink). @@ -21,12 +34,19 @@ are also many different types of plugins useful for testing and development in the plugins/ directory. + Various plugins have separate documentation found in @DOC_INSTALL_DIR@/plugins/. + + \section plugin_creation Creating your own plugin + AMB allows you to create your own plugins. Plugins inherit from either AbstractSource, AbstractSink, or AmbPluginImpl. + + It is recommended that new plugins be written using AmbPlugin and AmbPluginImpl. + \section routing_engine Routing Engine Plugins As of 0.12, the routing engine itself can be exchanged for a plugin. This allows users to swap in routing engines with different behaviors, additional security, and custom throttling and filtering features. The easiest way to get started creating a routing engine plugin would be to look at - AbstractRoutingEngine, the base class for all routing engines and the default + AbstractRoutingEngine, the base class for all routing engines and the default routing engine in ambd/core.cpp. **/ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4313156e..54cea0b6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,8 +1,7 @@ -set(amb_examples configwheel databaseconfig databasesource dbusconfig exampleconfig +set(amb_examples configwheel databasesource dbusconfig exampleconfig gpsnmea obdsourceconfig opencvluxconfig opencvdbusconfig qtmainloopconfig websocketsink2 websocketsource2 testsourceconfig bluemonkey/bluemonkeyconfig) - configure_file (${CMAKE_CURRENT_SOURCE_DIR}/configwheel.in ${CMAKE_CURRENT_SOURCE_DIR}/configwheel @ONLY) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/databasesource.in ${CMAKE_CURRENT_SOURCE_DIR}/databasesource @ONLY) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/dbusconfig.in ${CMAKE_CURRENT_SOURCE_DIR}/dbusconfig @ONLY) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 92184b9d..0b41a490 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,5 +1,5 @@ -set(amb_sources abstractpropertytype.cpp abstractroutingengine.cpp listplusplus.cpp abstractsink.cpp vehicleproperty.cpp abstractsource.cpp debugout.cpp timestamp.cpp uuidhelper.cpp mappropertytype.hpp propertyinfo.hpp superptr.hpp asyncqueue.hpp) -set(amb_headers_install abstractpropertytype.h nullptr.h abstractroutingengine.h listplusplus.h abstractsink.h vehicleproperty.h debugout.h abstractsource.h timestamp.h uuidhelper.h mappropertytype.hpp propertyinfo.hpp superptr.hpp asyncqueue.hpp) +set(amb_sources abstractpropertytype.cpp abstractroutingengine.cpp listplusplus.cpp abstractsink.cpp vehicleproperty.cpp abstractsource.cpp debugout.cpp timestamp.cpp uuidhelper.cpp mappropertytype.hpp propertyinfo.hpp superptr.hpp asyncqueue.hpp ambpluginimpl.cpp ambplugin.h) +set(amb_headers_install abstractpropertytype.h nullptr.h abstractroutingengine.h listplusplus.h abstractsink.h vehicleproperty.h debugout.h abstractsource.h timestamp.h uuidhelper.h mappropertytype.hpp propertyinfo.hpp superptr.hpp asyncqueue.hpp ambplugin.h ambpluginimpl.h) add_library(amb SHARED ${amb_sources}) @@ -7,9 +7,9 @@ find_library(uuid_LIBRARY uuid DOC "Uuid libraries") find_path(uuid_INCLUDE_DIR uuid/uuid.h DOC "Libtool headers") if(uuid_LIBRARY) - message(STATUS "uuid found") + message(STATUS "uuid found") else(uuid_LIBRARY) - message(FATAL_ERROR "uuid missing. please install uuid-dev") + message(FATAL_ERROR "uuid missing. please install uuid-dev") endif(uuid_LIBRARY) include_directories( ${include_dirs} ${uuid_INCLUDE_DIR}) diff --git a/lib/abstractpropertytype.h b/lib/abstractpropertytype.h index 1d299bbc..6efbee13 100644 --- a/lib/abstractpropertytype.h +++ b/lib/abstractpropertytype.h @@ -87,7 +87,7 @@ public: AbstractPropertyType(std::string property) : name(property), timestamp(amb::currentTime()), sequence(-1), zone(Zone::None), priority(Normal) { - void*(name); + } virtual ~AbstractPropertyType() diff --git a/plugins/common/ambplugin.h b/lib/ambplugin.h index 04fa3b19..c150b527 100644 --- a/plugins/common/ambplugin.h +++ b/lib/ambplugin.h @@ -24,10 +24,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include <string> /*! - * \defgroup ivipocbase ivipocbase static library + * \file ambplugin.h * \brief Contains common code used in all IviPoC II plugins for Automotive message broker(AMB). + */ + +/*! + * AmbPlugin class contains common code used in all IviPoC II plugins for Automotive message broker(AMB). + * For the AMB library API please visit <a href="https://github.com/otcshare/automotive-message-broker">Automotive message broker web page</a>. + * + * \class AmbPlugin * - * Example of the minimal code to write a new plugin using ivipocbase: + * Example of the minimal code to write a new plugin using AmbPlugin: * * \code * #include "ambpluginimpl.h" @@ -51,15 +58,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * @{ */ -/*! - * AmbPlugin class contains common code used in all IviPoC II plugins for Automotive message broker(AMB). - * For the AMB library API please visit <a href="https://github.com/otcshare/automotive-message-broker">Automotive message broker web page</a>. - * - * \class AmbPlugin - */ - -//class AmbPluginImpl; - template<class T> class AmbPlugin : public AbstractSource { diff --git a/plugins/common/ambpluginimpl.cpp b/lib/ambpluginimpl.cpp index dc646857..7bf7e712 100644 --- a/plugins/common/ambpluginimpl.cpp +++ b/lib/ambpluginimpl.cpp @@ -133,8 +133,10 @@ AbstractPropertyType* AmbPluginImpl::findPropertyType(const VehicleProperty::Pro return nullptr; } -std::shared_ptr<AbstractPropertyType> AmbPluginImpl::addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory) +std::shared_ptr<AbstractPropertyType> AmbPluginImpl::addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory, std::string sourceUuid) { + if(sourceUuid.empty()) + sourceUuid = uuid(); std::shared_ptr<AbstractPropertyType> propertyType(typeFactory()); if(!propertyType) return propertyType; @@ -154,9 +156,10 @@ std::shared_ptr<AbstractPropertyType> AmbPluginImpl::addPropertySupport(Zone::Ty propertyType.swap(registeredPropertyType); } propertyType->zone = zone; - propertyType->sourceUuid = uuid(); + propertyType->sourceUuid = sourceUuid; + propertyType->timestamp = amb::currentTime(); ZonePropertyType& zonePropType = properties[name]; - zonePropType.insert( make_pair(zone, propertyType)); + zonePropType.insert(make_pair(zone, propertyType)); return propertyType; } diff --git a/plugins/common/ambpluginimpl.h b/lib/ambpluginimpl.h index d9482f0f..96080379 100644 --- a/plugins/common/ambpluginimpl.h +++ b/lib/ambpluginimpl.h @@ -145,7 +145,7 @@ protected: * \param typeFactory Function to be used to create instance of the AbstractPropertyType for registered property * \return AbstractPropertyType* if signal exits otherwise nullptr(in this case we do not know its datatype) */ - std::shared_ptr<AbstractPropertyType> addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory); + std::shared_ptr<AbstractPropertyType> addPropertySupport(Zone::Type zone, std::function<AbstractPropertyType* (void)> typeFactory, std::string sourceUuid=""); template <class T> std::shared_ptr<AbstractPropertyType> addPropertySupport(Zone::Type zone) diff --git a/packaging/automotive-message-broker.spec.in b/packaging/automotive-message-broker.spec.in index 25850843..56266491 100644 --- a/packaging/automotive-message-broker.spec.in +++ b/packaging/automotive-message-broker.spec.in @@ -272,6 +272,7 @@ cp packaging.in/config.tizen %{buildroot}%{_sysconfdir}/ambd/ %{_bindir}/amb-get-history %{_bindir}/amb-set %{_bindir}/amb-listen +%{_bindir}/ambctl %files devel %defattr(-,root,root,-) diff --git a/plugins/bluemonkey/CMakeLists.txt b/plugins/bluemonkey/CMakeLists.txt index 53b621ac..ec6962a6 100644 --- a/plugins/bluemonkey/CMakeLists.txt +++ b/plugins/bluemonkey/CMakeLists.txt @@ -4,12 +4,12 @@ find_package(Qt5Core REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5Qml REQUIRED) if(Qt5Core_FOUND) - message(STATUS "using Qt5") + message(STATUS "using Qt5") - set(QT_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Qml_INCLUDE_DIRS}) - set(QT_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Network_LIBRARIES} ${Qt5Qml_LIBRARIES}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") - add_definitions(${Qt5Core_DEFINITIONS}) + set(QT_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Qml_INCLUDE_DIRS}) + set(QT_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Network_LIBRARIES} ${Qt5Qml_LIBRARIES}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") + add_definitions(${Qt5Core_DEFINITIONS}) endif(Qt5Core_FOUND) @@ -18,25 +18,25 @@ set(CMAKE_AUTOMOC ON) 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} amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${QT_LIBRARIES} ${communi_LIBRARIES}) - install(TARGETS bluemonkeyIrcModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) + 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} amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${QT_LIBRARIES} ${communi_LIBRARIES}) + install(TARGETS bluemonkeyIrcModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) endif(communi) find_package(Qt5Sql) if(Qt5Sql_FOUND) - message(STATUS "enabling database bluemonkey module") - add_library(bluemonkeyDbModule MODULE db.cpp) - set_target_properties(bluemonkeyDbModule PROPERTIES PREFIX "") - target_link_libraries(bluemonkeyDbModule ${link_libraries} amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${QT_LIBRARIES} ${Qt5Sql_LIBRARIES}) - install(TARGETS bluemonkeyDbModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) + message(STATUS "enabling database bluemonkey module") + add_library(bluemonkeyDbModule MODULE db.cpp) + set_target_properties(bluemonkeyDbModule PROPERTIES PREFIX "") + target_link_libraries(bluemonkeyDbModule ${link_libraries} amb -L${CMAKE_CURRENT_BINARY_DIR}/lib ${QT_LIBRARIES} ${Qt5Sql_LIBRARIES}) + install(TARGETS bluemonkeyDbModule LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) endif() include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${communi_INCLUDE_DIRS} ${QT_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common) @@ -53,4 +53,31 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.js ${CMAKE_CURRENT_BINARY_DIR install(TARGETS bluemonkeyplugin LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) install (FILES ${config_files} DESTINATION /etc/ambd/bluemonkey) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_BINARY_DIR}/bluemonkey.README @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/bluemonkey.in.idl ${CMAKE_CURRENT_BINARY_DIR}/docs/bluemonkey.idl @ONLY) + +set(bluemonkey_doc_files ${CMAKE_CURRENT_BINARY_DIR}/bluemonkey.README ${CMAKE_CURRENT_BINARY_DIR}/docs/bluemonkey.idl) + +if(enable_docs) + find_package(Doxygen) + if(DOXYGEN_FOUND) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + add_custom_target(bluemonkey_docs ALL ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating Bluemonkey javascript API documentation with Doxygen" VERBATIM) + + #generate mappings documentation + add_custom_target(genmappings_bluemonkey + python ${CMAKE_SOURCE_DIR}/tools/genmapping --output ${CMAKE_CURRENT_BINARY_DIR}/docs/ambdbusmappings.idl ${dbus_mapping_headers} + COMMENT "running genmapping") + add_dependencies(bluemonkey_docs genmappings_bluemonkey) + + install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/html DESTINATION ${DOC_INSTALL_DIR}/plugins/bluemonkey COMPONENT Docs) + install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/latex DESTINATION ${DOC_INSTALL_DIR}/plugins/bluemonkey COMPONENT Docs) + endif(DOXYGEN_FOUND) + +endif(enable_docs) + +install (FILES ${bluemonkey_doc_files} DESTINATION ${DOC_INSTALL_DIR}/plugins) + endif(bluemonkey_plugin) diff --git a/Doxyfile.in b/plugins/bluemonkey/Doxyfile.in index 015c9ad7..2a9ada12 100644 --- a/Doxyfile.in +++ b/plugins/bluemonkey/Doxyfile.in @@ -1,3 +1,3 @@ PROJECT_NAME = @PROJECT_NAME@ PROJECT_NUMBER = @PROJECT_VERSION@ -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/lib/ +INPUT = @CMAKE_CURRENT_BINARY_DIR@/docs/ diff --git a/plugins/bluemonkey/README b/plugins/bluemonkey/README new file mode 100644 index 00000000..27f47052 --- /dev/null +++ b/plugins/bluemonkey/README @@ -0,0 +1,30 @@ +Bluemonkey Source Plugin + +Bluemonkey is a javascript rendering engine that allows the scripting of source plugin behavior in javascript. + +To use the OBD-II Source plugin, add the following config to your /etc/ambd/config: + + +"sources" : [ + { + "name" : "bluemonkey", + "path" : "/usr/lib/automotive-message-broker/bluemonkeyplugin.so", + "config" : "/etc/ambd/bluemonkey/config.js" + } + ] + +Configuration Key Definitions: + +"name" +name of plugin. This key is not used by the plugin at this moment. + +"path" +path to plugin on the filesystem. + +"config" +path to the bluemonkey configuration script. + +Bluemonkey Javascript API: + +see bluemonkey.idl (installed to ${PREFIX}share/doc/packages/automotive-meassage-broker/plugins/ + diff --git a/plugins/bluemonkey/bluemonkey.cpp b/plugins/bluemonkey/bluemonkey.cpp index b8c98168..48cf662d 100644 --- a/plugins/bluemonkey/bluemonkey.cpp +++ b/plugins/bluemonkey/bluemonkey.cpp @@ -127,6 +127,20 @@ AbstractPropertyType* qVariantToAbstractPropertyType(QString name, QVariant var) return nullptr; } +QVariant toQVariant(AbstractPropertyType* val) +{ + QVariantMap value; + + value["name"] = val->name.c_str(); + value["zone"] = val->zone; + value["source"] = val->sourceUuid.c_str(); + value["timestamp"] = val->timestamp; + value["sequence"] = val->sequence; + value["value"] = gvariantToQVariant(val->toVariant()); + + return value; +} + BluemonkeySink::BluemonkeySink(AbstractRoutingEngine* e, map<string, string> config, AbstractSource &parent) : QObject(0), AmbPluginImpl(e, config, parent), engine(nullptr), mSilentMode(false) { @@ -174,12 +188,12 @@ QObject *BluemonkeySink::subscribeTo(QString str) return new Property(str.toStdString(), "", routingEngine, Zone::None, this); } -QObject *BluemonkeySink::subscribeToSource(QString str, QString srcFilter) +QObject *BluemonkeySink::subscribeTo(QString str, int zone, QString srcFilter) { - return new Property(str.toStdString(), srcFilter, routingEngine, Zone::None, this); + return new Property(str.toStdString(), srcFilter, routingEngine, zone, this); } -QObject* BluemonkeySink::subscribeToZone(QString str, int zone) +QObject* BluemonkeySink::subscribeTo(QString str, int zone) { return new Property(str.toStdString(), "", routingEngine, zone, this); } @@ -363,11 +377,9 @@ void BluemonkeySink::getHistory(QStringList properties, QDateTime begin, QDateTi { QVariantList list; - for(auto itr = reply->values.begin(); itr != reply->values.end(); itr++) + for(auto val : reply->values) { - AbstractPropertyType *val = *itr; - - list.append(gvariantToQVariant(val->toVariant())); + list.append(toQVariant(val)); } QJSValue val = cbFunction.engine()->toScriptValue<QVariantList>(list); @@ -469,12 +481,11 @@ void Property::getHistory(QDateTime begin, QDateTime end, QJSValue cbFunction) { QVariantList list; - for(auto itr = reply->values.begin(); itr != reply->values.end(); itr++) + for(auto val : reply->values) { - AbstractPropertyType *val = *itr; - - list.append(gvariantToQVariant(val->toVariant())); + list.append(toQVariant(val)); } + QJSValue val = cbFunction.engine()->toScriptValue<QVariantList>(list); cbFunction.call(QJSValueList()<<val); @@ -492,15 +503,15 @@ Property::Property(VehicleProperty::Property prop, QString srcFilter, AbstractRo setType(prop.c_str()); } -QString Property::type() +QString Property::name() { return mValue->name.c_str(); } void Property::setType(QString t) { - if(mValue && type() != "") - routingEngine->unsubscribeToProperty(type().toStdString(), this); + if(mValue && name() != "") + routingEngine->unsubscribeToProperty(name().toStdString(), this); routingEngine->subscribeToProperty(t.toStdString(), this); diff --git a/plugins/bluemonkey/bluemonkey.h b/plugins/bluemonkey/bluemonkey.h index b25daccc..7ba04d3e 100644 --- a/plugins/bluemonkey/bluemonkey.h +++ b/plugins/bluemonkey/bluemonkey.h @@ -47,16 +47,28 @@ Q_DECLARE_INTERFACE(ModuleInterface, "org.automotive.bluemonkey.moduleinterface" class Property: public QObject, public AbstractSink { Q_OBJECT - Q_PROPERTY(QString type READ type) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(QString source READ source) + Q_PROPERTY(double timestamp READ timestamp) Q_PROPERTY(QVariant value READ value WRITE setValue) Q_PROPERTY(int zone READ zone) public: Property(VehicleProperty::Property, QString srcFilter, AbstractRoutingEngine* re, Zone::Type zone = Zone::None, QObject *parent = 0); - QString type(); + QString name(); void setType(QString t); + QString source() + { + return mValue->sourceUuid.c_str(); + } + + double timestamp() + { + return mValue->timestamp; + } + virtual PropertyList subscriptions() { return PropertyList(); } virtual void supportedChanged(const PropertyList &) { @@ -111,8 +123,9 @@ private: //source privates public Q_SLOTS: QObject* subscribeTo(QString str); - QObject* subscribeToSource(QString str, QString srcFilter); - QObject* subscribeToZone(QString str, int zone); + QObject* subscribeTo(QString str, int zone); + QObject* subscribeTo(QString str, int zone, QString srcFilter); + QStringList sourcesForProperty(QString property); QVariant zonesForProperty(QString property, QString src); diff --git a/plugins/bluemonkey/bluemonkey.in.idl b/plugins/bluemonkey/bluemonkey.in.idl new file mode 100644 index 00000000..4cef21f2 --- /dev/null +++ b/plugins/bluemonkey/bluemonkey.in.idl @@ -0,0 +1,144 @@ +/*! + * \mainpage Automotive Message Broker Library Documentation - Bluemonkey Plugin + * \version @PROJECT_VERSION@ + * \section intro Introduction + * Bluemonkey is a javascript rendering engine that allows the scripting of source plugin behavior in javascript. + * It allows developers a quick way to prototype plugin code as well as a way to create custom properties. + * \section properties Properties + * Bluemonkey uses internal property names (not DBus API interface names). These properties are defined in + * lib/vehicleproperty.h. There are mappings from AMB internal property names to DBus API properties in the + * <a href="ambdbusmappings_8idl">mappings documentation</a>. The mappings comes in handy when you want to implement properties that are + * exported as an DBus API interface (ie, org.automotive.VehicleSpeed). + * \section example Example bluemonkey script + * \code + * var speedProperty = bluemonkey.subscribeTo("VehicleSpeed"); + * + * var testTimer = bluemonkey.createTimer(); + * testTimer.interval = 3000; + * testTimer.singleShot = false; + * testTimer.timeout.connect(function() { + * //VehicleSpeed + * speedProperty.value = Math.floor((Math.random() * 100) + 1); + * }); + * \endcode + * \section Javascript API documentation + * Javascript API documentation is found in bluemonkey.idl and is described using WebIDL. Plugin configuration documentation can be found in bluemonkey.README. + */ + + /*! + * \name @PROJECT_NAME@ Bluemonkey interface documentation + * \version @PROJECT_VERSION@ + * \brief the bluemonkey script engine is powered by Qt QML's javascript engine. It supports QObject types as well + * as ECMA script (javascript). All QObject properties, slots, and signals are available in javascript. + * \see Qt's QMetaObject system for additional details + */ + + +partial interface Navigator { + readonly attribute Bluemonkey bluemonkey; +}; + +interface Bluemonkey { + /*! + * \brief subscribe to a property + * \returns PropertyInterface representing the property + */ + PropertyInterface subscribeTo(DOMString propertyName, optional unsigned short zone, optional DOMString source); + + /*! + * \brief return the AMB sources that provide propertyName + */ + DOMString[] sourcesForProperty(DOMString propertyName); + + /*! + * \brief returns the available zones that contians propertyName + */ + unsigned short[] zonesForProperty(DOMString propertyName); + + /*! + * \brief return supported properties + */ + DOMString[] supportedProperties(); + + /*! + * \brief load another script + */ + void loadConfig(DOMString configFile); + + /*! + * \brief load a bluemonkey module + */ + void loadModule(DOMString moduleFile); + + /*! + * \brief log text to AMB output + */ + void log(DOMString text); + + /*! + * \brief + */ + QTimer createTimer(); + + /*! + * \brief + */ + QObject createQObject(); + + /*! + * \brief return logged data between "begin" and "end" + */ + void getHistory(DOMString[] properties, Date begin, Date end, HistoryCallback callback); + + /*! + * \brief + */ + void createCustomProperty(DOMString name, any value, optional unsigned short zone); + +}; + +interface PropertyInterface { + /*! + * \brief + */ + readonly attribute DOMString type; + + /*! + * \brief + */ + readonly attribute unsigned short zone; + + /*! + * \brief + */ + readonly attribute any value; + + /*! + * \brief + */ + readonly attribute DOMString source; + + /*! + * \brief + */ + readonly attribute DOMTimestamp timestamp; + + /*! + * \brief + */ + readonly attribute Signal changed; + + void getHistory(Date begin, Date end, HistoryCallback callback); +}; + +interface Signal { + /*! + * \brief + */ + void connect(ChangedCallback callback) +}; + +callback ChangedCallback = void(any value); (); + +callback HistoryCallback = void(PropertyInterface[] data); (); + diff --git a/plugins/common/CMakeLists.txt b/plugins/common/CMakeLists.txt index 8a2311ac..bf18717b 100644 --- a/plugins/common/CMakeLists.txt +++ b/plugins/common/CMakeLists.txt @@ -1,7 +1,7 @@ set(plugins_common_sources abstractio.hpp serialport.hpp bluetoothadapterproxy.c bluetooth.hpp bluetoothmanagerproxy.c bluetoothserialproxy.c bluetooth5.cpp canadapter.cpp cansocket.cpp cansocketreader.cpp - canbusimpl.cpp cansocketadapter.cpp logger.cpp mutex.cpp thread.cpp ambpluginimpl.cpp ambplugin.h) + canbusimpl.cpp cansocketadapter.cpp logger.cpp mutex.cpp thread.cpp ) set(plugins_common_headers_install abstractio.hpp serialport.hpp bluetooth.hpp bluetoothadapterproxy.h bluetoothmanagerproxy.h bluetoothserialproxy.h bluetooth5.h canbus.h canadapter.h cansocket.h cansocketreader.h - canbusimpl.h cansocketadapter.h canobserver.h logger.h mutex.h thread.h ambplugin.h ambpluginimpl.h) + canbusimpl.h cansocketadapter.h canobserver.h logger.h mutex.h thread.h) add_library(amb-plugins-common SHARED ${plugins_common_sources}) diff --git a/plugins/database/CMakeLists.txt b/plugins/database/CMakeLists.txt index 8f977d25..041fb01f 100644 --- a/plugins/database/CMakeLists.txt +++ b/plugins/database/CMakeLists.txt @@ -6,6 +6,9 @@ pkg_check_modules(sqlite REQUIRED sqlite3) include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${sqlite_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/plugins/common) +set(database_table_create "CREATE TABLE IF NOT EXISTS data (key TEXT, value BLOB, source TEXT, zone INTEGER, time REAL, sequence REAL, tripId TEXT)" CACHE INTERNAL "database plugin table create command") +add_definitions(-Ddatabase_table_create="${database_table_create}") + set(databasesinkplugin_headers databasesink.h utils.h basedb.hpp baseobject.h sqlitedatabase.h sqlitequery.h) set(databasesinkplugin_sources databasesink.cpp utils.cpp sqlitedatabase.cpp sqlitequery.cpp basedb.hpp) add_library(databasesinkplugin MODULE ${databasesinkplugin_sources}) @@ -14,6 +17,8 @@ target_link_libraries(databasesinkplugin amb -L${CMAKE_CURRENT_BINARY_DIR}/lib $ install(TARGETS databasesinkplugin LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_SOURCE_DIR}/README @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_BINARY_DIR}/database.README @ONLY) + +install (FILES ${CMAKE_CURRENT_BINARY_DIR}/database.README DESTINATION ${DOC_INSTALL_DIR}/plugins) endif(database_plugin) diff --git a/plugins/database/README b/plugins/database/README index f380f0ff..d18e9148 100644 --- a/plugins/database/README +++ b/plugins/database/README @@ -1,4 +1,5 @@ Database plugin +Version: @PROJECT_VERSION@ This plugin logs properties in a sqlite database file. It can also be used as a source to play back previous logs to AMB. @@ -10,15 +11,15 @@ cmake -Ddatabase_plugin=On .. To use the Database plugin, add the following to the "sources" array in /etc/ambd/config: { - "name" : "Database", - "path" : "/usr/lib/automotive-message-broker/databasesinkplugin.so", - "databaseFile" : "storage", - "bufferLength" : "100", - "properties" : "{ 'properties' : ['VehicleSpeed','EngineSpeed'] }", - "startOnLoad" : "false", - "playbackOnLoad" : "false", - "playbackMultiplier" : "1", - "frequency" : "1" + "name" : "Database", + "path" : "/usr/lib/automotive-message-broker/databasesinkplugin.so", + "databaseFile" : "storage", + "bufferLength" : "100", + "properties" : "{ 'properties' : ['VehicleSpeed','EngineSpeed'] }", + "startOnLoad" : "false", + "playbackOnLoad" : "false", + "playbackMultiplier" : "1", + "frequency" : "1" } Configuration Key Definitions: @@ -35,7 +36,7 @@ path to log file Default: "storage" "bufferLength" -Number of logged items to keep in memory before flushing to the database file. +Number of logged items to keep in memory before flushing to the database file. A higher number will reduce writes and improve performance. Default: 100 @@ -63,7 +64,7 @@ Default: 1 "frequency" Frequency in Hz in which the database will write contents. Only the newest values -will be written. Other values are discarded. If bufferLength is not full,the +will be written. Other values are discarded. If bufferLength is not full,the database will not be written to until it is. Default: 1 @@ -72,7 +73,7 @@ AMB Properties: DatabaseFile Type: string -File to be used to log or play back. +File to be used to log or play back. corresponds to configuration option "databaseFile". @@ -91,7 +92,7 @@ Type: bool Access: read/write Indicates whether database playback is occuring. Set to true to turn on playback. -Set to false to turn off playback. This property is mutually exclusive with the +Set to false to turn off playback. This property is mutually exclusive with the DatabaseLogging property. Setting this to true will turn off logging. Default: false when configuration option "playbackOnLoad" is not set. diff --git a/plugins/database/basedb.hpp b/plugins/database/basedb.hpp index 353b3284..4d6a1296 100644 --- a/plugins/database/basedb.hpp +++ b/plugins/database/basedb.hpp @@ -87,7 +87,7 @@ public: if(! db->Connected()) { DebugOut(0)<<"BaseDB: database not found "<<dbname<<endl; - throw -1; + return; } q = new sqlitequery(); diff --git a/plugins/database/databasesink.cpp b/plugins/database/databasesink.cpp index f7ed7cf7..9bfe5b25 100644 --- a/plugins/database/databasesink.cpp +++ b/plugins/database/databasesink.cpp @@ -140,7 +140,7 @@ DatabaseSink::DatabaseSink(AbstractRoutingEngine *engine, map<std::string, std:: :AmbPluginImpl(engine, config, parent), shared(nullptr), playback(false), playbackShared(nullptr), playbackMultiplier(1) { tablename = "data"; - tablecreate = "CREATE TABLE IF NOT EXISTS data (key TEXT, value BLOB, source TEXT, zone INTEGER, time REAL, sequence REAL, tripId TEXT)"; + tablecreate = database_table_create; if(config.find("bufferLength") != config.end()) { @@ -341,7 +341,7 @@ void DatabaseSink::setDatabaseFileName(string filename) { initDb(); - vector<vector<string> > supportedStr = shared->db->select("SELECT DISTINCT key, zone FROM " + tablename); + vector<vector<string> > supportedStr = shared->db->select("SELECT DISTINCT key, zone, source FROM " + tablename); for(int i=0; i < supportedStr.size(); i++) { @@ -350,11 +350,13 @@ void DatabaseSink::setDatabaseFileName(string filename) if(!contains(supported(), name)) { std::string zoneStr = supportedStr[i][1]; + std::string sourceStr = supportedStr[i][2]; - DebugOut() << "adding property " << name << " in zone: " << zoneStr << endl; + DebugOut() << "adding property " << name << " in zone: " << zoneStr << "for source: " << sourceStr << endl; Zone::Type zone = boost::lexical_cast<Zone::Type>(zoneStr); - addPropertySupport(zone, [name]() { return VehicleProperty::getPropertyTypeForPropertyNameValue(name); }); + auto property = addPropertySupport(zone, [name]() { return VehicleProperty::getPropertyTypeForPropertyNameValue(name); }); + property->sourceUuid = sourceStr; } } @@ -417,17 +419,18 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply) for(auto itr = reply->properties.begin(); itr != reply->properties.end(); itr++) { + DebugOut() << "prop: " << (*itr) << endl; if(itr != reply->properties.begin()) query<<" OR "; query<<"key='"<<(*itr)<<"'"; } - query<<") AND"; + query<<")"; - if(reply->timeBegin && reply->timeEnd) + if(reply->timeEnd) { - query<<" time BETWEEN "<<reply->timeBegin<<" AND "<<reply->timeEnd; + query<<" AND time BETWEEN "<<reply->timeBegin<<" AND "<<reply->timeEnd; } if(reply->sequenceBegin >= 0 && reply->sequenceEnd >=0) @@ -444,9 +447,19 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply) DebugOut()<<"Dataset size "<<data.size()<<endl; - for(auto i=0;i<data.size();i++) + if(!data.size()) { - if(data[i].size() != 6) + reply->success = false; + reply->error = AsyncPropertyReply::InvalidOperation; + } + else + { + reply->success = true; + } + + for(auto i=0; i<data.size(); i++) + { + if(data[i].size() != 7) continue; DBObject dbobj; @@ -456,6 +469,7 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply) dbobj.zone = boost::lexical_cast<double>(data[i][3]); dbobj.time = boost::lexical_cast<double>(data[i][4]); dbobj.sequence = boost::lexical_cast<double>(data[i][5]); + dbobj.tripId = data[i][6]; AbstractPropertyType* property = VehicleProperty::getPropertyTypeForPropertyNameValue(dbobj.key, dbobj.value); if(property) @@ -467,7 +481,7 @@ void DatabaseSink::getRangePropertyAsync(AsyncRangePropertyReply *reply) } } - reply->success = true; + reply->completed(reply); delete db; diff --git a/plugins/dbus/CMakeLists.txt b/plugins/dbus/CMakeLists.txt index 7bc4fd79..fc3b6e54 100644 --- a/plugins/dbus/CMakeLists.txt +++ b/plugins/dbus/CMakeLists.txt @@ -17,4 +17,7 @@ install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/amb.conf DESTINATION /etc/dbus-1/syst configure_file(${CMAKE_CURRENT_SOURCE_DIR}/amb.conf ${CMAKE_CURRENT_SOURCE_DIR}/amb.conf) +set(dbus_mapping_headers ${CMAKE_CURRENT_SOURCE_DIR}/runningstatus.h ${CMAKE_CURRENT_SOURCE_DIR}/environmentproperties.h ${CMAKE_CURRENT_SOURCE_DIR}/vehicleinfo.h ${CMAKE_CURRENT_SOURCE_DIR}/maintenance.h ${CMAKE_CURRENT_SOURCE_DIR}/parking.h ${CMAKE_CURRENT_SOURCE_DIR}/drivingsafety.h ${CMAKE_CURRENT_SOURCE_DIR}/personalization.h + CACHE INTERNAL "dbus mapping headers") + add_subdirectory(amb-qt) diff --git a/plugins/dbus/abstractdbusinterface.cpp b/plugins/dbus/abstractdbusinterface.cpp index dce2888b..c8dcdf17 100644 --- a/plugins/dbus/abstractdbusinterface.cpp +++ b/plugins/dbus/abstractdbusinterface.cpp @@ -103,7 +103,8 @@ static void handleMyMethodCall(GDBusConnection *connection, { AbstractProperty* prop = (*itr).second; - propertyList.push_back(prop->ambPropertyName()); + if(!contains(propertyList, prop->ambPropertyName())) + propertyList.push_back(prop->ambPropertyName()); } std::string ifaceName = iface->interfaceName(); @@ -114,7 +115,7 @@ static void handleMyMethodCall(GDBusConnection *connection, request.timeBegin = beginTime; request.timeEnd = endTime; request.zone = iface->zone(); - request.sourceUuid = iface->source(); + //request.sourceUuid = iface->source(); request.completed = [&invocation,&ifaceName](AsyncRangePropertyReply* reply) { @@ -247,7 +248,7 @@ void AbstractDBusInterface::addProperty(AbstractProperty* property) "</method>" "<signal name='" + pn + "Changed' >" " <arg type='v' name='" + nameToLower + "' direction='out' />" - " <arg type='d' name='timestamp' direction='out' />" + " <arg type='d' name='imestamp' direction='out' />" "</signal>" "<property type='i' name='" + property->name() + "Sequence' access='read' />"; diff --git a/plugins/dbus/amb-qt/CMakeLists.txt b/plugins/dbus/amb-qt/CMakeLists.txt index 1bf54b79..a1ae739c 100644 --- a/plugins/dbus/amb-qt/CMakeLists.txt +++ b/plugins/dbus/amb-qt/CMakeLists.txt @@ -10,11 +10,6 @@ if(Qt5Core_FOUND) set(QT_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS} ${Qt5Quick_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS}) set(QT_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Quick_LIBRARIES} ${Qt5DBus_LIBRARIES}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") - message(STATUS "size of void_p: ${CMAKE_SIZEOF_VOID_P}") - if(CMAKE_SIZEOF_VOID_P MATCHES "8") - message(STATUS "can has 64bits") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=large") - endif(CMAKE_SIZEOF_VOID_P MATCHES "8") add_definitions(${Qt5Core_DEFINITIONS}) set(CMAKE_AUTOMOC ON) endif(Qt5Core_FOUND) diff --git a/plugins/dbus/dbusplugin.cpp b/plugins/dbus/dbusplugin.cpp index e95644ed..241dc134 100644 --- a/plugins/dbus/dbusplugin.cpp +++ b/plugins/dbus/dbusplugin.cpp @@ -72,6 +72,7 @@ void DBusSink::supportedChanged(const PropertyList &supportedProperties) routingEngine->subscribeToProperty(p, mSourceFilter, this); addProperty(prop); supported = true; + mTime = amb::currentTime(); } } } diff --git a/plugins/dbus/dbusplugin.h b/plugins/dbus/dbusplugin.h index 897fdef1..9440e740 100644 --- a/plugins/dbus/dbusplugin.h +++ b/plugins/dbus/dbusplugin.h @@ -67,19 +67,6 @@ public: } protected: - template <typename T> - void wantProperty(VehicleProperty::Property property, std::string propertyName, std::string signature, AbstractProperty::Access access) - { - //propertyDBusMap[property] = new VariantType(routingEngine, signature, property, propertyName, access); - propertyDBusMap.push_back( new VariantType(routingEngine, property, propertyName, access)); - } - - - void wantPropertyString(VehicleProperty::Property property, std::string propertyName, std::string signature, AbstractProperty::Access access) - { - //propertyDBusMap[property] = new VariantType(routingEngine, signature, property, propertyName, access); - propertyDBusMap.push_back( new VariantType(routingEngine, property, propertyName, access)); - } void wantPropertyVariant(VehicleProperty::Property ambProperty, std::string propertyName, std::string signature, AbstractProperty::Access access) { diff --git a/plugins/dbus/environmentproperties.h b/plugins/dbus/environmentproperties.h index a235f976..be54b125 100644 --- a/plugins/dbus/environmentproperties.h +++ b/plugins/dbus/environmentproperties.h @@ -18,7 +18,7 @@ public: * @access readonly * @attributeComment \brief Must return the brightness outside the vehicle in lux. */ - wantPropertyVariant(VehicleProperty::ExteriorBrightness,"ExteriorBrightness", "q", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::ExteriorBrightness, "ExteriorBrightness", "q", AbstractProperty::Read); } }; @@ -207,7 +207,7 @@ public: WindowStatusProperty(VehicleProperty::Property, AbstractRoutingEngine* re, GDBusConnection* connection) :DBusSink("WindowStatus", re, connection, map<string, string>()) { - wantPropertyVariant(VehicleProperty::WindowStatus,"Openness", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::WindowStatus, "Openness", AbstractProperty::ReadWrite); wantPropertyVariant(VehicleProperty::Defrost, "Defrost", AbstractProperty::ReadWrite); } }; @@ -218,7 +218,7 @@ public: SideWindowStatusProperty(VehicleProperty::Property, AbstractRoutingEngine* re, GDBusConnection* connection) :DBusSink("SideWindow", re, connection, map<string, string>()) { - wantPropertyVariant(VehicleProperty::WindowStatus,"Openness", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::WindowStatus, "Openness", AbstractProperty::ReadWrite); wantPropertyVariant(VehicleProperty::WindowLockStatus, "Lock", AbstractProperty::ReadWrite); } }; @@ -229,7 +229,7 @@ public: DefrostProperty(VehicleProperty::Property, AbstractRoutingEngine* re, GDBusConnection* connection) :DBusSink("Defrost", re, connection, map<string, string>()) { - wantPropertyVariant(VehicleProperty::DefrostWindow,"DefrostWindow", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::DefrostWindow, "DefrostWindow", AbstractProperty::ReadWrite); wantPropertyVariant(VehicleProperty::DefrostMirror, "DefrostMirror", AbstractProperty::ReadWrite); } }; diff --git a/plugins/dbus/parking.h b/plugins/dbus/parking.h index 483fd259..7355b487 100644 --- a/plugins/dbus/parking.h +++ b/plugins/dbus/parking.h @@ -13,7 +13,7 @@ public: SecurityAlertProperty(VehicleProperty::Property, AbstractRoutingEngine* re, GDBusConnection* connection) :DBusSink("SecurityAlert", re, connection, map<string, string>()) { - wantProperty<Security::Status>(VehicleProperty::SecurityAlertStatus,"SecurityAlert", "i", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::SecurityAlertStatus, "SecurityAlert", "i", AbstractProperty::Read); } }; @@ -29,9 +29,9 @@ public: * @access readonly * @attributeComment must return status of parking brake: Engaged = true, Disengaged = false. **/ - wantProperty<bool>(VehicleProperty::ParkingBrakeStatus,"ParkingBrake", "b", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::ParkingBrakeStatus, "ParkingBrake", "b", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::ParkingBrakeStatusW3C,"Status", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::ParkingBrakeStatusW3C, "Status", AbstractProperty::Read); } @@ -50,7 +50,7 @@ public: * @access readonly * @attributeComment must return status of parking light: Engaged = true, Disengaged = false. **/ - wantProperty<bool>(VehicleProperty::ParkingLightStatus,"ParkingLight", "b", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::ParkingLightStatus, "ParkingLight", "b", AbstractProperty::Read); } }; @@ -66,7 +66,7 @@ public: * @access readonly * @attributeComment must return status of hazard light: Engaged = true, Disengaged = false. **/ - wantProperty<bool>(VehicleProperty::HazardLightStatus,"HazardLight", "b", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::HazardLightStatus, "HazardLight", "b", AbstractProperty::ReadWrite); } }; diff --git a/plugins/dbus/personalization.h b/plugins/dbus/personalization.h index f6bc518a..9bba7b85 100644 --- a/plugins/dbus/personalization.h +++ b/plugins/dbus/personalization.h @@ -61,12 +61,12 @@ public: SeatAdjustment(VehicleProperty::Property, AbstractRoutingEngine* re, GDBusConnection* connection) :DBusSink("SeatAdjustment", re, connection, map<string, string>()) { - wantPropertyVariant(VehicleProperty::SeatPositionBackCushion,"SeatBackCushion", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::SeatPositionRecline,"SeatReclineBack", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::SeatPositionSlide,"SeatSlide", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::SeatPositionCushionHeight,"SeatCushionHeight", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::SeatPositionHeadrest,"SeatHeadrest", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::SeatPositionSideCushion,"SeatSideCushion", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::SeatPositionBackCushion, "SeatBackCushion", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::SeatPositionRecline, "SeatReclineBack", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::SeatPositionSlide, "SeatSlide", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::SeatPositionCushionHeight, "SeatCushionHeight", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::SeatPositionHeadrest, "SeatHeadrest", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::SeatPositionSideCushion, "SeatSideCushion", AbstractProperty::ReadWrite); } }; diff --git a/plugins/dbus/runningstatus.h b/plugins/dbus/runningstatus.h index 4d5825c9..f9deaf45 100644 --- a/plugins/dbus/runningstatus.h +++ b/plugins/dbus/runningstatus.h @@ -35,10 +35,10 @@ public: * @access readonly * @attributeComment \brief Must return Vehicle Speed in kilometers per hour. **/ - wantPropertyVariant(VehicleProperty::VehicleSpeed,"Speed", "i", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::VehicleSpeed, "Speed", AbstractProperty::Read); /// Deprecated: - wantPropertyVariant(VehicleProperty::VehicleSpeed,"VehicleSpeed", "i", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::VehicleSpeed, "VehicleSpeed", AbstractProperty::Read); } @@ -57,10 +57,10 @@ public: * @access readonly * @attributeComment \brief Must return Engine Speed in rotations per minute. **/ - wantPropertyVariant(VehicleProperty::EngineSpeed,"Speed", "i", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::EngineSpeed, "Speed", AbstractProperty::Read); /// Deprecated: - wantPropertyVariant(VehicleProperty::EngineSpeed,"EngineSpeed", "i", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::EngineSpeed, "EngineSpeed", AbstractProperty::Read); } @@ -131,17 +131,13 @@ public: :DBusSink("Transmission", re, connection, map<string, string>()) { - wantPropertyVariant(VehicleProperty::TransmissionShiftPosition, - "ShiftPosition", "y", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::TransmissionShiftPosition, "ShiftPosition", "y", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::TransmissionGearPosition, - "GearPosition", "y", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::TransmissionGearPosition, "GearPosition", "y", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::TransmissionGearPosition, - "Gear", "y", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::TransmissionGearPosition, "Gear", "y", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::TransmissionModeW3C, - "Mode", "y", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::TransmissionModeW3C, "Mode", "y", AbstractProperty::Read); wantPropertyVariant(VehicleProperty::TransmissionGearType, "Type", "q", AbstractProperty::Read); } @@ -242,8 +238,8 @@ public: :DBusSink("Horn", re, connection, map<string, string>()) { /// TODO: deprecated remove in 0.14 - wantPropertyVariant(VehicleProperty::Horn,"On",AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::Horn,"Status",AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::Horn, "On", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::Horn, "Status", AbstractProperty::Read); } }; @@ -255,21 +251,21 @@ public: FuelProperty(VehicleProperty::Property, AbstractRoutingEngine *re, GDBusConnection *connection) :DBusSink("Fuel", re, connection, map<string, string>()) { - wantPropertyVariant(VehicleProperty::FuelLevel,"Level", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::FuelLevel, "Level", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::FuelRange,"Range", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::FuelRange, "Range", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::FuelConsumption,"InstantConsumption", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::FuelConsumption, "InstantConsumption", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::FuelEconomy,"InstantEconomy", AbstractProperty::Read); + wantPropertyVariant(VehicleProperty::FuelEconomy, "InstantEconomy", AbstractProperty::Read); - wantPropertyVariant(VehicleProperty::FuelAverageEconomy,"AverageEconomy", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::FuelAverageEconomy, "AverageEconomy", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::FuelAverageConsumption,"AverageConsumption", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::FuelAverageConsumption, "AverageConsumption", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::FuelConsumptionSinceRestart,"FuelConsumedSinceRestart", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::FuelConsumptionSinceRestart, "FuelConsumedSinceRestart", AbstractProperty::ReadWrite); - wantPropertyVariant(VehicleProperty::FuelTimeSinceRestart,"TimeSinceRestart", AbstractProperty::ReadWrite); + wantPropertyVariant(VehicleProperty::FuelTimeSinceRestart, "TimeSinceRestart", AbstractProperty::ReadWrite); } }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e54f797b..36d50cf8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,12 +1,13 @@ set(amb_tests ${CMAKE_CURRENT_BINARY_DIR}/amb-get ${CMAKE_CURRENT_BINARY_DIR}/amb-set - ${CMAKE_CURRENT_BINARY_DIR}/amb-get-history ${CMAKE_CURRENT_BINARY_DIR}/amb-listen - ${CMAKE_CURRENT_BINARY_DIR}/gen-set) + ${CMAKE_CURRENT_BINARY_DIR}/amb-get-history ${CMAKE_CURRENT_BINARY_DIR}/amb-listen + ${CMAKE_CURRENT_BINARY_DIR}/gen-set) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-get.py ${CMAKE_CURRENT_BINARY_DIR}/amb-get @ONLY) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-set.py ${CMAKE_CURRENT_BINARY_DIR}/amb-set @ONLY) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-get-history.py ${CMAKE_CURRENT_BINARY_DIR}/amb-get-history @ONLY) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/amb-listen.py ${CMAKE_CURRENT_BINARY_DIR}/amb-listen @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gen-set.py ${CMAKE_CURRENT_BINARY_DIR}/gen-set @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gen-set.py ${CMAKE_CURRENT_SOURCE_DIR}/gen-set @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gendb.sh ${CMAKE_CURRENT_SOURCE_DIR}/gendb @ONLY) install (PROGRAMS ${amb_tests} DESTINATION bin) diff --git a/tests/amb-get-history.py b/tests/amb-get-history.py index f934e0d8..637e7d2b 100755 --- a/tests/amb-get-history.py +++ b/tests/amb-get-history.py @@ -5,6 +5,8 @@ import sys import argparse import json +print "This application is deprecated. It will disappear in the future. Use ambctl" + parser = argparse.ArgumentParser() parser.add_argument("get", help="{objectName}") parser.add_argument("start", help="{startTime}") diff --git a/tests/amb-get.py b/tests/amb-get.py index 4a70401b..352961b9 100755 --- a/tests/amb-get.py +++ b/tests/amb-get.py @@ -5,6 +5,8 @@ import sys import argparse import json +print "This application is deprecated. It will disappear in the future. Use ambctl" + parser = argparse.ArgumentParser() parser.add_argument("get", help="get {objectName}") args = parser.parse_args() diff --git a/tests/amb-listen.py b/tests/amb-listen.py index 81ecfaca..1b28996a 100755 --- a/tests/amb-listen.py +++ b/tests/amb-listen.py @@ -7,6 +7,7 @@ import gobject import json from dbus.mainloop.glib import DBusGMainLoop +print "This application is deprecated. It will disappear in the future. Use ambctl" def print_data(interface, properties, invalidated): print json.dumps(properties, indent=2) @@ -28,7 +29,7 @@ for o in objects: bus.add_signal_receiver(print_data, dbus_interface="org.freedesktop.DBus.Properties", signal_name="PropertiesChanged", - path=o) + path=o) loop = gobject.MainLoop() loop.run() diff --git a/tests/amb-set.py b/tests/amb-set.py index 1c7e02c5..bbdbc48d 100755 --- a/tests/amb-set.py +++ b/tests/amb-set.py @@ -4,6 +4,8 @@ import dbus import sys import argparse +print "This application is deprecated. It will disappear in the future. Use ambctl" + parser = argparse.ArgumentParser() parser.add_argument("objectName", help="{objectName}") parser.add_argument("property", help="{propertyToSet}") @@ -22,17 +24,17 @@ zone = int(args.zone) realValue = 0 if valueType == "boolean": - realValue = value == "true" + realValue = value == "true" elif valueType == "integer": - realValue = dbus.Int32(value) + realValue = dbus.Int32(value) elif valueType == "string": - realValue = value + realValue = value elif valueType == "double": - realValue = double(value) + realValue = double(value) elif valueType == "UInt16": - realValue = dbus.UInt16(value) + realValue = dbus.UInt16(value) else: - raise Exception("Unknown type: " + valueType) + raise Exception("Unknown type: " + valueType) bus = dbus.SystemBus() managerObject = bus.get_object("org.automotive.message.broker", "/"); diff --git a/tests/gendb.sh b/tests/gendb.sh index 34a1978d..9830d82d 100755 --- a/tests/gendb.sh +++ b/tests/gendb.sh @@ -1,23 +1,28 @@ #!/bin/bash -TABLE="CREATE TABLE IF NOT EXISTS data (key TEXT, value BLOB, source TEXT, time REAL, sequence REAL);" +TABLE="@database_table_create@;" + +if [ -f generated.db ]; + then + rm generated.db +fi -rm generated.db -rm generated.db.sql echo $TABLE > generated.db.sql echo "BEGIN IMMEDIATE TRANSACTION;" >> generated.db.sql -for (( i=0; i<120; i++ )) +for (( i=0; i<130; i++ )) do T=$(echo 1385571956 + $i) for (( n=1; n<1000; n++ )) do MS=$(echo $n \* 0.001 | bc) TIME=$(echo $T + $MS | bc) - echo "insert into data values('VehicleSpeed',$(( ( RANDOM % 300 ) + 1 )),'test', $TIME, -1);" >> generated.db.sql + echo "insert into data values('VehicleSpeed', $(( ( RANDOM % 300 ) + 1 )),'test', 0, $TIME, -1, 'alskejroanpnfansadfasdfa');" >> generated.db.sql done done echo "END TRANSACTION;" >> generated.db.sql sqlite3 generated.db < generated.db.sql + +exit diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 00000000..32f49b9f --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,4 @@ +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/genmapping.py ${CMAKE_CURRENT_SOURCE_DIR}/genmapping @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/ambctl.py ${CMAKE_CURRENT_SOURCE_DIR}/ambctl @ONLY) + +install (PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/ambctl DESTINATION bin) diff --git a/tools/ambctl.py b/tools/ambctl.py new file mode 100644 index 00000000..c49cbc31 --- /dev/null +++ b/tools/ambctl.py @@ -0,0 +1,341 @@ +#!/usr/bin/python + +import argparse +import dbus +import sys +import json +import gobject +import fileinput +import termios, fcntl, os +import glib +import curses.ascii +from dbus.mainloop.glib import DBusGMainLoop + +def help(): + help = ("Available commands:\n" + "help Prints help data\n" + "list List supported ObjectNames\n" + "get Get properties from an ObjectName\n" + "listen Listen for changes on an ObjectName\n" + "set Set a property for an ObjectName\n" + "getHistory Get logged data within a time range\n" + "quit Exit ambctl\n") + return help + +def changed(interface, properties, invalidated): + print json.dumps(properties, indent=2) + +def processCommand(command, commandArgs, noMain=True): + + if command == 'help': + print help() + return 1 + + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + bus = dbus.SystemBus() + try: + managerObject = bus.get_object("org.automotive.message.broker", "/"); + managerInterface = dbus.Interface(managerObject, "org.automotive.Manager") + except: + print "Error connecting to AMB. is AMB running?" + return 1 + + if command == "list" : + supportedList = managerInterface.List() + for objectName in supportedList: + print objectName + return 1 + elif command == "get": + if commandArgs[0] == "help": + print "ObjectName [ObjectName...]" + return 1 + + for objectName in commandArgs: + objects = managerInterface.FindObject(objectName) + print objectName + for o in objects: + propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", o),"org.freedesktop.DBus.Properties") + print json.dumps(propertiesInterface.GetAll("org.automotive."+objectName), indent=2) + return 1 + elif command == "listen": + if commandArgs[0] == "help": + print "ObjectName [ObjectName...]" + return 1 + for objectName in commandArgs: + objects = managerInterface.FindObject(objectName) + for o in objects: + bus.add_signal_receiver(changed, + dbus_interface="org.freedesktop.DBus.Properties", + signal_name="PropertiesChanged", path=o) + if noMain != True: + try: + main_loop = gobject.MainLoop(None, False) + main_loop.run() + except KeyboardInterrupt: + return 1 + elif command == "set": + if len(commandArgs) and commandArgs[0] == "help": + print "ObjectName PropertyName VALUE [ZONE]" + return 1 + if len(commandArgs) < 3: + print "set requires more arguments (see set help)" + return 1 + objectName = commandArgs[0] + propertyName = commandArgs[1] + value = commandArgs[2] + zone = 0 + if len(commandArgs) == 4: + zone = int(commandArgs[3]) + object = managerInterface.FindObjectForZone(objectName, zone) + propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.freedesktop.DBus.Properties") + property = propertiesInterface.Get("org.automotive."+objectName, propertyName) + realValue = property.__class__(value) + propertiesInterface.Set("org.automotive."+objectName, propertyName, realValue) + property = propertiesInterface.Get("org.automotive."+objectName, propertyName) + if property == realValue: + print propertyName + " = ", property + else: + print "Error setting property" + return 1 + elif command == "getHistory": + if commandArgs[0] == "help": + print "ObjectName [STARTTIME] [ENDTIME] [ZONE]" + return 1 + if len(commandArgs) < 1: + print "getHistory requires more arguments (see getHistory help)" + return 1 + objectName = commandArgs[0] + start = 1 + if len(commandArgs) >= 2: + start = float(commandArgs[1]) + end = 9999999999 + if len(commandArgs) >= 3: + end = float(commandArgs[2]) + zone = 0 + if len(commandArgs) == 4: + zone = int(commandArgs[3]) + object = managerInterface.FindObjectForZone(objectName, zone); + propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.automotive."+objectName) + print json.dumps(propertiesInterface.GetHistory(start, end), indent=2) + else: + print "Invalid command" + return 1 + + + +parser = argparse.ArgumentParser(description='Process DBus mappings.') +parser.add_argument('command', metavar='COMMAND [help]', nargs='?', default='stdin', help='amb dbus command') + +parser.add_argument('commandArgs', metavar='ARG', nargs='*', + help='amb dbus command arguments') + +args = parser.parse_args() + +if args.command == "stdin": + class Data: + history = [] + line = "" + templine = "" + promptAmbctl = "[ambctl]" + promptEnd = "# " + fullprompt = promptAmbctl + promptEnd + curpos = 0 + historypos = -1 + def full_line_len(self): + return len(self.fullprompt) + len(self.line) + def insert(self, str): + if self.curpos == len(self.line): + self.line+=str + self.curpos = len(self.line) + else: + self.line = self.line[:self.curpos] + str + self.line[self.curpos:] + self.curpos+=1 + def arrow_back(self): + if self.curpos > 0: + self.curpos-=1 + return True + return False + + def arrow_forward(self): + if self.curpos < len(self.line): + self.curpos+=1 + return True + return False + + def back_space(self): + if self.curpos > 0: + self.curpos-=1 + self.line = self.line[:self.curpos] + self.line[self.curpos+1:] + return True + return False + def delete(self): + if self.curpos < len(self.line): + self.line = self.line[:self.curpos] + self.line[self.curpos+2:] + return True + return False + + def save_temp(self): + if len(self.history)-1 == 0 or len(self.history)-1 != self.historypos: + return + self.templine = self.line + + def push(self): + self.history.append(self.line) + self.historypos = len(self.history)-1 + self.clear() + + def set(self, str): + self.line = str + self.curpos = len(self.line) + + def history_up(self): + if self.historypos >= 0: + self.line = self.history[self.historypos] + if self.historypos != 0: + self.historypos-=1 + return True + return False + + def history_down(self): + if self.historypos >= 0 and self.historypos < len(self.history)-1: + self.historypos+=1 + self.line = self.history[self.historypos] + + else: + self.historypos = len(self.history)-1 + self.set(self.templine) + + return True + + def clear(self): + self.set("") + templist = "" + + + + class bcolors: + HEADER = '\x1b[95m' + OKBLUE = '\x1b[94m' + OKGREEN = '\x1b[92m' + WARNING = '\x1b[93m' + FAIL = '\x1b[91m' + ENDC = '\x1b[0m' + GREEN = '\x1b[32m' + WHITE = '\x1b[37m' + BLUE = '\x1b[34m' + + def erase_line(): + sys.stdout.write('\x1b[2K\x1b[80D') + + def cursor_left(): + sys.stdout.write('\x1b[1D') + + def cursor_right(): + sys.stdout.write('\x1b[1C') + + def display_prompt(): + sys.stdout.write(bcolors.OKBLUE+Data.promptAmbctl+bcolors.WHITE+Data.promptEnd); + + def redraw(data): + erase_line() + display_prompt() + sys.stdout.write(data.line) + cursorpos = len(data.line) - data.curpos + for x in xrange(cursorpos): + cursor_left() + sys.stdout.flush() + + def handle_keyboard(source, cond, data): + str = source.read() + #print "char: ", ord(str) + + if len(str) > 1: + if ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 68: #left arrow + if data.arrow_back(): + cursor_left() + sys.stdout.flush() + elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 67: #right arrow + if data.arrow_forward(): + cursor_right() + sys.stdout.flush() + elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 70: #end + while data.arrow_forward(): + cursor_right() + sys.stdout.flush() + elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 72: #home + while data.arrow_back(): + cursor_left() + sys.stdout.flush() + elif len(str) == 4 and ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 51 and ord(str[3]) == 126: #del + data.delete() + redraw(data) + elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 65: + #up arrow + data.save_temp() + data.history_up() + while data.arrow_forward(): + cursor_right() + redraw(data) + elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 66: + #down arrow + data.history_down() + while data.arrow_forward(): + cursor_right() + redraw(data) + elif ord(str) == 10: #enter + if data.line == "": + return True + print "" + words = data.line.split(' ') + if words[0] == "quit": + sys.exit() + try: + if len(words) > 1: + processCommand(words[0], words[1:]) + else: + processCommand(words[0], []) + except dbus.exceptions.DBusException, error: + print error + except: + print "Error running command ", sys.exc_info()[0] + data.push(); + data.clear() + redraw(data) + elif ord(str) == 127: #backspace + data.back_space() + redraw(data) + elif curses.ascii.isalnum(ord(str)) or ord(str) == curses.ascii.SP: #regular text + data.insert(str) + redraw(data) + + return True + print "@PROJECT_PRETTY_NAME@ @PROJECT_VERSION@" + + data = Data() + fd = sys.stdin.fileno() + old = termios.tcgetattr(fd) + new = termios.tcgetattr(fd) + new[3] = new[3] & ~termios.ICANON & ~termios.ECHO + termios.tcsetattr(fd, termios.TCSANOW, new) + + oldflags = fcntl.fcntl(fd, fcntl.F_GETFL) + fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK) + + io_stdin = glib.IOChannel(fd) + io_stdin.add_watch(glib.IO_IN, handle_keyboard, data) + + try: + erase_line() + display_prompt() + sys.stdout.flush() + main_loop = gobject.MainLoop(None, False) + main_loop.run() + except KeyboardInterrupt: + sys.exit() + finally: + termios.tcsetattr(fd, termios.TCSAFLUSH, old) + fcntl.fcntl(fd, fcntl.F_SETFL, oldflags) + +else: + processCommand(args.command, args.commandArgs, False) + diff --git a/tools/genmapping.py b/tools/genmapping.py new file mode 100755 index 00000000..143a67fc --- /dev/null +++ b/tools/genmapping.py @@ -0,0 +1,90 @@ +#!/usr/bin/python + +import os +import argparse + +parser = argparse.ArgumentParser(description='Process DBus mappings.') +parser.add_argument('mappingFiles', metavar='N', nargs='+', + help='dbus headers to find mappings in') +parser.add_argument('--output', dest='output', + help='output file to write idl to') +args = parser.parse_args() +print "parsing" +print args.mappingFiles + +interfaces = [] + +class Member: + ambName = "" + memberName = "" + + def __repr__(self): + return "Member" + def toString(self): + return "{" + self.ambName + " => " + self.memberName + "}" + def toIdl(self): + return ' const DOMString ' + self.ambName + ' = "' + self.memberName + '";\n' + +class Interface: + def __init__(self): + self.name = "" + self.members = [] + def __repr__(self): + return "Interface('" + name + "')" + def toString(self): + output = self.name + ":" + for member in self.members: + output += member.toString() + "," + return output + def toIdl(self): + output = "interface " + self.name + " {\n" + for member in self.members: + output += member.toIdl() + output += "\n};\n" + return output + +for input in args.mappingFiles: + try: file = open(input) + except IOError: + print "Failed to open " + input + with file: + for line in file: + i = line.find("DBusSink(\""); + if i != -1: + interface = Interface() + ifaceNameBeg = line.find('("') + ifaceNameEnd = line.find('",') + interface.name = line[ifaceNameBeg+2 : ifaceNameEnd] + interfaces.append(interface) + wantPropertyVariant = 'wantPropertyVariant(' + i = line.find(wantPropertyVariant) + if i!= -1: + member = Member() + ambNameEnd = line.find(', "')-2 + member.ambName = line[i+len(wantPropertyVariant) : i + ambNameEnd].replace("VehicleProperty::", "") + memberNameBeg = line.find(', "')+3 + memberNameEnd = line.find('",') + member.memberName = line[memberNameBeg : memberNameEnd] + interfaces[-1].members.append(member) + file.close() + +try: outputFile = open(args.output, 'w') +except IOError: + print "Error could not open output file: " + args.output +with outputFile: + header =("/*!\n" + " * \\name AMB to AMB-DBus Mapping Tables\n" + " * \\file " + os.path.basename(args.output) + "\n" + " * \\brief This describes the AMB internal property names to AMB DBus interface property names\n" + " * AMB internal property names are designed to be flat variable names (ie, 'ConvertableRoofStatus'). The DBus\n" + " * properties however follow the naming scheme defined in the W3C automotive business group vehicle <a href='http://w3c.github.io/automotive-bg/data_spec.html'>data specification</a>\n" + " * The pattern each interface is 'const DOMString AMBProperty = DBusProperty' where 'AMBProperty' is the internal name and 'DBusProperty' is the DBus property name") + header += " */\n\n" + outputFile.write(header) + for iface in interfaces: + outputFile.write(iface.toIdl()) + outputFile.write("\n") + outputFile.close() + + + diff --git a/xwalk/vehicle.html b/xwalk/vehicle.html index 19d9c218..dd8961a3 100644 --- a/xwalk/vehicle.html +++ b/xwalk/vehicle.html @@ -10,21 +10,41 @@ vehicle = navigator.vehicle; function get(objName) { - if(!vehicle[objName].get) { - debug("no get() method for " + objName); - return; - } - - vehicle[objName].get().then(function(data) { - try { - debug("get " + objName + ": " + JSON.stringify(data)); - } catch(error) { - debug("error " + error.message); - } - }, - function(error) { - debug("error getting " + objName + ": " + error.message); - }); + if(!vehicle[objName].get) { + debug("Error no get() method for " + objName); + return; + } + + var zones = vehicle[objName].zones; + if(zones.length !== 0) + { + for(var zone in zones) + { + vehicle[objName].get(zone).then(function(data) { + try { + debug("get " + objName + ": " + JSON.stringify(data)); + } catch(error) { + debug("error " + error.message); + } + }, + function(error) { + debug("error getting " + objName + ": " + error.message); + }); + } + } + else + { + vehicle[objName].get().then(function(data) { + try { + debug("get " + objName + ": " + JSON.stringify(data)); + } catch(error) { + debug("error " + error.message); + } + }, + function(error) { + debug("error getting " + objName + ": " + error.message); + }); + } } debug("testing zones..."); @@ -50,34 +70,34 @@ debug("testing subscribe()"); var subReplies = 0; var handle = vehicle.vehicleSpeed.subscribe(function(data) { - console.log("got subscribe callback"); - debug("Vehicle speed changed: " + data.speed); - subReplies++; - - if (subReplies === 5) { - debug("unsubscribing"); - vehicle.vehicleSpeed.unsubscribe(handle); - } + console.log("got subscribe callback"); + debug("Vehicle speed changed: " + data.speed); + subReplies++; + + if (subReplies === 5) { + debug("unsubscribing"); + vehicle.vehicleSpeed.unsubscribe(handle); + } }); debug("test invalid zone error"); vehicle.vehicleSpeed.get("invalidzone").then(function() { }, - function(error) { debug("Invalid zone: " + error.message); }); + function(error) { debug("Invalid zone: " + error.message); }); ///test set() debug("testing set()"); vehicle.lightStatus.set({"fog" : false}).then(function() { - debug("set success!"); + debug("set success!"); }, function(error) { - debug("set fail! " + error.message); + debug("set fail! " + error.message); }); for(var propName in vehicle) { - if(typeof(obj[propName]) != "undefined") { - debug("vehicle." + propName); - get(propName); - } + if(typeof(vehicle[propName]) != "undefined") { + debug("vehicle." + propName); + get(propName); + } } </script> |