├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── auto-merge.yml ├── dependabot.yml ├── stale.yml └── workflows │ ├── codeql.yml │ ├── dependabot-automerge.yml │ └── test-and-release.yml ├── .gitignore ├── .mocharc.json ├── .releaseconfig.json ├── LICENSE ├── README.md ├── RetentionPolicies.md ├── admin ├── i18n │ ├── de │ │ └── translations.json │ ├── en │ │ └── translations.json │ ├── es │ │ └── translations.json │ ├── fr │ │ └── translations.json │ ├── it │ │ └── translations.json │ ├── nl │ │ └── translations.json │ ├── pl │ │ └── translations.json │ ├── pt │ │ └── translations.json │ ├── ru │ │ └── translations.json │ ├── uk │ │ └── translations.json │ └── zh-cn │ │ └── translations.json ├── influxdb.png ├── jsonConfig.json ├── jsonCustom.json └── words.js ├── docs └── de │ ├── img │ ├── influxdb_Filtern_loggen.jpg │ ├── influxdb_ioBroker_Adapter_SQL_objects_Data.jpg │ ├── influxdb_ioBroker_Adapter_SQL_objects_filter.jpg │ ├── influxdb_ioBroker_Adapter_SQL_objects_timerange.jpg │ ├── influxdb_ioBroker_Adapter_SQL_objects_type.jpg │ ├── influxdb_ioBroker_Adapter_influxDB_Konfig.jpg │ ├── influxdb_ioBroker_Adapter_influxDB_objects.jpg │ ├── influxdb_ioBroker_Adapter_rickshaw03.jpg │ └── influxdb_ioBroker_adapter_History_devices.jpg │ └── influxdb.md ├── io-package.json ├── lib ├── Database.js ├── DatabaseInfluxDB1x.js ├── DatabaseInfluxDB2x.js └── aggregate.js ├── main.js ├── package-lock.json ├── package.json └── test ├── lib ├── setup.js └── testcases.js ├── mocha.setup.js ├── testAdapter.js ├── testAdapterBuffer.js ├── testAdapterExisting.js ├── testAdapterTags.js └── testPackageFiles.js /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Something is not working as it should 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 1. Go to '...' 15 | 2. Click on '...' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots & Logfiles** 23 | If applicable, add screenshots and logfiles to help explain your problem. 24 | 25 | **Versions:** 26 | - Adapter version: 27 | - JS-Controller version: 28 | - Node version: 29 | - Operating system: 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/auto-merge.yml: -------------------------------------------------------------------------------- 1 | # Configure here which dependency updates should be merged automatically. 2 | # The recommended configuration is the following: 3 | - match: 4 | # Only merge patches for production dependencies 5 | dependency_type: production 6 | update_type: "semver:patch" 7 | - match: 8 | # Except for security fixes, here we allow minor patches 9 | dependency_type: production 10 | update_type: "security:minor" 11 | - match: 12 | # and development dependencies can have a minor update, too 13 | dependency_type: development 14 | update_type: "semver:minor" 15 | 16 | # The syntax is based on the legacy dependabot v1 automerged_updates syntax, see: 17 | # https://dependabot.com/docs/config-file/#automerged_updates -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | time: "04:00" 8 | timezone: Europe/Berlin 9 | - package-ecosystem: npm 10 | directory: "/" 11 | schedule: 12 | interval: monthly 13 | time: "04:00" 14 | timezone: Europe/Berlin 15 | open-pull-requests-limit: 20 16 | versioning-strategy: increase -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 7 9 | 10 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) 11 | onlyLabels: [] 12 | 13 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 14 | exemptLabels: 15 | - enhancement 16 | - security 17 | 18 | # Set to true to ignore issues in a project (defaults to false) 19 | exemptProjects: true 20 | 21 | # Set to true to ignore issues in a milestone (defaults to false) 22 | exemptMilestones: true 23 | 24 | # Set to true to ignore issues with an assignee (defaults to false) 25 | exemptAssignees: false 26 | 27 | # Label to use when marking as stale 28 | staleLabel: wontfix 29 | 30 | # Comment to post when marking as stale. Set to `false` to disable 31 | markComment: > 32 | This issue has been automatically marked as stale because it has not had 33 | recent activity. It will be closed if no further activity occurs within the next 7 days. 34 | Please check if the issue is still relevant in the most current version of the adapter 35 | and tell us. Also check that all relevant details, logs and reproduction steps 36 | are included and update them if needed. 37 | Thank you for your contributions. 38 | 39 | Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivitäten gab. 40 | Es wird geschlossen, wenn nicht innerhalb der nächsten 7 Tage weitere Aktivitäten stattfinden. 41 | Bitte überprüft, ob das Problem auch in der aktuellsten Version des Adapters noch relevant ist, 42 | und teilt uns dies mit. Überprüft auch, ob alle relevanten Details, Logs und Reproduktionsschritte 43 | enthalten sind bzw. aktualisiert diese. 44 | Vielen Dank für Eure Unterstützung. 45 | 46 | # Comment to post when removing the stale label. 47 | # unmarkComment: > 48 | # Your comment here. 49 | 50 | # Comment to post when closing a stale Issue or Pull Request. 51 | closeComment: > 52 | This issue has been automatically closed because of inactivity. Please open a new 53 | issue if still relevant and make sure to include all relevant details, logs and 54 | reproduction steps. 55 | Thank you for your contributions. 56 | 57 | Dieses Problem wurde aufgrund von Inaktivität automatisch geschlossen. Bitte öffnet ein 58 | neues Issue, falls dies noch relevant ist und stellt sicher das alle relevanten Details, 59 | Logs und Reproduktionsschritte enthalten sind. 60 | Vielen Dank für Eure Unterstützung. 61 | 62 | # Limit the number of actions per hour, from 1-30. Default is 30 63 | limitPerRun: 30 64 | 65 | # Limit to only `issues` or `pulls` 66 | only: issues 67 | 68 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': 69 | # pulls: 70 | # daysUntilStale: 30 71 | # markComment: > 72 | # This pull request has been automatically marked as stale because it has not had 73 | # recent activity. It will be closed if no further activity occurs. Thank you 74 | # for your contributions. 75 | 76 | # issues: 77 | # exemptLabels: 78 | # - confirmed -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | schedule: 9 | - cron: "12 15 * * 1" 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: [ javascript ] 24 | 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | 29 | - name: Initialize CodeQL 30 | uses: github/codeql-action/init@v2 31 | with: 32 | languages: ${{ matrix.language }} 33 | queries: +security-and-quality 34 | 35 | - name: Autobuild 36 | uses: github/codeql-action/autobuild@v2 37 | 38 | - name: Perform CodeQL Analysis 39 | uses: github/codeql-action/analyze@v2 40 | with: 41 | category: "/language:${{ matrix.language }}" 42 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-automerge.yml: -------------------------------------------------------------------------------- 1 | # Automatically merge Dependabot PRs when version comparison is within the range 2 | # that is configured in .github/auto-merge.yml 3 | 4 | name: Auto-Merge Dependabot PRs 5 | 6 | on: 7 | pull_request_target: 8 | 9 | jobs: 10 | auto-merge: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v4 15 | 16 | - name: Check if PR should be auto-merged 17 | uses: ahmadnassri/action-dependabot-auto-merge@v2 18 | with: 19 | # This must be a personal access token with push access 20 | github-token: ${{ secrets.AUTO_MERGE_TOKEN }} 21 | # By default, squash and merge, so Github chooses nice commit messages 22 | command: squash and merge -------------------------------------------------------------------------------- /.github/workflows/test-and-release.yml: -------------------------------------------------------------------------------- 1 | # This is a composition of lint and test scripts 2 | # Make sure to update this file along with the others 3 | 4 | name: Test and Release 5 | 6 | # Run this job on all pushes and pull requests 7 | # as well as tags with a semantic version 8 | on: 9 | push: 10 | branches: 11 | - '*' 12 | tags: 13 | # normal versions 14 | - "v?[0-9]+.[0-9]+.[0-9]+" 15 | # pre-releases 16 | - "v?[0-9]+.[0-9]+.[0-9]+-**" 17 | pull_request: {} 18 | 19 | # Cancel previous PR/branch runs when a new commit is pushed 20 | concurrency: 21 | group: ${{ github.ref }} 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | # Performs quick checks before the expensive test runs 26 | check-and-lint: 27 | if: contains(github.event.head_commit.message, '[skip ci]') == false 28 | 29 | runs-on: ubuntu-latest 30 | 31 | strategy: 32 | matrix: 33 | node-version: [18.x] 34 | 35 | steps: 36 | - uses: actions/checkout@v4 37 | - name: Use Node.js ${{ matrix.node-version }} 38 | uses: actions/setup-node@v4 39 | with: 40 | node-version: ${{ matrix.node-version }} 41 | 42 | 43 | - name: Install Dependencies 44 | run: npm ci 45 | 46 | # - name: Perform a type check 47 | # run: npm run check:ts 48 | # env: 49 | # CI: true 50 | # - name: Lint TypeScript code 51 | # run: npm run lint 52 | - name: Test package files 53 | run: node node_modules/mocha/bin/mocha test/testPackageFiles.js --exit 54 | 55 | # Runs adapter tests on all supported node versions and OSes 56 | adapter-tests-influxdb1: 57 | if: contains(github.event.head_commit.message, '[skip ci]') == false 58 | 59 | needs: [check-and-lint] 60 | 61 | runs-on: ${{ matrix.os }} 62 | strategy: 63 | matrix: 64 | node-version: [16.x, 18.x, 20.x] 65 | os: [ubuntu-latest, windows-latest, macos-latest] 66 | 67 | steps: 68 | - uses: actions/checkout@v4 69 | - name: Use Node.js ${{ matrix.node-version }} 70 | uses: actions/setup-node@v4 71 | with: 72 | node-version: ${{ matrix.node-version }} 73 | 74 | - name: Install Dependencies 75 | run: npm ci 76 | 77 | - name: Install Influxdb 1.x (Linux) 78 | if: startsWith(runner.OS, 'linux') 79 | run: | 80 | wget -nv https://dl.influxdata.com/influxdb/releases/influxdb_1.8.6_amd64.deb 81 | sudo dpkg -i influxdb_1.8.6_amd64.deb 82 | sudo systemctl start influxdb 83 | 84 | - name: Run local tests (Linux) 85 | if: startsWith(runner.OS, 'linux') 86 | run: npm test 87 | # - name: Run unit tests 88 | # run: npm run test:unit 89 | # - name: Run integration tests # (linux/osx) 90 | # if: startsWith(runner.OS, 'windows') == false 91 | # run: DEBUG=testing:* npm run test:integration 92 | # - name: Run integration tests # (windows) 93 | # if: startsWith(runner.OS, 'windows') 94 | # run: set DEBUG=testing:* & npm run test:integration 95 | 96 | # Runs adapter tests on all supported node versions and OSes 97 | adapter-tests-influxdb2: 98 | if: contains(github.event.head_commit.message, '[skip ci]') == false 99 | 100 | needs: [check-and-lint] 101 | 102 | runs-on: ${{ matrix.os }} 103 | strategy: 104 | matrix: 105 | node-version: [16.x, 18.x, 20.x] 106 | os: [ubuntu-latest] 107 | 108 | steps: 109 | - uses: actions/checkout@v4 110 | - name: Use Node.js ${{ matrix.node-version }} 111 | uses: actions/setup-node@v4 112 | with: 113 | node-version: ${{ matrix.node-version }} 114 | 115 | - name: Install Dependencies 116 | run: npm ci 117 | 118 | - name: Install Influxdb 2.x (Linux) 119 | id: influxdb2 120 | if: startsWith(runner.OS, 'linux') 121 | run: | 122 | wget -nv https://dl.influxdata.com/influxdb/releases/influxdb2-2.0.7-amd64.deb 123 | sudo dpkg -i influxdb2-2.0.7-amd64.deb 124 | sudo systemctl start influxdb 125 | sleep 20 126 | sudo journalctl -u influxdb 127 | sudo influx setup --org test-org --bucket test-bucket --username test-user --password test-password --token test-token --force 128 | sudo influx config list 129 | AUTHTOKEN=$(sudo influx auth create --read-buckets --read-checks --read-dashboards --read-dbrps --read-notificationEndpoints --read-notificationRules --read-orgs --read-tasks --read-telegrafs --read-user --write-buckets --write-checks --write-dashboards --write-dbrps --write-notificationEndpoints --write-notificationRules --write-orgs --write-tasks --write-telegrafs --write-user --org test-org --token test-token --json --hide-headers) 130 | AUTHTOKEN="${AUTHTOKEN//'%'/'%25'}" 131 | AUTHTOKEN="${AUTHTOKEN//$'\n'/'%0A'}" 132 | AUTHTOKEN="${AUTHTOKEN//$'\r'/'%0D'}" 133 | echo "::set-output name=AUTHTOKEN::$AUTHTOKEN" 134 | sudo influx org list --token test-token 135 | sudo influx bucket list --token test-token 136 | sudo influx auth list --user test-user --token test-token --org test-org 137 | 138 | - name: Run local tests (Linux) 139 | if: startsWith(runner.OS, 'linux') 140 | env: 141 | INFLUXDB2: true 142 | AUTHTOKEN: ${{ steps.influxdb2.outputs.AUTHTOKEN }} 143 | run: npm test 144 | # - name: Run unit tests 145 | # run: npm run test:unit 146 | # - name: Run integration tests # (linux/osx) 147 | # if: startsWith(runner.OS, 'windows') == false 148 | # run: DEBUG=testing:* npm run test:integration 149 | # - name: Run integration tests # (windows) 150 | # if: startsWith(runner.OS, 'windows') 151 | # run: set DEBUG=testing:* & npm run test:integration 152 | 153 | # Deploys the final package to NPM 154 | deploy: 155 | needs: [adapter-tests-influxdb1,adapter-tests-influxdb2] 156 | 157 | # Trigger this step only when a commit on master is tagged with a version number 158 | if: | 159 | contains(github.event.head_commit.message, '[skip ci]') == false && 160 | github.event_name == 'push' && 161 | startsWith(github.ref, 'refs/tags/') 162 | runs-on: ubuntu-latest 163 | strategy: 164 | matrix: 165 | node-version: [18.x] 166 | 167 | steps: 168 | - name: Checkout code 169 | uses: actions/checkout@v4 170 | 171 | - name: Use Node.js ${{ matrix.node-version }} 172 | uses: actions/setup-node@v4 173 | with: 174 | node-version: ${{ matrix.node-version }} 175 | 176 | - name: Extract the version and commit body from the tag 177 | id: extract_release 178 | # The body may be multiline, therefore we need to escape some characters 179 | run: | 180 | VERSION="${{ github.ref }}" 181 | VERSION=${VERSION##*/} 182 | VERSION=${VERSION##*v} 183 | echo "::set-output name=VERSION::$VERSION" 184 | BODY=$(git show -s --format=%b) 185 | BODY="${BODY//'%'/'%25'}" 186 | BODY="${BODY//$'\n'/'%0A'}" 187 | BODY="${BODY//$'\r'/'%0D'}" 188 | echo "::set-output name=BODY::$BODY" 189 | 190 | - name: Install Dependencies 191 | run: npm ci 192 | 193 | # - name: Create a clean build 194 | # run: npm run build 195 | - name: Publish package to npm 196 | run: | 197 | npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }} 198 | npm whoami 199 | npm publish 200 | 201 | - name: Create Github Release 202 | uses: actions/create-release@v1 203 | env: 204 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 205 | with: 206 | tag_name: ${{ github.ref }} 207 | release_name: Release v${{ steps.extract_release.outputs.VERSION }} 208 | draft: false 209 | # Prerelease versions create prereleases on Github 210 | prerelease: ${{ contains(steps.extract_release.outputs.VERSION, '-') }} 211 | body: ${{ steps.extract_release.outputs.BODY }} 212 | 213 | - name: Notify Sentry.io about the release 214 | run: | 215 | npm i -g @sentry/cli 216 | export SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} 217 | export SENTRY_URL=https://sentry.iobroker.net 218 | export SENTRY_ORG=iobroker 219 | export SENTRY_PROJECT=iobroker-influxdb 220 | export SENTRY_VERSION=iobroker.influxdb@${{ steps.extract_release.outputs.VERSION }} 221 | sentry-cli releases new $SENTRY_VERSION 222 | sentry-cli releases set-commits $SENTRY_VERSION --auto 223 | sentry-cli releases finalize $SENTRY_VERSION 224 | 225 | # Add the following line BEFORE finalize if sourcemap uploads are needed 226 | # sentry-cli releases files $SENTRY_VERSION upload-sourcemaps build/ 227 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | admin/i18n/flat.txt 2 | admin/i18n/*/flat.txt 3 | iob_npm.done 4 | node_modules 5 | .idea 6 | exe 7 | /tmp 8 | -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": [ 3 | "./test/mocha.setup.js" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.releaseconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["iobroker", "license"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2024 bluefox , apollon77 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /RetentionPolicies.md: -------------------------------------------------------------------------------- 1 | # Understanding retention policies 2 | 3 | It is important to understand how **Retention Policies** and **Shard Group Durations** are related in order to determine how long data will be kept in InfluxDB. 4 | 5 | 6 | 7 | Influx stores all measurements within a given time range into the same **Shard** which itself is part of a **Shard Group**. The Shard Group enforces a time range defined by `Shard Group Duration` to all shards, but it is set differently depending on the Influx release. 8 | 9 | When exceeding the configured `Shard Group Duration`, 10 | 11 | - a new Shard is created which stores newer measurement data from that point onwards 12 | - the old Shard with all its measurement-data is still kept in the database, but will be dropped, once the retention policy for the measurement is exceeded 13 | 14 | 15 | Measurement data-points are not deleted by Influx via "looking" at their retention policies individually, but instead the Shard as a whole is subject to retention policy check and will be dropped, if the retention policy is exceeded. The check however will only be performed on old Shards, meaning Shards that are still active are not checked, as they also still can receive new measurement data points. 16 | 17 | *Please refer to https://docs.influxdata.com/influxdb/v1.4/concepts/schema_and_data_layout/#shard-group-duration-management for more explanation and examples.* 18 | 19 | 20 | The following two examples illustrate how the same retention period will be enforced differently, depeding on the configured Shard Group Duration. 21 | 22 | | | Example 1 | Example 2 | 23 | |--|--|--| 24 | | Retention Period | 2 hours | 2 hours | 25 | | Shard Group Duration | 1 hour | 1 day | 26 | | How long will data be kept at max? | 2 hours | 1 day | 27 | | Why? | The Shard is switched every hour, hence Influx will enforce the configured RP once **every hour** and keep only data from the **last 2 hours**. | The Shard is switched once a day, and Influx will then enforce the configured RP, meaning it will only keep data from the last **2 hours**. Because of this, measurement-data inserted at the beginning of the Shard-lifetime in theory should only be kept for 2 hours, but effectively will be kept a **whole day**. | 28 | 29 | ## iobroker.influxdb Adapter 30 | The Influx Adapter only allows you to select a **Retention Period** and itself will automatically choose the **Shard Group Duration** according to [official InfluxDB recommendations](https://docs.influxdata.com/influxdb/v2.0/reference/internals/shards/#shard-group-duration). 31 | 32 | | Bucket retention period | Default shard group duration | 33 | |--|--| 34 | | less than 2 days | 1h | 35 | | between 2 days and 6 months | 1d | 36 | | greater than 6 months |7d | 37 | 38 | 39 | The Shard Group Duration can still be altered manually in the DB itself, but in order to keep the adapter configuration manageable, it can not be changed directly within ioBroker. 40 | 41 | By design the adapter enforces only one global retention policy that applies to all measurements - regardless of the DB version that is used. The policy can be changed at any time, but for the reasons described earlier it might take a while for the changes to take effect. 42 | 43 | ## Additional considerations 44 | 45 | - The shard group duration is often configured shorter than the retention period, in order to be enforced effectively. But it is difficult to state this as a general advice, since other factors, like performance should be considered, too. If shard group durations are configured extremely short, this might be beneficial for housekeeping, but it could negatively impact performance, like causing longer query times, or slow write speeds. 46 | - A retention policy may not be lower than 1 hour. This was a choice made by Influx devs (https://github.com/influxdata/influxdb/issues/5198#issuecomment-166629531) and can only be bypassed by building InfluxDB from latest source with changed values directly. 47 | - Retention policies are checked by default every 30 minutes. This can be changed however in [server configuration for Influx 1.x](https://docs.influxdata.com/influxdb/v1.8/administration/config/#retention-policy-settings) and [server configuration for Influx 2.x](https://docs.influxdata.com/influxdb/v2.0/reference/config-options/#storage-retention-check-interval). This does **not** bypass the principles explained earlier. 48 | - **Influx 1.x**: For existing dbs the adapter is able to detect the current default retention policy and will update it. If you modified retention policies manually and now are still experiencing missing data in the adapter, it might be related to the changed default-policy. See also here for more information: https://docs.influxdata.com/influxdb/v1.7/troubleshooting/frequently-asked-questions/#why-am-i-missing-data-after-creating-a-new-default-retention-policy. -------------------------------------------------------------------------------- /admin/i18n/de/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = Deaktivieren", 3 | "0 = disable delta check": "0 = Abweichungsprüfung deaktivieren", 4 | "0 = disabled": "0 = deaktiviert", 5 | "1 day": "1 Tag", 6 | "1 months": "1 Monat", 7 | "1 week": "1 Woche", 8 | "1 year": "1 Jahr", 9 | "2 weeks": "2 Wochen", 10 | "2 years": "2 Jahre", 11 | "3 days": "3 Tage", 12 | "3 months": "3 Monate", 13 | "5 days": "5 Tage", 14 | "6 months": "6 Monate", 15 | "Alias Info": "Wenn Alias-ID gesetzt ist, werden die Daten als diese ID in Datendateien protokolliert", 16 | "Apply lower retention": "Geringere Vorhaltezeit anwenden", 17 | "Are you sure? All data will be dropped.": "Sollen wirklich alle Daten gelöscht werden?", 18 | "Automatic": "Automatisch", 19 | "Block time": "Blockzeit", 20 | "Boolean": "Boolean", 21 | "Buffer Datapoints": "Schreibaktionen zusammenfassen", 22 | "Buffer Flush Interval": "Schreibintervall", 23 | "Confirmation required.": "Bestätigung erforderlich.", 24 | "Counter": "Zähler", 25 | "Custom retention duration (days)": "Benutzerdefinierte Aufbewahrungsdauer (Tage)", 26 | "Custom timeframe": "Benutzerdefinierter Zeitrahmen", 27 | "DB Name": "DB Name", 28 | "DB Type": "DB Typ", 29 | "DB settings:": "DB Einstellungen:", 30 | "DB version": "DB-Version", 31 | "De-bounce interval(ms)": "Protokolliert den Wert nur, wenn er für X ms unverändert bleibt", 32 | "De-bounce time": "Entprellzeit", 33 | "Default settings": "Standardeinstellungen", 34 | "Disable charting optimized logging of skipped values": "Optimierte Protokollierung übersprungener Werte für Diagramme deaktivieren", 35 | "Enable enhanced debug logs for the datapoint": "Erweiterte Debug-Protokolle für den Datenpunkt aktivieren", 36 | "Encrypt": "Datenbankverbindung verschlüsseln", 37 | "Encrypt:": "Verschlüsseln:", 38 | "Enter a number or leave the field empty": "Eine Zahl angeben oder das Feld leer lassen, um die aufgezeichneten Werte nicht einzuschränken", 39 | "Expert Settings": "Experteneinstellungen", 40 | "History adapter settings": "History-Adapter Einstellungen", 41 | "Host": "Server", 42 | "Log the last value again on startup": "Protokollieren Sie den letzten Wert erneut beim Start", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "Eine Verkürzung der Vorhaltezeit ist mit Vorsicht zu genießen: Vergangene Daten, die die Vorhaltezeit überschreiten, gehen verloren.", 44 | "Milliseconds": "Millisekunden", 45 | "Number": "Zahl", 46 | "Number of days to keep the data.": "Anzahl der Tage, um die Daten aufzubewahren.", 47 | "Ok": "Ok", 48 | "Organization": "Organisation", 49 | "Password": "Passwort", 50 | "Password confirm": "Passwort-Wiederholung", 51 | "Please confirm!": "Bitte bestätigen!", 52 | "Port": "Port", 53 | "Reject on SSL errors": "Ablehnen bei SSL-Fehlern", 54 | "Request timeout": "Request Timeout", 55 | "Reset DB": "Alle Daten in Datenbank löschen", 56 | "Round real to": "Runden Sie bei der Abfrage die Zahlen auf", 57 | "SQL history adapter settings": "SQL History Adapter Einstellungen", 58 | "Save last previous value": "Speichere vorherigen Wert", 59 | "Seconds": "Sekunden", 60 | "Send health-check pings to database": "Pings zur Verfügbarkeitsprüfung an die Datenbank senden", 61 | "Start or enable adapter first": "Adapter muss zuerst aktiviert werden", 62 | "Storage retention": "Aufbewahrungsdauer", 63 | "Store as": "Speichern als", 64 | "String": "Text", 65 | "Test connection": "Verbindung testen", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Diese Funktion kann nur für Datenbanken verwendet werden, die leer sind oder bereits mit aktivierter Funktion eingerichtet wurden. Andernfalls kommt es zu Fehlern (siehe Protokolle).", 67 | "Token": "Token", 68 | "Use tags to store metadata information, instead of fields": "Verwende Tags, anstelle von Feldern, um Metadateninformationen zu speichern", 69 | "User": "Benutzer", 70 | "Validate SSL certificate": "SSL-Zertifikat validieren", 71 | "aliasId": "Alias-ID", 72 | "blockTime": "Alle neuen Werte für X ms nach dem letzten protokollierten Wert ignorieren", 73 | "debounce": "Änderungen ignorieren, bis der Wert für X Millisekunden unverändert bleibt", 74 | "health-check help": "Regelmäßige Verfügbarkeits-Anfragen werden an den DB-Server gesendet, um zu überprüfen, ob er noch aktiv ist.", 75 | "ignore values above x": "Ignoriere Werte größer als", 76 | "ignore values below x": "Ignoriere Werte kleiner als", 77 | "ignore values below zero": "Werte unter 0 ignorieren (<0)", 78 | "ignore zero or null values": "Ignoriere 0 oder Nullwerte (==0)", 79 | "keep forever": "keine automatische Löschung", 80 | "log changes interval(s)": "trotzdem gleiche Werte aufzeichnen (Sekunden)", 81 | "log changes minimal delta": "Minimale Differenz zum letzten Wert", 82 | "log changes only": "Nur Änderungen aufzeichnen", 83 | "note": "History Einstellungen müssen für jeden State einzeln gemacht werden, im Tab \"States\" und nur wenn die Adapter Instanz aktiv ist", 84 | "only enter when e.g. a reverse proxy is used": "nur eingeben, wenn ein Reverse-Proxy oder dergleichen verwendet wird", 85 | "path": "Pfad", 86 | "retention": "Storage Vorhaltezeit", 87 | "use 0 to not buffer at all": "Wert 0 schreibt Werte direkt", 88 | "usetags help": "Weitere Informationen sind in der Dokumentation: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields zu finden." 89 | } 90 | -------------------------------------------------------------------------------- /admin/i18n/en/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = disable", 3 | "0 = disable delta check": "0 = disable delta check", 4 | "0 = disabled": "0 = disabled", 5 | "1 day": "1 day", 6 | "1 months": "1 months", 7 | "1 week": "1 week", 8 | "1 year": "1 year", 9 | "2 weeks": "2 weeks", 10 | "2 years": "2 years", 11 | "3 days": "3 days", 12 | "3 months": "3 months", 13 | "5 days": "5 days", 14 | "6 months": "6 months", 15 | "Alias Info": "if Alias-ID is set, the data will be logged as this ID in database", 16 | "Apply lower retention": "Apply lower retention", 17 | "Are you sure? All data will be dropped.": "All data will be dropped. Are you sure?", 18 | "Automatic": "Automatic", 19 | "Block time": "Blocktime", 20 | "Boolean": "Boolean", 21 | "Buffer Datapoints": "Buffer States", 22 | "Buffer Flush Interval": "Buffer Flush Interval", 23 | "Confirmation required.": "Confirmation required.", 24 | "Counter": "Counter", 25 | "Custom retention duration (days)": "Custom retention duration (days)", 26 | "Custom timeframe": "Custom timeframe", 27 | "DB Name": "DB Name", 28 | "DB Type": "DB Type", 29 | "DB settings:": "DB settings:", 30 | "DB version": "DB version", 31 | "De-bounce interval(ms)": "Only logs the value if it stays unchanged for X ms", 32 | "De-bounce time": "Debounce Time", 33 | "Default settings": "Default settings", 34 | "Disable charting optimized logging of skipped values": "Disable charting optimized logging of skipped values", 35 | "Enable enhanced debug logs for the datapoint": "Enable enhanced debug logs for the state", 36 | "Encrypt": "Encrypt Database connection", 37 | "Encrypt:": "Encrypt:", 38 | "Enter a number or leave the field empty": "Enter a number or leave the field empty to not limit the recorded values", 39 | "Expert Settings": "Expert Settings", 40 | "History adapter settings": "History adapter settings", 41 | "Host": "Host", 42 | "Log the last value again on startup": "Log the last value again on startup", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.", 44 | "Milliseconds": "Milliseconds", 45 | "Number": "Number", 46 | "Number of days to keep the data.": "Number of days to keep the data.", 47 | "Ok": "Ok", 48 | "Organization": "Organization", 49 | "Password": "Password", 50 | "Password confirm": "Password confirm", 51 | "Please confirm!": "Please confirm!", 52 | "Port": "Port", 53 | "Reject on SSL errors": "Reject on SSL errors", 54 | "Request timeout": "Request timeout", 55 | "Reset DB": "Reset DB", 56 | "Round real to": "On query round numbers to", 57 | "SQL history adapter settings": "SQL history adapter settings", 58 | "Save last previous value": "Save last previous value", 59 | "Seconds": "Seconds", 60 | "Send health-check pings to database": "Send health-check pings to database", 61 | "Start or enable adapter first": "Start or enable adapter first", 62 | "Storage retention": "Storage retention", 63 | "Store as": "Store as", 64 | "String": "String", 65 | "Test connection": "Test connection", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).", 67 | "Token": "Token", 68 | "Use tags to store metadata information, instead of fields": "Use tags to store metadata information, instead of fields", 69 | "User": "User", 70 | "Validate SSL certificate": "Validate SSL certificate", 71 | "aliasId": "Alias-ID", 72 | "blockTime": "Ignore all new values for X ms after last logged value", 73 | "debounce": "Ignore changes till value stays unchanged for X Milliseconds", 74 | "health-check help": "Regular health checks probes are sent to the DB server to check if it is still alive.", 75 | "ignore values above x": "Ignore values above", 76 | "ignore values below x": "Ignore values below", 77 | "ignore values below zero": "ignore values below zero (<0)", 78 | "ignore zero or null values": "ignore 0 or null values (==0)", 79 | "keep forever": "keep forever", 80 | "log changes interval(s)": "Record the same values (seconds)", 81 | "log changes minimal delta": "Minimum difference from last value", 82 | "log changes only": "Record changes only", 83 | "note": "History settings must be done for every state individually on the tab \"States\" and only if adapter is active", 84 | "only enter when e.g. a reverse proxy is used": "only enter when a reverse proxy or such is used", 85 | "path": "Path", 86 | "retention": "Storage retention", 87 | "use 0 to not buffer at all": "Use 0 to not buffer at all", 88 | "usetags help": "For more information, please refer to the documentation: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } 90 | -------------------------------------------------------------------------------- /admin/i18n/es/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = desactivar", 3 | "0 = disable delta check": "0 = deshabilitar la verificación delta", 4 | "0 = disabled": "0 = deshabilitado", 5 | "1 day": "1 día", 6 | "1 months": "1 mes", 7 | "1 week": "1 semana", 8 | "1 year": "1 año", 9 | "2 weeks": "2 semanas", 10 | "2 years": "2 años", 11 | "3 days": "3 días", 12 | "3 months": "3 meses", 13 | "5 days": "5 dias", 14 | "6 months": "6 meses", 15 | "Alias Info": "si se establece Alias-ID, los datos se registrarán como este ID en la base de datos", 16 | "Apply lower retention": "Aplicar menor retención", 17 | "Are you sure? All data will be dropped.": "¿Estás seguro? Todos los datos serán eliminados.", 18 | "Automatic": "Automático", 19 | "Block time": "hora de bloque", 20 | "Boolean": "booleano", 21 | "Buffer Datapoints": "Puntos de datos del búfer", 22 | "Buffer Flush Interval": "Intervalo de lavado del tampón", 23 | "Confirmation required.": "Confirmación requerida.", 24 | "Counter": "Mostrador", 25 | "Custom retention duration (days)": "Duración de la retención personalizada (días)", 26 | "Custom timeframe": "Marco de tiempo personalizado", 27 | "DB Name": "Nombre de DB", 28 | "DB Type": "Tipo de DB", 29 | "DB settings:": "Configuración de DB:", 30 | "DB version": "Versión DB", 31 | "De-bounce interval(ms)": "Solo registra el valor si permanece sin cambios durante X ms", 32 | "De-bounce time": "Tiempo de rebote", 33 | "Default settings": "Configuración por defecto", 34 | "Disable charting optimized logging of skipped values": "Deshabilitar el registro optimizado de gráficos de valores omitidos", 35 | "Enable enhanced debug logs for the datapoint": "Habilitar registros de depuración mejorados para el punto de datos", 36 | "Encrypt": "Cifrar la conexión de la base de datos", 37 | "Encrypt:": "Encriptar:", 38 | "Enter a number or leave the field empty": "Ingrese un número o deje el campo vacío para no limitar los valores registrados", 39 | "Expert Settings": "Configuración experta", 40 | "History adapter settings": "Configuración del adaptador de historial", 41 | "Host": "Anfitrión", 42 | "Log the last value again on startup": "Registre el último valor nuevamente al inicio", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "Reducir el período de retención debe considerarse con precaución: los datos anteriores que excedan el período de retención se perderán.", 44 | "Milliseconds": "milisegundos", 45 | "Number": "Número", 46 | "Number of days to keep the data.": "Número de días para conservar los datos.", 47 | "Ok": "De acuerdo", 48 | "Organization": "Organización", 49 | "Password": "Contraseña", 50 | "Password confirm": "Contraseña confirmada", 51 | "Please confirm!": "Por favor confirmar", 52 | "Port": "Puerto", 53 | "Reject on SSL errors": "Rechazar en errores de SSL", 54 | "Request timeout": "Pide tiempo fuera", 55 | "Reset DB": "Restablecer DB", 56 | "Round real to": "En consulta números redondos a", 57 | "SQL history adapter settings": "Configuración del adaptador de historial SQL", 58 | "Save last previous value": "Guarde el último valor anterior", 59 | "Seconds": "Segundos", 60 | "Send health-check pings to database": "Enviar pings de verificación de estado a la base de datos", 61 | "Start or enable adapter first": "Comience o habilite el adaptador primero", 62 | "Storage retention": "retención de almacenamiento", 63 | "Store as": "Guardar como", 64 | "String": "Cuerda", 65 | "Test connection": "Conexión de prueba", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Esta función solo se puede utilizar en bases de datos que estén vacías o que ya se hayan configurado con esta función habilitada. De lo contrario, provocará errores (consulte los registros).", 67 | "Token": "Simbólico", 68 | "Use tags to store metadata information, instead of fields": "Utilice etiquetas para almacenar información de metadatos, en lugar de campos", 69 | "User": "Usuario", 70 | "Validate SSL certificate": "Validar certificado SSL", 71 | "aliasId": "ID de alias", 72 | "blockTime": "Ignorar todos los valores nuevos para X ms después del último valor registrado", 73 | "debounce": "Ignorar cambios hasta que el valor permanezca sin cambios durante X milisegundos", 74 | "health-check help": "Se envían sondas de verificación de estado regulares al servidor de base de datos para verificar si todavía está vivo.", 75 | "ignore values above x": "Ignorar los valores anteriores", 76 | "ignore values below x": "Ignorar valores a continuación", 77 | "ignore values below zero": "ignorar valores por debajo de cero (<0)", 78 | "ignore zero or null values": "ignorar 0 o valores nulos (==0)", 79 | "keep forever": "mantener para siempre", 80 | "log changes interval(s)": "Registrar los mismos valores (segundos)", 81 | "log changes minimal delta": "Diferencia mínima del último valor", 82 | "log changes only": "Registrar solo cambios", 83 | "note": "La configuración del historial se debe realizar para cada estado individualmente en la pestaña \"Estados\" y solo si el adaptador está activo", 84 | "only enter when e.g. a reverse proxy is used": "solo ingrese cuando se use un proxy inverso o similar", 85 | "path": "Sendero", 86 | "retention": "Retención de almacenamiento", 87 | "use 0 to not buffer at all": "Use 0 para no almacenar el búfer en absoluto", 88 | "usetags help": "Para obtener más información, consulte la documentación: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/fr/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = disable", 3 | "0 = disable delta check": "0 = disable delta check", 4 | "0 = disabled": "0 = désactivé", 5 | "1 day": "1 day", 6 | "1 months": "1 months", 7 | "1 week": "1 week", 8 | "1 year": "1 year", 9 | "2 weeks": "2 weeks", 10 | "2 years": "2 years", 11 | "3 days": "3 days", 12 | "3 months": "3 months", 13 | "5 days": "5 days", 14 | "6 months": "6 months", 15 | "Alias Info": "si Alias-ID est défini, les données seront enregistrées sous cet ID dans la base de données", 16 | "Apply lower retention": "Appliquer une rétention inférieure", 17 | "Are you sure? All data will be dropped.": "Are you sure? All data will be dropped.", 18 | "Automatic": "Automatique", 19 | "Block time": "Temps de blocage", 20 | "Boolean": "booléen", 21 | "Buffer Datapoints": "Buffer Datapoints", 22 | "Buffer Flush Interval": "Buffer Flush Interval", 23 | "Confirmation required.": "Confirmation requise.", 24 | "Counter": "Compteur", 25 | "Custom retention duration (days)": "Durée de conservation personnalisée (jours)", 26 | "Custom timeframe": "Délai personnalisé", 27 | "DB Name": "DB Name", 28 | "DB Type": "DB Type", 29 | "DB settings:": "DB settings:", 30 | "DB version": "Version de la base de données", 31 | "De-bounce interval(ms)": "Enregistre uniquement la valeur si elle reste inchangée pendant X ms", 32 | "De-bounce time": "Temps de rebond", 33 | "Default settings": "Default settings", 34 | "Disable charting optimized logging of skipped values": "Désactiver la journalisation optimisée des graphiques des valeurs ignorées", 35 | "Enable enhanced debug logs for the datapoint": "Activer les journaux de débogage améliorés pour le point de données", 36 | "Encrypt": "Crypter la connexion à la base de données", 37 | "Encrypt:": "Encrypt:", 38 | "Enter a number or leave the field empty": "Entrez un nombre ou laissez le champ vide pour ne pas limiter les valeurs enregistrées", 39 | "Expert Settings": "Paramètres experts", 40 | "History adapter settings": "History adapter settings", 41 | "Host": "Host", 42 | "Log the last value again on startup": "Enregistrez à nouveau la dernière valeur au démarrage", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "La réduction de la période de conservation doit être envisagée avec prudence : les données antérieures dépassant la période de conservation seront perdues.", 44 | "Milliseconds": "Millisecondes", 45 | "Number": "Numéro", 46 | "Number of days to keep the data.": "Nombre de jours de conservation des données.", 47 | "Ok": "Ok", 48 | "Organization": "Organisation", 49 | "Password": "Password", 50 | "Password confirm": "Password confirm", 51 | "Please confirm!": "Veuillez confirmer", 52 | "Port": "Port", 53 | "Reject on SSL errors": "Rejeter sur les erreurs SSL", 54 | "Request timeout": "Délai d'expiration de la demande", 55 | "Reset DB": "Reset DB", 56 | "Round real to": "Sur requête arrondir les nombres à", 57 | "SQL history adapter settings": "SQL history adapter settings", 58 | "Save last previous value": "Save last previous value", 59 | "Seconds": "Seconds", 60 | "Send health-check pings to database": "Envoyer des pings de vérification d'état à la base de données", 61 | "Start or enable adapter first": "Start or enable adapter first", 62 | "Storage retention": "Rétention de stockage", 63 | "Store as": "Stocker comme", 64 | "String": "Corde", 65 | "Test connection": "Test connection", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Cette fonctionnalité ne peut être utilisée que sur des bases de données vides ou déjà configurées avec cette fonctionnalité activée. Sinon, cela provoquera des erreurs (voir les journaux).", 67 | "Token": "Jeton", 68 | "Use tags to store metadata information, instead of fields": "Utilisez des balises pour stocker les informations de métadonnées, au lieu de champs", 69 | "User": "User", 70 | "Validate SSL certificate": "Valider le certificat SSL", 71 | "aliasId": "Alias-ID", 72 | "blockTime": "Ignorer toutes les nouvelles valeurs pendant X ms après la dernière valeur enregistrée", 73 | "debounce": "Ignorer les modifications jusqu'à ce que la valeur reste inchangée pour X millisecondes", 74 | "health-check help": "Des vérifications de santé régulières sont envoyées au serveur de base de données pour vérifier s'il est toujours actif.", 75 | "ignore values above x": "Ignorer les valeurs ci-dessus", 76 | "ignore values below x": "Ignorer les valeurs ci-dessous", 77 | "ignore values below zero": "ignorer les valeurs inférieures à zéro (<0)", 78 | "ignore zero or null values": "ignorer les valeurs 0 ou nulles (==0)", 79 | "keep forever": "keep forever", 80 | "log changes interval(s)": "Enregistrer les mêmes valeurs (secondes)", 81 | "log changes minimal delta": "Différence minimale par rapport à la dernière valeur", 82 | "log changes only": "Enregistrer uniquement les modifications", 83 | "note": "History settings must be done for every state individually on the tab \"States\" and only if adapter is active", 84 | "only enter when e.g. a reverse proxy is used": "entrer uniquement lorsqu'un proxy inverse ou similaire est utilisé", 85 | "path": "Chemin", 86 | "retention": "Storage retention", 87 | "use 0 to not buffer at all": "Use 0 to not buffer at all", 88 | "usetags help": "Pour plus d'informations, veuillez vous référer à la documentation : https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/it/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = disabilita", 3 | "0 = disable delta check": "0 = disabilita il controllo delta", 4 | "0 = disabled": "0 = disabilitato", 5 | "1 day": "1 giorno", 6 | "1 months": "1 mese", 7 | "1 week": "1 settimana", 8 | "1 year": "1 anno", 9 | "2 weeks": "2 settimane", 10 | "2 years": "2 anni", 11 | "3 days": "3 giorni", 12 | "3 months": "3 mesi", 13 | "5 days": "5 giorni", 14 | "6 months": "6 mesi", 15 | "Alias Info": "se è impostato Alias-ID, i dati verranno registrati come questo ID nel database", 16 | "Apply lower retention": "Applicare una ritenzione inferiore", 17 | "Are you sure? All data will be dropped.": "Sei sicuro? Tutti i dati verranno eliminati.", 18 | "Automatic": "Automatico", 19 | "Block time": "Blocktime", 20 | "Boolean": "booleano", 21 | "Buffer Datapoints": "Buffer puntiforme", 22 | "Buffer Flush Interval": "Intervallo di flussaggio del tampone", 23 | "Confirmation required.": "Conferma richiesta.", 24 | "Counter": "Contatore", 25 | "Custom retention duration (days)": "Durata di conservazione personalizzata (giorni)", 26 | "Custom timeframe": "Tempi personalizzati", 27 | "DB Name": "Nome DB", 28 | "DB Type": "Tipo di DB", 29 | "DB settings:": "Impostazioni DB:", 30 | "DB version": "Versione DB", 31 | "De-bounce interval(ms)": "Registra il valore solo se rimane invariato per X ms", 32 | "De-bounce time": "Tempo di rimbalzo", 33 | "Default settings": "Impostazioni predefinite", 34 | "Disable charting optimized logging of skipped values": "Disabilita la registrazione ottimizzata per la creazione di grafici dei valori ignorati", 35 | "Enable enhanced debug logs for the datapoint": "Abilita i log di debug avanzati per il punto dati", 36 | "Encrypt": "Crittografa la connessione al database", 37 | "Encrypt:": "Encrypt:", 38 | "Enter a number or leave the field empty": "Immettere un numero o lasciare il campo vuoto per non limitare i valori registrati", 39 | "Expert Settings": "Impostazioni avanzate", 40 | "History adapter settings": "Impostazioni della scheda Cronologia", 41 | "Host": "Ospite", 42 | "Log the last value again on startup": "Registra di nuovo l'ultimo valore all'avvio", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "La riduzione del periodo di conservazione deve essere considerata con cautela: i dati passati che superano il periodo di conservazione andranno persi.", 44 | "Milliseconds": "Millisecondi", 45 | "Number": "Numero", 46 | "Number of days to keep the data.": "Numero di giorni di conservazione dei dati.", 47 | "Ok": "Ok", 48 | "Organization": "Organizzazione", 49 | "Password": "Parola d'ordine", 50 | "Password confirm": "Conferma la password", 51 | "Please confirm!": "Si prega di confermare", 52 | "Port": "Porta", 53 | "Reject on SSL errors": "Rifiuta errori SSL", 54 | "Request timeout": "Richiedi timeout", 55 | "Reset DB": "Ripristina DB", 56 | "Round real to": "Su interrogazione arrotondare i numeri a", 57 | "SQL history adapter settings": "Impostazioni della scheda cronologia SQL", 58 | "Save last previous value": "Salva l'ultimo valore precedente", 59 | "Seconds": "secondi", 60 | "Send health-check pings to database": "Invia ping di controllo dello stato al database", 61 | "Start or enable adapter first": "Inizia o abilita prima l'adattatore", 62 | "Storage retention": "Conservazione della memoria", 63 | "Store as": "Conserva come", 64 | "String": "Corda", 65 | "Test connection": "Connessione di prova", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Questa funzione può essere utilizzata solo su database vuoti o già configurati con questa funzione abilitata. Altrimenti causerà errori (vedi log).", 67 | "Token": "Gettone", 68 | "Use tags to store metadata information, instead of fields": "Usa i tag per memorizzare le informazioni sui metadati, invece dei campi", 69 | "User": "Utente", 70 | "Validate SSL certificate": "Convalida il certificato SSL", 71 | "aliasId": "ID alias", 72 | "blockTime": "Ignora tutti i nuovi valori per X ms dopo l'ultimo valore registrato", 73 | "debounce": "Ignora le modifiche fino a quando il valore rimane invariato per X Milliseconds", 74 | "health-check help": "Controlli di integrità regolari vengono inviati al server DB per verificare se è ancora attivo.", 75 | "ignore values above x": "Ignora i valori sopra", 76 | "ignore values below x": "Ignora i valori sottostanti", 77 | "ignore values below zero": "ignora i valori inferiori a zero (<0)", 78 | "ignore zero or null values": "ignora 0 o valori nulli (==0)", 79 | "keep forever": "tienilo per sempre", 80 | "log changes interval(s)": "Registra gli stessi valori (secondi)", 81 | "log changes minimal delta": "Differenza minima dall'ultimo valore", 82 | "log changes only": "Registra solo le modifiche", 83 | "note": "Le impostazioni della cronologia devono essere eseguite singolarmente per ogni stato nella scheda \"Stati\" e solo se l'adattatore è attivo", 84 | "only enter when e.g. a reverse proxy is used": "immettere solo quando viene utilizzato un proxy inverso o simile", 85 | "path": "Il percorso", 86 | "retention": "Conservazione di memoria", 87 | "use 0 to not buffer at all": "Utilizzare 0 per non bufferizzare affatto", 88 | "usetags help": "Per ulteriori informazioni, fare riferimento alla documentazione: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/nl/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = uitschakelen", 3 | "0 = disable delta check": "0 = delta-controle uitschakelen", 4 | "0 = disabled": "0 = uitgeschakeld", 5 | "1 day": "1 dag", 6 | "1 months": "1 maanden", 7 | "1 week": "1 week", 8 | "1 year": "1 jaar", 9 | "2 weeks": "2 weken", 10 | "2 years": "2 jaar", 11 | "3 days": "3 dagen", 12 | "3 months": "3 maanden", 13 | "5 days": "5 dagen", 14 | "6 months": "6 maanden", 15 | "Alias Info": "als Alias-ID is ingesteld, worden de gegevens als deze ID in de database gelogd", 16 | "Apply lower retention": "Lagere retentie toepassen", 17 | "Are you sure? All data will be dropped.": "Weet je het zeker? Alle gegevens worden verwijderd.", 18 | "Automatic": "automatisch", 19 | "Block time": "Bloktijd", 20 | "Boolean": "Booleaans", 21 | "Buffer Datapoints": "Buffer-datapunten", 22 | "Buffer Flush Interval": "Buffer Flush Interval", 23 | "Confirmation required.": "Bevestiging vereist.", 24 | "Counter": "Balie", 25 | "Custom retention duration (days)": "Aangepaste bewaarduur (dagen)", 26 | "Custom timeframe": "Aangepast tijdsbestek", 27 | "DB Name": "DB-naam", 28 | "DB Type": "DB Type", 29 | "DB settings:": "DB-instellingen:", 30 | "DB version": "DB-versie", 31 | "De-bounce interval(ms)": "Registreert de waarde alleen als deze gedurende X ms . ongewijzigd blijft", 32 | "De-bounce time": "De-bounce tijd", 33 | "Default settings": "Standaard instellingen", 34 | "Disable charting optimized logging of skipped values": "Geoptimaliseerde registratie van overgeslagen waarden in grafieken uitschakelen", 35 | "Enable enhanced debug logs for the datapoint": "Verbeterde foutopsporingslogboeken voor het datapunt inschakelen", 36 | "Encrypt": "Databaseverbinding versleutelen", 37 | "Encrypt:": "versleutelen:", 38 | "Enter a number or leave the field empty": "Voer een getal in of laat het veld leeg om de geregistreerde waarden niet te beperken", 39 | "Expert Settings": "Expertinstellingen", 40 | "History adapter settings": "Geschiedenis adapter instellingen", 41 | "Host": "gastheer", 42 | "Log the last value again on startup": "Log de laatste waarde opnieuw bij het opstarten", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "Het verlagen van de bewaarperiode moet met de nodige voorzichtigheid worden overwogen: gegevens uit het verleden die de bewaarperiode overschrijden, gaan verloren.", 44 | "Milliseconds": "milliseconden", 45 | "Number": "Nummer", 46 | "Number of days to keep the data.": "Aantal dagen om de gegevens te bewaren.", 47 | "Ok": "OK", 48 | "Organization": "Organisatie", 49 | "Password": "Wachtwoord", 50 | "Password confirm": "Wachtwoord bevestigen", 51 | "Please confirm!": "Bevestig alstublieft", 52 | "Port": "Haven", 53 | "Reject on SSL errors": "Weigeren bij SSL-fouten", 54 | "Request timeout": "Verzoek time-out", 55 | "Reset DB": "Stel DB opnieuw in", 56 | "Round real to": "Op query ronde getallen naar", 57 | "SQL history adapter settings": "Instellingen voor SQL-geschiedenisadapter", 58 | "Save last previous value": "Sla de laatste vorige waarde op", 59 | "Seconds": "seconden", 60 | "Send health-check pings to database": "Stuur gezondheidscheck pings naar database", 61 | "Start or enable adapter first": "Start of schakel eerst de adapter in", 62 | "Storage retention": "Opslagbehoud", 63 | "Store as": "Opslaan als", 64 | "String": "Draad", 65 | "Test connection": "Test verbinding", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Deze functie kan alleen worden gebruikt op databases die leeg zijn of al zijn ingesteld met deze functie ingeschakeld. Anders veroorzaakt het fouten (zie logs).", 67 | "Token": "Teken", 68 | "Use tags to store metadata information, instead of fields": "Gebruik tags om metadata-informatie op te slaan in plaats van velden", 69 | "User": "Gebruiker", 70 | "Validate SSL certificate": "SSL-certificaat valideren", 71 | "aliasId": "Alias-ID", 72 | "blockTime": "Negeer alle nieuwe waarden voor X ms na de laatste gelogde waarde", 73 | "debounce": "Wijzigingen negeren totdat waarde ongewijzigd blijft voor X Milliseconds", 74 | "health-check help": "Regelmatige gezondheidscontroles worden naar de DB-server gestuurd om te controleren of deze nog in leven is.", 75 | "ignore values above x": "Bovenstaande waarden negeren", 76 | "ignore values below x": "Negeer onderstaande waarden", 77 | "ignore values below zero": "negeer waarden onder nul (<0)", 78 | "ignore zero or null values": "negeer 0 of null-waarden (==0)", 79 | "keep forever": "blijf voor altijd", 80 | "log changes interval(s)": "Noteer dezelfde waarden (seconden)", 81 | "log changes minimal delta": "Minimaal verschil met laatste waarde", 82 | "log changes only": "Alleen wijzigingen opnemen", 83 | "note": "Geschiedenisinstellingen moeten voor elke afzonderlijke status worden uitgevoerd op het tabblad \"Staten\" en alleen als de adapter actief is", 84 | "only enter when e.g. a reverse proxy is used": "alleen invoeren als een reverse proxy of iets dergelijks wordt gebruikt", 85 | "path": "Pad", 86 | "retention": "Opslag retentie", 87 | "use 0 to not buffer at all": "Gebruik 0 om helemaal niet te bufferen", 88 | "usetags help": "Raadpleeg de documentatie voor meer informatie: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/pl/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = wyłącz", 3 | "0 = disable delta check": "0 = wyłącz kontrolę delta", 4 | "0 = disabled": "0 = wyłączone", 5 | "1 day": "1 dzień", 6 | "1 months": "1 miesiąc", 7 | "1 week": "1 tydzień", 8 | "1 year": "1 rok", 9 | "2 weeks": "2 tygodnie", 10 | "2 years": "2 lata", 11 | "3 days": "3 dni", 12 | "3 months": "3 miesiące", 13 | "5 days": "5 dni", 14 | "6 months": "6 miesięcy", 15 | "Alias Info": "jeśli ustawiony jest Alias-ID, dane będą rejestrowane jako ten identyfikator w bazie danych", 16 | "Apply lower retention": "Zastosuj mniejszą retencję", 17 | "Are you sure? All data will be dropped.": "Jesteś pewny? Wszystkie dane zostaną usunięte.", 18 | "Automatic": "Automatyczny", 19 | "Block time": "Czas blokady", 20 | "Boolean": "Boole'a", 21 | "Buffer Datapoints": "Bufory Datapoints", 22 | "Buffer Flush Interval": "Przerwa między buforami", 23 | "Confirmation required.": "Wymagane Potwierdzenie.", 24 | "Counter": "Lada", 25 | "Custom retention duration (days)": "Niestandardowy czas przechowywania (dni)", 26 | "Custom timeframe": "Niestandardowe ramy czasowe", 27 | "DB Name": "Nazwa DB", 28 | "DB Type": "Typ DB", 29 | "DB settings:": "Ustawienia DB:", 30 | "DB version": "Wersja DB", 31 | "De-bounce interval(ms)": "Rejestruje wartość tylko wtedy, gdy pozostaje niezmieniona przez X ms", 32 | "De-bounce time": "Czas odbicia", 33 | "Default settings": "Ustawienia domyślne", 34 | "Disable charting optimized logging of skipped values": "Wyłącz zoptymalizowane rejestrowanie pominiętych wartości na wykresach", 35 | "Enable enhanced debug logs for the datapoint": "Włącz rozszerzone dzienniki debugowania dla punktu danych", 36 | "Encrypt": "Szyfruj połączenie z bazą danych", 37 | "Encrypt:": "Szyfruj:", 38 | "Enter a number or leave the field empty": "Wpisz liczbę lub pozostaw puste pole, aby nie ograniczać rejestrowanych wartości", 39 | "Expert Settings": "Ustawienia eksperckie", 40 | "History adapter settings": "Ustawienia adaptera historii", 41 | "Host": "Gospodarz", 42 | "Log the last value again on startup": "Zarejestruj ostatnią wartość ponownie podczas uruchamiania", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "Obniżenie okresu przechowywania należy rozważać z ostrożnością: Przeszłe dane przekraczające okres przechowywania zostaną utracone.", 44 | "Milliseconds": "Milisekundy", 45 | "Number": "Numer", 46 | "Number of days to keep the data.": "Liczba dni przechowywania danych.", 47 | "Ok": "Ok", 48 | "Organization": "Organizacja", 49 | "Password": "Hasło", 50 | "Password confirm": "Potwierdź hasło", 51 | "Please confirm!": "Proszę potwierdzić", 52 | "Port": "Port", 53 | "Reject on SSL errors": "Odrzuć błędy SSL", 54 | "Request timeout": "Limit czasu żądania", 55 | "Reset DB": "Zresetuj DB", 56 | "Round real to": "Na zapytanie okrągłe liczby do", 57 | "SQL history adapter settings": "Ustawienia adaptera historii SQL", 58 | "Save last previous value": "Zapisz ostatnią poprzednią wartość", 59 | "Seconds": "sekundy", 60 | "Send health-check pings to database": "Wysyłaj pingi sprawdzające kondycję do bazy danych", 61 | "Start or enable adapter first": "Najpierw włącz lub włącz adapter", 62 | "Storage retention": "Przechowywanie pamięci", 63 | "Store as": "Przechowuj jako", 64 | "String": "Strunowy", 65 | "Test connection": "Testuj połączenie", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Ta funkcja może być używana tylko w przypadku baz danych, które są puste lub zostały już skonfigurowane z włączoną tą funkcją. W przeciwnym razie spowoduje to błędy (patrz logi).", 67 | "Token": "Znak", 68 | "Use tags to store metadata information, instead of fields": "Używaj tagów do przechowywania informacji o metadanych zamiast pól", 69 | "User": "Użytkownik", 70 | "Validate SSL certificate": "Zweryfikuj certyfikat SSL", 71 | "aliasId": "Alias-ID", 72 | "blockTime": "Ignoruj ​​wszystkie nowe wartości przez X ms po ostatniej zarejestrowanej wartości", 73 | "debounce": "Zignoruj ​​zmiany, aż wartość pozostanie niezmieniona przez X Milliseconds", 74 | "health-check help": "Regularne sondy sprawdzające kondycję są wysyłane do serwera bazy danych w celu sprawdzenia, czy nadal działa.", 75 | "ignore values above x": "Zignoruj ​​wartości powyżej", 76 | "ignore values below x": "Zignoruj ​​wartości poniżej", 77 | "ignore values below zero": "zignoruj ​​wartości poniżej zera (<0)", 78 | "ignore zero or null values": "zignoruj ​​wartości 0 lub null (==0)", 79 | "keep forever": "zachowaj na zawsze", 80 | "log changes interval(s)": "Zapisz te same wartości (sekundy)", 81 | "log changes minimal delta": "Minimalna różnica od ostatniej wartości", 82 | "log changes only": "Nagrywaj tylko zmiany", 83 | "note": "Ustawienia historii muszą być wykonane dla każdego stanu indywidualnie na karcie \"Stany\" i tylko wtedy, gdy adapter jest aktywny", 84 | "only enter when e.g. a reverse proxy is used": "wprowadź tylko wtedy, gdy używane jest odwrotne proxy lub takie", 85 | "path": "Ścieżka", 86 | "retention": "Przechowywanie danych", 87 | "use 0 to not buffer at all": "Użyj 0, aby w ogóle nie buforować", 88 | "usetags help": "Więcej informacji można znaleźć w dokumentacji: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/pt/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = desativar", 3 | "0 = disable delta check": "0 = desativar o cheque delta", 4 | "0 = disabled": "0 = desativado", 5 | "1 day": "1 dia", 6 | "1 months": "1 mês", 7 | "1 week": "1 semana", 8 | "1 year": "1 ano", 9 | "2 weeks": "2 semanas", 10 | "2 years": "2 anos", 11 | "3 days": "3 dias", 12 | "3 months": "3 meses", 13 | "5 days": "5 dias", 14 | "6 months": "6 meses", 15 | "Alias Info": "se Alias-ID estiver definido, os dados serão registrados como este ID no banco de dados", 16 | "Apply lower retention": "Aplicar menor retenção", 17 | "Are you sure? All data will be dropped.": "Você tem certeza? Todos os dados serão descartados.", 18 | "Automatic": "Automático", 19 | "Block time": "Blocktime", 20 | "Boolean": "boleano", 21 | "Buffer Datapoints": "Datapoints do buffer", 22 | "Buffer Flush Interval": "Intervalo de descarga do buffer", 23 | "Confirmation required.": "Necessária confirmação.", 24 | "Counter": "Contador", 25 | "Custom retention duration (days)": "Duração da retenção personalizada (dias)", 26 | "Custom timeframe": "Período personalizado", 27 | "DB Name": "Nome do banco de dados", 28 | "DB Type": "Tipo de banco de dados", 29 | "DB settings:": "Configurações de banco de dados:", 30 | "DB version": "Versão DB", 31 | "De-bounce interval(ms)": "Apenas registra o valor se permanecer inalterado por X ms", 32 | "De-bounce time": "Tempo de recuperação", 33 | "Default settings": "Configurações padrão", 34 | "Disable charting optimized logging of skipped values": "Desativar o registro otimizado de gráficos de valores ignorados", 35 | "Enable enhanced debug logs for the datapoint": "Habilitar logs de depuração aprimorados para o ponto de dados", 36 | "Encrypt": "Criptografar conexão de banco de dados", 37 | "Encrypt:": "Criptografar:", 38 | "Enter a number or leave the field empty": "Digite um número ou deixe o campo vazio para não limitar os valores registrados", 39 | "Expert Settings": "Configurações para especialistas", 40 | "History adapter settings": "Configurações do adaptador de histórico", 41 | "Host": "Hospedeiro", 42 | "Log the last value again on startup": "Registre o último valor novamente na inicialização", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "A redução do período de retenção deve ser considerada com cautela: os dados anteriores que excederem o período de retenção serão perdidos.", 44 | "Milliseconds": "Milissegundos", 45 | "Number": "Número", 46 | "Number of days to keep the data.": "Número de dias para manter os dados.", 47 | "Ok": "Ok", 48 | "Organization": "Organização", 49 | "Password": "Senha", 50 | "Password confirm": "Confirmação de senha", 51 | "Please confirm!": "Por favor confirme", 52 | "Port": "Porta", 53 | "Reject on SSL errors": "Rejeitar em erros de SSL", 54 | "Request timeout": "Solicitar tempo limite", 55 | "Reset DB": "Redefinir DB", 56 | "Round real to": "Na consulta arredondar os números para", 57 | "SQL history adapter settings": "Configurações do adaptador de histórico SQL", 58 | "Save last previous value": "Salvar o último valor anterior", 59 | "Seconds": "Segundos", 60 | "Send health-check pings to database": "Envie pings de verificação de integridade para o banco de dados", 61 | "Start or enable adapter first": "Inicie ou ative o adaptador primeiro", 62 | "Storage retention": "Retenção de armazenamento", 63 | "Store as": "Armazenar como", 64 | "String": "Fragmento", 65 | "Test connection": "Conexão de teste", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Este recurso só pode ser usado em bancos de dados que estão vazios ou já foram configurados com este recurso habilitado. Caso contrário, causará erros (consulte os logs).", 67 | "Token": "Símbolo", 68 | "Use tags to store metadata information, instead of fields": "Use tags para armazenar informações de metadados, em vez de campos", 69 | "User": "Do utilizador", 70 | "Validate SSL certificate": "Validar certificado SSL", 71 | "aliasId": "Alias-ID", 72 | "blockTime": "Ignore todos os novos valores por X ms após o último valor registrado", 73 | "debounce": "Ignorar alterações até que o valor permaneça inalterado por X Milissegundos", 74 | "health-check help": "Sondagens de verificações regulares de integridade são enviadas ao servidor de banco de dados para verificar se ele ainda está ativo.", 75 | "ignore values above x": "Ignorar valores acima", 76 | "ignore values below x": "Ignorar valores abaixo", 77 | "ignore values below zero": "ignorar valores abaixo de zero (<0)", 78 | "ignore zero or null values": "ignore 0 ou valores nulos (==0)", 79 | "keep forever": "mantenha para sempre", 80 | "log changes interval(s)": "Grave os mesmos valores (segundos)", 81 | "log changes minimal delta": "Diferença mínima do último valor", 82 | "log changes only": "Registrar apenas alterações", 83 | "note": "As configurações de histórico devem ser feitas para cada estado individual na guia \"Estados\" e somente se o adaptador estiver ativo", 84 | "only enter when e.g. a reverse proxy is used": "só entrar quando um proxy reverso ou tal for usado", 85 | "path": "Caminho", 86 | "retention": "Retenção de armazenamento", 87 | "use 0 to not buffer at all": "Use 0 para não buffer no total", 88 | "usetags help": "Para obter mais informações, consulte a documentação: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/ru/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = не активно", 3 | "0 = disable delta check": "0 = не проверять минимальное изменение", 4 | "0 = disabled": "0 = отключено", 5 | "1 day": "1 день", 6 | "1 months": "1 месяц", 7 | "1 week": "1 неделя", 8 | "1 year": "1 год", 9 | "2 weeks": "2 недели", 10 | "2 years": "2 года", 11 | "3 days": "3 дня", 12 | "3 months": "3 месяца", 13 | "5 days": "5 дней", 14 | "6 months": "6 месяцев", 15 | "Alias Info": "если установлен Alias-ID, данные будут зарегистрированы как этот идентификатор в базе данных", 16 | "Apply lower retention": "Применить более низкое удержание", 17 | "Are you sure? All data will be dropped.": "Вы уверены? Все данные в базе будут удалены. ", 18 | "Automatic": "автоматический", 19 | "Block time": "Блокировка", 20 | "Boolean": "логический", 21 | "Buffer Datapoints": "Собирать значения для записи", 22 | "Buffer Flush Interval": "Интервал записи значений в базу из RAM", 23 | "Confirmation required.": "Требуется подтверждение.", 24 | "Counter": "Прилавок", 25 | "Custom retention duration (days)": "Пользовательский срок хранения (дни)", 26 | "Custom timeframe": "Пользовательский таймфрейм", 27 | "DB Name": "Имя базы", 28 | "DB Type": "Тип базы", 29 | "DB settings:": "Настройки базы:", 30 | "DB version": "Версия БД", 31 | "De-bounce interval(ms)": "Регистрирует значение только в том случае, если оно остается неизменным в течение X мс.", 32 | "De-bounce time": "Интервал игнорирования дребезга", 33 | "Default settings": "Настройки по умолчанию для состояний", 34 | "Disable charting optimized logging of skipped values": "Отключить оптимизированную регистрацию пропущенных значений для построения диаграмм", 35 | "Enable enhanced debug logs for the datapoint": "Включить расширенные журналы отладки для точки данных", 36 | "Encrypt": "Зашифровать соединение с базой данных", 37 | "Encrypt:": "Шифрование:", 38 | "Enter a number or leave the field empty": "Введите число или оставьте поле пустым, чтобы не ограничивать записываемые значения", 39 | "Expert Settings": "Экспертные настройки", 40 | "History adapter settings": "Настройки драйвера history", 41 | "Host": "Хост", 42 | "Log the last value again on startup": "Снова запишите последнее значение при запуске", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "К уменьшению срока хранения следует подходить с осторожностью: прошлые данные, превышающие срок хранения, будут потеряны.", 44 | "Milliseconds": "Миллисекунды", 45 | "Number": "Количество", 46 | "Number of days to keep the data.": "Количество дней хранения данных.", 47 | "Ok": "Ok", 48 | "Organization": "Организация", 49 | "Password": "Пароль", 50 | "Password confirm": "Подтверждение пароля", 51 | "Please confirm!": "Пожалуйста подтвердите", 52 | "Port": "Порт", 53 | "Reject on SSL errors": "Отклонить при ошибках SSL", 54 | "Request timeout": "Время ожидания запроса", 55 | "Reset DB": "Очистить базу", 56 | "Round real to": "По запросу округлить числа до", 57 | "SQL history adapter settings": "Настройки профайлера в SQL базу данных", 58 | "Save last previous value": "Сохранять предыдущее значение", 59 | "Seconds": "секунд", 60 | "Send health-check pings to database": "Отправлять эхо-запросы проверки работоспособности в базу данных", 61 | "Start or enable adapter first": "Сначала надо запустить или активировать драйвер", 62 | "Storage retention": "Сохранение хранения", 63 | "Store as": "Сохранить как", 64 | "String": "Нить", 65 | "Test connection": "Проверить соединение", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Эту функцию можно использовать только с пустыми базами данных, которые уже были настроены с включенной этой функцией. В противном случае это вызовет ошибки (см. Логи).", 67 | "Token": "Токен", 68 | "Use tags to store metadata information, instead of fields": "Используйте теги для хранения информации метаданных вместо полей", 69 | "User": "Пользователь", 70 | "Validate SSL certificate": "Проверить SSL-сертификат", 71 | "aliasId": "Псевдоним-ID", 72 | "blockTime": "Игнорировать все новые значения для X мс после последнего зарегистрированного значения", 73 | "debounce": "Игнорировать изменения до тех пор, пока не будет постоянного значения в течение X миллисекунд", 74 | "health-check help": "На сервер БД отправляются регулярные зонды проверки работоспособности, чтобы проверить, жив ли он.", 75 | "ignore values above x": "Игнорировать значения выше", 76 | "ignore values below x": "Игнорировать значения ниже", 77 | "ignore values below zero": "игнорировать значения ниже нуля (<0)", 78 | "ignore zero or null values": "игнорировать 0 или нулевые значения (==0)", 79 | "keep forever": "хранить вечно", 80 | "log changes interval(s)": "Запишите те же значения (секунды)", 81 | "log changes minimal delta": "Минимальная разница от последнего значения", 82 | "log changes only": "Записывать только изменения", 83 | "note": "Настройки history делаются для каждого состояния отдельно в закладке \"Состояния\" и только, когда инстанция активирована", 84 | "only enter when e.g. a reverse proxy is used": "входить только тогда, когда используется обратный прокси-сервер или что-то подобное", 85 | "path": "Дорожка", 86 | "retention": "Время хранения в базе", 87 | "use 0 to not buffer at all": "Для деактвации буферизации введите 0", 88 | "usetags help": "Для получения дополнительной информации обратитесь к документации: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/uk/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = вимкнено", 3 | "0 = disable delta check": "0 = вимкнути дельта-перевірку", 4 | "0 = disabled": "0 = вимкнено", 5 | "1 day": "1 день", 6 | "1 months": "1 місяць", 7 | "1 week": "1 тиждень", 8 | "1 year": "1 рік", 9 | "2 weeks": "2 тижні", 10 | "2 years": "2 роки", 11 | "3 days": "3 дні", 12 | "3 months": "3 місяці", 13 | "5 days": "5 днів", 14 | "6 months": "6 місяців", 15 | "Alias Info": "якщо встановлено Alias-ID, дані будуть зареєстровані як цей ідентифікатор у базі даних", 16 | "Apply lower retention": "Застосувати нижче утримання", 17 | "Are you sure? All data will be dropped.": "Усі дані буде видалено. Ти впевнений?", 18 | "Automatic": "Автоматичний", 19 | "Block time": "Час блоку", 20 | "Boolean": "Логічний", 21 | "Buffer Datapoints": "Буферні стани", 22 | "Buffer Flush Interval": "Інтервал промивання буфера", 23 | "Confirmation required.": "Потрібне підтвердження.", 24 | "Counter": "Лічильник", 25 | "Custom retention duration (days)": "Спеціальна тривалість зберігання (дні)", 26 | "Custom timeframe": "Спеціальні часові рамки", 27 | "DB Name": "Назва БД", 28 | "DB Type": "Тип БД", 29 | "DB settings:": "Налаштування БД:", 30 | "DB version": "версія БД", 31 | "De-bounce interval(ms)": "Записує значення, лише якщо воно залишається незмінним протягом X мс", 32 | "De-bounce time": "Час відбою", 33 | "Default settings": "Налаштування за замовчуванням", 34 | "Disable charting optimized logging of skipped values": "Вимкнути оптимізоване ведення журналу пропущених значень", 35 | "Enable enhanced debug logs for the datapoint": "Увімкнути розширені журнали налагодження для стану", 36 | "Encrypt": "Шифрувати підключення до бази даних", 37 | "Encrypt:": "Шифрувати:", 38 | "Enter a number or leave the field empty": "Введіть число або залиште поле порожнім, щоб не обмежувати записані значення", 39 | "Expert Settings": "Експертні налаштування", 40 | "History adapter settings": "Налаштування адаптера історії", 41 | "Host": "Хост", 42 | "Log the last value again on startup": "Зареєструйте останнє значення знову під час запуску", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "Зменшення терміну зберігання слід розглядати з обережністю: минулі дані, які перевищують термін зберігання, будуть втрачені.", 44 | "Milliseconds": "мілісекунди", 45 | "Number": "Номер", 46 | "Number of days to keep the data.": "Кількість днів для зберігання даних.", 47 | "Ok": "В порядку", 48 | "Organization": "організація", 49 | "Password": "Пароль", 50 | "Password confirm": "Підтвердження пароля", 51 | "Please confirm!": "Будь-ласка підтвердіть!", 52 | "Port": "Порт", 53 | "Reject on SSL errors": "Відхилити через помилки SSL", 54 | "Request timeout": "Час очікування запиту минув", 55 | "Reset DB": "Скинути БД", 56 | "Round real to": "На запит круглі числа до", 57 | "SQL history adapter settings": "Параметри адаптера історії SQL", 58 | "Save last previous value": "Зберегти останнє попереднє значення", 59 | "Seconds": "секунд", 60 | "Send health-check pings to database": "Надсилати запити перевірки справності до бази даних", 61 | "Start or enable adapter first": "Спочатку запустіть або ввімкніть адаптер", 62 | "Storage retention": "Зберігання", 63 | "Store as": "Зберігати як", 64 | "String": "Рядок", 65 | "Test connection": "Тестове підключення", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "Цю функцію можна використовувати лише в базах даних, які порожні або вже налаштовані з увімкненою цією функцією. Інакше це призведе до помилок (див. журнали).", 67 | "Token": "Токен", 68 | "Use tags to store metadata information, instead of fields": "Використовуйте теги для зберігання інформації метаданих замість полів", 69 | "User": "Користувач", 70 | "Validate SSL certificate": "Перевірте сертифікат SSL", 71 | "aliasId": "Псевдонім-ID", 72 | "blockTime": "Ігнорувати всі нові значення протягом X мс після останнього зареєстрованого значення", 73 | "debounce": "Ігнорувати зміни, доки значення не залишиться незмінним протягом X мілісекунд", 74 | "health-check help": "Регулярні перевірки справності надсилаються на сервер БД, щоб перевірити, чи він ще живий.", 75 | "ignore values above x": "Ігнорувати значення вище", 76 | "ignore values below x": "Ігнорувати значення нижче", 77 | "ignore values below zero": "ігнорувати значення нижче нуля (<0)", 78 | "ignore zero or null values": "ігнорувати 0 або нульові значення (==0)", 79 | "keep forever": "зберігати назавжди", 80 | "log changes interval(s)": "Запишіть однакові значення (секунд)", 81 | "log changes minimal delta": "Мінімальна різниця з останнім значенням", 82 | "log changes only": "Тільки записувати зміни", 83 | "note": "Налаштування історії необхідно робити для кожного стану окремо на вкладці «Стани» і тільки якщо адаптер активний", 84 | "only enter when e.g. a reverse proxy is used": "вводити лише тоді, коли використовується зворотний проксі або подібний", 85 | "path": "шлях", 86 | "retention": "Зберігання", 87 | "use 0 to not buffer at all": "Використовуйте 0, щоб взагалі не буферизувати", 88 | "usetags help": "Для отримання додаткової інформації зверніться до документації: https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#Store-metadata-information-as-tags-instead-of-fields" 89 | } -------------------------------------------------------------------------------- /admin/i18n/zh-cn/translations.json: -------------------------------------------------------------------------------- 1 | { 2 | "0 = disable": "0 = 禁用", 3 | "0 = disable delta check": "0 =禁用增量检查", 4 | "0 = disabled": "0 = 禁用", 5 | "1 day": "1天", 6 | "1 months": "1个月", 7 | "1 week": "1周", 8 | "1 year": "1年", 9 | "2 weeks": "2周", 10 | "2 years": "2年", 11 | "3 days": "3天", 12 | "3 months": "3个月", 13 | "5 days": "5天", 14 | "6 months": "6个月", 15 | "Alias Info": "如果设置了 Alias-ID,则数据将作为该 ID 记录在数据库中", 16 | "Apply lower retention": "应用较低的保留", 17 | "Are you sure? All data will be dropped.": "你确定吗?", 18 | "Automatic": "自动的", 19 | "Block time": "出块时间", 20 | "Boolean": "布尔值", 21 | "Buffer Datapoints": "缓冲区数据点", 22 | "Buffer Flush Interval": "缓冲冲洗间隔", 23 | "Confirmation required.": "需要确认。", 24 | "Counter": "柜台", 25 | "Custom retention duration (days)": "自定义保留期限(天)", 26 | "Custom timeframe": "自定义时间范围", 27 | "DB Name": "数据库名称", 28 | "DB Type": "数据库类型", 29 | "DB settings:": "数据库设置:", 30 | "DB version": "数据库版本", 31 | "De-bounce interval(ms)": "仅在 X 毫秒内保持不变时记录该值", 32 | "De-bounce time": "去抖时间", 33 | "Default settings": "默认设置", 34 | "Disable charting optimized logging of skipped values": "禁用跳过值的图表优化记录", 35 | "Enable enhanced debug logs for the datapoint": "为数据点启用增强的调试日志", 36 | "Encrypt": "加密数据库连接", 37 | "Encrypt:": "加密:", 38 | "Enter a number or leave the field empty": "输入一个数字或将该字段留空以不限制记录的值", 39 | "Expert Settings": "专家设置", 40 | "History adapter settings": "历史记录适配器设置", 41 | "Host": "主机", 42 | "Log the last value again on startup": "在启动时再次记录最后一个值", 43 | "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.": "应谨慎考虑降低保留期限:超过保留期限的过去数据将丢失。", 44 | "Milliseconds": "毫秒", 45 | "Number": "数字", 46 | "Number of days to keep the data.": "保留数据的天数。", 47 | "Ok": "确定", 48 | "Organization": "组织", 49 | "Password": "密码", 50 | "Password confirm": "确认密码", 51 | "Please confirm!": "请确认", 52 | "Port": "端口", 53 | "Reject on SSL errors": "拒绝 SSL 错误", 54 | "Request timeout": "请求超时", 55 | "Reset DB": "重置数据库", 56 | "Round real to": "在查询轮数到", 57 | "SQL history adapter settings": "SQL历史记录适配器设置", 58 | "Save last previous value": "保存上一个上一个值", 59 | "Seconds": "秒", 60 | "Send health-check pings to database": "将健康检查 ping 发送到数据库", 61 | "Start or enable adapter first": "首先启动或启用适配器", 62 | "Storage retention": "存储保留", 63 | "Store as": "存储为", 64 | "String": "细绳", 65 | "Test connection": "测试连接", 66 | "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).": "此功能只能用于空数据库或已启用此功能设置的数据库。否则会导致错误(见日志)。", 67 | "Token": "代币", 68 | "Use tags to store metadata information, instead of fields": "使用标签来存储元数据信息,而不是字段", 69 | "User": "用户", 70 | "Validate SSL certificate": "验证 SSL 证书", 71 | "aliasId": "别名 ID", 72 | "blockTime": "在上次记录值之后忽略 X 毫秒的所有新值", 73 | "debounce": "忽略更改,直到值保持不变为X毫秒", 74 | "health-check help": "定期健康检查探针会发送到数据库服务器以检查它是否还活着。", 75 | "ignore values above x": "忽略上面的值", 76 | "ignore values below x": "忽略下面的值", 77 | "ignore values below zero": "忽略零以下的值 (<0)", 78 | "ignore zero or null values": "忽略 0 或空值 (==0)", 79 | "keep forever": "永远保持", 80 | "log changes interval(s)": "记录相同的值(秒)", 81 | "log changes minimal delta": "与上一个值的最小差异", 82 | "log changes only": "仅记录更改", 83 | "note": "仅在适配器处于活动状态时,才必须在“状态”选项卡上分别为每个状态进行历史记录设置", 84 | "only enter when e.g. a reverse proxy is used": "仅在使用反向代理等时输入", 85 | "path": "小路", 86 | "retention": "储存保留", 87 | "use 0 to not buffer at all": "使用0根本不缓冲", 88 | "usetags help": "有关更多信息,请参阅文档:" 89 | } -------------------------------------------------------------------------------- /admin/influxdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/admin/influxdb.png -------------------------------------------------------------------------------- /admin/jsonConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "tabs", 3 | "i18n": true, 4 | "items": { 5 | "dbTab": { 6 | "type": "panel", 7 | "label": "DB settings", 8 | "items": { 9 | "dbversion": { 10 | "type": "select", 11 | "label": "DB-Version", 12 | "noTranslation": true, 13 | "default": "1.x", 14 | "options": [ 15 | {"label": "1.x", "value": "1.x"}, 16 | {"label": "2.x", "value": "2.x"} 17 | ], 18 | "sm": 12, 19 | "md": 8 20 | }, 21 | "protocol": { 22 | "newLine": true, 23 | "type": "select", 24 | "noTranslation": true, 25 | "options": [ 26 | {"label": "http", "value": "http"}, 27 | {"label": "https", "value": "https"} 28 | ], 29 | "label": "Protocol", 30 | "sm": 12, 31 | "md": 2 32 | }, 33 | "host": { 34 | "type": "text", 35 | "label": "Host", 36 | "sm": 12, 37 | "md": 8 38 | }, 39 | "port": { 40 | "type": "number", 41 | "label": "Port", 42 | "min": 1, 43 | "max": 65565, 44 | "sm": 12, 45 | "md": 2 46 | }, 47 | "path": { 48 | "type": "text", 49 | "label": "Path", 50 | "help": "only enter when e.g. a reverse proxy is used", 51 | "hidden": "data.dbversion === '1.x'", 52 | "disabled": "data.dbversion === '1.x'", 53 | "sm": 12, 54 | "md": 4 55 | }, 56 | "user": { 57 | "newLine": true, 58 | "type": "text", 59 | "label": "User", 60 | "hidden": "data.dbversion === '2.x'", 61 | "disabled": "data.dbversion === '2.x'", 62 | "sm": 12, 63 | "md": 4 64 | }, 65 | "password": { 66 | "type": "password", 67 | "label": "Password", 68 | "hidden": "data.dbversion === '2.x'", 69 | "disabled": "data.dbversion === '2.x'", 70 | "repeat": true, 71 | "sm": 12, 72 | "md": 8 73 | }, 74 | "organization": { 75 | "newLine": true, 76 | "type": "text", 77 | "label": "Organization", 78 | "hidden": "data.dbversion === '1.x'", 79 | "disabled": "data.dbversion === '1.x'", 80 | "sm": 12, 81 | "md": 4 82 | }, 83 | "token": { 84 | "type": "text", 85 | "label": "Token", 86 | "hidden": "data.dbversion === '1.x'", 87 | "disabled": "data.dbversion === '1.x'", 88 | "sm": 12, 89 | "md": 8 90 | }, 91 | "dbname": { 92 | "newLine": true, 93 | "type": "text", 94 | "label": "DB Name", 95 | "sm": 12, 96 | "md": 8 97 | }, 98 | "requestTimeout": { 99 | "newLine": true, 100 | "type": "number", 101 | "label": "Request timeout", 102 | "help": "Milliseconds", 103 | "sm": 12, 104 | "md": 2 105 | }, 106 | "validateSSL": { 107 | "newLine": false, 108 | "type": "checkbox", 109 | "label": "Validate SSL certificate", 110 | "hidden": "data.dbversion === '1.x'", 111 | "disabled": "data.dbversion === '1.x'", 112 | "sm": 12, 113 | "md": 4 114 | }, 115 | "round": { 116 | "newLine": true, 117 | "type": "number", 118 | "label": "Round real to", 119 | "sm": 12, 120 | "md": 4 121 | }, 122 | "relogLastValueOnStart": { 123 | "type": "checkbox", 124 | "label": "Log the last value again on startup", 125 | "sm": 12, 126 | "md": 4 127 | }, 128 | "seriesBufferMax": { 129 | "newLine": true, 130 | "type": "number", 131 | "label": "Buffer Datapoints", 132 | "help": "use 0 to not buffer at all", 133 | "sm": 12, 134 | "md": 4 135 | }, 136 | "seriesBufferFlushInterval": { 137 | "type": "number", 138 | "label": "Buffer Flush Interval", 139 | "help": "Seconds", 140 | "sm": 12, 141 | "md": 4, 142 | "lg": 3 143 | }, 144 | 145 | "_testConnection": { 146 | "newLine": true, 147 | "variant": "contained", 148 | "color": "primary", 149 | "disabled": "!_alive", 150 | "type": "sendTo", 151 | "error": { 152 | "connect timeout": "Connection timeout" 153 | }, 154 | "icon": "data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDMyIDMyIiB3aWR0aD0iNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KICAgIDxwYXRoIGZpbGw9ImN1cnJlbnRDb2xvciIgZD0ibTIyLjk4NSAxMy42OTJoLS4wMTl2LTEuNzQ2YS44MjIuODIyIDAgMCAwIDAtLjEzOSAxIDEgMCAwIDAgLS4wMTEtLjE0NXYtNS4zNjhhLjcwOC43MDggMCAwIDAgMC0uMTM5IDIuNjQgMi42NCAwIDAgMCAtMS42MzQtMi4xNzFjLTEuNzUtLjk1NC01LjI2OS0xLjY0NS05LjMzLTEuNjQ1cy03LjU3OS42OTEtOS4zMjkgMS42NDVhMi42NCAyLjY0IDAgMCAwIC0xLjYzNSAyLjE2Ny43ODguNzg4IDAgMCAwIDAgLjEzNWwtLjAxIDUuNTIyYTEuMDQxIDEuMDQxIDAgMCAwIC4wMi4yNTZsLS4wMSA1LjRhLjg4NS44ODUgMCAwIDAgLjAxLjE5MWwtLjAxIDUuNDU1cy0uMTE4IDEuMTkgMS43ODQgMi4yNTVjMS4zMjguNzQ0IDMuOTU2IDEuNTM1IDkuMTg5IDEuNTM1YTM3LjA5MSAzNy4wOTEgMCAwIDAgNC43MTUtLjI2NCA3Ljk5MyA3Ljk5MyAwIDEgMCA2LjI2OC0xMi45NDV6bS0xOS42NjEtNy43NzJhNC43MDYgNC43MDYgMCAwIDEgLjk4Ni0uNDk0IDIzLjExMiAyMy4xMTIgMCAwIDEgNy42ODEtMS4wODcgMjMuMTExIDIzLjExMSAwIDAgMSA3LjY4MSAxLjA4NyA0LjczOSA0LjczOSAwIDAgMSAuOTg3LjQ5NCAxLjcgMS43IDAgMCAxIC4yMzIuMjA5IDIuMjc2IDIuMjc2IDAgMCAxIC0uMzE4LjMxOCA0Ljk4NCA0Ljk4NCAwIDAgMSAtLjkuNDM4IDIzLjE0IDIzLjE0IDAgMCAxIC03LjY4MSAxLjA4NiAyMy4xNDEgMjMuMTQxIDAgMCAxIC03LjY4Mi0xLjA4NiA1LjAxOSA1LjAxOSAwIDAgMSAtLjktLjQzOCAyLjMzNCAyLjMzNCAwIDAgMSAtLjMxOC0uMzE4IDEuNzcgMS43NyAwIDAgMSAuMjMyLS4yMDl6bS0uMyAyLjY0M2MxLjM4Ny43IDQuMDA1IDEuNDA4IDguOTY4IDEuNDA4czcuNTc1LS43IDguOTY0LTEuNDA2djMuMTEyYTIuMzE2IDIuMzE2IDAgMCAxIC0uNzM3LjY0N2MtMS4xNzQuNjY0LTMuNTMgMS4yNzktOC4yMjcgMS4yNzktNC42NjkgMC03LjAyOC0uNjE2LTguMjEyLTEuMjhhMi40NTUgMi40NTUgMCAwIDEgLS43NS0uNjQ2cTAtLjAzNi0uMDEyLS4wNzJ6bTguOTc2IDE2LjMzN2MtNC42NyAwLTcuMDI5LS42MTctOC4yMTMtMS4yODFhMi40MzggMi40MzggMCAwIDEgLS43NjItLjY2MmwuMDA2LTMuMWMxLjM4OC43IDQuMDA2IDEuNDA4IDguOTY5IDEuNDA4IDEuMTE3IDAgMi4xMTItLjAzNSAzLS4xLS4wMTEuMTY3LS4wMTYuMzM1LS4wMTYuNTA1YTcuOTM4IDcuOTM4IDAgMCAwIC42MTUgMy4wNzJjLTEuMDE4LjEwMy0yLjIwOC4xNTgtMy41OTkuMTU4em0zLjQtNS43OGMtLjk3NS4wODUtMi4xLjEzNC0zLjQuMTM0LTQuNjcgMC03LjAyOS0uNjE2LTguMjEzLTEuMjhhMi40MjkgMi40MjkgMCAwIDEgLS43NjEtLjY2MmwuMDA2LTMuMWMxLjM4OC43IDQuMDA2IDEuNDA4IDguOTY5IDEuNDA4YTMwLjIyMyAzMC4yMjMgMCAwIDAgNi41MzktLjU4NSA4LjAyIDguMDIgMCAwIDAgLTMuMTQgNC4wODZ6bTcuNTgxIDguNTRhNS45ODggNS45ODggMCAwIDEgLTUuODUxLTcuMzE1Yy4wMDYtLjAxOS4wMTEtLjAzOS4wMTYtLjA1OHMuMDA5LS4wMzkuMDEyLS4wNTlhNiA2IDAgMSAxIDUuODIzIDcuNDMyeiIvPg0KICAgIDxwYXRoIGZpbGw9ImN1cnJlbnRDb2xvciIgZD0ibTE5LjYzOSAyMS45YTEgMSAwIDAgMCAxLjQxOCAxLjQxMSAyLjYyOCAyLjYyOCAwIDAgMSAzLjcyNSAwIDEgMSAwIDAgMCAxLjQxOC0xLjQxMSA0LjYyOCA0LjYyOCAwIDAgMCAtNi41NjEgMHoiLz4NCiAgICA8ZWxsaXBzZSBmaWxsPSJjdXJyZW50Q29sb3IiIGN4PSIyMi45ODUiIGN5PSIyNC44NDMiIHJ4PSIxLjY2NyIgcnk9IjEuNjc0Ii8+DQogICAgPHBhdGggZmlsbD0iY3VycmVudENvbG9yIiBkPSJtMjcuOTc5IDE5Ljc2OGE3LjA0NSA3LjA0NSAwIDAgMCAtOS45ODggMCAxIDEgMCAxIDAgMS40MTcgMS40MTIgNS4wNDUgNS4wNDUgMCAwIDEgNy4xNTQgMCAxIDEgMCAxIDAgMS40MTctMS40MTJ6Ii8+DQo8L3N2Zz4=", 155 | "command": "test", 156 | "jsonData": "{\"config\": {\"dbversion\": \"${data.dbversion}\", \"protocol\": \"${data.protocol}\", \"port\": \"${data.port}\", \"host\": \"${data.host}\", \"user\": \"${data.user}\", \"organization\": \"${data.organization}\", \"dbname\": \"${data.dbname}\", \"requestTimeout\": \"${data.requestTimeout}\", \"validateSSL\": ${data.validateSSL}, \"password\": \"${encodeURIComponent(data.password || '')}\", \"token\": \"${data.token}\", \"path\": \"${data.path}\"}}", 157 | "label": "Test connection" 158 | }, 159 | 160 | "_resetDB": { 161 | "type": "sendTo", 162 | "variant": "outlined", 163 | "color": "primary", 164 | "icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjODAxMTExIiBkPSJNNiAxOWMwIDEuMS45IDIgMiAyaDhjMS4xIDAgMi0uOSAyLTJWN0g2djEyek0xOSA0aC0zLjVsLTEtMWgtNWwtMSAxSDV2MmgxNFY0eiIvPjwvc3ZnPgkJCQkJCQkJ", 165 | "disabled": "!_alive", 166 | "result": { 167 | "deleted": "Deleted! Restarting..." 168 | }, 169 | "confirm": { 170 | "text": "Are you sure? All data will be dropped.", 171 | "title": "Please confirm", 172 | "ok": "Delete", 173 | "cancel": "Cancel" 174 | }, 175 | "command": "destroy", 176 | "label": "Reset DB" 177 | } 178 | } 179 | }, 180 | "defaultTab": { 181 | "type": "panel", 182 | "label": "Default settings", 183 | "items": { 184 | "debounceTime": { 185 | "newLine": true, 186 | "type": "number", 187 | "sm": 12, 188 | "md": 4, 189 | "min": 0, 190 | "max": 86400000, 191 | "label": "De-bounce time", 192 | "help": "De-bounce interval(ms)" 193 | }, 194 | "blockTime": { 195 | "type": "number", 196 | "sm": 12, 197 | "md": 4, 198 | "min": 0, 199 | "max": 86400000, 200 | "label": "Block time", 201 | "defaultFunc": "(data.debounce || data.debounce === '0' || data.debounce === 0) ? parseInt(data.debounce, 10) : 0", 202 | "help": "blockTime" 203 | }, 204 | "changesRelogInterval": { 205 | "newLine": true, 206 | "type": "number", 207 | "label": "log changes interval(s)", 208 | "help": "0 = disable", 209 | "sm": 12, 210 | "md": 6, 211 | "lg": 4 212 | }, 213 | "changesMinDelta": { 214 | "type": "number", 215 | "label": "log changes minimal delta", 216 | "help": "0 = disable delta check", 217 | "sm": 12, 218 | "md": 6, 219 | "lg": 4 220 | }, 221 | "retention": { 222 | "newLine": true, 223 | "type": "select", 224 | "label": "retention", 225 | "options": [ 226 | { 227 | "value": 0, 228 | "label": "keep forever" 229 | }, 230 | { 231 | "value": 63072000, 232 | "label": "2 years" 233 | }, 234 | { 235 | "value": 31536000, 236 | "label": "1 year" 237 | }, 238 | { 239 | "value": 15811200, 240 | "label": "6 months" 241 | }, 242 | { 243 | "value": 7948800, 244 | "label": "3 months" 245 | }, 246 | { 247 | "value": 2678400, 248 | "label": "1 months" 249 | }, 250 | { 251 | "value": 1209600, 252 | "label": "2 weeks" 253 | }, 254 | { 255 | "value": 604800, 256 | "label": "1 week" 257 | }, 258 | { 259 | "value": 432000, 260 | "label": "5 days" 261 | }, 262 | { 263 | "value": 259200, 264 | "label": "3 days" 265 | }, 266 | { 267 | "value": 86400, 268 | "label": "1 day" 269 | }, 270 | { 271 | "value": -1, 272 | "label": "Custom timeframe" 273 | } 274 | ], 275 | "sm": 12, 276 | "md": 6 277 | }, 278 | "customRetentionDuration": { 279 | "type": "number", 280 | "label": "Custom retention duration (days)", 281 | "min": 1, 282 | "sm": 12, 283 | "md": 4, 284 | "hidden": "(data.retention !== -1)", 285 | "help": "Number of days to keep the data." 286 | }, 287 | "retentionConfirm": { 288 | "newLine": true, 289 | "type": "checkbox", 290 | "label": "Apply lower retention", 291 | "hidden": "((originalData.retention >= 0 && data.retention >= 0 && ((data.retention >= originalData.retention && originalData.retention != 0) || data.retention == 0)) || (originalData.retention === -1 && data.retention >= 0 && ((data.retention >= parseInt(originalData.customRetentionDuration, 10) * 24 * 60) || data.retention == 0)) || (originalData.retention > 0 && data.retention === -1 && (parseInt(data.customRetentionDuration, 10) * 24 * 60 >= originalData.retention)) || (originalData.retention === -1 && data.retention === -1 && data.customRetentionDuration >= originalData.customRetentionDuration))", 292 | "disabled": "((originalData.retention >= 0 && data.retention >= 0 && ((data.retention >= originalData.retention && originalData.retention != 0) || data.retention == 0)) || (originalData.retention === -1 && data.retention >= 0 && ((data.retention >= parseInt(originalData.customRetentionDuration, 10) * 24 * 60) || data.retention == 0)) || (originalData.retention > 0 && data.retention === -1 && (parseInt(data.customRetentionDuration, 10) * 24 * 60 >= originalData.retention)) || (originalData.retention === -1 && data.retention === -1 && data.customRetentionDuration >= originalData.customRetentionDuration))", 293 | "confirm": { 294 | "text": "Lowering the retention period should be considered with caution: Past data exceeding the retention period will be lost.", 295 | "condition": "data.retentionConfirm && data.retentionConfirm != originalData.retentionConfirm", 296 | "title": "Please confirm!", 297 | "type": "warning" 298 | }, 299 | "validator": "data.retentionConfirm", 300 | "validatorErrorText": "Confirmation required.", 301 | "validatorNoSaveOnError" : true, 302 | "doNotSave": true 303 | }, 304 | "round": { 305 | "newLine": true, 306 | "type": "text", 307 | "label": "Round real to", 308 | "sm": 12, 309 | "md": 4, 310 | "lg": 3, 311 | "validator": "((data.round || '').toString().length === 0) || isFinite(data.round)", 312 | "validatorErrorText": "Enter a number or leave the field empty", 313 | "validatorNoSaveOnError": true 314 | }, 315 | "disableSkippedValueLogging": { 316 | "newLine": true, 317 | "label": "Disable charting optimized logging of skipped values", 318 | "type": "checkbox", 319 | "sm": 12, 320 | "md": 4 321 | }, 322 | "enableDebugLogs": { 323 | "newLine": true, 324 | "label": "Enable enhanced debug logs for the datapoint", 325 | "type": "checkbox", 326 | "sm": 12, 327 | "md": 4 328 | }, 329 | "debounce": { 330 | "type": "number", 331 | "sm": 12, 332 | "md": 4, 333 | "min": 0, 334 | "label": "De-bounce time", 335 | "help": "debounce", 336 | "hidden": "true" 337 | } 338 | } 339 | }, 340 | "advancedTab": { 341 | "type": "panel", 342 | "label": "Expert Settings", 343 | "items": { 344 | "usetags": { 345 | "type": "checkbox", 346 | "sm": 12, 347 | "md": 6, 348 | "label": "Use tags to store metadata information, instead of fields", 349 | "help": "usetags help", 350 | "hidden": "data.dbversion === '1.x'", 351 | "disabled": "data.dbversion === '1.x'", 352 | "confirm": { 353 | "text": "This feature can only be used on databases that are empty, or already were setup with this feature enabled. Otherwise it will cause errors (see logs).", 354 | "condition": "data.usetags && data.usetags != originalData.usetags", 355 | "title": "Please confirm!", 356 | "type": "warning" 357 | } 358 | }, 359 | "pingserver": { 360 | "type": "checkbox", 361 | "sm": 12, 362 | "md": 6, 363 | "label": "Send health-check pings to database", 364 | "help": "health-check help", 365 | "hidden": "data.dbversion === '1.x'", 366 | "disabled": "data.dbversion === '1.x'" 367 | } 368 | } 369 | } 370 | } 371 | } 372 | -------------------------------------------------------------------------------- /admin/jsonCustom.json: -------------------------------------------------------------------------------- 1 | { 2 | "i18n": true, 3 | "type": "panel", 4 | "items": { 5 | "debounceTime": { 6 | "newLine": true, 7 | "type": "number", 8 | "sm": 6, 9 | "min": 0, 10 | "max": 86400000, 11 | "defaultFunc": "customObj && customObj.common && customObj.common.type === 'number' ? instanceObj.native.debounceTime : 0", 12 | "label": "De-bounce time", 13 | "help": "De-bounce interval(ms)" 14 | }, 15 | "blockTime": { 16 | "type": "number", 17 | "sm": 6, 18 | "min": 0, 19 | "max": 86400000, 20 | "label": "Block time", 21 | "defaultFunc": "(data.debounce || data.debounce === '0' || data.debounce === 0) ? parseInt(data.debounce, 10) : instanceObj.native.blockTime", 22 | "help": "blockTime" 23 | }, 24 | "changesOnly": { 25 | "newLine": true, 26 | "type": "checkbox", 27 | "label": "log changes only", 28 | "defaultFunc": "customObj && customObj.common && customObj.common.type === 'number'", 29 | "sm": 6 30 | }, 31 | "changesRelogInterval": { 32 | "newLine": true, 33 | "type": "number", 34 | "label": "log changes interval(s)", 35 | "min": 0, 36 | "max": 86400000, 37 | "help": "0 = disabled", 38 | "defaultFunc": "instanceObj.native.changesRelogInterval", 39 | "sm": 6, 40 | "disabled": "!data.changesOnly" 41 | }, 42 | "changesMinDelta": { 43 | "type": "number", 44 | "label": "log changes minimal delta", 45 | "min": 0, 46 | "defaultFunc": "customObj && customObj.common && customObj.common.type === 'number' ? instanceObj.native.changesMinDelta : 0", 47 | "default": 0, 48 | "sm": 6, 49 | "help": "0 = disable delta check", 50 | "disabled": "!data.changesOnly" 51 | }, 52 | "ignoreBelowNumber": { 53 | "newLine": true, 54 | "type": "text", 55 | "label": "ignore values below x", 56 | "hidden": "!customObj || !customObj.common || customObj.common.type !== 'number'", 57 | "defaultFunc": "data.ignoreBelowZero ? '0' : ''", 58 | "validator": "((data.ignoreBelowNumber || '').toString().length === 0) || isFinite(data.ignoreBelowNumber)", 59 | "validatorErrorText": "Enter a number or leave the field empty", 60 | "validatorNoSaveOnError": true, 61 | "sm": 6 62 | }, 63 | "ignoreAboveNumber": { 64 | "type": "text", 65 | "label": "ignore values above x", 66 | "hidden": "!customObj || !customObj.common || customObj.common.type !== 'number'", 67 | "validator": "((data.ignoreAboveNumber || '').toString().length === 0) || isFinite(data.ignoreAboveNumber)", 68 | "validatorErrorText": "Enter a number or leave the field empty", 69 | "validatorNoSaveOnError": true, 70 | "sm": 6 71 | }, 72 | "ignoreZero": { 73 | "newLine": true, 74 | "type": "checkbox", 75 | "label": "ignore zero or null values", 76 | "sm": 6 77 | }, 78 | "disableSkippedValueLogging": { 79 | "newLine": true, 80 | "label": "Disable charting optimized logging of skipped values", 81 | "type": "checkbox", 82 | "sm": 12, 83 | "defaultFunc": "instanceObj.native.disableSkippedValueLogging || false" 84 | }, 85 | "storageType": { 86 | "newLine": true, 87 | "type": "select", 88 | "label": "Store as", 89 | "options": [ 90 | { 91 | "value": "", 92 | "label": "Automatic" 93 | }, 94 | { 95 | "value": "String", 96 | "label": "String" 97 | }, 98 | { 99 | "value": "Number", 100 | "label": "Number" 101 | }, 102 | { 103 | "value": "Boolean", 104 | "label": "Boolean" 105 | } 106 | ], 107 | "default": "", 108 | "sm": 6 109 | }, 110 | "aliasId": { 111 | "newLine": true, 112 | "type": "text", 113 | "label": "aliasId", 114 | "maxLength": 255, 115 | "default": "", 116 | "sm": 12, 117 | "help": "Alias Info" 118 | }, 119 | "round": { 120 | "newLine": true, 121 | "type": "text", 122 | "label": "Round real to", 123 | "sm": 6, 124 | "validator": "((data.round || '').toString().length === 0) || isFinite(data.round)", 125 | "validatorErrorText": "Enter a number or leave the field empty", 126 | "validatorNoSaveOnError": true, 127 | "hidden": "!customObj || !customObj.common || customObj.common.type !== 'number' || (data.storageType && data.storageType !== 'Number')" 128 | }, 129 | "enableDebugLogs": { 130 | "newLine": true, 131 | "label": "Enable enhanced debug logs for the datapoint", 132 | "type": "checkbox", 133 | "sm": 12, 134 | "defaultFunc": "instanceObj.native.enableDebugLogs || false" 135 | }, 136 | "debounce": { 137 | "type": "number", 138 | "label": "De-bounce time", 139 | "help": "De-bounce interval(ms)", 140 | "min": 0, 141 | "max": 86400000, 142 | "defaultFunc": "customObj && customObj.common && customObj.common.type === 'number' ? instanceObj.native.debounce : 0", 143 | "hidden": "true", 144 | "sm": 6 145 | }, 146 | "ignoreBelowZero": { 147 | "type": "checkbox", 148 | "label": "ignore values below zero", 149 | "hidden": "true", 150 | "sm": 6 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /docs/de/img/influxdb_Filtern_loggen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_Filtern_loggen.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_Data.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_Data.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_filter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_filter.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_timerange.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_timerange.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_type.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_Adapter_SQL_objects_type.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_Adapter_influxDB_Konfig.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_Adapter_influxDB_Konfig.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_Adapter_influxDB_objects.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_Adapter_influxDB_objects.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_Adapter_rickshaw03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_Adapter_rickshaw03.jpg -------------------------------------------------------------------------------- /docs/de/img/influxdb_ioBroker_adapter_History_devices.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/234de8d73a8e1b48aabce21d9133eb8a13af2956/docs/de/img/influxdb_ioBroker_adapter_History_devices.jpg -------------------------------------------------------------------------------- /docs/de/influxdb.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | * * * 4 | 5 | ## Konfiguration 6 | 7 | ### DB-Einstellungen 8 | 9 | Hier werden die Einstellungen, die beim Anlegen der influxDB gemacht wurden eingegeben, damit der ioBroker-Server Zugriff auf diese Datenbank erhält. [![](img/influxdb_ioBroker_Adapter_influxDB_Konfig.jpg)](img/influxdb_ioBroker_Adapter_influxDB_Konfig.jpg) 10 | 11 | #### Host 12 | 13 | Hostname oder IP des Datenbank Servers. 14 | 15 | #### Port 16 | 17 | hier wird der Port eingegeben über den die Datenbank auf dem Host zu erreichen ist. 18 | 19 | #### Protocol 20 | 21 | Hier wird angegeben ob der Zugriff auf die Datenbank per einfachem http oder gesichertem https durchgeführt werden soll 22 | 23 | #### Login 24 | 25 | Der Besitzer der Datenbank (User) unter dessen ID die Daten aufgezeichnet werden sollen 26 | 27 | #### Passwort 28 | 29 | Dieses ist das Passwort des angegebenen Users in der SQL-Datenbank. Zur Sicherheit muss dieses Passwort im folgenden Feld wiederholt eingegeben werden. 30 | 31 | #### Aufrunden auf 32 | 33 | Angabe der Nachkommastellen mit denen Zahlen gespeichert werden sollen. 34 | 35 | #### Schreibaktionen sammeln 36 | 37 | Der hier eingegeben Wert bestimmt wieviele neue Daten vorliegen sollen, bevor wieder in die Datenbank geschrieben werden soll. Je höher der Wert, desto seltener wird in die DB geschrieben, desto höher ist aber der Datenverlust bei Ausfall des Adapters. Eine 0 sorgt für sofortigen Eintrag in die DB. Dementsprechend bedeutet die Eingabe "0": Sofortiges Schreiben in die Datenbank. Dies erhöht die Last auf der Datenbank und im Adapter. 38 | 39 | #### Schreibintervall 40 | 41 | Wird hier ein Wert eingegeben werden die Daten bereits nach der vorgegebenen Zeit in Sekunden in die Datenbank geschrieben, auch wenn die im letzten Punkt eingestellte Anzahl von Daten noch nicht erreicht ist. 42 | 43 | ### Default Einstellungen für Zustände 44 | 45 | Diese Einstellungen geben die Werte vor, die bei der Konfiguration des Loggings der einzelnen Datenpunkte als Vorgabe genutzt werden sollen. [![](img/influxdb_ioBroker_Adapter_influxDB_objects.jpg)](img/influxdb_ioBroker_Adapter_influxDB_objects.jpg) 46 | 47 | #### Nur Änderungen aufzeichnen 48 | 49 | Ist diese Checkbox angehakt müssen aufeinanderfolgende Daten unterschiedliche Werte haben damit sie aufgezeichnet werden. Sendet ein Sensor, z.B. mehrfach die gleiche Temperatur wird dies nicht aufgezeichnet, erst bei einer Änderung wird wieder eine Datensatz angelegt. 50 | 51 | #### gleiche Werte aufzeichnen 52 | 53 | sollen bei gleichem Wert von Zeit zu Zeit trotzdem diese (unveränderten) Werte gespeichert werden, kann hier eine Zeitspanne in Sekunden festgelegt werden, wie häufig dieses geschehen soll. Dementsprechend bedeutet die Eingabe 0, dass kein doppelter Wert gespeichert werden soll. 54 | 55 | #### Minimale Abweichung vom letzten Wert 56 | 57 | sollen bei ständig wechselnden Werten trotzdem diese (geänderten) Werte nicht gespeichert werden, kann hier ein Mindestwert festgelegt werden, den sich der Wert ändern muss, damit wieder ein neuer Wert gespeichert wird. Dies ist beispielsweise bei Strommesssteckdosen sinnvoll, bei dem nicht jede leichte Veränderung geloggt werden soll. Dementsprechend bedeutet die Eingabe 0, dass jeder Wert gespeichert werden soll. 58 | 59 | #### Speichern als 60 | 61 | Wenn nötig kann hier der Datentyp festgelegt werden mit dem die Daten gespeichert werden sollen. Dies sollte nur vor der ersten Aktivierung durchgeführt werden. 62 | 63 | [![](img/influxdb_ioBroker_Adapter_SQL_objects_type.jpg)](img/iinfluxdb_oBroker_Adapter_SQL_objects_type.jpg) In einer InfluxDB wird der Datentyp mit dem ersten Datensatz festgelegt und muss danach identisch bleiben. 64 | 65 | #### Storage Vorhaltezeit 66 | 67 | Legt fest, wie lange die Werte gespeichert werden sollen (unendlich, 2 Jahre, 1 Jahre, …, 1 Tag). [![](img/influxdb_ioBroker_Adapter_SQL_objects_timerange.jpg)](img/influxdb_ioBroker_Adapter_SQL_objects_timerange.jpg) 68 | 69 | #### Entprellzeit (ms) 70 | 71 | Schutz vor zu häufigen Änderungen eines Wertes. Dies ist der Mindestabstand in Millisekunden bis wieder ein Wert geschrieben wird. 72 | 73 | * * * 74 | 75 | ## Einstellungen für Datenpunkte 76 | 77 | Die Einstellungen für die zu loggenden Datenpunkte werden in dem Reiter „Objekte“ bei dem entsprechenden Datenpunkt durchgeführt. [![ioBroker_adapter_History_devices](img/influxdb_ioBroker_adapter_History_devices.jpg)](img/influxdb_ioBroker_adapter_History_devices.jpg) Dazu wählt man ganz rechts in der Spalte das Zahnradsymbol zu dem gewünschten Datenpunkt aus. Das Konfigurationsmenü öffnet sich: [![](img/influxdb_ioBroker_Adapter_influxDB_objects.jpg)](img/influxdb_ioBroker_Adapter_influxDB_objects.jpg) 78 | 79 | ### Aktiviert 80 | 81 | Logging des Datenpunktes aktivieren Nur Änderungen aufzeichnen: Es werden nur Werte gespeichert, wenn sich der Wert des Datenpunktes ändert. Das spart Speicherplatz.Eine sinnvolle Nutzung ergibt sich, wenn man vorher über die Filterfelder in dem Tabellenheader die Datenpunkte so filtert, dass man z.B. nur die „State“ Datenpunkte herausfiltert, um sie dann zu loggen [![Filtern_loggen](img/influxdb_Filtern_loggen.jpg)](img/Filtern_loggen.jpg) 82 | 83 | 1. die Ansicht als Liste ohne Gruppierung anzeigen lassen 84 | 2. den oder die Filterbegriffe eingeben 85 | 3. alle gefilterten Datenpunkte zum loggen auswählen 86 | 1. Das Konfigurationsmenü für die Einstellungen der log-Parameter öffnet sich 87 | 4. Das loggen für alle gefilterten Datenpunkte auf einmal aktivieren 88 | 1. Weitere Parameter wie „nur Änderungen“ und Vorhaltezeit für alle gefilterten Datenpunkte einheitlich auswählen 89 | 5. Die Änderungen speichern 90 | 91 | * * * 92 | 93 | ## **Bedienung** 94 | 95 | Wählt man in der Titelzeile unter Historie "mit" oder "influxdb.0" aus, werden nur noch Datenpunkte mit Logging angezeigt. [![](img/influxdb_ioBroker_Adapter_SQL_objects_filter.jpg)](img/influxdb_ioBroker_Adapter_SQL_objects_filter.jpg) Ein Klick auf das Zahnradsymbol öffnet die geloggten Daten: [![](img/influxdb_ioBroker_Adapter_SQL_objects_Data.jpg)](img/influxdb_ioBroker_Adapter_SQL_objects_Data.jpg) Im Reiter Table werden die Daten tabellarisch angezeigt. [![ioBroker_Adapter_rickshaw03](img/influxdb_ioBroker_Adapter_rickshaw03.jpg)](img/influxdb_ioBroker_Adapter_rickshaw03.jpg) Im Reiter Chart kann bei installiertem Rickshaw-Adapter eine Verlaufsgrafik angezeigt werden. 96 | 97 | * * * 98 | 99 | ## Installation einer influxDB Datenbank 100 | 101 | Die Beschreibung einer Installation einer influxDB-Datenbank folgt. 102 | -------------------------------------------------------------------------------- /io-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "common": { 3 | "name": "influxdb", 4 | "desc": { 5 | "en": "Logging of states into InfluxDB", 6 | "de": "Loggt die Historie von einzelnen Zuständen in einer InfluxDB", 7 | "ru": "Сохраняет историю событий для отдельных состояний в InfluxDB", 8 | "pt": "Registro de estados no InfluxDB", 9 | "nl": "Loggen van staten in InfluxDB", 10 | "fr": "Journalisation des états dans InfluxDB", 11 | "it": "Registrazione degli stati in InfluxDB", 12 | "es": "Registro de estados en InfluxDB", 13 | "pl": "Logowanie stanów do InfluxDB", 14 | "uk": "Збереження історії подій для окремих станів в InfluxDB", 15 | "zh-cn": "将状态记录到InfluxDB中" 16 | }, 17 | "version": "4.0.3", 18 | "title": "Logging data with InfluxDB", 19 | "titleLang": { 20 | "en": "Logging data with InfluxDB", 21 | "de": "Daten mit InfluxDB protokollieren", 22 | "ru": "Запись данных с помощью InfluxDB", 23 | "pt": "Registro de dados com InfluxDB", 24 | "nl": "Loggen van gegevens met InfluxDB", 25 | "fr": "Consignation des données avec InfluxDB", 26 | "it": "Registrazione dei dati con InfluxDB", 27 | "es": "Datos de registro con InfluxDB", 28 | "pl": "Rejestrowanie danych za pomocą InfluxDB", 29 | "uk": "Запис даних за допомогою InfluxDB", 30 | "zh-cn": "使用InfluxDB记录数据" 31 | }, 32 | "news": { 33 | "4.0.3": { 34 | "en": "Some packages were updated", 35 | "de": "Einige Pakete wurden aktualisiert", 36 | "ru": "Некоторые пакеты были обновлены", 37 | "pt": "Alguns pacotes foram atualizados", 38 | "nl": "Sommige pakketten werden bijgewerkt", 39 | "fr": "Certains paquets ont été mis à jour", 40 | "it": "Alcuni pacchetti sono stati aggiornati", 41 | "es": "Algunos paquetes se actualizaron", 42 | "pl": "Niektóre pakiety zostały zaktualizowane", 43 | "uk": "Деякі пакети були оновлено", 44 | "zh-cn": "一些软件包已更新" 45 | }, 46 | "4.0.2": { 47 | "en": "Corrected JSON config\nCorrected filter function in booleanTypeCheckQuery\nAllowed the self-signed certificates using \"test connection\" button\nThe deletion of data from DB was implemented for V2\nAdded support for `count` aggregate type on getHistory\nminimal supported node.js version is 16 now", 48 | "de": "JSON config korrigiert\nKorrigierte Filterfunktion in booleanTypeCheckQuery\nErlaubt die selbstsignierten Zertifikate mit \"Test-Verbindung\" Taste\nDie Löschung von Daten aus DB wurde für V2 implementiert\nUnterstützung für Grafit-Aggregat-Typ auf getHistory\nminimal unterstützt node.js version ist jetzt 16", 49 | "ru": "Правильный конфиг JSON\nИсправлена функция фильтра в booleanTypeCheckQuery\nРазрешены самоподписанные сертификаты с помощью кнопки \"test connection\"\nУдаление данных от DB было реализовано для V2\nДобавлена поддержка подсчета агрегатного типа на getHistory\nминимальная поддерживаемая версия node.js 16 сейчас", 50 | "pt": "Configuração JSON corrigida\nFunção de filtro corrigida em booleanTypeCheckQuery\nPermitiram os certificados auto-assinados usando o botão \"conexão de teste\"\nA exclusão de dados da DB foi implementada para V2\nAdicionado suporte para contar o tipo agregado em getHistory\nversão node.js suportada mínima é 16 agora", 51 | "nl": "Quality over Quantity (QoQ) Releases Vertaling:\nVertaling:\nDe zelf toegewezen certificaten met \"teest verbinding\" knop\nDe deletie van de gegevens van DB werd geïnformeerd voor V2\nVermeldde steun voor het tel aggregate type\nminimaal ondersteunde node", 52 | "fr": "Correction de la configuration JSON\nFonction de filtre corrigée dans booleanTypeCheckQuery\nAutorisé les certificats autosignés à l'aide du bouton \"test connection\"\nLa suppression des données du DB a été mise en œuvre pour V2\nAjout du support pour compter le type agrégé sur getHistory\nla version node.js supportée est 16 maintenant", 53 | "it": "Corretto JSON config\nFunzione di filtro corretto in booleanTypeCheckQuery\nConsentito i certificati autofirmati utilizzando il pulsante \"Connessione di prova\"\nLa cancellazione dei dati da DB è stata implementata per V2\nAggiunto supporto per conteggio tipo aggregato su getHistory\nversione minima supportato node.js è 16 ora", 54 | "es": "Corregido JSON config\nFunción de filtro corregida en booleanTypeCheckQuery\nPermitió los certificados auto-firmados usando el botón \"prueba de conexión\"\nLa eliminación de los datos del DB se llevó a cabo para V2\nSoporte añadido para el tipo de cuenta agregado en getHistory\nversión mínima soportado node.js es 16 ahora", 55 | "pl": "Zgoda JSON\nFunkcja filtrów w booleanTypeCheckQuery\nUzyskał on certyfikaty za pomocą przycisku \"test connection\"\nDetekcja danych z DB została zaimplementowana dla V2\nWsparcie dla liczby zbitych typów\nminimalna wersja węzła jest obecnie 16", 56 | "uk": "Виправлено налаштування JSON\nВиправлена функція фільтра в booleanTypeCheckQuery\nДозволені сертифікати самопризначені за допомогою кнопки \"test Connection\"\nВидалення даних з DB реалізовано для V2\nДодано підтримку підрахунку агрегатного типу на getHistory\nмінімальний підтриманий вузол.js версія 16 тепер", 57 | "zh-cn": "惩教所\n善良Type CheckQuery的过滤功能\n允许使用“试验联系”的自发证书\n第五2行删除数据\n增加对准礼品总值的支持\n最低支持无误的版本现在是16个。" 58 | }, 59 | "4.0.1": { 60 | "en": "Corrected JSON config", 61 | "de": "JSON config korrigiert", 62 | "ru": "Правильный конфиг JSON", 63 | "pt": "Configuração JSON corrigida", 64 | "nl": "Quality over Quantity (QoQ) Releases Vertaling:", 65 | "fr": "Correction de la configuration JSON", 66 | "it": "Corretto JSON config", 67 | "es": "Corregido JSON config", 68 | "pl": "Zgoda JSON", 69 | "uk": "Виправлено налаштування JSON", 70 | "zh-cn": "惩教所" 71 | }, 72 | "4.0.0": { 73 | "en": "Allowed the self-signed certificates using \"test connection\" button\nThe deletion of data from DB was implemented for V2\nAdded support for `count` aggregate type on getHistory\nminimal supported node.js version is 16 now", 74 | "de": "Erlaubt die selbstsignierten Zertifikate mit \"Test-Verbindung\" Taste\nDie Löschung von Daten aus DB wurde für V2 implementiert\nUnterstützung für Grafit-Aggregat-Typ auf getHistory\nminimal unterstützt node.js version ist jetzt 16", 75 | "ru": "Разрешены самоподписанные сертификаты с помощью кнопки \"test connection\"\nУдаление данных от DB было реализовано для V2\nДобавлена поддержка подсчета агрегатного типа на getHistory\nминимальная поддерживаемая версия node.js 16 сейчас", 76 | "pt": "Permitiram os certificados auto-assinados usando o botão \"conexão de teste\"\nA exclusão de dados da DB foi implementada para V2\nAdicionado suporte para contar o tipo agregado em getHistory\nversão node.js suportada mínima é 16 agora", 77 | "nl": "De zelf toegewezen certificaten met \"teest verbinding\" knop\nDe deletie van de gegevens van DB werd geïnformeerd voor V2\nVermeldde steun voor het tel aggregate type\nminimaal ondersteunde node", 78 | "fr": "Autorisé les certificats autosignés à l'aide du bouton \"test connection\"\nLa suppression des données du DB a été mise en œuvre pour V2\nAjout du support pour compter le type agrégé sur getHistory\nla version node.js supportée est 16 maintenant", 79 | "it": "Consentito i certificati autofirmati utilizzando il pulsante \"Connessione di prova\"\nLa cancellazione dei dati da DB è stata implementata per V2\nAggiunto supporto per conteggio tipo aggregato su getHistory\nversione minima supportato node.js è 16 ora", 80 | "es": "Permitió los certificados auto-firmados usando el botón \"prueba de conexión\"\nLa eliminación de los datos del DB se llevó a cabo para V2\nSoporte añadido para el tipo de cuenta agregado en getHistory\nversión mínima soportado node.js es 16 ahora", 81 | "pl": "Uzyskał on certyfikaty za pomocą przycisku \"test connection\"\nDetekcja danych z DB została zaimplementowana dla V2\nWsparcie dla liczby zbitych typów\nminimalna wersja węzła jest obecnie 16", 82 | "uk": "Дозволені сертифікати самопризначені за допомогою кнопки \"test Connection\"\nВидалення даних з DB реалізовано для V2\nДодано підтримку підрахунку агрегатного типу на getHistory\nмінімальний підтриманий вузол.js версія 16 тепер", 83 | "zh-cn": "允许使用“试验联系”的自发证书\n第五2行删除数据\n增加对准礼品总值的支持\n最低支持无误的版本现在是16个。" 84 | }, 85 | "3.2.0": { 86 | "en": "Adjust cache file to be different per instance when having multiple instances", 87 | "de": "Bestimmen Sie die Cache-Datei, um unterschiedlich zu sein pro Instanz, wenn mehrere Instanzen haben", 88 | "ru": "Отрегулируйте файл кэша для того чтобы быть различным в случае если иметь несколько экземпляров", 89 | "pt": "Ajuste o arquivo de cache para ser diferente por instância quando tiver várias instâncias", 90 | "nl": "Geef cachedo aan om anders te zijn als je meerdere instanties hebt", 91 | "fr": "Ajuster le fichier cache pour être différent par instance lorsqu'il existe plusieurs instances", 92 | "it": "Regolare il file della cache per essere diverso per istanza quando hanno più istanze", 93 | "es": "Ajuste el archivo de caché para ser diferente por ejemplo al tener múltiples instancias", 94 | "pl": "Plik Adjust cache może być różny na przykład, gdy posiada wiele instancji", 95 | "zh-cn": "当发生多种情况时,独立的理由档案各不相同。" 96 | }, 97 | "3.1.8": { 98 | "en": "Fix crash cases reported by Sentry", 99 | "de": "Reparieren Crashfälle gemeldet von Sentry", 100 | "ru": "Исправление случаев аварии, описанных Sentry", 101 | "pt": "Corrigir casos de acidente relatados por Sentry", 102 | "nl": "Vertaling:", 103 | "fr": "Troubles de crash signalés par Sentry", 104 | "it": "Correzione dei casi di crash segnalati da Sentry", 105 | "es": "Casos de accidente fijo reportados por Sentry", 106 | "pl": "Sprawy katastrofy Fix podane przez Sentry’a", 107 | "zh-cn": "Sentry所报告的六例事故" 108 | }, 109 | "3.1.7": { 110 | "en": "Allow to remove a configuration value for \"round\" in config again", 111 | "de": "Lassen Sie einen Konfigurationswert für Runde in config wieder entfernen", 112 | "ru": "Разрешить удалить конфигурационную ценность для раунда в config снова", 113 | "pt": "Permitir remover um valor de configuração para round em config novamente", 114 | "nl": "Sta toe om weer een configuratiewaarde te verwijderen voor ronde in het leger", 115 | "fr": "Permettre de supprimer une valeur de configuration pour round in config à nouveau", 116 | "it": "Permette di rimuovere un valore di configurazione per round in config di nuovo", 117 | "es": "Permitir eliminar de nuevo un valor de configuración para redondear en configuración", 118 | "pl": "Allow, aby usunąć wartość konfiguracyjna w zakręcie ponownie w konfigunie", 119 | "zh-cn": "允许再次取消一轮谈判的组合价值" 120 | } 121 | }, 122 | "mode": "daemon", 123 | "platform": "Javascript/Node.js", 124 | "loglevel": "info", 125 | "messagebox": true, 126 | "subscribe": "messagebox", 127 | "keywords": [ 128 | "charts", 129 | "logging", 130 | "influxdb" 131 | ], 132 | "preserveSettings": "custom", 133 | "supportCustoms": true, 134 | "getHistory": true, 135 | "enabled": true, 136 | "compact": true, 137 | "dependencies": [ 138 | { 139 | "js-controller": ">=3.3.0" 140 | } 141 | ], 142 | "globalDependencies": [ 143 | { 144 | "admin": ">=5.1.28" 145 | } 146 | ], 147 | "supportStopInstance": 10000, 148 | "stopTimeout": 10000, 149 | "authors": [ 150 | "Bluefox ", 151 | "Apollon77 ", 152 | "Excodibur" 153 | ], 154 | "license": "MIT", 155 | "readme": "https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md", 156 | "icon": "influxdb.png", 157 | "extIcon": "https://raw.githubusercontent.com/ioBroker/ioBroker.influxdb/master/admin/influxdb.png", 158 | "type": "storage", 159 | "docs": { 160 | "de": [ 161 | "docs/de/influxdb.md" 162 | ] 163 | }, 164 | "plugins": { 165 | "sentry": { 166 | "dsn": "https://29eecf4e8c954f2ea78110d47a9b122d@sentry.iobroker.net/54" 167 | } 168 | }, 169 | "adminUI": { 170 | "config": "json", 171 | "custom": "json" 172 | }, 173 | "connectionType": "local", 174 | "dataSource": "push", 175 | "tier": 1, 176 | "eraseOnUpload": true, 177 | "licenseInformation": { 178 | "license": "MIT", 179 | "type": "free" 180 | }, 181 | "messages": [ 182 | { 183 | "condition": { 184 | "operand": "and", 185 | "rules": [ 186 | "oldVersion<2.1.1", 187 | "newVersion>=2.1.1" 188 | ] 189 | }, 190 | "title": { 191 | "en": "Password needs to re re-entered after upgrade and other changes", 192 | "de": "Das Passwort muss nach dem Upgrade erneut eingegeben werden", 193 | "ru": "Пароль необходимо повторно ввести после обновления", 194 | "pt": "A senha precisa ser reinserida após a atualização", 195 | "nl": "Wachtwoord moet opnieuw worden ingevoerd na upgrade", 196 | "fr": "Le mot de passe doit être ressaisi après la mise à niveau", 197 | "it": "La password deve essere reinserita dopo l'aggiornamento", 198 | "es": "La contraseña debe volver a ingresarse después de la actualización", 199 | "pl": "Hasło musi zostać ponownie wprowadzone po aktualizacji", 200 | "uk": "Пароль потрібно повторно ввести після оновлення", 201 | "zh-cn": "升级后需要重新输入密码" 202 | }, 203 | "text": { 204 | "en": "After upgrading to Version 2.1.1 or later you need to re-entr your passwort/token for the access to the InfluxDB in the instance configuration.", 205 | "de": "Nach dem Upgrade auf Version 2.1.1 oder höher müssen Sie Ihr Passwort/Token für den Zugriff auf die InfluxDB in der Instanzkonfiguration erneut eingeben.", 206 | "ru": "После обновления до версии 2.1.1 или более поздней вам необходимо повторно ввести свой пароль/токен для доступа к InfluxDB в конфигурации экземпляра.", 207 | "pt": "Após atualizar para a Versão 2.1.1 ou posterior, você precisa reinserir sua senha/token para acesso ao InfluxDB na configuração da instância.", 208 | "nl": "Na het upgraden naar versie 2.1.1 of hoger moet u uw wachtwoord/token opnieuw invoeren voor toegang tot de InfluxDB in de instantieconfiguratie.", 209 | "fr": "Après la mise à niveau vers la version 2.1.1 ou ultérieure, vous devez ressaisir votre mot de passe/token pour l'accès à InfluxDB dans la configuration de l'instance.", 210 | "it": "Dopo l'aggiornamento alla versione 2.1.1 o successiva è necessario reinserire la password/token per l'accesso a InfluxDB nella configurazione dell'istanza.", 211 | "es": "Después de actualizar a la versión 2.1.1 o posterior, debe volver a ingresar su contraseña/token para acceder a InfluxDB en la configuración de la instancia.", 212 | "pl": "Po aktualizacji do wersji 2.1.1 lub nowszej należy ponownie wprowadzić hasło/token, aby uzyskać dostęp do bazy danych InfluxDB w konfiguracji instancji.", 213 | "uk": "Після оновлення до версії 2.1.1 або пізніше вам необхідно повторно ввести свій пароль/токен для доступу до InfluxDB в конфігурації екземпляра.", 214 | "zh-cn": "升级到 2.1.1 或更高版本后,您需要重新输入密码/令牌才能在实例配置中访问 InfluxDB。" 215 | }, 216 | "level": "warn", 217 | "buttons": [ 218 | "agree", 219 | "cancel" 220 | ] 221 | }, 222 | { 223 | "condition": { 224 | "operand": "and", 225 | "rules": [ 226 | "oldVersion<3.0.0", 227 | "newVersion>=3.0.0" 228 | ] 229 | }, 230 | "title": { 231 | "en": "Important notice!", 232 | "de": "Wichtiger Hinweis!", 233 | "ru": "Важное замечание!", 234 | "pt": "Notícia importante!", 235 | "nl": "Belangrijke mededeling!", 236 | "fr": "Avis important!", 237 | "it": "Avviso IMPORTANTE!", 238 | "es": "Noticia importante!", 239 | "pl": "Ważna uwaga!", 240 | "uk": "Важливе повідомлення!", 241 | "zh-cn": "重要通知!" 242 | }, 243 | "text": { 244 | "en": "This new version introduces several changes how values are logged because we fixed several issues and added new features. Please especially check the defined \"debounce\" and \"block time\" settings in your datapoints if values are not logged as expected and make sure the settings make sense. For more details please refer to the changelog and Readme.", 245 | "de": "Diese neue Version führt mehrere Änderungen ein, wie Werte protokolliert werden, da wir mehrere Probleme behoben und neue Funktionen hinzugefügt haben. Bitte überprüfen Sie insbesondere die definierten „Entprellen“- und „Sperrzeit“-Einstellungen in Ihren Datenpunkten, wenn Werte nicht wie erwartet protokolliert werden, und stellen Sie sicher, dass die Einstellungen sinnvoll sind. Weitere Details finden Sie im Changelog und in der Readme.", 246 | "ru": "В этой новой версии внесено несколько изменений в регистрацию значений, поскольку мы исправили несколько проблем и добавили новые функции. Пожалуйста, особенно проверьте определенные настройки «debounce» и «block time» в ваших точках данных, если значения не регистрируются должным образом, и убедитесь, что настройки имеют смысл. Для получения более подробной информации, пожалуйста, обратитесь к журналу изменений и Readme.", 247 | "pt": "Esta nova versão apresenta várias alterações na forma como os valores são registrados, pois corrigimos vários problemas e adicionamos novos recursos. Verifique especialmente as configurações definidas de \"debounce\" e \"block time\" em seus pontos de dados se os valores não forem registrados conforme o esperado e verifique se as configurações fazem sentido. Para obter mais detalhes, consulte o log de alterações e o Leiame.", 248 | "nl": "Deze nieuwe versie introduceert verschillende wijzigingen in de manier waarop waarden worden geregistreerd, omdat we verschillende problemen hebben opgelost en nieuwe functies hebben toegevoegd. Controleer vooral de gedefinieerde \"debounce\" en \"block time\" instellingen in uw datapunten als de waarden niet zijn vastgelegd zoals verwacht en zorg ervoor dat de instellingen kloppen. Raadpleeg de changelog en Readme voor meer informatie.", 249 | "fr": "Cette nouvelle version introduit plusieurs changements dans la journalisation des valeurs car nous avons corrigé plusieurs problèmes et ajouté de nouvelles fonctionnalités. Veuillez vérifier en particulier les paramètres \"anti-rebond\" et \"temps de blocage\" définis dans vos points de données si les valeurs ne sont pas enregistrées comme prévu et assurez-vous que les paramètres ont un sens. Pour plus de détails, veuillez consulter le journal des modifications et le fichier Lisez-moi.", 250 | "it": "Questa nuova versione introduce diverse modifiche al modo in cui i valori vengono registrati perché abbiamo risolto diversi problemi e aggiunto nuove funzionalità. Controllare in particolare le impostazioni definite \"debounce\" e \"block time\" nei propri datapoint se i valori non sono registrati come previsto e assicurarsi che le impostazioni abbiano un senso. Per maggiori dettagli, fare riferimento al log delle modifiche e al Leggimi.", 251 | "es": "Esta nueva versión introduce varios cambios en la forma en que se registran los valores porque solucionamos varios problemas y agregamos nuevas funciones. Verifique especialmente la configuración definida de \"antirrebote\" y \"tiempo de bloqueo\" en sus puntos de datos si los valores no se registran como se esperaba y asegúrese de que la configuración tenga sentido. Para obtener más detalles, consulte el registro de cambios y el archivo Léame.", 252 | "pl": "Ta nowa wersja wprowadza kilka zmian w sposobie rejestrowania wartości, ponieważ naprawiliśmy kilka problemów i dodaliśmy nowe funkcje. W szczególności sprawdź zdefiniowane ustawienia „odbicia” i „czasu blokowania” w punktach danych, jeśli wartości nie są rejestrowane zgodnie z oczekiwaniami i upewnij się, że ustawienia mają sens. Aby uzyskać więcej informacji, zapoznaj się z dziennikiem zmian i Readme.", 253 | "uk": "Ця нова версія вносить кілька змін у реєстрацію значень, оскільки ми виправили кілька проблем і додали нові функції. Будь ласка, особливо перевірте визначені налаштування «затримки» та «часу блокування» в ваших точках даних, якщо значення не реєструються так, як очікувалося, і переконайтеся, що налаштування мають сенс. Для отримання додаткової інформації див. Журнал змін та Readme.", 254 | "zh-cn": "这个新版本引入了一些更改值的记录方式,因为我们修复了几个问题并添加了新功能。如果未按预期记录值,请特别检查数据点中定义的“去抖动”和“阻塞时间”设置,并确保设置有意义。有关更多详细信息,请参阅更改日志和自述文件。" 255 | }, 256 | "link": "https://github.com/ioBroker/ioBroker.influxdb/blob/master/README.md#default-settings", 257 | "level": "warn", 258 | "linkText": { 259 | "en": "Readme", 260 | "de": "Liesmich", 261 | "ru": "Прочти меня", 262 | "pt": "Leia-me", 263 | "nl": "Leesmij", 264 | "fr": "Lisez-moi", 265 | "it": "Leggimi", 266 | "es": "Léame", 267 | "pl": "Readme", 268 | "uk": "Прочитай мене", 269 | "zh-cn": "自述文件" 270 | }, 271 | "buttons": [ 272 | "agree", 273 | "cancel" 274 | ] 275 | } 276 | ] 277 | }, 278 | "native": { 279 | "debounce": 1000, 280 | "retention": 31536000, 281 | "dbname": "iobroker", 282 | "host": "localhost", 283 | "protocol": "http", 284 | "path": "", 285 | "port": 8086, 286 | "user": "", 287 | "password": "", 288 | "token": "", 289 | "organization": "", 290 | "round": 4, 291 | "seriesBufferMax": 0, 292 | "seriesBufferFlushInterval": 600, 293 | "changesRelogInterval": 0, 294 | "changesMinDelta": 0, 295 | "reconnectInterval": 10000, 296 | "pingInterval": 15000, 297 | "requestTimeout": 30000, 298 | "validateSSL": true, 299 | "dbversion": "1.x", 300 | "usetags": false, 301 | "pingserver": true, 302 | "blockTime": 0, 303 | "debounceTime": 0, 304 | "disableSkippedValueLogging": false, 305 | "enableLogging": false, 306 | "customRetentionDuration": 365, 307 | "relogLastValueOnStart": true 308 | }, 309 | "protectedNative": [ 310 | "password", 311 | "token" 312 | ], 313 | "encryptedNative": [ 314 | "password", 315 | "token" 316 | ], 317 | "instanceObjects": [ 318 | { 319 | "_id": "info", 320 | "type": "channel", 321 | "common": { 322 | "name": "Information" 323 | }, 324 | "native": {} 325 | }, 326 | { 327 | "_id": "info.connection", 328 | "type": "state", 329 | "common": { 330 | "role": "indicator.connected", 331 | "name": "If connected to InfluxDB", 332 | "type": "boolean", 333 | "read": true, 334 | "write": false, 335 | "def": false 336 | }, 337 | "native": {} 338 | } 339 | ], 340 | "objects": [] 341 | } 342 | -------------------------------------------------------------------------------- /lib/Database.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Database { 4 | connect () {} 5 | getDatabaseNames (callback) {} 6 | createDatabase(dbname, callback_error) {} 7 | createRetentionPolicyForDB(dbname, retention, callback_error) {} 8 | dropDatabase(dbname, callback_error) {} 9 | 10 | writeSeries(series, callback_error) {} 11 | writePoints(seriesId, pointsToSend, callback_error) {} 12 | writePoint(seriesName, values, options, callback_error) {} 13 | 14 | query(query, callback) {} 15 | 16 | calculateShardGroupDuration(retentionTime) { // in seconds 17 | // Shard Group Duration according to official Influx recommendations 18 | if (!retentionTime) { // infinite 19 | return 604800; // 7 days 20 | } else if (retentionTime < 172800) {// < 2 days 21 | return 3600; // 1 hour 22 | } else if (retentionTime >= 172800 && retentionTime <= 15811200) {// >= 2 days, <= 6 months (~182 days) 23 | return 86400; // 1 day 24 | } else {// > 6 months 25 | return 604800; // 7 days 26 | } 27 | } 28 | } 29 | 30 | module.exports = Database; 31 | -------------------------------------------------------------------------------- /lib/DatabaseInfluxDB1x.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Database = require('./Database.js'); 4 | const influx = require('influx'); 5 | 6 | class DatabaseInfluxDB1x extends Database { 7 | constructor (log, host, port, protocol, username, password, database, requestTimeout, timePrecision) { 8 | super(); 9 | 10 | this.log = log; 11 | 12 | this.host = host; 13 | this.port = port; 14 | this.protocol = protocol; 15 | this.username = username; 16 | this.password = password; 17 | this.database = database; 18 | this.timePrecision = timePrecision; // ms 19 | this.requestTimeout = requestTimeout; 20 | 21 | //disable ping 22 | this.ping = false; 23 | 24 | this.connect(); 25 | } 26 | 27 | connect () { 28 | this.log.debug(`Connect InfluxDB1: ${this.protocol}://${this.host}:${this.port} [${this.database}]`); 29 | 30 | this.connection = influx({ 31 | host: this.host, 32 | port: this.port, // optional, default 8086 33 | protocol: this.protocol, // optional, default 'http' 34 | username: this.username, 35 | password: this.password, 36 | database: this.database, 37 | timePrecision: this.timePrecision, 38 | requestTimeout: this.requestTimeout 39 | }); 40 | 41 | this.request = this.connection.request; 42 | } 43 | 44 | getDatabaseNames (callback) { 45 | this.connection.getDatabaseNames(callback); 46 | } 47 | 48 | getRetentionPolicyForDB(dbname, callback) { 49 | this.connection.query(`SHOW RETENTION POLICIES ON "${dbname}"`, (err, rows) => { 50 | if(err){ 51 | this.log.error(`Error retrieving retention policy: ${err}`); 52 | callback(err, null); 53 | } else { 54 | const regex = /(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?/; 55 | let retentionTime, retentionName = null; 56 | rows[0].forEach(row => { 57 | if (row.default) { 58 | const regMatch = row.duration.match(regex); 59 | const retHours = parseInt(regMatch[1]) || 0; 60 | const retMinutes = parseInt(regMatch[2]) || 0; 61 | const retSeconds = parseInt(regMatch[3]) || 0; 62 | this.log.debug (`Extracted retention time for ${dbname} - Hours: ${retHours} Minutes: ${retMinutes} Seconds: ${retSeconds}`); 63 | retentionTime = retHours * 60 * 60 + retMinutes * 60 + retSeconds; 64 | retentionName = row.name; 65 | } 66 | }); 67 | callback(null, {name: retentionName, time: retentionTime}); 68 | } 69 | }); 70 | } 71 | 72 | async applyRetentionPolicyToDB(dbname, retention, callback) { 73 | this.getRetentionPolicyForDB(dbname, (err, oldRetention) => { 74 | // Check, if there was an error 75 | if (err) { 76 | return callback(err); 77 | } 78 | 79 | //Check, if it needs to be changed, otherwise skip 80 | this.log.debug(`old retention: ${JSON.stringify(oldRetention)} new retention: ${retention}`); 81 | 82 | if (oldRetention.time !== null && oldRetention.time === parseInt(retention, 10)) { 83 | this.log.debug(`Retention policy for ${dbname} remains unchanged.`); 84 | return callback(false); 85 | } 86 | 87 | const shardDuration = this.calculateShardGroupDuration(retention); 88 | 89 | // Get name of currently active default policy first, to update only it. 90 | // Excodibur: As for new DBs Influx 1 creates "autogen" policy by default, is is unlikely that there is a scenario 91 | // where the policy needs to be CREATEd from scratch, since there is always one set. Just keeping it in 92 | // here for perhaps unknown config-scenarios. 93 | const command = oldRetention.name ? 'ALTER' : 'CREATE'; 94 | this.log.debug(`Retention policy will be ${command}ed`); 95 | 96 | const retentionName = oldRetention.name ? oldRetention.name : 'global'; 97 | 98 | this.log.info(`Applying retention policy (${retentionName}) for ${dbname} to ${retention === 0 ? 'infinity' : retention + ' seconds'}. Shard Duration: ${shardDuration} seconds`); 99 | this.connection.query(`${command} RETENTION POLICY "${retentionName}" ON "${dbname}" DURATION ${retention}s REPLICATION 1 SHARD DURATION ${shardDuration}s DEFAULT`, callback); 100 | }); 101 | } 102 | 103 | createDatabase(dbname, callback_error) { 104 | this.connection.createDatabase(dbname, callback_error); 105 | } 106 | 107 | dropDatabase(dbname, callback_error) { 108 | this.connection.dropDatabase(dbname, callback_error); 109 | } 110 | 111 | writeSeries(series, callback_error) { 112 | this.connection.writeSeries(series, callback_error); 113 | } 114 | 115 | writePoints(seriesId, pointsToSend, callback_error) { 116 | this.connection.writePoints(seriesId, pointsToSend, callback_error); 117 | } 118 | 119 | writePoint(seriesName, values, options, callback_error) { 120 | this.connection.writePoint(seriesName, values, options, callback_error); 121 | } 122 | 123 | query(query, callback) { 124 | this.log.debug(`Query to execute: ${query}`); 125 | this.connection.query(query, callback); 126 | } 127 | 128 | /*ping(interval) { 129 | // Ping is only used internally. As _pool is private it won't work like below 130 | this.connection._pool.ping(interval); 131 | }*/ 132 | } 133 | 134 | module.exports = { 135 | DatabaseInfluxDB1x : DatabaseInfluxDB1x 136 | }; 137 | -------------------------------------------------------------------------------- /lib/DatabaseInfluxDB2x.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Database = require('./Database.js'); 4 | const InfluxClient = require('@influxdata/influxdb-client'); 5 | const InfluxClientApis = require('@influxdata/influxdb-client-apis'); 6 | 7 | /* Old node-influx lib had some connection-pool handling that is not present in new influx lib, 8 | so to not break old code we use a fictional pool here. */ 9 | class FakeConnectionPool { 10 | constructor() { 11 | this.connections = []; 12 | } 13 | 14 | activatePool () { 15 | this.connections.push('fakehost'); 16 | } 17 | 18 | getHostsAvailable () { 19 | return this.connections; 20 | } 21 | } 22 | 23 | //Influx 2.x auth requires token, not user/pw 24 | class DatabaseInfluxDB2x extends Database { 25 | constructor(log, host, port, protocol, path, token, organization, database, requestTimeout, validateSSL, useTags, timePrecision) { 26 | super(); 27 | 28 | this.log = log; 29 | 30 | this.host = host; 31 | this.port = port; 32 | this.protocol = protocol; 33 | this.path = path; 34 | this.token = token; 35 | this.organization = organization; 36 | this.database = database; 37 | this.timePrecision = timePrecision; // ms 38 | this.requestTimeout = requestTimeout; // 30000 39 | this.useTags = useTags || false; 40 | this.validateSSL = validateSSL; 41 | 42 | this.request = new FakeConnectionPool(); 43 | 44 | this.connect(); 45 | } 46 | 47 | connect() { 48 | const url = `${this.protocol}://${this.host}:${this.port}/${this.path || ''}`; 49 | 50 | this.log.debug(`Connect InfluxDB2: ${url} [${this.database}]`); 51 | 52 | this.connection = new InfluxClient.InfluxDB({ 53 | url, 54 | token: this.token, 55 | timeout: this.requestTimeout, 56 | transportOptions: {rejectUnauthorized: this.validateSSL}, 57 | }); 58 | 59 | this.queryApi = this.connection.getQueryApi(this.organization); 60 | this.writeApi = this.connection.getWriteApi(this.organization, this.database, this.timePrecision); 61 | 62 | this.bucketsApi = new InfluxClientApis.BucketsAPI(this.connection); 63 | this.orgsApi = new InfluxClientApis.OrgsAPI(this.connection); 64 | this.healthApi = new InfluxClientApis.HealthAPI(this.connection); 65 | this.deleteApi = new InfluxClientApis.DeleteAPI(this.connection); 66 | 67 | this.bucketIds = []; 68 | 69 | this.request.activatePool(); 70 | } 71 | 72 | async deleteData(start, stop, org, bucket, predicate, callback_error) { 73 | try { 74 | await this.deleteApi.postDelete({ 75 | org, 76 | bucket, 77 | body: { 78 | start: new Date(start).toISOString(), 79 | stop: new Date(stop).toISOString(), 80 | predicate: predicate, 81 | }, 82 | }); 83 | 84 | callback_error(null); 85 | } catch (error) { 86 | this.log.error(error); 87 | callback_error(error); 88 | } 89 | } 90 | 91 | async getDatabaseNames(callback) { 92 | this.log.debug(`Organization being checked: ${this.organization}`); 93 | 94 | try { 95 | const organizations = await this.orgsApi.getOrgs({ org: this.organization }); 96 | this.log.debug(`Organizations: ${JSON.stringify(organizations)}`); 97 | if (!organizations || !organizations.orgs || !organizations.orgs.length) { 98 | throw new Error('No organizations exists or the token do not have proper permissions. Please check the token (see Readme for Tipps)!') 99 | } 100 | this.organizationId = organizations.orgs[0].id; 101 | 102 | const buckets = await this.bucketsApi.getBuckets({ orgID: this.organizationId }); 103 | this.log.debug(`Buckets: ${JSON.stringify(buckets)}`); 104 | 105 | const foundDatabases = []; 106 | 107 | buckets.buckets.forEach((bucket) => { 108 | foundDatabases.push(bucket.name); 109 | this.bucketIds[bucket.name] = bucket.id; 110 | }); 111 | 112 | callback(null, foundDatabases) 113 | } catch (error) { 114 | callback(error, null); 115 | } 116 | } 117 | 118 | async getRetentionPolicyForDB(dbname, callback) { 119 | this.log.debug(`Getting retention policy for ${dbname}`); 120 | try { 121 | const bucketData = await this.bucketsApi.getBucketsID({ bucketID: this.bucketIds[dbname] }); 122 | this.log.debug(`Found retention policy: ${bucketData.retentionRules[0].everySeconds} seconds`); 123 | callback({time: bucketData.retentionRules[0].everySeconds}); 124 | } catch (error) { 125 | this.log.error(error); 126 | callback(null); 127 | } 128 | } 129 | 130 | async applyRetentionPolicyToDB(dbname, retention, callback_error) { 131 | const shardGroupDuration = this.calculateShardGroupDuration(retention); 132 | this.log.info(`Applying retention policy for ${dbname} to ${!retention ? "infinity" : retention + " seconds"}. Shard Group Duration (calculated): ${shardGroupDuration} seconds`); 133 | try { 134 | await this.bucketsApi.patchBucketsID({ 135 | bucketID: this.bucketIds[dbname], 136 | body: { 137 | retentionRules: [{ 138 | type: 'expire', 139 | everySeconds: parseInt(retention), 140 | shardGroupDurationSeconds: shardGroupDuration 141 | }] 142 | } 143 | }); 144 | callback_error(null); 145 | } catch (error) { 146 | this.log.error(error); 147 | callback_error(error); 148 | } 149 | } 150 | 151 | async createDatabase(dbname, callback_error) { 152 | try { 153 | this.log.info(`Creating database ${dbname} for orgId ${this.organizationId}`); 154 | const newBucket = await this.bucketsApi.postBuckets({ 155 | body: { 156 | orgID: this.organizationId, 157 | name: dbname 158 | } 159 | }); 160 | 161 | this.bucketIds[dbname] = newBucket.id; 162 | callback_error(false); 163 | } catch (error) { 164 | this.log.error(error); 165 | callback_error(true); 166 | } 167 | } 168 | 169 | async dropDatabase(dbname, callback_error) { 170 | try { 171 | this.log.info(`Dropping database ${dbname} for orgId ${this.organizationId}`); 172 | await this.bucketsApi.deleteBucketsID({ bucketID: this.bucketIds[dbname] }); 173 | 174 | callback_error(false); 175 | } catch (error) { 176 | this.log.error(error); 177 | callback_error(true); 178 | } 179 | } 180 | 181 | async writeSeries(series, callback_error) { 182 | this.log.debug(`Write series: ${JSON.stringify(series)}`); 183 | 184 | const points = []; 185 | for (const [pointId, valueSets] of Object.entries(series)) { 186 | valueSets.forEach((values) => { 187 | values.forEach((value) => { 188 | points.push(this.stateValueToPoint(pointId, value)); 189 | }); 190 | }); 191 | } 192 | 193 | try { 194 | this.writeApi.writePoints(points); 195 | await this.writeApi.flush(); 196 | this.log.debug(`Points written to ${this.database}`); 197 | callback_error(); 198 | } catch (error) { 199 | callback_error(error); 200 | } 201 | } 202 | 203 | async writePoints(pointId, pointsToSend, callback_error) { 204 | this.log.debug(`Write Points: ${pointId} pointstoSend:${JSON.stringify(pointsToSend)}`); 205 | 206 | const points = []; 207 | pointsToSend.forEach((values) => { 208 | values.forEach((value) => { 209 | points.push(this.stateValueToPoint(pointId, value)); 210 | }); 211 | }); 212 | 213 | try { 214 | this.writeApi.writePoints(points); 215 | await this.writeApi.flush(); 216 | this.log.debug(`Points written to ${this.database}`); 217 | callback_error(); 218 | } catch (error) { 219 | callback_error(error); 220 | } 221 | } 222 | 223 | async writePoint(pointId, values, options, callback_error) { 224 | this.log.debug(`Write Point: ${pointId} values:${JSON.stringify(values)} options: ${JSON.stringify(options)}`); 225 | 226 | try { 227 | this.writeApi.writePoint(this.stateValueToPoint(pointId, values)); 228 | await this.writeApi.flush(); 229 | this.log.debug(`Point written to ${this.database}`); 230 | callback_error(); 231 | } catch (error) { 232 | this.log.warn(`Point could not be written to database: ${this.database}`); 233 | callback_error(error); 234 | } 235 | 236 | } 237 | 238 | stateValueToPoint(pointName, stateValue) { 239 | let point = null; 240 | 241 | if (this.useTags) { 242 | point = new InfluxClient.Point(pointName) 243 | .timestamp(stateValue.time) 244 | .tag('q', String(stateValue.q)) 245 | .tag('ack', String(stateValue.ack)) 246 | .tag('from', stateValue.from); 247 | } else { 248 | point = new InfluxClient.Point(pointName) 249 | .timestamp(stateValue.time) 250 | .floatField('q', stateValue.q) 251 | .booleanField('ack', stateValue.ack) 252 | .stringField('from', stateValue.from); 253 | } 254 | 255 | switch (typeof stateValue.value) { 256 | case 'boolean': 257 | point.booleanField('value', stateValue.value); 258 | break; 259 | case 'number': 260 | point.floatField('value', parseFloat(stateValue.value)); 261 | break; 262 | case 'string': 263 | default: 264 | point.stringField('value', stateValue.value); 265 | break; 266 | } 267 | return point; 268 | } 269 | 270 | query(query, callback) { 271 | this.log.debug(`Query to execute: ${query}`); 272 | let rows = []; 273 | 274 | this.queryApi.queryRows(query, { 275 | next (row, tableMeta) { 276 | const fields = tableMeta.toObject(row); 277 | 278 | //Columns "_time" and "_value" are mapped to "time" and "value" for backwards compatibility 279 | if (fields['_time'] !== null) 280 | fields['time'] = fields['_time']; 281 | 282 | //if (fields["_value"] !== null) 283 | // fields["value"] = fields["_value"]; 284 | 285 | rows.push(fields); 286 | 287 | // console.log(JSON.stringify(o, null, 2)) 288 | }, 289 | error (error) { 290 | //Ignore errors that are related to an empty range. The handling of this currently seems inconsistent for flux. 291 | //See also https://github.com/influxdata/flux/issues/3543 292 | if (error.message.match('.*cannot query an empty range.*')) 293 | callback(null, rows); 294 | else 295 | callback(error, null); 296 | }, 297 | complete () { 298 | callback(null, rows); 299 | 300 | } 301 | }); 302 | } 303 | 304 | getMetaDataStorageType (callback) { 305 | const queries = [ 306 | `import "influxdata/influxdb/schema" schema.tagKeys(bucket: "${this.database}")`, 307 | `import "influxdata/influxdb/schema" schema.fieldKeys(bucket: "${this.database}")`, 308 | ]; 309 | 310 | this.queries(queries, (error, result) => { 311 | let storageType = "none"; 312 | if (error) { 313 | callback(error, null); 314 | } else { 315 | this.log.debug(`Result of metadata storage type check: ${JSON.stringify(result)}`); 316 | for (let i = 0; i <= 1; i++) { 317 | result[i].forEach(row => { 318 | switch(row._value) { 319 | case 'q': 320 | case 'ack': 321 | case 'from': 322 | storageType = i == 0 ? 'tags' : 'fields'; 323 | return; 324 | } 325 | }); 326 | } 327 | callback(null, storageType); 328 | } 329 | 330 | }); 331 | } 332 | 333 | async queries (queries, callback) { 334 | const collectedRows = []; 335 | let success = false; 336 | let errors = []; 337 | for (const query of queries) { 338 | await new Promise((resolve, reject) => { 339 | this.query(query, (error, rows) => { 340 | if (error) { 341 | this.log.warn(`Error in query "${query}": ${error}`); 342 | errors.push(error); 343 | collectedRows.push([]); 344 | } else { 345 | success = true; 346 | collectedRows.push(rows); 347 | } 348 | resolve(); 349 | }); 350 | }); 351 | } 352 | 353 | let retError = null; 354 | if (errors.length) { 355 | retError = new Error(`${errors.length} Error happened while processing ${queries.length} queries`); 356 | retError.errors = errors; 357 | } 358 | callback(retError, success ? collectedRows : null); 359 | } 360 | 361 | ping(interval) { 362 | // can't do much with interval, so ignoring it for compatibility reasons 363 | return this.healthApi.getHealth() 364 | .then(result => result.status === 'pass' ? [{ online: true }] : [{ online: false }]); 365 | } 366 | } 367 | 368 | module.exports = { 369 | DatabaseInfluxDB2x: DatabaseInfluxDB2x 370 | } 371 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iobroker.influxdb", 3 | "description": "Log states in InfluxDB", 4 | "version": "4.0.3", 5 | "author": "bluefox ", 6 | "contributors": [ 7 | "bluefox ", 8 | "Apollon77", 9 | "Excodibur" 10 | ], 11 | "homepage": "https://github.com/ioBroker/ioBroker.influxdb", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/ioBroker/ioBroker.influxdb" 15 | }, 16 | "engines": { 17 | "node": ">=16" 18 | }, 19 | "keywords": [ 20 | "ioBroker", 21 | "log data", 22 | "home automation" 23 | ], 24 | "optionalDependencies": {}, 25 | "dependencies": { 26 | "@influxdata/influxdb-client": "^1.33.2", 27 | "@influxdata/influxdb-client-apis": "^1.33.2", 28 | "@iobroker/adapter-core": "^3.1.4", 29 | "influx": "^4.2.3" 30 | }, 31 | "devDependencies": { 32 | "@alcalzone/release-script": "^3.7.0", 33 | "@alcalzone/release-script-plugin-iobroker": "^3.7.0", 34 | "@alcalzone/release-script-plugin-license": "^3.7.0", 35 | "@iobroker/adapter-dev": "^1.3.0", 36 | "mocha": "^10.7.3", 37 | "chai": "^4.4.1" 38 | }, 39 | "bugs": { 40 | "url": "https://github.com/ioBroker/ioBroker.influxdb/issues" 41 | }, 42 | "main": "main.js", 43 | "files": [ 44 | "admin/", 45 | "docs/", 46 | "lib/", 47 | "io-package.json", 48 | "LICENSE", 49 | "RetentionPolicies.md", 50 | "main.js" 51 | ], 52 | "scripts": { 53 | "test": "node node_modules/mocha/bin/mocha --exit", 54 | "build:lang": "gulp adminWords2languages", 55 | "release": "release-script", 56 | "release-patch": "release-script patch --yes", 57 | "release-minor": "release-script minor --yes", 58 | "release-major": "release-script major --yes", 59 | "translate": "translate-adapter" 60 | }, 61 | "license": "MIT" 62 | } 63 | -------------------------------------------------------------------------------- /test/mocha.setup.js: -------------------------------------------------------------------------------- 1 | process.on("unhandledRejection", (r) => { throw r; }); 2 | -------------------------------------------------------------------------------- /test/testAdapter.js: -------------------------------------------------------------------------------- 1 | /* jshint -W097 */ 2 | /* jshint strict: false */ 3 | /* jslint node: true */ 4 | /* jshint expr: true */ 5 | const expect = require('chai').expect; 6 | const setup = require('./lib/setup'); 7 | const tests = require('./lib/testcases'); 8 | 9 | let objects = null; 10 | let states = null; 11 | let onStateChanged = null; 12 | let sendToID = 1; 13 | 14 | const adapterShortName = setup.adapterName.substring(setup.adapterName.indexOf('.') + 1); 15 | 16 | let now; 17 | 18 | function checkConnectionOfAdapter(cb, counter) { 19 | counter = counter || 0; 20 | console.log(`Try check #${counter}`); 21 | if (counter > 30) { 22 | cb && cb('Cannot check connection'); 23 | return; 24 | } 25 | 26 | console.log(`Checking alive key for key : ${adapterShortName}`); 27 | states.getState(`system.adapter.${adapterShortName}.0.alive`, (err, state) => { 28 | err && console.error(err); 29 | if (state && state.val) { 30 | cb && cb(); 31 | } else { 32 | setTimeout(() => 33 | checkConnectionOfAdapter(cb, counter + 1) 34 | , 1000); 35 | } 36 | }); 37 | } 38 | 39 | function checkValueOfState(id, value, cb, counter) { 40 | counter = counter || 0; 41 | if (counter > 20) { 42 | cb && cb(`Cannot check value Of State ${id}`); 43 | return; 44 | } 45 | 46 | states.getState(id, (err, state) => { 47 | err && console.error(err); 48 | if (value === null && !state) { 49 | cb && cb(); 50 | } else 51 | if (state && (value === undefined || state.val === value)) { 52 | cb && cb(); 53 | } else { 54 | setTimeout(() => 55 | checkValueOfState(id, value, cb, counter + 1) 56 | , 500); 57 | } 58 | }); 59 | } 60 | 61 | function sendTo(target, command, message, callback) { 62 | onStateChanged = function (id, state) { 63 | if (id === 'messagebox.system.adapter.test.0') { 64 | callback(state.message); 65 | } 66 | }; 67 | 68 | states.pushMessage(`system.adapter.${target}`, { 69 | command: command, 70 | message: message, 71 | from: 'system.adapter.test.0', 72 | callback: { 73 | message: message, 74 | id: sendToID++, 75 | ack: false, 76 | time: Date.now() 77 | } 78 | }); 79 | } 80 | 81 | describe(`Test ${adapterShortName} adapter`, function () { 82 | before(`Test ${adapterShortName} adapter: Start js-controller`, function (_done) { 83 | this.timeout(600000); // because of first install from npm 84 | 85 | setup.setupController(async () => { 86 | const config = await setup.getAdapterConfig(); 87 | // enable adapter 88 | config.common.enabled = true; 89 | config.common.loglevel = 'debug'; 90 | 91 | if (process.env.INFLUXDB2) { 92 | const authToken = JSON.parse(process.env.AUTHTOKEN).token; 93 | console.log(`AUTHTOKEN=${process.env.AUTHTOKEN}`); 94 | console.log(`extracted token =${authToken}`); 95 | config.native.dbversion = '2.x'; 96 | 97 | let secret = await setup.getSecret(); 98 | if (secret === null) { 99 | secret = 'Zgfr56gFe87jJOM'; 100 | } 101 | 102 | console.log(`############SECRET: ${secret}`); 103 | config.native.token = setup.encrypt(secret, 'test-token'); //authToken; 104 | config.native.organization = 'test-org'; 105 | } else if (process.env.INFLUX_DB1_HOST) { 106 | config.native.host = process.env.INFLUX_DB1_HOST; 107 | } 108 | config.native.enableDebugLogs = true; 109 | 110 | await setup.setAdapterConfig(config.common, config.native); 111 | 112 | setup.startController( 113 | true, 114 | (id, obj) => {}, 115 | (id, state) => onStateChanged && onStateChanged(id, state), 116 | async (_objects, _states) => { 117 | objects = _objects; 118 | states = _states; 119 | 120 | await tests.preInit(objects, states, sendTo, adapterShortName); 121 | 122 | _done(); 123 | }); 124 | }); 125 | }); 126 | 127 | it(`Test ${adapterShortName} adapter: Check if adapter started`, function (done) { 128 | this.timeout(60000); 129 | 130 | checkConnectionOfAdapter(res => { 131 | res && console.log(res); 132 | expect(res).not.to.be.equal('Cannot check connection'); 133 | sendTo('influxdb.0', 'enableHistory', { 134 | id: 'system.adapter.influxdb.0.memHeapTotal', 135 | options: { 136 | changesOnly: true, 137 | debounce: 0, 138 | retention: 31536000, 139 | storageType: 'String' 140 | } 141 | }, result => { 142 | expect(result.error).to.be.undefined; 143 | expect(result.success).to.be.true; 144 | 145 | sendTo('influxdb.0', 'enableHistory', { 146 | id: 'system.adapter.influxdb.0.uptime', 147 | options: { 148 | changesOnly: false, 149 | debounce: 0, 150 | retention: 31536000, 151 | storageType: 'Boolean' 152 | } 153 | }, result => { 154 | expect(result.error).to.be.undefined; 155 | expect(result.success).to.be.true; 156 | 157 | sendTo('influxdb.0', 'enableHistory', { 158 | id: 'system.adapter.influxdb.0.memHeapUsed', 159 | options: { 160 | changesOnly: false, 161 | debounce: 0, 162 | retention: 31536000, 163 | } 164 | }, result => { 165 | expect(result.error).to.be.undefined; 166 | expect(result.success).to.be.true; 167 | 168 | // wait till adapter receives the new settings 169 | setTimeout(() => 170 | done(), 2000); 171 | }); 172 | }); 173 | }); 174 | }); 175 | }); 176 | 177 | tests.register(it, expect, sendTo, adapterShortName, false, 0, 3); 178 | 179 | it(`Test ${adapterShortName}: Write string value for memHeapUsed into DB to force a type conflict`, function (done) { 180 | this.timeout(5000); 181 | now = Date.now(); 182 | 183 | states.setState('system.adapter.influxdb.0.memHeapUsed', {val: 'Blubb', ts: now - 20000, from: 'test.0'}, err => { 184 | err && console.log(err); 185 | setTimeout(() => { 186 | //sendTo('influxdb.0', 'flushBuffer', {id: 'system.adapter.influxdb.0.memHeapUsed'}, result => { 187 | sendTo('influxdb.0', 'flushBuffer', {}, result => { 188 | expect(result.error).to.be.not.ok; 189 | done(); 190 | }); 191 | }, 1000); 192 | }); 193 | }); 194 | 195 | it(`Test ${adapterShortName}: Read values from DB using query`, function (done) { 196 | this.timeout(10000); 197 | 198 | let query = 'SELECT * FROM "influxdb.0.testValue"'; 199 | if (process.env.INFLUXDB2) { 200 | const date = Date.now(); 201 | query = `from(bucket: "iobroker") |> range(start: -2d) |> filter(fn: (r) => r["_measurement"] == "influxdb.0.testValue") |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value") |> group() |> sort(columns:["_time"], desc: false)`; 202 | } 203 | sendTo('influxdb.0', 'query', query, result => { 204 | console.log(JSON.stringify(result.result, null, 2)); 205 | expect(result.result[0].length).to.be.at.least(5); 206 | let found = 0; 207 | for (let i = 0; i < result.result[0].length; i++) { 208 | if (result.result[0][i].value >= 1 && result.result[0][i].value <= 3) { 209 | found ++; 210 | } 211 | } 212 | expect(found).to.be.equal(14); 213 | 214 | done(); 215 | }); 216 | }); 217 | 218 | it(`Test ${adapterShortName}: Check Datapoint Types`, function (done) { 219 | this.timeout(65000); 220 | 221 | if (process.env.INFLUXDB2) { 222 | // TODO: Find Flux equivalent! 223 | return done(); 224 | } 225 | 226 | setTimeout(function() { 227 | let query = 'SHOW FIELD KEYS FROM "influxdb.0.testValue"'; 228 | sendTo('influxdb.0', 'query', query, result => { 229 | console.log(`result: ${JSON.stringify(result.result, null, 2)}`); 230 | let found = false; 231 | for (let i = 0; i < result.result[0].length; i++) { 232 | if (result.result[0][i].fieldKey === 'value') { 233 | found = true; 234 | expect(result.result[0][i].fieldType).to.be.equal('float'); 235 | break; 236 | } 237 | } 238 | expect(found).to.be.true; 239 | 240 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.memHeapTotal"', result2 => { 241 | console.log(`result2: ${JSON.stringify(result2.result, null, 2)}`); 242 | let found = false; 243 | for (let i = 0; i < result2.result[0].length; i++) { 244 | if (result2.result[0][i].fieldKey === 'value') { 245 | found = true; 246 | expect(result2.result[0][i].fieldType).to.be.equal('string'); 247 | break; 248 | } 249 | } 250 | expect(found).to.be.true; 251 | 252 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.uptime"', result3 => { 253 | console.log(`result3: ${JSON.stringify(result3.result, null, 2)}`); 254 | let found = false; 255 | for (let i = 0; i < result3.result[0].length; i++) { 256 | if (result3.result[0][i].fieldKey === 'value') { 257 | found = true; 258 | expect(result3.result[0][i].fieldType).to.be.equal('boolean'); 259 | break; 260 | } 261 | } 262 | expect(found).to.be.true; 263 | 264 | setTimeout(() => 265 | done(), 3000); 266 | }); 267 | }); 268 | }); 269 | }, 60000); 270 | }); 271 | 272 | it(`Test ${adapterShortName}: Check that storageType is set now for memHeapUsed`, function (done) { 273 | this.timeout(5000); 274 | 275 | objects.getObject('system.adapter.influxdb.0.memHeapUsed', (err, obj) => { 276 | expect(err).to.be.null; 277 | console.log(JSON.stringify(obj, null, 2)); 278 | expect(obj.common.custom['influxdb.0'].storageType).to.be.equal('Number'); 279 | done(); 280 | }); 281 | }); 282 | 283 | after(`Test ${adapterShortName} adapter: Stop js-controller`, function (done) { 284 | this.timeout(15000); 285 | 286 | setup.stopController(normalTerminated => { 287 | console.log(`Adapter normal terminated: ${normalTerminated}`); 288 | setTimeout(done, 2000); 289 | }); 290 | }); 291 | }); 292 | -------------------------------------------------------------------------------- /test/testAdapterBuffer.js: -------------------------------------------------------------------------------- 1 | /* jshint -W097 */ 2 | /* jshint strict: false */ 3 | /* jslint node: true */ 4 | /* jshint expr: true */ 5 | const expect = require('chai').expect; 6 | const setup = require('./lib/setup'); 7 | const tests = require('./lib/testcases'); 8 | 9 | let objects = null; 10 | let states = null; 11 | let onStateChanged = null; 12 | let sendToID = 1; 13 | 14 | const adapterShortName = setup.adapterName.substring(setup.adapterName.indexOf('.') + 1); 15 | 16 | let now; 17 | 18 | function checkConnectionOfAdapter(cb, counter) { 19 | counter = counter || 0; 20 | console.log('Try check #' + counter); 21 | if (counter > 30) { 22 | cb && cb('Cannot check connection'); 23 | return; 24 | } 25 | 26 | console.log('Checking alive key for key: ' + adapterShortName); 27 | states.getState(`system.adapter.${adapterShortName}.0.alive`, (err, state) => { 28 | err && console.error(err); 29 | if (state && state.val) { 30 | cb && cb(); 31 | } else { 32 | setTimeout(() => 33 | checkConnectionOfAdapter(cb, counter + 1), 1000); 34 | } 35 | }); 36 | } 37 | 38 | function checkValueOfState(id, value, cb, counter) { 39 | counter = counter || 0; 40 | if (counter > 20) { 41 | return cb && cb('Cannot check value Of State ' + id); 42 | } 43 | 44 | states.getState(id, (err, state) => { 45 | err && console.error(err); 46 | if (value === null && !state) { 47 | cb && cb(); 48 | } else 49 | if (state && (value === undefined || state.val === value)) { 50 | cb && cb(); 51 | } else { 52 | setTimeout(() => 53 | checkValueOfState(id, value, cb, counter + 1), 500); 54 | } 55 | }); 56 | } 57 | 58 | function sendTo(target, command, message, callback) { 59 | onStateChanged = function (id, state) { 60 | if (id === 'messagebox.system.adapter.test.0') { 61 | callback(state.message); 62 | } 63 | }; 64 | 65 | states.pushMessage('system.adapter.' + target, { 66 | command: command, 67 | message: message, 68 | from: 'system.adapter.test.0', 69 | callback: { 70 | message: message, 71 | id: sendToID++, 72 | ack: false, 73 | time: Date.now() 74 | } 75 | }); 76 | } 77 | 78 | describe(`Test ${adapterShortName} adapter with Buffered write`, function () { 79 | before(`Test ${adapterShortName} adapter: Start js-controller`, function (_done) { 80 | this.timeout(600000); // because of first install from npm 81 | 82 | setup.setupController(async () => { 83 | const config = await setup.getAdapterConfig(); 84 | // enable adapter 85 | config.common.enabled = true; 86 | config.common.loglevel = 'debug'; 87 | 88 | if (process.env.INFLUXDB2) { 89 | const authToken = JSON.parse(process.env.AUTHTOKEN).token; 90 | console.log('AUTHTOKEN=' + process.env.AUTHTOKEN); 91 | console.log('extracted token =' + authToken); 92 | config.native.dbversion = '2.x'; 93 | 94 | let secret = await setup.getSecret(); 95 | if (secret === null) 96 | secret = 'Zgfr56gFe87jJOM'; 97 | 98 | config.native.token = setup.encrypt(secret, 'test-token'); //authToken; 99 | config.native.organization = 'test-org'; 100 | } else if (process.env.INFLUX_DB1_HOST) { 101 | config.native.host = process.env.INFLUX_DB1_HOST; 102 | } 103 | 104 | config.native.seriesBufferFlushInterval = 30; 105 | config.native.seriesBufferMax = 5; 106 | config.native.retention = -1; 107 | config.native.customRetentionDuration = 10; 108 | config.native.dbname = 'otheriobroker'; 109 | 110 | config.native.enableDebugLogs = true; 111 | 112 | await setup.setAdapterConfig(config.common, config.native); 113 | 114 | setup.startController( 115 | true, 116 | (id, obj) => {}, 117 | (id, state) => onStateChanged && onStateChanged(id, state), 118 | async (_objects, _states) => { 119 | objects = _objects; 120 | states = _states; 121 | 122 | await tests.preInit(objects, states, sendTo, adapterShortName); 123 | 124 | _done(); 125 | }); 126 | }); 127 | }); 128 | 129 | it(`Test ${adapterShortName} adapter: Check if adapter started`, function (done) { 130 | this.timeout(60000); 131 | 132 | checkConnectionOfAdapter(res => { 133 | res && console.log(res); 134 | expect(res).not.to.be.equal('Cannot check connection'); 135 | 136 | objects.setObject('system.adapter.test.0', { 137 | common: {}, 138 | type: 'instance' 139 | }, 140 | () => { 141 | states.subscribeMessage('system.adapter.test.0'); 142 | 143 | sendTo('influxdb.0', 'enableHistory', { 144 | id: 'system.adapter.influxdb.0.memHeapTotal', 145 | options: { 146 | changesOnly: true, 147 | debounce: 0, 148 | retention: 31536000, 149 | storageType: 'String' 150 | } 151 | }, result => { 152 | expect(result.error).to.be.undefined; 153 | expect(result.success).to.be.true; 154 | 155 | sendTo('influxdb.0', 'enableHistory', { 156 | id: 'system.adapter.influxdb.0.uptime', 157 | options: { 158 | changesOnly: false, 159 | debounce: 0, 160 | retention: 31536000, 161 | storageType: 'Boolean' 162 | } 163 | }, result => { 164 | expect(result.error).to.be.undefined; 165 | expect(result.success).to.be.true; 166 | 167 | sendTo('influxdb.0', 'enableHistory', { 168 | id: 'system.adapter.influxdb.0.memHeapUsed', 169 | options: { 170 | changesOnly: false, 171 | debounce: 0, 172 | retention: 31536000, 173 | } 174 | }, result => { 175 | expect(result.error).to.be.undefined; 176 | expect(result.success).to.be.true; 177 | 178 | setTimeout(() => 179 | done(), 2000); 180 | }); 181 | }); 182 | }); 183 | }); 184 | }); 185 | }); 186 | 187 | tests.register(it, expect, sendTo, adapterShortName, false, 0, 3); 188 | 189 | it(`Test ${adapterShortName}: Write string value for memHeapUsed into DB to force a type conflict`, function (done) { 190 | this.timeout(5000); 191 | now = Date.now(); 192 | 193 | states.setState('system.adapter.influxdb.0.memHeapUsed', {val: 'Blubb', ts: now - 20000, from: 'test.0'}, (err) => { 194 | err && console.log(err); 195 | setTimeout(() => { 196 | //sendTo('influxdb.0', 'flushBuffer', {id: 'system.adapter.influxdb.0.memHeapUsed'}, result => { 197 | sendTo('influxdb.0', 'flushBuffer', {}, result => { 198 | expect(result.error).to.be.not.ok; 199 | done(); 200 | }); 201 | }, 1000); 202 | }); 203 | }); 204 | 205 | it(`Test ${adapterShortName}: Read values from DB using query`, function (done) { 206 | this.timeout(10000); 207 | 208 | let query = 'SELECT * FROM "influxdb.0.testValue"'; 209 | if (process.env.INFLUXDB2) { 210 | const date = Date.now(); 211 | query = `from(bucket: "iobroker") |> range(start: -2d) |> filter(fn: (r) => r["_measurement"] == "influxdb.0.testValue") |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value") |> group() |> sort(columns:["_time"], desc: false)`; 212 | } 213 | 214 | sendTo('influxdb.0', 'query', query, result => { 215 | console.log(JSON.stringify(result.result, null, 2)); 216 | expect(result.result[0].length).to.be.at.least(5); 217 | let found = 0; 218 | for (let i = 0; i < result.result[0].length; i++) { 219 | if (result.result[0][i].value >= 1 && result.result[0][i].value <= 3) { 220 | found ++; 221 | } 222 | } 223 | expect(found).to.be.equal(14); 224 | 225 | done(); 226 | }); 227 | }); 228 | 229 | it(`Test ${adapterShortName}: Check Datapoint Types`, function (done) { 230 | this.timeout(65000); 231 | 232 | if (process.env.INFLUXDB2) { 233 | // TODO: FIndFlux equivalent! 234 | return done(); 235 | } 236 | 237 | setTimeout(function() { 238 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "influxdb.0.testValue"', result => { 239 | console.log('result: ' + JSON.stringify(result.result, null, 2)); 240 | let found = false; 241 | for (let i = 0; i < result.result[0].length; i++) { 242 | if (result.result[0][i].fieldKey === 'value') { 243 | found = true; 244 | expect(result.result[0][i].fieldType).to.be.equal('float'); 245 | break; 246 | } 247 | } 248 | expect(found).to.be.true; 249 | 250 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.memHeapTotal"', function (result2) { 251 | console.log('result2: ' + JSON.stringify(result2.result, null, 2)); 252 | let found = false; 253 | for (let i = 0; i < result2.result[0].length; i++) { 254 | if (result2.result[0][i].fieldKey === 'value') { 255 | found = true; 256 | expect(result2.result[0][i].fieldType).to.be.equal('string'); 257 | break; 258 | } 259 | } 260 | expect(found).to.be.true; 261 | 262 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.uptime"', function (result3) { 263 | console.log('result3: ' + JSON.stringify(result3.result, null, 2)); 264 | let found = false; 265 | for (let i = 0; i < result3.result[0].length; i++) { 266 | if (result3.result[0][i].fieldKey === 'value') { 267 | found = true; 268 | expect(result3.result[0][i].fieldType).to.be.equal('boolean'); 269 | break; 270 | } 271 | } 272 | expect(found).to.be.true; 273 | 274 | setTimeout(() => 275 | done(), 3000); 276 | }); 277 | }); 278 | }); 279 | }, 60000); 280 | }); 281 | 282 | it(`Test ${adapterShortName}: Check that storageType is set now for memHeapUsed`, function (done) { 283 | this.timeout(5000); 284 | 285 | objects.getObject('system.adapter.influxdb.0.memHeapUsed', (err, obj) => { 286 | expect(err).to.be.null; 287 | console.log(JSON.stringify(obj, null, 2)); 288 | expect(obj.common.custom['influxdb.0'].storageType).to.be.equal('Number'); 289 | done(); 290 | }); 291 | }); 292 | 293 | after(`Test ${adapterShortName} adapter: Stop js-controller`, function (done) { 294 | this.timeout(15000); 295 | 296 | setup.stopController(normalTerminated => { 297 | console.log('Adapter normal terminated: ' + normalTerminated); 298 | setTimeout(done, 2000); 299 | }); 300 | }); 301 | }); 302 | -------------------------------------------------------------------------------- /test/testAdapterExisting.js: -------------------------------------------------------------------------------- 1 | /* jshint -W097 */ 2 | /* jshint strict: false */ 3 | /* jslint node: true */ 4 | /* jshint expr: true */ 5 | const expect = require('chai').expect; 6 | const setup = require('./lib/setup'); 7 | const tests = require('./lib/testcases'); 8 | 9 | let objects = null; 10 | let states = null; 11 | let onStateChanged = null; 12 | let sendToID = 1; 13 | 14 | const adapterShortName = setup.adapterName.substring(setup.adapterName.indexOf('.') + 1); 15 | 16 | let now; 17 | 18 | function checkConnectionOfAdapter(cb, counter) { 19 | counter = counter || 0; 20 | console.log(`Try check #${counter}`); 21 | if (counter > 30) { 22 | cb && cb('Cannot check connection'); 23 | return; 24 | } 25 | 26 | console.log(`Checking alive key for key : ${adapterShortName}`); 27 | states.getState(`system.adapter.${adapterShortName}.0.alive`, (err, state) => { 28 | err && console.error(err); 29 | if (state && state.val) { 30 | cb && cb(); 31 | } else { 32 | setTimeout(() => 33 | checkConnectionOfAdapter(cb, counter + 1) 34 | , 1000); 35 | } 36 | }); 37 | } 38 | 39 | function checkValueOfState(id, value, cb, counter) { 40 | counter = counter || 0; 41 | if (counter > 20) { 42 | cb && cb(`Cannot check value Of State ${id}`); 43 | return; 44 | } 45 | 46 | states.getState(id, (err, state) => { 47 | err && console.error(err); 48 | if (value === null && !state) { 49 | cb && cb(); 50 | } else 51 | if (state && (value === undefined || state.val === value)) { 52 | cb && cb(); 53 | } else { 54 | setTimeout(() => 55 | checkValueOfState(id, value, cb, counter + 1) 56 | , 500); 57 | } 58 | }); 59 | } 60 | 61 | function sendTo(target, command, message, callback) { 62 | onStateChanged = function (id, state) { 63 | if (id === 'messagebox.system.adapter.test.0') { 64 | callback(state.message); 65 | } 66 | }; 67 | 68 | states.pushMessage(`system.adapter.${target}`, { 69 | command: command, 70 | message: message, 71 | from: 'system.adapter.test.0', 72 | callback: { 73 | message: message, 74 | id: sendToID++, 75 | ack: false, 76 | time: Date.now() 77 | } 78 | }); 79 | } 80 | 81 | describe(`Test ${adapterShortName} adapter`, function () { 82 | before(`Test ${adapterShortName} adapter: Start js-controller`, function (_done) { 83 | this.timeout(600000); // because of first install from npm 84 | 85 | setup.setupController(async () => { 86 | const config = await setup.getAdapterConfig(); 87 | // enable adapter 88 | config.common.enabled = true; 89 | config.common.loglevel = 'debug'; 90 | 91 | if (process.env.INFLUXDB2) { 92 | const authToken = JSON.parse(process.env.AUTHTOKEN).token; 93 | console.log(`AUTHTOKEN=${process.env.AUTHTOKEN}`); 94 | console.log(`extracted token =${authToken}`); 95 | config.native.dbversion = '2.x'; 96 | 97 | let secret = await setup.getSecret(); 98 | if (secret === null) { 99 | secret = 'Zgfr56gFe87jJOM'; 100 | } 101 | 102 | console.log(`############SECRET: ${secret}`); 103 | config.native.token = setup.encrypt(secret, 'test-token'); //authToken; 104 | config.native.organization = 'test-org'; 105 | } else if (process.env.INFLUX_DB1_HOST) { 106 | config.native.host = process.env.INFLUX_DB1_HOST; 107 | } 108 | config.native.enableDebugLogs = true; 109 | 110 | await setup.setAdapterConfig(config.common, config.native); 111 | 112 | setup.startController( 113 | true, 114 | (id, obj) => {}, 115 | (id, state) => onStateChanged && onStateChanged(id, state), 116 | async (_objects, _states) => { 117 | objects = _objects; 118 | states = _states; 119 | 120 | await tests.preInit(objects, states, sendTo, adapterShortName); 121 | 122 | _done(); 123 | }); 124 | }); 125 | }); 126 | 127 | it(`Test ${adapterShortName} adapter: Check if adapter started`, function (done) { 128 | this.timeout(60000); 129 | 130 | checkConnectionOfAdapter(res => { 131 | res && console.log(res); 132 | expect(res).not.to.be.equal('Cannot check connection'); 133 | sendTo('influxdb.0', 'enableHistory', { 134 | id: 'system.adapter.influxdb.0.memHeapTotal', 135 | options: { 136 | changesOnly: true, 137 | debounce: 0, 138 | retention: 31536000, 139 | storageType: 'String' 140 | } 141 | }, result => { 142 | expect(result.error).to.be.undefined; 143 | expect(result.success).to.be.true; 144 | 145 | sendTo('influxdb.0', 'enableHistory', { 146 | id: 'system.adapter.influxdb.0.uptime', 147 | options: { 148 | changesOnly: false, 149 | debounce: 0, 150 | retention: 31536000, 151 | storageType: 'Boolean' 152 | } 153 | }, result => { 154 | expect(result.error).to.be.undefined; 155 | expect(result.success).to.be.true; 156 | 157 | sendTo('influxdb.0', 'enableHistory', { 158 | id: 'system.adapter.influxdb.0.memHeapUsed', 159 | options: { 160 | changesOnly: false, 161 | debounce: 0, 162 | retention: 31536000, 163 | } 164 | }, result => { 165 | expect(result.error).to.be.undefined; 166 | expect(result.success).to.be.true; 167 | 168 | // wait till adapter receives the new settings 169 | setTimeout(() => 170 | done(), 2000); 171 | }); 172 | }); 173 | }); 174 | }); 175 | }); 176 | 177 | tests.register(it, expect, sendTo, adapterShortName, false, 1, 3); 178 | 179 | it(`Test ${adapterShortName}: Write string value for memHeapUsed into DB to force a type conflict`, function (done) { 180 | this.timeout(5000); 181 | now = Date.now(); 182 | 183 | states.setState('system.adapter.influxdb.0.memHeapUsed', {val: 'Blubb', ts: now - 20000, from: 'test.0'}, err => { 184 | err && console.log(err); 185 | setTimeout(() => { 186 | //sendTo('influxdb.0', 'flushBuffer', {id: 'system.adapter.influxdb.0.memHeapUsed'}, result => { 187 | sendTo('influxdb.0', 'flushBuffer', {}, result => { 188 | expect(result.error).to.be.not.ok; 189 | done(); 190 | }); 191 | }, 1000); 192 | }); 193 | }); 194 | 195 | it(`Test ${adapterShortName}: Read values from DB using query`, function (done) { 196 | this.timeout(10000); 197 | 198 | let query = 'SELECT * FROM "influxdb.0.testValue"'; 199 | if (process.env.INFLUXDB2) { 200 | const date = Date.now(); 201 | query = `from(bucket: "iobroker") |> range(start: -2d) |> filter(fn: (r) => r["_measurement"] == "influxdb.0.testValue") |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value") |> group() |> sort(columns:["_time"], desc: false)`; 202 | } 203 | sendTo('influxdb.0', 'query', query, result => { 204 | console.log(JSON.stringify(result.result, null, 2)); 205 | expect(result.result[0].length).to.be.at.least(5); 206 | let found = 0; 207 | for (let i = 0; i < result.result[0].length; i++) { 208 | if (result.result[0][i].value >= 1 && result.result[0][i].value <= 3) { 209 | found ++; 210 | } 211 | } 212 | expect(found).to.be.equal(28); 213 | 214 | done(); 215 | }); 216 | }); 217 | 218 | it(`Test ${adapterShortName}: Check Datapoint Types`, function (done) { 219 | this.timeout(65000); 220 | 221 | if (process.env.INFLUXDB2) { 222 | // TODO: Find Flux equivalent! 223 | return done(); 224 | } 225 | 226 | setTimeout(function() { 227 | let query = 'SHOW FIELD KEYS FROM "influxdb.0.testValue"'; 228 | sendTo('influxdb.0', 'query', query, result => { 229 | console.log(`result: ${JSON.stringify(result.result, null, 2)}`); 230 | let found = false; 231 | for (let i = 0; i < result.result[0].length; i++) { 232 | if (result.result[0][i].fieldKey === 'value') { 233 | found = true; 234 | expect(result.result[0][i].fieldType).to.be.equal('float'); 235 | break; 236 | } 237 | } 238 | expect(found).to.be.true; 239 | 240 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.memHeapTotal"', result2 => { 241 | console.log(`result2: ${JSON.stringify(result2.result, null, 2)}`); 242 | let found = false; 243 | for (let i = 0; i < result2.result[0].length; i++) { 244 | if (result2.result[0][i].fieldKey === 'value') { 245 | found = true; 246 | expect(result2.result[0][i].fieldType).to.be.equal('string'); 247 | break; 248 | } 249 | } 250 | expect(found).to.be.true; 251 | 252 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.uptime"', result3 => { 253 | console.log(`result3: ${JSON.stringify(result3.result, null, 2)}`); 254 | let found = false; 255 | for (let i = 0; i < result3.result[0].length; i++) { 256 | if (result3.result[0][i].fieldKey === 'value') { 257 | found = true; 258 | expect(result3.result[0][i].fieldType).to.be.equal('boolean'); 259 | break; 260 | } 261 | } 262 | expect(found).to.be.true; 263 | 264 | setTimeout(() => 265 | done(), 3000); 266 | }); 267 | }); 268 | }); 269 | }, 60000); 270 | }); 271 | 272 | it(`Test ${adapterShortName}: Check that storageType is set now for memHeapUsed`, function (done) { 273 | this.timeout(5000); 274 | 275 | objects.getObject('system.adapter.influxdb.0.memHeapUsed', (err, obj) => { 276 | expect(err).to.be.null; 277 | console.log(JSON.stringify(obj, null, 2)); 278 | expect(obj.common.custom['influxdb.0'].storageType).to.be.equal('Number'); 279 | done(); 280 | }); 281 | }); 282 | 283 | after(`Test ${adapterShortName} adapter: Stop js-controller`, function (done) { 284 | this.timeout(15000); 285 | 286 | setup.stopController(normalTerminated => { 287 | console.log(`Adapter normal terminated: ${normalTerminated}`); 288 | setTimeout(done, 2000); 289 | }); 290 | }); 291 | }); 292 | -------------------------------------------------------------------------------- /test/testAdapterTags.js: -------------------------------------------------------------------------------- 1 | /* jshint -W097 */ 2 | /* jshint strict: false */ 3 | /* jslint node: true */ 4 | /* jshint expr: true */ 5 | const expect = require('chai').expect; 6 | const setup = require('./lib/setup'); 7 | const tests = require('./lib/testcases'); 8 | 9 | let objects = null; 10 | let states = null; 11 | let onStateChanged = null; 12 | let sendToID = 1; 13 | 14 | const adapterShortName = setup.adapterName.substring(setup.adapterName.indexOf('.') + 1); 15 | 16 | let now; 17 | 18 | function checkConnectionOfAdapter(cb, counter) { 19 | counter = counter || 0; 20 | console.log(`Try check #${counter}`); 21 | if (counter > 30) { 22 | cb && cb('Cannot check connection'); 23 | return; 24 | } 25 | 26 | console.log(`Checking alive key for key : ${adapterShortName}`); 27 | states.getState(`system.adapter.${adapterShortName}.0.alive`, (err, state) => { 28 | err && console.error(err); 29 | if (state && state.val) { 30 | cb && cb(); 31 | } else { 32 | setTimeout(() => 33 | checkConnectionOfAdapter(cb, counter + 1) 34 | , 1000); 35 | } 36 | }); 37 | } 38 | 39 | function checkValueOfState(id, value, cb, counter) { 40 | counter = counter || 0; 41 | if (counter > 20) { 42 | cb && cb(`Cannot check value Of State ${id}`); 43 | return; 44 | } 45 | 46 | states.getState(id, (err, state) => { 47 | err && console.error(err); 48 | if (value === null && !state) { 49 | cb && cb(); 50 | } else 51 | if (state && (value === undefined || state.val === value)) { 52 | cb && cb(); 53 | } else { 54 | setTimeout(() => 55 | checkValueOfState(id, value, cb, counter + 1) 56 | , 500); 57 | } 58 | }); 59 | } 60 | 61 | function sendTo(target, command, message, callback) { 62 | onStateChanged = function (id, state) { 63 | if (id === 'messagebox.system.adapter.test.0') { 64 | callback(state.message); 65 | } 66 | }; 67 | 68 | states.pushMessage(`system.adapter.${target}`, { 69 | command: command, 70 | message: message, 71 | from: 'system.adapter.test.0', 72 | callback: { 73 | message: message, 74 | id: sendToID++, 75 | ack: false, 76 | time: Date.now() 77 | } 78 | }); 79 | } 80 | 81 | describe(`Test ${adapterShortName} adapter`, function () { 82 | before(`Test ${adapterShortName} adapter: Start js-controller`, function (_done) { 83 | this.timeout(600000); // because of first install from npm 84 | 85 | setup.setupController(async () => { 86 | const config = await setup.getAdapterConfig(); 87 | // enable adapter 88 | config.common.enabled = true; 89 | config.common.loglevel = 'debug'; 90 | 91 | if (process.env.INFLUXDB2) { 92 | const authToken = JSON.parse(process.env.AUTHTOKEN).token; 93 | console.log(`AUTHTOKEN=${process.env.AUTHTOKEN}`); 94 | console.log(`extracted token =${authToken}`); 95 | config.native.dbversion = '2.x'; 96 | 97 | let secret = await setup.getSecret(); 98 | if (secret === null) { 99 | secret = 'Zgfr56gFe87jJOM'; 100 | } 101 | 102 | console.log(`############SECRET: ${secret}`); 103 | config.native.token = setup.encrypt(secret, 'test-token'); //authToken; 104 | config.native.organization = 'test-org'; 105 | } else if (process.env.INFLUX_DB1_HOST) { 106 | config.native.host = process.env.INFLUX_DB1_HOST; 107 | } 108 | config.native.enableDebugLogs = true; 109 | config.native.dbname = 'tagsiobroker'; 110 | config.native.usetags = true; 111 | 112 | await setup.setAdapterConfig(config.common, config.native); 113 | 114 | setup.startController( 115 | true, 116 | (id, obj) => {}, 117 | (id, state) => onStateChanged && onStateChanged(id, state), 118 | async (_objects, _states) => { 119 | objects = _objects; 120 | states = _states; 121 | 122 | await tests.preInit(objects, states, sendTo, adapterShortName); 123 | 124 | _done(); 125 | }); 126 | }); 127 | }); 128 | 129 | it(`Test ${adapterShortName} adapter: Check if adapter started`, function (done) { 130 | this.timeout(60000); 131 | 132 | checkConnectionOfAdapter(res => { 133 | res && console.log(res); 134 | expect(res).not.to.be.equal('Cannot check connection'); 135 | sendTo('influxdb.0', 'enableHistory', { 136 | id: 'system.adapter.influxdb.0.memHeapTotal', 137 | options: { 138 | changesOnly: true, 139 | debounce: 0, 140 | retention: 31536000, 141 | storageType: 'String' 142 | } 143 | }, result => { 144 | expect(result.error).to.be.undefined; 145 | expect(result.success).to.be.true; 146 | 147 | sendTo('influxdb.0', 'enableHistory', { 148 | id: 'system.adapter.influxdb.0.uptime', 149 | options: { 150 | changesOnly: false, 151 | debounce: 0, 152 | retention: 31536000, 153 | storageType: 'Boolean' 154 | } 155 | }, result => { 156 | expect(result.error).to.be.undefined; 157 | expect(result.success).to.be.true; 158 | 159 | sendTo('influxdb.0', 'enableHistory', { 160 | id: 'system.adapter.influxdb.0.memHeapUsed', 161 | options: { 162 | changesOnly: false, 163 | debounce: 0, 164 | retention: 31536000, 165 | } 166 | }, result => { 167 | expect(result.error).to.be.undefined; 168 | expect(result.success).to.be.true; 169 | 170 | // wait till adapter receives the new settings 171 | setTimeout(() => 172 | done(), 2000); 173 | }); 174 | }); 175 | }); 176 | }); 177 | }); 178 | 179 | if (process.env.INFLUXDB2) { // Test only with Influxdb 2.x 180 | tests.register(it, expect, sendTo, adapterShortName, false, 0, 3); 181 | 182 | it(`Test ${adapterShortName}: Write string value for memHeapUsed into DB to force a type conflict`, function (done) { 183 | this.timeout(5000); 184 | now = Date.now(); 185 | 186 | states.setState('system.adapter.influxdb.0.memHeapUsed', { 187 | val: 'Blubb', 188 | ts: now - 20000, 189 | from: 'test.0' 190 | }, err => { 191 | err && console.log(err); 192 | setTimeout(() => { 193 | //sendTo('influxdb.0', 'flushBuffer', {id: 'system.adapter.influxdb.0.memHeapUsed'}, result => { 194 | sendTo('influxdb.0', 'flushBuffer', {}, result => { 195 | expect(result.error).to.be.not.ok; 196 | done(); 197 | }); 198 | }, 1000); 199 | }); 200 | }); 201 | 202 | it(`Test ${adapterShortName}: Read values from DB using query`, function (done) { 203 | this.timeout(10000); 204 | 205 | let query = 'SELECT * FROM "influxdb.0.testValue"'; 206 | if (process.env.INFLUXDB2) { 207 | const date = Date.now(); 208 | query = `from(bucket: "iobroker") |> range(start: -2d) |> filter(fn: (r) => r["_measurement"] == "influxdb.0.testValue") |> duplicate(column: "_value", as: "value") |> sort(columns:["_time"], desc: false)`; 209 | } 210 | sendTo('influxdb.0', 'query', query, result => { 211 | console.log(JSON.stringify(result.result, null, 2)); 212 | expect(result.result[0].length).to.be.at.least(5); 213 | let found = 0; 214 | for (let i = 0; i < result.result[0].length; i++) { 215 | if (result.result[0][i].value >= 1 && result.result[0][i].value <= 3) { 216 | found++; 217 | } 218 | } 219 | expect(found).to.be.equal(78); 220 | 221 | done(); 222 | }); 223 | }); 224 | 225 | it(`Test ${adapterShortName}: Check Datapoint Types`, function (done) { 226 | this.timeout(65000); 227 | 228 | if (process.env.INFLUXDB2) { 229 | // TODO: Find Flux equivalent! 230 | return done(); 231 | } 232 | 233 | setTimeout(function () { 234 | let query = 'SHOW FIELD KEYS FROM "influxdb.0.testValue"'; 235 | sendTo('influxdb.0', 'query', query, result => { 236 | console.log(`result: ${JSON.stringify(result.result, null, 2)}`); 237 | let found = false; 238 | for (let i = 0; i < result.result[0].length; i++) { 239 | if (result.result[0][i].fieldKey === 'value') { 240 | found = true; 241 | expect(result.result[0][i].fieldType).to.be.equal('float'); 242 | break; 243 | } 244 | } 245 | expect(found).to.be.true; 246 | 247 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.memHeapTotal"', result2 => { 248 | console.log(`result2: ${JSON.stringify(result2.result, null, 2)}`); 249 | let found = false; 250 | for (let i = 0; i < result2.result[0].length; i++) { 251 | if (result2.result[0][i].fieldKey === 'value') { 252 | found = true; 253 | expect(result2.result[0][i].fieldType).to.be.equal('string'); 254 | break; 255 | } 256 | } 257 | expect(found).to.be.true; 258 | 259 | sendTo('influxdb.0', 'query', 'SHOW FIELD KEYS FROM "system.adapter.influxdb.0.uptime"', result3 => { 260 | console.log(`result3: ${JSON.stringify(result3.result, null, 2)}`); 261 | let found = false; 262 | for (let i = 0; i < result3.result[0].length; i++) { 263 | if (result3.result[0][i].fieldKey === 'value') { 264 | found = true; 265 | expect(result3.result[0][i].fieldType).to.be.equal('boolean'); 266 | break; 267 | } 268 | } 269 | expect(found).to.be.true; 270 | 271 | setTimeout(() => 272 | done(), 3000); 273 | }); 274 | }); 275 | }); 276 | }, 60000); 277 | }); 278 | 279 | it(`Test ${adapterShortName}: Check that storageType is set now for memHeapUsed`, function (done) { 280 | this.timeout(5000); 281 | 282 | objects.getObject('system.adapter.influxdb.0.memHeapUsed', (err, obj) => { 283 | expect(err).to.be.null; 284 | console.log(JSON.stringify(obj, null, 2)); 285 | expect(obj.common.custom['influxdb.0'].storageType).to.be.equal('Number'); 286 | done(); 287 | }); 288 | }); 289 | } 290 | 291 | after(`Test ${adapterShortName} adapter: Stop js-controller`, function (done) { 292 | this.timeout(15000); 293 | 294 | setup.stopController(normalTerminated => { 295 | console.log(`Adapter normal terminated: ${normalTerminated}`); 296 | setTimeout(done, 2000); 297 | }); 298 | }); 299 | }); 300 | -------------------------------------------------------------------------------- /test/testPackageFiles.js: -------------------------------------------------------------------------------- 1 | /* jshint -W097 */ 2 | /* jshint strict: false */ 3 | /* jslint node: true */ 4 | /* jshint expr: true */ 5 | 'use strict'; 6 | 7 | const expect = require('chai').expect; 8 | const fs = require('fs'); 9 | 10 | describe('Test package.json and io-package.json', () => { 11 | it('Test package files', done => { 12 | console.log(); 13 | 14 | const fileContentIOPackage = fs.readFileSync(__dirname + '/../io-package.json', 'utf8'); 15 | const ioPackage = JSON.parse(fileContentIOPackage); 16 | 17 | const fileContentNPMPackage = fs.readFileSync(__dirname + '/../package.json', 'utf8'); 18 | const npmPackage = JSON.parse(fileContentNPMPackage); 19 | 20 | expect(ioPackage).to.be.an('object'); 21 | expect(npmPackage).to.be.an('object'); 22 | 23 | expect(ioPackage.common.version, 'ERROR: Version number in io-package.json needs to exist').to.exist; 24 | expect(npmPackage.version, 'ERROR: Version number in package.json needs to exist').to.exist; 25 | 26 | expect(ioPackage.common.version, 'ERROR: Version numbers in package.json and io-package.json needs to match').to.be.equal(npmPackage.version); 27 | 28 | if (!ioPackage.common.news || !ioPackage.common.news[ioPackage.common.version]) { 29 | console.log('WARNING: No news entry for current version exists in io-package.json, no rollback in Admin possible!'); 30 | console.log(); 31 | } 32 | 33 | expect(npmPackage.author, 'ERROR: Author in package.json needs to exist').to.exist; 34 | expect(ioPackage.common.authors, 'ERROR: Authors in io-package.json needs to exist').to.exist; 35 | 36 | expect(ioPackage.common.license, 'ERROR: License missing in io-package in common.license').to.exist; 37 | 38 | if (ioPackage.common.name.indexOf('template') !== 0) { 39 | if (Array.isArray(ioPackage.common.authors)) { 40 | expect(ioPackage.common.authors.length, 'ERROR: Author in io-package.json needs to be set').to.not.be.equal(0); 41 | if (ioPackage.common.authors.length === 1) { 42 | expect(ioPackage.common.authors[0], 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name '); 43 | } 44 | } 45 | else { 46 | expect(ioPackage.common.authors, 'ERROR: Author in io-package.json needs to be a real name').to.not.be.equal('my Name '); 47 | } 48 | } 49 | else { 50 | console.log('WARNING: Testing for set authors field in io-package skipped because template adapter'); 51 | console.log(); 52 | } 53 | expect(fs.existsSync(__dirname + '/../README.md'), 'ERROR: README.md needs to exist! Please create one with description, detail information and changelog. English is mandatory.').to.be.true; 54 | if (!ioPackage.common.titleLang || typeof ioPackage.common.titleLang !== 'object') { 55 | console.log('WARNING: titleLang is not existing in io-package.json. Please add'); 56 | console.log(); 57 | } 58 | if ( 59 | ioPackage.common.title.includes('iobroker') || 60 | ioPackage.common.title.includes('ioBroker') || 61 | ioPackage.common.title.includes('adapter') || 62 | ioPackage.common.title.includes('Adapter') 63 | ) { 64 | console.log('WARNING: title contains Adapter or ioBroker. It is clear anyway, that it is adapter for ioBroker.'); 65 | console.log(); 66 | } 67 | 68 | if (!ioPackage.common.controller && !ioPackage.common.onlyWWW && !ioPackage.common.noConfig) { 69 | if (!ioPackage.common.materialize || !fs.existsSync(__dirname + '/../admin/index_m.html') || !fs.existsSync(__dirname + '/../gulpfile.js')) { 70 | console.log('WARNING: Admin3 support is missing! Please add it'); 71 | console.log(); 72 | } 73 | if (ioPackage.common.materialize) { 74 | expect(fs.existsSync(__dirname + '/../admin/index_m.html'), 'Admin3 support is enabled in io-package.json, but index_m.html is missing!').to.be.true; 75 | } 76 | } 77 | 78 | const licenseFileExists = fs.existsSync(__dirname + '/../LICENSE'); 79 | const fileContentReadme = fs.readFileSync(__dirname + '/../README.md', 'utf8'); 80 | if (!fileContentReadme.includes('## Changelog')) { 81 | console.log('Warning: The README.md should have a section ## Changelog'); 82 | console.log(); 83 | } 84 | expect((licenseFileExists || fileContentReadme.includes('## License')), 'A LICENSE must exist as LICENSE file or as part of the README.md').to.be.true; 85 | if (!licenseFileExists) { 86 | console.log('Warning: The License should also exist as LICENSE file'); 87 | console.log(); 88 | } 89 | if (!fileContentReadme.includes('## License')) { 90 | console.log('Warning: The README.md should also have a section ## License to be shown in Admin3'); 91 | console.log(); 92 | } 93 | done(); 94 | }); 95 | }); 96 | --------------------------------------------------------------------------------