Compare commits

..
56 Commits
Author SHA1 Message Date
fengzeroz 97e986e14f Merge pull request #1233 from fengzeroz/v2.4
version: 2.4.4
2023-04-28 13:55:49 +08:00
fengzero 64e265770e version: 2.4.4 2023-04-28 05:54:36 +00:00
fengzeroz e919af04b0 Merge pull request #1227 from eeff/eeff/2.4
fix: global metrics OS info
2023-04-27 10:35:54 +08:00
eeff 5b00c22e70 fix: global metrics OS info 2023-04-26 17:52:24 +08:00
lxm c83b0498d6 Merge pull request #1225 from lixiumei123/v2.4
fix(file plugin):read error
2023-04-26 14:47:30 +08:00
liyuxi b2c1c45c01 fix(file plugin):read error 2023-04-26 06:26:58 +00:00
eeff f1db3782b9 Merge pull request #1222 from eeff/eeff/2.4
Pick to 2.4: static tag value expired error in read_report_group
2023-04-26 14:19:27 +08:00
eeff 5e19ff78ff fix: static tag value expired error in read_report_group 2023-04-26 11:44:08 +08:00
lxm 8fce63ae7b Merge pull request #1218 from lixiumei123/v2.4
refactor:replace plugin name before starting
2023-04-24 14:24:00 +08:00
liyuxi dc16ca62d3 refactor:replace plugin name before starting 2023-04-24 03:39:24 +00:00
fengzeroz 76bbb2cbce Merge pull request #1213 from hxy7yx/v2.4
Revert "Open source Modbus TCP/RTU, delete existing Modbus TCP commun…
2023-04-21 15:50:57 +08:00
hxy7yx 1079af396e Revert "Open source Modbus TCP/RTU, delete existing Modbus TCP community"
This reverts commit faaef6c2e7.
2023-04-21 15:41:09 +08:00
fengzeroz fed03422b3 Merge pull request #1212 from fengzeroz/v2.4
version: 2.4.3
2023-04-21 11:10:53 +08:00
fengzero c8a06bfc30 version: 2.4.3 2023-04-21 03:10:07 +00:00
eeff fc12d7fbff Merge pull request #1210 from eeff/eeff/2.4
Pick to 2.4 feat(mqtt): make offline cache setting more explicit
2023-04-20 18:09:29 +08:00
eeff 92f387ae7b feat(mqtt): make offline cache setting more explicit
1. Add `offline-cache` bool parameter.
  2. Require `cache-mem-size` and `cache-disk-size` only when
     `offline-cache` is enabled. We provide no defaults for
     `cache-mem-size` and `cache-disk-size`, so the user must provide
     values explicitly.
