Compare commits

..
95 Commits
Author SHA1 Message Date
fengzeroz c789ffc8ad Merge pull request #1430 from eeff/v2.5
Pick to 2.5 feat(metrics): reset metric values to zero when node stopped
2023-08-07 16:45:31 +08:00
fengzeroz f93bf7183b Merge pull request #1441 from gc87/persist-v2.5
[v2.5]fix(fx): plugin name
2023-08-03 16:59:44 +08:00
fengzeroz 12eb0e6c74 Merge pull request #1442 from hxy7yx/v2.5-1
fix node count of monitor
2023-08-03 16:58:14 +08:00
hxy7yx e7b62d9218 fix node count of monitor 2023-08-03 16:14:00 +08:00
gc87 a2a608a720 fix(fx): plugin name 2023-08-03 04:18:40 +08:00
fengzeroz 0583a45d1d Merge pull request #1435 from lixiumei123/v2.5
version:2.5.3
2023-08-02 09:46:08 +08:00
liyuxi d4a749c3e9 version:2.5.3 2023-08-01 10:12:04 +00:00
fengzeroz a86064cf8a Merge pull request #1434 from eeff/eeff/fix
Pick to v2.5 to fix: send signal to process group when neuron stopped
2023-08-01 10:32:01 +08:00
eeff 471f8e439e fix: send signal to process group when neuron stopped 2023-08-01 10:21:00 +08:00
fengzeroz 6ab74604d4 Merge pull request #1433 from ZhouBox/v2.5
[v2.5]feat:add cmd about stopping running neuron
2023-08-01 10:15:06 +08:00
xiang.zhou dd1faf19c7 feat:add cmd about stopping running neuron 2023-07-31 16:41:08 +08:00
eeff 84c117cafb feat(metrics): reset metric values to zero when node stopped 2023-07-31 11:05:32 +08:00
fengzeroz 9e091c3fc9 Merge pull request #1425 from hxy7yx/v2.5-1
remove modbus-qh-tcp
2023-07-28 16:59:46 +08:00
fengzeroz c03d85d31d Merge pull request #1428 from fengzeroz/v2.5
fix(driver): memory leak
2023-07-28 16:55:22 +08:00
fengzero 5f1a702bdb fix(driver): memory leak 2023-07-28 08:37:39 +00:00
hxy7yx 382c17c78a remove modbus-qh-tcp 2023-07-28 11:36:34 +08:00
fengzeroz 34247aa1f1 Merge pull request #1423 from hxy7yx/v2.5-1
Log optimization
2023-07-27 14:02:57 +08:00
hxy7yx 4cf7357a22 Log optimization 2023-07-26 17:51:52 +08:00
fengzeroz 29ae8339e9 Merge pull request #1419 from hxy7yx/v2.5-1
add modbus ut
2023-07-25 17:51:19 +08:00
hxy7yx 146bb62e81 add modbus ut 2023-07-25 17:31:00 +08:00
hxy7yx d65773eb90 Merge pull request #1416 from hxy7yx/v2.5-1
reset response_size when retry
2023-07-25 16:45:01 +08:00
hxy7yx 9301489e3e reset response_size when retry 2023-07-25 16:28:12 +08:00
fengzeroz d68668619a Merge pull request #1412 from fengzeroz/v2.5
fix(driver): cannot be uploaded in time when values have not changed
2023-07-25 14:47:30 +08:00
fengzeroz fa3c6a1eb8 Merge pull request #1414 from eeff/v2.5
Pick to v2.5 fix(persist): refresh node and tag count when deleting nodes and groups
2023-07-25 14:46:28 +08:00
eeff f707797208 fix(persist): refresh node and tag count when deleting nodes and groups 2023-07-25 14:20:53 +08:00
lxm 4146bd1510 Merge pull request #1408 from eeff/v2.5
Pick to 2.5 fix: persist node_count and tag_count to signed number
2023-07-24 17:34:15 +08:00
fengzero 7c52356d30 fix(driver): cannot be uploaded in time when values have not changed 2023-07-24 07:39:54 +00:00
eeff e3654f4303 fix: persist node_count and tag_count to signed number 2023-07-21 16:45:17 +08:00
lxm 9c81e79992 Merge pull request #1405 from fengzeroz/v2.5
fix(driver): if the state of the node was stopped before restart, sto…
2023-07-20 17:14:56 +08:00
fengzero 39a1d924e7 fix(driver): if the state of the node was stopped before restart, stop the node 2023-07-20 08:59:44 +00:00
lxm 4b237a67d0 Merge pull request #1399 from fengzeroz/v2.5
feat(driver): update and report immediately
2023-07-20 13:51:35 +08:00
fengzero 2eb00f54fc fix(driver): wrong multiplication cal when writing 2023-07-20 03:27:10 +00:00
fengzero a24f2a8a76 feat(driver): update and report immediately 2023-07-20 03:27:10 +00:00
lxm 384eab840a Merge pull request #1397 from hxy7yx/v2.5-1
optimize modbus
2023-07-20 11:13:27 +08:00
hxy7yx 5003991ad4 optimize modbus 2023-07-19 16:41:04 +08:00
lxm dad58af7e6 Merge pull request #1391 from lixiumei123/v2.5
version:2.5.2
2023-07-13 16:54:13 +08:00
liyuxi cd8727b81e version:2.5.2 2023-07-12 10:28:32 +00:00
eeff a5b2a345c6 Merge pull request #1389 from eeff/v2.5
Pick to v2.5 feat: add persister utilities for getting node/tag count
2023-07-12 15:06:55 +08:00
eeff 46e64f7845 feat: add persister utilities for getting node/tag count 2023-07-11 15:40:22 +08:00
lxm c62ab89ff2 Merge pull request #1386 from lixiumei123/v2.5
fix tags with write-only attribute will send read commands
2023-07-10 16:07:18 +08:00
liyuxi 55171e1eb0 fix tags with write-only attribute will send read commands 2023-07-10 03:42:28 +00:00
fengzeroz d586487077 Merge pull request #1384 from fengzeroz/v2.5
fix cppcheck
2023-07-10 11:37:43 +08:00
fengzero fa8dcb3f98 fix cppcheck 2023-07-10 02:26:37 +00:00
fengzeroz a115fbd303 Merge pull request #1383 from fengzeroz/v2.5
fix(serial): return fd
2023-07-07 17:57:18 +08:00
fengzero 94f164e08c fix(serial): return fd 2023-07-07 09:55:49 +00:00
fengzeroz d2d1d3cd91 Merge pull request #1382 from fengzeroz/v2.5
serial: using smart link
2023-07-07 17:14:36 +08:00
fengzero e88894e34d serial: using smart link 2023-07-07 09:13:37 +00:00
fengzeroz 10a4521a99 Merge pull request #1381 from fengzeroz/v2.5
serial: smart link
2023-07-07 15:37:01 +08:00
fengzero ef06dec1a5 serial: smart link 2023-07-07 07:23:16 +00:00
lxm 45994cc23f Merge pull request #1376 from hxy7yx/v2.5
delete transport_mode in modbus rtu
2023-07-05 18:21:51 +08:00
hxy7yx f360d34688 delete transport_mode in modbus rtu 2023-07-05 18:08:13 +08:00
lxm cae5c3f9c6 Merge pull request #1363 from hxy7yx/v2.5-2
optimization of password error reporting
2023-07-05 15:16:47 +08:00
lxm 68775233d3 Merge pull request #1375 from lixiumei123/v2.5
version:2.5.1
2023-07-03 21:00:15 +08:00
liyuxi 2d4ef2e81a version:2.5.1 2023-07-03 10:16:39 +00:00
lxm b1fc78632d Merge pull request #1371 from hxy7yx/v2.5
delete modbus rtu udp temporarily
2023-07-03 16:06:47 +08:00
lxm e52a3d8dd9 Merge pull request #1372 from lixiumei123/v2.5
delete file plugin
2023-07-03 16:01:30 +08:00
liyuxi 82e216c161 delete file plugin 2023-07-03 07:14:41 +00:00
hxy7yx 2cb2d81254 delete modbus rtu udp temporarily 2023-07-03 14:12:01 +08:00
fengzeroz 203acf54c8 Merge pull request #1360 from hxy7yx/v2.5
exclude license when downloading logs
2023-07-03 13:50:57 +08:00
hxy7yx 413cb7600f Merge branch 'v2.5' into v2.5-2 2023-06-28 13:48:01 +08:00
hxy7yx 8d57bbb252 optimization of password error reporting 2023-06-28 13:44:11 +08:00
eeff 3cecf258a3 Merge pull request #1358 from eeff/v2.5
Pick to fix(ekuiper): check setting host and port is available
2023-06-28 11:08:07 +08:00
hxy7yx eb5de62e46 exclude license when downloading logs 2023-06-28 09:49:21 +08:00
eeff 0fde678e1e fix(ekuiper): check setting host and port is available 2023-06-27 15:23:25 +08:00
fengzero 2b33aa933a improve(connection): donot close fd if tty read returns 0 2023-06-26 07:22:14 +00:00
fengzeroz 9d1c68a420 Merge pull request #1354 from eeff/v2.5
Pick to v2.5 fix(restful): template api handle NEU_ERR_PLUGIN_NAME_TOO_LONG
2023-06-25 16:33:37 +08:00
fengzeroz 5ee5b71dab Merge pull request #1352 from fengzeroz/v2.5
fix(connection): check result of recv
2023-06-25 16:30:49 +08:00
eeff 3de06119d0 fix(restful): template api handle NEU_ERR_PLUGIN_NAME_TOO_LONG 2023-06-25 10:30:30 +08:00
fengzero 7e4119de21 fix(connection): check result of recv 2023-06-21 08:55:47 +00:00
fengzeroz 40df46a0fc Merge pull request #1349 from fengzeroz/v2.5
fix(driver): delay write tag
2023-06-21 15:05:27 +08:00
fengzero eedf2a9819 fix(driver): delay write tag 2023-06-21 06:18:28 +00:00
fengzero 4472c2aeb1 Revert "fix(ekuiper): check ip address listenable"
This reverts commit 3fcbe3f7b7.
2023-06-16 10:47:06 +00:00
fengzeroz 872ac53c3f Merge pull request #1343 from fengzeroz/v2.5
chore(ci): ui version 2.5.0
2023-06-16 15:18:32 +08:00
fengzero a5fea3f2bb chore(ci): ui version 2.5.0 2023-06-16 07:03:11 +00:00
fengzeroz 1e0ed4be64 Merge pull request #1340 from hxy7yx/v2.5
Change the log-level 'info' to 'notice'
2023-06-16 11:05:15 +08:00
fengzeroz 0080cde80b Merge pull request #1337 from fengzeroz/v2.5
fix(connection): connection cannot be recovered when the line is abno…
2023-06-16 10:15:41 +08:00
hxy7yx 5cf6d23d43 Merge branch 'v2.5' into v2.5 2023-06-16 10:12:23 +08:00
hxy7yx caecaf67a6 Change the log-level 'info' to 'notice' 2023-06-16 10:11:44 +08:00
fengzero 8efdc08a32 fix(connection): connection cannot be recovered when the line is abnormal 2023-06-15 10:17:42 +00:00
fengzeroz 6d95a37651 Merge pull request #1335 from eeff/v2.5
Pick to v2.5 feat: remove neuronex sql schema
2023-06-15 15:32:40 +08:00
eeff 5a0a6206cf feat(restful): remove ekuiper http api 2023-06-15 15:30:02 +08:00
eeff 4035de49ca feat: remove neuronex sql schema 2023-06-15 15:13:13 +08:00
eeff e379386249 Merge pull request #1333 from eeff/v2.5
Pick to v2.5 fix(restful): check node name length in node update request
2023-06-15 14:45:40 +08:00
eeff c003332911 fix(restful): check node name length in node update request 2023-06-15 14:29:19 +08:00
eeff 4c38f80618 Merge pull request #1331 from eeff/v2.5
Pick to v2.5 fix: make template request more robust
2023-06-15 14:28:56 +08:00
eeff 2d0e36d596 fix: make template request more robust 2023-06-15 11:07:40 +08:00
eeff b9945c458e fix: neu_url_decode return value on buffer overflow 2023-06-15 11:07:40 +08:00
fengzeroz 614b949354 Merge pull request #1330 from hxy7yx/v2.5
update error codes in ft
2023-06-15 10:30:20 +08:00
fengzeroz 134dffee48 Merge pull request #1325 from eeff/v2.5
fix(ekuiper): check ip address listenable
2023-06-15 09:49:13 +08:00
hxy7yx 820265dfc3 update error codes in ft 2023-06-14 18:02:03 +08:00
eeff 3fcbe3f7b7 fix(ekuiper): check ip address listenable 2023-06-14 17:36:52 +08:00
fengzeroz ee6e962aa6 Merge pull request #1324 from fengzeroz/v2.5
chore(ci): branch v2.5
2023-06-14 13:28:58 +08:00
fengzero a7bf4a85e5 chore(ci): branch v2.5 2023-06-14 05:28:11 +00:00
fengzeroz 10df7590ca Merge pull request #1323 from fengzeroz/v2.5
version: 2.5.0
2023-06-14 13:23:48 +08:00
fengzero c31db4b5db version: 2.5.0 2023-06-14 05:21:06 +00:00
462 changed files with 451437 additions and 36493 deletions
+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
+41 -42
View File
@@ -13,38 +13,37 @@ jobs:
steps:
# checkout
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Run clang-format style check for C/C++ programs.
uses: DoozyX/clang-format-lint-action@v0.18
uses: DoozyX/clang-format-lint-action@v0.12
with:
source: 'src plugins include tests'
exclude: 'include/neuron/utils/uthash.h include/neuron/utils/utarray.h include/neuron/utils/utlist.h include/neuron/utils/zlog.h src/otel/trace.pb-c.h src/otel/trace.pb-c.c src/otel/resource.pb-c.h src/otel/resource.pb-c.c src/otel/common.pb-c.c src/otel/common.pb-c.h'
style: file
exclude: 'include/neuron/utils/uthash.h include/neuron/utils/utarray.h include/neuron/utils/utlist.h include/neuron/utils/zlog.h'
clangFormatVersion: 10
style: file
cppcheck:
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 --suppress=*:src/otel/trace.pb-c.c --suppress=*:src/otel/common.pb-c.c --suppress=*:src/otel/resource.pb-c.c ./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.10
container: neugates/build:x86_64-main
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
submodules: recursive
@@ -58,50 +57,50 @@ jobs:
- name: unit test
run: |
cd build
ctest --output-on-failure
sudo apt-get update
sudo apt install -y lcov
ctest --output-on-failure -O tests/reports/ut.log --output-junit tests/reports/output.xml
lcov --capture --directory . --output-file testneuron.info --test-name testneuron
genhtml -o result testneuron.info
pft:
- uses: actions/upload-artifact@v3
with:
name: ut_result
path: |
build/tests/reports/ut.log
build/tests/reports/output.xml
build/result/index.html
build/neuron.log
ft:
runs-on: ubuntu-20.04
container: ghcr.io/neugates/build:x86_64-v2.10
strategy:
matrix:
plugin: [core, ekuiper, modbus, mqtt, azure, metrics]
container: neugates/build:x86_64-main
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
submodules: recursive
- name: setup dependencies
run: |
sudo apt-get install -y mosquitto
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.10.0
UI_VERSION: 2.6.1
BRANCH: v2.10
VERSION: 2.5.3
UI_VERSION: 2.5.3
BRANCH: v2.5
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.10
container: neugates/build:${{ matrix.arch[1] }}-main
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.10
container: neugates/build:${{ matrix.arch[1] }}-main
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"
+13 -30
View File
@@ -33,15 +33,14 @@ endif()
if(USE_GCOV)
message(STATUS "using gcov")
SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage -O0")
SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
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,17 +65,15 @@ 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)
aux_source_directory(src/otel NEURON_SRC_OTEL)
set(NEURON_BASE_SOURCES
src/base/tag.c
src/base/neu_plugin_common.c
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
@@ -86,10 +83,11 @@ 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)
@@ -98,24 +96,13 @@ if (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} ${NEURON_SRC_OTEL})
target_sources(neuron-base PRIVATE ${NEURON_BASE_SOURCES} ${NEURON_SRC_PARSE})
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 protobuf-c)
${CMAKE_THREAD_LIBS_INIT})
add_dependencies(neuron-base neuron-version)
# dependency imposed by nng
@@ -131,25 +118,25 @@ 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
plugins/restful/ndriver_handle.c
plugins/restful/datatag_handle.c
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/otel_handle.c
plugins/restful/rest.c
plugins/restful/user.c)
@@ -163,7 +150,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)
@@ -175,17 +161,14 @@ 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(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)
-18
View File
@@ -55,21 +55,3 @@ $ tar xzf sqlite3.tar.gz --strip-components=1 -C sqlite3
$ cd sqlite3
$ ./configure CFLAGS=-fPIC && make && sudo make install
```
[protobuf](https://github.com/protocolbuffers/protobuf)
```shell
$ wget --no-check-certificate --content-disposition https://github.com/protocolbuffers/protobuf/releases/download/v3.20.1/protobuf-cpp-3.20.1.tar.gz
$ tar -xzvf protobuf-cpp-3.20.1.tar.gz
$ cd protobuf-3.20.1
$ ./configure --enable-shared=no CFLAGS=-fPIC CXXFLAGS=-fPIC
$ make && make install
```
[protobuf-c](https://github.com/protobuf-c/protobuf-c.git)
```shell
$ git clone -b v1.4.0 https://github.com/protobuf-c/protobuf-c.git
$ cd protobuf-c
$ ./autogen.sh
$ ./configure --disable-protoc --enable-shared=no CFLAGS=-fPIC CXXFLAGS=-fPIC
$ make && make install
```
+3 -5
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)
@@ -20,10 +19,10 @@ The following are some important features of Neuron:
- 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 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#mqtt-sparkplugb-solution) 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 [HTTP API](https://neugates.io/docs/en/latest/http-api/http-api.html) and [MQTT API](https://neugates.io/docs/en/latest/configuration/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.
@@ -43,8 +42,7 @@ Next, please follow the [getting started guide](https://neugates.io/docs/en/late
>
> Neuron open source edition only includes Modbus and MQTT drivers.
>
> If you need more driver protocol support and edge computing services, you can choose Neuron's commercial version [NeuronEX](https://www.emqx.com/en/products/neuronex).
> NeuronEX comes with a built-in license for 30 data tags that can be applied to all southbound drivers. And NeuronEX also supports edge intelligent analysis of industrial data to enable you to quickly gain business insights. To download NeuronEX, please click [here](https://www.emqx.com/en/downloads-and-install/neuronex).
> [Apply for a 15-day trial license](https://www.emqx.com/en/apply-licenses/neuron) to load all drivers.
#### More installation options
+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.10/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.10/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.10/libs)
set(LIBRARY_DIR /home/neuron/libs)
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
-7
View File
@@ -21,10 +21,3 @@ 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.10/libs)
set(LIBRARY_DIR /home/neuron/libs)
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
-8
View File
@@ -1,8 +0,0 @@
ignore:
- "src/otel/*.pb-c.c"
coverage:
status:
project:
default:
target: auto # the required coverage value
threshold: 0.1% # the leniency in hitting the target
-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
+1 -2
View File
@@ -1,9 +1,8 @@
{
"plugins": [
"libplugin-mqtt.so",
"libplugin-aws-iot.so",
"libplugin-azure-iot.so",
"libplugin-ekuiper.so",
"libplugin-monitor.so",
"libplugin-modbus-tcp.so",
"libplugin-modbus-rtu.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, MQTTv50
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
@@ -79,24 +97,28 @@ class Client:
)
self._client = client
self._run(self._client.connect(host, port, version=MQTTv50))
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,10 +173,14 @@ class Client:
`retain` retained flag
"""
self._client.publish(topic, payload, qos=qos,
retain=retain, user_property=[('traceparent', '00-8fb7651916cd43dd8448eb211c80319c-0000000000000000-01'), ('tracestate', 'service.name=ex,a=b,c=d,e=f,g=h')])
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.
@@ -172,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()
@@ -181,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
@@ -190,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()
@@ -222,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
+35
View File
@@ -0,0 +1,35 @@
# Functional test
Functional testing uses the robotframework automated testing framework, providing templates for each test case of the northbound APP and southbound DRIVER types.
Testing is divided into the following categories.
|Test case|Description|
|-----|----------|
|Core interface test|Mainly including the addition, deletion, modification, query, subscription, and other operations of the HTTP API interface for core data(PLUGIN, NODE, GROUP, TAG)|
|Southbound DRIVER test||
|Northbound APP test||
|Plugin specific test case|Such as OPC UA specific device discovery, can different devices be connected normally|
To run all functional testers
Enter the neuron/build directory.
Install Mosquito software.
```shell
$ sudo apt-get install -y mosquitto
```
Start the mosquitto server.
```shell
$ mosquitto -v &
```
Install requirements.
```shell
$ python3 -m pip install -U pip
$ python3 -m pip install -r ft/requirements.txt
```
Run functional tests and generate test reports.
```shell
$ python3 -m robot --maxerroelines=600 -P ft/ -d ft/reports ft
```
@@ -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