mirror of
https://github.com/emqx/neuron.git
synced 2026-10-29 23:19:18 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba8d56fdd0 | ||
|
|
8795028313 | ||
|
|
05d83878db | ||
|
|
d031a0ee71 | ||
|
|
969a302b58 | ||
|
|
57d5a51aad | ||
|
|
c46795ce30 | ||
|
|
ef9e505517 | ||
|
|
24d3ce2667 | ||
|
|
3c71082121 | ||
|
|
0d1c2b93c0 | ||
|
|
0ae76e1c5f | ||
|
|
5f41286600 | ||
|
|
9c48d6bcaa | ||
|
|
83eb1ecf61 | ||
|
|
4059c22de1 | ||
|
|
179dc71408 | ||
|
|
43fc2a7080 | ||
|
|
a95ecfe7c5 | ||
|
|
07b9d077b1 | ||
|
|
6119023896 | ||
|
|
b3b9e69b7a | ||
|
|
05aa6ea141 | ||
|
|
74415465ff | ||
|
|
658779c28f | ||
|
|
edee7007b3 | ||
|
|
012c7b756c | ||
|
|
3b0bdefd1a | ||
|
|
380bae660c | ||
|
|
32e49e0386 | ||
|
|
24111cacac | ||
|
|
978e0d3d8f | ||
|
|
549fe9ed7c | ||
|
|
4e4491eda2 | ||
|
|
a9f4089979 | ||
|
|
02d14ea096 | ||
|
|
33dbdd9eca | ||
|
|
52dfb55007 | ||
|
|
9b4dfef460 | ||
|
|
31316c9363 | ||
|
|
58ca53f07d | ||
|
|
f65d734285 | ||
|
|
bdaba2c339 | ||
|
|
1c3cb0f9a3 | ||
|
|
d6a040515e | ||
|
|
fd22dc29d2 | ||
|
|
865a9fc364 | ||
|
|
86f17aaf90 |
@@ -12,3 +12,4 @@ PointerAlignment: Right
|
||||
SpaceAfterCStyleCast: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
BreakBeforeBinaryOperators: None
|
||||
|
||||
|
||||
@@ -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
-117
@@ -9,165 +9,89 @@ on:
|
||||
|
||||
jobs:
|
||||
clang_format_check:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
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 plugins/mqtt/ptformat.pb-c.h plugins/mqtt/ptformat.pb-c.c'
|
||||
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-24.04
|
||||
container: ghcr.io/neugates/build:x86_64-v2.12
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: cppcheck
|
||||
run: |
|
||||
sudo apt install -y 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
|
||||
sudo apt install cppcheck
|
||||
cppcheck --enable=all --error-exitcode=2 --suppress=missingInclude --suppress=unusedFunction ./plugins ./simulator ./src
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-24.04
|
||||
container: ghcr.io/neugates/build:x86_64-v2.12
|
||||
ut:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: install dep
|
||||
run: |
|
||||
./install.sh -d /usr/local -a x86_64 -c x86_64-linux-gnu
|
||||
|
||||
- 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
|
||||
make -j4
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: neuron-build
|
||||
path: |
|
||||
build
|
||||
|
||||
|
||||
ut:
|
||||
runs-on: ubuntu-24.04
|
||||
container: ghcr.io/neugates/build:x86_64-v2.12
|
||||
needs: [build]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: neuron-build
|
||||
path: ./build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
|
||||
make -j4
|
||||
|
||||
- name: unit test
|
||||
run: |
|
||||
chmod -R +x ./build/
|
||||
cd build
|
||||
cmake -DUSE_GCOV=1 .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: create cov report
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install lcov
|
||||
mkdir -p cov_report
|
||||
./create_cov_report.sh ut
|
||||
ft:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
verbose: true
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
directory: ./cov_report/
|
||||
files: ./cov_report/cov-ut.info
|
||||
|
||||
pft:
|
||||
runs-on: ubuntu-24.04
|
||||
container: ghcr.io/neugates/build:x86_64-v2.12
|
||||
needs: [build]
|
||||
strategy:
|
||||
matrix:
|
||||
plugin: [core, ekuiper, modbus, mqtt, azure, metrics, launch]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: setup dependencies
|
||||
|
||||
- name: install dep
|
||||
run: |
|
||||
sudo apt-get install -y mosquitto
|
||||
pip install -U pytest requests prometheus-client gmqtt pynng sniffio
|
||||
sudo apt-get install -y socat
|
||||
./install.sh -d /usr/local -a x86_64 -c x86_64-linux-gnu
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: neuron-build
|
||||
path: ./build
|
||||
- name: compile
|
||||
run: |
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
|
||||
make -j4
|
||||
|
||||
- name: function test
|
||||
run: |
|
||||
chmod -R +x ./build/
|
||||
cd build
|
||||
cmake -DUSE_GCOV=1 .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-linux-gnu.cmake
|
||||
cd ..
|
||||
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 \
|
||||
--ignore=tests/ft/login/test_launch.py \
|
||||
--ignore=tests/ft/login/test_filter_error.py \
|
||||
--ignore=tests/ft/login/test_login.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"
|
||||
#elif [ "${{ matrix.plugin }}" = "launch" ]; then
|
||||
#pytest -s -v tests/ft/login
|
||||
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
|
||||
|
||||
- name: create cov report
|
||||
if: ${{ matrix.plugin != 'launch' }}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install lcov
|
||||
mkdir -p cov_report
|
||||
./create_cov_report.sh ${{ matrix.plugin }}
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
if: ${{ matrix.plugin != 'launch' }}
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
verbose: true
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
directory: ./cov_report/
|
||||
files: ./cov_report/cov-${{ matrix.plugin }}.info
|
||||
name: ft_result
|
||||
path: |
|
||||
ft/reports/log.html
|
||||
ft/reports/output.xml
|
||||
ft/reports/report.html
|
||||
build/neuron.log
|
||||
+215
-40
@@ -7,38 +7,48 @@ on:
|
||||
types:
|
||||
- published
|
||||
|
||||
env:
|
||||
VERSION: 2.12.2
|
||||
UI_VERSION: 2.6.1
|
||||
BRANCH: v2.12
|
||||
|
||||
jobs:
|
||||
cross-build:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-18.04
|
||||
strategy:
|
||||
matrix:
|
||||
arch:
|
||||
- [x86_64-linux-gnu, x86_64, amd64]
|
||||
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.12
|
||||
- [aarch64-linux-gnu, aarch64, gcc-aarch64-linux-gnu, g++-aarch64-linux-gnu, /opt/externs/libs, arm64]
|
||||
- [arm-linux-gnueabihf, armv4, gcc-arm-linux-gnueabihf, g++-arm-linux-gnueabihf, /opt/externs/libs, armhf]
|
||||
- [x86_64-linux-gnu, x86_64, gcc, g++, /usr/local, amd64]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: install
|
||||
run: sudo apt-get update && sudo apt-get install -y ${{ matrix.arch[2] }} ${{ matrix.arch[3] }} pkg-config alien
|
||||
|
||||
- name: install dep
|
||||
run: |
|
||||
./install.sh -d ${{ matrix.arch[4] }} -c ${{ matrix.arch[0] }} -a ${{ matrix.arch[1] }}
|
||||
|
||||
- name: get version
|
||||
id: get_version
|
||||
run: echo "::set-output name=version::$(cat version)"
|
||||
|
||||
- name: compile
|
||||
run: |
|
||||
git config --global --add safe.directory $(pwd)
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/${{ matrix.arch[0] }}.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DDISABLE_UT=ON
|
||||
make -j4
|
||||
|
||||
- name: get ui version
|
||||
id: get_ui_version
|
||||
run: echo "::set-output name=version::$(cat ui_version)"
|
||||
|
||||
- name: fetch dashboard
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "emqx/neuron-dashboard-src"
|
||||
version: "tags/${{ env.UI_VERSION }}"
|
||||
version: "tags/${{ steps.get_ui_version.outputs.version }}"
|
||||
file: "neuron-dashboard.zip"
|
||||
target: "neuron-dashboard.zip"
|
||||
|
||||
@@ -48,30 +58,39 @@ jobs:
|
||||
|
||||
- name: Create neuron sdk package
|
||||
run: |
|
||||
./package-sdk.sh -p ${{ matrix.arch[2] }} -n neuron-sdk-$VERSION
|
||||
./package-sdk.sh -p ${{ matrix.arch[5] }} -n neuron-sdk-${{ steps.get_version.outputs.version }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: neuron-sdk-${{ matrix.arch[2] }}
|
||||
name: neuron-sdk-${{ matrix.arch[5] }}
|
||||
path: |
|
||||
neuron-sdk-*.tar.gz
|
||||
|
||||
build-debug-sdk:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
arch:
|
||||
- [x86_64-linux-gnu, x86_64, amd64]
|
||||
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.12
|
||||
- [x86_64-linux-gnu, x86_64, gcc, g++, /usr/local, amd64]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: install
|
||||
run: sudo apt-get update && sudo apt-get install -y ${{ matrix.arch[2] }} ${{ matrix.arch[3] }} pkg-config alien
|
||||
|
||||
- name: install dep
|
||||
run: |
|
||||
./install.sh -d ${{ matrix.arch[4] }} -c ${{ matrix.arch[0] }} -a ${{ matrix.arch[1] }}
|
||||
|
||||
- name: get version
|
||||
id: get_version
|
||||
run: echo "::set-output name=version::$(cat version)"
|
||||
|
||||
- name: compile
|
||||
run: |
|
||||
git config --global --add safe.directory $(pwd)
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/${{ matrix.arch[0] }}.cmake \
|
||||
-DDISABLE_UT=ON
|
||||
@@ -79,42 +98,198 @@ jobs:
|
||||
|
||||
- name: Create neuron sdk package
|
||||
run: |
|
||||
./package-sdk.sh -p ${{ matrix.arch[2] }} -n neuron-sdk-debug-$VERSION
|
||||
./package-sdk.sh -p ${{ matrix.arch[5] }} -n neuron-sdk-debug-${{ steps.get_version.outputs.version }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: neuron-sdk-debug
|
||||
name: neuron-sdk-debug-${{ matrix.arch[5] }}
|
||||
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: Extract branch name
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
id: extract_branch
|
||||
|
||||
- name: delete old daily-pre-release
|
||||
uses: dev-drprasad/delete-tag-and-release@v0.2.1
|
||||
uses: dev-drprasad/delete-tag-and-release@v0.2.0
|
||||
with:
|
||||
delete_release: true
|
||||
tag_name: ${{ env.BRANCH }}-daily
|
||||
tag_name: ${{ steps.extract_branch.outputs.branch }}-daily
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: neuron-sdk-debug
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: neuron-sdk-amd64
|
||||
|
||||
- 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
|
||||
tag_name: ${{ steps.extract_branch.outputs.branch }}-daily
|
||||
release_name: Daily Release(${{ steps.extract_branch.outputs.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@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: get version
|
||||
id: get_version
|
||||
run: echo "::set-output name=version::$(cat version)"
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: release_url
|
||||
|
||||
- id: release_url
|
||||
run: |
|
||||
value=`cat release_url.txt`
|
||||
echo "::set-output name=name::$value"
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.type }}-${{ matrix.arch }}
|
||||
|
||||
- id: package
|
||||
run: echo "::set-output name=name::${{ matrix.type }}-${{ steps.get_version.outputs.version }}-${{ matrix.arch }}.${{ matrix.package }}"
|
||||
|
||||
- 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 }}-${{ steps.get_version.outputs.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@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: get version
|
||||
id: get_version
|
||||
run: echo "::set-output name=version::$(cat version)"
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: release_url
|
||||
|
||||
- id: release_url
|
||||
run: |
|
||||
value=`cat release_url.txt`
|
||||
echo "::set-output name=name::$value"
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.type }}-${{ matrix.arch }}
|
||||
|
||||
- id: package
|
||||
run: echo "::set-output name=name::${{ matrix.type }}-${{ steps.get_version.outputs.version }}-${{ matrix.arch }}.${{ matrix.package }}"
|
||||
|
||||
- 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 }}-${{ steps.get_version.outputs.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@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: get version
|
||||
id: get_version
|
||||
run: echo "::set-output name=version::$(cat version)"
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.type }}-${{ matrix.arch }}
|
||||
|
||||
- id: package
|
||||
run: echo "::set-output name=name::${{ matrix.type }}-${{ steps.get_version.outputs.version }}-${{ matrix.arch }}.${{ matrix.package }}"
|
||||
|
||||
- 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 }}-${{ steps.get_version.outputs.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 }}-${{ steps.get_version.outputs.version }}-linux-${{ matrix.arch }}.${{ matrix.package }}
|
||||
asset_content_type: application/octet-stream
|
||||
@@ -0,0 +1,42 @@
|
||||
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: Create helm package
|
||||
working-directory: deploy/charts/neuron
|
||||
run: helm package .
|
||||
- name: Update helm repo
|
||||
run: |
|
||||
sudo mv $(find deploy/charts/neuron -name "*.tgz") /repos/charts
|
||||
sudo helm repo index /repos/charts
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Test helm
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
deployment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: minikube start --kubernetes-version="v1.23.0"
|
||||
- uses: actions/checkout@v2
|
||||
- name: Deploy neuron by helm
|
||||
shell: bash
|
||||
run: |
|
||||
helm install neuron deploy/charts/neuron\
|
||||
--set image.repository="emqx/neuron"\
|
||||
--set image.tag="2.0.1"
|
||||
- name: Check deployment
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
set -euo pipefail
|
||||
while [ "$(kubectl get pods -o json | jq '.items[0].status.containerStatuses[] | select(.ready==true) | .containerID')" = "" ]; do
|
||||
echo "=============================="
|
||||
kubectl get pods
|
||||
echo "=============================="
|
||||
echo "waiting neuron started"
|
||||
sleep 10
|
||||
done
|
||||
|
||||
|
||||
+1
-5
@@ -16,8 +16,4 @@ tmp
|
||||
*.deb
|
||||
*.rpm
|
||||
neuron-sdk
|
||||
.vscode
|
||||
log.html
|
||||
output.xml
|
||||
report.html
|
||||
*.cache
|
||||
.vscode
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "extern/uthash"]
|
||||
path = extern/uthash
|
||||
url = https://github.com/troydhanson/uthash.git
|
||||
|
||||
+26
-79
@@ -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")
|
||||
@@ -53,85 +44,51 @@ add_custom_target(neuron-version
|
||||
COMMAND ${CMAKE_COMMAND} -P
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/neuron-version.cmake)
|
||||
|
||||
configure_file(extern/uthash/include/uthash.h ${CMAKE_SOURCE_DIR}/include/neuron/utils/uthash.h)
|
||||
configure_file(extern/uthash/include/utarray.h ${CMAKE_SOURCE_DIR}/include/neuron/utils/utarray.h)
|
||||
configure_file(extern/uthash/include/utlist.h ${CMAKE_SOURCE_DIR}/include/neuron/utils/utlist.h)
|
||||
|
||||
find_package(nng CONFIG REQUIRED)
|
||||
find_package(LibXml2 REQUIRED)
|
||||
find_package(Threads)
|
||||
|
||||
if (CMAKE_STAGING_PREFIX)
|
||||
include_directories(${CMAKE_STAGING_PREFIX}/include)
|
||||
link_directories(${CMAKE_STAGING_PREFIX}/lib)
|
||||
include_directories(${CMAKE_STAGING_PREFIX}/include/libxml2)
|
||||
else()
|
||||
include_directories(/usr/local/include)
|
||||
link_directories(/usr/local/lib)
|
||||
include_directories(/usr/local/include/libxml2)
|
||||
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/connection/connection.c
|
||||
src/connection/connection_eth.c
|
||||
src/connection/mqtt_client.c
|
||||
src/connection/mqtt_c_client.c
|
||||
src/connection/mqtt_client_intf.c
|
||||
src/event/event_linux.c
|
||||
src/event/event_unix.c
|
||||
src/utils/asprintf.c
|
||||
src/utils/json.c
|
||||
src/utils/http.c
|
||||
src/utils/http_handler.c
|
||||
src/utils/neu_jwt.c
|
||||
src/utils/base64.c
|
||||
src/utils/async_queue.c
|
||||
src/utils/log.c
|
||||
src/utils/cid.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 (USE_MQTT_SM)
|
||||
message(STATUS "use mqtt sm")
|
||||
add_definitions(-DNEU_USE_MQTT_SM)
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
message(STATUS "build release")
|
||||
add_definitions(-DNEU_RELEASE)
|
||||
endif()
|
||||
|
||||
src/utils/mem_cache.c)
|
||||
|
||||
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 xml2
|
||||
${CMAKE_THREAD_LIBS_INIT} -lm protobuf-c)
|
||||
target_compile_definitions(neuron-base PRIVATE MQTT_USE_BIO)
|
||||
target_link_libraries(neuron-base nng libzlog.so jansson crypto ssl mqttc jwt
|
||||
${CMAKE_THREAD_LIBS_INIT})
|
||||
add_dependencies(neuron-base neuron-version)
|
||||
|
||||
# dependency imposed by nng
|
||||
#find_package(MbedTLS)
|
||||
target_link_libraries(neuron-base mbedtls mbedx509 mbedcrypto)
|
||||
|
||||
set(PERSIST_SOURCES
|
||||
src/persist/persist.c
|
||||
src/persist/json/persist_json_plugin.c)
|
||||
set(NEURON_SOURCES
|
||||
src/main.c
|
||||
src/argparse.c
|
||||
@@ -139,46 +96,43 @@ set(NEURON_SOURCES
|
||||
src/core/manager_internal.c
|
||||
src/core/manager.c
|
||||
src/core/subscribe.c
|
||||
src/core/sub_msg.c
|
||||
src/core/plugin_manager.c
|
||||
src/core/node_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/license.c
|
||||
plugins/restful/license_handle.c
|
||||
plugins/restful/log_handle.c
|
||||
plugins/restful/metric_handle.c
|
||||
plugins/restful/normal_handle.c
|
||||
plugins/restful/rw_handle.c
|
||||
plugins/restful/adapter_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/version_handle.c
|
||||
plugins/restful/scan_handle.c
|
||||
plugins/restful/otel_handle.c
|
||||
plugins/restful/cid_handle.c
|
||||
plugins/restful/system_handle.c
|
||||
plugins/restful/datalayers_handle.c
|
||||
plugins/restful/rest.c
|
||||
plugins/restful/user.c)
|
||||
plugins/restful/http.c
|
||||
plugins/restful/proxy.c
|
||||
plugins/restful/websocket.c
|
||||
${PERSIST_SOURCES})
|
||||
|
||||
set(CMAKE_BUILD_RPATH ./)
|
||||
add_executable(neuron)
|
||||
target_sources(neuron PRIVATE ${NEURON_SOURCES})
|
||||
target_include_directories(neuron PRIVATE include/neuron src plugins)
|
||||
target_link_libraries(neuron dl neuron-base sqlite3 -lm xml2)
|
||||
target_link_options(neuron PRIVATE "LINKER:--dynamic-list-data")
|
||||
target_link_libraries(neuron dl neuron-base sqlite3 -lm)
|
||||
|
||||
#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)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/neuron.pem DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
file(GLOB SQL_SCHEMAS ${CMAKE_SOURCE_DIR}/persistence/*.sql)
|
||||
file(COPY ${SQL_SCHEMAS} DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/default_plugins.json DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
@@ -186,20 +140,13 @@ 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/file)
|
||||
add_subdirectory(plugins/monitor)
|
||||
add_subdirectory(plugins/datalayers)
|
||||
|
||||
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)
|
||||
|
||||
+12
-56
@@ -19,18 +19,11 @@ $ cd jansson && mkdir build && cd build
|
||||
$ cmake -DJANSSON_BUILD_DOCS=OFF -DJANSSON_EXAMPLES=OFF ..&& make && sudo make install
|
||||
```
|
||||
|
||||
[mbedtls](https://github.com/ARMmbed/mbedtls.git)
|
||||
[nng](https://github.com/neugates/nng.git)
|
||||
```shell
|
||||
$ git clone -b v2.16.12 https://github.com/Mbed-TLS/mbedtls.git
|
||||
$ cd mbedtls && mkdir build && cd build
|
||||
$ cmake -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DENABLE_TESTING=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON .. && make && sudo make install
|
||||
```
|
||||
|
||||
[NanoSDK](https://github.com/neugates/NanoSDK.git)
|
||||
```shell
|
||||
$ git clone -b neuron https://github.com/neugates/NanoSDK.git
|
||||
$ cd NanoSDK && mkdir build && cd build
|
||||
$ cmake -DBUILD_SHARED_LIBS=OFF -DNNG_TESTS=OFF -DNNG_ENABLE_SQLITE=ON -DNNG_ENABLE_TLS=ON .. && make && sudo make install
|
||||
$ git clone https://github.com/neugates/nng.git
|
||||
$ cd nng && mkdir build && cd build
|
||||
$ cmake -DBUILD_SHARED_LIBS=OFF -DNNG_TESTS=OFF .. && make && sudo make install
|
||||
```
|
||||
|
||||
[jwt](https://github.com/benmcollins/libjwt.git)
|
||||
@@ -40,6 +33,13 @@ $ cd libjwt && mkdir build && cd build
|
||||
$ cmake -DENABLE_PIC=ON -DBUILD_SHARED_LIBS=OFF .. && make && sudo make install
|
||||
```
|
||||
|
||||
[MQTT-C](https://github.com/neugates/MQTT-C.git)
|
||||
```shell
|
||||
$ git clone https://github.com/neugates/MQTT-C.git
|
||||
$ cd MQTT-C && mkdir build && cd build
|
||||
$ cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DMQTT_C_OpenSSL_SUPPORT=ON -DMQTT_C_EXAMPLES=OFF .. && make && sudo make install
|
||||
```
|
||||
|
||||
[googletest](https://github.com/google/googletest.git)
|
||||
```shell
|
||||
$ git clone -b release-1.11.0 https://github.com/google/googletest.git
|
||||
@@ -53,49 +53,5 @@ $ curl -o sqlite3.tar.gz https://www.sqlite.org/2022/sqlite-autoconf-3390000.tar
|
||||
$ mkdir sqlite3
|
||||
$ tar xzf sqlite3.tar.gz --strip-components=1 -C sqlite3
|
||||
$ cd sqlite3
|
||||
$ ./configure CFLAGS=-fPIC && make && sudo make install
|
||||
$ ./configure && 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 && sudo 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 && sudo make install
|
||||
```
|
||||
|
||||
[libxml2](https://github.com/GNOME/libxml2.git)
|
||||
```shell
|
||||
$ git clone -b v2.9.14 https://github.com/GNOME/libxml2.git
|
||||
$ cd libxml2
|
||||
$ ./autogen.sh
|
||||
$ ./configure --enable-shared=no CFLAGS=-fPIC CXXFLAGS=-fPIC
|
||||
$ make && sudo make install
|
||||
```
|
||||
|
||||
[arrow](https://github.com/apache/arrow)
|
||||
|
||||
To build Apache Arrow C++ for the datalayers plugin, please refer to the [official Arrow](https://github.com/apache/arrow) for the most up-to-date information on dependencies, configuration, and build steps.
|
||||
|
||||
You must enable the following features at a minimum for the datalayers plugin:
|
||||
|
||||
```cmake
|
||||
-DARROW_FLIGHT=ON \
|
||||
-DARROW_FLIGHT_SQL=ON
|
||||
```
|
||||
|
||||
Required Dependencies:
|
||||
When enabling DARROW_FLIGHT and DARROW_FLIGHT_SQL, you must ensure the following dependencies are installed on your system at least: \
|
||||
gRPC \
|
||||
Boost \
|
||||
Thrift
|
||||
+12
-13
@@ -18,17 +18,17 @@ Neuron 是一款开源的、轻量级工业协议网关软件,支持数十种
|
||||
以下是 Neuron 的一些重要特性:
|
||||
|
||||
- 具有实时能力的边缘原生应用程序可以利用边缘端的低延迟网络。
|
||||
- 松耦合模块化 [架构设计](https://neugates.io/docs/zh/latest/introduction/architecture/architecture.html) 通过可插拔模块扩展更多功能服务。
|
||||
- 松耦合模块化 [架构设计](https://neugates.io/docs/en/latest/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/module-plugins/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.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/api.html)和[MQTT](https://neugates.io/docs/en/latest/mqtt.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/getting-started/license_policy.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/zh/latest/getting-started/quick_start.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/zh/latest/getting-started/installation.html) 查看不同安装方式的操作步骤。
|
||||
|
||||
## 文档
|
||||
|
||||
@@ -70,20 +70,21 @@ Neuron 文档地址:[https://neugates.io/docs/zh/latest/](https://neugates.io/
|
||||
|
||||
**安装依赖**
|
||||
|
||||
请参考 [Install-dependencies](https://github.com/emqx/neuron/blob/main/Install-dependencies.md)
|
||||
请参考 [github.com/neugates/neuron/blob/main/Install-dependencies.md](https://github.com/neugates/neuron/blob/main/Install-dependencies.md)
|
||||
|
||||
**编译**
|
||||
|
||||
```
|
||||
$ git clone https://github.com/emqx/neuron
|
||||
$ cd neuron
|
||||
$ git submodule update --init
|
||||
$ mkdir build && cd build
|
||||
$ cmake .. && make
|
||||
```
|
||||
|
||||
**安装 Dashboard**
|
||||
|
||||
在 [neuron-dashboard](https://github.com/emqx/neuron-dashboard/releases) 页面下载最新的 `neuron-dashboard.zip`,解压后放到 Neuron 可执行目录下的 dist 目录中。
|
||||
在 [github.com/emqx/neuron-dashboard/releases](https://github.com/emqx/neuron-dashboard/releases) 页面下载最新的 `neuron-dashboard.zip`,解压后放到 Neuron 可执行目录下的 dist 目录中。
|
||||
|
||||
**运行**
|
||||
|
||||
@@ -112,11 +113,9 @@ $ ctest --output-on-failure
|
||||
运行所有的功能测试
|
||||
|
||||
```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
|
||||
$ pip3 install -r ft/requirements.txt
|
||||
$ python3 -m robot -P ft/ --variable neuron_api:http -d ft/http_reports ft
|
||||
```
|
||||
|
||||
### 压力测试
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
[](https://github.com/emqx/neuron/releases)
|
||||
[](https://hub.docker.com/r/emqx/neuron)
|
||||
[](https://codecov.io/gh/emqx/neuron)
|
||||
[](https://slack-invite.emqx.io/)
|
||||
[](https://discord.gg/xYGf3fQnES)
|
||||
[](https://twitter.com/EMQTech)
|
||||
[](https://www.youtube.com/channel/UC5FjR77ErAxvZENEWzQaO5Q)
|
||||
|
||||
English | [简体中文](https://github.com/neugates/neuron/blob/main/README-CN.md)
|
||||
|
||||
Neuron is an Industrial IoT (IIoT) connectivity server for modern big data and AI/ML technology to leverage the power of Industrial 4.0. It supports one-stop access to dozens of industrial protocols and converts them into MQTT protocol and realize the interconnection between IIoT platforms and various industrial devices.
|
||||
|
||||

|
||||
@@ -15,17 +16,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.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/module-plugins/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.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/api.html) and [MQTT](https://neugates.io/docs/en/latest/mqtt.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/getting-started/license_policy.html) to run.
|
||||
|
||||
For more information, please visit [Neuron homepage](https://neugates.io/).
|
||||
|
||||
@@ -37,20 +38,19 @@ 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/getting-started/quick_start.html#run-for-the-first-time) to tour the Neuron features.
|
||||
|
||||
> **Limitations**
|
||||
>
|
||||
> 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
|
||||
|
||||
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/getting-started/installation.html).
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -67,20 +67,21 @@ The Neuron documentation is available at [neugates.io/docs/en/latest/](https://n
|
||||
|
||||
**Install required dependencies**
|
||||
|
||||
[Install-dependencies](https://github.com/emqx/neuron/blob/main/Install-dependencies.md)
|
||||
[github.com/neugates/neuron/blob/main/Install-dependencies.md](https://github.com/neugates/neuron/blob/main/Install-dependencies.md)
|
||||
|
||||
**Build**
|
||||
|
||||
```
|
||||
$ git clone https://github.com/emqx/neuron
|
||||
$ cd neuron
|
||||
$ git submodule update --init
|
||||
$ mkdir build && cd build
|
||||
$ cmake .. && make
|
||||
```
|
||||
|
||||
**Install Dashboard**
|
||||
|
||||
Download the latest `neuron-dashboard.zip` from the [neuron-dashboard](https://github.com/emqx/neuron-dashboard/releases) page, unzip it and put it to the `dist` directory under the Neuron executable directory.
|
||||
Download the latest `neuron-dashboard.zip` from the [github.com/emqx/neuron-dashboard/releases](https://github.com/emqx/neuron-dashboard/releases) page, unzip it and put it to the `dist` directory under the Neuron executable directory.
|
||||
|
||||
**Run**
|
||||
|
||||
@@ -94,6 +95,47 @@ $ ./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
|
||||
$ mosquitto -v &
|
||||
$ pip3 install -r ft/requirements.txt
|
||||
$ python3 -m robot -P ft/ --variable neuron_api:http -d ft/http_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,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.12/libs)
|
||||
set(LIBRARY_DIR /opt/externs/libs)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
@@ -19,6 +19,5 @@ set(CMAKE_FIND_ROOT_PATH ${CMAKE_STAGING_PREFIX})
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_SYSROOT ${CMAKE_STAGING_PREFIX})
|
||||
link_directories(${CMAKE_STAGING_PREFIX})
|
||||
|
||||
file(COPY ${CMAKE_STAGING_PREFIX}/lib/libzlog.so.1.2 DESTINATION /usr/local/lib)
|
||||
@@ -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.12/libs)
|
||||
set(LIBRARY_DIR /opt/externs/libs)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
@@ -19,6 +19,5 @@ set(CMAKE_FIND_ROOT_PATH ${CMAKE_STAGING_PREFIX})
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_SYSROOT ${CMAKE_STAGING_PREFIX})
|
||||
link_directories(${CMAKE_STAGING_PREFIX})
|
||||
|
||||
file(COPY ${CMAKE_STAGING_PREFIX}/lib/libzlog.so.1.2 DESTINATION /usr/local/lib)
|
||||
|
||||
@@ -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.12/libs)
|
||||
set(LIBRARY_DIR /opt/externs/libs)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
@@ -19,6 +19,5 @@ set(CMAKE_FIND_ROOT_PATH ${CMAKE_STAGING_PREFIX})
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_SYSROOT ${CMAKE_STAGING_PREFIX})
|
||||
link_directories(${CMAKE_STAGING_PREFIX})
|
||||
|
||||
file(COPY ${CMAKE_STAGING_PREFIX}/lib/libzlog.so.1.2 DESTINATION /usr/local/lib)
|
||||
@@ -1,30 +0,0 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
|
||||
set(CMAKE_C_COMPILER ${TOOL_DIR}/${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${TOOL_DIR}/${COMPILER_PREFIX}-g++)
|
||||
set(CMAKE_AR ${TOOL_DIR}/${COMPILER_PREFIX}-ar)
|
||||
set(CMAKE_LINKER ${TOOL_DIR}/${COMPILER_PREFIX}-ld)
|
||||
set(CMAKE_NM ${TOOL_DIR}/${COMPILER_PREFIX}-nm)
|
||||
set(CMAKE_OBJDUMP ${TOOL_DIR}/${COMPILER_PREFIX}-objdump)
|
||||
set(CMAKE_RANLIB ${TOOL_DIR}/${COMPILER_PREFIX}-ranlib)
|
||||
set(CMAKE_STAGING_PREFIX ${LIBRARY_DIR}/${COMPILER_PREFIX})
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_STAGING_PREFIX})
|
||||
|
||||
include_directories(SYSTEM ${CMAKE_STAGING_PREFIX}/include)
|
||||
include_directories(SYSTEM ${CMAKE_STAGING_PREFIX}/openssl/include)
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_STAGING_PREFIX})
|
||||
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,29 +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.12/libs)
|
||||
set(LIBRARY_DIR /usr/local)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
set(CMAKE_AR ${COMPILER_PREFIX}-ar)
|
||||
set(CMAKE_LINKER ${COMPILER_PREFIX}-ld)
|
||||
set(CMAKE_NM ${COMPILER_PREFIX}-nm)
|
||||
set(CMAKE_OBJDUMP ${COMPILER_PREFIX}-objdump)
|
||||
set(CMAKE_RANLIB ${COMPILER_PREFIX}-ranlib)
|
||||
set(CMAKE_STAGING_PREFIX ${LIBRARY_DIR}/${COMPILER_PREFIX})
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_STAGING_PREFIX})
|
||||
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-lto")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-lto")
|
||||
|
||||
include_directories(SYSTEM ${CMAKE_STAGING_PREFIX}/include)
|
||||
include_directories(SYSTEM ${CMAKE_STAGING_PREFIX}/openssl/include)
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_STAGING_PREFIX})
|
||||
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})
|
||||
|
||||
file(COPY ${CMAKE_STAGING_PREFIX}/lib/libzlog.so.1.2 DESTINATION /usr/local/lib)
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_STAGING_PREFIX})
|
||||
@@ -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
|
||||
@@ -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,11 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
"libplugin-mqtt.so",
|
||||
"libplugin-aws-iot.so",
|
||||
"libplugin-azure-iot.so",
|
||||
"libplugin-ekuiper.so",
|
||||
"libplugin-modbus-tcp.so",
|
||||
"libplugin-modbus-rtu.so",
|
||||
"libplugin-file.so"
|
||||
"libplugin-mqtt.so",
|
||||
"libplugin-modbus-tcp.so"
|
||||
]
|
||||
}
|
||||
@@ -15,10 +15,10 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 1.0.6
|
||||
version: 1.0.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: 2.2.8
|
||||
appVersion: "2.0.1"
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# neuron
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
A Helm chart for Kubernetes
|
||||
|
||||
|
||||
## Install the Chart
|
||||
|
||||
- From Github
|
||||
@@ -24,27 +23,37 @@ helm uninstall my-neuron
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| affinity | object | `{}` | |
|
||||
| autoscaling.enabled | bool | `false` | |
|
||||
| autoscaling.maxReplicas | int | `100` | |
|
||||
| autoscaling.minReplicas | int | `1` | |
|
||||
| autoscaling.targetCPUUtilizationPercentage | int | `80` | |
|
||||
| clusterDomain | string | `"cluster.local"` | Kubernetes Cluster Domain |
|
||||
| containerPorts | object | `{"api":7001,"web":7000}` | Container Ports |
|
||||
| containerPorts.api | int | `7001` | containerPorts.api |
|
||||
| containerPorts.web | int | `7000` | containerPorts.web |
|
||||
| fullnameOverride | string | `""` | |
|
||||
| hostPorts | object | `{"api":30371,"enabled":false,"web":30370}` | only for kubeedge deployment |
|
||||
| image.pullPolicy | string | `"IfNotPresent"` | |
|
||||
| image.repository | string | `"emqx/neuron"` | |
|
||||
| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. |
|
||||
| imagePullSecrets | list | `[]` | |
|
||||
| ingress.annotations | object | `{}` | |
|
||||
| ingress.className | string | `""` | |
|
||||
| ingress.enabled | bool | `false` | |
|
||||
| ingress.hosts[0].host | string | `"chart-example.local"` | |
|
||||
| ingress.hosts[0].paths[0].path | string | `"/"` | |
|
||||
| ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
|
||||
| ingress.tls | list | `[]` | |
|
||||
| nameOverride | string | `""` | |
|
||||
| neuronEnv.enabled | bool | `true` | |
|
||||
| neuronEnv.keys.disableAuth | string | `"DISABLE_AUTH"` | |
|
||||
| neuronEnv.values.disableAuth | bool | `true` | |
|
||||
| neuronMounts[0].capacity | string | `"100Mi"` | |
|
||||
| neuronMounts[0].mountPath | string | `"/opt/neuron/persistence"` | |
|
||||
| neuronMounts[0].name | string | `"pvc-neuron-data"` | |
|
||||
| nodeSelector | object | `{}` | |
|
||||
| persistence.accessMode | string | `"ReadWriteOnce"` | |
|
||||
| persistence.enabled | bool | `false` | |
|
||||
| persistence.storageClass | string | `"standard"` | |
|
||||
| persistence.existingClaim | string | `""` | Existing PersistentVolumeClaims The value is evaluated as a template So, for example, the name can depend on .Release or .Chart |
|
||||
| podAnnotations | object | `{}` | |
|
||||
| readinessProbe.enabled | bool | `true` | |
|
||||
| readinessProbe.initialDelaySeconds | int | `5` | |
|
||||
| readinessProbe.periodSeconds | int | `5` | |
|
||||
| resources | object | `{}` | |
|
||||
| service.annotations | object | `{"eip.openelb.kubesphere.io/v1alpha2":"eip-pool","lb.kubesphere.io/v1alpha1":"openelb","protocol.openelb.kubesphere.io/v1alpha1":"layer2"}` | Provide any additional annotations which may be required. Evaluated as a template |
|
||||
| service.annotations | object | `{}` | Provide any additional annotations which may be required. Evaluated as a template |
|
||||
| service.enabled | bool | `true` | |
|
||||
| service.loadBalancerSourceRanges | list | `[]` | loadBalancerSourceRanges: - 10.10.10.0/24 |
|
||||
| service.nodePorts | object | `{"api":null,"web":null}` | Specify the nodePort(s) value for the LoadBalancer and NodePort service types. ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport |
|
||||
@@ -54,11 +63,7 @@ helm uninstall my-neuron
|
||||
| service.ports.web.name | string | `"web"` | Neuron Dashboard port name |
|
||||
| service.ports.web.port | int | `7000` | Neuron Dashboard port |
|
||||
| service.type | string | `"ClusterIP"` | |
|
||||
| tolerations[0].effect | string | `"NoExecute"` | |
|
||||
| tolerations[0].key | string | `"node.kubernetes.io/not-ready"` | |
|
||||
| tolerations[0].operator | string | `"Exists"` | |
|
||||
| tolerations[0].tolerationSeconds | int | `30` | |
|
||||
| tolerations[1].effect | string | `"NoExecute"` | |
|
||||
| tolerations[1].key | string | `"node.kubernetes.io/unreachable"` | |
|
||||
| tolerations[1].operator | string | `"Exists"` | |
|
||||
| tolerations[1].tolerationSeconds | int | `30` | |
|
||||
| serviceAccount.annotations | object | `{}` | Annotations to add to the service account |
|
||||
| serviceAccount.create | bool | `true` | Specifies whether a service account should be created |
|
||||
| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template |
|
||||
| tolerations | list | `[]` | |
|
||||
@@ -50,6 +50,16 @@ app.kubernetes.io/name: {{ include "neuron.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "neuron.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "neuron.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Get the TLS secret.
|
||||
|
||||
@@ -15,17 +15,15 @@ spec:
|
||||
labels:
|
||||
{{- include "neuron.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "neuron.serviceAccountName" . }}
|
||||
volumes:
|
||||
{{- range $mount := .Values.neuronMounts }}
|
||||
- name: {{ $mount.name }}
|
||||
{{- if $.Values.persistence.enabled }}
|
||||
- name: neuron-persistence
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ printf "%s-%s" $.Release.Name (tpl $mount.name $) }}
|
||||
claimName: {{ (tpl .Values.persistence.existingClaim $) | default (include "neuron.fullname" .) }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.tls.enabled }}
|
||||
- name: certs
|
||||
secret:
|
||||
@@ -40,32 +38,27 @@ spec:
|
||||
- name: neuron
|
||||
image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if .Values.neuronEnv.enabled }}
|
||||
env:
|
||||
- name: {{ .Values.neuronEnv.keys.disableAuth }}
|
||||
value: "{{ .Values.neuronEnv.values.disableAuth }}"
|
||||
{{- end }}
|
||||
{{- if .Values.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
port: {{ .Values.service.web | default 7000 }}
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: web
|
||||
containerPort: {{ .Values.service.ports.web.port | default 7000 }}
|
||||
containerPort: {{ .Values.containerPorts.web | default 7000 }}
|
||||
{{- if .Values.hostPorts.enabled }}
|
||||
hostPort: {{ .Values.hostPorts.web | default 7000 }}
|
||||
{{- end}}
|
||||
- name: api
|
||||
containerPort: {{ .Values.service.ports.api.port | default 7001 }}
|
||||
containerPort: {{ .Values.containerPorts.api | default 7001 }}
|
||||
{{- if .Values.hostPorts.enabled }}
|
||||
hostPort: {{ .Values.hostPorts.api | default 7001 }}
|
||||
{{- end}}
|
||||
volumeMounts:
|
||||
{{- range $mount := .Values.neuronMounts }}
|
||||
- name: {{ $mount.name }}
|
||||
mountPath: {{ $mount.mountPath }}
|
||||
{{- end }}
|
||||
- name: neuron-persistence
|
||||
mountPath: "/opt/neuron/persistence"
|
||||
{{- if .Values.tls.enabled }}
|
||||
- name: certs
|
||||
mountPath: "/opt/neuron/config/neuron.pem"
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "neuron.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "neuron.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,41 +0,0 @@
|
||||
{{- if $.Values.persistence.enabled }}
|
||||
{{- $top := . -}}
|
||||
{{- range $mount := .Values.ekuiperMounts }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ printf "%s-%s" $.Release.Name (tpl $mount.name $) }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
annotations:
|
||||
kubesphere.io/creator: admin
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ $.Values.persistence.accessMode }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ $mount.capacity }}
|
||||
storageClassName: {{ $.Values.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- range $mount := .Values.neuronMounts }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ printf "%s-%s" $.Release.Name (tpl $mount.name $) }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
annotations:
|
||||
kubesphere.io/creator: admin
|
||||
finalizers:
|
||||
- kubernetes.io/pvc-protection
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ $.Values.persistence.accessMode }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ $mount.capacity }}
|
||||
storageClassName: {{ $.Values.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "neuron.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "neuron.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -6,12 +6,6 @@ metadata:
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "neuron.labels" . | nindent 4 }}
|
||||
{{- if eq .Values.service.type "LoadBalancer" }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
{{- if eq .Values.service.type "LoadBalancer" }}
|
||||
|
||||
@@ -13,6 +13,15 @@ imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# -- Specifies whether a service account should be created
|
||||
create: true
|
||||
# -- Annotations to add to the service account
|
||||
annotations: {}
|
||||
# -- The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
# @ignored
|
||||
@@ -62,24 +71,32 @@ service:
|
||||
# - 10.10.10.0/24
|
||||
#
|
||||
loadBalancerSourceRanges: []
|
||||
## TODO: it's just for OpenELB
|
||||
# -- Provide any additional annotations which may be required. Evaluated as a template
|
||||
annotations:
|
||||
lb.kubesphere.io/v1alpha1: openelb
|
||||
eip.openelb.kubesphere.io/v1alpha2: eip-pool
|
||||
protocol.openelb.kubesphere.io/v1alpha1: layer2
|
||||
annotations: {}
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
|
||||
persistence:
|
||||
enabled: false
|
||||
accessMode: ReadWriteOnce
|
||||
## TODO: not all storage class can work well, it depends on the specific storage
|
||||
storageClass: standard
|
||||
# storageClass: huawei-nfs
|
||||
|
||||
neuronMounts:
|
||||
- name: pvc-neuron-data
|
||||
capacity: 100Mi
|
||||
mountPath: "/opt/neuron/persistence"
|
||||
# -- Existing PersistentVolumeClaims
|
||||
# The value is evaluated as a template
|
||||
# So, for example, the name can depend on .Release or .Chart
|
||||
existingClaim: ""
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
@@ -93,17 +110,16 @@ resources: {}
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations:
|
||||
- key: "node.kubernetes.io/not-ready"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 30
|
||||
- key: "node.kubernetes.io/unreachable"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 30
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
@@ -155,13 +171,17 @@ tls:
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
|
||||
neuronEnv:
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
keys:
|
||||
disableAuth: DISABLE_AUTH
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
|
||||
values:
|
||||
disableAuth: true
|
||||
# -- Container Ports
|
||||
containerPorts:
|
||||
# -- containerPorts.web
|
||||
web: 7000
|
||||
# -- containerPorts.api
|
||||
api: 7001
|
||||
|
||||
# -- only for kubeedge deployment
|
||||
hostPorts:
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
[global]
|
||||
|
||||
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"
|
||||
simple = "%d [%V] [%c] %f:%L %m%n"
|
||||
|
||||
[rules]
|
||||
|
||||
*.* "./logs/%c.log", 25MB * 1 ~ "./logs/%c.#2r.log"; file_format
|
||||
*.* >stdout; stdout_format
|
||||
*.* $remote_syslog,"%V"; syslog
|
||||
*.DEBUG >stdout; simple
|
||||
*.DEBUG $ws, "%V,%c"; simple
|
||||
|
||||
+1
Submodule extern/uthash added at 44a66fe8e0
@@ -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()
|
||||
@@ -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"
|
||||
}
|
||||
+60004
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
+6004
File diff suppressed because it is too large
Load Diff
@@ -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,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"
|
||||
}
|
||||
+604
@@ -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"
|
||||
}
|
||||
+604
@@ -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"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0001",
|
||||
"adapter_name": "modbus-tcp-0001"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0002",
|
||||
"adapter_name": "modbus-tcp-0001"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0003",
|
||||
"adapter_name": "modbus-tcp-0001"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0001",
|
||||
"adapter_name": "modbus-tcp-0002"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0002",
|
||||
"adapter_name": "modbus-tcp-0002"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0003",
|
||||
"adapter_name": "modbus-tcp-0002"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0004",
|
||||
"adapter_name": "modbus-tcp-0002"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0001",
|
||||
"adapter_name": "modbus-tcp-0003"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0002",
|
||||
"adapter_name": "modbus-tcp-0003"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0003",
|
||||
"adapter_name": "modbus-tcp-0003"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0004",
|
||||
"adapter_name": "modbus-tcp-0003"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0001",
|
||||
"adapter_name": "modbus-tcp-0004"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0002",
|
||||
"adapter_name": "modbus-tcp-0004"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0003",
|
||||
"adapter_name": "modbus-tcp-0004"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0004",
|
||||
"adapter_name": "modbus-tcp-0004"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0001",
|
||||
"adapter_name": "modbus-tcp-0005"
|
||||
}
|
||||
+1204
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"read_interval": 1000,
|
||||
"group_config_name": "group-0002",
|
||||
"adapter_name": "modbus-tcp-0005"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user