2023-04-20 16:43:45 +08:00
eeff 7cb61f6fa5 Merge pull request #1207 from eeff/eeff/2.4
feat: update global memory metrics
2023-04-20 13:48:19 +08:00
eeff 72eb9c4219 feat: update global memory metrics 2023-04-20 12:05:33 +08:00
hxy7yx faaef6c2e7 Open source Modbus TCP/RTU, delete existing Modbus TCP community 2023-04-20 11:15:06 +08:00
fengzeroz ff22e3413e Merge pull request #1204 from eeff/eeff/2.4
Pick to 2.4: make monitor schema description more clear
2023-04-20 09:55:15 +08:00
eeff 393d85741a chore: make monitor schema description more clear 2023-04-18 16:31:44 +08:00
fengzeroz 680a2839c2 Merge pull request #1201 from eeff/eeff/2.4
fix(restful): global config json parsing on empty array
2023-04-18 10:36:06 +08:00
eeff 5ee46fa972 fix(restful): global config json parsing on empty array 2023-04-18 10:14:19 +08:00
fengzeroz ae94644430 Merge pull request #1196 from fengzeroz/v2.4
version: 2.4.2
2023-04-14 15:39:59 +08:00
fengzero f5c730dcfc version: 2.4.2 2023-04-14 07:38:23 +00:00
eeff 488cccf521 Merge pull request #1185 from eeff/eeff/2.4
Pick to 2.4: data race when close mqtt client
2023-04-12 17:43:19 +08:00
eeff a0d5851719 fix: data race when close mqtt client 2023-04-12 11:10:58 +08:00
eeff c518d6c196 Merge pull request #1181 from eeff/eeff/2.4
Pick to 2.4: sql schema add default setting for data-strream-processing node
2023-04-11 16:22:20 +08:00
eeff c385103c9c feat: sql schema add default setting for data-strream-processing node 2023-04-11 16:03:47 +08:00
eeff f216b3f4e9 Merge pull request #1180 from eeff/eeff/2.4
Pick to 2.4: update mqtt schema
2023-04-11 12:14:56 +08:00
eeff c768f45e9e chore: update mqtt schema 2023-04-10 17:29:45 +08:00
eeff fa55497b55 chore: make mqtt configuration parameter description more clear 2023-04-10 17:29:41 +08:00
fengzeroz 5336d1c250 Merge pull request #1178 from fengzeroz/v2.4
improve(connection): replace old client
2023-04-10 14:08:35 +08:00
fengzero dede8ee8f4 fix(connection): replace client 2023-04-10 03:33:54 +00:00
fengzero 17e2015a9c fix compile warning 2023-04-10 03:26:17 +00:00
fengzero 3361284252 improve(connection): replace old client 2023-04-10 03:12:12 +00:00
fengzeroz 8f6d9d1c41 Merge pull request #1174 from fengzeroz/v2.4
version: 2.4.1
2023-04-07 16:52:38 +08:00
fengzero 3f75222410 version: 2.4.1 2023-04-07 08:52:01 +00:00
fengzeroz ddf5d252f6 Merge pull request #1173 from ZhouBox/feature-build-2.4
[v2.4]feature:use ghcr.io and use corresponding tag
2023-04-07 16:06:42 +08:00
zhouxiang 6e467f5f27 fix:use tag directly 2023-04-07 15:41:36 +08:00
zhouxiang fd1266bc9e [v2.4]feature:use ghcr.io and use corresponding tag 2023-04-07 14:39:44 +08:00
fengzeroz d8b605ef1c Merge pull request #1172 from fengzeroz/v2.4
serial: more baudrate 300/200/150
2023-04-07 14:23:16 +08:00
fengzero c9122b5b7c serial: more baudrate 300/200/150 2023-04-07 06:21:52 +00:00
fengzeroz 8c11cb3466 Merge pull request #1170 from gc87/spb-float-fix-v2.4
[v2.4]fix: determined f32 type data is treated as d64
2023-04-07 11:07:41 +08:00
gc87 80680c55f5 fix: determined f32 type data is treated as d64 2023-04-07 10:51:14 +08:00
fengzero 132c25b4ad serial: more baudrate 1800/1200/600 2023-04-06 08:14:38 +00:00
fengzeroz cc7e5d092a Merge pull request #1162 from lixiumei123/v2.4
fix(log debug):error reporting that the node does not exist
2023-04-06 14:38:56 +08:00
liyuxi 2e3f6d6db2 fix(log debug):error reporting that the node does not exist 2023-04-06 06:20:56 +00:00
fengzeroz 43a95b7910 Merge pull request #1156 from eeff/eeff/2.4
Pick to 2.4: schema use drop drown selection button for QoS setting
2023-04-06 13:01:09 +08:00
fengzeroz 053be086b0 Merge pull request #1158 from lixiumei123/v2.4
fix(file plugin):fix delay
2023-04-06 13:00:26 +08:00
fengzeroz 66dba0f69a Merge pull request #1160 from fengzeroz/v2.4
limit log size
2023-04-06 12:59:12 +08:00
fengzero c6752c5761 limit log size 2023-04-06 04:57:46 +00:00
liyuxi 53f5c496ea fix(file plugin):fix delay 2023-04-06 02:26:46 +00:00
eeff 1e28e4bc0e fix(mqtt): schema use drop drown selection button for QoS setting 2023-04-04 19:03:41 +08:00
fengzeroz 2bbcc6a154 Merge pull request #1154 from fengzeroz/v2.4
ci: branch v2.4
2023-03-31 17:34:16 +08:00
fengzero 00d6418288 ci: branch v2.4 2023-03-31 09:33:43 +00:00
456 changed files with 445702 additions and 32254 deletions
+1
View File
@@ -12,3 +12,4 @@ PointerAlignment: Right
SpaceAfterCStyleCast: true
AllowShortFunctionsOnASingleLine: Inline
BreakBeforeBinaryOperators: None
+28
View File
@@ -0,0 +1,28 @@
name: Check helm version
on:
push:
paths:
- deploy/charts/neuron/templates/**
pull_request:
paths:
- deploy/charts/neuron/templates/**
jobs:
check-helm-version:
runs-on: ubuntu-latest
steps:
- run: minikube start
- uses: actions/checkout@v2
- name: Update helm
run: |
helm repo add emqx https://repos.emqx.io/charts
helm repo update
- name: Check helm version
run: |
old=$(helm show chart emqx/neuron |egrep "^version" | sed -r 's|^version:[[:space:]]([0-9]+.[0-9]+.[0-9]+)$|\1|g')
now=$(egrep "^version" deploy/charts/neuron/Chart.yaml | sed -r 's|^version:[[:space:]]([0-9]+.[0-9]+.[0-9]+)$|\1|g')
if [ "$old" = "$now" ];then
echo "Need update version for Chart.yaml"
exit 1
fi
+30 -41
View File
@@ -7,13 +7,18 @@ on:
types:
- published
env:
BRANCH: v2.4
jobs:
clang_format_check:
runs-on: ubuntu-20.04
steps:
# checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
submodules: recursive
@@ -29,22 +34,21 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
submodules: recursive
- name: cppcheck
run: |
sudo apt install cppcheck
cppcheck --enable=all --error-exitcode=2 --inline-suppr --suppress=missingInclude --suppress=unusedFunction ./plugins ./src
cppcheck --enable=all --error-exitcode=2 --inline-suppr --suppress=missingInclude --suppress=variableScope ./simulator
cppcheck --enable=all --error-exitcode=2 --inline-suppr --suppress=missingInclude --suppress=unusedFunction ./plugins ./simulator ./src
ut:
runs-on: ubuntu-20.04
container: ghcr.io/neugates/build:x86_64-v2.9
container: ghcr.io/neugates/build:x86_64-v2.4
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
submodules: recursive
@@ -52,7 +56,7 @@ jobs:
run: |
git config --global --add safe.directory $(pwd)
mkdir -p build && cd build
cmake -DUSE_GCOV=1 .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
make -j4
- name: unit test
@@ -60,50 +64,35 @@ jobs:
cd build
ctest --output-on-failure
pft:
ft:
runs-on: ubuntu-20.04
container: ghcr.io/neugates/build:x86_64-v2.9
strategy:
matrix:
plugin: [core, ekuiper, modbus, mqtt, azure, metrics]
container: ghcr.io/neugates/build:x86_64-v2.4
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
submodules: recursive
- name: setup dependencies
run: |
if [ "${{ matrix.plugin }}" = "mqtt" ] || [ "${{ matrix.plugin }}" = "azure" ]; then
sudo apt-get install -y mosquitto
fi
pip install -U pytest requests prometheus-client gmqtt pynng sniffio
sudo apt-get install -y socat
- name: compile
run: |
git config --global --add safe.directory $(pwd)
mkdir -p build && cd build
cmake -DUSE_GCOV=1 .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
make -j4
- name: function test
run: |
if [ "${{ matrix.plugin }}" = "core" ]; then
pytest -s -v tests/ft \
--ignore=tests/ft/app/test_ekuiper.py \
--ignore=tests/ft/app/test_mqtt.py \
--ignore=tests/ft/app/test_azure.py \
--ignore=tests/ft/driver/test_modbus.py \
--ignore=tests/ft/metrics/test_metrics.py
elif [ "${{ matrix.plugin }}" = "ekuiper" ]; then
pytest -s -v tests/ft/app/"test_ekuiper.py"
elif [ "${{ matrix.plugin }}" = "modbus" ]; then
pytest -s -v tests/ft/driver/"test_modbus.py"
elif [ "${{ matrix.plugin }}" = "mqtt" ]; then
pytest -s -v tests/ft/app/"test_mqtt.py"
elif [ "${{ matrix.plugin }}" = "azure" ]; then
pytest -s -v tests/ft/app/"test_azure.py"
else
pytest -s -v tests/ft/metrics/"test_metrics.py"
fi
sudo apt-get install -y mosquitto
mosquitto -v &
python3 -m pip install -U pip
python3 -m pip install -r ft/requirements.txt
python3 -m robot --maxerrorlines=600 -P ft/ -d ft/reports ft
- uses: actions/upload-artifact@v3
with:
name: ft_result
path: |
ft/reports/log.html
ft/reports/output.xml
ft/reports/report.html
build/neuron.log
+163 -20
View File
@@ -8,9 +8,9 @@ on:
- published
env:
VERSION: 2.9.0
UI_VERSION: 2.6.1
BRANCH: v2.9
VERSION: 2.4.4
UI_VERSION: 2.4.3
BRANCH: v2.4
jobs:
cross-build:
@@ -21,10 +21,10 @@ jobs:
- [aarch64-linux-gnu, aarch64, arm64]
- [arm-linux-gnueabihf, armv4, armhf]
- [x86_64-linux-gnu, x86_64, amd64]
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.9
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.4
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
submodules: recursive
@@ -54,7 +54,7 @@ jobs:
- uses: actions/upload-artifact@v3
with:
name: neuron-sdk
name: neuron-sdk-${{ matrix.arch[2] }}
path: |
neuron-sdk-*.tar.gz
@@ -64,10 +64,10 @@ jobs:
matrix:
arch:
- [x86_64-linux-gnu, x86_64, amd64]
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.9
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.4
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
submodules: recursive
@@ -85,14 +85,15 @@ jobs:
- uses: actions/upload-artifact@v3
with:
name: neuron-sdk
name: neuron-sdk-debug-${{ matrix.arch[2] }}
path: |
neuron-sdk-debug-*.tar.gz
create_update_daily_release:
runs-on: ubuntu-latest
create_daily_release:
runs-on: ubuntu-20.04
if: github.event_name == 'push'
needs: [cross-build, build-debug-sdk]
steps:
- name: delete old daily-pre-release
uses: dev-drprasad/delete-tag-and-release@v0.2.1
@@ -102,17 +103,159 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v3
with:
name: neuron-sdk
- uses: softprops/action-gh-release@v1
- name: create daily-pre-release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: Daily Release(${{ env.BRANCH }})
tag_name: ${{ env.BRANCH }}-daily
release_name: Daily Release(${{ env.BRANCH }})
draft: false
prerelease: true
files: |
neuron-sdk-*
- shell: bash
run: |
echo "${{ steps.create_release.outputs.upload_url }}" > release_url.txt
- uses: actions/upload-artifact@v3
with:
name: release_url
path: release_url.txt
upload_daily_release_asset:
runs-on: ubuntu-20.04
if: github.event_name == 'push'
needs: create_daily_release
strategy:
matrix:
arch: [arm64, armhf, amd64]
type: [neuron-sdk]
package: [tar.gz]
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/download-artifact@v2
with:
name: release_url
- id: release_url
run: |
value=`cat release_url.txt`
echo "name=$value" >> $GITHUB_OUTPUT
- uses: actions/download-artifact@v2
with:
name: ${{ matrix.type }}-${{ matrix.arch }}
- id: package
run: echo "name=${{ matrix.type }}-${{ env.VERSION }}-${{ matrix.arch }}.${{ matrix.package }}" >> $GITHUB_OUTPUT
- name: upload daily release asset
id: upload-release-asset
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.release_url.outputs.name }}
asset_path: ./${{ steps.package.outputs.name }}
asset_name: ${{ matrix.type }}-${{ env.VERSION }}-daily-linux-${{ matrix.arch }}.${{ matrix.package }}
asset_content_type: application/octet-stream
upload_daily_release_debug_asset:
runs-on: ubuntu-20.04
if: github.event_name == 'push'
needs: create_daily_release
strategy:
matrix:
arch: [amd64]
type: [neuron-sdk-debug]
package: [tar.gz]
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/download-artifact@v2
with:
name: release_url
- id: release_url
run: |
value=`cat release_url.txt`
echo "name=$value" >> $GITHUB_OUTPUT
- uses: actions/download-artifact@v2
with:
name: ${{ matrix.type }}-${{ matrix.arch }}
- id: package
run: echo "name=${{ matrix.type }}-${{ env.VERSION }}-${{ matrix.arch }}.${{ matrix.package }}" >> $GITHUB_OUTPUT
- name: upload daily release asset
id: upload-release-asset
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.release_url.outputs.name }}
asset_path: ./${{ steps.package.outputs.name }}
asset_name: ${{ matrix.type }}-${{ env.VERSION }}-daily-linux-${{ matrix.arch }}.${{ matrix.package }}
asset_content_type: application/octet-stream
clean:
runs-on: ubuntu-20.04
needs: [upload_daily_release_asset, upload_daily_release_debug_asset]
steps:
- uses: geekyeggo/delete-artifact@v1
with:
name: release_url
release:
runs-on: ubuntu-20.04
if: github.event_name == 'release'
needs: cross-build
strategy:
matrix:
arch: [arm64, armhf, amd64]
type: [neuron-sdk]
package: [tar.gz]
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/download-artifact@v2
with:
name: ${{ matrix.type }}-${{ matrix.arch }}
- id: package
run: echo "name=${{ matrix.type }}-${{ env.VERSION }}-${{ matrix.arch }}.${{ matrix.package }}" >> $GITHUB_OUTPUT
- name: gen packages sha256
run: sudo bash -c "echo $(sha256sum ./${{ steps.package.outputs.name }} | awk '{print $1}') > ./${{ steps.package.outputs.name }}.sha256"
- uses: actions/upload-release-asset@v1
if: github.event_name == 'release'
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./${{ steps.package.outputs.name}}.sha256
asset_name: ${{ matrix.type }}-${{ env.VERSION }}-linux-${{ matrix.arch }}.${{ matrix.package }}.sha256
asset_content_type: application/octet-stream
- uses: actions/upload-release-asset@v1
if: github.event_name == 'release'
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./${{ steps.package.outputs.name}}
asset_name: ${{ matrix.type }}-${{ env.VERSION }}-linux-${{ matrix.arch }}.${{ matrix.package }}
asset_content_type: application/octet-stream
+44
View File
@@ -0,0 +1,44 @@
name: Release neuron
on:
push:
tags:
- "*"
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Check appVersion for helm
run: |
appVersion=$(egrep "^appVersion" deploy/charts/neuron/Chart.yaml | sed -r 's|^appVersion:[[:space:]]([0-9]+.[0-9]+.[0-9]+)$|\1|g')
if [ "$appVersion" != "${GITHUB_REF##*/}" ]; then
echo "Need update appVersion for Chart.yaml"
exit 1
fi
helm:
runs-on: self-hosted
if: github.repository_owner == 'emqx'
needs:
- release
steps:
- uses: actions/checkout@v2
- name: Check appVersion for helm
working-directory: deploy/charts/neuron
run: |
appVersion=$(egrep "^appVersion" Chart.yaml | sed -r 's|^appVersion:[[:space:]]([0-9]+.[0-9]+.[0-9]+)$|\1|g')
if [ "$appVersion" != "${GITHUB_REF##*/}" ]; then
echo "Need update appVersion for Chart.yaml"
exit 1
fi
- name: Update helm repo
uses: emqx/push-helm-action@v1
with:
charts_dir: "${{ github.workspace }}/deploy/charts/neuron"
version: ${{ github.ref_name }}
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws_region: "us-west-2"
aws_bucket_name: "repos-emqx-io"
+1 -4
View File
@@ -16,7 +16,4 @@ tmp
*.deb
*.rpm
neuron-sdk
.vscode
log.html
output.xml
report.html
.vscode
+11 -40
View File
@@ -31,17 +31,8 @@ if(NOT DISABLE_WERROR)
set(CMAKE_C_FLAGS "$ENV{CFLAGS} -Werror")
endif()
if(USE_GCOV)
message(STATUS "using gcov")
SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage -O0")
SET(GCC_COVERAGE_LINK_FLAGS "-lgcov")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
endif(USE_GCOV)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -g")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O0")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O1")
if(NOT DISABLE_ASAN)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -fsanitize=address")
@@ -66,7 +57,6 @@ endif()
set(PERSIST_SOURCES
src/persist/persist.c
src/persist/sqlite.c
src/persist/json/persist_json_plugin.c)
aux_source_directory(src/parser NEURON_SRC_PARSE)
set(NEURON_BASE_SOURCES
@@ -75,7 +65,7 @@ set(NEURON_BASE_SOURCES
src/base/tag_sort.c
src/base/group.c
src/base/metrics.c
src/base/msg.c
src/base/template.c
src/connection/connection.c
src/connection/connection_eth.c
src/connection/mqtt_client.c
@@ -85,28 +75,12 @@ set(NEURON_BASE_SOURCES
src/utils/json.c
src/utils/http.c
src/utils/http_handler.c
src/utils/http_proxy.c
src/utils/neu_jwt.c
src/utils/base64.c
src/utils/async_queue.c
src/utils/log.c
src/utils/mem_cache.c
${PERSIST_SOURCES})
if (SMART_LINK)
message(STATUS "using smart link")
add_definitions(-DNEU_SMART_LINK)
set(NEURON_BASE_SOURCES ${NEURON_BASE_SOURCES} src/connection/smart_link.c)
endif()
if (CLIB)
message(STATUS "set clib")
add_definitions(-DNEU_CLIB=${CLIB})
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
message(STATUS "build release")
add_definitions(-DNEU_RELEASE)
endif()
add_library(neuron-base SHARED)
target_sources(neuron-base PRIVATE ${NEURON_BASE_SOURCES} ${NEURON_SRC_PARSE})
@@ -114,7 +88,7 @@ target_include_directories(neuron-base
PRIVATE include/neuron src)
target_link_libraries(neuron-base libssl.a libcrypto.a)
target_link_libraries(neuron-base nng libzlog.so jansson jwt
${CMAKE_THREAD_LIBS_INIT} -lm)
${CMAKE_THREAD_LIBS_INIT})
add_dependencies(neuron-base neuron-version)
# dependency imposed by nng
@@ -130,15 +104,15 @@ set(NEURON_SOURCES
src/core/subscribe.c
src/core/plugin_manager.c
src/core/node_manager.c
src/core/template_manager.c
src/core/storage.c
src/adapter/msg_q.c
src/adapter/storage.c
src/adapter/adapter.c
src/adapter/driver/cache.c
src/adapter/driver/driver.c
plugins/restful/handle.c
plugins/restful/log_handle.c
plugins/restful/metric_handle.c
plugins/restful/file_handle.c
plugins/restful/normal_handle.c
plugins/restful/rw_handle.c
plugins/restful/adapter_handle.c
@@ -146,8 +120,8 @@ set(NEURON_SOURCES
plugins/restful/global_config_handle.c
plugins/restful/group_config_handle.c
plugins/restful/plugin_handle.c
plugins/restful/template_handle.c
plugins/restful/version_handle.c
plugins/restful/scan_handle.c
plugins/restful/rest.c
plugins/restful/user.c)
@@ -161,7 +135,6 @@ target_link_options(neuron PRIVATE "LINKER:--dynamic-list-data")
#copy file for run
file(COPY ${CMAKE_SOURCE_DIR}/zlog.conf DESTINATION ${CMAKE_BINARY_DIR}/config)
file(COPY ${CMAKE_SOURCE_DIR}/dev.conf DESTINATION ${CMAKE_BINARY_DIR}/config)
file(COPY ${CMAKE_SOURCE_DIR}/neuron.json DESTINATION ${CMAKE_BINARY_DIR}/config)
file(COPY ${CMAKE_SOURCE_DIR}/.gitkeep DESTINATION ${CMAKE_BINARY_DIR}/logs)
file(COPY ${CMAKE_SOURCE_DIR}/.gitkeep DESTINATION ${CMAKE_BINARY_DIR}/persistence)
file(COPY ${CMAKE_SOURCE_DIR}/neuron.key DESTINATION ${CMAKE_BINARY_DIR}/config)
@@ -173,17 +146,15 @@ file(COPY ${CMAKE_SOURCE_DIR}/default_plugins.json DESTINATION ${CMAKE_BINARY_DI
add_subdirectory(plugins/modbus)
add_subdirectory(plugins/mqtt)
add_subdirectory(plugins/ekuiper)
add_subdirectory(plugins/monitor)
add_subdirectory(plugins/file)
add_subdirectory(simulator)
if(NOT DISABLE_UT)
add_subdirectory(tests/ut)
add_subdirectory(tests)
endif()
add_subdirectory(tests/plugins/c1)
add_subdirectory(tests/plugins/s1)
add_subdirectory(tests/plugins/sc1)
# Set sane defaults for multi-lib linux systems
include(GNUInstallDirs)
if(UNIX)
+7 -7
View File
@@ -18,17 +18,17 @@ Neuron 是一款开源的、轻量级工业协议网关软件,支持数十种
以下是 Neuron 的一些重要特性:
- 具有实时能力的边缘原生应用程序可以利用边缘端的低延迟网络。
- 松耦合模块化 [架构设计](https://neugates.io/docs/zh/latest/introduction/architecture/architecture.html) 通过可插拔模块扩展更多功能服务。
- 松耦合模块化 [架构设计](https://neugates.io/docs/en/latest/architecture/architecture.html) 通过可插拔模块扩展更多功能服务。
- 支持可以在运行时更新设备和应用程序模块的热插件。
- 支持多种工业设备协议,包括 Modbus、OPCUA、Ethernet/IP、IEC104、BACnet 等 [更多协议](https://neugates.io/docs/zh/latest/configuration/south-devices/south-devices.html)。
- 支持多种工业设备协议,包括 Modbus、OPCUA、Ethernet/IP、IEC104、BACnet 等 [更多协议](https://neugates.io/docs/en/latest/introduction/module-list/module-list.html)。
- 支持同时连接大量不同协议的工业设备。
- 结合[eKuiper](https://www.lfedge.org/projects/ekuiper)提供的规则引擎功能,快速实现基于规则的设备控制或 AI/ML 分析。
- 通过 [SparkplugB](https://neugates.io/docs/zh/latest/use-cases/use_cases.html#mqtt-sparkplugb-%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88) 解决方案支持对工业应用程序的数据访问,例如 MES 或 ERP、SCADA、historian 和数据分析软件。
- 通过 [SparkplugB](https://neugates.io/docs/en/latest/use-cases/use_cases.html) 解决方案支持对工业应用程序的数据访问,例如 MES 或 ERP、SCADA、historian 和数据分析软件。
- 具有非常低的内存占用,小于 10M 的内存占用和 CPU 使用率,可以在 ARM、x86 和 RISC-V 等资源有限的硬件上运行。
- 支持在本地安装可执行文件或部署在容器化环境中。
- 控制工业设备,通过[HTTP API](https://neugates.io/docs/zh/latest/http-api/http-api.html)和[MQTT API](https://neugates.io/docs/en/latest/north-apps/mqtt/api.html) 服务更改参数和数据标签。
- 控制工业设备,通过[API](https://neugates.io/docs/en/latest/http-api/configuration.html)和[MQTT](https://neugates.io/docs/en/latest/north-apps/mqtt/api.html) 服务更改参数和数据标签。
- 与其他 EMQ 产品高度集成,包括 [EMQX](https://www.emqx.com/zh/products/emqx)、[NanoMQ](https://nanomq.io/zh)、[eKuiper](https://ekuiper.org/zh)。
- 核心框架和 Modbus、MQTT 和 eKuiper 的代码在 LGPLv3 的许可下开源。商业模块需要 [EMQ 许可证](https://neugates.io/docs/zh/latest/introduction/license-describe.html) 才能运行。
- 核心框架和 Modbus、MQTT 和 eKuiper 的代码在 LGPLv3 的许可下开源。商业模块需要 [EMQ 许可证](https://neugates.io/docs/en/latest/introduction/license-describe.html) 才能运行。
获取更多信息,请访问 [Neuron 官网](https://neugates.io/zh)。
@@ -40,7 +40,7 @@ Neuron 是一款开源的、轻量级工业协议网关软件,支持数十种
docker run -d --name neuron -p 7000:7000 -p 7001:7001 -p 9081:9081 --privileged=true --restart=always emqx/neuron:latest
```
接下来请参考 [快速入门](https://neugates.io/docs/zh/latest/quick-start/hardware-specifications.html) 开启您的 Neuron 之旅。
接下来请参考 [入门指南](https://neugates.io/docs/en/latest/quick-start/installation.html) 开启您的 Neuron 之旅。
> **提示**
>
@@ -52,7 +52,7 @@ docker run -d --name neuron -p 7000:7000 -p 7001:7001 -p 9081:9081 --privileged=
您可以从 [neugates.io/zh/downloads?os=Linux](https://neugates.io/zh/downloads?os=Linux) 下载不同格式的 Neuron 安装包进行手动安装。
也可以直接访问 [Neuron 安装文档](https://neugates.io/docs/zh/latest/installation/installation.html) 查看不同安装方式的操作步骤。
也可以直接访问 [Neuron 安装文档](https://neugates.io/docs/en/latest/quick-start/installation.html) 查看不同安装方式的操作步骤。
## 文档
+50 -8
View File
@@ -2,7 +2,6 @@
[![GitHub Release](https://img.shields.io/github/release/emqx/neuron?color=brightgreen&label=Release)](https://github.com/emqx/neuron/releases)
[![Docker Pulls](https://img.shields.io/docker/pulls/emqx/neuron?label=Docker%20Pulls)](https://hub.docker.com/r/emqx/neuron)
[![codecov](https://codecov.io/gh/emqx/neuron/graph/badge.svg?token=X95RD0NUT0)](https://codecov.io/gh/emqx/neuron)
[![Slack](https://img.shields.io/badge/Slack-Neuron-39AE85?logo=slack)](https://slack-invite.emqx.io/)
[![Discord](https://img.shields.io/discord/931086341838622751?label=Discord&logo=discord)](https://discord.gg/xYGf3fQnES)
[![Twitter](https://img.shields.io/badge/Follow-EMQ-1DA1F2?logo=twitter)](https://twitter.com/EMQTech)
@@ -15,17 +14,17 @@ Neuron is an Industrial IoT (IIoT) connectivity server for modern big data and A
The following are some important features of Neuron:
- Edge native application with real-time capability to leverage the low latency network of edge side.
- Loosely-coupled modularity [architecture design](https://neugates.io/docs/en/latest/introduction/architecture/architecture.html) for extending more functional services by pluggable modules.
- Loosely-coupled modularity [architecture design](https://neugates.io/docs/en/latest/architecture/architecture.html) for extending more functional services by pluggable modules.
- Support hot plugins that can update device and application modules during runtime.
- Support numerous protocols for industrial devices, including Modbus, OPCUA, Ethernet/IP, IEC104, BACnet and [more](https://neugates.io/docs/en/latest/configuration/south-devices/south-devices.html).
- Support numerous protocols for industrial devices, including Modbus, OPCUA, Ethernet/IP, IEC104, BACnet and [more](https://neugates.io/docs/en/latest/introduction/module-list/module-list.html).
- Support simultaneous connection of a large number of industrial devices with different protocols.
- Combine with the rule engine function provided by [eKuiper](https://www.lfedge.org/projects/ekuiper) to quickly implement rule-based device control or AI/ML analytics.
- Support data access to industrial applications, such as MES or ERP, SCADA, historian and data analytics software via [SparkplugB](https://neugates.io/docs/en/latest/use-cases/sparkplug/sparkplug.html) solution.
- Support data access to industrial applications, such as MES or ERP, SCADA, historian and data analytics software via [SparkplugB](https://neugates.io/docs/en/latest/use-cases/use_cases.html) solution.
- Has very low memory footprint, less than 10M, and CPU usage, can run on limited resource hardware like ARM, x86 and RISC-V.
- Support installation of native executable or deployed in containerized enviornment.
- Control industrial devices, and make changes to the parameters and data tags through [HTTP API](https://neugates.io/docs/en/latest/api/configuration.html) and [MQTT API](https://neugates.io/docs/en/latest/configuration/north-apps/mqtt/api.html) services.
- Control industrial devices, and make changes to the parameters and data tags through [API](https://neugates.io/docs/en/latest/http-api/configuration.html) and [MQTT](https://neugates.io/docs/en/latest/north-apps/mqtt/api.html) services.
- Highly integrated with other EMQ products, including [EMQX](https://www.emqx.com/en/products/emqx), [NanoMQ](https://nanomq.io/), [eKuiper](https://ekuiper.org/).
- The code of the core framework and Modbus, MQTT and eKuiper are licensed under open source LGPLv3. Commercial modules require a [EMQ License](https://neugates.io/docs/en/latest/installation/license-install/license-install.html) to run.
- The code of the core framework and Modbus, MQTT and eKuiper are licensed under open source LGPLv3. Commercial modules require a [EMQ License](https://neugates.io/docs/en/latest/introduction/license-describe.html) to run.
For more information, please visit [Neuron homepage](https://neugates.io/).
@@ -37,7 +36,7 @@ For more information, please visit [Neuron homepage](https://neugates.io/).
docker run -d --name neuron -p 7000:7000 -p 7001:7001 -p 9081:9081 --privileged=true --restart=always emqx/neuron:latest
```
Next, please follow the [getting started guide](https://neugates.io/docs/en/latest/quick-start/hardware-specifications.html) to tour the Neuron features.
Next, please follow the [getting started guide](https://neugates.io/docs/en/latest/quick-start/installation.html) to tour the Neuron features.
> **Limitations**
>
@@ -49,7 +48,7 @@ Next, please follow the [getting started guide](https://neugates.io/docs/en/late
If you prefer to install and manage Neuron yourself, you can download the latest version from [neugates.io/downloads?os=Linux](https://neugates.io/downloads?os=Linux).
For more installation options, see the [Neuron installation documentation](https://neugates.io/docs/en/latest/installation/installation.html).
For more installation options, see the [Neuron installation documentation](https://neugates.io/docs/en/latest/quick-start/installation.html).
## Documentation
@@ -93,6 +92,49 @@ $ ./neuron
>Change the log level in the rules in the zlog.conf file. Available levels include INFO, DEBUG, NOTICE, WARN, ERROR and FATAL.
>
## Test
To run all unit testers
```shell
$ cd build
$ ctest --output-on-failure
```
### Functional test
To run all functional testers
```shell
$ sudo apt-get install -y mosquitto
$ mosquitto -v &
$ python3 -m pip install -U pip
$ python3 -m pip install -r ft/requirements.txt
$ python3 -m robot --maxerroelines=600 -P ft/ -d ft/reports ft
```
### Pressure test
There are datasets for pressure testing in directory `ft/data/persistence/`.
To run pressure tests
```shell
# python dependencies
$ pip3 install -r ft/requirements.txt
# through http api, on dataset total-10k
$ python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-10k -d ft/http-total-10k ft/pressure.test
# through http api, on dataset total-50k
$ python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-50k -d ft/http-total-50k ft/pressure.test
# A MQTT broker is needed if using the mqtt api, mosquitto in this example
$ mosquitto -v &
# through mqtt api, on dataset simple-1k
$ python3 -m robot -P ft/ --variable neuron_api:mqtt --variable dataset:simple-1k -d ft/mqtt-simple-1k ft/pressure.test
```
## License
See [LICENSE](./LICENSE).
+1 -1
View File
@@ -1,7 +1,7 @@
set(CMAKE_SYSTEM_NAME Linux)
set(COMPILER_PREFIX aarch64-linux-gnu)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(LIBRARY_DIR /home/neuron/v2.9/libs)
set(LIBRARY_DIR /home/neuron/libs)
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
+1 -1
View File
@@ -1,7 +1,7 @@
set(CMAKE_SYSTEM_NAME Linux)
set(COMPILER_PREFIX arm-linux-gnueabi)
set(CMAKE_SYSTEM_PROCESSOR armv5tejl)
set(LIBRARY_DIR /home/neuron/v2.9/libs)
set(LIBRARY_DIR /home/neuron/libs)
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
+1 -1
View File
@@ -1,7 +1,7 @@
set(CMAKE_SYSTEM_NAME Linux)
set(COMPILER_PREFIX arm-linux-gnueabihf)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(LIBRARY_DIR /home/neuron/v2.9/libs)
set(LIBRARY_DIR /home/neuron/libs)
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
-11
View File
@@ -17,14 +17,3 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
link_directories(${CMAKE_STAGING_PREFIX})
if(CMAKE_SYSTEM_PROCESSOR MATCHES "mips32")
link_libraries(atomic)
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64")
link_libraries(atomic)
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "loongarch64")
link_libraries(atomic)
endif()
+1 -1
View File
@@ -1,7 +1,7 @@
set(CMAKE_SYSTEM_NAME Linux)
set(COMPILER_PREFIX x86_64-linux-gnu)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(LIBRARY_DIR /home/neuron/v2.9/libs)
set(LIBRARY_DIR /home/neuron/libs)
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
-54
View File
@@ -1,54 +0,0 @@
#!/bin/bash
# core trace
lcov -c -d build/CMakeFiles/neuron-base.dir/src -o cov_report/cov-neuron-base.info
lcov -c -d build/CMakeFiles/neuron.dir/src -o cov_report/cov-neuron.info
lcov -c -d build/CMakeFiles/neuron.dir/plugins/restful -o cov_report/cov-restful.info
# always with core trace
function gen_trace () {
lcov -a cov-neuron-base.info -a cov-neuron.info -a cov-restful.info $@;
}
case $1 in
(ut)
rm -f cov_report/cov-neuron.info cov_report/cov-restful.info
for dir in build/tests/ut/CMakeFiles/*_test.dir; do
test_name=$(basename ${dir} "_test.dir")
lcov -c -d ${dir} -o "cov_report/cov-${test_name}_test.info"
done
cd cov_report
lcov $(for file in cov-*.info; do echo "-a $file "; done) -a cov-neuron-base.info -o cov-ut.info;;
(ft)
lcov -c -d build/plugins/mqtt/CMakeFiles/plugin-mqtt.dir -o cov_report/cov-mqtt.info
lcov -c -d build/plugins/modbus/CMakeFiles/plugin-modbus-rtu.dir -o cov_report/cov-modbus-rtu.info
lcov -c -d build/plugins/modbus/CMakeFiles/plugin-modbus-tcp.dir -o cov_report/cov-modbus-tcp.info
cd cov_report
gen_trace -a cov-mqtt.info -a cov-modbus-rtu.info -a cov-modbus-tcp.info -o cov-ft.info;;
(ekuiper)
lcov -c -d build/plugins/ekuiper/CMakeFiles/plugin-ekuiper.dir -o cov_report/cov-ekuiper.info
cd cov_report
gen_trace -a cov-ekuiper.info -o cov-ekuiper.info;;
(modbus)
lcov -c -d build/plugins/modbus/CMakeFiles/plugin-modbus-rtu.dir -o cov_report/cov-modbus-rtu.info
lcov -c -d build/plugins/modbus/CMakeFiles/plugin-modbus-tcp.dir -o cov_report/cov-modbus-tcp.info
lcov -c -d build/simulator/CMakeFiles/modbus_simulator.dir -o cov_report/cov-simulator-modbus.info
cd cov_report
gen_trace -a cov-simulator-modbus.info -a cov-modbus-rtu.info -a cov-modbus-tcp.info -o cov-modbus.info;;
(mqtt)
lcov -c -d build/plugins/mqtt/CMakeFiles/plugin-mqtt.dir -o cov_report/cov-mqtt.info
cd cov_report
gen_trace -a cov-mqtt.info -o cov-mqtt.info;;
(azure)
lcov -c -d build/plugins/mqtt/CMakeFiles/plugin-azure-iot.dir -o cov_report/cov-azure.info
cd cov_report
gen_trace -a cov-azure.info -o cov-azure.info;;
(core)
cd cov_report
gen_trace -o cov-core.info;;
(metrics)
cd cov_report
gen_trace -o cov-metrics.info;;
(*)
lcov -c -d build/plugins/$1/CMakeFiles/plugin-$1.dir -o cov_report/cov-$1.info;;
esac
+4 -5
View File
@@ -1,10 +1,9 @@
{
"plugins": [
"libplugin-mqtt.so",
"libplugin-aws-iot.so",
"libplugin-azure-iot.so",
"libplugin-ekuiper.so",
"libplugin-modbus-tcp.so",
"libplugin-modbus-rtu.so"
"libplugin-monitor.so",
"libplugin-modbus-tcp-comm.so",
"libplugin-file.so"
]
}
}
+3 -5
View File
@@ -4,12 +4,10 @@ file perms = 666
[formats]
stdout_format = "%d:%ms [%V] [%c] %f:%L %m%n"
file_format = "%d:%ms [%V] %f:%L %m%n"
syslog = "<P>%d(%Y-%m-%dT%T%z) %H neuron[%p]: level=%v msg="[%c] %m" file="%f:%L"%n"
stdout_format = "%d [%V] [%c] %f:%L %m%n"
file_format = "%d [%V] %f:%L %m%n"
[rules]
*.* "./logs/%c.log", 25MB * 1 ~ "./logs/%c.#2r.log"; file_format
*.* "./logs/%c.log", 50MB * 1 ~ "./logs/%c.#2s.log"; file_format
*.* >stdout; stdout_format
*.* $remote_syslog,"%V"; syslog
@@ -2,41 +2,48 @@ import asyncio
import time
from collections import defaultdict, deque
from robot.api import logger
from robot.api.deco import keyword, library
from gmqtt import Client as MQTTClient, Subscription
from gmqtt.mqtt.constants import MQTTv311
def info(msg):
print(msg)
ROBOT_AUTO_KEYWORDS = False
@library
class Client:
"""
"""A keyword library for Robot Framework. It provides keywords for
performing various operations on an MQTT broker. See http://mqtt.org/
for more details on MQTT specification.
This library uses gmqtt: Python async MQTT client. For more information
on underlying methods and documentation, see:
https://github.com/wialon/gmqtt
"""
def __init__(self, reconnect_retries=-1, reconnect_delay=0.1):
ROBOT_LIBRARY_SCOPE = "GLOBAL"
ROBOT_LIBRARY_VERSION = "0.1.0"
def __init__(self, reconnect_retries=5, reconnect_delay=0):
"""
`reconnect_retries` number of reconnect attempt in case of lost
connections, default to -1
connections, default to 5
`reconnect_delay` delay between reconnect attemps in seconds,
default to 0.1
default to 0
"""
self._client = None
self._reconnect_retries = reconnect_retries
self._reconnect_delay = reconnect_delay
self._messages = defaultdict(deque)
self._handlers = {}
self._subcribed = asyncio.Event()
self._unsubcribed = asyncio.Event()
self._recved = asyncio.Event()
self._run = asyncio.get_event_loop().run_until_complete
@keyword
def connect(
self,
host,
@@ -64,6 +71,17 @@ class Client:
`clean_session` specifies the clean session flag for the connection
Examples:
Connect to a broker with default port and client id
| Connect | 127.0.0.1 |
Connect to a broker by specifying the port and client id explicitly
| Connect | 127.0.0.1 | 1883 | test.client |
Connect to a broker with clean session flag set to false
| Connect | 127.0.0.1 | clean_session=${false} |
"""
client = MQTTClient(client_id, clean_session=clean_session)
client.on_connect = self._on_connect
@@ -81,22 +99,26 @@ class Client:
self._run(self._client.connect(host, port, version=MQTTv311))
@keyword
def disconnect(self):
"""Disconnect from MQTT Broker."""
"""Disconnect from MQTT Broker.
Example:
| Disconnect |
"""
self._run(self._client.disconnect())
self._messages.clear()
self._handlers.clear()
@keyword
def unsubscribe_all_and_clear_messages(self):
"""Unsubscribe all subscriptions and clear all messages in queue."""
for topic in self._messages:
self.unsubscribe(topic)
self._messages.clear()
self._handlers.clear()
def subscribe(
self, topic, qos=0, timeout=1, handler=None, no_except=False
):
@keyword
def subscribe(self, topic, qos=0, timeout=1):
"""Subscribe to a topic and return a message payload received
within the specified time.
@@ -106,47 +128,38 @@ class Client:
`timeout` duration of subscription, default to 1 second
`handler` callback on received message, should take one parameter `payload`
Examples:
`no_except` indicate to not throw exception
Subscribe and get a list of all messages received within 5 seconds
| ${messages}= | Subscribe | test/test | qos=1 | timeout=5 |
"""
timeout = 1 if timeout < 1 else timeout
self._client.subscribe(Subscription(topic, qos))
if self._wait(self._subcribed, timeout=timeout):
if no_except:
info(
f"WARN: MQTT client subscribe timeout, topic={topic} qos={qos}"
)
else:
raise Exception(
f"MQTT client subscribe timeout, topic={topic} qos={qos}"
)
info(f"MQTT client subscribed to topic={topic} qos={qos}")
if handler:
self._handlers[topic] = handler
raise Exception(
"MQTT client subscribe timeout topic=%s qos=%s" % (topic, qos))
logger.info("MQTT client subscribed to topic=%s qos=%s" % (topic, qos))
def unsubscribe(self, topic, timeout=1, no_except=False):
@keyword
def unsubscribe(self, topic, timeout=1):
"""Unsubscribe the client from the specified topic.
`topic` topic to unsubscribe from
`timeout` duration of unsubscription, default to 1 second
`no_except` indicate to not throw exception
Example:
| Unsubscribe | test/mqtt_test |
"""
timeout = 1 if timeout < 1 else timeout
self._client.unsubscribe(topic)
if self._wait(self._unsubcribed, timeout=timeout):
if no_except:
info(f"WARN: MQTT client unsubscribe timeout, topic={topic}")
else:
raise Exception(
f"MQTT client unsubscribe timeout, topic={topic}"
)
self._messages[topic].clear()
self._handlers.pop(topic, None)
info(f"MQTT client unsubscribed topic={topic}")
raise Exception("MQTT client unsubscribe timeout topic=%s" % topic)
logger.info("MQTT client unsubscribed topic=%s" % topic)
@keyword
def publish(self, topic, payload, qos=0, retain=False):
"""Publish a message to a topic with specified qos and retained flag.
It is required that a connection has been established using `Connect`
@@ -160,9 +173,14 @@ class Client:
`retain` retained flag
Examples:
| Publish | test/test | test message | 1 | ${false} |
"""
self._client.publish(topic, payload, qos=qos, retain=retain)
@keyword
def listen(self, topic, timeout=1):
"""Listen to a topic and return a message payload received within the
specified time. Requires an Subscribe to have been called previously.
@@ -171,8 +189,14 @@ class Client:
`timeout` duration to listen, default to 1 second
Examples:
Listen and get a message received within 5 seconds
| ${messages}= | Listen | test/test | timeout=5 |
"""
start = time.time_ns()
timeout = 1 if timeout < 1 else timeout
start = time.time()
while True:
if topic in self._messages and self._messages[topic]:
msg = self._messages[topic].popleft()
@@ -180,7 +204,7 @@ class Client:
if (
self._wait(self._recved, timeout=timeout)
or (time.time_ns() - start) >= timeout * 1_000_000_000
or (time.time() - start) >= timeout
):
break
@@ -189,29 +213,23 @@ class Client:
Returns true on timeout, false otherwise."""
try:
self._run(asyncio.wait_for(event.wait(), timeout))
event.clear()
except asyncio.TimeoutError:
return True
finally:
event.clear()
return False
def _on_connect(self, client, flags, rc, properties):
info("MQTT client connected")
logger.info("MQTT client connected")
def _on_message(self, client, topic, payload, qos, properties):
info(
"MQTT client received: topic=%s qos=%s payload=%s"
% (topic, qos, payload)
)
if topic in self._handlers:
self._handlers[topic](payload=payload.decode())
else:
self._messages[topic].append(payload.decode())
logger.info("MQTT client received: topic=%s qos=%s payload=%s" %
(topic, qos, payload))
self._messages[topic].append(payload.decode())
self._recved.set()
return 0
def _on_disconnect(self, client, packet, exc=None):
info("MQTT client disconnected")
logger.info("MQTT client disconnected")
def _on_subscribe(self, client, mid, qos, properties):
self._subcribed.set()
@@ -221,6 +239,9 @@ class Client:
if __name__ == "__main__":
# import logging
# logging.basicConfig(level=logging.DEBUG)
host = "127.0.0.1"
topic = "test/test_mqtt"
client = Client()
+235
View File
@@ -0,0 +1,235 @@
from os import remove
import os
import random
import subprocess
import shutil
import time
def prepare_persistence_dir():
os.system("mkdir -p build/persistence")
class Neuron(object):
process = 0
profiler_process = None
def __init__(self):
pass
def Start_Neuron(self):
prepare_persistence_dir()
self.process = subprocess.Popen(['./neuron', '--log'], cwd='build/')
return self.process
def Stop_Neuron(self, remove_persistence_data=True):
if self.profiler_process is not None:
# wait for plotting
time.sleep(5)
self.process.kill()
if remove_persistence_data:
os.system("rm build/persistence/sqlite.db")
prepare_persistence_dir()
def End_Neuron(self, process):
process.kill()
def Remove_Persistence(self):
os.system("rm build/persistence/sqlite.db")
prepare_persistence_dir()
def Profile_Neuron(self, interval, result_dir):
cmd = [
'psrecord', str(self.process.pid),
'--interval', str(interval),
'--plot', result_dir + '/cpu_mem.svg'
]
self.profiler_process = subprocess.Popen(cmd)
class Tool(object):
def __init__(self):
pass
def Array_Len(self, array):
return len(array)
class Plugin(object):
def __init__(self):
pass
def Get_Plugin_By_Name(self, splugins, name):
for plugin in splugins:
if plugin['name'] == name:
return plugin['id']
return 0
def Plugin_With_Name_Sholud_Exist(self, splugins, name):
assert 0 != self.Get_Plugin_By_Name(splugins, name)
def Plugin_With_Name_Should_Not_Exist(self, splugins, name):
assert 0 == self.Get_Plugin_By_Name(splugins, name)
class GrpConfig(object):
def __init__(self):
pass
def Get_Interval_In_Group_Config(self, gconfigs, gname):
for gconfig in gconfigs[0]:
if gconfig['name'] == gname:
return gconfig['interval']
return 0
def Group_Config_Size(self, gconfigs):
size = 0
for gconfig in gconfigs[0]:
size = size + 1
return size
def Get_Random_Group_Config(self, gconfigs):
return random.choice(gconfigs)['name']
def Group_Config_Check(self, gconfigs, name, interval):
ret = -1
for gconfig in gconfigs:
if gconfig['name'] == name:
if gconfig['interval'] == int(interval):
ret = 0
break
return ret
def Get_Group_Config_By_Name(self, sgconfigs, name):
for gconfig in sgconfigs:
if gconfig['name'] == name:
return gconfig['name']
return 0
class Node(object):
def __init__(self):
pass
def Get_Node_By_Name(self, snodes, name):
for node in snodes:
if node['name'] == name:
return True
return False
def Node_Should_Exist(self, snodes, name):
assert True == self.Get_Node_By_Name(snodes, name)
def Node_Should_Not_Exist(self, snodes, name):
assert False == self.Get_Node_By_Name(snodes, name)
def Node_With_Name_Should_Not_Exist(self, snodes, name):
assert 0 == self.Get_Node_By_Name(snodes, name)
def Get_Random_Node(self, snodes):
return random.choice(snodes)['id']
class Tag(object):
def __init__(self):
pass
def Tag_Check(self, tags, name, type, group_config_name, attribute, address):
ret = -1
for tag in tags:
if tag['name'] == name:
if tag['type'] == int(type) and tag['group_config_name'] == group_config_name and tag['attribute'] == int(attribute) and tag['address'] == address:
ret = 0
break
return ret
def Tag_Find_By_Name(self, tags, name):
for tag in tags:
if tag['name'] == name:
return tag
return None
class Subscribe(object):
def __init__(self):
pass
def Subscribe_Check(self, groups, node_id, group_config_name):
ret = -1
for group in groups:
if group['node_id'] == int(node_id) and group['group_config_name'] == group_config_name:
ret = 0
break
return ret
class Read(object):
def __init__(self):
pass
def Compare_Tag_Value_Bool(self, tags, name, value):
ret = -1
for tag in tags:
if tag['name'] == name:
if isinstance(value, str):
if (tag['value'] == False and value.lower() == "false" or
tag['value'] == True and value.lower() == "true"):
ret = 0
elif tag['value'] == int(value):
ret = 0
break
return ret
def Compare_Tag_Value_Int(self, tags, name, value):
ret = -1
for tag in tags:
if tag['name'] == name:
if int(tag['value']) == int(value):
ret = 0
break
return ret
def Compare_Tag_Value_Float(self, tags, name, value):
ret = -1
for tag in tags:
if tag['name'] == name:
if float(tag['value']) <= float(value) + 0.1 and float(tag['value']) >= float(value) - 0.1:
ret = 0
break
return ret
def Compare_Tag_Value_String(self, tags, name, value):
ret = -1
for tag in tags:
if tag['name'] == name:
if tag['value'] == str(value):
ret = 0
break
return ret
def Compare_Tag_Value_Strings(self, tags, name, value):
ret = -1
for tag in tags:
if tag['name'] == name:
if "\"" + tag['value'] + "\"" == str(value):
ret = 0
break
return ret
def Check_Tag_Error(self, tags, name, value):
ret = -1
for tag in tags:
if tag['name'] == name:
if int(tag['error']) == int(value):
ret = 0
break
return ret
@@ -0,0 +1,10 @@
{
"nodes": [
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0000",
"state": 1
}
]
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0000"
}
@@ -0,0 +1,7 @@
{
"params": {
"host": "127.0.0.1",
"port": 60502,
"connection_mode": 0
}
}
@@ -0,0 +1,11 @@
{
"params": {
"req-topic": "Neuron/req",
"res-topic": "Neuron/resp",
"ssl": "false",
"host": "127.0.0.1",
"port": 1883,
"username": "",
"password": ""
}
}
@@ -0,0 +1,10 @@
{
"subscriptions": [
{
"sub_adapter_name": "mqtt-0000",
"group_config_name": "group-0000",
"src_adapter_name": "modbus-tcp-0000",
"read_interval": 1000
}
]
}
@@ -0,0 +1,3 @@
{
"plugins": []
}
@@ -0,0 +1,10 @@
{
"nodes": [
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0000",
"state": 1
}
]
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0000"
}
@@ -0,0 +1,7 @@
{
"params": {
"host": "127.0.0.1",
"port": 60502,
"connection_mode": 0
}
}
@@ -0,0 +1,11 @@
{
"params": {
"req-topic": "Neuron/req",
"res-topic": "Neuron/resp",
"ssl": "false",
"host": "127.0.0.1",
"port": 1883,
"username": "",
"password": ""
}
}
@@ -0,0 +1,10 @@
{
"subscriptions": [
{
"sub_adapter_name": "mqtt-0000",
"group_config_name": "group-0000",
"src_adapter_name": "modbus-tcp-0000",
"read_interval": 1000
}
]
}
@@ -0,0 +1,3 @@
{
"plugins": []
}
+124
View File
@@ -0,0 +1,124 @@
{
"nodes": [
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0000",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0001",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0002",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0003",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0004",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0005",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0006",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0007",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0008",
"state": 1
},
{
"type": 1,
"plugin_name": "modbus-tcp",
"name": "modbus-tcp-0009",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0000",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0001",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0002",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0003",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0004",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0005",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0006",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0007",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0008",
"state": 1
},
{
"type": 1,
"plugin_name": "neuron-opcua-plugin",
"name": "opcua-0009",
"state": 1
}
]
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0000"
}
@@ -0,0 +1,604 @@
{
"tags": [
{
"type": 4,
"name": "modbus1",
"attribute": 3,
"address": "1!400001"
},
{
"type": 4,
"name": "modbus2",
"attribute": 3,
"address": "1!400002"
},
{
"type": 4,
"name": "modbus3",
"attribute": 3,
"address": "1!400003"
},
{
"type": 4,
"name": "modbus4",
"attribute": 3,
"address": "1!400004"
},
{
"type": 4,
"name": "modbus5",
"attribute": 3,
"address": "1!400005"
},
{
"type": 4,
"name": "modbus6",
"attribute": 3,
"address": "1!400006"
},
{
"type": 4,
"name": "modbus7",
"attribute": 3,
"address": "1!400007"
},
{
"type": 4,
"name": "modbus8",
"attribute": 3,
"address": "1!400008"
},
{
"type": 4,
"name": "modbus9",
"attribute": 3,
"address": "1!400009"
},
{
"type": 4,
"name": "modbus10",
"attribute": 3,
"address": "1!400010"
},
{
"type": 4,
"name": "modbus11",
"attribute": 3,
"address": "1!400011"
},
{
"type": 4,
"name": "modbus12",
"attribute": 3,
"address": "1!400012"
},
{
"type": 4,
"name": "modbus13",
"attribute": 3,
"address": "1!400013"
},
{
"type": 4,
"name": "modbus14",
"attribute": 3,
"address": "1!400014"
},
{
"type": 4,
"name": "modbus15",
"attribute": 3,
"address": "1!400015"
},
{
"type": 4,
"name": "modbus16",
"attribute": 3,
"address": "1!400016"
},
{
"type": 4,
"name": "modbus17",
"attribute": 3,
"address": "1!400017"
},
{
"type": 4,
"name": "modbus18",
"attribute": 3,
"address": "1!400018"
},
{
"type": 4,
"name": "modbus19",
"attribute": 3,
"address": "1!400019"
},
{
"type": 4,
"name": "modbus20",
"attribute": 3,
"address": "1!400020"
},
{
"type": 4,
"name": "modbus21",
"attribute": 3,
"address": "1!400021"
},
{
"type": 4,
"name": "modbus22",
"attribute": 3,
"address": "1!400022"
},
{
"type": 4,
"name": "modbus23",
"attribute": 3,
"address": "1!400023"
},
{
"type": 4,
"name": "modbus24",
"attribute": 3,
"address": "1!400024"
},
{
"type": 4,
"name": "modbus25",
"attribute": 3,
"address": "1!400025"
},
{
"type": 4,
"name": "modbus26",
"attribute": 3,
"address": "1!400026"
},
{
"type": 4,
"name": "modbus27",
"attribute": 3,
"address": "1!400027"
},
{
"type": 4,
"name": "modbus28",
"attribute": 3,
"address": "1!400028"
},
{
"type": 4,
"name": "modbus29",
"attribute": 3,
"address": "1!400029"
},
{
"type": 4,
"name": "modbus30",
"attribute": 3,
"address": "1!400030"
},
{
"type": 4,
"name": "modbus31",
"attribute": 3,
"address": "1!400031"
},
{
"type": 4,
"name": "modbus32",
"attribute": 3,
"address": "1!400032"
},
{
"type": 4,
"name": "modbus33",
"attribute": 3,
"address": "1!400033"
},
{
"type": 4,
"name": "modbus34",
"attribute": 3,
"address": "1!400034"
},
{
"type": 4,
"name": "modbus35",
"attribute": 3,
"address": "1!400035"
},
{
"type": 4,
"name": "modbus36",
"attribute": 3,
"address": "1!400036"
},
{
"type": 4,
"name": "modbus37",
"attribute": 3,
"address": "1!400037"
},
{
"type": 4,
"name": "modbus38",
"attribute": 3,
"address": "1!400038"
},
{
"type": 4,
"name": "modbus39",
"attribute": 3,
"address": "1!400039"
},
{
"type": 4,
"name": "modbus40",
"attribute": 3,
"address": "1!400040"
},
{
"type": 4,
"name": "modbus41",
"attribute": 3,
"address": "1!400041"
},
{
"type": 4,
"name": "modbus42",
"attribute": 3,
"address": "1!400042"
},
{
"type": 4,
"name": "modbus43",
"attribute": 3,
"address": "1!400043"
},
{
"type": 4,
"name": "modbus44",
"attribute": 3,
"address": "1!400044"
},
{
"type": 4,
"name": "modbus45",
"attribute": 3,
"address": "1!400045"
},
{
"type": 4,
"name": "modbus46",
"attribute": 3,
"address": "1!400046"
},
{
"type": 4,
"name": "modbus47",
"attribute": 3,
"address": "1!400047"
},
{
"type": 4,
"name": "modbus48",
"attribute": 3,
"address": "1!400048"
},
{
"type": 4,
"name": "modbus49",
"attribute": 3,
"address": "1!400049"
},
{
"type": 4,
"name": "modbus50",
"attribute": 3,
"address": "1!400050"
},
{
"type": 4,
"name": "modbus51",
"attribute": 3,
"address": "1!400051"
},
{
"type": 4,
"name": "modbus52",
"attribute": 3,
"address": "1!400052"
},
{
"type": 4,
"name": "modbus53",
"attribute": 3,
"address": "1!400053"
},
{
"type": 4,
"name": "modbus54",
"attribute": 3,
"address": "1!400054"
},
{
"type": 4,
"name": "modbus55",
"attribute": 3,
"address": "1!400055"
},
{
"type": 4,
"name": "modbus56",
"attribute": 3,
"address": "1!400056"
},
{
"type": 4,
"name": "modbus57",
"attribute": 3,
"address": "1!400057"
},
{
"type": 4,
"name": "modbus58",
"attribute": 3,
"address": "1!400058"
},
{
"type": 4,
"name": "modbus59",
"attribute": 3,
"address": "1!400059"
},
{
"type": 4,
"name": "modbus60",
"attribute": 3,
"address": "1!400060"
},
{
"type": 4,
"name": "modbus61",
"attribute": 3,
"address": "1!400061"
},
{
"type": 4,
"name": "modbus62",
"attribute": 3,
"address": "1!400062"
},
{
"type": 4,
"name": "modbus63",
"attribute": 3,
"address": "1!400063"
},
{
"type": 4,
"name": "modbus64",
"attribute": 3,
"address": "1!400064"
},
{
"type": 4,
"name": "modbus65",
"attribute": 3,
"address": "1!400065"
},
{
"type": 4,
"name": "modbus66",
"attribute": 3,
"address": "1!400066"
},
{
"type": 4,
"name": "modbus67",
"attribute": 3,
"address": "1!400067"
},
{
"type": 4,
"name": "modbus68",
"attribute": 3,
"address": "1!400068"
},
{
"type": 4,
"name": "modbus69",
"attribute": 3,
"address": "1!400069"
},
{
"type": 4,
"name": "modbus70",
"attribute": 3,
"address": "1!400070"
},
{
"type": 4,
"name": "modbus71",
"attribute": 3,
"address": "1!400071"
},
{
"type": 4,
"name": "modbus72",
"attribute": 3,
"address": "1!400072"
},
{
"type": 4,
"name": "modbus73",
"attribute": 3,
"address": "1!400073"
},
{
"type": 4,
"name": "modbus74",
"attribute": 3,
"address": "1!400074"
},
{
"type": 4,
"name": "modbus75",
"attribute": 3,
"address": "1!400075"
},
{
"type": 4,
"name": "modbus76",
"attribute": 3,
"address": "1!400076"
},
{
"type": 4,
"name": "modbus77",
"attribute": 3,
"address": "1!400077"
},
{
"type": 4,
"name": "modbus78",
"attribute": 3,
"address": "1!400078"
},
{
"type": 4,
"name": "modbus79",
"attribute": 3,
"address": "1!400079"
},
{
"type": 4,
"name": "modbus80",
"attribute": 3,
"address": "1!400080"
},
{
"type": 4,
"name": "modbus81",
"attribute": 3,
"address": "1!400081"
},
{
"type": 4,
"name": "modbus82",
"attribute": 3,
"address": "1!400082"
},
{
"type": 4,
"name": "modbus83",
"attribute": 3,
"address": "1!400083"
},
{
"type": 4,
"name": "modbus84",
"attribute": 3,
"address": "1!400084"
},
{
"type": 4,
"name": "modbus85",
"attribute": 3,
"address": "1!400085"
},
{
"type": 4,
"name": "modbus86",
"attribute": 3,
"address": "1!400086"
},
{
"type": 4,
"name": "modbus87",
"attribute": 3,
"address": "1!400087"
},
{
"type": 4,
"name": "modbus88",
"attribute": 3,
"address": "1!400088"
},
{
"type": 4,
"name": "modbus89",
"attribute": 3,
"address": "1!400089"
},
{
"type": 4,
"name": "modbus90",
"attribute": 3,
"address": "1!400090"
},
{
"type": 4,
"name": "modbus91",
"attribute": 3,
"address": "1!400091"
},
{
"type": 4,
"name": "modbus92",
"attribute": 3,
"address": "1!400092"
},
{
"type": 4,
"name": "modbus93",
"attribute": 3,
"address": "1!400093"
},
{
"type": 4,
"name": "modbus94",
"attribute": 3,
"address": "1!400094"
},
{
"type": 4,
"name": "modbus95",
"attribute": 3,
"address": "1!400095"
},
{
"type": 4,
"name": "modbus96",
"attribute": 3,
"address": "1!400096"
},
{
"type": 4,
"name": "modbus97",
"attribute": 3,
"address": "1!400097"
},
{
"type": 4,
"name": "modbus98",
"attribute": 3,
"address": "1!400098"
},
{
"type": 4,
"name": "modbus99",
"attribute": 3,
"address": "1!400099"
},
{
"type": 4,
"name": "modbus100",
"attribute": 3,
"address": "1!400100"
}
]
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0001",
"adapter_name": "modbus-tcp-0000"
}
@@ -0,0 +1,604 @@
{
"tags": [
{
"type": 4,
"name": "modbus101",
"attribute": 3,
"address": "1!400101"
},
{
"type": 4,
"name": "modbus102",
"attribute": 3,
"address": "1!400102"
},
{
"type": 4,
"name": "modbus103",
"attribute": 3,
"address": "1!400103"
},
{
"type": 4,
"name": "modbus104",
"attribute": 3,
"address": "1!400104"
},
{
"type": 4,
"name": "modbus105",
"attribute": 3,
"address": "1!400105"
},
{
"type": 4,
"name": "modbus106",
"attribute": 3,
"address": "1!400106"
},
{
"type": 4,
"name": "modbus107",
"attribute": 3,
"address": "1!400107"
},
{
"type": 4,
"name": "modbus108",
"attribute": 3,
"address": "1!400108"
},
{
"type": 4,
"name": "modbus109",
"attribute": 3,
"address": "1!400109"
},
{
"type": 4,
"name": "modbus110",
"attribute": 3,
"address": "1!400110"
},
{
"type": 4,
"name": "modbus111",
"attribute": 3,
"address": "1!400111"
},
{
"type": 4,
"name": "modbus112",
"attribute": 3,
"address": "1!400112"
},
{
"type": 4,
"name": "modbus113",
"attribute": 3,
"address": "1!400113"
},
{
"type": 4,
"name": "modbus114",
"attribute": 3,
"address": "1!400114"
},
{
"type": 4,
"name": "modbus115",
"attribute": 3,
"address": "1!400115"
},
{
"type": 4,
"name": "modbus116",
"attribute": 3,
"address": "1!400116"
},
{
"type": 4,
"name": "modbus117",
"attribute": 3,
"address": "1!400117"
},
{
"type": 4,
"name": "modbus118",
"attribute": 3,
"address": "1!400118"
},
{
"type": 4,
"name": "modbus119",
"attribute": 3,
"address": "1!400119"
},
{
"type": 4,
"name": "modbus120",
"attribute": 3,
"address": "1!400120"
},
{
"type": 4,
"name": "modbus121",
"attribute": 3,
"address": "1!400121"
},
{
"type": 4,
"name": "modbus122",
"attribute": 3,
"address": "1!400122"
},
{
"type": 4,
"name": "modbus123",
"attribute": 3,
"address": "1!400123"
},
{
"type": 4,
"name": "modbus124",
"attribute": 3,
"address": "1!400124"
},
{
"type": 4,
"name": "modbus125",
"attribute": 3,
"address": "1!400125"
},
{
"type": 4,
"name": "modbus126",
"attribute": 3,
"address": "1!400126"
},
{
"type": 4,
"name": "modbus127",
"attribute": 3,
"address": "1!400127"
},
{
"type": 4,
"name": "modbus128",
"attribute": 3,
"address": "1!400128"
},
{
"type": 4,
"name": "modbus129",
"attribute": 3,
"address": "1!400129"
},
{
"type": 4,
"name": "modbus130",
"attribute": 3,
"address": "1!400130"
},
{
"type": 4,
"name": "modbus131",
"attribute": 3,
"address": "1!400131"
},
{
"type": 4,
"name": "modbus132",
"attribute": 3,
"address": "1!400132"
},
{
"type": 4,
"name": "modbus133",
"attribute": 3,
"address": "1!400133"
},
{
"type": 4,
"name": "modbus134",
"attribute": 3,
"address": "1!400134"
},
{
"type": 4,
"name": "modbus135",
"attribute": 3,
"address": "1!400135"
},
{
"type": 4,
"name": "modbus136",
"attribute": 3,
"address": "1!400136"
},
{
"type": 4,
"name": "modbus137",
"attribute": 3,
"address": "1!400137"
},
{
"type": 4,
"name": "modbus138",
"attribute": 3,
"address": "1!400138"
},
{
"type": 4,
"name": "modbus139",
"attribute": 3,
"address": "1!400139"
},
{
"type": 4,
"name": "modbus140",
"attribute": 3,
"address": "1!400140"
},
{
"type": 4,
"name": "modbus141",
"attribute": 3,
"address": "1!400141"
},
{
"type": 4,
"name": "modbus142",
"attribute": 3,
"address": "1!400142"
},
{
"type": 4,
"name": "modbus143",
"attribute": 3,
"address": "1!400143"
},
{
"type": 4,
"name": "modbus144",
"attribute": 3,
"address": "1!400144"
},
{
"type": 4,
"name": "modbus145",
"attribute": 3,
"address": "1!400145"
},
{
"type": 4,
"name": "modbus146",
"attribute": 3,
"address": "1!400146"
},
{
"type": 4,
"name": "modbus147",
"attribute": 3,
"address": "1!400147"
},
{
"type": 4,
"name": "modbus148",
"attribute": 3,
"address": "1!400148"
},
{
"type": 4,
"name": "modbus149",
"attribute": 3,
"address": "1!400149"
},
{
"type": 4,
"name": "modbus150",
"attribute": 3,
"address": "1!400150"
},
{
"type": 4,
"name": "modbus151",
"attribute": 3,
"address": "1!400151"
},
{
"type": 4,
"name": "modbus152",
"attribute": 3,
"address": "1!400152"
},
{
"type": 4,
"name": "modbus153",
"attribute": 3,
"address": "1!400153"
},
{
"type": 4,
"name": "modbus154",
"attribute": 3,
"address": "1!400154"
},
{
"type": 4,
"name": "modbus155",
"attribute": 3,
"address": "1!400155"
},
{
"type": 4,
"name": "modbus156",
"attribute": 3,
"address": "1!400156"
},
{
"type": 4,
"name": "modbus157",
"attribute": 3,
"address": "1!400157"
},
{
"type": 4,
"name": "modbus158",
"attribute": 3,
"address": "1!400158"
},
{
"type": 4,
"name": "modbus159",
"attribute": 3,
"address": "1!400159"
},
{
"type": 4,
"name": "modbus160",
"attribute": 3,
"address": "1!400160"
},
{
"type": 4,
"name": "modbus161",
"attribute": 3,
"address": "1!400161"
},
{
"type": 4,
"name": "modbus162",
"attribute": 3,
"address": "1!400162"
},
{
"type": 4,
"name": "modbus163",
"attribute": 3,
"address": "1!400163"
},
{
"type": 4,
"name": "modbus164",
"attribute": 3,
"address": "1!400164"
},
{
"type": 4,
"name": "modbus165",
"attribute": 3,
"address": "1!400165"
},
{
"type": 4,
"name": "modbus166",
"attribute": 3,
"address": "1!400166"
},
{
"type": 4,
"name": "modbus167",
"attribute": 3,
"address": "1!400167"
},
{
"type": 4,
"name": "modbus168",
"attribute": 3,
"address": "1!400168"
},
{
"type": 4,
"name": "modbus169",
"attribute": 3,
"address": "1!400169"
},
{
"type": 4,
"name": "modbus170",
"attribute": 3,
"address": "1!400170"
},
{
"type": 4,
"name": "modbus171",
"attribute": 3,
"address": "1!400171"
},
{
"type": 4,
"name": "modbus172",
"attribute": 3,
"address": "1!400172"
},
{
"type": 4,
"name": "modbus173",
"attribute": 3,
"address": "1!400173"
},
{
"type": 4,
"name": "modbus174",
"attribute": 3,
"address": "1!400174"
},
{
"type": 4,
"name": "modbus175",
"attribute": 3,
"address": "1!400175"
},
{
"type": 4,
"name": "modbus176",
"attribute": 3,
"address": "1!400176"
},
{
"type": 4,
"name": "modbus177",
"attribute": 3,
"address": "1!400177"
},
{
"type": 4,
"name": "modbus178",
"attribute": 3,
"address": "1!400178"
},
{
"type": 4,
"name": "modbus179",
"attribute": 3,
"address": "1!400179"
},
{
"type": 4,
"name": "modbus180",
"attribute": 3,
"address": "1!400180"
},
{
"type": 4,
"name": "modbus181",
"attribute": 3,
"address": "1!400181"
},
{
"type": 4,
"name": "modbus182",
"attribute": 3,
"address": "1!400182"
},
{
"type": 4,
"name": "modbus183",
"attribute": 3,
"address": "1!400183"
},
{
"type": 4,
"name": "modbus184",
"attribute": 3,
"address": "1!400184"
},
{
"type": 4,
"name": "modbus185",
"attribute": 3,
"address": "1!400185"
},
{
"type": 4,
"name": "modbus186",
"attribute": 3,
"address": "1!400186"
},
{
"type": 4,
"name": "modbus187",
"attribute": 3,
"address": "1!400187"
},
{
"type": 4,
"name": "modbus188",
"attribute": 3,
"address": "1!400188"
},
{
"type": 4,
"name": "modbus189",
"attribute": 3,
"address": "1!400189"
},
{
"type": 4,
"name": "modbus190",
"attribute": 3,
"address": "1!400190"
},
{
"type": 4,
"name": "modbus191",
"attribute": 3,
"address": "1!400191"
},
{
"type": 4,
"name": "modbus192",
"attribute": 3,
"address": "1!400192"
},
{
"type": 4,
"name": "modbus193",
"attribute": 3,
"address": "1!400193"
},
{
"type": 4,
"name": "modbus194",
"attribute": 3,
"address": "1!400194"
},
{
"type": 4,
"name": "modbus195",
"attribute": 3,
"address": "1!400195"
},
{
"type": 4,
"name": "modbus196",
"attribute": 3,
"address": "1!400196"
},
{
"type": 4,
"name": "modbus197",
"attribute": 3,
"address": "1!400197"
},
{
"type": 4,
"name": "modbus198",
"attribute": 3,
"address": "1!400198"
},
{
"type": 4,
"name": "modbus199",
"attribute": 3,
"address": "1!400199"
},
{
"type": 4,
"name": "modbus200",
"attribute": 3,
"address": "1!400200"
}
]
}
@@ -0,0 +1,7 @@
{
"params": {
"host":"127.0.0.1",
"port":60502,
"connection_mode":0
}
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0001"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0001",
"adapter_name": "modbus-tcp-0001"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0002",
"adapter_name": "modbus-tcp-0001"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0003",
"adapter_name": "modbus-tcp-0001"
}
@@ -0,0 +1,7 @@
{
"params": {
"host":"127.0.0.1",
"port":60502,
"connection_mode":0
}
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0002"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0001",
"adapter_name": "modbus-tcp-0002"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0002",
"adapter_name": "modbus-tcp-0002"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0003",
"adapter_name": "modbus-tcp-0002"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0004",
"adapter_name": "modbus-tcp-0002"
}
@@ -0,0 +1,7 @@
{
"params": {
"host":"127.0.0.1",
"port":60502,
"connection_mode":0
}
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0003"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0001",
"adapter_name": "modbus-tcp-0003"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0002",
"adapter_name": "modbus-tcp-0003"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0003",
"adapter_name": "modbus-tcp-0003"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0004",
"adapter_name": "modbus-tcp-0003"
}
@@ -0,0 +1,7 @@
{
"params": {
"host":"127.0.0.1",
"port":60502,
"connection_mode":0
}
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0004"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0001",
"adapter_name": "modbus-tcp-0004"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0002",
"adapter_name": "modbus-tcp-0004"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0003",
"adapter_name": "modbus-tcp-0004"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0004",
"adapter_name": "modbus-tcp-0004"
}
@@ -0,0 +1,7 @@
{
"params": {
"host":"127.0.0.1",
"port":60502,
"connection_mode":0
}
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0005"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0001",
"adapter_name": "modbus-tcp-0005"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0002",
"adapter_name": "modbus-tcp-0005"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0003",
"adapter_name": "modbus-tcp-0005"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0004",
"adapter_name": "modbus-tcp-0005"
}
@@ -0,0 +1,7 @@
{
"params": {
"host":"127.0.0.1",
"port":60502,
"connection_mode":0
}
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0000",
"adapter_name": "modbus-tcp-0006"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0001",
"adapter_name": "modbus-tcp-0006"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0002",
"adapter_name": "modbus-tcp-0006"
}
@@ -0,0 +1,5 @@
{
"read_interval": 1000,
"group_config_name": "group-0003",
"adapter_name": "modbus-tcp-0006"
}

Some files were not shown because too many files have changed in this diff Show More