diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bb82856f..185d0bcc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -250,7 +250,8 @@ add_subdirectory( plotjuggler_plugins/DataLoadParquet ) add_subdirectory( plotjuggler_plugins/DataLoadULog ) add_subdirectory( plotjuggler_plugins/DataStreamSample ) -add_subdirectory( plotjuggler_plugins/DataStreamWebsocket ) +add_subdirectory( plotjuggler_plugins/DataStreamWebsocketServer ) +add_subdirectory( plotjuggler_plugins/DataStreamWebsocketClient ) add_subdirectory( plotjuggler_plugins/DataStreamUDP ) add_subdirectory( plotjuggler_plugins/DataStreamMQTT ) add_subdirectory( plotjuggler_plugins/DataStreamZMQ ) @@ -319,4 +320,4 @@ if(NOT COMPILING_WITH_AMENT AND NOT COMPILING_WITH_CATKIN) DESTINATION ${PJ_CMAKECONFIG_INSTALL_DIR} ) -endif() +endif() \ No newline at end of file diff --git a/COMPILE.md b/COMPILE.md index 598efae28..b7634cb93 100644 --- a/COMPILE.md +++ b/COMPILE.md @@ -1,47 +1,69 @@ -# Compile in Linux +# Compilation +These instructions are adjusted to fit our usage of PlotJuggler. For the original compilation instructions, see [here](https://github.com/facontidavide/PlotJuggler/blob/main/COMPILE.md). +## Compile on Ubuntu (tested in 18.04) +### Dependencies -On Ubuntu, the dependencies can be installed with the command: +The dependencies can be installed with the command: sudo apt -y install qtbase5-dev libqt5svg5-dev libqt5websockets5-dev \ - libqt5opengl5-dev libqt5x11extras5-dev libprotoc-dev libzmq-dev - -On Fedora: + libqt5opengl5-dev libqt5x11extras5-dev libprotoc-dev libzmq-dev + +Install the latest version (tested till 10.0.1) of Arrow for C++ and Apache Parquet for C++ according to the install instructions [here](https://arrow.apache.org/install/). - sudo dnf install qt5-qtbase-devel qt5-qtsvg-devel qt5-websockets-devel \ - qt5-qtopendl-devel qt5-qtx11extras-devel +### Build the repository -Clone the repository into **~/plotjuggler_ws**: +Clone the repository: ``` -git clone https://github.com/facontidavide/PlotJuggler.git ~/plotjuggler_ws/src/PlotJuggler -cd ~/plotjuggler_ws +git clone https://github.com/mtan1503/PlotJuggler.git +cd PlotJuggler ``` -Then compile using cmake (qmake is NOT supported): +Then compile using cmake and install to your computer: ``` -cmake -S src/PlotJuggler -B build/PlotJuggler -DCMAKE_INSTALL_PREFIX=install -cmake --build build/PlotJuggler --config RelWithDebInfo --parallel --target install +mkdir build && cd build +cmake .. +make -j8 +sudo make install ``` - -## Optional: build with Conan - -If you want to use [conan](https://conan.io/) to manage the dependencies, -follow this instructions instead. +If you run into issues during compilation, check the *Troubleshooting* chapter below. +## Run PlotJuggler +If you installed PlotJuggler, then you can open the app +If you want to run your build, the from your `build/` folder run: +``` +./bin/plotjuggler +``` +## Troubleshooting +### Compilation issues +#### CMake Error: cannot create imported target +If you get an error similar to the error below, this happens because in an older version of PlotJuggler the CMakeLists used `find_package(Arrow CONFIG)` and `find_package(Parquet CONFIG)`. +``` +CMake Error at /usr/lib/x86_64-linux-gnu/cmake/Arrow/FindBrotli.cmake:122 (add_library): + add_library cannot create imported target "Brotli::brotlicommon" because another target with the same name already exists. +Call Stack (most recent call first): + /usr/share/cmake-3.22/Modules/CMakeFindDependencyMacro.cmake:47 (find_package) + /usr/lib/x86_64-linux-gnu/cmake/Arrow/ArrowConfig.cmake:115 (find_dependency) + plotjuggler_plugins/DataLoadParquet/cmake/FindArrow.cmake:424 (find_package) + plotjuggler_plugins/DataLoadParquet/CMakeLists.txt:17 (find_package) +``` +To get rid of this issue, delete the Arrow and Parquet folder in the path that specifies where ArrowConfig.cmake is located within this repository. For example, from the main folder of this repository: ``` -conan install src/PlotJuggler --install-folder build/PlotJuggler \ - --build missing -pr:b=default +cd plotjuggler_plugins/DataLoadParquet/ +rm -r cmake/ +``` +### Run time issues -export CMAKE_TOOLCHAIN=$(pwd)/build/PlotJuggler/conan_toolchain.cmake +#### Problem: PlotJuggler closes when I open a Parquet file +It is likely that your Parquet/Arrow version and the version of this branch do not align. -cmake -S src/PlotJuggler -B build/PlotJuggler \ - -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN \ - -DCMAKE_INSTALL_PREFIX=install \ - -DCMAKE_POLICY_DEFAULT_CMP0091=NEW +Make sure that you have the latest Arrow version installed (10.0.1). +* Check your current Arrow and Parquet version with `dpkg --list | grep arrow` and `dpkg --list | grep parquet`. +* See instructions above for how to instal the newest version. -cmake --build build/PlotJuggler --config RelWithDebInfo --parallel --target install -``` +Make sure that you have built this repo with the latest version of Arrow and Parquet. +* See build instructions above. ## Deploy as an AppImage @@ -61,106 +83,12 @@ mkdir -p AppDir/usr/bin Then: ``` -cd src/PlotJuggler;export VERSION=$(git describe --abbrev=0 --tags);cd - +cd PlotJuggler;export VERSION=$(git describe --abbrev=0 --tags);cd - echo $VERSION cp -v install/bin/* AppDir/usr/bin ./linuxdeploy-x86_64.AppImage --appdir=AppDir \ - -d ./src/PlotJuggler/PlotJuggler.desktop \ - -i ./src/PlotJuggler/plotjuggler.png \ + -d ./PlotJuggler/PlotJuggler.desktop \ + -i ./PlotJuggler/plotjuggler.png \ --plugin qt --output appimage ``` - -# Compile in Mac - -On Mac, the dependencies can be installed using [brew](https://brew.sh/) with the following command: - - brew install qt@5 protobuf mosquitto zeromq zstd - -Clone the repository into **~/plotjuggler_ws**: - -``` -git clone https://github.com/facontidavide/PlotJuggler.git ~/plotjuggler_ws/src/PlotJuggler -cd ~/plotjuggler_ws -``` - -Then compile using cmake: - -``` -cmake -S src/PlotJuggler -B build/PlotJuggler -DCMAKE_INSTALL_PREFIX=install -cmake --build build/PlotJuggler --config RelWithDebInfo --parallel --target install -``` - -# Compile in Windows - -Dependencies in Windows are managed either using -[conan](https://conan.io/) or [vcpkg](https://vcpkg.io/en/index.html) - -The rest of this section assumes that you installed -You need to install first [Qt](https://www.qt.io/download-open-source) and -[git](https://desktop.github.com/). - -**Visual studio 2019 (16)**, that is part of the Qt 5.15.x installation, - will be used to compile PlotJuggler. - -Start creating a folder called **plotjuggler_ws** and cloning the repo: - -``` -cd \ -mkdir plotjuggler_ws -cd plotjuggler_ws -git clone https://github.com/facontidavide/PlotJuggler.git src/PlotJuggler -``` - -## Build with Conan - -Note: the Arrow/Parque plugin is not supported in Conan. Use vcpkg instead, if you need -that specific plugin. - -``` -conan install src/PlotJuggler --install-folder build/PlotJuggler ^ - --build=missing -pr:b=default - -set CMAKE_TOOLCHAIN=%cd%/build/PlotJuggler/conan_toolchain.cmake - -cmake -G "Visual Studio 16" ^ - -S src/PlotJuggler -B build/PlotJuggler ^ - -DCMAKE_TOOLCHAIN_FILE=%CMAKE_TOOLCHAIN% ^ - -DCMAKE_INSTALL_PREFIX=%cd%/install ^ - -DCMAKE_POLICY_DEFAULT_CMP0091=NEW - - -cmake --build build/PlotJuggler --config Release --parallel --target install -``` - -## Build with vcpkg - -Change the path where **vcpkg.cmake** can be found as needed. - -``` -set CMAKE_TOOLCHAIN=/path/vcpkg/scripts/buildsystems/vcpkg.cmake - -cmake -G "Visual Studio 16" ^ - -S src/PlotJuggler -B build/PlotJuggler ^ - -DCMAKE_TOOLCHAIN_FILE=%CMAKE_TOOLCHAIN% ^ - -DCMAKE_INSTALL_PREFIX=%cd%/install - -cmake --build build/PlotJuggler --config Release --parallel --target install -``` - -## Create a Windows installer - -Change the **Qt** and **QtInstallerFramework** version as needed. - -``` -xcopy src\PlotJuggler\installer installer\ /Y /S /f /z -xcopy install\bin\*.* installer\io.plotjuggler.application\data /Y /S /f /z - -C:\Qt\5.15.2\msvc2019_64\bin\windeployqt.exe --release ^ - installer\io.plotjuggler.application\data\plotjuggler.exe - -C:\Qt\Tools\QtInstallerFramework\4.1\bin\binarycreator.exe ^ - --offline-only -c installer\config.xml -p installer ^ - PlotJuggler-Windows-installer.exe - -``` diff --git a/plotjuggler_plugins/DataLoadParquet/CMakeLists.txt b/plotjuggler_plugins/DataLoadParquet/CMakeLists.txt index 00735b298..7665cae79 100644 --- a/plotjuggler_plugins/DataLoadParquet/CMakeLists.txt +++ b/plotjuggler_plugins/DataLoadParquet/CMakeLists.txt @@ -12,16 +12,22 @@ else() message(STATUS "Finding Parquet without package managers") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") - find_package(Arrow CONFIG QUIET) - find_package(Parquet CONFIG QUIET) + find_package(Arrow QUIET) + if(NOT ${Arrow_FOUND}) + message(FATAL_ERROR "Apache Arrow not found.") + endif() + + find_package(Parquet QUIET) + if(NOT ${Parquet_FOUND}) + message(FATAL_ERROR "Parquet not found.") + endif() + endif() -if(Arrow_FOUND) - message(STATUS "[Parquet] found") - include_directories( ../ - ${ARROW_INCLUDE_DIR} - ${PARQUET_INCLUDE_DIR} ) +if(${Arrow_FOUND} AND ${Parquet_FOUND}) + message(STATUS "Arrow version: ${ARROW_VERSION}") + message(STATUS "Parquet version: ${PARQUET_VERSION}") add_definitions(${QT_DEFINITIONS}) add_definitions(-DQT_PLUGIN) @@ -32,17 +38,16 @@ if(Arrow_FOUND) add_library(DataLoadParquet SHARED ${SRC} ${UI_SRC} ) - target_link_libraries(DataLoadParquet + target_link_libraries(DataLoadParquet + Arrow::arrow_shared + Parquet::parquet_shared ${Qt5Widgets_LIBRARIES} ${Qt5Xml_LIBRARIES} - ${PARQUET_LIBRARIES} plotjuggler_base) install(TARGETS DataLoadParquet DESTINATION ${PJ_PLUGIN_INSTALL_DIRECTORY} ) else() - message("[Parquet] not found. Skipping plugin DataLoadParquet.") + message("Arrow/Parquet not found. Skipping plugin DataLoadParquet.") endif() - - diff --git a/plotjuggler_plugins/DataLoadParquet/cmake/FindArrow.cmake b/plotjuggler_plugins/DataLoadParquet/cmake/FindArrow.cmake deleted file mode 100644 index 9d2faaf58..000000000 --- a/plotjuggler_plugins/DataLoadParquet/cmake/FindArrow.cmake +++ /dev/null @@ -1,466 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# - Find Arrow (arrow/api.h, libarrow.a, libarrow.so) -# This module defines -# ARROW_FOUND, whether Arrow has been found -# ARROW_FULL_SO_VERSION, full shared object version of found Arrow "100.0.0" -# ARROW_IMPORT_LIB, path to libarrow's import library (Windows only) -# ARROW_INCLUDE_DIR, directory containing headers -# ARROW_LIBS, deprecated. Use ARROW_LIB_DIR instead -# ARROW_LIB_DIR, directory containing Arrow libraries -# ARROW_SHARED_IMP_LIB, deprecated. Use ARROW_IMPORT_LIB instead -# ARROW_SHARED_LIB, path to libarrow's shared library -# ARROW_SO_VERSION, shared object version of found Arrow such as "100" -# ARROW_STATIC_LIB, path to libarrow.a -# ARROW_VERSION, version of found Arrow -# ARROW_VERSION_MAJOR, major version of found Arrow -# ARROW_VERSION_MINOR, minor version of found Arrow -# ARROW_VERSION_PATCH, patch version of found Arrow - -if(DEFINED ARROW_FOUND) - return() -endif() - -find_package(PkgConfig) -include(FindPackageHandleStandardArgs) - -if(WIN32 AND NOT MINGW) - # This is used to handle builds using e.g. clang in an MSVC setting. - set(MSVC_TOOLCHAIN TRUE) -else() - set(MSVC_TOOLCHAIN FALSE) -endif() - -set(ARROW_SEARCH_LIB_PATH_SUFFIXES) -if(CMAKE_LIBRARY_ARCHITECTURE) - list(APPEND ARROW_SEARCH_LIB_PATH_SUFFIXES "lib/${CMAKE_LIBRARY_ARCHITECTURE}") -endif() -list(APPEND - ARROW_SEARCH_LIB_PATH_SUFFIXES - "lib64" - "lib32" - "lib" - "bin") -set(ARROW_CONFIG_SUFFIXES - "_RELEASE" - "_RELWITHDEBINFO" - "_MINSIZEREL" - "_DEBUG" - "") -if(CMAKE_BUILD_TYPE) - string(TOUPPER ${CMAKE_BUILD_TYPE} ARROW_CONFIG_SUFFIX_PREFERRED) - set(ARROW_CONFIG_SUFFIX_PREFERRED "_${ARROW_CONFIG_SUFFIX_PREFERRED}") - list(INSERT ARROW_CONFIG_SUFFIXES 0 "${ARROW_CONFIG_SUFFIX_PREFERRED}") -endif() - -if(NOT DEFINED ARROW_MSVC_STATIC_LIB_SUFFIX) - if(MSVC_TOOLCHAIN) - set(ARROW_MSVC_STATIC_LIB_SUFFIX "_static") - else() - set(ARROW_MSVC_STATIC_LIB_SUFFIX "") - endif() -endif() - -# Internal function. -# -# Set shared library name for ${base_name} to ${output_variable}. -# -# Example: -# arrow_build_shared_library_name(ARROW_SHARED_LIBRARY_NAME arrow) -# # -> ARROW_SHARED_LIBRARY_NAME=libarrow.so on Linux -# # -> ARROW_SHARED_LIBRARY_NAME=libarrow.dylib on macOS -# # -> ARROW_SHARED_LIBRARY_NAME=arrow.dll with MSVC on Windows -# # -> ARROW_SHARED_LIBRARY_NAME=libarrow.dll with MinGW on Windows -function(arrow_build_shared_library_name output_variable base_name) - set(${output_variable} - "${CMAKE_SHARED_LIBRARY_PREFIX}${base_name}${CMAKE_SHARED_LIBRARY_SUFFIX}" - PARENT_SCOPE) -endfunction() - -# Internal function. -# -# Set import library name for ${base_name} to ${output_variable}. -# This is useful only for MSVC build. Import library is used only -# with MSVC build. -# -# Example: -# arrow_build_import_library_name(ARROW_IMPORT_LIBRARY_NAME arrow) -# # -> ARROW_IMPORT_LIBRARY_NAME=arrow on Linux (meaningless) -# # -> ARROW_IMPORT_LIBRARY_NAME=arrow on macOS (meaningless) -# # -> ARROW_IMPORT_LIBRARY_NAME=arrow.lib with MSVC on Windows -# # -> ARROW_IMPORT_LIBRARY_NAME=libarrow.dll.a with MinGW on Windows -function(arrow_build_import_library_name output_variable base_name) - set(${output_variable} - "${CMAKE_IMPORT_LIBRARY_PREFIX}${base_name}${CMAKE_IMPORT_LIBRARY_SUFFIX}" - PARENT_SCOPE) -endfunction() - -# Internal function. -# -# Set static library name for ${base_name} to ${output_variable}. -# -# Example: -# arrow_build_static_library_name(ARROW_STATIC_LIBRARY_NAME arrow) -# # -> ARROW_STATIC_LIBRARY_NAME=libarrow.a on Linux -# # -> ARROW_STATIC_LIBRARY_NAME=libarrow.a on macOS -# # -> ARROW_STATIC_LIBRARY_NAME=arrow.lib with MSVC on Windows -# # -> ARROW_STATIC_LIBRARY_NAME=libarrow.dll.a with MinGW on Windows -function(arrow_build_static_library_name output_variable base_name) - set(${output_variable} - "${CMAKE_STATIC_LIBRARY_PREFIX}${base_name}${ARROW_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}" - PARENT_SCOPE) -endfunction() - -# Internal function. -# -# Set macro value for ${macro_name} in ${header_content} to ${output_variable}. -# -# Example: -# arrow_extract_macro_value(version_major -# "ARROW_VERSION_MAJOR" -# "#define ARROW_VERSION_MAJOR 1.0.0") -# # -> version_major=1.0.0 -function(arrow_extract_macro_value output_variable macro_name header_content) - string(REGEX MATCH "#define +${macro_name} +[^\r\n]+" macro_definition - "${header_content}") - string(REGEX REPLACE "^#define +${macro_name} +(.+)$" "\\1" macro_value - "${macro_definition}") - set(${output_variable} - "${macro_value}" - PARENT_SCOPE) -endfunction() - -# Internal macro only for arrow_find_package. -# -# Find package in HOME. -macro(arrow_find_package_home) - find_path(${prefix}_include_dir "${header_path}" - PATHS "${home}" - PATH_SUFFIXES "include" - NO_DEFAULT_PATH) - set(include_dir "${${prefix}_include_dir}") - set(${prefix}_INCLUDE_DIR - "${include_dir}" - PARENT_SCOPE) - - if(MSVC_TOOLCHAIN) - set(CMAKE_SHARED_LIBRARY_SUFFIXES_ORIGINAL ${CMAKE_FIND_LIBRARY_SUFFIXES}) - # .dll isn't found by find_library with MSVC because .dll isn't included in - # CMAKE_FIND_LIBRARY_SUFFIXES. - list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX}") - endif() - find_library(${prefix}_shared_lib - NAMES "${shared_lib_name}" - PATHS "${home}" - PATH_SUFFIXES ${ARROW_SEARCH_LIB_PATH_SUFFIXES} - NO_DEFAULT_PATH) - if(MSVC_TOOLCHAIN) - set(CMAKE_SHARED_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_ORIGINAL}) - endif() - set(shared_lib "${${prefix}_shared_lib}") - set(${prefix}_SHARED_LIB - "${shared_lib}" - PARENT_SCOPE) - if(shared_lib) - add_library(${target_shared} SHARED IMPORTED) - set_target_properties(${target_shared} PROPERTIES IMPORTED_LOCATION "${shared_lib}") - if(include_dir) - set_target_properties(${target_shared} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${include_dir}") - endif() - find_library(${prefix}_import_lib - NAMES "${import_lib_name}" - PATHS "${home}" - PATH_SUFFIXES ${ARROW_SEARCH_LIB_PATH_SUFFIXES} - NO_DEFAULT_PATH) - set(import_lib "${${prefix}_import_lib}") - set(${prefix}_IMPORT_LIB - "${import_lib}" - PARENT_SCOPE) - if(import_lib) - set_target_properties(${target_shared} PROPERTIES IMPORTED_IMPLIB "${import_lib}") - endif() - endif() - - find_library(${prefix}_static_lib - NAMES "${static_lib_name}" - PATHS "${home}" - PATH_SUFFIXES ${ARROW_SEARCH_LIB_PATH_SUFFIXES} - NO_DEFAULT_PATH) - set(static_lib "${${prefix}_static_lib}") - set(${prefix}_STATIC_LIB - "${static_lib}" - PARENT_SCOPE) - if(static_lib) - add_library(${target_static} STATIC IMPORTED) - set_target_properties(${target_static} PROPERTIES IMPORTED_LOCATION "${static_lib}") - if(include_dir) - set_target_properties(${target_static} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${include_dir}") - endif() - endif() -endmacro() - -# Internal macro only for arrow_find_package. -# -# Find package by CMake package configuration. -macro(arrow_find_package_cmake_package_configuration) - find_package(${cmake_package_name} CONFIG) - if(${cmake_package_name}_FOUND) - set(${prefix}_USE_CMAKE_PACKAGE_CONFIG - TRUE - PARENT_SCOPE) - if(TARGET ${target_shared}) - foreach(suffix ${ARROW_CONFIG_SUFFIXES}) - get_target_property(shared_lib ${target_shared} IMPORTED_LOCATION${suffix}) - if(shared_lib) - # Remove shared library version: - # libarrow.so.100.0.0 -> libarrow.so - # Because ARROW_HOME and pkg-config approaches don't add - # shared library version. - string(REGEX REPLACE "(${CMAKE_SHARED_LIBRARY_SUFFIX})[.0-9]+$" "\\1" - shared_lib "${shared_lib}") - set(${prefix}_SHARED_LIB - "${shared_lib}" - PARENT_SCOPE) - break() - endif() - endforeach() - endif() - if(TARGET ${target_static}) - foreach(suffix ${ARROW_CONFIG_SUFFIXES}) - get_target_property(static_lib ${target_static} IMPORTED_LOCATION${suffix}) - if(static_lib) - set(${prefix}_STATIC_LIB - "${static_lib}" - PARENT_SCOPE) - break() - endif() - endforeach() - endif() - endif() -endmacro() - -# Internal macro only for arrow_find_package. -# -# Find package by pkg-config. -macro(arrow_find_package_pkg_config) - pkg_check_modules(${prefix}_PC ${pkg_config_name}) - if(${prefix}_PC_FOUND) - set(${prefix}_USE_PKG_CONFIG - TRUE - PARENT_SCOPE) - - set(include_dir "${${prefix}_PC_INCLUDEDIR}") - set(lib_dir "${${prefix}_PC_LIBDIR}") - set(shared_lib_paths "${${prefix}_PC_LINK_LIBRARIES}") - # Use the first shared library path as the IMPORTED_LOCATION - # for ${target_shared}. This assumes that the first shared library - # path is the shared library path for this module. - list(GET shared_lib_paths 0 first_shared_lib_path) - # Use the rest shared library paths as the INTERFACE_LINK_LIBRARIES - # for ${target_shared}. This assumes that the rest shared library - # paths are dependency library paths for this module. - list(LENGTH shared_lib_paths n_shared_lib_paths) - if(n_shared_lib_paths LESS_EQUAL 1) - set(rest_shared_lib_paths) - else() - list(SUBLIST - shared_lib_paths - 1 - -1 - rest_shared_lib_paths) - endif() - - set(${prefix}_VERSION - "${${prefix}_PC_VERSION}" - PARENT_SCOPE) - set(${prefix}_INCLUDE_DIR - "${include_dir}" - PARENT_SCOPE) - set(${prefix}_SHARED_LIB - "${first_shared_lib_path}" - PARENT_SCOPE) - - add_library(${target_shared} SHARED IMPORTED) - set_target_properties(${target_shared} - PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${include_dir}" - INTERFACE_LINK_LIBRARIES "${rest_shared_lib_paths}" - IMPORTED_LOCATION "${first_shared_lib_path}") - get_target_property(shared_lib ${target_shared} IMPORTED_LOCATION) - - find_library(${prefix}_static_lib - NAMES "${static_lib_name}" - PATHS "${lib_dir}" - NO_DEFAULT_PATH) - set(static_lib "${${prefix}_static_lib}") - set(${prefix}_STATIC_LIB - "${static_lib}" - PARENT_SCOPE) - if(static_lib) - add_library(${target_static} STATIC IMPORTED) - set_target_properties(${target_static} - PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${include_dir}" - IMPORTED_LOCATION "${static_lib}") - endif() - endif() -endmacro() - -function(arrow_find_package - prefix - home - base_name - header_path - cmake_package_name - pkg_config_name) - arrow_build_shared_library_name(shared_lib_name ${base_name}) - arrow_build_import_library_name(import_lib_name ${base_name}) - arrow_build_static_library_name(static_lib_name ${base_name}) - - set(target_shared ${base_name}_shared) - set(target_static ${base_name}_static) - - if(home) - arrow_find_package_home() - set(${prefix}_FIND_APPROACH - "HOME: ${home}" - PARENT_SCOPE) - else() - arrow_find_package_cmake_package_configuration() - if(${cmake_package_name}_FOUND) - set(${prefix}_FIND_APPROACH - "CMake package configuration: ${cmake_package_name}" - PARENT_SCOPE) - else() - arrow_find_package_pkg_config() - set(${prefix}_FIND_APPROACH - "pkg-config: ${pkg_config_name}" - PARENT_SCOPE) - endif() - endif() - - if(NOT include_dir) - if(TARGET ${target_shared}) - get_target_property(include_dir ${target_shared} INTERFACE_INCLUDE_DIRECTORIES) - elseif(TARGET ${target_static}) - get_target_property(include_dir ${target_static} INTERFACE_INCLUDE_DIRECTORIES) - endif() - endif() - if(include_dir) - set(${prefix}_INCLUDE_DIR - "${include_dir}" - PARENT_SCOPE) - endif() - - if(shared_lib) - get_filename_component(lib_dir "${shared_lib}" DIRECTORY) - elseif(static_lib) - get_filename_component(lib_dir "${static_lib}" DIRECTORY) - else() - set(lib_dir NOTFOUND) - endif() - set(${prefix}_LIB_DIR - "${lib_dir}" - PARENT_SCOPE) - # For backward compatibility - set(${prefix}_LIBS - "${lib_dir}" - PARENT_SCOPE) -endfunction() - -if(NOT "$ENV{ARROW_HOME}" STREQUAL "") - file(TO_CMAKE_PATH "$ENV{ARROW_HOME}" ARROW_HOME) -endif() -arrow_find_package(ARROW - "${ARROW_HOME}" - arrow - arrow/api.h - Arrow - arrow) - -if(ARROW_HOME) - if(ARROW_INCLUDE_DIR) - file(READ "${ARROW_INCLUDE_DIR}/arrow/util/config.h" ARROW_CONFIG_H_CONTENT) - arrow_extract_macro_value(ARROW_VERSION_MAJOR "ARROW_VERSION_MAJOR" - "${ARROW_CONFIG_H_CONTENT}") - arrow_extract_macro_value(ARROW_VERSION_MINOR "ARROW_VERSION_MINOR" - "${ARROW_CONFIG_H_CONTENT}") - arrow_extract_macro_value(ARROW_VERSION_PATCH "ARROW_VERSION_PATCH" - "${ARROW_CONFIG_H_CONTENT}") - if("${ARROW_VERSION_MAJOR}" STREQUAL "" - OR "${ARROW_VERSION_MINOR}" STREQUAL "" - OR "${ARROW_VERSION_PATCH}" STREQUAL "") - set(ARROW_VERSION "0.0.0") - else() - set(ARROW_VERSION - "${ARROW_VERSION_MAJOR}.${ARROW_VERSION_MINOR}.${ARROW_VERSION_PATCH}") - endif() - - arrow_extract_macro_value(ARROW_SO_VERSION_QUOTED "ARROW_SO_VERSION" - "${ARROW_CONFIG_H_CONTENT}") - string(REGEX REPLACE "^\"(.+)\"$" "\\1" ARROW_SO_VERSION "${ARROW_SO_VERSION_QUOTED}") - arrow_extract_macro_value(ARROW_FULL_SO_VERSION_QUOTED "ARROW_FULL_SO_VERSION" - "${ARROW_CONFIG_H_CONTENT}") - string(REGEX REPLACE "^\"(.+)\"$" "\\1" ARROW_FULL_SO_VERSION - "${ARROW_FULL_SO_VERSION_QUOTED}") - endif() -else() - if(ARROW_USE_CMAKE_PACKAGE_CONFIG) - find_package(Arrow CONFIG) - elseif(ARROW_USE_PKG_CONFIG) - pkg_get_variable(ARROW_SO_VERSION arrow so_version) - pkg_get_variable(ARROW_FULL_SO_VERSION arrow full_so_version) - endif() -endif() - -set(ARROW_ABI_VERSION ${ARROW_SO_VERSION}) - -mark_as_advanced(ARROW_ABI_VERSION - ARROW_CONFIG_SUFFIXES - ARROW_FULL_SO_VERSION - ARROW_IMPORT_LIB - ARROW_INCLUDE_DIR - ARROW_LIBS - ARROW_LIB_DIR - ARROW_SEARCH_LIB_PATH_SUFFIXES - ARROW_SHARED_IMP_LIB - ARROW_SHARED_LIB - ARROW_SO_VERSION - ARROW_STATIC_LIB - ARROW_VERSION - ARROW_VERSION_MAJOR - ARROW_VERSION_MINOR - ARROW_VERSION_PATCH) - -find_package_handle_standard_args( - Arrow - REQUIRED_VARS # The first required variable is shown - # in the found message. So this list is - # not sorted alphabetically. - ARROW_INCLUDE_DIR ARROW_LIB_DIR ARROW_FULL_SO_VERSION ARROW_SO_VERSION - VERSION_VAR ARROW_VERSION) -set(ARROW_FOUND ${Arrow_FOUND}) - -if(Arrow_FOUND AND NOT Arrow_FIND_QUIETLY) - message(STATUS "Arrow version: ${ARROW_VERSION} (${ARROW_FIND_APPROACH})") - message(STATUS "Arrow SO and ABI version: ${ARROW_SO_VERSION}") - message(STATUS "Arrow full SO version: ${ARROW_FULL_SO_VERSION}") - message(STATUS "Found the Arrow core shared library: ${ARROW_SHARED_LIB}") - message(STATUS "Found the Arrow core import library: ${ARROW_IMPORT_LIB}") - message(STATUS "Found the Arrow core static library: ${ARROW_STATIC_LIB}") -endif() diff --git a/plotjuggler_plugins/DataLoadParquet/cmake/FindParquet.cmake b/plotjuggler_plugins/DataLoadParquet/cmake/FindParquet.cmake deleted file mode 100644 index e071fc822..000000000 --- a/plotjuggler_plugins/DataLoadParquet/cmake/FindParquet.cmake +++ /dev/null @@ -1,126 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# - Find Parquet (parquet/api/reader.h, libparquet.a, libparquet.so) -# -# This module requires Arrow from which it uses -# arrow_find_package() -# -# This module defines -# PARQUET_FOUND, whether Parquet has been found -# PARQUET_IMPORT_LIB, path to libparquet's import library (Windows only) -# PARQUET_INCLUDE_DIR, directory containing headers -# PARQUET_LIBS, deprecated. Use PARQUET_LIB_DIR instead -# PARQUET_LIB_DIR, directory containing Parquet libraries -# PARQUET_SHARED_IMP_LIB, deprecated. Use PARQUET_IMPORT_LIB instead -# PARQUET_SHARED_LIB, path to libparquet's shared library -# PARQUET_SO_VERSION, shared object version of found Parquet such as "100" -# PARQUET_STATIC_LIB, path to libparquet.a - -if(DEFINED PARQUET_FOUND) - return() -endif() - -set(find_package_arguments) -if(${CMAKE_FIND_PACKAGE_NAME}_FIND_VERSION) - list(APPEND find_package_arguments "${${CMAKE_FIND_PACKAGE_NAME}_FIND_VERSION}") -endif() -if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED) - list(APPEND find_package_arguments REQUIRED) -endif() -if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) - list(APPEND find_package_arguments QUIET) -endif() -find_package(Arrow ${find_package_arguments}) - -if(NOT "$ENV{PARQUET_HOME}" STREQUAL "") - file(TO_CMAKE_PATH "$ENV{PARQUET_HOME}" PARQUET_HOME) -endif() - -if((NOT PARQUET_HOME) AND ARROW_HOME) - set(PARQUET_HOME ${ARROW_HOME}) -endif() - -if(ARROW_FOUND) - arrow_find_package(PARQUET - "${PARQUET_HOME}" - parquet - parquet/api/reader.h - Parquet - parquet) - if(PARQUET_HOME) - if(PARQUET_INCLUDE_DIR) - file(READ "${PARQUET_INCLUDE_DIR}/parquet/parquet_version.h" - PARQUET_VERSION_H_CONTENT) - arrow_extract_macro_value(PARQUET_VERSION_MAJOR "PARQUET_VERSION_MAJOR" - "${PARQUET_VERSION_H_CONTENT}") - arrow_extract_macro_value(PARQUET_VERSION_MINOR "PARQUET_VERSION_MINOR" - "${PARQUET_VERSION_H_CONTENT}") - arrow_extract_macro_value(PARQUET_VERSION_PATCH "PARQUET_VERSION_PATCH" - "${PARQUET_VERSION_H_CONTENT}") - if("${PARQUET_VERSION_MAJOR}" STREQUAL "" - OR "${PARQUET_VERSION_MINOR}" STREQUAL "" - OR "${PARQUET_VERSION_PATCH}" STREQUAL "") - set(PARQUET_VERSION "0.0.0") - else() - set(PARQUET_VERSION - "${PARQUET_VERSION_MAJOR}.${PARQUET_VERSION_MINOR}.${PARQUET_VERSION_PATCH}") - endif() - - arrow_extract_macro_value(PARQUET_SO_VERSION_QUOTED "PARQUET_SO_VERSION" - "${PARQUET_VERSION_H_CONTENT}") - string(REGEX REPLACE "^\"(.+)\"$" "\\1" PARQUET_SO_VERSION - "${PARQUET_SO_VERSION_QUOTED}") - arrow_extract_macro_value(PARQUET_FULL_SO_VERSION_QUOTED "PARQUET_FULL_SO_VERSION" - "${PARQUET_VERSION_H_CONTENT}") - string(REGEX REPLACE "^\"(.+)\"$" "\\1" PARQUET_FULL_SO_VERSION - "${PARQUET_FULL_SO_VERSION_QUOTED}") - endif() - else() - if(PARQUET_USE_CMAKE_PACKAGE_CONFIG) - find_package(Parquet CONFIG) - elseif(PARQUET_USE_PKG_CONFIG) - pkg_get_variable(PARQUET_SO_VERSION parquet so_version) - pkg_get_variable(PARQUET_FULL_SO_VERSION parquet full_so_version) - endif() - endif() - set(PARQUET_ABI_VERSION "${PARQUET_SO_VERSION}") -endif() - -mark_as_advanced(PARQUET_ABI_VERSION - PARQUET_IMPORT_LIB - PARQUET_INCLUDE_DIR - PARQUET_LIBS - PARQUET_LIB_DIR - PARQUET_SHARED_IMP_LIB - PARQUET_SHARED_LIB - PARQUET_SO_VERSION - PARQUET_STATIC_LIB - PARQUET_VERSION) - -find_package_handle_standard_args( - Parquet - REQUIRED_VARS PARQUET_INCLUDE_DIR PARQUET_LIB_DIR PARQUET_SO_VERSION - VERSION_VAR PARQUET_VERSION) -set(PARQUET_FOUND ${Parquet_FOUND}) - -if(Parquet_FOUND AND NOT Parquet_FIND_QUIETLY) - message(STATUS "Parquet version: ${PARQUET_VERSION} (${PARQUET_FIND_APPROACH})") - message(STATUS "Found the Parquet shared library: ${PARQUET_SHARED_LIB}") - message(STATUS "Found the Parquet import library: ${PARQUET_IMPORT_LIB}") - message(STATUS "Found the Parquet static library: ${PARQUET_STATIC_LIB}") -endif() diff --git a/plotjuggler_plugins/DataLoadParquet/cmake/FindZstd.cmake b/plotjuggler_plugins/DataLoadParquet/cmake/FindZstd.cmake deleted file mode 100644 index eaba39746..000000000 --- a/plotjuggler_plugins/DataLoadParquet/cmake/FindZstd.cmake +++ /dev/null @@ -1,69 +0,0 @@ -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -########################################################################### - -#[=======================================================================[.rst: -FindZstd ----------- - -Find the zstd library - -Result Variables -^^^^^^^^^^^^^^^^ - -``Zstd_FOUND`` - System has zstd -``Zstd_INCLUDE_DIRS`` - The zstd include directories. -``Zstd_LIBRARIES`` - The libraries needed to use zstd -#]=======================================================================] - -if(UNIX) - find_package(PkgConfig QUIET) - pkg_search_module(PC_Zstd libzstd) -endif() - -find_path(Zstd_INCLUDE_DIR zstd.h - HINTS - ${PC_Zstd_INCLUDEDIR} - ${PC_Zstd_INCLUDE_DIRS} -) - -find_library(Zstd_LIBRARY NAMES zstd - HINTS - ${PC_Zstd_LIBDIR} - ${PC_Zstd_LIBRARY_DIRS} -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Zstd - REQUIRED_VARS - Zstd_LIBRARY - Zstd_INCLUDE_DIR -) - -if(Zstd_FOUND) - set(Zstd_LIBRARIES ${Zstd_LIBRARY}) - set(Zstd_INCLUDE_DIRS ${Zstd_INCLUDE_DIR}) -endif() - -mark_as_advanced(Zstd_INCLUDE_DIRS Zstd_LIBRARIES) diff --git a/plotjuggler_plugins/DataStreamWebsocketClient/CMakeLists.txt b/plotjuggler_plugins/DataStreamWebsocketClient/CMakeLists.txt new file mode 100644 index 000000000..f28a6e4de --- /dev/null +++ b/plotjuggler_plugins/DataStreamWebsocketClient/CMakeLists.txt @@ -0,0 +1,30 @@ + + +find_package(Qt5 QUIET COMPONENTS WebSockets) + +if( NOT Qt5WebSockets_FOUND) + message(STATUS "Can't find Qt5WebSockets in your system. Have you tried [sudo apt-get install libqt5websockets5-dev] ?") +else() + + include_directories( ../ ) + + add_definitions(${QT_DEFINITIONS}) + add_definitions(-DQT_PLUGIN) + + QT5_WRAP_UI ( UI_SRC websocket_client.ui ) + + SET( SRC websocket_client.cpp ) + + add_library(DataStreamWebsocketClient SHARED ${SRC} ${UI_SRC} ) + + target_link_libraries(DataStreamWebsocketClient + ${Qt5Widgets_LIBRARIES} + Qt5::WebSockets + plotjuggler_base ) + + install(TARGETS DataStreamWebsocketClient DESTINATION ${PJ_PLUGIN_INSTALL_DIRECTORY} ) + +endif() + + + diff --git a/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.cpp b/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.cpp new file mode 100644 index 000000000..b34acc97b --- /dev/null +++ b/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.cpp @@ -0,0 +1,221 @@ +/*Websocket PlotJuggler Plugin license(Faircode, Davide Faconti) + +Copyright(C) 2018 Philippe Gauthier - ISIR - UPMC +Copyright(C) 2020 Davide Faconti +Copyright(C) 2022 Thijs Gloudemans +Permission is hereby granted to any person obtaining a copy of this software and +associated documentation files(the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and / or sell copies("Use") of the Software, and to permit persons +to whom the Software is furnished to do so. The above copyright notice and this permission +notice shall be included in all copies or substantial portions of the Software. THE +SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#include "websocket_client.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ui_websocket_client.h" + +class WebsocketClientDialog : public QDialog +{ +public: + WebsocketClientDialog() : QDialog(nullptr), ui(new Ui::WebsocketClientDialog) + { + ui->setupUi(this); + setWindowTitle("WebSocket Client"); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + } + ~WebsocketClientDialog() + { + while (ui->layoutOptions->count() > 0) + { + auto item = ui->layoutOptions->takeAt(0); + item->widget()->setParent(nullptr); + } + delete ui; + } + Ui::WebsocketClientDialog* ui; +}; + +WebsocketClient::WebsocketClient(): + _running(false), _socket("plotJuggler", QWebSocketProtocol::VersionUnknown) +{ + connect(&_socket, &QWebSocket::connected, this, &WebsocketClient::onNewConnection); + // connect(&_socket, &QWebSocket::disconnected, this, &WebsocketClient::socketDisconnected); +} + +WebsocketClient::~WebsocketClient() +{ + shutdown(); +} + +bool WebsocketClient::start(QStringList*) +{ + if (_running) + { + return _running; + } + + if (parserFactories() == nullptr || parserFactories()->empty()) + { + QMessageBox::warning(nullptr, tr("Websocket Client"), + tr("No available MessageParsers"), QMessageBox::Ok); + _running = false; + return false; + } + + bool ok = false; + + WebsocketClientDialog* dialog = new WebsocketClientDialog(); + + for (const auto& it : *parserFactories()) + { + dialog->ui->comboBoxProtocol->addItem(it.first); + + if (auto widget = it.second->optionsWidget()) + { + widget->setVisible(false); + dialog->ui->layoutOptions->addWidget(widget); + } + } + + // load previous values + QSettings settings; + QString protocol = settings.value("WebsocketClient::protocol", "JSON").toString(); + QString url = settings.value("WebsocketClient::url", "0.0.0.0:9871").toString(); + + dialog->ui->lineEditUrl->setText(url); + + ParserFactoryPlugin::Ptr parser_creator; + + connect(dialog->ui->comboBoxProtocol, + qOverload(&QComboBox::currentIndexChanged), + this, [&](const QString & selected_protocol) { + if (parser_creator) + { + if( auto prev_widget = parser_creator->optionsWidget()) + { + prev_widget->setVisible(false); + } + } + parser_creator = parserFactories()->at(selected_protocol); + + if (auto widget = parser_creator->optionsWidget()) + { + widget->setVisible(true); + } + }); + + dialog->ui->comboBoxProtocol->setCurrentText(protocol); + + int res = dialog->exec(); + if (res == QDialog::Rejected) + { + _running = false; + return false; + } + + url = dialog->ui->lineEditUrl->text(); + protocol = dialog->ui->comboBoxProtocol->currentText(); + dialog->deleteLater(); + + QString socket_address = cleanQString(url); + _parser = parser_creator->createParser({}, {}, {}, dataMap()); + + // save back to service + settings.setValue("WebsocketClient::protocol", protocol); + settings.setValue("WebsocketClient::url", url); + + _socket.open(QUrl(socket_address)); + + _running = true; + + return _running; +} + +void WebsocketClient::shutdown() +{ + if (_running) + { + socketDisconnected(); + qDebug() << "WebSocket disconnected."; + _socket.close(); + _running = false; + } +} + +void WebsocketClient::onNewConnection() // handle_new_connection +{ + connect(&_socket, &QWebSocket::textMessageReceived, this, + &WebsocketClient::processMessage); + connect(&_socket, &QWebSocket::disconnected, this, &WebsocketClient::socketDisconnected); +} + +void WebsocketClient::processMessage(QString message) +{ + std::lock_guard lock(mutex()); + using namespace std::chrono; + auto ts = high_resolution_clock::now().time_since_epoch(); + double timestamp = 1e-6 * double(duration_cast(ts).count()); + QByteArray bmsg = message.toLocal8Bit(); + MessageRef msg(reinterpret_cast(bmsg.data()), bmsg.size()); + + try + { + _parser->parseMessage(msg, timestamp); + } + catch (std::exception& err) + { + QMessageBox::warning(nullptr, tr("Websocket client"), + tr("Problem parsing the message. Websocket client will be " + "stopped.\n%1") + .arg(err.what()), + QMessageBox::Ok); + shutdown(); + emit closed(); + return; + } + emit dataReceived(); + return; +} + +void WebsocketClient::socketDisconnected() +{ +} + +QString WebsocketClient::cleanQString(QString to_clean) +{ + QString cleaned; + + for(int i = 0; i < to_clean.size(); ++i) + { + QChar qc = to_clean.at(i); + unsigned char c = *(unsigned char*)(&qc); + if(c >= 127) + { + cleaned.append("?"); + } else if (QChar(c).isPrint()) { + cleaned.append(QChar(c)); + } + } + + return cleaned; +} + \ No newline at end of file diff --git a/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.h b/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.h new file mode 100644 index 000000000..b3f681d4f --- /dev/null +++ b/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.h @@ -0,0 +1,72 @@ +/*DataStreamServer PlotJuggler Plugin license(Faircode) + +Copyright(C) 2018 Philippe Gauthier - ISIR - UPMC +Permission is hereby granted to any person obtaining a copy of this software and +associated documentation files(the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and / or sell copies("Use") of the Software, and to permit persons +to whom the Software is furnished to do so. The above copyright notice and this permission +notice shall be included in all copies or substantial portions of the Software. THE +SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#pragma once + +#include +#include +#include + +#include +#include +#include "PlotJuggler/datastreamer_base.h" +#include "PlotJuggler/messageparser_base.h" + +using namespace PJ; + +class WebsocketClient : public PJ::DataStreamer +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "facontidavide.PlotJuggler3.DataStreamer") + Q_INTERFACES(PJ::DataStreamer) + + public: + WebsocketClient(); + + virtual bool start(QStringList*) override; + + virtual void shutdown() override; + + virtual bool isRunning() const override + { + return _running; + } + + virtual ~WebsocketClient() override; + + virtual const char* name() const override + { + return "WebSocket Client"; + } + + virtual bool isDebugPlugin() override + { + return false; + } + + private: + bool _running; + PJ::MessageParserPtr _parser; + QWebSocket _socket; + + + private slots: + void onNewConnection(); + void processMessage(QString message); // handle_new_text_message + void socketDisconnected(); // handle_close_connection + QString cleanQString(QString to_clean); + +}; diff --git a/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.ui b/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.ui new file mode 100644 index 000000000..db129cae4 --- /dev/null +++ b/plotjuggler_plugins/DataStreamWebsocketClient/websocket_client.ui @@ -0,0 +1,106 @@ + + + WebsocketClientDialog + + + + 0 + 0 + 293 + 232 + + + + WebSocket Client + + + + + + + 12 + 75 + true + + + + Websocket url: + + + + + + + + + + + 12 + 75 + true + + + + Message Protocol: + + + + + + + + + + + 0 + + + 6 + + + 0 + + + 6 + + + + + + 75 + true + + + + Protocol options: + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/plotjuggler_plugins/DataStreamWebsocket/CMakeLists.txt b/plotjuggler_plugins/DataStreamWebsocketServer/CMakeLists.txt similarity index 100% rename from plotjuggler_plugins/DataStreamWebsocket/CMakeLists.txt rename to plotjuggler_plugins/DataStreamWebsocketServer/CMakeLists.txt diff --git a/plotjuggler_plugins/DataStreamWebsocket/websocket_client.py b/plotjuggler_plugins/DataStreamWebsocketServer/websocket_client.py similarity index 100% rename from plotjuggler_plugins/DataStreamWebsocket/websocket_client.py rename to plotjuggler_plugins/DataStreamWebsocketServer/websocket_client.py diff --git a/plotjuggler_plugins/DataStreamWebsocket/websocket_server.cpp b/plotjuggler_plugins/DataStreamWebsocketServer/websocket_server.cpp similarity index 100% rename from plotjuggler_plugins/DataStreamWebsocket/websocket_server.cpp rename to plotjuggler_plugins/DataStreamWebsocketServer/websocket_server.cpp diff --git a/plotjuggler_plugins/DataStreamWebsocket/websocket_server.h b/plotjuggler_plugins/DataStreamWebsocketServer/websocket_server.h similarity index 100% rename from plotjuggler_plugins/DataStreamWebsocket/websocket_server.h rename to plotjuggler_plugins/DataStreamWebsocketServer/websocket_server.h diff --git a/plotjuggler_plugins/DataStreamWebsocket/websocket_server.ui b/plotjuggler_plugins/DataStreamWebsocketServer/websocket_server.ui similarity index 100% rename from plotjuggler_plugins/DataStreamWebsocket/websocket_server.ui rename to plotjuggler_plugins/DataStreamWebsocketServer/websocket_server.ui