diff --git a/.github/workflows/containerize_fms_consumer.yaml b/.github/workflows/containerize_fms_consumer.yaml new file mode 100644 index 0000000..844d235 --- /dev/null +++ b/.github/workflows/containerize_fms_consumer.yaml @@ -0,0 +1,93 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +name: Containerize FMS Consumer and Push to Container Registry + +# Containerizes and pushes a build of the FMS Consumer to a container registry. +# + +on: + push: + branches: + - main + pull_request: + branches: + - main + paths: + - "components/Dockerfile.fms-consumer" + - "components/fms-consumer/src/**" + - "components/fms-consumer/Cargo.toml" + - "components/fms-proto/proto/**" + - "components/fms-proto/src/**" + - "components/fms-proto/Cargo.toml" + - "components/influx-client/src/**" + - "components/influx-client/Cargo.toml" + - ".github/workflows/containerize_fms_consumer.yaml" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }}/fms-consumer + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Docker buildx + id: buildx + uses: docker/setup-buildx-action@v2 + with: + install: true + + - name: Login to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata and create tag + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: "components/." + file: "components/Dockerfile.fms-consumer" + push: true + platforms: linux/amd64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/containerize_fms_forwarder.yaml b/.github/workflows/containerize_fms_forwarder.yaml new file mode 100644 index 0000000..f94c930 --- /dev/null +++ b/.github/workflows/containerize_fms_forwarder.yaml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +name: Containerize FMS Forwarder and Push to Container Registry + +# Containerizes and pushes a build of the FMS Forwarder to a container registry. +# + +on: + push: + branches: + - main + pull_request: + branches: + - main + paths: + - "components/Dockerfile.fms-forwarder" + - "components/fms-forwarder/src/**" + - "components/fms-forwarder/proto/**" + - "components/fms-proto/proto/**" + - "components/fms-proto/src/**" + - "components/fms-proto/Cargo.toml" + - "components/influx-client/src/**" + - "components/influx-client/Cargo.toml" + - ".github/workflows/containerize_fms_forwarder.yaml" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }}/fms-forwarder + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata and create {branch}-{sha} tag + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: "components/." + file: "components/Dockerfile.fms-forwarder" + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/containerize_fms_server.yaml b/.github/workflows/containerize_fms_server.yaml new file mode 100644 index 0000000..7b5f882 --- /dev/null +++ b/.github/workflows/containerize_fms_server.yaml @@ -0,0 +1,90 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +name: Containerize FMS Server and Push to Container Registry + +# Containerizes and pushes a build of the FMS Server to a container registry. +# + +on: + push: + branches: + - main + pull_request: + branches: + - main + paths: + - "components/Dockerfile.fms-server" + - "components/fms-server/src/**" + - "components/fms-server/Cargo.toml" + - "components/influx-client/src/**" + - "components/influx-client/Cargo.toml" + - ".github/workflows/containerize_fms_server.yaml" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }}/fms-server + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Docker buildx + id: buildx + uses: docker/setup-buildx-action@v2 + with: + install: true + + - name: Login to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata and create tag + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: "components/." + file: "components/Dockerfile.fms-server" + push: true + platforms: linux/amd64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f124a41 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +.DS_Store +*.drawio.bkp +**/target + +*-mqtt.env +*-kafka.env +*-kafka.properties diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b097564 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,93 @@ +# Community Code of Conduct + +**Version 2.0 +January 1, 2023** + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as community members, contributors, Committers[^1], and Project Leads (collectively "Contributors") pledge to make participation in our projects and our community a harassment-free and inclusive experience for everyone. + +This Community Code of Conduct ("Code") outlines our behavior expectations as members of our community in all Eclipse Foundation activities, both offline and online. It is not intended to govern scenarios or behaviors outside of the scope of Eclipse Foundation activities. Nor is it intended to replace or supersede the protections offered to all our community members under the law. Please follow both the spirit and letter of this Code and encourage other Contributors to follow these principles into our work. Failure to read or acknowledge this Code does not excuse a Contributor from compliance with the Code. + +## Our Standards + +Examples of behavior that contribute to creating a positive and professional environment include: + +- Using welcoming and inclusive language; +- Actively encouraging all voices; +- Helping others bring their perspectives and listening actively. If you find yourself dominating a discussion, it is especially important to encourage other voices to join in; +- Being respectful of differing viewpoints and experiences; +- Gracefully accepting constructive criticism; +- Focusing on what is best for the community; +- Showing empathy towards other community members; +- Being direct but professional; and +- Leading by example by holding yourself and others accountable + +Examples of unacceptable behavior by Contributors include: + +- The use of sexualized language or imagery; +- Unwelcome sexual attention or advances; +- Trolling, insulting/derogatory comments, and personal or political attacks; +- Public or private harassment, repeated harassment; +- Publishing others' private information, such as a physical or electronic address, without explicit permission; +- Violent threats or language directed against another person; +- Sexist, racist, or otherwise discriminatory jokes and language; +- Posting sexually explicit or violent material; +- Sharing private content, such as emails sent privately or non-publicly, or unlogged forums such as IRC channel history; +- Personal insults, especially those using racist or sexist terms; +- Excessive or unnecessary profanity; +- Advocating for, or encouraging, any of the above behavior; and +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +With the support of the Eclipse Foundation employees, consultants, officers, and directors (collectively, the "Staff"), Committers, and Project Leads, the Eclipse Foundation Conduct Committee (the "Conduct Committee") is responsible for clarifying the standards of acceptable behavior. The Conduct Committee takes appropriate and fair corrective action in response to any instances of unacceptable behavior. + +## Scope + +This Code applies within all Project, Working Group, and Interest Group spaces and communication channels of the Eclipse Foundation (collectively, "Eclipse spaces"), within any Eclipse-organized event or meeting, and in public spaces when an individual is representing an Eclipse Foundation Project, Working Group, Interest Group, or their communities. Examples of representing a Project or community include posting via an official social media account, personal accounts, or acting as an appointed representative at an online or offline event. Representation of Projects, Working Groups, and Interest Groups may be further defined and clarified by Committers, Project Leads, or the Staff. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Conduct Committee via conduct@eclipse-foundation.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Without the explicit consent of the reporter, the Conduct Committee is obligated to maintain confidentiality with regard to the reporter of an incident. The Conduct Committee is further obligated to ensure that the respondent is provided with sufficient information about the complaint to reply. If such details cannot be provided while maintaining confidentiality, the Conduct Committee will take the respondent‘s inability to provide a defense into account in its deliberations and decisions. Further details of enforcement guidelines may be posted separately. + +Staff, Committers and Project Leads have the right to report, remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code, or to block temporarily or permanently any Contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. Any such actions will be reported to the Conduct Committee for transparency and record keeping. + +Any Staff (including officers and directors of the Eclipse Foundation), Committers, Project Leads, or Conduct Committee members who are the subject of a complaint to the Conduct Committee will be recused from the process of resolving any such complaint. + +## Responsibility + +The responsibility for administering this Code rests with the Conduct Committee, with oversight by the Executive Director and the Board of Directors. For additional information on the Conduct Committee and its process, please write to . + +## Investigation of Potential Code Violations + +All conflict is not bad as a healthy debate may sometimes be necessary to push us to do our best. It is, however, unacceptable to be disrespectful or offensive, or violate this Code. If you see someone engaging in objectionable behavior violating this Code, we encourage you to address the behavior directly with those involved. If for some reason, you are unable to resolve the matter or feel uncomfortable doing so, or if the behavior is threatening or harassing, please report it following the procedure laid out below. + +Reports should be directed to . It is the Conduct Committee’s role to receive and address reported violations of this Code and to ensure a fair and speedy resolution. + +The Eclipse Foundation takes all reports of potential Code violations seriously and is committed to confidentiality and a full investigation of all allegations. The identity of the reporter will be omitted from the details of the report supplied to the accused. Contributors who are being investigated for a potential Code violation will have an opportunity to be heard prior to any final determination. Those found to have violated the Code can seek reconsideration of the violation and disciplinary action decisions. Every effort will be made to have all matters disposed of within 60 days of the receipt of the complaint. + +## Actions +Contributors who do not follow this Code in good faith may face temporary or permanent repercussions as determined by the Conduct Committee. + +This Code does not address all conduct. It works in conjunction with our [Communication Channel Guidelines](https://www.eclipse.org/org/documents/communication-channel-guidelines/), [Social Media Guidelines](https://www.eclipse.org/org/documents/social_media_guidelines.php), [Bylaws](https://www.eclipse.org/org/documents/eclipse-foundation-be-bylaws-en.pdf), and [Internal Rules](https://www.eclipse.org/org/documents/ef-be-internal-rules.pdf) which set out additional protections for, and obligations of, all contributors. The Foundation has additional policies that provide further guidance on other matters. + +It’s impossible to spell out every possible scenario that might be deemed a violation of this Code. Instead, we rely on one another’s good judgment to uphold a high standard of integrity within all Eclipse Spaces. Sometimes, identifying the right thing to do isn’t an easy call. In such a scenario, raise the issue as early as possible. + +## No Retaliation + +The Eclipse community relies upon and values the help of Contributors who identify potential problems that may need to be addressed within an Eclipse Space. Any retaliation against a Contributor who raises an issue honestly is a violation of this Code. That a Contributor has raised a concern honestly or participated in an investigation, cannot be the basis for any adverse action, including threats, harassment, or discrimination. If you work with someone who has raised a concern or provided information in an investigation, you should continue to treat the person with courtesy and respect. If you believe someone has retaliated against you, report the matter as described by this Code. Honest reporting does not mean that you have to be right when you raise a concern; you just have to believe that the information you are providing is accurate. + +False reporting, especially when intended to retaliate or exclude, is itself a violation of this Code and will not be accepted or tolerated. + +Everyone is encouraged to ask questions about this Code. Your feedback is welcome, and you will get a response within three business days. Write to . + +## Amendments + +The Eclipse Foundation Board of Directors may amend this Code from time to time and may vary the procedures it sets out where appropriate in a particular case. + +### Attribution + +This Code was inspired by the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct/). + +[^1]: Capitalized terms used herein without definition shall have the meanings assigned to them in the Bylaws. diff --git a/DEPENDENCIES b/DEPENDENCIES new file mode 100644 index 0000000..5d78458 --- /dev/null +++ b/DEPENDENCIES @@ -0,0 +1,173 @@ +crate/cratesio/-/aho-corasick/1.0.2, Unlicense AND (MIT AND Unlicense) AND MIT AND LicenseRef-scancode-generic-exception, restricted, #9759 +crate/cratesio/-/anstream/0.3.2, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/anstyle/1.0.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/anstyle-parse/0.2.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/anstyle-query/1.0.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/anyhow/1.0.72, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/arrayvec/0.7.4, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/async-channel/1.9.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/async-stream/0.3.5, MIT, approved, clearlydefined +crate/cratesio/-/async-stream-impl/0.3.5, MIT, approved, clearlydefined +crate/cratesio/-/async-trait/0.1.72, Apache-2.0 AND MIT AND Apache-2.0 AND MIT, approved, #6666 +crate/cratesio/-/axum/0.6.19, MIT, approved, clearlydefined +crate/cratesio/-/axum-core/0.3.4, MIT, approved, clearlydefined +crate/cratesio/-/base64/0.21.2, Apache-2.0 AND MIT AND Apache-2.0 AND MIT, approved, #9764 +crate/cratesio/-/bitflags/1.3.2, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/bitflags/2.3.3, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/bytes/1.4.0, MIT, approved, clearlydefined +crate/cratesio/-/castaway/0.1.2, MIT, approved, clearlydefined +crate/cratesio/-/cfg-if/1.0.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/chrono/0.4.26, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/clap/4.3.19, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/clap_builder/4.3.19, Apache-2.0 AND MIT AND Apache-2.0 AND MIT, approved, #9774 +crate/cratesio/-/clap_lex/0.5.0, Apache-2.0 AND MIT AND Apache-2.0 AND MIT, approved, #9773 +crate/cratesio/-/colorchoice/1.0.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/concurrent-queue/2.2.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/const_format/0.2.31, Zlib, approved, clearlydefined +crate/cratesio/-/const_format_proc_macros/0.2.31, Zlib, approved, clearlydefined +crate/cratesio/-/crossbeam-channel/0.5.8, Apache-2.0 AND MIT AND Apache-2.0 AND MIT AND (Apache-2.0 AND BSD-3-Clause AND CC-BY-3.0 AND MIT), approved, #9756 +crate/cratesio/-/crossbeam-utils/0.8.16, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/csv/1.2.2, Unlicense OR MIT, approved, clearlydefined +crate/cratesio/-/csv-core/0.1.10, MIT OR (MIT AND Unlicense), approved, clearlydefined +crate/cratesio/-/curl/0.4.44, MIT AND (MIT AND curl), restricted, #9765 +crate/cratesio/-/curl-sys/0.4.65, , restricted, clearlydefined +crate/cratesio/-/duration-str/0.5.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/either/1.9.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/encoding_rs/0.8.32, Apache-2.0 AND BSD-3-Clause AND MIT AND Apache-2.0 AND (Apache-2.0 AND CC0-1.0 AND MIT) AND MIT AND BSD-3-Clause AND (Apache-2.0 AND BSD-3-Clause AND CC0-1.0 AND MIT) AND (Apache-2.0 AND MIT) AND CC0-1.0, approved, #9762 +crate/cratesio/-/env_logger/0.10.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/equivalent/1.0.1, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/event-listener/2.5.3, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/fastrand/1.9.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/fnv/1.0.7, Apache-2.0 AND MIT, approved, clearlydefined +crate/cratesio/-/form_urlencoded/1.2.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures-channel/0.3.28, Apache-2.0 AND MIT AND Apache-2.0 AND MIT AND BSD-2-Clause-Views, approved, #6671 +crate/cratesio/-/futures-core/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures-executor/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures-io/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures-lite/1.13.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/futures-macro/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures-sink/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures-task/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/futures-timer/3.0.2, Apache-2.0 AND MIT, approved, clearlydefined +crate/cratesio/-/futures-util/0.3.28, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/getrandom/0.2.10, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/h2/0.3.20, MIT, approved, clearlydefined +crate/cratesio/-/hashbrown/0.12.3, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/hashbrown/0.14.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/http/0.2.9, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/httparse/1.8.0, Apache-2.0 AND MIT AND Apache-2.0 AND MIT, approved, #4256 +crate/cratesio/-/http-body/0.4.5, MIT, approved, clearlydefined +crate/cratesio/-/httpdate/1.0.2, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/humantime/2.1.0, Apache-2.0 OR (Apache-2.0 AND MIT), approved, clearlydefined +crate/cratesio/-/hyper/0.14.27, MIT, approved, clearlydefined +crate/cratesio/-/hyper-timeout/0.4.1, Apache-2.0 AND MIT, approved, clearlydefined +crate/cratesio/-/iana-time-zone/0.1.57, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/idna/0.4.0, Apache-2.0 AND MIT AND Apache-2.0 AND MIT AND LicenseRef-scancode-unicode, restricted, #9786 +crate/cratesio/-/indexmap/1.9.3, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/indexmap/2.0.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/influxrs/2.0.1, MIT, approved, clearlydefined +crate/cratesio/-/isahc/1.7.2, MIT AND CC-BY-4.0 AND MPL-2.0, approved, #9775 +crate/cratesio/-/is-terminal/0.4.9, MIT, approved, clearlydefined +crate/cratesio/-/itertools/0.10.5, Apache-2.0 AND MIT AND Apache-2.0 AND MIT, approved, #4247 +crate/cratesio/-/itoa/1.0.9, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/libc/0.2.147, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/libnghttp2-sys/0.1.7, , restricted, clearlydefined +crate/cratesio/-/libz-sys/1.1.12, Apache-2.0 AND MIT AND Apache-2.0 AND MIT AND Zlib AND GPL-1.0-or-later AND (GPL-2.0-or-later AND LicenseRef-scancode-ada-linking-exception) AND BSD-3-Clause AND BSL-1.0 AND LicenseRef-scancode-mit-old-style AND LicenseRef-scancode-other-permissive AND LicenseRef-scancode-info-zip-2009-01 AND LicenseRef-scancode-peter-deutsch-document AND (CC-BY-3.0 AND CC-BY-4.0 AND Zlib), restricted, #9763 +crate/cratesio/-/linux-raw-sys/0.4.3, Apache-2.0 WITH LLVM-exception AND MIT AND Apache-2.0 AND (Apache-2.0 WITH LLVM-exception) AND MIT, restricted, #9787 +crate/cratesio/-/log/0.4.19, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/matchit/0.7.0, MIT, approved, clearlydefined +crate/cratesio/-/memchr/2.5.0, Unlicense OR MIT, approved, clearlydefined +crate/cratesio/-/mime/0.3.17, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/minimal-lexical/0.2.1, Apache-2.0 AND MIT AND Apache-2.0 AND MIT AND (Apache-2.0 AND BSD-3-Clause AND LicenseRef-scancode-free-unknown AND MIT) AND (Apache-2.0 AND LicenseRef-scancode-free-unknown AND MIT) AND BSD-3-Clause AND (Apache-2.0 AND LicenseRef-scancode-red-hat-attribution AND LicenseRef-scancode-sunpro AND MIT), restricted, #9755 +crate/cratesio/-/mio/0.8.8, MIT, approved, clearlydefined +crate/cratesio/-/nom/7.1.3, MIT AND CC0-1.0, approved, #9761 +crate/cratesio/-/num_cpus/1.16.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/num_enum/0.5.11, BSD-3-Clause OR (MIT OR Apache-2.0), approved, clearlydefined +crate/cratesio/-/num_enum_derive/0.5.11, BSD-3-Clause OR (MIT OR Apache-2.0), approved, clearlydefined +crate/cratesio/-/num-traits/0.2.16, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/once_cell/1.18.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/openssl-probe/0.1.5, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/openssl-sys/0.9.90, MIT AND (Apache-2.0 AND MIT), approved, #9757 +crate/cratesio/-/paho-mqtt/0.12.1, BSD-3-Clause AND EPL-1.0 AND EPL-1.0 AND BSD-3-Clause AND (Apache-2.0 AND CPL-1.0 AND EPL-1.0 AND LicenseRef-scancode-eclipse-sua-2011 AND MPL-1.1), restricted, #9785 +crate/cratesio/-/paho-mqtt-sys/0.8.1, BSD-3-Clause AND EPL-1.0 AND EPL-1.0 AND (BSD-3-Clause AND EPL-1.0 AND EPL-2.0) AND (BSD-3-Clause AND EPL-2.0) AND BSD-3-Clause AND EPL-2.0 AND (Apache-2.0 AND CPL-1.0 AND LicenseRef-scancode-eclipse-sua-2011 AND MPL-1.1) AND GPL-2.0-or-later AND (BSD-3-Clause AND EPL-2.0 AND GPL-2.0-or-later) AND (GPL-2.0-only AND MIT) AND GPL-2.0-only, restricted, #9776 +crate/cratesio/-/parking/2.1.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/percent-encoding/2.3.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/pin-project/1.1.2, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/pin-project-internal/1.1.2, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/pin-project-lite/0.2.10, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/pin-utils/0.1.0, Apache-2.0 AND MIT, approved, clearlydefined +crate/cratesio/-/polling/2.8.0, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/ppv-lite86/0.2.17, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/proc-macro2/1.0.66, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/proc-macro-crate/1.3.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/prost/0.11.9, Apache-2.0, approved, #7713 +crate/cratesio/-/prost-derive/0.11.9, Apache-2.0, approved, #7717 +crate/cratesio/-/prost-types/0.11.9, Apache-2.0 AND BSD-2-Clause, approved, #7714 +crate/cratesio/-/protobuf/3.2.0, MIT, approved, clearlydefined +crate/cratesio/-/protobuf-support/3.2.0, MIT, approved, clearlydefined +crate/cratesio/-/quote/1.0.32, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/rand/0.8.5, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/rand_chacha/0.3.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/rand_core/0.6.4, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/rdkafka/0.33.2, MIT, approved, clearlydefined +crate/cratesio/-/rdkafka-sys/4.5.0, , restricted, clearlydefined +crate/cratesio/-/regex/1.9.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/regex-automata/0.3.3, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/regex-syntax/0.7.4, Apache-2.0 AND MIT AND Apache-2.0 AND MIT AND Unicode-DFS-2016, approved, #9758 +crate/cratesio/-/ring/0.16.20, ISC AND (LicenseRef-CRYPTOGAMS OR OpenSSL) AND MIT AND OpenSSL AND LicenseRef-SSLeay, approved, #7112 +crate/cratesio/-/rust_decimal/1.30.0, MIT, approved, clearlydefined +crate/cratesio/-/rustix/0.38.4, Apache-2.0 WITH LLVM-exception OR (Apache-2.0 OR MIT), approved, clearlydefined +crate/cratesio/-/rustls/0.21.5, Apache-2.0 OR (ISC OR MIT), approved, clearlydefined +crate/cratesio/-/rustls-pemfile/1.0.3, Apache-2.0 OR (ISC OR MIT), approved, clearlydefined +crate/cratesio/-/rustls-webpki/0.101.2, ISC, approved, #9798 +crate/cratesio/-/ryu/1.0.15, Apache-2.0 AND BSL-1.0 AND CC-BY-SA-3.0, approved, #4267 +crate/cratesio/-/sct/0.7.0, Apache-2.0 OR (ISC OR MIT), approved, clearlydefined +crate/cratesio/-/serde/1.0.176, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/serde_derive/1.0.176, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/serde_json/1.0.104, Apache-2.0 AND MIT, approved, #4264 +crate/cratesio/-/serde_path_to_error/0.1.14, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/serde_urlencoded/0.7.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/slab/0.4.8, MIT, approved, clearlydefined +crate/cratesio/-/sluice/0.5.5, MIT, approved, clearlydefined +crate/cratesio/-/socket2/0.4.9, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/spin/0.5.2, MIT, approved, clearlydefined +crate/cratesio/-/strsim/0.10.0, MIT, approved, clearlydefined +crate/cratesio/-/syn/1.0.109, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/syn/2.0.27, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/sync_wrapper/0.1.2, Apache-2.0, approved, clearlydefined +crate/cratesio/-/termcolor/1.2.0, Unlicense OR MIT, approved, clearlydefined +crate/cratesio/-/thiserror/1.0.44, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/thiserror-impl/1.0.44, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/time/0.1.45, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/time/0.3.23, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/time-core/0.1.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/tinyvec/1.6.0, Zlib OR (Apache-2.0 OR MIT), approved, clearlydefined +crate/cratesio/-/tinyvec_macros/0.1.1, MIT OR (Apache-2.0 OR Zlib), approved, clearlydefined +crate/cratesio/-/tokio/1.29.1, MIT, approved, clearlydefined +crate/cratesio/-/tokio-io-timeout/1.2.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/tokio-macros/2.1.0, MIT, approved, clearlydefined +crate/cratesio/-/tokio-rustls/0.24.1, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/tokio-stream/0.1.14, MIT, approved, clearlydefined +crate/cratesio/-/tokio-util/0.7.8, MIT, approved, clearlydefined +crate/cratesio/-/toml_datetime/0.6.3, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/toml_edit/0.19.14, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/tonic/0.9.2, MIT AND Apache-2.0, approved, #9772 +crate/cratesio/-/tower/0.4.13, MIT AND Apache-2.0, approved, #6661 +crate/cratesio/-/tower-layer/0.3.2, MIT, approved, clearlydefined +crate/cratesio/-/tower-service/0.3.2, MIT, approved, clearlydefined +crate/cratesio/-/tracing/0.1.37, MIT, approved, clearlydefined +crate/cratesio/-/tracing-attributes/0.1.26, MIT, approved, clearlydefined +crate/cratesio/-/tracing-core/0.1.31, MIT, approved, clearlydefined +crate/cratesio/-/tracing-futures/0.2.5, MIT, approved, clearlydefined +crate/cratesio/-/try-lock/0.2.4, MIT, approved, clearlydefined +crate/cratesio/-/unicode-bidi/0.3.13, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/unicode-ident/1.0.11, , approved, #4138 +crate/cratesio/-/unicode-normalization/0.1.22, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/unicode-xid/0.2.4, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/untrusted/0.7.1, ISC AND (ISC AND MIT), approved, #4249 +crate/cratesio/-/url/2.4.0, MIT OR Apache-2.0, approved, clearlydefined +crate/cratesio/-/utf8parse/0.2.1, Apache-2.0 OR MIT, approved, clearlydefined +crate/cratesio/-/waker-fn/1.1.0, Apache-2.0 AND MIT, approved, clearlydefined +crate/cratesio/-/want/0.3.1, MIT, approved, clearlydefined +crate/cratesio/-/winnow/0.5.1, MIT, approved, #9760 diff --git a/LICENSE b/LICENSE index f49a4e1..d645695 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -198,4 +199,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/LICENSES b/LICENSES new file mode 120000 index 0000000..d342382 --- /dev/null +++ b/LICENSES @@ -0,0 +1 @@ +components/LICENSES \ No newline at end of file diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000..aee5a7f --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,43 @@ +# Notices for the Fleet Management Service Blueprint + +This content is produced and maintained by the Eclipse SDV Blueprints project. + +* Project home: https://projects.eclipse.org/projects/automotive.sdv-blueprints + +## Trademarks + +Eclipse SDV Blueprints is a trademark of the Eclipse Foundation. Eclipse, and the +Eclipse Logo are registered trademarks of the Eclipse Foundation. + +## Copyright + +All content is the property of the respective authors or their employers. +For more information regarding authorship of content, please consult the +listed source code repository logs. + +## Declared Project Licenses + +This program and the accompanying materials are made available under the +terms of the Apache License, Version 2.0 which is available at +http://www.apache.org/licenses/LICENSE-2.0 + +SPDX-License-Identifier: Apache-2.0 + +## Source Code + +The project maintains the following source code repositories: + +* https://github.com/eclipse-sdv-blueprints/fleet-management + +## Third-Party Dependencies + +See [DEPENDENCIES](DEPENDENCIES) + +## Cryptography + +Content may contain encryption software. The country in which you are currently +may have restrictions on the import, possession, and use, and/or re-export to +another country, of encryption software. BEFORE using any encryption software, +please check the country's laws, regulations and policies concerning the import, +possession, or use, and re-export of encryption software, to see if this is +permitted. diff --git a/README.md b/README.md index 66031a0..2be242f 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,102 @@ - -

Fleet Management Blueprint

+ -

A simple Eclipse SDV Blueprint for Truck Fleet Ops.

+See the NOTICE file(s) distributed with this work for additional +information regarding copyright ownership. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at - -

- status: maintained - issues: NA - -

+ http://www.apache.org/licenses/LICENSE-2.0 - - -

- Getting Started • - Documentation • - Need Help? • -

+Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. - -
+SPDX-License-Identifier: Apache-2.0 +--> +The [Eclipse SDV Blueprints](https://github.com/eclipse-sdv-blueprints) project is a collaborative initiative +led by Eclipse SDV members to bring the *software defined vehicle* concepts to life. -## Introduction -The **Eclipse SDV Blueprints** project is a collaborative initiative led by Eclipse SDV members to bring the "software defined vehicle" concepts to life. A crucial aspect of each blueprint is to ensure users can easily reproduce it on their own. This requires well-written and highly clear documentation. Users can utilize blueprints as they are, for inspiration or as a foundation to customize and meet their specific needs. +The project hosts a collection of blueprints that demonstrate the application of technologies developed in +the context of the [Eclipse SDV Working Group](https://sdv.eclipse.org). -The Eclipse SDV Blueprints project hosts a collection of blueprints that demonstrate the application of technologies developed within the projects of the Eclipse SDV working group (sdv.eclipse.org). This allows for showcasing the capabilities and features of the software provided by the Eclipse SDV working group, while also exploring collaboration opportunities and integration of these technologies. +This repository contains the **Fleet Management Blueprint** which is a close to *real-life* showcase +for truck fleet management where trucks run an SDV software stack so that logistics fleet operators can +manage apps, data and services for a diverse set of vehicles. +The use case showcases how one can customize the standard VSS model and use it to report data from a vehicle +to a back end. The following diagram provides an overview of the current architecture: + -**Fleet Management Blueprint** is a close to "real-life" showcase for truck fleet management where trucks run SDV stacks so that logistics fleet operators can manage apps, data and services for a diverse set of vehicles.. +The overall idea is to enable back end applications to consume data coming from a vehicle using the rFMS API. -
+Data originates from the vehicle's sensors which are represented by a CSV file that is being played back by the +kuksa.val CSV feeder. The CSV feeder publishes the data to the kuksa.val Databroker. From there, the FMS Forwarder +consumes the data and writes it to an InfluxDB in the back end. The measurements in the InfluxDB can then be +visualized in a web browser by means of a Grafana dashboard. Alternatively, the measurements can be retrieved by +a Fleet Management application via the FMS Server's (HTTP based) rFMS API. -## Getting Started -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -
+# Quick Start -## Documentation +The easiest way to set up and start the services is by means of using the Docker Compose file in the top level folder: -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -
+```sh +docker compose -f ./fms-blueprint-compose.yaml up --detach +``` -## Contributing +This will pull or build (if necessary) the container images and create and start all components. -If you want to contribute bug reports or feature requests, please use *GitHub Issues*. -
+Once all services have been started, the current vehicle status can be viewed on a [Grafana dashboard](http://127.0.0.1:3000), +using *admin*/*admin* as username and password for logging in. -## License and Copyright -This program and the accompanying materials are made available under the terms of the Apache License 2.0 which is available at -[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0) +The rFMS API can be used to retrieve the data, e.g. + +```sh +curl -v -s http://127.0.0.1:8081/rfms/vehicleposition?latestOnly=true | jq +``` + +# Using Eclipse Hono to send Vehicle Data to Back End + +By default, the Docker Compose file starts the FMS Forwarder configured to write vehicle data directly to the +Influx DB running in the back end. + +However, in a real world scenario, this tight coupling between the vehicle and the Influx DB is not desirable. +As an alternative, the Docker Compose file supports a profile which configures the FMS Forwarder to send vehicle data +to the MQTT adapter of an Eclipse Hono instance. + +1. Register the vehicle as a device in Hono using the [provision-vehicle-to.hono.sh script](./provision-vehicle-to.hono.sh): + + ```sh + ./provision-vehicle-to-hono.sh --tenant=MY_TENANT_ID --device-id=MY_DEVICE_ID --device-pwd=MY_PWD + ``` + + Make sure to replace `MY_TENANT_ID`, `MY_DEVICE_ID` and `MY_PWD` with your own values. + The script registers the tenant and device in Hono's Sandbox installation at `hono.eclipseprojects.io` unless the + *--host* and/or *--kafka-brokers* command line arguments are used. Use the *--help* switch to print usage information. + + The script will also create three property files (`hono-mqtt.env`, `hono-kafka.env` and `hono-kafka.properties`) that are + used to configure the FMS Forwarder and FMS Consumer components when started via Docker Compose in the next step. + +2. Start up the vehicle and back end services using Docker Compose: + + ```sh + docker compose -f ./fms-blueprint-compose.yaml -f ./fms-blueprint-compose-hono.yaml up --detach + ``` + + The second compose file specified on the command line will also start the [FMS Consumer](./components/fms-consumer) + back end component which receives vehicle data via Hono's north bound Kafka based Telemetry API and writes it to the + Influx DB. + +# Manual configuration + +All information required for setting up the networks, volumes, configs and containers is contained in the +Docker Compose file. Please refer to the Docker and/or Podman documentation for details how to perform the +setup manually. + +Additional information can be found in the components' corresponding subfolders. diff --git a/components/.dockerignore b/components/.dockerignore new file mode 100644 index 0000000..d2a4b93 --- /dev/null +++ b/components/.dockerignore @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +**/target +**/Cargo.lock diff --git a/components/.gitignore b/components/.gitignore new file mode 100644 index 0000000..84beb7f --- /dev/null +++ b/components/.gitignore @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +target diff --git a/components/Cargo.lock b/components/Cargo.lock new file mode 100644 index 0000000..84c4303 --- /dev/null +++ b/components/Cargo.lock @@ -0,0 +1,2391 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "async-trait" +version = "0.1.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a1de45611fdb535bfde7b7de4fd54f4fd2b17b1737c0a59b69bf9b92074b8c" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "castaway" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "clap" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const_format" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "csv" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "curl" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +dependencies = [ + "curl-sys", + "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi", +] + +[[package]] +name = "curl-sys" +version = "0.4.65+curl-8.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986" +dependencies = [ + "cc", + "libc", + "libnghttp2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "winapi", +] + +[[package]] +name = "duration-str" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f037c488d179e21c87ef5fa9c331e8e62f5dddfa84618b41bb197da03edff1" +dependencies = [ + "chrono", + "nom", + "rust_decimal", + "serde", + "thiserror", + "time 0.3.23", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fms-consumer" +version = "0.1.0-SNAPSHOT" +dependencies = [ + "clap", + "env_logger", + "fms-proto", + "futures", + "influx-client", + "log", + "openssl-src", + "protobuf", + "rdkafka", + "tokio", +] + +[[package]] +name = "fms-forwarder" +version = "0.1.0-SNAPSHOT" +dependencies = [ + "async-trait", + "chrono", + "clap", + "duration-str", + "env_logger", + "fms-proto", + "influx-client", + "log", + "paho-mqtt", + "prost", + "prost-types", + "protobuf", + "protoc-bin-vendored", + "tokio", + "tonic", + "tonic-build", +] + +[[package]] +name = "fms-proto" +version = "0.1.0-SNAPSHOT" +dependencies = [ + "protobuf", + "protobuf-codegen", + "protoc-bin-vendored", +] + +[[package]] +name = "fms-server" +version = "0.1.0-SNAPSHOT" +dependencies = [ + "async-trait", + "axum", + "chrono", + "clap", + "const_format", + "env_logger", + "influx-client", + "influxrs", + "log", + "serde", + "serde_json", + "tokio", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + +[[package]] +name = "influx-client" +version = "0.1.0-SNAPSHOT" +dependencies = [ + "clap", + "fms-proto", + "influxrs", + "isahc", + "log", + "protobuf", +] + +[[package]] +name = "influxrs" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7862dbbb5d65b8a96c7b84738e32fc275d68d055f97577416c16298df00791f7" +dependencies = [ + "csv", + "isahc", + "log", + "serde", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "isahc" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" +dependencies = [ + "async-channel", + "castaway", + "crossbeam-utils", + "curl", + "curl-sys", + "encoding_rs", + "event-listener", + "futures-lite", + "http", + "log", + "mime", + "once_cell", + "polling", + "slab", + "sluice", + "tracing", + "tracing-futures", + "url", + "waker-fn", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libnghttp2-sys" +version = "0.1.7+1.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "111.26.0+1.1.1u" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "paho-mqtt" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6a19171f5b405f350373e32b6c2c4b47c225afccc837c11d2e7e22ba1749c62" +dependencies = [ + "async-channel", + "crossbeam-channel", + "futures", + "futures-timer", + "libc", + "log", + "paho-mqtt-sys", + "thiserror", +] + +[[package]] +name = "paho-mqtt-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1782b5e75d712f951a2a4c7d3175a2ef37d93ddb3ad8656b37092f3f05464bc9" +dependencies = [ + "cmake", + "openssl-sys", +] + +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap 1.9.3", +] + +[[package]] +name = "pin-project" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "protobuf" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror", +] + +[[package]] +name = "protobuf-codegen" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd418ac3c91caa4032d37cb80ff0d44e2ebe637b2fb243b6234bf89cdac4901" +dependencies = [ + "anyhow", + "once_cell", + "protobuf", + "protobuf-parse", + "regex", + "tempfile", + "thiserror", +] + +[[package]] +name = "protobuf-parse" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d39b14605eaa1f6a340aec7f320b34064feb26c93aec35d6a9a2272a8ddfa49" +dependencies = [ + "anyhow", + "indexmap 1.9.3", + "log", + "protobuf", + "protobuf-support", + "tempfile", + "thiserror", + "which", +] + +[[package]] +name = "protobuf-support" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372" +dependencies = [ + "thiserror", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005ca8623e5633e298ad1f917d8be0a44bcf406bf3cde3b80e63003e49a3f27d" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb9fc9cce84c8694b6ea01cc6296617b288b703719b725b8c9c65f7c5874435" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d2a07dcf7173a04d49974930ccbfb7fd4d74df30ecfc8762cf2f895a094516" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54fef0b04fcacba64d1d80eed74a20356d96847da8497a59b0a0a436c9165b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8782f2ce7d43a9a5c74ea4936f001e9e8442205c244f7a3d4286bd4c37bc924" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5de656c7ee83f08e0ae5b81792ccfdc1d04e7876b1d9a38e6876a9e09e02537" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9653c3ed92974e34c5a6e0a510864dab979760481714c172e0a34e437cb98804" + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rdkafka" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da18026aad1c24033da3da726200de7e911e75c2e2cc2f77ffb9b4502720faae" +dependencies = [ + "futures-channel", + "futures-util", + "libc", + "log", + "rdkafka-sys", + "serde", + "serde_derive", + "serde_json", + "slab", + "tokio", +] + +[[package]] +name = "rdkafka-sys" +version = "4.5.0+1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb0676c2112342ac7165decdedbc4e7086c0af384479ccce534546b10687a5d" +dependencies = [ + "cmake", + "libc", + "libz-sys", + "num_enum", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rust_decimal" +version = "1.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0446843641c69436765a35a5a77088e28c2e6a12da93e84aa3ab1cd4aa5a042" +dependencies = [ + "arrayvec", + "num-traits", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "serde" +version = "1.0.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76dc28c9523c5d70816e393136b86d48909cfb27cecaa902d338c19ed47164dc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e7b8c5dc823e3b90651ff1d3808419cd14e5ad76de04feaf37da114e7a306f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "serde_json" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "sluice" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" +dependencies = [ + "async-channel", + "futures-core", + "futures-io", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +dependencies = [ + "cfg-if", + "fastrand 2.0.0", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +dependencies = [ + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +dependencies = [ + "autocfg", + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.27", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.27", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" +dependencies = [ + "memchr", +] diff --git a/components/Cargo.lock.license b/components/Cargo.lock.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/components/Cargo.lock.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/components/Cargo.toml b/components/Cargo.toml new file mode 100644 index 0000000..4b2b288 --- /dev/null +++ b/components/Cargo.toml @@ -0,0 +1,65 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +[workspace] +members = [ + "fms-consumer", + "fms-forwarder", + "fms-server", + "influx-client", +] + +[workspace.package] +license = "Apache-2.0" +readme = "../README.md" +repository = "https://github.com/eclipse-sdv-blueprints/fleet-management" +version = "0.1.0-SNAPSHOT" +edition = "2021" +documentation = "https://eclipse-sdv-blueprints.github.io/blueprints-website/" + +[workspace.dependencies] +async-trait = { version = "0.1" } +chrono = { version = "0.4" } +clap = { version = "4.3", default-features = false } +duration-str = { version = "0.5" } +env_logger = { version = "0.10" } +fms-proto = { path = "fms-proto" } +influx-client = { path = "influx-client", default-features = false } +influxrs = { version = "2.0" } +log = { version = "0.4" } +openssl = { version = "0.10", default-features = false } +protobuf = { version = "3" } +protobuf-codegen = { version = "3" } +protoc-bin-vendored = { version = "3" } +# prost has no features +prost = { version = "0.11" } +# prost-types has no features +prost-types = { version = "0.11" } +# tokio does not enable features by default +tokio = { version = "1.29" } +tonic = { version = "0.9", default-features = false } +tonic-build = { version = "0.9", default-features = false } + +[profile.release] +lto = true # Link time optimization (dead code removal etc...) +opt-level = "s" +codegen-units = 1 +incremental = false +strip = true + diff --git a/components/DEPENDENCIES b/components/DEPENDENCIES new file mode 100644 index 0000000..e69de29 diff --git a/components/Dockerfile.fms-consumer b/components/Dockerfile.fms-consumer new file mode 100644 index 0000000..121d4b2 --- /dev/null +++ b/components/Dockerfile.fms-consumer @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +FROM ghcr.io/rust-cross/rust-musl-cross:x86_64-musl AS builder-amd64 +ENV BUILDTARGET="x86_64-unknown-linux-musl" + + +FROM ghcr.io/rust-cross/rust-musl-cross:aarch64-musl AS builder-arm64 +ENV BUILDTARGET="aarch64-unknown-linux-musl" + +FROM builder-$TARGETARCH as builder +ARG TARGETARCH +RUN apt-get update && apt-get install -y ca-certificates \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# This will speed up fetching the crate.io index in the future, see +# https://blog.rust-lang.org/2022/06/22/sparse-registry-testing.html +ENV CARGO_UNSTABLE_SPARSE_REGISTRY=true + +RUN echo "Building for $TARGETARCH" +RUN mkdir components +COPY . components/ +WORKDIR /home/rust/src/components + +RUN cargo build --package fms-consumer --release --target $BUILDTARGET +RUN mv target/${BUILDTARGET}/release/fms-consumer /home/rust + +FROM scratch + +COPY --from=builder /home/rust/fms-consumer /app/fms-consumer +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY LICENSES /app/ + +ENTRYPOINT [ "/app/fms-consumer" ] diff --git a/components/Dockerfile.fms-forwarder b/components/Dockerfile.fms-forwarder new file mode 100644 index 0000000..4c50020 --- /dev/null +++ b/components/Dockerfile.fms-forwarder @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +FROM ghcr.io/rust-cross/rust-musl-cross:x86_64-musl AS builder-amd64 +ENV BUILDTARGET="x86_64-unknown-linux-musl" + + +FROM ghcr.io/rust-cross/rust-musl-cross:aarch64-musl AS builder-arm64 +ENV BUILDTARGET="aarch64-unknown-linux-musl" + +FROM builder-$TARGETARCH as builder +ARG TARGETARCH +RUN apt-get update && apt-get install -y ca-certificates \ + && apt-get clean && rm -rf /var/lib/apt/lists/* +# This will speed up fetching the crate.io index in the future, see +# https://blog.rust-lang.org/2022/06/22/sparse-registry-testing.html +ENV CARGO_UNSTABLE_SPARSE_REGISTRY=true +# This is supposedly required for successfully building for arm64 using buildx with QEMU +# see https://github.com/rust-lang/cargo/issues/10583 +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true + +RUN echo "Building for $TARGETARCH" +RUN mkdir components +COPY . components/ +WORKDIR /home/rust/src/components + +RUN cargo build --package fms-forwarder --release --target $BUILDTARGET +RUN mv target/${BUILDTARGET}/release/fms-forwarder /home/rust + +FROM scratch + +COPY --from=builder /home/rust/fms-forwarder /app/fms-forwarder +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY LICENSES /app/ + +ENTRYPOINT [ "/app/fms-forwarder" ] diff --git a/components/Dockerfile.fms-server b/components/Dockerfile.fms-server new file mode 100644 index 0000000..28782ab --- /dev/null +++ b/components/Dockerfile.fms-server @@ -0,0 +1,48 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +FROM ghcr.io/rust-cross/rust-musl-cross:x86_64-musl AS builder-amd64 +ENV BUILDTARGET="x86_64-unknown-linux-musl" + + +FROM ghcr.io/rust-cross/rust-musl-cross:aarch64-musl AS builder-arm64 +ENV BUILDTARGET="aarch64-unknown-linux-musl" + +FROM builder-$TARGETARCH as builder +ARG TARGETARCH + +# This will speed up fetching the crate.io index in the future, see +# https://blog.rust-lang.org/2022/06/22/sparse-registry-testing.html +ENV CARGO_UNSTABLE_SPARSE_REGISTRY=true + +RUN echo "Building for $TARGETARCH" +RUN mkdir components +COPY . components/ +WORKDIR /home/rust/src/components + +RUN cargo build --package fms-server --release --target $BUILDTARGET +RUN mv target/${BUILDTARGET}/release/fms-server /home/rust + +FROM scratch + +COPY --from=builder /home/rust/fms-server /app/fms-server +COPY LICENSES /app/ + +EXPOSE 8081 +ENTRYPOINT [ "/app/fms-server" ] diff --git a/components/LICENSES/Apache-2.0.txt b/components/LICENSES/Apache-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/components/LICENSES/Apache-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/components/LICENSES/Unicode-DFS-2016.txt b/components/LICENSES/Unicode-DFS-2016.txt new file mode 100644 index 0000000..85d0d58 --- /dev/null +++ b/components/LICENSES/Unicode-DFS-2016.txt @@ -0,0 +1,46 @@ +UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE + +See Terms of Use +for definitions of Unicode Inc.’s Data Files and Software. + +NOTICE TO USER: Carefully read the following legal agreement. +BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. +IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +THE DATA FILES OR SOFTWARE. + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2022 Unicode, Inc. All rights reserved. +Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Unicode data files and any associated documentation +(the "Data Files") or Unicode software and any associated documentation +(the "Software") to deal in the Data Files or Software +without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, and/or sell copies of +the Data Files or Software, and to permit persons to whom the Data Files +or Software are furnished to do so, provided that either +(a) this copyright and permission notice appear with all copies +of the Data Files or Software, or +(b) this copyright and permission notice appear in associated +Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT OF THIRD PARTY RIGHTS. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in these Data Files or Software without prior +written authorization of the copyright holder. diff --git a/components/LICENSES/async-stream-0.3.5.txt b/components/LICENSES/async-stream-0.3.5.txt new file mode 100644 index 0000000..8cbd7d6 --- /dev/null +++ b/components/LICENSES/async-stream-0.3.5.txt @@ -0,0 +1,51 @@ +Copyright (c) 2019 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +Copyright (c) 2018 David Tolnay + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/axum-0.6.19.txt b/components/LICENSES/axum-0.6.19.txt new file mode 100644 index 0000000..11598b4 --- /dev/null +++ b/components/LICENSES/axum-0.6.19.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Axum Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/bytes-1.4.0.txt b/components/LICENSES/bytes-1.4.0.txt new file mode 100644 index 0000000..58fb29a --- /dev/null +++ b/components/LICENSES/bytes-1.4.0.txt @@ -0,0 +1,25 @@ +Copyright (c) 2018 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/castaway-0.1.2.txt b/components/LICENSES/castaway-0.1.2.txt new file mode 100644 index 0000000..efda8e4 --- /dev/null +++ b/components/LICENSES/castaway-0.1.2.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Stephen M. Coakley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/LICENSES/const-format-0.2.31.txt b/components/LICENSES/const-format-0.2.31.txt new file mode 100644 index 0000000..0712d0f --- /dev/null +++ b/components/LICENSES/const-format-0.2.31.txt @@ -0,0 +1,17 @@ +Copyright (c) 2020 Matias Rodriguez. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/components/LICENSES/curl-0.4.44.txt b/components/LICENSES/curl-0.4.44.txt new file mode 100644 index 0000000..5f5e4b0 --- /dev/null +++ b/components/LICENSES/curl-0.4.44.txt @@ -0,0 +1,19 @@ +Copyright (c) 2014 Carl Lerche + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/components/LICENSES/curl-sys-0.4.65.txt b/components/LICENSES/curl-sys-0.4.65.txt new file mode 100644 index 0000000..5f5e4b0 --- /dev/null +++ b/components/LICENSES/curl-sys-0.4.65.txt @@ -0,0 +1,19 @@ +Copyright (c) 2014 Carl Lerche + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/components/LICENSES/encoding_rs-0.8.32.txt b/components/LICENSES/encoding_rs-0.8.32.txt new file mode 100644 index 0000000..f690e71 --- /dev/null +++ b/components/LICENSES/encoding_rs-0.8.32.txt @@ -0,0 +1,26 @@ +Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/components/LICENSES/h2-0.3.20.txt b/components/LICENSES/h2-0.3.20.txt new file mode 100644 index 0000000..11239dd --- /dev/null +++ b/components/LICENSES/h2-0.3.20.txt @@ -0,0 +1,25 @@ +Copyright (c) 2017 h2 authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/http-body-0.4.5.txt b/components/LICENSES/http-body-0.4.5.txt new file mode 100644 index 0000000..27b08f2 --- /dev/null +++ b/components/LICENSES/http-body-0.4.5.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Hyper Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/hyper-0.14.27.txt b/components/LICENSES/hyper-0.14.27.txt new file mode 100644 index 0000000..bc1e966 --- /dev/null +++ b/components/LICENSES/hyper-0.14.27.txt @@ -0,0 +1,19 @@ +Copyright (c) 2014-2021 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/components/LICENSES/is-terminal-0.4.9.txt b/components/LICENSES/is-terminal-0.4.9.txt new file mode 100644 index 0000000..b2319d8 --- /dev/null +++ b/components/LICENSES/is-terminal-0.4.9.txt @@ -0,0 +1,23 @@ +Portions of this project are derived from atty, which bears the following +copyright notice and permission notice: + +Copyright (c) 2015-2019 Doug Tangren + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/matchit-0.7.0.txt b/components/LICENSES/matchit-0.7.0.txt new file mode 100644 index 0000000..a2978d5 --- /dev/null +++ b/components/LICENSES/matchit-0.7.0.txt @@ -0,0 +1,53 @@ +MIT License + +Copyright (c) 2022 Ibraheem Ahmed + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------ + +BSD 3-Clause License + +Copyright (c) 2013, Julien Schmidt +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/components/LICENSES/mio-0.8.8.txt b/components/LICENSES/mio-0.8.8.txt new file mode 100644 index 0000000..3516413 --- /dev/null +++ b/components/LICENSES/mio-0.8.8.txt @@ -0,0 +1,19 @@ +Copyright (c) 2014 Carl Lerche and other MIO contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/components/LICENSES/nom-7.1.3.txt b/components/LICENSES/nom-7.1.3.txt new file mode 100644 index 0000000..88557e4 --- /dev/null +++ b/components/LICENSES/nom-7.1.3.txt @@ -0,0 +1,20 @@ +Copyright (c) 2014-2019 Geoffroy Couprie + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/openssl-sys-0.9.90.txt b/components/LICENSES/openssl-sys-0.9.90.txt new file mode 100644 index 0000000..39e0ed6 --- /dev/null +++ b/components/LICENSES/openssl-sys-0.9.90.txt @@ -0,0 +1,25 @@ +Copyright (c) 2014 Alex Crichton + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/protobuf-3.2.0.txt b/components/LICENSES/protobuf-3.2.0.txt new file mode 100644 index 0000000..acce639 --- /dev/null +++ b/components/LICENSES/protobuf-3.2.0.txt @@ -0,0 +1,19 @@ +Copyright (c) 2019 Stepan Koltsov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/components/LICENSES/rdkafka-0.33.2.txt b/components/LICENSES/rdkafka-0.33.2.txt new file mode 100644 index 0000000..eb7158a --- /dev/null +++ b/components/LICENSES/rdkafka-0.33.2.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Federico Giraud + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/LICENSES/ring.txt b/components/LICENSES/ring.txt new file mode 100644 index 0000000..bf78743 --- /dev/null +++ b/components/LICENSES/ring.txt @@ -0,0 +1,204 @@ +Note that it is easy for this file to get out of sync with the licenses in the +source code files. It's recommended to compare the licenses in the source code +with what's mentioned here. + +*ring* is derived from BoringSSL, so the licensing situation in *ring* is +similar to BoringSSL. + +*ring* uses an ISC-style license like BoringSSL for code in new files, +including in particular all the Rust code: + + Copyright 2015-2016 Brian Smith. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL +licensing. Files that are completely new have a Google copyright and an ISC +license. This license is reproduced at the bottom of this file. + +Contributors to BoringSSL are required to follow the CLA rules for Chromium: +https://cla.developers.google.com/clas + +Files in third_party/ have their own licenses, as described therein. The MIT +license, for third_party/fiat, which, unlike other third_party directories, is +compiled into non-test libraries, is included below. + +The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the +OpenSSL License and the original SSLeay license apply to the toolkit. See below +for the actual license texts. Actually both licenses are BSD-style Open Source +licenses. In case of any license issues related to OpenSSL please contact +openssl-core@openssl.org. + +The following are Google-internal bug numbers where explicit permission from +some authors is recorded for use of their work: + 27287199 + 27287880 + 27287883 + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + +ISC license used for completely new code in BoringSSL: + +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + +The code in third_party/fiat carries the MIT license: + +Copyright (c) 2015-2016 the fiat-crypto authors (see +https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS). + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/LICENSES/rust_decimal-1.30.0.txt b/components/LICENSES/rust_decimal-1.30.0.txt new file mode 100644 index 0000000..68364ef --- /dev/null +++ b/components/LICENSES/rust_decimal-1.30.0.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Paul Mason + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/LICENSES/rustls-webpki-0.101.2.txt b/components/LICENSES/rustls-webpki-0.101.2.txt new file mode 100644 index 0000000..cd87be1 --- /dev/null +++ b/components/LICENSES/rustls-webpki-0.101.2.txt @@ -0,0 +1,19 @@ +Except as otherwise noted, this project is licensed under the following +(ISC-style) terms: + +Copyright 2015 Brian Smith. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +The files under third-party/chromium are licensed as described in +third-party/chromium/LICENSE. diff --git a/components/LICENSES/slab-0.4.8.txt b/components/LICENSES/slab-0.4.8.txt new file mode 100644 index 0000000..819ce21 --- /dev/null +++ b/components/LICENSES/slab-0.4.8.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/sluice-0.5.5.txt b/components/LICENSES/sluice-0.5.5.txt new file mode 100644 index 0000000..6552d1f --- /dev/null +++ b/components/LICENSES/sluice-0.5.5.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Stephen M. Coakley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/LICENSES/spin.txt b/components/LICENSES/spin.txt new file mode 100644 index 0000000..b2d7f7b --- /dev/null +++ b/components/LICENSES/spin.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Mathijs van de Nes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/components/LICENSES/strsim-0.10.0.txt b/components/LICENSES/strsim-0.10.0.txt new file mode 100644 index 0000000..8d1fbe1 --- /dev/null +++ b/components/LICENSES/strsim-0.10.0.txt @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2015 Danny Guo +Copyright (c) 2016 Titus Wormer +Copyright (c) 2018 Akash Kurdekar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/LICENSES/tokio-1.29.1.txt b/components/LICENSES/tokio-1.29.1.txt new file mode 100644 index 0000000..8bdf6bd --- /dev/null +++ b/components/LICENSES/tokio-1.29.1.txt @@ -0,0 +1,25 @@ +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tokio-macros-2.1.0.txt b/components/LICENSES/tokio-macros-2.1.0.txt new file mode 100644 index 0000000..12d1037 --- /dev/null +++ b/components/LICENSES/tokio-macros-2.1.0.txt @@ -0,0 +1,47 @@ +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +The MIT License (MIT) + +Copyright (c) 2019 Yoshua Wuyts + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/LICENSES/tokio-stream-0.1.14.txt b/components/LICENSES/tokio-stream-0.1.14.txt new file mode 100644 index 0000000..8bdf6bd --- /dev/null +++ b/components/LICENSES/tokio-stream-0.1.14.txt @@ -0,0 +1,25 @@ +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tokio-util-0.7.8.txt b/components/LICENSES/tokio-util-0.7.8.txt new file mode 100644 index 0000000..8bdf6bd --- /dev/null +++ b/components/LICENSES/tokio-util-0.7.8.txt @@ -0,0 +1,25 @@ +Copyright (c) 2023 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tonic-0.9.2.txt b/components/LICENSES/tonic-0.9.2.txt new file mode 100644 index 0000000..3077098 --- /dev/null +++ b/components/LICENSES/tonic-0.9.2.txt @@ -0,0 +1,19 @@ +Copyright (c) 2020 Lucio Franco + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/components/LICENSES/tower-0.4.13.txt b/components/LICENSES/tower-0.4.13.txt new file mode 100644 index 0000000..b980cac --- /dev/null +++ b/components/LICENSES/tower-0.4.13.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tower Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tower-layer-0.3.2.txt b/components/LICENSES/tower-layer-0.3.2.txt new file mode 100644 index 0000000..b980cac --- /dev/null +++ b/components/LICENSES/tower-layer-0.3.2.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tower Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tower-service-0.3.2.txt b/components/LICENSES/tower-service-0.3.2.txt new file mode 100644 index 0000000..b980cac --- /dev/null +++ b/components/LICENSES/tower-service-0.3.2.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tower Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tracing-0.1.37.txt b/components/LICENSES/tracing-0.1.37.txt new file mode 100644 index 0000000..cdb28b4 --- /dev/null +++ b/components/LICENSES/tracing-0.1.37.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tracing-attributes-0.1.26.txt b/components/LICENSES/tracing-attributes-0.1.26.txt new file mode 100644 index 0000000..cdb28b4 --- /dev/null +++ b/components/LICENSES/tracing-attributes-0.1.26.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tracing-core-0.1.31.txt b/components/LICENSES/tracing-core-0.1.31.txt new file mode 100644 index 0000000..cdb28b4 --- /dev/null +++ b/components/LICENSES/tracing-core-0.1.31.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/tracing-futures-0.2.5.txt b/components/LICENSES/tracing-futures-0.2.5.txt new file mode 100644 index 0000000..cdb28b4 --- /dev/null +++ b/components/LICENSES/tracing-futures-0.2.5.txt @@ -0,0 +1,25 @@ +Copyright (c) 2019 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/components/LICENSES/try-lock-0.2.4.txt b/components/LICENSES/try-lock-0.2.4.txt new file mode 100644 index 0000000..5cddb26 --- /dev/null +++ b/components/LICENSES/try-lock-0.2.4.txt @@ -0,0 +1,21 @@ +Copyright (c) 2018 Sean McArthur +Copyright (c) 2016 Alex Crichton + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/components/LICENSES/untrusted-0.7.1.txt b/components/LICENSES/untrusted-0.7.1.txt new file mode 100644 index 0000000..7151db6 --- /dev/null +++ b/components/LICENSES/untrusted-0.7.1.txt @@ -0,0 +1,13 @@ +// Copyright 2015-2016 Brian Smith. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/components/LICENSES/want-0.3.1.txt b/components/LICENSES/want-0.3.1.txt new file mode 100644 index 0000000..e0f0f8a --- /dev/null +++ b/components/LICENSES/want-0.3.1.txt @@ -0,0 +1,20 @@ +Copyright (c) 2018-2019 Sean McArthur + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/components/LICENSES/winnow-0.5.1.txt b/components/LICENSES/winnow-0.5.1.txt new file mode 100644 index 0000000..c9b44cb --- /dev/null +++ b/components/LICENSES/winnow-0.5.1.txt @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components/fms-consumer/Cargo.toml b/components/fms-consumer/Cargo.toml new file mode 100644 index 0000000..70d6170 --- /dev/null +++ b/components/fms-consumer/Cargo.toml @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +[package] +name = "fms-consumer" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +documentation.workspace = true +readme.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { workspace = true, features = ["std", "env", "color", "help", "usage", "error-context", "suggestions"] } +env_logger = { workspace = true } +fms-proto = { workspace = true } +futures = "0.3" +influx-client = { workspace = true, features = ["writer"] } +rdkafka = { version = "0.33", default-features = false, features = ["libz", "tokio", "cmake-build", "ssl-vendored"] } +log = { workspace = true } +protobuf = { workspace = true } +tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] } + +[build-dependencies] +# see https://github.com/fede1024/rust-rdkafka/issues/572#issuecomment-1529316876 +openssl-src = { version = "111", features = ["force-engine"] } diff --git a/components/fms-consumer/src/main.rs b/components/fms-consumer/src/main.rs new file mode 100644 index 0000000..80e2acb --- /dev/null +++ b/components/fms-consumer/src/main.rs @@ -0,0 +1,283 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use std::collections::HashMap; +use std::fs::File; +use std::io::{self, BufRead, BufReader}; +use std::process; +use std::sync::Arc; +use std::time::Duration; + +use clap::{Arg, ArgAction, ArgMatches, Command}; +use fms_proto::fms::VehicleStatus; +use futures::TryStreamExt; +use influx_client::writer::InfluxWriter; +use log::{debug, error, info, trace}; + +use rdkafka::config::RDKafkaLogLevel; +use rdkafka::consumer::stream_consumer::StreamConsumer; +use rdkafka::consumer::Consumer; +use rdkafka::message::{BorrowedHeaders, BorrowedMessage, Headers}; +use rdkafka::{ClientConfig, Message}; + +const CONTENT_TYPE_PROTOBUF: &str = "application/vnd.google.protobuf"; + +const HEADER_NAME_ORIG_ADDRESS: &str = "orig_address"; + +const PARAM_KAFKA_PROPERTIES_FILE: &str = "kafka-properties-file"; +const PARAM_KAFKA_TOPIC_NAME: &str = "kafka-topic"; + +fn add_property_bag_to_map(property_bag: String, headers: &mut HashMap) { + property_bag.split("&").for_each(|p| { + trace!("processing property: {p}"); + p.split_once('=') + .map(|(k,v)| { + if headers.contains_key(k) { + trace!("skipping property [{k}] from property bag because header with same name exists"); + } else { + trace!("adding propery [k: {k}, v: {v}] to header map"); + headers.insert(k.to_string(), v.to_string()); + } + }); + }); +} + +fn get_headers_as_map(headers: &BorrowedHeaders) -> HashMap { + let mut result = HashMap::new(); + headers.iter().for_each(|header| { + match ( + header.key, + header + .value + .and_then(|v| String::from_utf8(v.to_vec()).map_or(None, Option::Some)), + ) { + (HEADER_NAME_ORIG_ADDRESS, Some(value)) => { + value.rsplit_once("/?").map(|(_topic, props)| { + debug!("found property bag in {HEADER_NAME_ORIG_ADDRESS} header: {props}"); + add_property_bag_to_map(props.to_string(), &mut result); + }); + } + (_, Some(value)) => { + result.insert(header.key.to_string(), value); + } + (_, None) => { + debug!("message contains empty header [{}]", header.key); + } + }; + }); + + result +} + +fn read_lines(filename: &String) -> Result>, Box> { + // Open the file in read-only mode. + match File::open(filename) { + Ok(file) => { + // Read the file line by line, and return an iterator of the lines of the file. + Ok(io::BufReader::new(file).lines()) + } + Err(e) => Err(Box::new(e)), + } +} + +fn get_kafka_client_config(filename: &String) -> Result> { + read_lines(filename).map(|lines| { + let mut client_config = ClientConfig::new(); + for line in lines { + match line { + Ok(property) => match property.split_once("=") { + Some((key, value)) => { + client_config.set(key, value); + } + None => { + debug!("cannot parse line into property: {}", property); + } + }, + Err(e) => { + debug!("cannot read line from file: {e}"); + } + } + } + client_config + }) +} + +fn deserialize_vehicle_status(protobuf: &[u8]) -> Option { + use protobuf::Message; + + match VehicleStatus::parse_from_bytes(protobuf) { + Ok(vehicle_status) => { + trace!("successfully deserialized VehicleStatus from protobuf"); + Some(vehicle_status) + } + Err(e) => { + debug!("failed to deserialize VehicleStatus from protobuf: {}", e); + None + } + } +} + +async fn process_protobuf_message( + message_properties: HashMap, + payload: &[u8], + influx_writer: Arc, +) { + match message_properties.get("device_id") { + Some(device_id) => { + debug!("received message from vehicle {}", device_id); + match deserialize_vehicle_status(payload) { + Some(vehicle_status) => influx_writer.write_vehicle_status(&vehicle_status).await, + None => {} + } + } + None => debug!("discarding message from unknown device"), + } +} + +async fn process_message(m: &BorrowedMessage<'_>, influx_writer: Arc) { + if let Some(headers) = m.headers() { + let message_properties = get_headers_as_map(headers); + match ( + message_properties.get("content-type").map(String::as_str), + m.payload(), + ) { + (Some(CONTENT_TYPE_PROTOBUF), Some(payload)) => { + debug!("received protobuf message"); + process_protobuf_message(message_properties, payload, influx_writer).await + } + (_, None) => debug!("ignoring message without payload"), + _ => {} + } + } else { + debug!("ignoring message without headers"); + } +} + +async fn run_async_processor(args: &ArgMatches) { + let influx_writer = InfluxWriter::new(&args).map_or_else( + |e| { + error!("failed to create InfluxDB writer: {e}"); + process::exit(1); + }, + Arc::new, + ); + + let mut client_config = + get_kafka_client_config(args.get_one::(PARAM_KAFKA_PROPERTIES_FILE).unwrap()) + .unwrap_or_else(|e| { + error!("failed to create Kafka client: {e}"); + process::exit(1); + }); + + // Create the `StreamConsumer`, to receive the messages from the topic in form of a `Stream`. + let consumer: StreamConsumer = client_config + .set_log_level(RDKafkaLogLevel::Debug) + .create() + .unwrap_or_else(|e| { + error!("failed to create Kafka client: {e}"); + process::exit(1); + }); + + let topic_name = args.get_one::(PARAM_KAFKA_TOPIC_NAME).unwrap(); + + match consumer.fetch_metadata(Some(topic_name), Duration::from_secs(10)) { + Err(e) => { + error!("could not retrieve meta data for topic [{topic_name}] from broker: {e}"); + process::exit(1); + } + Ok(metadata) => match metadata + .topics() + .into_iter() + .find(|topic| topic.name() == topic_name) + { + Some(topic) => { + if topic.partitions().len() == 0 { + error!("topic [{topic_name}] does not exist (yet)"); + process::exit(1); + } + } + None => { + error!("broker did not return meta data for topic [{topic_name}]"); + process::exit(1); + } + }, + } + + match consumer.subscribe(&[topic_name.as_str()]) { + Err(e) => { + error!("failed to subscribe to topic: {e}"); + process::exit(1); + } + Ok(_) => { + info!("successfully subscribed to topic {topic_name}"); + info!("starting message consumer"); + consumer + .stream() + .try_for_each(|borrowed_message| { + let cloned_writer = influx_writer.clone(); + async move { + process_message(&borrowed_message, cloned_writer).await; + Ok(()) + } + }) + .await + .unwrap_or_else(|e| { + error!("could not start consumer for topic [{topic_name}]: {e}"); + process::exit(1); + }); + } + } +} + +#[tokio::main] +pub async fn main() { + env_logger::init(); + + let version = option_env!("VERGEN_GIT_SEMVER_LIGHTWEIGHT") + .unwrap_or(option_env!("VERGEN_GIT_SHA").unwrap_or("unknown")); + + let mut parser = Command::new("FMS data consumer") + .version(version) + .about("Receives FMS related VSS data points via Hono's Kafka based Telemetry API and writes them to an InfluxDB server") + .arg( + Arg::new(PARAM_KAFKA_PROPERTIES_FILE) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_KAFKA_PROPERTIES_FILE) + .help("The path to a file containing Kafka client properties for connecting to the Kafka broker(s).") + .action(ArgAction::Set) + .value_name("PATH") + .env("KAFKA_PROPERTIES_FILE") + .required(true), + ) + .arg( + Arg::new(PARAM_KAFKA_TOPIC_NAME) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_KAFKA_TOPIC_NAME) + .alias("topic") + .help("The name of the Kafka topic to consume VSS data from.") + .value_name("TOPIC") + .required(true) + .env("KAFKA_TOPIC_NAME"), + ); + + parser = influx_client::connection::add_command_line_args(parser); + let args = parser.get_matches(); + info!("starting FMS data consumer"); + run_async_processor(&args).await +} diff --git a/components/fms-forwarder/Cargo.toml b/components/fms-forwarder/Cargo.toml new file mode 100644 index 0000000..00579b2 --- /dev/null +++ b/components/fms-forwarder/Cargo.toml @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +[package] +name = "fms-forwarder" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +documentation.workspace = true +readme.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-trait = { workspace = true } +chrono = { workspace = true } +clap = { workspace = true, features = ["std", "env", "color", "help", "usage", "error-context", "suggestions"] } +duration-str = { workspace = true } +env_logger = { workspace = true } +fms-proto = { workspace = true } +influx-client = { workspace = true, features = ["writer"] } +log = { workspace = true } +paho-mqtt = { version = "0.12", default-features = false, features = [ "vendored-ssl" ] } +protobuf = { workspace = true } +prost = { workspace = true } +prost-types = { workspace = true } +tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] } +tonic = { workspace = true, features = ["channel", "codegen", "tls", "prost"] } + +[build-dependencies] +protoc-bin-vendored = { workspace = true } +tonic-build = { workspace = true, features = ["prost", "transport"]} diff --git a/components/fms-forwarder/README.md b/components/fms-forwarder/README.md new file mode 100644 index 0000000..04df059 --- /dev/null +++ b/components/fms-forwarder/README.md @@ -0,0 +1,64 @@ + +The FMS Forwarder polls FMS related data from a [kuksa.val Databroker](https://github.com/eclipse/kuksa.val/tree/master/kuksa_databroker) +and HTTP POSTs the data as a set of *measurements* to an InfluxDB server. + +The implementation uses the proto definition for [kuksa.val.v1](https://github.com/eclipse/kuksa.val/tree/master/proto/kuksa/val/v1) +which has been copied to [/proto/kuksa/val/v1](/proto/kuksa/val/v1/). + +# Building + +Building the forwarder requires a [Rust development toolchain](https://rustup.rs/). + +# Running + +THe forwarder reads the current vehicle status data from a kuksa.val Databroker and forwards it to one of multiple supported +back ends. The type of back end can be selected by means of command line arguments when starting the forwarder. + +Please refer to the command line help for details: + +```sh +fms-forwarder --help +``` + +## Writing directly to an InfluxDB Server + +The forwarder can write status information directly to an InfluxDB server using its HTTP based API. +For this to work, the forwarder needs to be configured with the URI of the InfluxDB server and an API token for +authenticating to the server. + +Please refer to the command line help for details: + +```sh +fms-forwarder influx --help +``` + +## Publishing to Eclipse Hono + +The forwarder can publish status information to the MQTT adapter of an [Eclipse Hono](https://eclipse.org/hono) instance. +For this to work, the forwarder needs to be configured with the URI of the MQTT adapter endpoint, the credentials to use for +authentication and the name of the tenant that the device belongs to. + +Please refer to the command line help for details: + +```sh +fms-forwarder hono --help +``` diff --git a/components/fms-forwarder/build.rs b/components/fms-forwarder/build.rs new file mode 100644 index 0000000..09222d3 --- /dev/null +++ b/components/fms-forwarder/build.rs @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +fn main() -> Result<(), Box> { + + // use vendored protoc instead of relying on user provided protobuf installation + std::env::set_var("PROTOC", protoc_bin_vendored::protoc_bin_path().unwrap()); + + tonic_build::configure() + .compile_well_known_types(false) + .build_server(false) + .compile( + &["proto/kuksa/val/v1/val.proto"], + &[ + "proto", + "proto/kuksa/val/v1", + ])?; + Ok(()) +} diff --git a/components/fms-forwarder/proto/kuksa/val/v1/types.proto b/components/fms-forwarder/proto/kuksa/val/v1/types.proto new file mode 100644 index 0000000..21ddc33 --- /dev/null +++ b/components/fms-forwarder/proto/kuksa/val/v1/types.proto @@ -0,0 +1,284 @@ +// Copyright Robert Bosch GmbH, 2022. Part of the Eclipse Kuksa Project. +// +// All rights reserved. This configuration file is provided to you under the +// terms and conditions of the Eclipse Distribution License v1.0 which +// accompanies this distribution, and is available at +// http://www.eclipse.org/org/documents/edl-v10.php + +syntax = "proto3"; + +// I added V1 as in databroker. Is this good practice? +package kuksa.val.v1; +import "google/protobuf/timestamp.proto"; + +// Should probably be changed to something like: +// option go_package = "github.com/eclipse/kuksa.val/proto/v1"; +option go_package = "/kuksa_grpc_proto"; + +// Describes a VSS entry +// When requesting an entry, the amount of information returned can +// be controlled by specifying either a `View` or a set of `Field`s. +message DataEntry { + // Defines the full VSS path of the entry. + string path = 1; // [field: FIELD_PATH] + + // The value (datapoint) + Datapoint value = 2; // [field: FIELD_VALUE] + + // Actuator target (only used if the entry is an actuator) + Datapoint actuator_target = 3; // [field: FIELD_ACTUATOR_TARGET] + + // Metadata for this entry + Metadata metadata = 10; // [field: FIELD_METADATA] +} + +message Datapoint { + google.protobuf.Timestamp timestamp = 1; + + oneof value { + string string = 11; + bool bool = 12; + sint32 int32 = 13; + sint64 int64 = 14; + uint32 uint32 = 15; + uint64 uint64 = 16; + float float = 17; + double double = 18; + StringArray string_array = 21; + BoolArray bool_array = 22; + Int32Array int32_array = 23; + Int64Array int64_array = 24; + Uint32Array uint32_array = 25; + Uint64Array uint64_array = 26; + FloatArray float_array = 27; + DoubleArray double_array = 28; + } +} + +message Metadata { + // Data type + // The VSS data type of the entry (i.e. the value, min, max etc). + // + // NOTE: protobuf doesn't have int8, int16, uint8 or uint16 which means + // that these values must be serialized as int32 and uint32 respectively. + DataType data_type = 11; // [field: FIELD_METADATA_DATA_TYPE] + + // Entry type + EntryType entry_type = 12; // [field: FIELD_METADATA_ENTRY_TYPE] + + // Description + // Describes the meaning and content of the entry. + optional string description = 13; // [field: FIELD_METADATA_DESCRIPTION] + + // Comment [optional] + // A comment can be used to provide additional informal information + // on a entry. + optional string comment = 14; // [field: FIELD_METADATA_COMMENT] + + // Deprecation [optional] + // Whether this entry is deprecated. Can contain recommendations of what + // to use instead. + optional string deprecation = 15; // [field: FIELD_METADATA_DEPRECATION] + + // Unit [optional] + // The unit of measurement + optional string unit = 16; // [field: FIELD_METADATA_UNIT] + + // Value restrictions [optional] + // Restrict which values are allowed. + // Only restrictions matching the DataType {datatype} above are valid. + ValueRestriction value_restriction = 17; // [field: FIELD_METADATA_VALUE_RESTRICTION] + + // Entry type specific metadata + oneof entry_specific { + Actuator actuator = 20; // [field: FIELD_METADATA_ACTUATOR] + Sensor sensor = 30; // [field: FIELD_METADATA_SENSOR] + Attribute attribute = 40; // [field: FIELD_METADATA_ATTRIBUTE] + } +} + +/////////////////////// +// Actuator specific fields +message Actuator { + // Nothing for now +} + +//////////////////////// +// Sensor specific +message Sensor { + // Nothing for now +} + +//////////////////////// +// Attribute specific +message Attribute { + // Nothing for now. +} + +// Value restriction +// +// One ValueRestriction{type} for each type, since +// they don't make sense unless the types match +// +message ValueRestriction { + oneof type { + ValueRestrictionString string = 21; + // For signed VSS integers + ValueRestrictionInt signed = 22; + // For unsigned VSS integers + ValueRestrictionUint unsigned = 23; + // For floating point VSS values (float and double) + ValueRestrictionFloat floating_point = 24; + } +} + +message ValueRestrictionInt { + optional sint64 min = 1; + optional sint64 max = 2; + repeated sint64 allowed_values = 3; +} + +message ValueRestrictionUint { + optional uint64 min = 1; + optional uint64 max = 2; + repeated uint64 allowed_values = 3; +} + +message ValueRestrictionFloat { + optional double min = 1; + optional double max = 2; + + // allowed for doubles/floats not recommended + repeated double allowed_values = 3; +} + +// min, max doesn't make much sense for a string +message ValueRestrictionString { + repeated string allowed_values = 3; +} + +// VSS Data type of a signal +// +// Protobuf doesn't support int8, int16, uint8 or uint16. +// These are mapped to int32 and uint32 respectively. +// +enum DataType { + DATA_TYPE_UNSPECIFIED = 0; + DATA_TYPE_STRING = 1; + DATA_TYPE_BOOLEAN = 2; + DATA_TYPE_INT8 = 3; + DATA_TYPE_INT16 = 4; + DATA_TYPE_INT32 = 5; + DATA_TYPE_INT64 = 6; + DATA_TYPE_UINT8 = 7; + DATA_TYPE_UINT16 = 8; + DATA_TYPE_UINT32 = 9; + DATA_TYPE_UINT64 = 10; + DATA_TYPE_FLOAT = 11; + DATA_TYPE_DOUBLE = 12; + DATA_TYPE_TIMESTAMP = 13; + DATA_TYPE_STRING_ARRAY = 20; + DATA_TYPE_BOOLEAN_ARRAY = 21; + DATA_TYPE_INT8_ARRAY = 22; + DATA_TYPE_INT16_ARRAY = 23; + DATA_TYPE_INT32_ARRAY = 24; + DATA_TYPE_INT64_ARRAY = 25; + DATA_TYPE_UINT8_ARRAY = 26; + DATA_TYPE_UINT16_ARRAY = 27; + DATA_TYPE_UINT32_ARRAY = 28; + DATA_TYPE_UINT64_ARRAY = 29; + DATA_TYPE_FLOAT_ARRAY = 30; + DATA_TYPE_DOUBLE_ARRAY = 31; + DATA_TYPE_TIMESTAMP_ARRAY = 32; +} + +// Entry type +enum EntryType { + ENTRY_TYPE_UNSPECIFIED = 0; + ENTRY_TYPE_ATTRIBUTE = 1; + ENTRY_TYPE_SENSOR = 2; + ENTRY_TYPE_ACTUATOR = 3; +} + +// A `View` specifies a set of fields which should +// be populated in a `DataEntry` (in a response message) +enum View { + VIEW_UNSPECIFIED = 0; // Unspecified. Equivalent to VIEW_CURRENT_VALUE unless `fields` are explicitly set. + VIEW_CURRENT_VALUE = 1; // Populate DataEntry with value. + VIEW_TARGET_VALUE = 2; // Populate DataEntry with actuator target. + VIEW_METADATA = 3; // Populate DataEntry with metadata. + VIEW_FIELDS = 10; // Populate DataEntry only with requested fields. + VIEW_ALL = 20; // Populate DataEntry with everything. +} + +// A `Field` corresponds to a specific field of a `DataEntry`. +// +// It can be used to: +// * populate only specific fields of a `DataEntry` response. +// * specify which fields of a `DataEntry` should be set as +// part of a `Set` request. +// * subscribe to only specific fields of a data entry. +// * convey which fields of an updated `DataEntry` have changed. +enum Field { + FIELD_UNSPECIFIED = 0; // "*" i.e. everything + FIELD_PATH = 1; // path + FIELD_VALUE = 2; // value + FIELD_ACTUATOR_TARGET = 3; // actuator_target + FIELD_METADATA = 10; // metadata.* + FIELD_METADATA_DATA_TYPE = 11; // metadata.data_type + FIELD_METADATA_DESCRIPTION = 12; // metadata.description + FIELD_METADATA_ENTRY_TYPE = 13; // metadata.entry_type + FIELD_METADATA_COMMENT = 14; // metadata.comment + FIELD_METADATA_DEPRECATION = 15; // metadata.deprecation + FIELD_METADATA_UNIT = 16; // metadata.unit + FIELD_METADATA_VALUE_RESTRICTION = 17; // metadata.value_restriction.* + FIELD_METADATA_ACTUATOR = 20; // metadata.actuator.* + FIELD_METADATA_SENSOR = 30; // metadata.sensor.* + FIELD_METADATA_ATTRIBUTE = 40; // metadata.attribute.* +} + +// Error response shall be an HTTP-like code. +// Should follow https://www.w3.org/TR/viss2-transport/#status-codes. +message Error { + uint32 code = 1; + string reason = 2; + string message = 3; +} + +// Used in get/set requests to report errors for specific entries +message DataEntryError { + string path = 1; // vss path + Error error = 2; +} + +message StringArray { + repeated string values = 1; +} + +message BoolArray { + repeated bool values = 1; +} + +message Int32Array { + repeated sint32 values = 1; +} + +message Int64Array { + repeated sint64 values = 1; +} + +message Uint32Array { + repeated uint32 values = 1; +} + +message Uint64Array { + repeated uint64 values = 1; +} + +message FloatArray { + repeated float values = 1; +} + +message DoubleArray { + repeated double values = 1; +} diff --git a/components/fms-forwarder/proto/kuksa/val/v1/val.proto b/components/fms-forwarder/proto/kuksa/val/v1/val.proto new file mode 100644 index 0000000..948cd71 --- /dev/null +++ b/components/fms-forwarder/proto/kuksa/val/v1/val.proto @@ -0,0 +1,114 @@ +// Copyright Robert Bosch GmbH, 2022. Part of the Eclipse Kuksa Project. +// +// All rights reserved. This configuration file is provided to you under the +// terms and conditions of the Eclipse Distribution License v1.0 which +// accompanies this distribution, and is available at +// http://www.eclipse.org/org/documents/edl-v10.php + +// This is a base proto file for databroker and kuksa-val-basic +// function set + +syntax = "proto3"; + +package kuksa.val.v1; + +import "types.proto"; + +// Should probably be changed to something like: +// option go_package = "github.com/eclipse/kuksa.val/proto/v1"; +option go_package = "/kuksa_grpc_proto"; + +// Note on authorization: +// Tokens (auth-token or auth-uuid) are sent as (GRPC / http2) metadata. +// +// The auth-token is a JWT compliant token as the examples found here: +// https://github.com/eclipse/kuksa.val/tree/master/kuksa_certificates/jwt +// +// See also https://github.com/eclipse/kuksa.val/blob/master/doc/jwt.md +// +// Upon reception of auth-token, server shall generate an auth-uuid in metadata +// that the client can use instead of auth-token in subsequent calls. + +service VAL { + // Get entries + rpc Get(GetRequest) returns (GetResponse); + + // Set entries + rpc Set(SetRequest) returns (SetResponse); + + // Subscribe to a set of entries + // + // Returns a stream of notifications. + // + // InvalidArgument is returned if the request is malformed. + rpc Subscribe(SubscribeRequest) returns (stream SubscribeResponse); + + // Shall return information that allows the client to determine + // what server/server implementation/version it is talking to + // eg. kuksa-databroker 0.5.1 + rpc GetServerInfo(GetServerInfoRequest) returns (GetServerInfoResponse); +} + +// Define which data we want +message EntryRequest { + string path = 1; + View view = 2; + repeated Field fields = 3; +} + +// Request a set of entries. +message GetRequest { + repeated EntryRequest entries = 1; +} + +// Global errors are specified in `error`. +// Errors for individual entries are specified in `errors`. +message GetResponse { + repeated DataEntry entries = 1; + repeated DataEntryError errors = 2; + Error error = 3; +} + +// Define the data we want to set +message EntryUpdate { + DataEntry entry = 1; + repeated Field fields = 2; +} + +// A list of entries to be updated +message SetRequest { + repeated EntryUpdate updates = 1; +} + +// Global errors are specified in `error`. +// Errors for individual entries are specified in `errors`. +message SetResponse { + Error error = 1; + repeated DataEntryError errors = 2; +} + +// Define what to subscribe to +message SubscribeEntry { + string path = 1; + View view = 2; + repeated Field fields = 3; +} + +// Subscribe to changes in datapoints. +message SubscribeRequest { + repeated SubscribeEntry entries = 1; +} + +// A subscription response +message SubscribeResponse { + repeated EntryUpdate updates = 1; +} + +message GetServerInfoRequest { + // Nothing yet +} + +message GetServerInfoResponse { + string name = 1; + string version = 2; +} \ No newline at end of file diff --git a/components/fms-forwarder/src/hono_publisher.rs b/components/fms-forwarder/src/hono_publisher.rs new file mode 100644 index 0000000..2c9ad2e --- /dev/null +++ b/components/fms-forwarder/src/hono_publisher.rs @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use async_trait::async_trait; +use clap::{ArgMatches, Command}; +use fms_proto::fms::VehicleStatus; +use log::{debug, warn}; +use mqtt::MessageBuilder; +use paho_mqtt as mqtt; +use protobuf::Message; + +use crate::{status_publishing::StatusPublisher, mqtt_connection::{self, MqttConnection}}; + +const TOPIC_TELEMETRY: &str = "telemetry/?content-type=application%2Fvnd.google.protobuf"; + +/// Adds arguments to an existing command line which can be +/// used to configure the connection to a Hono MQTT protocol adapter. +/// +/// See [`mqtt_connection::add_command_line_args`] +/// +pub fn add_command_line_args(command: Command) -> Command { + mqtt_connection::add_command_line_args(command) +} + +pub struct HonoPublisher { + mqtt_connection: MqttConnection, +} + +impl HonoPublisher { + + /// Creates a new publisher. + /// + /// Determines the parameters necessary for creating the publisher from values specified on + /// the command line or via environment variables as defined by [`add_command_line_args`]. + /// + /// The publisher returned is configured to keep trying to (re-)connect to the configured + /// MQTT endpoint using a client certificate of username/password credentials. + pub async fn new(args: &ArgMatches) -> Result> { + + MqttConnection::new(&args).await + .map(|con| { + HonoPublisher { mqtt_connection: con } + }) + } + } + +#[async_trait] +impl StatusPublisher for HonoPublisher { + async fn publish_vehicle_status(&self, vehicle_status: &VehicleStatus) { + match vehicle_status.write_to_bytes() { + Ok(payload) => { + let msg = MessageBuilder::new() + .topic(TOPIC_TELEMETRY) + .payload(payload) + .finalize(); + match self.mqtt_connection.mqtt_client.publish(msg).await { + Ok(_t) => debug!( + "successfully published vehicle status to MQTT endpoint [uri: {}, topic: {}]", + self.mqtt_connection.uri, TOPIC_TELEMETRY + ), + Err(e) => { + warn!( + "error publishing vehicle status to MQTT endpoint [uri: {}, topic: {}]: {}", + self.mqtt_connection.uri, TOPIC_TELEMETRY, e + ); + } + }; + return; + } + Err(e) => warn!( + "error serializing vehicle status to protobuf message: {}", + e + ), + } + } +} diff --git a/components/fms-forwarder/src/main.rs b/components/fms-forwarder/src/main.rs new file mode 100644 index 0000000..8185955 --- /dev/null +++ b/components/fms-forwarder/src/main.rs @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use std::process; + +use clap::Command; +use fms_proto::fms::VehicleStatus; +use status_publishing::StatusPublisher; +use hono_publisher::HonoPublisher; +use influx_client::writer::InfluxWriter; +use log::{error, info}; +use tokio::sync::mpsc; + +mod status_publishing; +mod vehicle_abstraction; +mod hono_publisher; +mod mqtt_connection; + +const SUBCOMMAND_HONO: &str = "hono"; +const SUBCOMMAND_INFLUX: &str = "influx"; + +#[tokio::main] +async fn main() -> Result<(), Box> { + env_logger::init(); + let version = option_env!("VERGEN_GIT_SEMVER_LIGHTWEIGHT") + .unwrap_or(option_env!("VERGEN_GIT_SHA").unwrap_or("unknown")); + + let mut parser = Command::new("fms-forwarder") + .arg_required_else_help(true) + .version(version) + .about("Forwards FMS related VSS data points to a back end system"); + parser = vehicle_abstraction::add_command_line_args(parser); + parser = parser + .subcommand_required(true) + .subcommand(hono_publisher::add_command_line_args( + Command::new(SUBCOMMAND_HONO).about("Forwards VSS data to Hono's MQTT adapter"), + )) + .subcommand(influx_client::connection::add_command_line_args( + Command::new(SUBCOMMAND_INFLUX).about("Forwards VSS data to an Influx DB server"), + )); + + let args = parser.get_matches(); + + let publisher: Box = match args.subcommand_name() { + Some(SUBCOMMAND_HONO) => { + let hono_args = args.subcommand_matches(SUBCOMMAND_HONO).unwrap(); + match HonoPublisher::new(&hono_args).await { + Ok(writer) => Box::new(writer), + Err(e) => { + error!("failed to create Hono publisher: {}", e); + process::exit(1); + }, + } + }, + Some(SUBCOMMAND_INFLUX) => { + let influx_args = args.subcommand_matches(SUBCOMMAND_INFLUX).unwrap(); + match InfluxWriter::new(&influx_args) { + Ok(writer) => Box::new(writer), + Err(e) => { + error!("failed to create InfluxDB writer: {e}"); + process::exit(1); + } + } + }, + Some(_) => { + // cannot happen because subcommand is required + process::exit(1); + }, + None => { + // cannot happen because subcommand is required + process::exit(1); + }, + }; + + info!("starting FMS forwarder"); + + let (tx, mut rx) = mpsc::channel::(30); + vehicle_abstraction::init(&args, tx).await?; + + while let Some(vehicle_status) = rx.recv().await { + publisher + .as_ref() + .publish_vehicle_status(&vehicle_status) + .await; + } + Ok(()) +} diff --git a/components/fms-forwarder/src/mqtt_connection.rs b/components/fms-forwarder/src/mqtt_connection.rs new file mode 100644 index 0000000..2f2587f --- /dev/null +++ b/components/fms-forwarder/src/mqtt_connection.rs @@ -0,0 +1,264 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Arg, ArgMatches, Command}; +use log::{error, info, warn}; +use mqtt::{ + AsyncClient, ConnectOptionsBuilder, CreateOptionsBuilder, SslOptionsBuilder, +}; +use paho_mqtt as mqtt; +use std::{thread, time::Duration}; + + +const PARAM_CA_PATH: &str = "ca-path"; +const PARAM_DEVICE_CERT: &str = "device-cert"; +const PARAM_DEVICE_KEY: &str = "device-key"; +const PARAM_MQTT_CLIENT_ID: &str = "mqtt-client-id"; +const PARAM_MQTT_URI: &str = "mqtt-uri"; +const PARAM_MQTT_USERNAME: &str = "mqtt-username"; +const PARAM_MQTT_PASSWORD: &str = "mqtt-password"; +const PARAM_TRUST_STORE_PATH: &str = "trust-store-path"; + +/// Adds arguments to an existing command line which can be +/// used to configure the connection to an MQTT endpoint. +/// +/// The following arguments are being added: +/// +/// | long name | environment variable | default value | +/// |---------------------|----------------------|---------------| +/// | mqtt-client-id | MQTT_CLIENT_ID | random ID | +/// | mqtt-uri | MQTT_URI | - | +/// | mqtt-username | MQTT_USERNAME | - | +/// | mqtt-password | MQTT_PASSWORD | - | +/// | device-cert | DEVICE_CERT | - | +/// | device-key | DEVICE_KEY | - | +/// | ca-path | CA_PATH | - | +/// | trust-store-path | TRUST_STORE_PATH | - | +/// +pub fn add_command_line_args(command: Command) -> Command { + command + .arg( + Arg::new(PARAM_MQTT_CLIENT_ID) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_MQTT_CLIENT_ID) + .help("The client identifier to use in the MQTT Connect Packet.") + .value_name("ID") + .required(false) + .env("MQTT_CLIENT_ID"), + ) + .arg( + Arg::new(PARAM_MQTT_URI) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_MQTT_URI) + .help("The URI of the MQTT adapter to publish data to.") + .value_name("URI") + .required(true) + .env("MQTT_URI"), + ) + .arg( + Arg::new(PARAM_MQTT_USERNAME) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_MQTT_USERNAME) + .help("The username to use for authenticating to the MQTT endpoint.") + .value_name("USERNAME") + .required(false) + .env("MQTT_USERNAME"), + ) + .arg( + Arg::new(PARAM_MQTT_PASSWORD) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_MQTT_PASSWORD) + .help("The password to use for authenticating to the MQTT endpoint.") + .value_name("PWD") + .required(false) + .env("MQTT_PASSWORD"), + ) + .arg( + Arg::new(PARAM_DEVICE_CERT) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_DEVICE_CERT) + .help("The path to a PEM file containing the X.509 certificate that the device should use for authentication.") + .value_name("PATH") + .required(false) + .env("DEVICE_CERT"), + ) + .arg( + Arg::new(PARAM_DEVICE_KEY) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_DEVICE_KEY) + .help("The path to a PEM file containing the private key that the device should use for authentication.") + .value_name("PATH") + .required(false) + .env("DEVICE_KEY"), + ) + .arg( + Arg::new(PARAM_CA_PATH) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_CA_PATH) + .help("The path to a folder that contains PEM files for trusted certificate authorities.") + .value_name("PATH") + .required(false) + .env("CA_PATH"), + ) + .arg( + Arg::new(PARAM_TRUST_STORE_PATH) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_TRUST_STORE_PATH) + .help("The path to a file that contains PEM encoded trusted certificates.") + .value_name("PATH") + .required(false) + .env("TRUST_STORE_PATH"), + ) +} + +/// A connection to an MQTT endpoint. +/// +pub struct MqttConnection { + pub mqtt_client: AsyncClient, + pub uri: String, + pub client_id: String, +} + +impl MqttConnection { + + /// Creates a new connection to an MQTT endpoint. + /// + /// Expects to find parameters as defined by [`add_command_line_args`] in the passed + /// in *args*. + /// + /// The connection returned is configured to keep trying to (re-)connect to the configured + /// MQTT endpoint. + pub async fn new(args: &ArgMatches) -> Result> { + let mqtt_uri = args + .get_one::(PARAM_MQTT_URI) + .unwrap() + .to_owned(); + let client_id = args + .get_one::(PARAM_MQTT_CLIENT_ID) + .unwrap_or(&"".to_string()) + .to_owned(); + let mut ssl_options_builder = SslOptionsBuilder::new(); + match args.get_one::(PARAM_CA_PATH) { + Some(path) => match ssl_options_builder.ca_path(path) { + Err(e) => { + error!("failed to set CA path on MQTT client: {e}"); + return Err(Box::new(e)); + } + Ok(_builder) => (), + }, + None => (), + }; + match args.get_one::(PARAM_TRUST_STORE_PATH) { + Some(path) => match ssl_options_builder.trust_store(path) { + Err(e) => { + error!("failed to set trust store path on MQTT client: {e}"); + return Err(Box::new(e)); + } + Ok(_builder) => (), + }, + None => (), + }; + + let mut connect_options_builder = ConnectOptionsBuilder::new_v3(); + connect_options_builder.connect_timeout(Duration::from_secs(10)); + connect_options_builder + .automatic_reconnect(Duration::from_secs(1), Duration::from_secs(16)); + connect_options_builder.clean_session(true); + connect_options_builder.keep_alive_interval(Duration::from_secs(10)); + connect_options_builder.max_inflight(10); + + match ( + args.get_one::(PARAM_MQTT_USERNAME), + args.get_one::(PARAM_MQTT_PASSWORD), + args.get_one::(PARAM_DEVICE_CERT), + args.get_one::(PARAM_DEVICE_KEY), + ) { + (_, _, Some(cert_path), Some(key_path)) => { + match ssl_options_builder.key_store(cert_path) { + Ok(_builder) => (), + Err(e) => { + error!("failed to set client certificate for MQTT client: {e}"); + return Err(Box::new(e)); + } + } + match ssl_options_builder.private_key(key_path) { + Ok(_builder) => (), + Err(e) => { + error!("failed to set private key for MQTT client: {e}"); + return Err(Box::new(e)); + } + } + info!("using client certificate for authenticating to MQTT endpoint"); + } + (Some(username), Some(password), _, _) => { + connect_options_builder.user_name(username); + connect_options_builder.password(password); + info!("using username and password for authenticating to MQTT endpoint"); + } + _ => { + info!("no credentials specified, trying to connect anonymously to MQTT endpoint"); + } + } + + connect_options_builder.ssl_options(ssl_options_builder.finalize()); + let connect_options = connect_options_builder.finalize(); + info!("connecting to MQTT endpoint at {}", mqtt_uri); + match CreateOptionsBuilder::new() + .server_uri(&mqtt_uri) + .max_buffered_messages(50) + .send_while_disconnected(true) + .delete_oldest_messages(true) + .client_id(&client_id) + .create_client() + { + Err(e) => { + error!("failed to create MQTT client: {}", e); + Err(Box::new(e)) + } + Ok(client) => { + client.connect_with_callbacks( + connect_options, + MqttConnection::on_connect_success, + MqttConnection::on_connect_failure, + ); + Ok(MqttConnection { + mqtt_client: client, + uri: mqtt_uri, + client_id, + }) + } + } + } + + fn on_connect_success(_client: &AsyncClient, _msgid: u16) { + info!("successfully connected to MQTT endpoint"); + } + + fn on_connect_failure(client: &AsyncClient, _msgid: u16, rc: i32) { + warn!( + "attempt to connect to MQTT endpoint failed with error code {}, retrying ...", + rc + ); + thread::sleep(Duration::from_secs(3)); + client.reconnect_with_callbacks( + MqttConnection::on_connect_success, + MqttConnection::on_connect_failure, + ); + } +} diff --git a/components/fms-forwarder/src/status_publishing.rs b/components/fms-forwarder/src/status_publishing.rs new file mode 100644 index 0000000..4147ada --- /dev/null +++ b/components/fms-forwarder/src/status_publishing.rs @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use async_trait::async_trait; +use fms_proto::fms::VehicleStatus; +use influx_client::writer::InfluxWriter; + +/// A facade for publishing Vehicle status information to a back end store. +#[async_trait] +pub trait StatusPublisher { + /// Publishes status information. + async fn publish_vehicle_status(&self, vehicle_status: &VehicleStatus); +} + +#[async_trait] +impl StatusPublisher for InfluxWriter { + async fn publish_vehicle_status(&self, vehicle_status: &VehicleStatus) { + self.write_vehicle_status(vehicle_status).await + } +} diff --git a/components/fms-forwarder/src/vehicle_abstraction.rs b/components/fms-forwarder/src/vehicle_abstraction.rs new file mode 100644 index 0000000..c34af5d --- /dev/null +++ b/components/fms-forwarder/src/vehicle_abstraction.rs @@ -0,0 +1,593 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +//! An abstraction of a vehicle's (current) status based on +//! [Eclipse kuksa.val Databroker](https://github.com/eclipse/kuksa.val). +//! +use clap::{Arg, ArgMatches, Command}; +use log::{debug, error, info, warn}; +use protobuf::MessageField; +use tokio::sync::mpsc::Sender; + +use std::{collections::HashMap, error::Error, fmt::Display, time::Duration}; + +use tonic::{ + transport::{Channel, Endpoint}, + Request, +}; + +use fms_proto::fms::{TellTaleInfo, Trigger, VehicleStatus}; +use kuksa::{datapoint::Value, val_client::ValClient, EntryRequest, Field, GetRequest, View}; + +use self::kuksa::{DataEntry, SubscribeEntry, SubscribeRequest, UnsupportedValueTypeError}; + +const SNAPSHOT_VSS_PATHS: &[&str] = &[ + vss::VSS_VEHICLE_CHASSIS_PARKINGBRAKE_ISENGAGED, + vss::VSS_VEHICLE_CURRENTLOCATION_ALTITUDE, + vss::VSS_VEHICLE_CURRENTLOCATION_HEADING, + vss::VSS_VEHICLE_CURRENTLOCATION_LATITUDE, + vss::VSS_VEHICLE_CURRENTLOCATION_LONGITUDE, + vss::FMS_VEHICLE_CURRENTLOCATION_SPEED, + vss::VSS_VEHICLE_CURRENTLOCATION_TIMESTAMP, + vss::VSS_VEHICLE_CURRENTOVERALLWEIGHT, + vss::VSS_VEHICLE_EXTERIOR_AIRTEMPERATURE, + vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_DIESELEXHAUSTFLUID_LEVEL, + vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_ENGINEHOURS, + vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_SPEED, + vss::FMS_VEHICLE_POWERTRAIN_CURRENTFUELTYPE, + vss::FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_ACCUMULATEDCONSUMPTION, + vss::VSS_VEHICLE_POWERTRAIN_FUELSYSTEM_RANGE, + vss::FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_TANK_FIRST_LEVEL, + vss::FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_TANK_SECOND_LEVEL, + vss::VSS_VEHICLE_POWERTRAIN_RANGE, + vss::VSS_VEHICLE_SPEED, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_CARDISSUINGMEMBERSTATE, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_IDENTIFICATION, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_WORKINGSTATE, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER2_WORKINGSTATE, + vss::FMS_VEHICLE_TACHOGRAPH_VEHICLESPEED, + vss::FMS_VEHICLE_TRAVELED_DISTANCE_HIGH_RES, + vss::VSS_VEHICLE_VEHICLEIDENTIFICATION_VIN, +]; + +const TRIGGER_VSS_PATHS: &[&str] = &[ + vss::FMS_VEHICLE_CABIN_TELLTALE_ECT_STATUS, + vss::FMS_VEHICLE_CABIN_TELLTALE_ENGINEOIL_STATUS, + vss::FMS_VEHICLE_CABIN_TELLTALE_ENGINE_STATUS, + vss::FMS_VEHICLE_CABIN_TELLTALE_FUELLEVEL_STATUS, + vss::FMS_VEHICLE_CABIN_TELLTALE_PARKINGBRAKE_STATUS, + vss::VSS_VEHICLE_CHASSIS_PARKINGBRAKE_ISENGAGED, + vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_ISRUNNING, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_ISCARDPRESENT, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_WORKINGSTATE, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER2_ISCARDPRESENT, + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER2_WORKINGSTATE, +]; + +const PARAM_DATABROKER_URI: &str = "databroker-uri"; +const PARAM_DEFAULT_VIN: &str = "default-vin"; +const PARAM_TIMER_INTERVAL: &str = "timer-interval"; + +const TELL_TALE_NAME_ECT: &str = "ENGINE_COOLANT_TEMPERATURE"; +const TELL_TALE_NAME_ENGINE_OIL: &str = "ENGINE_OIL"; +const TELL_TALE_NAME_ENGINE_MIL_INDICATOR: &str = "ENGINE_MIL_INDICATOR"; +const TELL_TALE_NAME_FUEL_LEVEL: &str = "FUEL_LEVEL"; +const TELL_TALE_NAME_PARKING_BRAKE: &str = "PARKING_BRAKE"; + +const TRIGGER_DRIVER1_WORKING_STATE_CHANGED: &str = "DRIVER_1_WORKING_STATE_CHANGED"; +const TRIGGER_DRIVER2_WORKING_STATE_CHANGED: &str = "DRIVER_2_WORKING_STATE_CHANGED"; +const TRIGGER_PARKING_BRAKE_SWITCH_CHANGE: &str = "PARKING_BRAKE_SWITCH_CHANGE"; +const TRIGGER_DRIVER_LOGIN: &str = "DRIVER_LOGIN"; +const TRIGGER_DRIVER_LOGOUT: &str = "DRIVER_LOGOUT"; +const TRIGGER_ENGINE_ON: &str = "ENGINE_ON"; +const TRIGGER_ENGINE_OFF: &str = "ENGINE_OFF"; +const TRIGGER_TELL_TALE: &str = "TELL_TALE"; +const TRIGGER_TIMER: &str = "TIMER"; + +mod kuksa; +mod vss; + +/// Adds arguments to an existing command line which can be +/// used to configure the component's behavior. +/// +/// The following arguments are being added: +/// +/// | long name | environment variable | default value | description | +/// |---------------------|----------------------|---------------|-------------| +/// | *databroker-uri* | *KUKSA_DATA_BROKER_URI*| `http://127.0.0.1:55555` | The HTTP(S) URI of the kuksa.val Databroker's gRPC endpoint. | +/// | *default-vin* | *DEFAULT_VIN* | `YV2E4C3A5VB180691` | The default VIN to use if the kuksa.val Databroker does not contain the vehicle's VIN. The VIN is used as a tag on measurements written to the InfluxDB server. | +/// | *timer-interval* | *TIMER_INTERVAL* | `5s` | The time period to wait after polling FMS snapshot data from the kuksa.val Databroker, e.g 5m10s or 1h15m. | +/// +pub fn add_command_line_args(command_line: Command) -> Command { + command_line + .arg( + Arg::new(PARAM_DATABROKER_URI) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_DATABROKER_URI) + .alias("uri") + .help("The HTTP(S) URI of the kuksa.val Databroker's gRPC endpoint.") + .value_name("URI") + .required(false) + .env("KUKSA_DATA_BROKER_URI") + .default_value("http://127.0.0.1:55555"), + ) + .arg( + Arg::new(PARAM_DEFAULT_VIN) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_DEFAULT_VIN) + .help("The default VIN to use if the kuksa.val Databroker does not contain the vehicle's VIN. The VIN is used as a tag on measurements written to the InfluxDB server.") + .value_name("IDENTIFIER") + .required(false) + .env("DEFAULT_VIN") + .default_value("YV2E4C3A5VB180691"), + ) + .arg( + Arg::new(PARAM_TIMER_INTERVAL) + .value_parser(duration_str::parse) + .long(PARAM_TIMER_INTERVAL) + .alias("timer") + .help("The time period to wait after polling FMS snapshot data from the kuksa.val Databroker, e.g 5m10s or 1h15m.") + .value_name("DURATION_SPEC") + .required(false) + .env("TIMER_INTERVAL") + .default_value("5s"), + ) +} + +/// Indicates a problem while invoking a Databroker operation. +#[derive(Debug)] +pub struct DatabrokerError { + description: String, +} + +impl Error for DatabrokerError { + fn description(&self) -> &str { + self.description.as_str() + } +} + +impl Display for DatabrokerError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "error invoking Databroker: {:?}", self.description) + } +} + +enum FmsTrigger { + Timer, + Driver1Login, + Driver1Logout, + Driver1WorkingStateChanged(String), + Driver2Login, + Driver2Logout, + Driver2WorkingStateChanged(String), + EngineOn, + EngineOff, + ParkingBreakSwitchChanged(bool), + TellTale(TellTaleInfo), +} + +impl FmsTrigger { + fn new_trigger(type_: &str) -> Trigger { + let mut trigger = Trigger::new(); + trigger.context = "RFMS".to_string(); + trigger.type_ = type_.to_string(); + trigger + } + + pub fn as_trigger(&self) -> Trigger { + match self { + Self::Timer => FmsTrigger::new_trigger(TRIGGER_TIMER), + Self::Driver1Login => FmsTrigger::new_trigger(TRIGGER_DRIVER_LOGIN), + Self::Driver1Logout => FmsTrigger::new_trigger(TRIGGER_DRIVER_LOGOUT), + Self::Driver1WorkingStateChanged(_status) => { + FmsTrigger::new_trigger(TRIGGER_DRIVER1_WORKING_STATE_CHANGED) + } + Self::Driver2Login => FmsTrigger::new_trigger(TRIGGER_DRIVER_LOGIN), + Self::Driver2Logout => FmsTrigger::new_trigger(TRIGGER_DRIVER_LOGOUT), + Self::Driver2WorkingStateChanged(_status) => { + FmsTrigger::new_trigger(TRIGGER_DRIVER2_WORKING_STATE_CHANGED) + } + Self::EngineOn => FmsTrigger::new_trigger(TRIGGER_ENGINE_ON), + Self::EngineOff => FmsTrigger::new_trigger(TRIGGER_ENGINE_OFF), + Self::ParkingBreakSwitchChanged(_is_engaged) => { + FmsTrigger::new_trigger(TRIGGER_PARKING_BRAKE_SWITCH_CHANGE) + } + Self::TellTale(info) => { + let mut trigger = FmsTrigger::new_trigger(TRIGGER_TELL_TALE); + trigger.tell_tale_info = MessageField::some(info.clone()); + trigger + } + } + } + + fn new_tell_tale_trigger( + data_entry: DataEntry, + name: &str, + ) -> Result { + if let Some(value) = data_entry.clone().value.and_then(|v| v.value) { + match String::try_from(value) { + Ok(status) => { + let mut tell_tale_info = TellTaleInfo::new(); + tell_tale_info.tell_tale = name.to_string(); + tell_tale_info.status = status; + Ok(FmsTrigger::TellTale(tell_tale_info)) + } + Err(e) => Err(e), + } + } else { + Err(UnsupportedValueTypeError {}) + } + } + + fn new_boolean_trigger FmsTrigger>( + data_entry: DataEntry, + trigger_producer: P, + ) -> Result { + if let Some(data_point) = data_entry.clone().value { + bool::try_from(data_point.value.unwrap()).map(trigger_producer) + } else { + Err(UnsupportedValueTypeError {}) + } + } + + fn new_string_value_trigger FmsTrigger>( + data_entry: DataEntry, + trigger_producer: P, + ) -> Result { + if let Some(data_point) = data_entry.clone().value { + String::try_from(data_point.value.unwrap()).map(trigger_producer) + } else { + Err(UnsupportedValueTypeError {}) + } + } +} + +impl TryFrom for FmsTrigger { + type Error = UnsupportedValueTypeError; + + fn try_from(data_entry: DataEntry) -> Result { + match data_entry.path.as_str() { + vss::FMS_VEHICLE_CABIN_TELLTALE_ECT_STATUS => { + FmsTrigger::new_tell_tale_trigger(data_entry, TELL_TALE_NAME_ECT) + } + vss::FMS_VEHICLE_CABIN_TELLTALE_ENGINEOIL_STATUS => { + FmsTrigger::new_tell_tale_trigger(data_entry, TELL_TALE_NAME_ENGINE_OIL) + } + vss::FMS_VEHICLE_CABIN_TELLTALE_ENGINE_STATUS => { + FmsTrigger::new_tell_tale_trigger(data_entry, TELL_TALE_NAME_ENGINE_MIL_INDICATOR) + } + vss::FMS_VEHICLE_CABIN_TELLTALE_FUELLEVEL_STATUS => { + FmsTrigger::new_tell_tale_trigger(data_entry, TELL_TALE_NAME_FUEL_LEVEL) + } + vss::FMS_VEHICLE_CABIN_TELLTALE_PARKINGBRAKE_STATUS => { + FmsTrigger::new_tell_tale_trigger(data_entry, TELL_TALE_NAME_PARKING_BRAKE) + } + vss::VSS_VEHICLE_CHASSIS_PARKINGBRAKE_ISENGAGED => { + FmsTrigger::new_boolean_trigger(data_entry, FmsTrigger::ParkingBreakSwitchChanged) + } + vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_ISRUNNING => { + FmsTrigger::new_boolean_trigger(data_entry, |is_running| { + if is_running { + FmsTrigger::EngineOn + } else { + FmsTrigger::EngineOff + } + }) + } + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_ISCARDPRESENT => { + FmsTrigger::new_boolean_trigger(data_entry, |card_is_present| { + if card_is_present { + FmsTrigger::Driver1Login + } else { + FmsTrigger::Driver1Logout + } + }) + } + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_WORKINGSTATE => { + FmsTrigger::new_string_value_trigger( + data_entry, + FmsTrigger::Driver1WorkingStateChanged, + ) + } + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER2_ISCARDPRESENT => { + FmsTrigger::new_boolean_trigger(data_entry, |card_is_present| { + if card_is_present { + FmsTrigger::Driver2Login + } else { + FmsTrigger::Driver2Logout + } + }) + } + vss::FMS_VEHICLE_TACHOGRAPH_DRIVER2_WORKINGSTATE => { + FmsTrigger::new_string_value_trigger( + data_entry, + FmsTrigger::Driver2WorkingStateChanged, + ) + } + _ => Err(UnsupportedValueTypeError {}), + } + } +} + +struct KuksaValDatabroker { + client: Box>, + default_vin: String, +} + +impl KuksaValDatabroker { + async fn new(args: &ArgMatches) -> Result { + let databroker_uri = args + .get_one::(PARAM_DATABROKER_URI) + .unwrap() + .to_owned(); + + let default_vin = args + .get_one::(PARAM_DEFAULT_VIN) + .unwrap() + .to_owned(); + + info!( + "creating client for kuksa.val Databroker at {}", + databroker_uri + ); + Endpoint::from_shared(databroker_uri.to_owned()) + .map_err(|e| { + error!("invalid Databroker URI: {}", e); + DatabrokerError { + description: e.to_string(), + } + }) + .map(|builder| { + let channel = builder + .connect_timeout(Duration::from_secs(5)) + .timeout(Duration::from_secs(5)) + .connect_lazy(); + let client = ValClient::new(channel); + KuksaValDatabroker { + client: Box::new(client), + default_vin, + } + }) + } + + pub async fn get_vehicle_status(&mut self) -> Result { + let entry_requests: Vec = SNAPSHOT_VSS_PATHS + .into_iter() + .map(|path| EntryRequest { + path: path.to_string(), + view: View::CurrentValue as i32, + fields: vec![Field::Value as i32], + }) + .collect(); + + let mut vss_data: HashMap = HashMap::new(); + match self + .client + .get(Request::new(GetRequest { + entries: entry_requests, + })) + .await + .map(|res| res.into_inner()) + { + Err(status) => { + warn!("failed to retrieve snapshot data points from Databroker {status}"); + Err(DatabrokerError { + description: format!("status code {}", status.code()), + }) + } + Ok(get_response) => { + if let Some(error) = get_response.error { + warn!( + "response from Databroker contains global error [code: {}, message: {}]", + error.code, error.message + ); + } else { + get_response + .errors + .into_iter() + .for_each(|data_entry_error| { + if let Some(err) = data_entry_error.error { + warn!( + "response from Databroker contains error [path: {}, error: {:?}]", + data_entry_error.path, err + ); + } + }); + get_response.entries.into_iter().for_each(|data_entry| { + let name = data_entry.path.to_owned(); + if let Some(value) = data_entry.value.and_then(|dp| dp.value) { + debug!("got value [path: {}]: {:?}", name, value); + vss_data.insert(name, value); + } + }); + } + Ok(kuksa::new_vehicle_status(vss_data, &self.default_vin)) + } + } + } + + pub async fn register_triggers( + &mut self, + sender: Sender, + ) -> Result<(), DatabrokerError> { + let subscribe_entries: Vec = TRIGGER_VSS_PATHS + .into_iter() + .map(|path| SubscribeEntry { + path: path.to_string(), + view: View::CurrentValue as i32, + fields: vec![Field::Value as i32], + }) + .collect(); + + let req = SubscribeRequest { + entries: subscribe_entries, + }; + + match self.client.subscribe(req).await { + Ok(response) => { + let mut stream = response.into_inner(); + tokio::task::spawn(async move { + while let Ok(message) = stream.message().await { + if let Some(response) = message { + for update in response.updates { + match update.entry { + Some(data_entry) => { + if let Ok(trigger) = FmsTrigger::try_from(data_entry) { + let _ = sender.send(trigger).await; + } + } + None => { + debug!( + "ignoring notification from Databroker containing no data" + ); + } + } + } + } + } + }); + Ok(()) + } + Err(e) => { + warn!("failed to register triggers for signals: {}", e); + Err(DatabrokerError { + description: e.message().to_string(), + }) + } + } + } +} + +/// Sets up a connection to the Databroker and registers callbacks for +/// signals that trigger the reporting of the vehicle's current status. +/// +/// Expects to find parameters as defined by [`add_command_line_args`] in the passed +/// in *args*. +/// +pub async fn init( + args: &ArgMatches, + status_publisher: Sender, +) -> Result<(), DatabrokerError> { + let timer_interval = args + .get_one::(PARAM_TIMER_INTERVAL) + .unwrap() + .to_owned(); + + let mut databroker = KuksaValDatabroker::new(args).await?; + let (tx, mut rx) = tokio::sync::mpsc::channel::(50); + let _ = &databroker.register_triggers(tx.clone()).await?; + + tokio::task::spawn(async move { + let mut current_status = VehicleStatus::new(); + + while let Some(fms_trigger) = rx.recv().await { + match databroker.get_vehicle_status().await { + Err(e) => { + warn!( + "failed to retrieve current vehicle status from databroker: {}", + e + ); + } + Ok(mut new_vehicle_status) => { + let last_known_status = current_status.clone(); + current_status = new_vehicle_status.clone(); + let mut trigger = fms_trigger.as_trigger(); + match fms_trigger { + FmsTrigger::Driver1Login => { + info!("driver one has logged in"); + trigger.driver = new_vehicle_status.driver1_id.clone(); + } + FmsTrigger::Driver1Logout => { + info!("driver one has logged out"); + trigger.driver = last_known_status.driver1_id.clone(); + } + FmsTrigger::Driver1WorkingStateChanged(status) => { + info!( + "driver one's working state has changed to status {}", + status + ); + trigger.driver = last_known_status.driver1_id.clone(); + } + FmsTrigger::Driver2Login => { + info!("driver two has logged in"); + trigger.driver = new_vehicle_status + .snapshot_data + .get_or_default() + .driver2_id + .clone(); + } + FmsTrigger::Driver2Logout => { + info!("driver two has logged out"); + trigger.driver = last_known_status + .snapshot_data + .get_or_default() + .driver2_id + .clone(); + } + FmsTrigger::Driver2WorkingStateChanged(status) => { + info!( + "driver two's working state has changed to status {}", + status + ); + trigger.driver = last_known_status + .snapshot_data + .get_or_default() + .driver2_id + .clone(); + } + FmsTrigger::EngineOn => { + info!("engine has been started"); + } + FmsTrigger::EngineOff => { + info!("engine has been stopped"); + } + FmsTrigger::ParkingBreakSwitchChanged(is_engaged) => { + info!("parking brake engaged: {}", is_engaged); + } + FmsTrigger::TellTale(info) => { + info!( + "tell tale {} has changed to status {}]", + info.tell_tale, info.status + ); + } + FmsTrigger::Timer => { + info!("timer has fired"); + } + } + new_vehicle_status.trigger = MessageField::some(trigger); + match status_publisher.send(new_vehicle_status).await { + Ok(_) => {} + Err(e) => { + warn!("failed to send new vehicle status via channel: {}", e); + } + }; + } + } + } + }); + + let timer_sender = tx.clone(); + tokio::task::spawn(async move { + loop { + tokio::time::sleep(timer_interval).await; + let _ = timer_sender.send(FmsTrigger::Timer).await; + } + }); + Ok(()) +} diff --git a/components/fms-forwarder/src/vehicle_abstraction/kuksa.rs b/components/fms-forwarder/src/vehicle_abstraction/kuksa.rs new file mode 100644 index 0000000..a05d328 --- /dev/null +++ b/components/fms-forwarder/src/vehicle_abstraction/kuksa.rs @@ -0,0 +1,404 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +tonic::include_proto!("kuksa.val.v1"); + +use log::debug; +use protobuf::{MessageField, well_known_types::timestamp::Timestamp}; + +use std::collections::HashMap; + +use self::datapoint::Value; +use fms_proto::fms::VehicleStatus; +use crate::vehicle_abstraction::vss; + +#[derive(Debug)] +pub struct UnsupportedValueTypeError{} + +impl TryFrom for u32 { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(v), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(Some(v)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for u64 { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(v as u64), + Value::Uint64(v) => Ok(v), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(Some(v as u64)), + Value::Uint64(v) => Ok(Some(v)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for i32 { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(v as i32), + Value::Int32(v) => Ok(v), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(Some(v as i32)), + Value::Int32(v) => Ok(Some(v)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for i64 { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(v as i64), + Value::Uint64(v) => Ok(v as i64), + Value::Int32(v) => Ok(v as i64), + Value::Int64(v) => Ok(v), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(Some(v as i64)), + Value::Uint64(v) => Ok(Some(v as i64)), + Value::Int32(v) => Ok(Some(v as i64)), + Value::Int64(v) => Ok(Some(v)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for f32 { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(v as f32), + Value::Int32(v) => Ok(v as f32), + Value::Float(v) => Ok(v), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(Some(v as f32)), + Value::Int32(v) => Ok(Some(v as f32)), + Value::Float(v) => Ok(Some(v)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for f64 { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(v as f64), + Value::Uint64(v) => Ok(v as f64), + Value::Int32(v) => Ok(v as f64), + Value::Int64(v) => Ok(v as f64), + Value::Double(v) => Ok(v), + Value::Float(v) => Ok(v as f64), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Uint32(v) => Ok(Some(v as f64)), + Value::Uint64(v) => Ok(Some(v as f64)), + Value::Int32(v) => Ok(Some(v as f64)), + Value::Int64(v) => Ok(Some(v as f64)), + Value::Double(v) => Ok(Some(v as f64)), + Value::Float(v) => Ok(Some(v as f64)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for String { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::String(v) => Ok(v), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::String(v) => Ok(Some(v)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for bool { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Bool(v) => Ok(v), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +impl TryFrom for Option { + type Error = UnsupportedValueTypeError; + fn try_from(value: Value) -> Result { + match value { + Value::Bool(v) => Ok(Some(v)), + _ => Err(UnsupportedValueTypeError{}), + } + } +} + +pub fn new_vehicle_status(data: HashMap, default_vin: &String) -> VehicleStatus { + let mut vehicle_status = VehicleStatus::new(); + vehicle_status.created = MessageField::some(Timestamp::now()); + + vehicle_status.vin = data + .get(vss::VSS_VEHICLE_VEHICLEIDENTIFICATION_VIN) + .map_or(default_vin.to_owned(), |value| { + value.clone().try_into().unwrap() + }); + + if let Some(value) = data.get(vss::VSS_VEHICLE_CHASSIS_PARKINGBRAKE_ISENGAGED) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .parking_brake_engaged = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::VSS_VEHICLE_CURRENTLOCATION_LATITUDE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .gnss_position + .mut_or_insert_default() + .latitude = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::VSS_VEHICLE_CURRENTLOCATION_LONGITUDE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .gnss_position + .mut_or_insert_default() + .longitude = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::VSS_VEHICLE_CURRENTLOCATION_ALTITUDE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .gnss_position + .mut_or_insert_default() + .altitude = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::VSS_VEHICLE_CURRENTLOCATION_HEADING) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .gnss_position + .mut_or_insert_default() + .heading = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::FMS_VEHICLE_CURRENTLOCATION_SPEED) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .gnss_position + .mut_or_insert_default() + .speed = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::VSS_VEHICLE_CURRENTLOCATION_TIMESTAMP) { + // this will succeed because we know that the Databroker will only accept a String as + // this VSS Data Entry's value + let iso_date_time: String = value.clone().try_into().unwrap(); + match chrono::DateTime::parse_from_rfc3339(&iso_date_time) { + Ok(instant) => { + let position_instant = vehicle_status + .snapshot_data + .mut_or_insert_default() + .gnss_position + .mut_or_insert_default() + .instant + .mut_or_insert_default(); + position_instant.seconds = instant.timestamp(); + position_instant.nanos = instant.timestamp_subsec_nanos() as i32; + } + Err(_e) => debug!("failed to parse value as ISO8601 date-time string"), + } + } + + if let Some(value) = data.get(vss::VSS_VEHICLE_CURRENTOVERALLWEIGHT) { + vehicle_status.gross_combination_vehicle_weight = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::VSS_VEHICLE_EXTERIOR_AIRTEMPERATURE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .ambient_air_temperature = value.clone().try_into().unwrap(); + } + + if let Some(value) = + data.get(vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_DIESELEXHAUSTFLUID_LEVEL) + { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .catalyst_fuel_level = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_ENGINEHOURS) { + vehicle_status.total_engine_hours = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_SPEED) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .engine_speed = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::FMS_VEHICLE_POWERTRAIN_CURRENTFUELTYPE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .fuel_type = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_ACCUMULATEDCONSUMPTION) { + vehicle_status.engine_total_fuel_used = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::VSS_VEHICLE_POWERTRAIN_RANGE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .estimated_distance_to_empty + .mut_or_insert_default() + .total = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::VSS_VEHICLE_POWERTRAIN_FUELSYSTEM_RANGE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .estimated_distance_to_empty + .mut_or_insert_default() + .fuel = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_TANK_FIRST_LEVEL) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .fuel_level1 = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_TANK_SECOND_LEVEL) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .fuel_level2 = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::VSS_VEHICLE_SPEED) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .wheel_based_speed = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_IDENTIFICATION) { + vehicle_status + .driver1_id + .mut_or_insert_default() + .tacho_driver_identification + .mut_or_insert_default() + .driver_identification = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::FMS_VEHICLE_TACHOGRAPH_DRIVER1_WORKINGSTATE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .driver1_working_state = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::FMS_VEHICLE_TACHOGRAPH_DRIVER2_WORKINGSTATE) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .driver2_working_state = value.clone().try_into().unwrap(); + } + if let Some(value) = data.get(vss::FMS_VEHICLE_TACHOGRAPH_VEHICLESPEED) { + vehicle_status + .snapshot_data + .mut_or_insert_default() + .tachograph_speed = value.clone().try_into().unwrap(); + } + + if let Some(value) = data.get(vss::FMS_VEHICLE_TRAVELED_DISTANCE_HIGH_RES) { + vehicle_status.hr_total_vehicle_distance = value.clone().try_into().unwrap(); + } + vehicle_status +} diff --git a/components/fms-forwarder/src/vehicle_abstraction/vss.rs b/components/fms-forwarder/src/vehicle_abstraction/vss.rs new file mode 100644 index 0000000..9adad88 --- /dev/null +++ b/components/fms-forwarder/src/vehicle_abstraction/vss.rs @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +pub const FMS_VEHICLE_CABIN_TELLTALE_ECT_STATUS: &str = + "Vehicle.Cabin.Telltale.ECT.Status"; +pub const FMS_VEHICLE_CABIN_TELLTALE_ENGINE_STATUS: &str = + "Vehicle.Cabin.Telltale.Engine.Status"; +pub const FMS_VEHICLE_CABIN_TELLTALE_ENGINEOIL_STATUS: &str = + "Vehicle.Cabin.Telltale.EngineOil.Status"; +pub const FMS_VEHICLE_CABIN_TELLTALE_FUELLEVEL_STATUS: &str = + "Vehicle.Cabin.Telltale.FuelLevel.Status"; +pub const FMS_VEHICLE_CABIN_TELLTALE_PARKINGBRAKE_STATUS: &str = + "Vehicle.Cabin.Telltale.ParkingBrake.Status"; +pub const VSS_VEHICLE_CURRENTOVERALLWEIGHT: &str = "Vehicle.CurrentOverallWeight"; +pub const VSS_VEHICLE_CHASSIS_PARKINGBRAKE_ISENGAGED: &str = "Vehicle.Chassis.ParkingBrake.IsEngaged"; +pub const VSS_VEHICLE_CURRENTLOCATION_LATITUDE: &str = "Vehicle.CurrentLocation.Latitude"; +pub const VSS_VEHICLE_CURRENTLOCATION_LONGITUDE: &str = "Vehicle.CurrentLocation.Longitude"; +pub const VSS_VEHICLE_CURRENTLOCATION_ALTITUDE: &str = "Vehicle.CurrentLocation.Altitude"; +pub const VSS_VEHICLE_CURRENTLOCATION_HEADING: &str = "Vehicle.CurrentLocation.Heading"; +pub const FMS_VEHICLE_CURRENTLOCATION_SPEED: &str = "Vehicle.CurrentLocation.Speed"; +pub const VSS_VEHICLE_CURRENTLOCATION_TIMESTAMP: &str = "Vehicle.CurrentLocation.Timestamp"; +pub const VSS_VEHICLE_EXTERIOR_AIRTEMPERATURE: &str = "Vehicle.Exterior.AirTemperature"; +pub const VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_DIESELEXHAUSTFLUID_LEVEL: &str = + "Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Level"; +pub const VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_ENGINEHOURS: &str = + "Vehicle.Powertrain.CombustionEngine.EngineHours"; +pub const VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_ISRUNNING: &str = + "Vehicle.Powertrain.CombustionEngine.IsRunning"; +pub const VSS_VEHICLE_POWERTRAIN_COMBUSTIONENGINE_SPEED: &str = + "Vehicle.Powertrain.CombustionEngine.Speed"; +pub const FMS_VEHICLE_POWERTRAIN_CURRENTFUELTYPE: &str = "Vehicle.Powertrain.CurrentFuelType"; +pub const FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_ACCUMULATEDCONSUMPTION: &str = + "Vehicle.Powertrain.FuelSystem.AccumulatedConsumption"; +pub const VSS_VEHICLE_POWERTRAIN_FUELSYSTEM_RANGE: &str = "Vehicle.Powertrain.FuelSystem.Range"; +pub const FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_TANK_FIRST_LEVEL: &str = + "Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel"; +pub const FMS_VEHICLE_POWERTRAIN_FUELSYSTEM_TANK_SECOND_LEVEL: &str = + "Vehicle.Powertrain.FuelSystem.Tank.Second.RelativeLevel"; +pub const VSS_VEHICLE_POWERTRAIN_RANGE: &str = "Vehicle.Powertrain.Range"; +pub const VSS_VEHICLE_SPEED: &str = "Vehicle.Speed"; +pub const FMS_VEHICLE_TACHOGRAPH_DRIVER1_CARDISSUINGMEMBERSTATE: &str = + "Vehicle.Tachograph.Driver.Driver1.CardIssuingMemberState"; +pub const FMS_VEHICLE_TACHOGRAPH_DRIVER1_IDENTIFICATION: &str = + "Vehicle.Tachograph.Driver.Driver1.Identification"; +pub const FMS_VEHICLE_TACHOGRAPH_DRIVER1_ISCARDPRESENT: &str = + "Vehicle.Tachograph.Driver.Driver1.IsCardPresent"; +pub const FMS_VEHICLE_TACHOGRAPH_DRIVER1_WORKINGSTATE: &str = + "Vehicle.Tachograph.Driver.Driver1.WorkingState"; +pub const FMS_VEHICLE_TACHOGRAPH_DRIVER2_ISCARDPRESENT: &str = + "Vehicle.Tachograph.Driver.Driver2.IsCardPresent"; +pub const FMS_VEHICLE_TACHOGRAPH_DRIVER2_WORKINGSTATE: &str = + "Vehicle.Tachograph.Driver.Driver2.WorkingState"; +pub const FMS_VEHICLE_TACHOGRAPH_VEHICLESPEED: &str = "Vehicle.Tachograph.VehicleSpeed"; +pub const FMS_VEHICLE_TRAVELED_DISTANCE_HIGH_RES: &str = "Vehicle.TraveledDistanceHighRes"; +pub const VSS_VEHICLE_VEHICLEIDENTIFICATION_VIN: &str = "Vehicle.VehicleIdentification.VIN"; diff --git a/components/fms-proto/Cargo.toml b/components/fms-proto/Cargo.toml new file mode 100644 index 0000000..adbb8a1 --- /dev/null +++ b/components/fms-proto/Cargo.toml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +[package] +name = "fms-proto" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +documentation.workspace = true +readme.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +protobuf = { workspace = true } + +[build-dependencies] +protobuf-codegen = { workspace = true } +protoc-bin-vendored = { workspace = true } diff --git a/components/fms-proto/README.md b/components/fms-proto/README.md new file mode 100644 index 0000000..4a9dbcf --- /dev/null +++ b/components/fms-proto/README.md @@ -0,0 +1,5 @@ +This package contains *protobuf* definitions and corresponding Rust code bindings for the types defined by the +[FMS specific VSS overlay](../../spec). + +The [FMS Forwarder](../fms-forwarder) and [FMS Server](../fms-server) components use these bindings to serialize +and deserialize FMS data being sent from a vehicle to the back end. diff --git a/components/fms-proto/build.rs b/components/fms-proto/build.rs new file mode 100644 index 0000000..88236f8 --- /dev/null +++ b/components/fms-proto/build.rs @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +fn main() -> Result<(), Box> { + + protobuf_codegen::Codegen::new() + .protoc() + // use vendored protoc instead of relying on user provided protobuf installation + .protoc_path(&protoc_bin_vendored::protoc_bin_path().unwrap()) + .include("proto") + .inputs(["proto/fms/v4/fms.proto"]) + .cargo_out_dir("fms") + .run_from_script(); + Ok(()) +} diff --git a/components/fms-proto/proto/fms/v4/fms.proto b/components/fms-proto/proto/fms/v4/fms.proto new file mode 100644 index 0000000..1e2076e --- /dev/null +++ b/components/fms-proto/proto/fms/v4/fms.proto @@ -0,0 +1,325 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +// This file contains message descriptions reflecting the data used by the FMS Standard v4.0 + +syntax = "proto3"; + +package fms.v4; + +import "google/protobuf/timestamp.proto"; + +message AccumulatedData { + // TBD +} + +// The status of an alternator. +message AlternatorInfo { + // The alternator's identifier. + uint32 id = 1; + string status = 2; +} + +message AxleLoad { + // Axle position from 1 to 15, 1 being in the front of the truck. + uint32 position = 1; + // The static vertical load of a vehicle axle in kilograms. + float load = 2; +} + +message ChargingStatusInfo { + // The event that caused the status to change: + // STARTED, COMPLETED, INTERRUPTED, COMPLETION_TIME_CHANGED, TIMER, CHARGIN_LEVEL, ERROR + string event = 1; + // Details regarding the event. Content is OEM specific. + string event_detail = 2; +} + +message ChargingConnectionStatusInfo { + // The event that caused the status to change: + // NOT_AVAILABLE, CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED, ERROR + string event = 1; + // Details regarding the event. Content is OEM specific. + string event_detail = 2; +} + +message DistanceToEmpty { + // Estimated distance to empty, summarizing fuel, gas and battery in meters. + optional uint64 total = 1; + // Estimated distance to empty, fuel tank, in meters. + optional uint64 fuel = 2; + // Estimated distance to empty, gas tank, in meters. + optional uint64 gas = 3; + // Estimated distance to empty, battery pack, in meters. + optional uint64 battery_pack = 4; +} + +// Status of a bus door. +message DoorStatus { + uint32 number = 1; + // allowed values: NOT_AVAILABLE, ENABLED, DISABLED, ERROR + string enabled_status = 2; + // allowed values: NOT_AVAILABLE, CLOSED, OPEN, ERROR + string open_status = 3; + // allowed values: NOT_AVAILABLE, UNLOCKED, LOCKED, ERROR + string lock_status = 4; +} + +message DriverId { + TachoDriverId tacho_driver_identification = 1; + OemDriverId oem_driver_identification = 2; +} + +message GnssPosition { + // Latitude (WGS84 based) + double latitude = 1; + // Longitude (WGS84 based) + double longitude = 2; + // The direction of the vehicle (0-359) + optional uint32 heading = 3; + // The altitude of the vehicle. Where 0 is sea level, negative + // values below sealevel and positive above sealevel. Unit in meters. + optional int32 altitude = 4; + // The GNSS(e.g. GPS)-speed in km/h. + optional double speed = 5; + // The time of the position data. + google.protobuf.Timestamp instant = 6; +} + +message OemDriverId { + // An OEM specific driver id. + optional string id = 1; + // An optional id type (e.g. pin, USB, encrypted EU id etc). + optional string type = 2; +} + +message SnapshotData { + GnssPosition gnss_position = 1; + // The vehicle wheelbased speed. + optional double wheel_based_speed = 2; + // The Tacho speed. + optional double tachograph_speed = 3; + // The engine (Diesel/gaseous) speed in rev/min. + optional double engine_speed = 4; + // The electric motor speed in rev/min. + optional double electric_motor_speed = 5; + // Type of fuel currently being utilized by the vehicle acc. j1939's SPN 5837. + optional string fuel_type = 6; + // The fuel level percentage. + optional double fuel_level1 = 7; + // Ratio of volume of fuel to the total volume of fuel storage container, in percent. + // When Fuel Level 2 is not used, Fuel Level 1 represents the total fuel in all fuel + // storage containers. When Fuel Level 2 is used, Fuel Level 1 represents the fuel + // level in the primary or left-side fuel storage container. + optional double fuel_level2 = 8; + // The adblue level percentage. + optional double catalyst_fuel_level = 9; + // Tachograph Working state of the first driver. + optional string driver1_working_state = 10; + // The identity of the second driver. + DriverId driver2_id = 11; + // Tachograph Working state of the second driver. + optional string driver2_working_state = 12; + // The Ambient air temperature in Celsius. + optional double ambient_air_temperature = 13; + // Switch signal which indicates when the parking brake is set. + // In general the switch actuated by the operator's park brake control, whether + // a pedal, lever or other control mechanism. + optional bool parking_brake_engaged = 14; + // Indicates the hybrid battery pack remaining charge. + // 0% means no charge remaining, + // 100% means full charge remaining. + // Is used as well for full electrical vehicles. + optional double hybrid_battery_pack_remaining_charge = 15; + // Indicates the charging status of the battery pack. Recuperation is excluded. + // NOT_AVAILABLE, NOT_CHARGING, CHARGING, CHARGING_AC, CHARGING_DC, ERROR + optional string battery_pack_charging_status = 16; + // Indicates the charging connection status of the battery pack. + // NOT_AVAILABLE, CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED, ERROR + optional string battery_pack_charging_connection_status = 17; + // Device used to charge the battery pack. Standard rFMS values + // taken from ISO 15118 (OEM can have additional values): + // ACD - Automatic Connection Device + // WPT - Wireless Power Transfer + // VEHICLE_COUPLER - manual connection of a flexible cable to an EV + // NONE - No device connected + // NOT_AVAILABLE - Unknown + optional string battery_pack_charging_device = 18; + // Charging power in watts. + optional double battery_pack_charging_power = 19; + // Estimated time when charging has reached the target level. + google.protobuf.Timestamp estimated_time_battery_pack_charging_completed = 20; + // Estimated distance to empty (tanks and/or battery packs) in meters. + DistanceToEmpty estimated_distance_to_empty = 21; + // The vehicle's axles and their current load. + repeated AxleLoad vehicle_axles = 22; + // List of trailers connected to the truck. + repeated Trailer trailers = 23; +} + +message TachoDriverId { + // The unique identification of a driver in a Member State. + // This field is formatted according the definition for driverIdentification + // in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + string driver_identification = 1; + // The country alpha code of the Member State having issued the card. + // This fieldd is formatted according the definition for NationAlpha + // in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + string card_issuing_memberState = 2; + // The type of equipment used to authenticate the driver. + optional string driver_authentication_equipment = 3; + // A card replacement index. This fields is formatted according the + // definition for CardReplacementIndex (chap 2.26) in: + // COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + optional string card_replacement_index = 4; + // A card renewal index. This fields is formatted according the + // definition for CardRenewalIndex (chap 2.25) in: + // COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + optional string card_renewal_index = 5; +} + +message TellTaleInfo { + string tell_tale = 1; + string status = 2; + // This is only set when tell_tale == OEM_SPECIFIC. + // This is an OEM specific string defining a tell tale in the OEM context. + optional string oem_tell_tale = 3; +} + +message Trailer { + // Trailer number from 1 to 5, 1 being closest to the truck, according to ISO 11992-2. + uint32 position = 1; + // The identification data sent by the trailer to the truck in the RGE23 message of ISO 11992-2. + // An alternative source is the DID (Data identifier definition) record VIN, as specified in + // ISO 11992-4. Even though both ISO 11992-2 and ISO 11992-4 specifies this as a VIN, the + // actual data sent from a trailer is not always the true VIN of the trailer. + string identification_data = 2; + // The vehicle identification number of the trailer. + // See ISO 3779 (17 characters) If the trailerIdentificationData is reporting + // a true VIN, trailerVin will have the same value. If it is possible to map the + // identification_data to a true VIN using other sources, the value can be provided here. + string vin = 3; + // The customer's name for the trailer + string custom_name = 4; + string type = 5; + // The sum of the static vertical loads of the trailer axles in kilograms. + // The load is sent in the EBS22 message of ISO 11992-2. + uint64 axle_load_sum = 6; + // The trailer's axles and their current load. + repeated AxleLoad axles = 7; +} + +message Trigger { + // If the trigger is based on one of the events defined by rFMS then this property MUST be set to "RFMS" + // and the "type" property MUST be set to the corresponding trigger type. + // Otherwise, this property MUST be set to a value indicating the (OEM specific) context in which the + // event occurred. + // rFMS standard values are "VOLVO TRUCKS", "SCANIA", "DAIMLER", "IVECO", "DAF", "MAN", + // "RENAULT TRUCKS", "VDL", "VOLVO BUSES", "IVECO BUS", "IRISBUS" + string context = 1; + string type = 2; + // Additional TriggerInfo content for OEM specific triggers, e.g. TRAILER_ATTACHED_TRIGGER [id of trailer] + repeated string info_items = 3; + // The id of the driver. This is only set if the trigger type is one of + // DRIVER_LOGIN, DRIVER_LOGOUT, DRIVER_1_WORKING_STATE_CHANGED, DRIVER_2_WORKING_STATE_CHANGED + DriverId driver = 4; + // The id of a PTO. This is only set if the trigger type is PTO_ENABLED or PTO_DISABLED + optional string pto_id = 5; + // Additional information which can be provide if the trigger type is TELL_TALE + TellTaleInfo tell_tale_info = 6; + // Additional information which can be provided if the trigger type is BATTERY_PACK_CHARGING_STATUS_CHANGE. + ChargingStatusInfo charging_status_info = 7; + // Additional information which can be provided if the trigger type is BATTERY_PACK_CHARGING_CONNECTION_STATUS_CHANGE. + // allowed values: NOT_AVAILABLE, CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED, ERROR + optional string charging_connection_status_info = 8; +} + +message UptimeData { + // List of tell tales with the actual status for each tell tale. + repeated TellTaleInfo tell_tales = 1; + // The distance in meter to the next service. + optional uint64 service_distance = 2; + // The temperature of the engine's coolant liquid in Celsius. + optional double engine_coolant_temperature = 3; + // The temperature of the battery pack coolant in Celsius. + // HVESS: High Voltage Energy Storage System + optional double hvess_outlet_coolant_temperature = 4; + // The temperature of the battery pack in Celsius. + // HVESS: High Voltage Energy Storage System + optional double hvess_temperature = 5; + // The air pressure in circuit 1 in Pascal. + optional uint64 service_brake_air_pressure_circuit1 = 6; + // The air pressure in circuit 2 in Pascal. + optional uint64 service_brake_air_pressure_circuit2 = 7; + // The total amount of time (seconds) that at least one door has been opened in the bus. + // Used mainly for buses. + optional uint64 duration_at_least_one_door_open = 8; + // The alternator status of the up to 4 alternators. Used mainly for buses. + AlternatorInfo alternator_info = 9; + // The bellow pressure in the front axle left side in Pascal. Used mainly for buses. + optional uint64 bellow_pressure_front_axle_left = 10; + // The bellow pressure in the front axle right side in Pascal. Used mainly for buses. + optional uint64 bellow_pressure_front_axle_right = 11; + // The bellow pressure in the rear axle left side in Pascal. Used mainly for buses. + optional uint64 bellow_pressure_rear_axle_left = 12; + // The bellow pressure in the rear axle right side in Pascal. Used mainly for buses. + optional uint64 bellow_pressure_rear_axle_right = 13; +} + +message VehicleStatus { + string vin = 1; + Trigger trigger = 2; + google.protobuf.Timestamp created = 3; + // Accumulated distance travelled by the vehicle during its operation in meter. + optional uint64 hr_total_vehicle_distance = 4; + // The total hours of operation for the vehicle combustion engine. + // At least one of total_engine_hours or total_electric_motor_hours is mandatory. + optional double total_engine_hours = 5; + // The total hours the electric motor is ready for propulsion (i.e. crank mode). + // At least one of total_engine_hours or total_electric_motor_hours is mandatory. + optional double total_electric_motor_hours = 6; + // The identity of the first driver. + DriverId driver1_id = 7; + // The full vehicle weight in kg. + optional uint32 gross_combination_vehicle_weight = 8; + // The total amount of fuel the vehicle has used during its lifetime in MilliLitres. + // At least one of engine_total_fuel_used, total_fuel_used_gaseous + // or total_electric_energy_used is mandatory. + optional uint64 engine_total_fuel_used = 9; + // The total amount of fuel consumed in kg (trip drive fuel + trip PTO governor + // moving fuel + trip PTO governor non-moving fuel + trip idle fuel) over the + // life of the engine. + // At least one of engine_total_fuel_used, total_fuel_used_gaseous + // or total_electric_energy_used is mandatory. + optional uint64 total_fuel_used_gaseous = 10; + // The total amount of electric energy consumed by the vehicle, excluding when + // plugged in (vehicle coupler) for charging, (incl. motor, PTO, cooling, + // etc.) in watt hours. Recuperation is subtracted from the value. + // At least one of engine_total_fuel_used, total_fuel_used_gaseous + // or total_electric_energy_used is mandatory. + optional uint64 total_electric_energy_used = 11; + // Composite indication of all bus door statuses. Bus specific parameter. + // allowed values: NOT_AVAILABLE, ALL_DOORS_DISABLED, AT_LEAST_ONE_DOOR_ENABLED, ERROR + optional string status2_of_doors = 12; + // Individual status for each bus door. Bus specific parameter. + repeated DoorStatus door_status = 13; + AccumulatedData accumulated_data = 14; + SnapshotData snapshot_data = 15; + UptimeData uptime_data = 16; +} \ No newline at end of file diff --git a/components/fms-proto/src/lib.rs b/components/fms-proto/src/lib.rs new file mode 100644 index 0000000..8f26e3b --- /dev/null +++ b/components/fms-proto/src/lib.rs @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +include!(concat!(env!("OUT_DIR"), "/fms/mod.rs")); diff --git a/components/fms-server/Cargo.toml b/components/fms-server/Cargo.toml new file mode 100644 index 0000000..354450f --- /dev/null +++ b/components/fms-server/Cargo.toml @@ -0,0 +1,43 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +[package] +name = "fms-server" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +documentation.workspace = true +readme.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-trait = "0.1" +axum = "0.6" +chrono = { workspace = true, features = ["serde"] } +clap = { workspace = true, features = ["std", "env", "color", "help", "usage", "error-context", "suggestions"] } +const_format = { version = "0.2" } +env_logger = { workspace = true } +influx-client = { workspace = true } +influxrs = { workspace = true } +log = { workspace = true } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/components/fms-server/src/influx_reader.rs b/components/fms-server/src/influx_reader.rs new file mode 100644 index 0000000..55ef32f --- /dev/null +++ b/components/fms-server/src/influx_reader.rs @@ -0,0 +1,169 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use chrono::{DateTime, Utc}; +use clap::ArgMatches; +use const_format::formatcp; +use influx_client::connection::InfluxConnection; +use influxrs::InfluxError; + +use crate::models::{self, GnssPositionObject, TriggerObject, VehiclePositionObject}; + +const FILTER_FIELDS_POSITION: &'static str = formatcp!( + r#"filter(fn: (r) => contains(set: ["{}","{}","{}","{}","{}","{}","{}","{}", "{}"], value: r._field)"#, + influx_client::FIELD_CREATED_DATE_TIME, + influx_client::FIELD_LATITUDE, + influx_client::FIELD_LONGITUDE, + influx_client::FIELD_ALTITUDE, + influx_client::FIELD_HEADING, + influx_client::FIELD_SPEED, + influx_client::FIELD_POSITION_DATE_TIME, + influx_client::FIELD_TACHOGRAPH_SPEED, + influx_client::FIELD_WHEEL_BASED_SPEED, +); +const FILTER_MEASUREMENT_SNAPSHOT: &'static str = formatcp!( + r#"filter(fn: (r) => r._measurement == "{}")"#, + influx_client::MEASUREMENT_SNAPSHOT, +); +const FILTER_TAG_ANY_VIN: &'static str = formatcp!(r#"filter(fn: (r) => r["{}"] =~ /.*/)"#, influx_client::TAG_VIN); +const FILTER_TAG_ANY_TRIGGER: &'static str = formatcp!(r#"filter(fn: (r) => r["{}"] =~ /.*/)"#, influx_client::TAG_TRIGGER); + +fn unpack_value_i32(value: Option<&String>) -> Option { + value.and_then(|v| v.parse().map_or(None, Option::Some)) +} + +fn unpack_value_f64(value: Option<&String>) -> Option { + value.and_then(|v| v.parse().map_or(None, Option::Some)) +} + +fn unpack_time(value: Option<&String>) -> Option> { + value.and_then(|v| v.parse().map_or(None, Option::Some)) +} + +pub struct InfluxReader { + influx_con: InfluxConnection, +} + +impl InfluxReader { + + pub fn new(args: &ArgMatches) -> Result> { + InfluxConnection::new(&args).map(|con| InfluxReader { influx_con: con }) + } + + pub async fn get_vehicles(&self) -> Result, InfluxError> { + let read_query = influxrs::Query::new(format!( + r#" + import "influxdata/influxdb/schema" + schema.tagValues(bucket: "{}", tag: "{}") + "#, + self.influx_con.bucket, + influx_client::TAG_VIN, + )); + + self.influx_con.client.query(read_query).await.map(|vins| { + vins.into_iter() + .filter_map(|entry| { + entry + .get("_value") + .map(|vin| models::VehicleObject::new(vin.to_string())) + }) + .collect() + }) + } + + pub async fn get_vehicleposition( + &self, + start_time: i64, + stop_time: i64, + vin: Option<&String>, + trigger: Option<&String>, + latest_only: bool, + ) -> Result, InfluxError> { + // Build Query + let time_filter = format!("range(start: {}, stop: {})", start_time, stop_time); + let vin_filter = match vin { + Some(v) => format!(r#"filter(fn: (r) => r["{}"] == "{}""#, influx_client::TAG_VIN, v), + None => FILTER_TAG_ANY_VIN.to_string(), + }; + let trigger_filter = match trigger { + Some(t) => format!(r#"filter(fn: (r) => r["{}"] == "{}")"#, influx_client::TAG_TRIGGER, t), + None => FILTER_TAG_ANY_TRIGGER.to_string(), + }; + + let mut read_query = influxrs::Query::new(format!(r#"from(bucket: "{}")"#, self.influx_con.bucket)) + .then(time_filter) + .then(FILTER_MEASUREMENT_SNAPSHOT) + .then(vin_filter) + .then(trigger_filter) + .then(FILTER_FIELDS_POSITION); + if latest_only { + read_query = read_query.then("last()"); + } + read_query = read_query + .then(r#"pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")"#); + + self.influx_con.client.query(read_query).await.map(|measurements| { + measurements + .into_iter() + .filter_map(|entry| { + match ( + entry.get(influx_client::TAG_VIN), + entry.get(influx_client::TAG_TRIGGER), + unpack_time(entry.get(influx_client::FIELD_CREATED_DATE_TIME)), + ) { + (Some(vin), Some(trigger), Some(created_date_time)) => { + let gnss_position = match ( + unpack_time(entry.get(influx_client::FIELD_POSITION_DATE_TIME)), + unpack_value_f64(entry.get(influx_client::FIELD_LONGITUDE)), + unpack_value_f64(entry.get(influx_client::FIELD_LATITUDE)), + ) { + (Some(position_date_time), Some(longitude), Some(latitude)) => { + Some(GnssPositionObject { + latitude, + longitude, + heading: unpack_value_i32(entry.get(influx_client::FIELD_HEADING)), + altitude: unpack_value_i32(entry.get(influx_client::FIELD_ALTITUDE)), + speed: unpack_value_f64(entry.get(influx_client::FIELD_SPEED)), + position_date_time, + }) + } + _ => None, + }; + + // set vehicle positions from result + Some(VehiclePositionObject { + vin: vin.to_string(), + trigger_type: TriggerObject::new( + trigger.to_string(), + "RFMS".to_string(), + ), + created_date_time, + received_date_time: chrono::Utc::now(), + gnss_position, + wheel_based_speed: unpack_value_f64(entry.get(influx_client::FIELD_WHEEL_BASED_SPEED)), + tachograph_speed: unpack_value_f64(entry.get(influx_client::FIELD_TACHOGRAPH_SPEED)), + }) + } + _ => None, + } + }) + .collect() + }) + } +} diff --git a/components/fms-server/src/main.rs b/components/fms-server/src/main.rs new file mode 100644 index 0000000..d745518 --- /dev/null +++ b/components/fms-server/src/main.rs @@ -0,0 +1,137 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use axum::http::StatusCode; +use axum::{routing::get, Json, Router}; + +use axum::extract::{Query, State}; +use clap::Command; +use log::{error, info}; + +use serde_json; +use serde_json::json; +use std::collections::HashMap; +use std::process; +use std::str::FromStr; +use std::sync::Arc; + +use chrono::{DateTime, Utc}; + +use influx_reader::InfluxReader; + +mod influx_reader; +mod models; + +#[tokio::main] +async fn main() { + env_logger::init(); + + let mut parser = Command::new("rFMS server") + .about("Exposes data from an InfluxDB via an rFMS API endpoint."); + parser = influx_client::connection::add_command_line_args(parser); + let args = parser.get_matches(); + let influx_reader = InfluxReader::new(&args).map_or_else( + |e| { + error!("failed to create InfluxDB client: {e}"); + process::exit(1); + }, + Arc::new, + ); + info!("starting rFMS server"); + let app = Router::new() + .route("/", get(root)) + .route("/rfms/vehicleposition", get(get_vehicleposition)) + .route("/rfms/vehicles", get(get_vehicles)) + .with_state(influx_reader); + axum::Server::bind(&"0.0.0.0:8081".parse().unwrap()) + .serve(app.into_make_service()) + .await + .unwrap(); +} + +async fn root() -> &'static str { + "Welcome to the rFMS server. The following endpoints are implemented: '/rfms/vehicleposition and /rfms/vehicles'" +} + +async fn get_vehicleposition( + State(influx_server): State>, + Query(params): Query>, +) -> Result, StatusCode> { + let start_time = params.get("starttime").map_or(0, |text| { + DateTime::::from_str(text).map_or(0, |time| time.timestamp()) + }); + + let stop_time = params + .get("stoptime") + .map_or_else(|| Utc::now().timestamp(), |text| { + DateTime::::from_str(text).map_or_else(|_| Utc::now().timestamp(), |time| time.timestamp()) + }); + + let vin = params.get("vin"); + let trigger_filter = params.get("triggerFilter"); + let latest_only = params + .get("latestOnly") + .map_or(false, |text| text.parse().unwrap_or(false)); + + influx_server + .get_vehicleposition(start_time, stop_time, vin, trigger_filter, latest_only) + .await + .map(|positions| { + let result = json!(models::VehiclePositionResponseObject { + vehicle_position_response: + models::VehiclePositionResponseObjectVehiclePositionResponse { + vehicle_positions: Some(positions) + }, + more_data_available: false, + more_data_available_link: None, + request_server_date_time: chrono::Utc::now() + }); + + Json(result) + }) + .map_err(|e| { + error!("error retrieving vehicle positions: {e}"); + StatusCode::INTERNAL_SERVER_ERROR + }) +} + +async fn get_vehicles( + State(influx_server): State>, + Query(_params): Query>, +) -> Result, StatusCode> { + influx_server + .get_vehicles() + .await + .map(|vehicles| { + let response = models::VehicleResponseObjectVehicleResponse { + vehicles: Some(vehicles), + }; + + let result_object = json!(models::VehicleResponseObject { + vehicle_response: response, + more_data_available: false, + more_data_available_link: None, + }); + Json(result_object) + }) + .map_err(|e| { + error!("error retrieving vehicle status: {e}"); + StatusCode::INTERNAL_SERVER_ERROR + }) +} diff --git a/components/fms-server/src/models.rs b/components/fms-server/src/models.rs new file mode 100644 index 0000000..69fb050 --- /dev/null +++ b/components/fms-server/src/models.rs @@ -0,0 +1,518 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + + +use crate::models; + +use serde::Deserialize; +use serde::Serialize; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct VehiclePositionObject { + /// vehicle identification number. See ISO 3779 (17 characters) + #[serde(rename = "vin")] + pub vin: String, + + #[serde(rename = "triggerType")] + pub trigger_type: TriggerObject, + + /// When the data was retrieved in the vehicle in iso8601 format. + #[serde(rename = "createdDateTime")] + pub created_date_time: chrono::DateTime::, + + /// Reception at Server. To be used for handling of \"more data available\" in iso8601 format. + #[serde(rename = "receivedDateTime")] + pub received_date_time: chrono::DateTime::, + + #[serde(rename = "gnssPosition")] + #[serde(skip_serializing_if="Option::is_none")] + pub gnss_position: Option, + + /// Wheel-Based Vehicle Speed in km/h (Speed of the vehicle as calculated from wheel or tailshaft speed) + #[serde(rename = "wheelBasedSpeed")] + #[serde(skip_serializing_if="Option::is_none")] + pub wheel_based_speed: Option, + + /// Tachograph vehicle speed in km/h (Speed of the vehicle registered by the tachograph) + #[serde(rename = "tachographSpeed")] + #[serde(skip_serializing_if="Option::is_none")] + pub tachograph_speed: Option, + +} + +/// This description is placed here due to limitations of describing references in OpenAPI Property __driverId__: The driver id of driver. (independant whether it is driver or Co-driver) This is only set if the TriggerType = DRIVER_LOGIN, DRIVER_LOGOUT, DRIVER_1_WORKING_STATE_CHANGED or DRIVER_2_WORKING_STATE_CHANGED For DRIVER_LOGIN it is the id of the driver that logged in For DRIVER_LOGOUT it is the id of the driver that logged out For DRIVER_1_WORKING_STATE_CHANGED it is the id of driver 1 For DRIVER_2_WORKING_STATE_CHANGED it is the id of driver 2 Property __tellTaleInfo__: The tell tale(s) that triggered this message. This is only set if the TriggerType = TELL_TALE +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct TriggerObject { + /// Trigger types for Context=RFMS: TIMER - Data was sent due to a timer trigger. (Timer value set outside rFMS scope) IGNITION_ON - Data was sent due to an ignition on IGNITION_OFF - Data was sent due to an ignition off PTO_ENABLED - Data was sent due to that a PTO was enabled, will be sent for each PTO that gets enabled PTO_DISABLED - Data was sent due to that a PTO was disabled, will be sent for each PTO that gets disabled. DRIVER_LOGIN - Data was sent due to a successful driver login. DRIVER_LOGOUT - Data was sent due to a driver logout TELL_TALE - Data was sent due to that at least one tell tale changed state ENGINE_ON - Data was sent due to an engine on. For electric motor crank is on ENGINE_OFF - Data was sent due to an engine off. For electric motor crank is off DRIVER_1_WORKING_STATE_CHANGED - Data was sent due to that driver 1 changed working state DRIVER_2_WORKING_STATE_CHANGED - Data was sent due to that driver 2 changed working state DISTANCE_TRAVELLED - Data was sent due to that a set distance was travelled. (Distance set outside rFMS scope) FUEL_TYPE_CHANGE - Data was sent due to that the type of fuel currently being utilized by the vehicle changed PARKING_BRAKE_SWITCH_CHANGE - Data was sent due to that the parking brake state has changed BATTERY_PACK_CHARGING_STATUS_CHANGE - Data was sent due to a change in the battery pack charging status. BATTERY_PACK_CHARGING_CONNECTION_STATUS_CHANGE - Data was sent due to a change in the battery pack charging connection status. TRAILER_CONNECTED - One or several trailers were connected TRAILER_DISCONNECTED - One or several trailers were disconnected + #[serde(rename = "triggerType")] + pub trigger_type: String, + + /// The context defines if this is part of the standard or OEM specific. rFMS standard values VOLVO TRUCKS, SCANIA, DAIMLER, IVECO, DAF, MAN, RENAULT TRUCKS, VDL, VOLVO BUSES, IVECO BUS, IRISBUS If the Trigger is defined in the rFMS standard, the Context = RFMS + #[serde(rename = "context")] + pub context: String, + + /// Additional TriggerInfo content for OEM specific triggers E.g. TRAILER_ATTACHED_TRIGGER [id of trailer] + #[serde(rename = "triggerInfo")] + #[serde(skip_serializing_if="Option::is_none")] + pub trigger_info: Option>, + + #[serde(rename = "driverId")] + #[serde(skip_serializing_if="Option::is_none")] + pub driver_id: Option, + + /// The id of a PTO. This is only set if the TriggerType = PTO_ENABLED or PTO_DISABLED + #[serde(rename = "ptoId")] + #[serde(skip_serializing_if="Option::is_none")] + pub pto_id: Option, + + #[serde(rename = "tellTaleInfo")] + #[serde(skip_serializing_if="Option::is_none")] + pub tell_tale_info: Option, + + #[serde(rename = "chargingStatusInfo")] + #[serde(skip_serializing_if="Option::is_none")] + pub charging_status_info: Option, + + #[serde(rename = "chargingConnectionStatusInfo")] + #[serde(skip_serializing_if="Option::is_none")] + pub charging_connection_status_info: Option, + +} + +impl TriggerObject { + #[allow(clippy::new_without_default)] + pub fn new(trigger_type: String, context: String, ) -> TriggerObject { + TriggerObject { + trigger_type, + context, + trigger_info: None, + driver_id: None, + pto_id: None, + tell_tale_info: None, + charging_status_info: None, + charging_connection_status_info: None, + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct GnssPositionObject { + /// Latitude (WGS84 based) + #[serde(rename = "latitude")] + pub latitude: f64, + + /// Longitude (WGS84 based) + #[serde(rename = "longitude")] + pub longitude: f64, + + /// The direction of the vehicle (0-359) + #[serde(rename = "heading")] + #[serde(skip_serializing_if="Option::is_none")] + pub heading: Option, + + /// The altitude of the vehicle. Where 0 is sea level, negative values below sealevel and positive above sealevel. Unit in meters. + #[serde(rename = "altitude")] + #[serde(skip_serializing_if="Option::is_none")] + pub altitude: Option, + + /// The GNSS(e.g. GPS)-speed in km/h + #[serde(rename = "speed")] + #[serde(skip_serializing_if="Option::is_none")] + pub speed: Option, + + /// The time of the position data in iso8601 format. + #[serde(rename = "positionDateTime")] + pub position_date_time: chrono::DateTime::, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct DriverIdObject { + #[serde(rename = "tachoDriverIdentification")] + #[serde(skip_serializing_if="Option::is_none")] + pub tacho_driver_identification: Option, + + #[serde(rename = "oemDriverIdentification")] + #[serde(skip_serializing_if="Option::is_none")] + pub oem_driver_identification: Option, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct TellTaleObject { + // Note: inline enums are not fully supported by openapi-generator + #[serde(rename = "tellTale")] + pub tell_tale: String, + + /// The OemTellTale is only set when the TellTale == OEM_SPECIFIC_TELL_TALE. This is an OEM specific string defining a tell tale in the OEM context. + #[serde(rename = "oemTellTale")] + #[serde(skip_serializing_if="Option::is_none")] + pub oem_tell_tale: Option, + + /// The current state of the tell tale. + // Note: inline enums are not fully supported by openapi-generator + #[serde(rename = "state")] + pub state: String, + +} + +/// Additional information can be provided if the trigger type is BATTERY_PACK_CHARGING_STATUS_CHANGE. +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct TriggerObjectChargingStatusInfo { + /// CHARGING_STARTED - Charging has started CHARGING_COMPLETED - Charging is completed CHARGING_INTERRUPTED - Charging has been interrupted (no error) ERROR - An error occurred when charging ESTIMATED_COMPLETION_TIME_CHANGED - The estimated time for completed charging has changed. (Threshold is outside scope of rFMS) TIMER - A predefined time has passed since last charge status update. (Frequency is outside the scope of rFMS) CHARGING_LEVEL - The charging level has reached a predefined level. (Charging levels are outside the scope of rFMS) + // Note: inline enums are not fully supported by openapi-generator + #[serde(rename = "event")] + #[serde(skip_serializing_if="Option::is_none")] + pub event: Option, + + /// Details regarding the event. Content is OEM specific + #[serde(rename = "eventDetail")] + #[serde(skip_serializing_if="Option::is_none")] + pub event_detail: Option, + +} + +/// Additional information can be provided if the trigger type is BATTERY_PACK_CHARGING_CONNECTION_STATUS_CHANGE. +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct TriggerObjectChargingConnectionStatusInfo { + /// CONNECTING - Vehicle is being connected to a charger CONNECTED - Vehicle is connected to a charger DISCONNECTING - Vehicle is being disconnected from the charger DISCONNECTED - Vehicle is not connected to a charger ERROR - An error occurred + // Note: inline enums are not fully supported by openapi-generator + #[serde(rename = "event")] + #[serde(skip_serializing_if="Option::is_none")] + pub event: Option, + + /// Details regarding the event. Content is OEM specific + #[serde(rename = "eventDetail")] + #[serde(skip_serializing_if="Option::is_none")] + pub event_detail: Option, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct DriverIdObjectTachoDriverIdentification { + /// The unique identification of a driver in a Member State. This fields is formatted according the definition for driverIdentification in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + #[serde(rename = "driverIdentification")] + pub driver_identification: String, + + /// The country alpha code of the Member State having issued the card. This fields is formatted according the definition for NationAlpha in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + #[serde(rename = "cardIssuingMemberState")] + pub card_issuing_member_state: String, + + /// Code to distinguish different types of equipment for the tachograph application. See description of the field 'DriverAuthenticationEquipment' in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + // Note: inline enums are not fully supported by openapi-generator + #[serde(rename = "driverAuthenticationEquipment")] + #[serde(skip_serializing_if="Option::is_none")] + pub driver_authentication_equipment: Option, + + /// A card replacement index. This fields is formatted according the definition for CardReplacementIndex (chap 2.26) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + #[serde(rename = "cardReplacementIndex")] + #[serde(skip_serializing_if="Option::is_none")] + pub card_replacement_index: Option, + + /// A card renewal index. This fields is formatted according the definition for CardRenewalIndex (chap 2.25) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b + #[serde(rename = "cardRenewalIndex")] + #[serde(skip_serializing_if="Option::is_none")] + pub card_renewal_index: Option, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct DriverIdObjectOemDriverIdentification { + /// Contains an optional id type (e.g. pin, USB, encrypted EU id...) + #[serde(rename = "idType")] + #[serde(skip_serializing_if="Option::is_none")] + pub id_type: Option, + + /// An OEM specific driver id. + #[serde(rename = "oemDriverIdentification")] + #[serde(skip_serializing_if="Option::is_none")] + pub oem_driver_identification: Option, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct VehiclePositionResponseObject { + #[serde(rename = "vehiclePositionResponse")] + pub vehicle_position_response: models::VehiclePositionResponseObjectVehiclePositionResponse, + + /// This will be set to true if the result set was too large to be sent back in one reply. A new request must be sent to get the rest of the vehicle positions, where the starttime parameter must be supplied. The starttime should be set to the latest ReceivedDateTime + 1 second of the last vehicle in the result set of this message. + #[serde(rename = "moreDataAvailable")] + pub more_data_available: bool, + + /// Populated with the link to the next part of the result when moreDataAvailable is true. The link is relative, i.e. starts with /rfms/vehiclepositions, and preserves any query parameters from the original request. + #[serde(rename = "moreDataAvailableLink")] + #[serde(skip_serializing_if="Option::is_none")] + pub more_data_available_link: Option, + + /// Time to be used to ask for historical data at customers (for starttime), to solve the problem of having different times at server and clients. This is the time at the server when this request was received. To avoid losing any messages or get duplicates, this is the time that should be supplied in the startTime parameter in the next request in iso8601 format. + #[serde(rename = "requestServerDateTime")] + pub request_server_date_time: chrono::DateTime::, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct VehiclePositionResponseObjectVehiclePositionResponse { + #[serde(rename = "vehiclePositions")] + #[serde(skip_serializing_if="Option::is_none")] + pub vehicle_positions: Option>, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct VehicleResponseObject { + #[serde(rename = "vehicleResponse")] + pub vehicle_response: models::VehicleResponseObjectVehicleResponse, + + /// This will be set to true if the result set was too large to be sent back in one reply. A new request must be sent to get the rest of the vehicles, where the lastVin parameter must be supplied. The lastVin should be set to the VIN of the last vehicle in the result set of this message. + #[serde(rename = "moreDataAvailable")] + pub more_data_available: bool, + + /// Populated with the link to the next part of the result when moreDataAvailable is true. The link is relative, i.e. starts with /rfms/vehicles, and preserves any query parameters from the original request. + #[serde(rename = "moreDataAvailableLink")] + #[serde(skip_serializing_if="Option::is_none")] + pub more_data_available_link: Option, + +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum VehiclesGetResponse { + /// OK + OK + (models::VehicleResponseObject) + , + /// The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing) Possible reason: Mandatory field missing, e.g. Authentication Header empty or missing The comments for the 4xx codes are from the Wikipedia article [List of HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors), which is released under the [Creative Commons Attribution-Share-Alike License 3.0](https://creativecommons.org/licenses/by-sa/3.0/). View authors on this [page](https://en.wikipedia.org/w/index.php?title=List_of_HTTP_status_codes&action=history). + TheServerCannotOrWillNotProcessTheRequestDueToAnApparentClientError + (models::ErrorObject) + , + /// Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource. See Basic access authentication and Digest access authentication. Possible reasons: Wrong credentials, Login credentials expired and/or Access token not valid or expired The comments for the 4xx codes are from the Wikipedia article [List of HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors), which is released under the [Creative Commons Attribution-Share-Alike License 3.0](https://creativecommons.org/licenses/by-sa/3.0/). View authors on this [page](https://en.wikipedia.org/w/index.php?title=List_of_HTTP_status_codes&action=history). + SimilarTo + (models::ErrorObject) + , + /// The request was a valid request, but the server is refusing to respond to it. Unlike a 401 Unauthorized response, authenticating will make no difference. On servers where authentication is required, this commonly means that the provided credentials were successfully authenticated but that the credentials still do not grant the client permission to access the resource (e.g. a recognized user attempting to access restricted content) Possible reason: Insufficient rights for the service, no rights on any service of this vehicle and/or Response is too large The comments for the 4xx codes are from the Wikipedia article [List of HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors), which is released under the [Creative Commons Attribution-Share-Alike License 3.0](https://creativecommons.org/licenses/by-sa/3.0/). View authors on this [page](https://en.wikipedia.org/w/index.php?title=List_of_HTTP_status_codes&action=history). + TheRequestWasAValidRequest + (models::ErrorObject) + , + /// The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible Possible reason: vehicle unknown and/or rFMS-Version not supported The comments for the 4xx codes are from the Wikipedia article [List of HTTP status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors), which is released under the [Creative Commons Attribution-Share-Alike License 3.0](https://creativecommons.org/licenses/by-sa/3.0/). View authors on this [page](https://en.wikipedia.org/w/index.php?title=List_of_HTTP_status_codes&action=history). + TheRequestedResourceCouldNotBeFoundButMayBeAvailableAgainInTheFuture + (models::ErrorObject) + , + /// Possible reason: unsupported Accept parameter sent + PossibleReason + (models::ErrorObject) + , + /// The user has sent too many requests in a given amount of time. Intended for use with rate limiting schemes Possible reason Request sent too often and/or Max concurrent calls + TheUserHasSentTooManyRequestsInAGivenAmountOfTime + (models::ErrorObject) +} + + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct VehicleResponseObjectVehicleResponse { + #[serde(rename = "vehicles")] + #[serde(skip_serializing_if="Option::is_none")] + pub vehicles: Option>, + +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct VehicleObject { + /// vehicle identification number. See ISO 3779 (17 characters) + #[serde(rename = "vin")] + pub vin: String, + + /// The customer's name for the vehicle. + #[serde(rename = "customerVehicleName")] + #[serde(skip_serializing_if="Option::is_none")] + pub customer_vehicle_name: Option, + + /// The vehicle brand. rFMS standard values VOLVO TRUCKS, SCANIA, DAIMLER, IVECO, DAF, MAN, RENAULT TRUCKS, VDL, VOLVO BUSES, IVECO BUS, IRISBUS + #[serde(rename = "brand")] + #[serde(skip_serializing_if="Option::is_none")] + pub brand: Option, + + #[serde(rename = "productionDate")] + #[serde(skip_serializing_if="Option::is_none")] + pub production_date: Option, + + /// Indicates the type of vehicle. rFMS standard values TRUCK, BUS, VAN + #[serde(rename = "type")] + #[serde(skip_serializing_if="Option::is_none")] + pub r#type: Option, + + /// Indicates the model of the vehicle. OEM specific value. + #[serde(rename = "model")] + #[serde(skip_serializing_if="Option::is_none")] + pub model: Option, + + /// The possible fuel types supported by this vehicle, formatted as the HEX id number according to SPN 5837. This does NOT indicate which fuel type that is presently being used. + #[serde(rename = "possibleFuelType")] + #[serde(skip_serializing_if="Option::is_none")] + pub possible_fuel_type: Option>, + + /// The emission level this vehicle supports. Possible values: European Union, Heavy-Duty Truck and Bus Engines: EURO_III, EURO_III_EEV, EURO_IV, EURO_V, EURO_VI European Union, Nonroad Engines: EURO_STAGE_III, EURO_STAGE_IV, EURO_STAGE_V United_States, Heavy-Duty Truck and Bus Engines: EPA_2004, EPA_2007, EPA_2010, EPA_2015_NOX10, EPA_2015_NOX05, EPA_2015_NOX02 United_States, Nonroad Engines: EPA_TIER_2, EPA_TIER_3, EPA_TIER_4_2008, EPA_TIER_4_2013 Brazil, Heavy-Duty Truck and Bus Engines: PROCONVE_P5, PROCONVE_P6, PROCONVE_P7 Brazil, Nonroad Engines: PROCONVE_MARI + #[serde(rename = "emissionLevel")] + #[serde(skip_serializing_if="Option::is_none")] + pub emission_level: Option, + + /// This parameter indicates how the tell tales shall be interpreted, the code is unique for each OEM. One OEM can have different interpretations depending on vehicle type. + #[serde(rename = "tellTaleCode")] + #[serde(skip_serializing_if="Option::is_none")] + pub tell_tale_code: Option, + + /// The chassis type of the vehicle. OEM specific value. This is used mainly for buses + #[serde(rename = "chassisType")] + #[serde(skip_serializing_if="Option::is_none")] + pub chassis_type: Option, + + /// Number of axles on the vehicle. This is used mainly for buses + #[serde(rename = "noOfAxles")] + #[serde(skip_serializing_if="Option::is_none")] + pub no_of_axles: Option, + + /// Total fuel tank volume for all tanks in milliltres. + #[serde(rename = "totalFuelTankVolume")] + #[serde(skip_serializing_if="Option::is_none")] + pub total_fuel_tank_volume: Option, + + /// Total gas tank capacity for all tanks in kilograms. + #[serde(rename = "totalFuelTankCapacityGaseous")] + #[serde(skip_serializing_if="Option::is_none")] + pub total_fuel_tank_capacity_gaseous: Option, + + /// Total battery pack capacity in watt hours. + #[serde(rename = "totalBatteryPackCapacity")] + #[serde(skip_serializing_if="Option::is_none")] + pub total_battery_pack_capacity: Option, + + /// The type of tachograph in the vehicle. rFMS standard values MTCO, DTCO, TSU, DTCO_G1, DTCO_G2, NONE DTCO - Digital tachograph, unknown generation DTCO_G1 - Digital tachograph generation 1 DTCO_G2 - Digital tachograph generation 2 NONE - No tachograph in the vehicle MTCO - Modular tachograph TSU - Tachograph simulator + #[serde(rename = "tachographType")] + #[serde(skip_serializing_if="Option::is_none")] + pub tachograph_type: Option, + + /// The type of gearbox the vehicle is equipped with. rFMS standard values MANUAL, AUTOMATIC, SEMI_AUTOMATIC, NO_GEAR (e.g electrical) + #[serde(rename = "gearboxType")] + #[serde(skip_serializing_if="Option::is_none")] + pub gearbox_type: Option, + + /// The type of body on the chassis. rFMS standard values CITY_BUS, INTERCITY_BUS, COACH. This is used mainly for buses. + #[serde(rename = "bodyType")] + #[serde(skip_serializing_if="Option::is_none")] + pub body_type: Option, + + /// The door configuration. The door order definition is OEM specific. E.g. [1, 2, 2] means the bus has 3 doors: 1 front door, double doors for door 2 and 3. This is used mainly for buses. + #[serde(rename = "doorConfiguration")] + #[serde(skip_serializing_if="Option::is_none")] + pub door_configuration: Option>, + + /// If the vehicle is equipped with a ramp or not. This is used mainly for buses. + #[serde(rename = "hasRampOrLift")] + #[serde(skip_serializing_if="Option::is_none")] + pub has_ramp_or_lift: Option, + + /// Paths that the client is authorized to call + #[serde(rename = "authorizedPaths")] + #[serde(skip_serializing_if="Option::is_none")] + pub authorized_paths: Option>, + +} + +impl VehicleObject { + pub fn new(vin : String) -> VehicleObject { + VehicleObject { + vin: vin, + customer_vehicle_name: None, + brand: None, + production_date: None, + r#type: None, + model: None, + possible_fuel_type: None, + emission_level: None, + tell_tale_code: None, + chassis_type: None, + no_of_axles: None, + total_fuel_tank_volume: None, + total_fuel_tank_capacity_gaseous: None, + total_battery_pack_capacity: None, + tachograph_type: None, + gearbox_type: None, + body_type: None, + door_configuration: None, + has_ramp_or_lift: None, + authorized_paths: None, + } + } +} + +/// Indicates when the vehicle was produced. +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct VehicleObjectProductionDate { + /// Day of the month where first day of the month is 1 + #[serde(rename = "day")] + #[serde(skip_serializing_if="Option::is_none")] + pub day: Option, + + /// Month of the year, where January is value 1 + #[serde(rename = "month")] + #[serde(skip_serializing_if="Option::is_none")] + pub month: Option, + + #[serde(rename = "year")] + #[serde(skip_serializing_if="Option::is_none")] + pub year: Option, + +} + +/// Optional responses for error codes, detailing the error if needed +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ErrorObject { + /// An identifier for this error + #[serde(rename = "error")] + #[serde(skip_serializing_if="Option::is_none")] + pub error: Option, + + /// A description of the error + #[serde(rename = "error_description")] + #[serde(skip_serializing_if="Option::is_none")] + pub error_description: Option, + + /// A URI providing more information + #[serde(rename = "error_uri")] + #[serde(skip_serializing_if="Option::is_none")] + pub error_uri: Option, + +} + + diff --git a/components/influx-client/Cargo.toml b/components/influx-client/Cargo.toml new file mode 100644 index 0000000..d458009 --- /dev/null +++ b/components/influx-client/Cargo.toml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +[package] +name = "influx-client" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +documentation.workspace = true +readme.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { workspace = true, features = ["std", "env", "color", "help", "usage", "error-context", "suggestions"]} +fms-proto = { workspace = true, optional = true } +protobuf = { workspace = true, optional = true } +influxrs = { workspace = true } +isahc = { version = "1.7", default-features = false, features = ["http2", "static-ssl", "static-curl", "text-decoding"] } +log = { workspace = true } + +[features] +default = ["writer"] +writer = ["dep:fms-proto", "dep:protobuf"] diff --git a/components/influx-client/src/connection.rs b/components/influx-client/src/connection.rs new file mode 100644 index 0000000..f9e1225 --- /dev/null +++ b/components/influx-client/src/connection.rs @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use clap::{ArgMatches, Arg, ArgGroup, Command}; +use influxrs::InfluxClient; +use log::{error, info}; + +const PARAM_INFLUXDB_BUCKET: &str = "influxdb-bucket"; +const PARAM_INFLUXDB_ORG: &str = "influxdb-org"; +const PARAM_INFLUXDB_URI: &str = "influxdb-uri"; +const PARAM_INFLUXDB_TOKEN: &str = "influxdb-token"; +const PARAM_INFLUXDB_TOKEN_FILE: &str = "influxdb-token-file"; + +/// Adds command line arguments to an existing command line which can be +/// used to configure the connection to an InfluxDB server. +/// +/// The following arguments are being added: +/// +/// | long name | environment variable | default value | +/// |---------------------|----------------------|---------------| +/// | influxdb-bucket | INFLUXDB_BUCKET | `demo` | +/// | influxdb-org | INFLUXDB_ORG | `sdv` | +/// | influxdb-uri | INFLUXDB_URI | - | +/// | influxdb-token | INFLUXDB_TOKEN | - | +/// | influxdb-token-file | INFLUXDB_TOKEN_FILE | - | +/// +pub fn add_command_line_args(command_line: Command) -> Command { + command_line + .arg( + Arg::new(PARAM_INFLUXDB_URI) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_INFLUXDB_URI) + .alias("ia") + .help("The HTTP(S) URI of the InfluxDB server to write data to.") + .value_name("URI") + .required(true) + .env("INFLUXDB_URI"), + ) + .group(ArgGroup::new("influxdb-auth-token").required(true)) + .arg( + Arg::new(PARAM_INFLUXDB_TOKEN) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_INFLUXDB_TOKEN) + .alias("token") + .help("The API token to use for authenticating to the InfluxDB server.") + .group("influxdb-auth-token") + .value_name("TOKEN") + .env("INFLUXDB_API_TOKEN"), + ) + .arg( + Arg::new(PARAM_INFLUXDB_TOKEN_FILE) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_INFLUXDB_TOKEN_FILE) + .alias("token-file") + .help("The path to a file that contains the API token to use for authenticating to the InfluxDB server.") + .group("influxdb-auth-token") + .value_name("FILE") + .conflicts_with("influxdb-token") + .env("INFLUXDB_API_TOKEN_FILE"), + ) + .arg( + Arg::new(PARAM_INFLUXDB_ORG) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_INFLUXDB_ORG) + .alias("org") + .help("The name of the organization to connect to on the InfluxDB server.") + .value_name("NAME") + .required(false) + .default_value("sdv") + .env("INFLUXDB_ORG"), + ) + .arg( + Arg::new(PARAM_INFLUXDB_BUCKET) + .value_parser(clap::builder::NonEmptyStringValueParser::new()) + .long(PARAM_INFLUXDB_BUCKET) + .alias("bucket") + .help("The name of the bucket to write data to on the InfluxDB server.") + .value_name("NAME") + .required(false) + .default_value("demo") + .env("INFLUXDB_BUCKET"), + ) +} + +fn read_token_from_file(filename: &str) -> std::io::Result { + info!("reading token from file {filename}"); + std::fs::read_to_string(filename) + .map(|s| s.trim().to_string()) + .map_err(|e| { + error!("failed to read token from file [{filename}]: {e}"); + e + }) +} + +/// A connection to an InfluxDB server. +pub struct InfluxConnection { + pub client: InfluxClient, + pub bucket: String, +} + +impl InfluxConnection { + /// Creates a new connection to an InfluxDB server. + /// + /// Determines the parameters necessary for creating the connection from values specified on + /// the command line or via environment variables as defined by [`add_command_line_args`]. + /// + /// # Examples + /// + /// ``` + /// use clap::{ArgMatches, Arg, ArgGroup, Command}; + /// use influx_client::connection::InfluxConnection; + /// + /// let mut command = influx_client::add_command_line_args(Command::new("influx_client")); + /// let matches = command.get_matches_from(vec![ + /// "influx_client", + /// "--influxdb-uri", "http://my-influx.io", + /// "--influxdb-token", "some-token", + /// "--influxdb-bucket", "the-bucket", + /// ]); + /// let connection = InfluxConnection::new(&matches)?; + /// assert_eq!(connection.bucket, "the-bucket".to_string()); + /// # Ok::<(), Box>(()) + /// ``` + pub fn new(args: &ArgMatches) -> Result> { + let influx_uri = args.get_one::(PARAM_INFLUXDB_URI).unwrap().to_owned(); + let influx_token = match args.get_one::(PARAM_INFLUXDB_TOKEN) { + Some(token) => token.to_string(), + None => { + let file_name = args.get_one::(PARAM_INFLUXDB_TOKEN_FILE).unwrap(); + match read_token_from_file(file_name) { + Ok(token) => token, + Err(e) => return Err(Box::new(e)), + } + } + }; + let influx_org = args.get_one::(PARAM_INFLUXDB_ORG).unwrap().to_owned(); + let influx_bucket = args + .get_one::(PARAM_INFLUXDB_BUCKET) + .unwrap() + .to_owned(); + let client = InfluxClient::builder(influx_uri, influx_token, influx_org) + .build() + .unwrap(); + Ok(InfluxConnection { + client, + bucket: influx_bucket, + }) + } +} diff --git a/components/influx-client/src/lib.rs b/components/influx-client/src/lib.rs new file mode 100644 index 0000000..96cc14c --- /dev/null +++ b/components/influx-client/src/lib.rs @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +//! A client for accessing an InfluxDB server. +//! +//! Supports connecting to an InfluxDB server based on parameters +//! read from the command line or from environment variables. + +pub const FIELD_ALTITUDE: &str = "altitude"; +pub const FIELD_AMBIENT_AIR_TEMP: &str = "ambientAirTemperature"; +pub const FIELD_CATALYST_FUEL_LEVEL: &str = "catalystFuelLevel"; +pub const FIELD_CREATED_DATE_TIME: &str = "createdDateTime"; +pub const FIELD_DRIVER1_ID: &str = "driver1Id"; +pub const FIELD_DRIVER1_CARD_ISSUER: &str = "driver1IdCardIssuer"; +pub const FIELD_DRIVER1_WORKING_STATE: &str = "driver1WorkingState"; +pub const FIELD_DRIVER2_ID: &str = "driver2Id"; +pub const FIELD_DRIVER2_CARD_ISSUER: &str = "driver2IdCardIssuer"; +pub const FIELD_DRIVER2_WORKING_STATE: &str = "driver2WorkingState"; +pub const FIELD_ENGINE_SPEED: &str = "engineSpeed"; +pub const FIELD_ENGINE_TOTAL_FUEL_USED: &str = "engineTotalFuelUsed"; +pub const FIELD_ESTIMATED_DIST_TO_EMPTY_FUEL: &str = "estimatedDistanceToEmptyFuel"; +pub const FIELD_ESTIMATED_DIST_TO_EMPTY_TOTAL: &str = "estimatedDistanceToEmptyTotal"; +pub const FIELD_FUEL_LEVEL1: &str = "fuelLevel1"; +pub const FIELD_FUEL_LEVEL2: &str = "fuelLevel2"; +pub const FIELD_FUEL_TYPE: &str = "fuelType"; +pub const FIELD_GROSS_COMBINATION_VEHICLE_WEIGHT: &str = "grossCombinationVehicleWeight"; +pub const FIELD_HEADING: &str = "heading"; +pub const FIELD_HR_TOTAL_VEHICLE_DISTANCE: &str = "hrTotalVehicleDistance"; +pub const FIELD_LATITUDE: &str = "latitude"; +pub const FIELD_LONGITUDE: &str = "longitude"; +pub const FIELD_PARKING_BREAK_SWITCH: &str = "parkingBrakeSwitch"; +pub const FIELD_POSITION_DATE_TIME: &str = "positionDateTime"; +pub const FIELD_SPEED: &str = "speed"; +pub const FIELD_TACHOGRAPH_SPEED: &str = "tachographSpeed"; +pub const FIELD_TOTAL_ELECTRIC_MOTOR_HOURS: &str = "totalElectricMotorHours"; +pub const FIELD_TOTAL_ENGINE_HOURS: &str = "totalEngineHours"; +pub const FIELD_WHEEL_BASED_SPEED: &str = "wheelBasedSpeed"; + +pub const MEASUREMENT_HEADER: &str = "header"; +pub const MEASUREMENT_SNAPSHOT: &str = "snapshot"; + +pub const TAG_TRIGGER: &str = "trigger"; +pub const TAG_VIN: &str = "vin"; + +pub mod connection; +#[cfg(feature = "writer")] +pub mod writer; + diff --git a/components/influx-client/src/writer.rs b/components/influx-client/src/writer.rs new file mode 100644 index 0000000..afc1ed6 --- /dev/null +++ b/components/influx-client/src/writer.rs @@ -0,0 +1,307 @@ +// SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +//! Provides means to write a Vehicle's current status properties +//! to an InfluxDB as Influx *measurements*. +use clap::ArgMatches; +use log::{debug, warn}; +use std::time::{SystemTime, UNIX_EPOCH}; +use protobuf::well_known_types::timestamp::Timestamp; +use fms_proto::fms::VehicleStatus; +use influxrs::Measurement; + +use crate::connection::InfluxConnection; + +fn build_header_measurement( + vin: &str, + trigger: &str, + created_date_time: u128, + vehicle_status: &VehicleStatus, +) -> Option { + let mut builder = Measurement::builder(crate::MEASUREMENT_HEADER) + .tag(crate::TAG_TRIGGER, trigger) + .tag(crate::TAG_VIN, vin) + .field(crate::FIELD_CREATED_DATE_TIME, created_date_time); + + if let Some(value) = vehicle_status.hr_total_vehicle_distance { + builder = builder.field(crate::FIELD_HR_TOTAL_VEHICLE_DISTANCE, value); + } + if let Some(value) = vehicle_status.gross_combination_vehicle_weight { + builder = builder.field(crate::FIELD_GROSS_COMBINATION_VEHICLE_WEIGHT, value); + } + if let Some(value) = vehicle_status.total_engine_hours { + builder = builder.field(crate::FIELD_TOTAL_ENGINE_HOURS, value); + } + if let Some(value) = vehicle_status.total_electric_motor_hours { + builder = builder.field(crate::FIELD_TOTAL_ELECTRIC_MOTOR_HOURS, value); + } + if let Some(value) = vehicle_status.engine_total_fuel_used { + builder = builder.field(crate::FIELD_ENGINE_TOTAL_FUEL_USED, value); + } + + if let Some(tacho_driver_id) = vehicle_status.driver1_id.clone().into_option() + .and_then(|driver_id| driver_id.tacho_driver_identification.into_option()) { + + builder = builder.field(crate::FIELD_DRIVER1_ID, tacho_driver_id.driver_identification); + builder = builder.field(crate::FIELD_DRIVER1_CARD_ISSUER, tacho_driver_id.card_issuing_memberState); + } + + match builder.build() { + Ok(measurement) => Some(measurement), + Err(e) => { + debug!("failed to create header Measurement: {e}"); + None + } + } +} + +fn build_snapshot_measurement( + vin: &str, + trigger: &str, + created_date_time: u128, + vehicle_status: &VehicleStatus, +) -> Option { + + let mut builder = Measurement::builder(crate::MEASUREMENT_SNAPSHOT) + .tag(crate::TAG_TRIGGER, trigger) + .tag(crate::TAG_VIN, vin) + .field(crate::FIELD_CREATED_DATE_TIME, created_date_time); + + if let Some(snapshot_data) = vehicle_status.snapshot_data.clone().into_option() { + if let Some(value) = snapshot_data.wheel_based_speed { + builder = builder.field(crate::FIELD_WHEEL_BASED_SPEED, value); + } + if let Some(value) = snapshot_data.tachograph_speed { + builder = builder.field(crate::FIELD_TACHOGRAPH_SPEED, value); + } + if let Some(value) = snapshot_data.fuel_type { + builder = builder.field(crate::FIELD_FUEL_TYPE, value); + } + if let Some(value) = snapshot_data.engine_speed { + builder = builder.field(crate::FIELD_ENGINE_SPEED, value); + } + if let Some(value) = snapshot_data.catalyst_fuel_level { + builder = builder.field(crate::FIELD_CATALYST_FUEL_LEVEL, value); + } + if let Some(value) = snapshot_data.fuel_level1 { + builder = builder.field(crate::FIELD_FUEL_LEVEL1, value); + } + if let Some(value) = snapshot_data.fuel_level2 { + builder = builder.field(crate::FIELD_FUEL_LEVEL2, value); + } + if let Some(value) = snapshot_data.driver1_working_state { + builder = builder.field(crate::FIELD_DRIVER1_WORKING_STATE, value); + } + if let Some(value) = snapshot_data.driver2_working_state { + builder = builder.field(crate::FIELD_DRIVER2_WORKING_STATE, value); + } + if let Some(value) = snapshot_data.ambient_air_temperature { + builder = builder.field(crate::FIELD_AMBIENT_AIR_TEMP, value); + } + if let Some(value) = snapshot_data.parking_brake_engaged { + builder = builder.field(crate::FIELD_PARKING_BREAK_SWITCH, value); + } + + if let Some(current_location) = snapshot_data.gnss_position.into_option() { + builder = builder + .field(crate::FIELD_LATITUDE, current_location.latitude) + .field(crate::FIELD_LONGITUDE, current_location.longitude); + + if let Some(value) = current_location.heading { + builder = builder.field(crate::FIELD_HEADING, value); + } + + if let Some(value) = current_location.altitude { + builder = builder.field(crate::FIELD_ALTITUDE, value); + } + + if let Some(value) = current_location.speed { + builder = builder.field(crate::FIELD_SPEED, value); + } + + if let Some(instant) = current_location.instant.clone().into_option() { + builder = builder.field(crate::FIELD_POSITION_DATE_TIME, instant.seconds); + } + } + + if let Some(distance_to_empty) = snapshot_data + .estimated_distance_to_empty + .into_option() + { + if let Some(value) = distance_to_empty.fuel { + builder = builder.field(crate::FIELD_ESTIMATED_DIST_TO_EMPTY_FUEL, value); + } + if let Some(value) = distance_to_empty.total { + builder = builder.field(crate::FIELD_ESTIMATED_DIST_TO_EMPTY_TOTAL, value); + } + } + + if let Some(tacho_driver_id) = snapshot_data.driver2_id.clone().into_option() + .and_then(|driver_id| driver_id.tacho_driver_identification.into_option()) { + builder = builder + .field(crate::FIELD_DRIVER2_ID, tacho_driver_id.driver_identification) + .field( + crate::FIELD_DRIVER2_CARD_ISSUER, + tacho_driver_id.card_issuing_memberState, + ); + } + } + + match builder.build() { + Ok(measurement) => Some(measurement), + Err(e) => { + debug!("failed to create snapshot Measurement: {e}"); + None + } + } +} + +/// A facade to an InfluxDB server for publishing Vehicle status information. +pub struct InfluxWriter { + influx_con: InfluxConnection, +} + +impl InfluxWriter { + + /// Creates a new writer. + /// + /// Determines the parameters necessary for creating the writer from values specified on + /// the command line or via environment variables as defined by [`super::add_command_line_args`]. + pub fn new(args: &ArgMatches) -> Result> { + InfluxConnection::new(args).map(|con| InfluxWriter { influx_con: con }) + } + + /// Writes Vehicle status information as measurements to the InfluxDB server. + /// + /// The measurements are being written to the *bucket* in the *organization* that have been + /// configured via command line arguments and/or environment variables passed in to [`self::InfluxWriter::new()`]. + /// + /// This function writes the current vehicle status to InfluxDB by means of two measurements: + /// + /// * *header* - contains the following tags/fields: + /// + /// | Type | Name | Description | + /// | ----- | --------------- | -------------------------------- | + /// | tag | trigger | The type of event that triggered the reporting of the vehicle status. | + /// | tag | vin | The vehicle's identification number. | + /// | field | createdDateTime | The instant of time (milliseconds since UNIX epoch) at which the vehicle status information had been created. | + /// | field | hrTotalVehicleDistance | The accumulated distance travelled by the vehicle during its operation in meter. | + /// | field | grossCombinationVehicleWeight | The full vehicle weight in kg. | + /// | field | totalEngineHours | The total hours of operation for the vehicle combustion engine. | + /// | field | totalElectricMotorHours | The total hours the electric motor is ready for propulsion (i.e. crank mode). | + /// | field | engineTotalFuelUsed | The total fuel the vehicle has used during its lifetime in MilliLitres. | + /// | field | driver1Id | The unique identification of driver one in a Member State. | + /// | field | driver1IdCardIssuer | The country alpha code of the Member State having issued driver one's card. | + /// + /// * *snapshot* - contains the following tags/fields: + /// + /// | Type | Name | Description | + /// | ----- | --------------- | -------------------------------- | + /// | tag | trigger | The type of event that triggered the reporting of the vehicle status. | + /// | tag | vin | The vehicle's identification number. | + /// | field | createdDateTime | The instant of time (milliseconds since UNIX epoch) at which the vehicle status information had been created. | + /// | field | latitude | Latitude (WGS84 based). | + /// | field | longitude | Longitude (WGS84 based). | + /// | field | heading | The direction of the vehicle (0-359). | + /// | field | altitude | The altitude of the vehicle. Where 0 is sea level, negative values below sealevel and positive above sealevel. Unit in meters. | + /// | field | speed | The GNSS(e.g. GPS)-speed in km/h. | + /// | field | positionDateTime | The time of the position data in ISO 8601 format. | + /// | field | wheelBasedSpeed | The vehicle's wheel based speed. | + /// | field | tachographSpeed | The Tacho speed. | + /// | field | engineSpeed | The engine (Diesel/gaseous) speed in rev/min. | + /// | field | fuelType | Type of fuel currently being utilized by the vehicle acc. SPN 5837. | + /// | field | catalystFuelLevel | The AdBlue level percentage. | + /// | field | fuelLevel1 | Ratio of volume of fuel to the total volume of fuel storage container, in percent. | + /// | field | fuelLevel2 | Ratio of volume of fuel to the total volume of fuel storage container, in percent. When Fuel Level 2 is not used, Fuel Level 1 represents the total fuel in all fuel storage containers. When Fuel Level 2 is used, Fuel Level 1 represents the fuel level in the primary or left-side fuel storage container. | + /// | field | estimatedDistanceToEmptyFuel | Estimated distance to empty, fuel tank, in meters. | + /// | field | estimatedDistanceToEmptyTotal | Estimated distance to empty, summarizing fuel, gas and battery in meters. | + /// | field | driver1WorkingState | Tachograph Working state of the driver one. | + /// | field | driver2Id | The unique identification of driver two in a Member State. | + /// | field | driver2IdCardIssuer | The country alpha code of the Member State having issued driver two's card. | + /// | field | driver2WorkingState | Tachograph Working state of the driver two. | + /// | field | ambientAirTemperature | The Ambient air temperature in Celsius. | + /// | field | parkingBrakeSwitch | Switch signal which indicates when the parking brake is set. | + /// + pub async fn write_vehicle_status(&self, vehicle_status: &VehicleStatus) { + if vehicle_status.vin.len() == 0 { + debug!("ignoring vehicle status without VIN ..."); + return; + } + let created_timestamp: u128 = match vehicle_status.created.clone().into_option() { + Some(ts) => match >::try_into(ts) { + Ok(sys_time) => sys_time.duration_since(UNIX_EPOCH).unwrap().as_millis(), + Err(e) => { + debug!("ignoring vehicle status with improper created timestamp: {e}"); + return; + }, + }, + None => { + debug!("ignoring vehicle status without created timestamp"); + return; + } + }; + let trigger = match vehicle_status.trigger.clone().into_option() { + Some(t) => match t.context.as_str() { + "RFMS" => t.type_.clone(), + _ => { + debug!("ignoring vehicle status with unsupported trigger context [{}]", t.context); + return; + }, + }, + None => { + debug!("ignoring vehicle status without trigger"); + return; + }, + }; + + let mut measurements: Vec = Vec::new(); + if let Some(measurement) = build_header_measurement( + vehicle_status.vin.as_str(), + &trigger, + created_timestamp, + &vehicle_status, + ) { + debug!("writing header measurement to influxdb"); + measurements.push(measurement); + } + if let Some(measurement) = build_snapshot_measurement( + vehicle_status.vin.as_str(), + &trigger, + created_timestamp, + &vehicle_status, + ) { + debug!("writing snapshot measurement to influxdb"); + measurements.push(measurement); + } + + if !measurements.is_empty() { + if let Err(e) = self + .influx_con + .client + .write( + self.influx_con.bucket.as_str(), + measurements[..].try_into().unwrap(), + ) + .await + { + warn!("failed to write data to influx: {e}"); + } + } + } +} diff --git a/csv-provider/README.md b/csv-provider/README.md new file mode 100644 index 0000000..118e43b --- /dev/null +++ b/csv-provider/README.md @@ -0,0 +1,32 @@ + +# Using the CSV-Provider + +With the CSV-provider one can replay signals from a CSV-file to an instance of the Kuksa.val data broker. More details are available in the [upstream repository](https://github.com/eclipse/kuksa.val.feeders/tree/main/csv_provider). To execute the CSV-provider with the Docker Compose setup, add the argument '--profile csv': + +``` +docker compose -f ./fms-demo-compose.yaml --profile direct --profile csv up --detach +``` + +## Recording +The file in `csv-provider/signalsFmsRecording.csv` is a CSV representation of the beginning of the CAN-trace in `dbc-feeder/220421_MAN_Si_RIO_CAN_converted.log`. The CSV-representation of the full VSS-recording of the CAN-trace is available in the archive `csv-providers/signalsFmsRecording.zip`. + +You can perform your own recording for other traces by using the [CSV recorder from the Kuksa.val.feeders repository](https://github.com/eclipse/kuksa.val.feeders/tree/main/csv_provider). The script in [run_recorderFMS.sh](run_recorderFMS.sh) contains the signals to record for this use case. \ No newline at end of file diff --git a/csv-provider/run_recorderFMS.sh b/csv-provider/run_recorderFMS.sh new file mode 100644 index 0000000..f3674de --- /dev/null +++ b/csv-provider/run_recorderFMS.sh @@ -0,0 +1,948 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +python3 recorder.py -a $1 -p $2 -s \ +Vehicle.ADAS.ABS.IsEnabled \ +Vehicle.ADAS.ABS.IsEngaged \ +Vehicle.ADAS.ABS.IsError \ +Vehicle.ADAS.ActiveAutonomyLevel \ +Vehicle.ADAS.CruiseControl.IsActive \ +Vehicle.ADAS.CruiseControl.IsClutchSwitchPressed \ +Vehicle.ADAS.CruiseControl.IsEnabled \ +Vehicle.ADAS.CruiseControl.IsError \ +Vehicle.ADAS.CruiseControl.IsPowerTakeOffOn \ +Vehicle.ADAS.CruiseControl.SpeedSet \ +Vehicle.ADAS.EBA.IsEnabled \ +Vehicle.ADAS.EBA.IsEngaged \ +Vehicle.ADAS.EBA.IsError \ +Vehicle.ADAS.EBD.IsEnabled \ +Vehicle.ADAS.EBD.IsEngaged \ +Vehicle.ADAS.EBD.IsError \ +Vehicle.ADAS.ESC.IsEnabled \ +Vehicle.ADAS.ESC.IsEngaged \ +Vehicle.ADAS.ESC.IsError \ +Vehicle.ADAS.ESC.IsStrongCrossWindDetected \ +Vehicle.ADAS.ESC.RoadFriction.LowerBound \ +Vehicle.ADAS.ESC.RoadFriction.MostProbable \ +Vehicle.ADAS.ESC.RoadFriction.UpperBound \ +Vehicle.ADAS.LaneDepartureDetection.IsEnabled \ +Vehicle.ADAS.LaneDepartureDetection.IsError \ +Vehicle.ADAS.LaneDepartureDetection.IsWarning \ +Vehicle.ADAS.ObstacleDetection.IsEnabled \ +Vehicle.ADAS.ObstacleDetection.IsError \ +Vehicle.ADAS.ObstacleDetection.IsWarning \ +Vehicle.ADAS.PowerOptimizeLevel \ +Vehicle.ADAS.SupportedAutonomyLevel \ +Vehicle.ADAS.TCS.IsEnabled \ +Vehicle.ADAS.TCS.IsEngaged \ +Vehicle.ADAS.TCS.IsError \ +Vehicle.Acceleration.Lateral \ +Vehicle.Acceleration.Longitudinal \ +Vehicle.Acceleration.Vertical \ +Vehicle.AngularVelocity.Pitch \ +Vehicle.AngularVelocity.Roll \ +Vehicle.AngularVelocity.Yaw \ +Vehicle.AverageSpeed \ +Vehicle.Body.BodyType \ +Vehicle.Body.Hood.IsOpen \ +Vehicle.Body.Horn.IsActive \ +Vehicle.Body.Lights.Backup.IsDefect \ +Vehicle.Body.Lights.Backup.IsOn \ +Vehicle.Body.Lights.Beam.High.IsDefect \ +Vehicle.Body.Lights.Beam.High.IsOn \ +Vehicle.Body.Lights.Beam.Low.IsDefect \ +Vehicle.Body.Lights.Beam.Low.IsOn \ +Vehicle.Body.Lights.Brake.IsActive \ +Vehicle.Body.Lights.Brake.IsDefect \ +Vehicle.Body.Lights.DirectionIndicator.Left.IsDefect \ +Vehicle.Body.Lights.DirectionIndicator.Left.IsSignaling \ +Vehicle.Body.Lights.DirectionIndicator.Right.IsDefect \ +Vehicle.Body.Lights.DirectionIndicator.Right.IsSignaling \ +Vehicle.Body.Lights.Fog.Front.IsDefect \ +Vehicle.Body.Lights.Fog.Front.IsOn \ +Vehicle.Body.Lights.Fog.Rear.IsDefect \ +Vehicle.Body.Lights.Fog.Rear.IsOn \ +Vehicle.Body.Lights.Hazard.IsDefect \ +Vehicle.Body.Lights.Hazard.IsSignaling \ +Vehicle.Body.Lights.IsHighBeamSwitchOn \ +Vehicle.Body.Lights.LicensePlate.IsDefect \ +Vehicle.Body.Lights.LicensePlate.IsOn \ +Vehicle.Body.Lights.LightSwitch \ +Vehicle.Body.Lights.Parking.IsDefect \ +Vehicle.Body.Lights.Parking.IsOn \ +Vehicle.Body.Lights.Running.IsDefect \ +Vehicle.Body.Lights.Running.IsOn \ +Vehicle.Body.Mirrors.Left.IsHeatingOn \ +Vehicle.Body.Mirrors.Left.Pan \ +Vehicle.Body.Mirrors.Left.Tilt \ +Vehicle.Body.Mirrors.Right.IsHeatingOn \ +Vehicle.Body.Mirrors.Right.Pan \ +Vehicle.Body.Mirrors.Right.Tilt \ +Vehicle.Body.PowerOptimizeLevel \ +Vehicle.Body.Raindetection.Intensity \ +Vehicle.Body.RearMainSpoilerPosition \ +Vehicle.Body.RefuelPosition \ +Vehicle.Body.Trunk.Front.IsLocked \ +Vehicle.Body.Trunk.Front.IsOpen \ +Vehicle.Body.Trunk.Rear.IsLocked \ +Vehicle.Body.Trunk.Rear.IsOpen \ +Vehicle.Body.Windshield.Front.IsHeatingOn \ +Vehicle.Body.Windshield.Front.WasherFluid.IsLevelLow \ +Vehicle.Body.Windshield.Front.WasherFluid.Level \ +Vehicle.Body.Windshield.Front.Wiping.Intensity \ +Vehicle.Body.Windshield.Front.Wiping.IsWipersWorn \ +Vehicle.Body.Windshield.Front.Wiping.Mode \ +Vehicle.Body.Windshield.Front.Wiping.System.ActualPosition \ +Vehicle.Body.Windshield.Front.Wiping.System.DriveCurrent \ +Vehicle.Body.Windshield.Front.Wiping.System.Frequency \ +Vehicle.Body.Windshield.Front.Wiping.System.IsBlocked \ +Vehicle.Body.Windshield.Front.Wiping.System.IsEndingWipeCycle \ +Vehicle.Body.Windshield.Front.Wiping.System.IsOverheated \ +Vehicle.Body.Windshield.Front.Wiping.System.IsPositionReached \ +Vehicle.Body.Windshield.Front.Wiping.System.IsWiperError \ +Vehicle.Body.Windshield.Front.Wiping.System.IsWiping \ +Vehicle.Body.Windshield.Front.Wiping.System.Mode \ +Vehicle.Body.Windshield.Front.Wiping.System.TargetPosition \ +Vehicle.Body.Windshield.Front.Wiping.WiperWear \ +Vehicle.Body.Windshield.Rear.IsHeatingOn \ +Vehicle.Body.Windshield.Rear.WasherFluid.IsLevelLow \ +Vehicle.Body.Windshield.Rear.WasherFluid.Level \ +Vehicle.Body.Windshield.Rear.Wiping.Intensity \ +Vehicle.Body.Windshield.Rear.Wiping.IsWipersWorn \ +Vehicle.Body.Windshield.Rear.Wiping.Mode \ +Vehicle.Body.Windshield.Rear.Wiping.System.ActualPosition \ +Vehicle.Body.Windshield.Rear.Wiping.System.DriveCurrent \ +Vehicle.Body.Windshield.Rear.Wiping.System.Frequency \ +Vehicle.Body.Windshield.Rear.Wiping.System.IsBlocked \ +Vehicle.Body.Windshield.Rear.Wiping.System.IsEndingWipeCycle \ +Vehicle.Body.Windshield.Rear.Wiping.System.IsOverheated \ +Vehicle.Body.Windshield.Rear.Wiping.System.IsPositionReached \ +Vehicle.Body.Windshield.Rear.Wiping.System.IsWiperError \ +Vehicle.Body.Windshield.Rear.Wiping.System.IsWiping \ +Vehicle.Body.Windshield.Rear.Wiping.System.Mode \ +Vehicle.Body.Windshield.Rear.Wiping.System.TargetPosition \ +Vehicle.Body.Windshield.Rear.Wiping.WiperWear \ +Vehicle.Cabin.Convertible.Status \ +Vehicle.Cabin.Door.Row1.Left.IsChildLockActive \ +Vehicle.Cabin.Door.Row1.Left.IsLocked \ +Vehicle.Cabin.Door.Row1.Left.IsOpen \ +Vehicle.Cabin.Door.Row1.Left.Shade.Position \ +Vehicle.Cabin.Door.Row1.Left.Shade.Switch \ +Vehicle.Cabin.Door.Row1.Left.Window.IsChildLockEngaged \ +Vehicle.Cabin.Door.Row1.Left.Window.IsOpen \ +Vehicle.Cabin.Door.Row1.Left.Window.Position \ +Vehicle.Cabin.Door.Row1.Left.Window.Switch \ +Vehicle.Cabin.Door.Row1.Right.IsChildLockActive \ +Vehicle.Cabin.Door.Row1.Right.IsLocked \ +Vehicle.Cabin.Door.Row1.Right.IsOpen \ +Vehicle.Cabin.Door.Row1.Right.Shade.Position \ +Vehicle.Cabin.Door.Row1.Right.Shade.Switch \ +Vehicle.Cabin.Door.Row1.Right.Window.IsChildLockEngaged \ +Vehicle.Cabin.Door.Row1.Right.Window.IsOpen \ +Vehicle.Cabin.Door.Row1.Right.Window.Position \ +Vehicle.Cabin.Door.Row1.Right.Window.Switch \ +Vehicle.Cabin.Door.Row2.Left.IsChildLockActive \ +Vehicle.Cabin.Door.Row2.Left.IsLocked \ +Vehicle.Cabin.Door.Row2.Left.IsOpen \ +Vehicle.Cabin.Door.Row2.Left.Shade.Position \ +Vehicle.Cabin.Door.Row2.Left.Shade.Switch \ +Vehicle.Cabin.Door.Row2.Left.Window.IsChildLockEngaged \ +Vehicle.Cabin.Door.Row2.Left.Window.IsOpen \ +Vehicle.Cabin.Door.Row2.Left.Window.Position \ +Vehicle.Cabin.Door.Row2.Left.Window.Switch \ +Vehicle.Cabin.Door.Row2.Right.IsChildLockActive \ +Vehicle.Cabin.Door.Row2.Right.IsLocked \ +Vehicle.Cabin.Door.Row2.Right.IsOpen \ +Vehicle.Cabin.Door.Row2.Right.Shade.Position \ +Vehicle.Cabin.Door.Row2.Right.Shade.Switch \ +Vehicle.Cabin.Door.Row2.Right.Window.IsChildLockEngaged \ +Vehicle.Cabin.Door.Row2.Right.Window.IsOpen \ +Vehicle.Cabin.Door.Row2.Right.Window.Position \ +Vehicle.Cabin.Door.Row2.Right.Window.Switch \ +Vehicle.Cabin.DoorCount \ +Vehicle.Cabin.DriverPosition \ +Vehicle.Cabin.HVAC.AmbientAirTemperature \ +Vehicle.Cabin.HVAC.IsAirConditioningActive \ +Vehicle.Cabin.HVAC.IsFrontDefrosterActive \ +Vehicle.Cabin.HVAC.IsRearDefrosterActive \ +Vehicle.Cabin.HVAC.IsRecirculationActive \ +Vehicle.Cabin.HVAC.PowerOptimizeLevel \ +Vehicle.Cabin.HVAC.Station.Row1.Left.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row1.Left.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row1.Left.Temperature \ +Vehicle.Cabin.HVAC.Station.Row1.Right.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row1.Right.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row1.Right.Temperature \ +Vehicle.Cabin.HVAC.Station.Row2.Left.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row2.Left.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row2.Left.Temperature \ +Vehicle.Cabin.HVAC.Station.Row2.Right.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row2.Right.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row2.Right.Temperature \ +Vehicle.Cabin.HVAC.Station.Row3.Left.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row3.Left.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row3.Left.Temperature \ +Vehicle.Cabin.HVAC.Station.Row3.Right.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row3.Right.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row3.Right.Temperature \ +Vehicle.Cabin.HVAC.Station.Row4.Left.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row4.Left.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row4.Left.Temperature \ +Vehicle.Cabin.HVAC.Station.Row4.Right.AirDistribution \ +Vehicle.Cabin.HVAC.Station.Row4.Right.FanSpeed \ +Vehicle.Cabin.HVAC.Station.Row4.Right.Temperature \ +Vehicle.Cabin.Infotainment.HMI.Brightness \ +Vehicle.Cabin.Infotainment.HMI.CurrentLanguage \ +Vehicle.Cabin.Infotainment.HMI.DateFormat \ +Vehicle.Cabin.Infotainment.HMI.DayNightMode \ +Vehicle.Cabin.Infotainment.HMI.DistanceUnit \ +Vehicle.Cabin.Infotainment.HMI.EVEconomyUnits \ +Vehicle.Cabin.Infotainment.HMI.FuelEconomyUnits \ +Vehicle.Cabin.Infotainment.HMI.FuelVolumeUnit \ +Vehicle.Cabin.Infotainment.HMI.TemperatureUnit \ +Vehicle.Cabin.Infotainment.HMI.TimeFormat \ +Vehicle.Cabin.Infotainment.HMI.TirePressureUnit \ +Vehicle.Cabin.Infotainment.Media.Action \ +Vehicle.Cabin.Infotainment.Media.DeclinedURI \ +Vehicle.Cabin.Infotainment.Media.Played.Album \ +Vehicle.Cabin.Infotainment.Media.Played.Artist \ +Vehicle.Cabin.Infotainment.Media.Played.PlaybackRate \ +Vehicle.Cabin.Infotainment.Media.Played.Source \ +Vehicle.Cabin.Infotainment.Media.Played.Track \ +Vehicle.Cabin.Infotainment.Media.Played.URI \ +Vehicle.Cabin.Infotainment.Media.SelectedURI \ +Vehicle.Cabin.Infotainment.Media.Volume \ +Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Latitude \ +Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Longitude \ +Vehicle.Cabin.Infotainment.Navigation.Mute \ +Vehicle.Cabin.Infotainment.Navigation.Volume \ +Vehicle.Cabin.Infotainment.PowerOptimizeLevel \ +Vehicle.Cabin.Infotainment.SmartphoneProjection.Active \ +Vehicle.Cabin.Infotainment.SmartphoneProjection.Source \ +Vehicle.Cabin.Infotainment.SmartphoneProjection.SupportedMode \ +Vehicle.Cabin.Lights.AmbientLight \ +Vehicle.Cabin.Lights.IsDomeOn \ +Vehicle.Cabin.Lights.IsGloveBoxOn \ +Vehicle.Cabin.Lights.IsTrunkOn \ +Vehicle.Cabin.Lights.LightIntensity \ +Vehicle.Cabin.Lights.Spotlight.Row1.IsLeftOn \ +Vehicle.Cabin.Lights.Spotlight.Row1.IsRightOn \ +Vehicle.Cabin.Lights.Spotlight.Row1.IsSharedOn \ +Vehicle.Cabin.Lights.Spotlight.Row2.IsLeftOn \ +Vehicle.Cabin.Lights.Spotlight.Row2.IsRightOn \ +Vehicle.Cabin.Lights.Spotlight.Row2.IsSharedOn \ +Vehicle.Cabin.Lights.Spotlight.Row3.IsLeftOn \ +Vehicle.Cabin.Lights.Spotlight.Row3.IsRightOn \ +Vehicle.Cabin.Lights.Spotlight.Row3.IsSharedOn \ +Vehicle.Cabin.Lights.Spotlight.Row4.IsLeftOn \ +Vehicle.Cabin.Lights.Spotlight.Row4.IsRightOn \ +Vehicle.Cabin.Lights.Spotlight.Row4.IsSharedOn \ +Vehicle.Cabin.PowerOptimizeLevel \ +Vehicle.Cabin.RearShade.Position \ +Vehicle.Cabin.RearShade.Switch \ +Vehicle.Cabin.RearviewMirror.DimmingLevel \ +Vehicle.Cabin.Seat.Row1.Pos1.Airbag.IsDeployed \ +Vehicle.Cabin.Seat.Row1.Pos1.Backrest.Lumbar.Height \ +Vehicle.Cabin.Seat.Row1.Pos1.Backrest.Lumbar.Support \ +Vehicle.Cabin.Seat.Row1.Pos1.Backrest.Recline \ +Vehicle.Cabin.Seat.Row1.Pos1.Backrest.SideBolster.Support \ +Vehicle.Cabin.Seat.Row1.Pos1.Headrest.Angle \ +Vehicle.Cabin.Seat.Row1.Pos1.Headrest.Height \ +Vehicle.Cabin.Seat.Row1.Pos1.Heating \ +Vehicle.Cabin.Seat.Row1.Pos1.Height \ +Vehicle.Cabin.Seat.Row1.Pos1.IsBelted \ +Vehicle.Cabin.Seat.Row1.Pos1.IsOccupied \ +Vehicle.Cabin.Seat.Row1.Pos1.Massage \ +Vehicle.Cabin.Seat.Row1.Pos1.Occupant.Identifier.Issuer \ +Vehicle.Cabin.Seat.Row1.Pos1.Occupant.Identifier.Subject \ +Vehicle.Cabin.Seat.Row1.Pos1.Position \ +Vehicle.Cabin.Seat.Row1.Pos1.Seating.Length \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.IsReclineBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.IsReclineForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.Lumbar.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.Lumbar.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.Lumbar.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.Lumbar.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.SideBolster.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Backrest.SideBolster.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Headrest.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Headrest.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Headrest.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Headrest.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsCoolerEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsTiltBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsTiltForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.IsWarmerEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Massage.IsDecreaseEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Massage.IsIncreaseEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Seating.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Switch.Seating.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos1.Tilt \ +Vehicle.Cabin.Seat.Row1.Pos2.Airbag.IsDeployed \ +Vehicle.Cabin.Seat.Row1.Pos2.Backrest.Lumbar.Height \ +Vehicle.Cabin.Seat.Row1.Pos2.Backrest.Lumbar.Support \ +Vehicle.Cabin.Seat.Row1.Pos2.Backrest.Recline \ +Vehicle.Cabin.Seat.Row1.Pos2.Backrest.SideBolster.Support \ +Vehicle.Cabin.Seat.Row1.Pos2.Headrest.Angle \ +Vehicle.Cabin.Seat.Row1.Pos2.Headrest.Height \ +Vehicle.Cabin.Seat.Row1.Pos2.Heating \ +Vehicle.Cabin.Seat.Row1.Pos2.Height \ +Vehicle.Cabin.Seat.Row1.Pos2.IsBelted \ +Vehicle.Cabin.Seat.Row1.Pos2.IsOccupied \ +Vehicle.Cabin.Seat.Row1.Pos2.Massage \ +Vehicle.Cabin.Seat.Row1.Pos2.Occupant.Identifier.Issuer \ +Vehicle.Cabin.Seat.Row1.Pos2.Occupant.Identifier.Subject \ +Vehicle.Cabin.Seat.Row1.Pos2.Position \ +Vehicle.Cabin.Seat.Row1.Pos2.Seating.Length \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.IsReclineBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.IsReclineForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.Lumbar.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.Lumbar.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.Lumbar.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.Lumbar.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.SideBolster.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Backrest.SideBolster.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Headrest.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Headrest.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Headrest.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Headrest.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsCoolerEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsTiltBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsTiltForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.IsWarmerEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Massage.IsDecreaseEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Massage.IsIncreaseEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Seating.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Switch.Seating.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos2.Tilt \ +Vehicle.Cabin.Seat.Row1.Pos3.Airbag.IsDeployed \ +Vehicle.Cabin.Seat.Row1.Pos3.Backrest.Lumbar.Height \ +Vehicle.Cabin.Seat.Row1.Pos3.Backrest.Lumbar.Support \ +Vehicle.Cabin.Seat.Row1.Pos3.Backrest.Recline \ +Vehicle.Cabin.Seat.Row1.Pos3.Backrest.SideBolster.Support \ +Vehicle.Cabin.Seat.Row1.Pos3.Headrest.Angle \ +Vehicle.Cabin.Seat.Row1.Pos3.Headrest.Height \ +Vehicle.Cabin.Seat.Row1.Pos3.Heating \ +Vehicle.Cabin.Seat.Row1.Pos3.Height \ +Vehicle.Cabin.Seat.Row1.Pos3.IsBelted \ +Vehicle.Cabin.Seat.Row1.Pos3.IsOccupied \ +Vehicle.Cabin.Seat.Row1.Pos3.Massage \ +Vehicle.Cabin.Seat.Row1.Pos3.Occupant.Identifier.Issuer \ +Vehicle.Cabin.Seat.Row1.Pos3.Occupant.Identifier.Subject \ +Vehicle.Cabin.Seat.Row1.Pos3.Position \ +Vehicle.Cabin.Seat.Row1.Pos3.Seating.Length \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.IsReclineBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.IsReclineForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.Lumbar.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.Lumbar.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.Lumbar.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.Lumbar.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.SideBolster.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Backrest.SideBolster.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Headrest.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Headrest.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Headrest.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Headrest.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsCoolerEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsDownEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsTiltBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsTiltForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsUpEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.IsWarmerEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Massage.IsDecreaseEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Massage.IsIncreaseEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Seating.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Switch.Seating.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row1.Pos3.Tilt \ +Vehicle.Cabin.Seat.Row2.Pos1.Airbag.IsDeployed \ +Vehicle.Cabin.Seat.Row2.Pos1.Backrest.Lumbar.Height \ +Vehicle.Cabin.Seat.Row2.Pos1.Backrest.Lumbar.Support \ +Vehicle.Cabin.Seat.Row2.Pos1.Backrest.Recline \ +Vehicle.Cabin.Seat.Row2.Pos1.Backrest.SideBolster.Support \ +Vehicle.Cabin.Seat.Row2.Pos1.Headrest.Angle \ +Vehicle.Cabin.Seat.Row2.Pos1.Headrest.Height \ +Vehicle.Cabin.Seat.Row2.Pos1.Heating \ +Vehicle.Cabin.Seat.Row2.Pos1.Height \ +Vehicle.Cabin.Seat.Row2.Pos1.IsBelted \ +Vehicle.Cabin.Seat.Row2.Pos1.IsOccupied \ +Vehicle.Cabin.Seat.Row2.Pos1.Massage \ +Vehicle.Cabin.Seat.Row2.Pos1.Occupant.Identifier.Issuer \ +Vehicle.Cabin.Seat.Row2.Pos1.Occupant.Identifier.Subject \ +Vehicle.Cabin.Seat.Row2.Pos1.Position \ +Vehicle.Cabin.Seat.Row2.Pos1.Seating.Length \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.IsReclineBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.IsReclineForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.Lumbar.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.Lumbar.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.Lumbar.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.Lumbar.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.SideBolster.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Backrest.SideBolster.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Headrest.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Headrest.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Headrest.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Headrest.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsCoolerEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsTiltBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsTiltForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.IsWarmerEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Massage.IsDecreaseEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Massage.IsIncreaseEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Seating.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Switch.Seating.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos1.Tilt \ +Vehicle.Cabin.Seat.Row2.Pos2.Airbag.IsDeployed \ +Vehicle.Cabin.Seat.Row2.Pos2.Backrest.Lumbar.Height \ +Vehicle.Cabin.Seat.Row2.Pos2.Backrest.Lumbar.Support \ +Vehicle.Cabin.Seat.Row2.Pos2.Backrest.Recline \ +Vehicle.Cabin.Seat.Row2.Pos2.Backrest.SideBolster.Support \ +Vehicle.Cabin.Seat.Row2.Pos2.Headrest.Angle \ +Vehicle.Cabin.Seat.Row2.Pos2.Headrest.Height \ +Vehicle.Cabin.Seat.Row2.Pos2.Heating \ +Vehicle.Cabin.Seat.Row2.Pos2.Height \ +Vehicle.Cabin.Seat.Row2.Pos2.IsBelted \ +Vehicle.Cabin.Seat.Row2.Pos2.IsOccupied \ +Vehicle.Cabin.Seat.Row2.Pos2.Massage \ +Vehicle.Cabin.Seat.Row2.Pos2.Occupant.Identifier.Issuer \ +Vehicle.Cabin.Seat.Row2.Pos2.Occupant.Identifier.Subject \ +Vehicle.Cabin.Seat.Row2.Pos2.Position \ +Vehicle.Cabin.Seat.Row2.Pos2.Seating.Length \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.IsReclineBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.IsReclineForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.Lumbar.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.Lumbar.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.Lumbar.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.Lumbar.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.SideBolster.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Backrest.SideBolster.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Headrest.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Headrest.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Headrest.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Headrest.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsCoolerEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsTiltBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsTiltForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.IsWarmerEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Massage.IsDecreaseEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Massage.IsIncreaseEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Seating.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Switch.Seating.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos2.Tilt \ +Vehicle.Cabin.Seat.Row2.Pos3.Airbag.IsDeployed \ +Vehicle.Cabin.Seat.Row2.Pos3.Backrest.Lumbar.Height \ +Vehicle.Cabin.Seat.Row2.Pos3.Backrest.Lumbar.Support \ +Vehicle.Cabin.Seat.Row2.Pos3.Backrest.Recline \ +Vehicle.Cabin.Seat.Row2.Pos3.Backrest.SideBolster.Support \ +Vehicle.Cabin.Seat.Row2.Pos3.Headrest.Angle \ +Vehicle.Cabin.Seat.Row2.Pos3.Headrest.Height \ +Vehicle.Cabin.Seat.Row2.Pos3.Heating \ +Vehicle.Cabin.Seat.Row2.Pos3.Height \ +Vehicle.Cabin.Seat.Row2.Pos3.IsBelted \ +Vehicle.Cabin.Seat.Row2.Pos3.IsOccupied \ +Vehicle.Cabin.Seat.Row2.Pos3.Massage \ +Vehicle.Cabin.Seat.Row2.Pos3.Occupant.Identifier.Issuer \ +Vehicle.Cabin.Seat.Row2.Pos3.Occupant.Identifier.Subject \ +Vehicle.Cabin.Seat.Row2.Pos3.Position \ +Vehicle.Cabin.Seat.Row2.Pos3.Seating.Length \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.IsReclineBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.IsReclineForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.Lumbar.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.Lumbar.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.Lumbar.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.Lumbar.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.SideBolster.IsLessSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Backrest.SideBolster.IsMoreSupportEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Headrest.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Headrest.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Headrest.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Headrest.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsCoolerEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsDownEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsTiltBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsTiltForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsUpEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.IsWarmerEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Massage.IsDecreaseEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Massage.IsIncreaseEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Seating.IsBackwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Switch.Seating.IsForwardEngaged \ +Vehicle.Cabin.Seat.Row2.Pos3.Tilt \ +Vehicle.Cabin.SeatPosCount \ +Vehicle.Cabin.SeatRowCount \ +Vehicle.Cabin.Sunroof.Position \ +Vehicle.Cabin.Sunroof.Shade.Position \ +Vehicle.Cabin.Sunroof.Shade.Switch \ +Vehicle.Cabin.Sunroof.Switch \ +Vehicle.CargoVolume \ +Vehicle.Chassis.Accelerator.PedalPosition \ +Vehicle.Chassis.Axle.Row1.SteeringAngle \ +Vehicle.Chassis.Axle.Row1.TireAspectRatio \ +Vehicle.Chassis.Axle.Row1.TireDiameter \ +Vehicle.Chassis.Axle.Row1.TireWidth \ +Vehicle.Chassis.Axle.Row1.TyreLocation \ +Vehicle.Chassis.Axle.Row1.VerticalLoad \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Brake.FluidLevel \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Brake.IsBrakesWorn \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Brake.IsFluidLevelLow \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Brake.PadWear \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Speed \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Tire.IsPressureLow \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Tire.Pressure \ +Vehicle.Chassis.Axle.Row1.Wheel.Left.Tire.Temperature \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Brake.FluidLevel \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Brake.IsBrakesWorn \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Brake.IsFluidLevelLow \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Brake.PadWear \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Speed \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Tire.IsPressureLow \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Tire.Pressure \ +Vehicle.Chassis.Axle.Row1.Wheel.Right.Tire.Temperature \ +Vehicle.Chassis.Axle.Row1.WheelCount \ +Vehicle.Chassis.Axle.Row1.WheelDiameter \ +Vehicle.Chassis.Axle.Row1.WheelWidth \ +Vehicle.Chassis.Axle.Row2.SteeringAngle \ +Vehicle.Chassis.Axle.Row2.TireAspectRatio \ +Vehicle.Chassis.Axle.Row2.TireDiameter \ +Vehicle.Chassis.Axle.Row2.TireWidth \ +Vehicle.Chassis.Axle.Row2.TyreLocation \ +Vehicle.Chassis.Axle.Row2.VerticalLoad \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Brake.FluidLevel \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Brake.IsBrakesWorn \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Brake.IsFluidLevelLow \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Brake.PadWear \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Speed \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Tire.IsPressureLow \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Tire.Pressure \ +Vehicle.Chassis.Axle.Row2.Wheel.Left.Tire.Temperature \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Brake.FluidLevel \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Brake.IsBrakesWorn \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Brake.IsFluidLevelLow \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Brake.PadWear \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Speed \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Tire.IsPressureLow \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Tire.Pressure \ +Vehicle.Chassis.Axle.Row2.Wheel.Right.Tire.Temperature \ +Vehicle.Chassis.Axle.Row2.WheelCount \ +Vehicle.Chassis.Axle.Row2.WheelDiameter \ +Vehicle.Chassis.Axle.Row2.WheelWidth \ +Vehicle.Chassis.Axle.Row3.TyreLocation \ +Vehicle.Chassis.Axle.Row3.VerticalLoad \ +Vehicle.Chassis.Axle.Row4.TyreLocation \ +Vehicle.Chassis.Axle.Row4.VerticalLoad \ +Vehicle.Chassis.Axle.Row5.TyreLocation \ +Vehicle.Chassis.Axle.Row5.VerticalLoad \ +Vehicle.Chassis.Axle.Row6.TyreLocation \ +Vehicle.Chassis.Axle.Row6.VerticalLoad \ +Vehicle.Chassis.AxleCount \ +Vehicle.Chassis.Brake.IsDriverEmergencyBrakingDetected \ +Vehicle.Chassis.Brake.PedalPosition \ +Vehicle.Chassis.ParkingBrake.IsEngaged \ +Vehicle.Chassis.SteeringWheel.Angle \ +Vehicle.Chassis.SteeringWheel.Extension \ +Vehicle.Chassis.SteeringWheel.Position \ +Vehicle.Chassis.SteeringWheel.Tilt \ +Vehicle.Chassis.Track \ +Vehicle.Chassis.Wheelbase \ +Vehicle.CombinedVehicleWeight \ +Vehicle.Connectivity.IsConnectivityAvailable \ +Vehicle.CurbWeight \ +Vehicle.CurrentLocation.Altitude \ +Vehicle.CurrentLocation.GNSSReceiver.FixType \ +Vehicle.CurrentLocation.GNSSReceiver.MountingPosition.X \ +Vehicle.CurrentLocation.GNSSReceiver.MountingPosition.Y \ +Vehicle.CurrentLocation.GNSSReceiver.MountingPosition.Z \ +Vehicle.CurrentLocation.Heading \ +Vehicle.CurrentLocation.HorizontalAccuracy \ +Vehicle.CurrentLocation.Latitude \ +Vehicle.CurrentLocation.Longitude \ +Vehicle.CurrentLocation.Speed \ +Vehicle.CurrentLocation.Timestamp \ +Vehicle.CurrentLocation.VerticalAccuracy \ +Vehicle.CurrentOverallWeight \ +Vehicle.DirectionIndicator \ +Vehicle.Driver.AttentiveProbability \ +Vehicle.Driver.DistractionLevel \ +Vehicle.Driver.FatigueLevel \ +Vehicle.Driver.HeartRate \ +Vehicle.Driver.Identifier.Issuer \ +Vehicle.Driver.Identifier.Subject \ +Vehicle.Driver.IsEyesOnRoad \ +Vehicle.EmissionsCO2 \ +Vehicle.Exterior.AirTemperature \ +Vehicle.Exterior.Humidity \ +Vehicle.Exterior.LightIntensity \ +Vehicle.GrossWeight \ +Vehicle.Height \ +Vehicle.IsBrokenDown \ +Vehicle.IsMoving \ +Vehicle.IsOverspeed \ +Vehicle.Length \ +Vehicle.LowVoltageBattery.CurrentCurrent \ +Vehicle.LowVoltageBattery.CurrentVoltage \ +Vehicle.LowVoltageBattery.NominalCapacity \ +Vehicle.LowVoltageBattery.NominalVoltage \ +Vehicle.LowVoltageSystemState \ +Vehicle.MaxTowBallWeight \ +Vehicle.MaxTowWeight \ +Vehicle.OBD.AbsoluteLoad \ +Vehicle.OBD.AcceleratorPositionD \ +Vehicle.OBD.AcceleratorPositionE \ +Vehicle.OBD.AcceleratorPositionF \ +Vehicle.OBD.AirStatus \ +Vehicle.OBD.AmbientAirTemperature \ +Vehicle.OBD.BarometricPressure \ +Vehicle.OBD.Catalyst.Bank1.Temperature1 \ +Vehicle.OBD.Catalyst.Bank1.Temperature2 \ +Vehicle.OBD.Catalyst.Bank2.Temperature1 \ +Vehicle.OBD.Catalyst.Bank2.Temperature2 \ +Vehicle.OBD.CommandedEGR \ +Vehicle.OBD.CommandedEVAP \ +Vehicle.OBD.CommandedEquivalenceRatio \ +Vehicle.OBD.ControlModuleVoltage \ +Vehicle.OBD.CoolantTemperature \ +Vehicle.OBD.DTCList \ +Vehicle.OBD.DistanceSinceDTCClear \ +Vehicle.OBD.DistanceWithMIL \ +Vehicle.OBD.DriveCycleStatus.DTCCount \ +Vehicle.OBD.DriveCycleStatus.IgnitionType \ +Vehicle.OBD.DriveCycleStatus.IsMILOn \ +Vehicle.OBD.EGRError \ +Vehicle.OBD.EVAPVaporPressure \ +Vehicle.OBD.EVAPVaporPressureAbsolute \ +Vehicle.OBD.EVAPVaporPressureAlternate \ +Vehicle.OBD.EngineLoad \ +Vehicle.OBD.EngineSpeed \ +Vehicle.OBD.EthanolPercent \ +Vehicle.OBD.FreezeDTC \ +Vehicle.OBD.FuelInjectionTiming \ +Vehicle.OBD.FuelLevel \ +Vehicle.OBD.FuelPressure \ +Vehicle.OBD.FuelRailPressureAbsolute \ +Vehicle.OBD.FuelRailPressureDirect \ +Vehicle.OBD.FuelRailPressureVac \ +Vehicle.OBD.FuelRate \ +Vehicle.OBD.FuelStatus \ +Vehicle.OBD.FuelType \ +Vehicle.OBD.HybridBatteryRemaining \ +Vehicle.OBD.IntakeTemp \ +Vehicle.OBD.IsPTOActive \ +Vehicle.OBD.LongTermFuelTrim1 \ +Vehicle.OBD.LongTermFuelTrim2 \ +Vehicle.OBD.LongTermO2Trim1 \ +Vehicle.OBD.LongTermO2Trim2 \ +Vehicle.OBD.LongTermO2Trim3 \ +Vehicle.OBD.LongTermO2Trim4 \ +Vehicle.OBD.MAF \ +Vehicle.OBD.MAP \ +Vehicle.OBD.MaxMAF \ +Vehicle.OBD.O2.Sensor1.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor1.Voltage \ +Vehicle.OBD.O2.Sensor2.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor2.Voltage \ +Vehicle.OBD.O2.Sensor3.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor3.Voltage \ +Vehicle.OBD.O2.Sensor4.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor4.Voltage \ +Vehicle.OBD.O2.Sensor5.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor5.Voltage \ +Vehicle.OBD.O2.Sensor6.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor6.Voltage \ +Vehicle.OBD.O2.Sensor7.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor7.Voltage \ +Vehicle.OBD.O2.Sensor8.ShortTermFuelTrim \ +Vehicle.OBD.O2.Sensor8.Voltage \ +Vehicle.OBD.O2WR.Sensor1.Current \ +Vehicle.OBD.O2WR.Sensor1.Lambda \ +Vehicle.OBD.O2WR.Sensor1.Voltage \ +Vehicle.OBD.O2WR.Sensor2.Current \ +Vehicle.OBD.O2WR.Sensor2.Lambda \ +Vehicle.OBD.O2WR.Sensor2.Voltage \ +Vehicle.OBD.O2WR.Sensor3.Current \ +Vehicle.OBD.O2WR.Sensor3.Lambda \ +Vehicle.OBD.O2WR.Sensor3.Voltage \ +Vehicle.OBD.O2WR.Sensor4.Current \ +Vehicle.OBD.O2WR.Sensor4.Lambda \ +Vehicle.OBD.O2WR.Sensor4.Voltage \ +Vehicle.OBD.O2WR.Sensor5.Current \ +Vehicle.OBD.O2WR.Sensor5.Lambda \ +Vehicle.OBD.O2WR.Sensor5.Voltage \ +Vehicle.OBD.O2WR.Sensor6.Current \ +Vehicle.OBD.O2WR.Sensor6.Lambda \ +Vehicle.OBD.O2WR.Sensor6.Voltage \ +Vehicle.OBD.O2WR.Sensor7.Current \ +Vehicle.OBD.O2WR.Sensor7.Lambda \ +Vehicle.OBD.O2WR.Sensor7.Voltage \ +Vehicle.OBD.O2WR.Sensor8.Current \ +Vehicle.OBD.O2WR.Sensor8.Lambda \ +Vehicle.OBD.O2WR.Sensor8.Voltage \ +Vehicle.OBD.OBDStandards \ +Vehicle.OBD.OilTemperature \ +Vehicle.OBD.OxygenSensorsIn2Banks \ +Vehicle.OBD.OxygenSensorsIn4Banks \ +Vehicle.OBD.PidsA \ +Vehicle.OBD.PidsB \ +Vehicle.OBD.PidsC \ +Vehicle.OBD.RelativeAcceleratorPosition \ +Vehicle.OBD.RelativeThrottlePosition \ +Vehicle.OBD.RunTime \ +Vehicle.OBD.RunTimeMIL \ +Vehicle.OBD.ShortTermFuelTrim1 \ +Vehicle.OBD.ShortTermFuelTrim2 \ +Vehicle.OBD.ShortTermO2Trim1 \ +Vehicle.OBD.ShortTermO2Trim2 \ +Vehicle.OBD.ShortTermO2Trim3 \ +Vehicle.OBD.ShortTermO2Trim4 \ +Vehicle.OBD.Speed \ +Vehicle.OBD.Status.DTCCount \ +Vehicle.OBD.Status.IgnitionType \ +Vehicle.OBD.Status.IsMILOn \ +Vehicle.OBD.ThrottleActuator \ +Vehicle.OBD.ThrottlePosition \ +Vehicle.OBD.ThrottlePositionB \ +Vehicle.OBD.ThrottlePositionC \ +Vehicle.OBD.TimeSinceDTCCleared \ +Vehicle.OBD.TimingAdvance \ +Vehicle.OBD.WarmupsSinceDTCClear \ +Vehicle.PowerOptimizeLevel \ +Vehicle.Powertrain.AccumulatedBrakingEnergy \ +Vehicle.Powertrain.Brake.ActualRetarderPercentage \ +Vehicle.Powertrain.CombustionEngine.ActualEnginePercentTorque \ +Vehicle.Powertrain.CombustionEngine.AspirationType \ +Vehicle.Powertrain.CombustionEngine.Bore \ +Vehicle.Powertrain.CombustionEngine.CompressionRatio \ +Vehicle.Powertrain.CombustionEngine.Configuration \ +Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Capacity \ +Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.IsLevelLow \ +Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Level \ +Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Range \ +Vehicle.Powertrain.CombustionEngine.DieselParticulateFilter.DeltaPressure \ +Vehicle.Powertrain.CombustionEngine.DieselParticulateFilter.InletTemperature \ +Vehicle.Powertrain.CombustionEngine.DieselParticulateFilter.OutletTemperature \ +Vehicle.Powertrain.CombustionEngine.Displacement \ +Vehicle.Powertrain.CombustionEngine.ECT \ +Vehicle.Powertrain.CombustionEngine.EOP \ +Vehicle.Powertrain.CombustionEngine.EOT \ +Vehicle.Powertrain.CombustionEngine.EngineCode \ +Vehicle.Powertrain.CombustionEngine.EngineCoolantCapacity \ +Vehicle.Powertrain.CombustionEngine.EngineHours \ +Vehicle.Powertrain.CombustionEngine.EngineOilCapacity \ +Vehicle.Powertrain.CombustionEngine.EngineOilLevel \ +Vehicle.Powertrain.CombustionEngine.IdleHours \ +Vehicle.Powertrain.CombustionEngine.IsRunning \ +Vehicle.Powertrain.CombustionEngine.MAF \ +Vehicle.Powertrain.CombustionEngine.MAP \ +Vehicle.Powertrain.CombustionEngine.MaxPower \ +Vehicle.Powertrain.CombustionEngine.MaxTorque \ +Vehicle.Powertrain.CombustionEngine.NumberOfCylinders \ +Vehicle.Powertrain.CombustionEngine.NumberOfValvesPerCylinder \ +Vehicle.Powertrain.CombustionEngine.OilLifeRemaining \ +Vehicle.Powertrain.CombustionEngine.Power \ +Vehicle.Powertrain.CombustionEngine.Speed \ +Vehicle.Powertrain.CombustionEngine.StrokeLength \ +Vehicle.Powertrain.CombustionEngine.TPS \ +Vehicle.Powertrain.CombustionEngine.Torque \ +Vehicle.Powertrain.CurrentFuelType \ +Vehicle.Powertrain.Eec2AcceleratorPedalPosition \ +Vehicle.Powertrain.Eec2EnginePercentLoad \ +Vehicle.Powertrain.ElectricMotor.CoolantTemperature \ +Vehicle.Powertrain.ElectricMotor.EngineCode \ +Vehicle.Powertrain.ElectricMotor.MaxPower \ +Vehicle.Powertrain.ElectricMotor.MaxRegenPower \ +Vehicle.Powertrain.ElectricMotor.MaxRegenTorque \ +Vehicle.Powertrain.ElectricMotor.MaxTorque \ +Vehicle.Powertrain.ElectricMotor.MotorHours \ +Vehicle.Powertrain.ElectricMotor.Power \ +Vehicle.Powertrain.ElectricMotor.Speed \ +Vehicle.Powertrain.ElectricMotor.Temperature \ +Vehicle.Powertrain.ElectricMotor.Torque \ +Vehicle.Powertrain.FuelSystem.AccumulatedConsumption \ +Vehicle.Powertrain.FuelSystem.AverageConsumption \ +Vehicle.Powertrain.FuelSystem.ConsumptionSinceStart \ +Vehicle.Powertrain.FuelSystem.HybridType \ +Vehicle.Powertrain.FuelSystem.InstantConsumption \ +Vehicle.Powertrain.FuelSystem.IsEngineStopStartEnabled \ +Vehicle.Powertrain.FuelSystem.IsFuelLevelLow \ +Vehicle.Powertrain.FuelSystem.Level \ +Vehicle.Powertrain.FuelSystem.Range \ +Vehicle.Powertrain.FuelSystem.SupportedFuel \ +Vehicle.Powertrain.FuelSystem.SupportedFuelTypes \ +Vehicle.Powertrain.FuelSystem.Tank.First.Fuel \ +Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel \ +Vehicle.Powertrain.FuelSystem.Tank.Second.Fuel \ +Vehicle.Powertrain.FuelSystem.Tank.Second.RelativeLevel \ +Vehicle.Powertrain.FuelSystem.TankCapacity \ +Vehicle.Powertrain.FuelSystem.TimeSinceStart \ +Vehicle.Powertrain.PTODriveEngagement \ +Vehicle.Powertrain.PowerOptimizeLevel \ +Vehicle.Powertrain.Range \ +Vehicle.Powertrain.TractionBattery.AccumulatedChargedEnergy \ +Vehicle.Powertrain.TractionBattery.AccumulatedChargedThroughput \ +Vehicle.Powertrain.TractionBattery.AccumulatedConsumedEnergy \ +Vehicle.Powertrain.TractionBattery.AccumulatedConsumedThroughput \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeCurrent.DC \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeCurrent.Phase1 \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeCurrent.Phase2 \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeCurrent.Phase3 \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeLimit \ +Vehicle.Powertrain.TractionBattery.Charging.ChargePlugType \ +Vehicle.Powertrain.TractionBattery.Charging.ChargePortFlap \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeRate \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeVoltage.DC \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeVoltage.Phase1 \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeVoltage.Phase2 \ +Vehicle.Powertrain.TractionBattery.Charging.ChargeVoltage.Phase3 \ +Vehicle.Powertrain.TractionBattery.Charging.IsCharging \ +Vehicle.Powertrain.TractionBattery.Charging.IsChargingCableConnected \ +Vehicle.Powertrain.TractionBattery.Charging.IsChargingCableLocked \ +Vehicle.Powertrain.TractionBattery.Charging.IsDischarging \ +Vehicle.Powertrain.TractionBattery.Charging.MaximumChargingCurrent.DC \ +Vehicle.Powertrain.TractionBattery.Charging.MaximumChargingCurrent.Phase1 \ +Vehicle.Powertrain.TractionBattery.Charging.MaximumChargingCurrent.Phase2 \ +Vehicle.Powertrain.TractionBattery.Charging.MaximumChargingCurrent.Phase3 \ +Vehicle.Powertrain.TractionBattery.Charging.Mode \ +Vehicle.Powertrain.TractionBattery.Charging.PowerLoss \ +Vehicle.Powertrain.TractionBattery.Charging.StartStopCharging \ +Vehicle.Powertrain.TractionBattery.Charging.Temperature \ +Vehicle.Powertrain.TractionBattery.Charging.TimeToComplete \ +Vehicle.Powertrain.TractionBattery.Charging.Timer.Mode \ +Vehicle.Powertrain.TractionBattery.Charging.Timer.Time \ +Vehicle.Powertrain.TractionBattery.CoolantTemperature \ +Vehicle.Powertrain.TractionBattery.CurrentCurrent \ +Vehicle.Powertrain.TractionBattery.CurrentPower \ +Vehicle.Powertrain.TractionBattery.CurrentVoltage \ +Vehicle.Powertrain.TractionBattery.DCDC.PowerLoss \ +Vehicle.Powertrain.TractionBattery.DCDC.Temperature \ +Vehicle.Powertrain.TractionBattery.GrossCapacity \ +Vehicle.Powertrain.TractionBattery.Id \ +Vehicle.Powertrain.TractionBattery.IsGroundConnected \ +Vehicle.Powertrain.TractionBattery.IsPowerConnected \ +Vehicle.Powertrain.TractionBattery.MaxVoltage \ +Vehicle.Powertrain.TractionBattery.NetCapacity \ +Vehicle.Powertrain.TractionBattery.NominalVoltage \ +Vehicle.Powertrain.TractionBattery.PowerLoss \ +Vehicle.Powertrain.TractionBattery.ProductionDate \ +Vehicle.Powertrain.TractionBattery.Range \ +Vehicle.Powertrain.TractionBattery.StateOfCharge.Current \ +Vehicle.Powertrain.TractionBattery.StateOfCharge.Displayed \ +Vehicle.Powertrain.TractionBattery.StateOfHealth \ +Vehicle.Powertrain.TractionBattery.Temperature.Average \ +Vehicle.Powertrain.TractionBattery.Temperature.Max \ +Vehicle.Powertrain.TractionBattery.Temperature.Min \ +Vehicle.Powertrain.Transmission.ClutchEngagement \ +Vehicle.Powertrain.Transmission.ClutchWear \ +Vehicle.Powertrain.Transmission.CurrentGear \ +Vehicle.Powertrain.Transmission.DiffLockFrontEngagement \ +Vehicle.Powertrain.Transmission.DiffLockRearEngagement \ +Vehicle.Powertrain.Transmission.DriveType \ +Vehicle.Powertrain.Transmission.GearChangeMode \ +Vehicle.Powertrain.Transmission.GearCount \ +Vehicle.Powertrain.Transmission.IsElectricalPowertrainEngaged \ +Vehicle.Powertrain.Transmission.IsLowRangeEngaged \ +Vehicle.Powertrain.Transmission.IsParkLockEngaged \ +Vehicle.Powertrain.Transmission.PerformanceMode \ +Vehicle.Powertrain.Transmission.SelectedGear \ +Vehicle.Powertrain.Transmission.Temperature \ +Vehicle.Powertrain.Transmission.TorqueDistribution \ +Vehicle.Powertrain.Transmission.TravelledDistance \ +Vehicle.Powertrain.Transmission.Type \ +Vehicle.Powertrain.Type \ +Vehicle.RoofLoad \ +Vehicle.Service.DistanceToService \ +Vehicle.Service.IsServiceDue \ +Vehicle.Service.TimeToService \ +Vehicle.Speed \ +Vehicle.StartTime \ +Vehicle.Tachograph.Driver.Driver1.AuthenticationEquipment \ +Vehicle.Tachograph.Driver.Driver1.CardIssuingMemberState \ +Vehicle.Tachograph.Driver.Driver1.CardRenewalIndex \ +Vehicle.Tachograph.Driver.Driver1.CardReplacementIndex \ +Vehicle.Tachograph.Driver.Driver1.Identification \ +Vehicle.Tachograph.Driver.Driver1.IsCardPresent \ +Vehicle.Tachograph.Driver.Driver1.IsLoggedIn \ +Vehicle.Tachograph.Driver.Driver1.OemIdentification \ +Vehicle.Tachograph.Driver.Driver1.OemIdentificationType \ +Vehicle.Tachograph.Driver.Driver1.TimeRelatedStatus \ +Vehicle.Tachograph.Driver.Driver1.WorkingState \ +Vehicle.Tachograph.Driver.Driver2.AuthenticationEquipment \ +Vehicle.Tachograph.Driver.Driver2.CardIssuingMemberState \ +Vehicle.Tachograph.Driver.Driver2.CardRenewalIndex \ +Vehicle.Tachograph.Driver.Driver2.CardReplacementIndex \ +Vehicle.Tachograph.Driver.Driver2.Identification \ +Vehicle.Tachograph.Driver.Driver2.IsCardPresent \ +Vehicle.Tachograph.Driver.Driver2.IsLoggedIn \ +Vehicle.Tachograph.Driver.Driver2.OemIdentification \ +Vehicle.Tachograph.Driver.Driver2.OemIdentificationType \ +Vehicle.Tachograph.Driver.Driver2.TimeRelatedStatus \ +Vehicle.Tachograph.Driver.Driver2.WorkingState \ +Vehicle.Tachograph.HandlingInformation \ +Vehicle.Tachograph.Performance \ +Vehicle.Tachograph.SystemEvent \ +Vehicle.Tachograph.VehicleSpeed \ +Vehicle.Trailer.IsConnected \ +Vehicle.TraveledDistance \ +Vehicle.TraveledDistanceHighRes \ +Vehicle.TraveledDistanceSinceStart \ +Vehicle.TripDuration \ +Vehicle.TripMeterReading \ +Vehicle.VehicleIdentification.AcrissCode \ +Vehicle.VehicleIdentification.BodyType \ +Vehicle.VehicleIdentification.Brand \ +Vehicle.VehicleIdentification.DateVehicleFirstRegistered \ +Vehicle.VehicleIdentification.KnownVehicleDamages \ +Vehicle.VehicleIdentification.MeetsEmissionStandard \ +Vehicle.VehicleIdentification.Model \ +Vehicle.VehicleIdentification.OptionalExtras \ +Vehicle.VehicleIdentification.ProductionDate \ +Vehicle.VehicleIdentification.PurchaseDate \ +Vehicle.VehicleIdentification.VIN \ +Vehicle.VehicleIdentification.VehicleConfiguration \ +Vehicle.VehicleIdentification.VehicleInteriorColor \ +Vehicle.VehicleIdentification.VehicleInteriorType \ +Vehicle.VehicleIdentification.VehicleModelDate \ +Vehicle.VehicleIdentification.VehicleSeatingCapacity \ +Vehicle.VehicleIdentification.VehicleSpecialUsage \ +Vehicle.VehicleIdentification.WMI \ +Vehicle.VehicleIdentification.Year \ +Vehicle.VersionVSS.Label \ +Vehicle.VersionVSS.Major \ +Vehicle.VersionVSS.Minor \ +Vehicle.VersionVSS.Patch \ +Vehicle.Width diff --git a/csv-provider/signalsFmsRecording.csv b/csv-provider/signalsFmsRecording.csv new file mode 100644 index 0000000..1d6c646 --- /dev/null +++ b/csv-provider/signalsFmsRecording.csv @@ -0,0 +1,705 @@ +field,signal,value,delay +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,67.19999694824219,0.0 +current,Vehicle.Powertrain.CombustionEngine.EngineHours,943.5,0.0 +current,Vehicle.Powertrain.Transmission.Type,UNKNOWN,0.0 +current,Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Level,62,0.0 +current,Vehicle.Cabin.SeatRowCount,2,0.0 +current,Vehicle.Powertrain.CombustionEngine.MaxTorque,0,0.0 +current,Vehicle.Powertrain.CombustionEngine.ECT,8,0.0 +current,Vehicle.Chassis.Wheelbase,0,0.0 +current,Vehicle.DirectionIndicator,Not available,0.0 +current,Vehicle.VersionVSS.Major,3,0.0 +current,Vehicle.Tachograph.Driver.Driver1.WorkingState,REST,0.0 +current,Vehicle.Chassis.Track,0,0.0 +current,Vehicle.IsMoving,False,0.0 +current,Vehicle.Cabin.DriverPosition,1,0.0 +current,Vehicle.Powertrain.ElectricMotor.MaxPower,0,0.0 +current,Vehicle.Powertrain.ElectricMotor.MaxTorque,0,0.0 +current,Vehicle.CurrentOverallWeight,655350,0.0 +current,Vehicle.Speed,0.0,0.0 +current,Vehicle.Chassis.AxleCount,2,0.0 +current,Vehicle.Width,0,0.0 +current,Vehicle.StartTime,0000-01-01T00:00Z,0.0 +current,Vehicle.IsOverspeed,False,0.0 +current,Vehicle.TraveledDistanceHighRes,54054555,0.0 +current,Vehicle.Powertrain.Transmission.DriveType,UNKNOWN,0.0 +current,Vehicle.Tachograph.Driver.Driver2.WorkingState,REST,0.0 +current,Vehicle.Tachograph.VehicleSpeed,0.0,0.0 +current,Vehicle.Powertrain.FuelSystem.HybridType,UNKNOWN,0.0 +current,Vehicle.Powertrain.CombustionEngine.AspirationType,UNKNOWN,0.0 +current,Vehicle.VersionVSS.Patch,1,0.0 +current,Vehicle.Powertrain.CombustionEngine.Speed,0,0.0 +current,Vehicle.GrossWeight,0,0.0 +current,Vehicle.Powertrain.ElectricMotor.MaxRegenPower,0,0.0 +current,Vehicle.Powertrain.ElectricMotor.MaxRegenTorque,0,0.0 +current,Vehicle.ADAS.CruiseControl.IsActive,False,0.0 +current,Vehicle.Chassis.SteeringWheel.Position,FRONT_LEFT,0.0 +current,Vehicle.VersionVSS.Minor,1,0.0 +current,Vehicle.Exterior.AirTemperature,10.5625,0.0 +current,Vehicle.Length,0,0.0 +current,Vehicle.Chassis.ParkingBrake.IsEngaged,True,0.0 +current,Vehicle.Cabin.DoorCount,4,0.0 +current,Vehicle.ADAS.CruiseControl.SpeedSet,255.0,0.0 +current,Vehicle.Powertrain.Transmission.GearCount,0,0.0 +current,Vehicle.Powertrain.CombustionEngine.MaxPower,0,0.0 +current,Vehicle.CurbWeight,0,0.0 +current,Vehicle.ADAS.CruiseControl.IsEnabled,True,0.0 +current,Vehicle.VehicleIdentification.VIN,87,0.0 +current,Vehicle.MaxTowBallWeight,0,0.0 +current,Vehicle.MaxTowWeight,0,0.0 +current,Vehicle.Height,0,0.0 +current,Vehicle.Powertrain.CombustionEngine.Configuration,UNKNOWN,0.0 +current,Vehicle.Powertrain.FuelSystem.Tank.Second.RelativeLevel,102.0,0.0 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,76.80000305175781,0.7383580207824707 +current,Vehicle.Exterior.AirTemperature,10.59375,0.6819970607757568 +current,Vehicle.Exterior.AirTemperature,10.625,0.9999392032623291 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,87.5999984741211,0.3188798427581787 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,1.0096988677978516 +current,Vehicle.Exterior.AirTemperature,10.65625,1.6732792854309082 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.0,0.3170478343963623 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.80000305175781,1.0011439323425293 +current,Vehicle.Exterior.AirTemperature,10.6875,0.685589075088501 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,95.19999694824219,0.3143138885498047 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,96.0,1.0020551681518555 +current,Vehicle.Exterior.AirTemperature,10.71875,0.6795239448547363 +current,Vehicle.CurrentOverallWeight,3820,0.04990696907043457 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,96.4000015258789,1.2683041095733643 +current,Vehicle.CurrentOverallWeight,655350,0.5214488506317139 +current,Vehicle.Exterior.AirTemperature,10.75,1.160055160522461 +current,Vehicle.Exterior.AirTemperature,10.78125,1.0025668144226074 +current,Vehicle.CurrentOverallWeight,3820,2.0483450889587402 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,96.80000305175781,0.26833581924438477 +current,Vehicle.Exterior.AirTemperature,10.8125,0.681826114654541 +current,Vehicle.CurrentOverallWeight,655350,0.8358230590820312 +current,Vehicle.CurrentOverallWeight,3820,1.2093899250030518 +current,Vehicle.CurrentOverallWeight,655350,1.7876629829406738 +current,Vehicle.Exterior.AirTemperature,10.84375,1.1660990715026855 +current,Vehicle.Powertrain.CombustionEngine.Speed,621,10.141195058822632 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,96.4000015258789,0.18018603324890137 +current,Vehicle.Powertrain.CombustionEngine.Speed,742,0.825098991394043 +current,Vehicle.CurrentOverallWeight,3820,0.9014279842376709 +current,Vehicle.Powertrain.CombustionEngine.Speed,706,0.11053800582885742 +current,Vehicle.Powertrain.CombustionEngine.Speed,699,1.0108668804168701 +current,Vehicle.CurrentOverallWeight,655350,0.6638660430908203 +current,Vehicle.Powertrain.CombustionEngine.Speed,681,0.3370089530944824 +current,Vehicle.Exterior.AirTemperature,10.875,0.8306879997253418 +current,Vehicle.CurrentOverallWeight,3820,0.047445058822631836 +current,Vehicle.Powertrain.CombustionEngine.Speed,698,0.13267207145690918 +current,Vehicle.Powertrain.CombustionEngine.Speed,702,1.0063278675079346 +current,Vehicle.Chassis.ParkingBrake.IsEngaged,False,0.2925839424133301 +current,Vehicle.CurrentOverallWeight,655350,0.35256409645080566 +current,Vehicle.Powertrain.CombustionEngine.Speed,701,0.3554260730743408 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,96.80000305175781,0.13505291938781738 +current,Vehicle.Exterior.AirTemperature,10.90625,0.6823821067810059 +current,Vehicle.CurrentOverallWeight,3820,0.04518580436706543 +current,Vehicle.Powertrain.CombustionEngine.Speed,700,0.13956809043884277 +current,Vehicle.CurrentOverallWeight,655350,1.6374988555908203 +current,Vehicle.Powertrain.CombustionEngine.Speed,719,1.378352165222168 +current,Vehicle.Powertrain.CombustionEngine.Speed,884,1.0000629425048828 +current,Vehicle.Speed,0.69921875,0.0014767646789550781 +current,Vehicle.Powertrain.CombustionEngine.Speed,893,0.3280520439147949 +current,Vehicle.Tachograph.VehicleSpeed,2.09765625,0.10811018943786621 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,96.0,0.0021729469299316406 +current,Vehicle.Speed,2.69921875,0.0008549690246582031 +current,Vehicle.Powertrain.CombustionEngine.Speed,911,0.3271799087524414 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,95.5999984741211,0.11259007453918457 +current,Vehicle.Tachograph.VehicleSpeed,2.8984375,0.05028796195983887 +current,Vehicle.Speed,3.19921875,0.0012102127075195312 +current,Vehicle.Powertrain.CombustionEngine.Speed,905,0.23359179496765137 +current,Vehicle.Tachograph.VehicleSpeed,3.19921875,0.19839787483215332 +current,Vehicle.Speed,3.09765625,0.001603841781616211 +current,Vehicle.Exterior.AirTemperature,10.9375,0.015481948852539062 +current,Vehicle.Powertrain.CombustionEngine.Speed,890,0.2282402515411377 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.80000305175781,0.09221076965332031 +current,Vehicle.Tachograph.VehicleSpeed,2.8984375,0.14809894561767578 +current,Vehicle.Speed,2.796875,0.0008661746978759766 +current,Vehicle.Powertrain.CombustionEngine.Speed,889,0.16022181510925293 +current,Vehicle.Tachograph.Driver.Driver1.WorkingState,DRIVE,0.2729310989379883 +current,Vehicle.Tachograph.Driver.Driver2.WorkingState,DRIVER_AVAILABLE,0.0018877983093261719 +current,Vehicle.IsMoving,True,0.002504110336303711 +current,Vehicle.Tachograph.VehicleSpeed,2.69921875,0.0054819583892822266 +current,Vehicle.Speed,2.5,0.0017871856689453125 +current,Vehicle.Powertrain.CombustionEngine.Speed,886,0.16577887535095215 +current,Vehicle.TraveledDistanceHighRes,54054560,0.08013796806335449 +current,Vehicle.Tachograph.VehicleSpeed,2.5,0.23806214332580566 +current,Vehicle.Speed,2.3984375,0.002362966537475586 +current,Vehicle.Powertrain.CombustionEngine.Speed,887,0.06408810615539551 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,95.19999694824219,0.07245302200317383 +current,Vehicle.Tachograph.VehicleSpeed,2.3984375,0.2978498935699463 +current,Vehicle.CurrentOverallWeight,3820,0.43006420135498047 +current,Vehicle.Speed,2.296875,0.0023958683013916016 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,95.5999984741211,0.13822197914123535 +current,Vehicle.Tachograph.VehicleSpeed,2.19921875,0.34323620796203613 +current,Vehicle.Speed,2.09765625,0.0011930465698242188 +current,Vehicle.Powertrain.CombustionEngine.Speed,881,0.07229900360107422 +current,Vehicle.Tachograph.VehicleSpeed,1.796875,0.4138479232788086 +current,Vehicle.CurrentOverallWeight,655350,0.15337395668029785 +current,Vehicle.Speed,1.59765625,0.0012309551239013672 +current,Vehicle.Powertrain.CombustionEngine.Speed,888,0.0866999626159668 +current,Vehicle.Tachograph.VehicleSpeed,1.5,0.3939502239227295 +current,Vehicle.Powertrain.CombustionEngine.ECT,9,0.3796117305755615 +current,Vehicle.CurrentOverallWeight,3820,0.004132270812988281 +current,Vehicle.Powertrain.CombustionEngine.Speed,887,0.22783160209655762 +current,Vehicle.Tachograph.VehicleSpeed,1.59765625,0.4390714168548584 +current,Vehicle.Powertrain.CombustionEngine.Speed,878,0.561302661895752 +current,Vehicle.Speed,1.796875,0.0016169548034667969 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.80000305175781,0.03970789909362793 +current,Vehicle.Tachograph.VehicleSpeed,1.796875,0.44544410705566406 +current,Vehicle.CurrentOverallWeight,655350,0.054894208908081055 +current,Vehicle.Exterior.AirTemperature,10.96875,0.1764688491821289 +current,Vehicle.Powertrain.CombustionEngine.Speed,884,0.288585901260376 +current,Vehicle.Speed,1.69921875,0.0011591911315917969 +current,Vehicle.Tachograph.VehicleSpeed,1.296875,0.43255615234375 +current,Vehicle.CurrentOverallWeight,3820,0.23528504371643066 +current,Vehicle.Powertrain.CombustionEngine.Speed,707,0.23934173583984375 +current,Vehicle.Speed,1.09765625,0.0017728805541992188 +current,Vehicle.Tachograph.VehicleSpeed,0.796875,0.33138513565063477 +current,Vehicle.Powertrain.CombustionEngine.Speed,700,0.47505879402160645 +current,Vehicle.Speed,0.5,0.0016248226165771484 +current,Vehicle.CurrentOverallWeight,655350,0.24329113960266113 +current,Vehicle.Tachograph.VehicleSpeed,0.3984375,0.04243898391723633 +current,Vehicle.Exterior.AirTemperature,11.0,0.1356220245361328 +current,Vehicle.Powertrain.CombustionEngine.Speed,699,0.29403090476989746 +current,Vehicle.Speed,0.19921875,0.000985860824584961 +current,Vehicle.Tachograph.Driver.Driver1.WorkingState,WORK,0.32655811309814453 +current,Vehicle.IsMoving,False,0.0025429725646972656 +current,Vehicle.Tachograph.VehicleSpeed,0.19921875,0.006002902984619141 +current,Vehicle.CurrentOverallWeight,3820,0.13102507591247559 +current,Vehicle.Powertrain.CombustionEngine.Speed,716,0.2521958351135254 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.4000015258789,0.023476362228393555 +current,Vehicle.Speed,0.59765625,0.00203704833984375 +current,Vehicle.Tachograph.VehicleSpeed,0.59765625,0.23144769668579102 +current,Vehicle.Powertrain.CombustionEngine.Speed,885,0.38185811042785645 +current,Vehicle.Speed,0.296875,0.0008902549743652344 +current,Vehicle.CurrentOverallWeight,655350,0.035843849182128906 +current,Vehicle.Tachograph.VehicleSpeed,1.09765625,0.1481761932373047 +current,Vehicle.Powertrain.CombustionEngine.Speed,898,0.342911958694458 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.0,0.011858940124511719 +current,Vehicle.TraveledDistanceHighRes,54054565,0.007472991943359375 +current,Vehicle.Speed,3.19921875,0.001024007797241211 +current,Vehicle.Tachograph.VehicleSpeed,3.09765625,0.08425092697143555 +current,Vehicle.Powertrain.CombustionEngine.Speed,904,0.3567378520965576 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.4000015258789,0.0015749931335449219 +current,Vehicle.Speed,3.69921875,0.0012359619140625 +current,Vehicle.Tachograph.VehicleSpeed,3.69921875,0.08728218078613281 +current,Vehicle.Powertrain.CombustionEngine.Speed,918,0.36405491828918457 +current,Vehicle.Tachograph.VehicleSpeed,3.8984375,0.6423459053039551 +current,Vehicle.Speed,3.8984375,0.0014989376068115234 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,95.19999694824219,0.33820581436157227 +current,Vehicle.Speed,3.59765625,0.0012390613555908203 +current,Vehicle.Tachograph.Driver.Driver1.WorkingState,DRIVE,0.026269912719726562 +current,Vehicle.IsMoving,True,0.002785205841064453 +current,Vehicle.Tachograph.VehicleSpeed,3.59765625,0.004136085510253906 +current,Vehicle.Powertrain.CombustionEngine.ECT,10,0.023540019989013672 +current,Vehicle.CurrentOverallWeight,3820,0.00569605827331543 +current,Vehicle.Powertrain.CombustionEngine.Speed,894,0.3009829521179199 +current,Vehicle.Speed,3.09765625,0.0019330978393554688 +current,Vehicle.Exterior.AirTemperature,11.03125,0.008881807327270508 +current,Vehicle.Tachograph.VehicleSpeed,3.0,0.06569290161132812 +current,Vehicle.TraveledDistanceHighRes,54054570,0.2682969570159912 +current,Vehicle.Powertrain.CombustionEngine.Speed,879,0.01494598388671875 +current,Vehicle.CurrentOverallWeight,655350,0.4639289379119873 +current,Vehicle.Tachograph.VehicleSpeed,2.59765625,0.2502739429473877 +current,Vehicle.Speed,2.59765625,0.0007650852203369141 +current,Vehicle.Powertrain.CombustionEngine.Speed,876,0.27129387855529785 +current,Vehicle.CurrentOverallWeight,3820,0.6989810466766357 +current,Vehicle.Speed,3.0,0.0028808116912841797 +current,Vehicle.Tachograph.VehicleSpeed,3.19921875,0.03001689910888672 +current,Vehicle.Powertrain.CombustionEngine.Speed,885,0.23520517349243164 +current,Vehicle.Speed,4.69921875,0.0010919570922851562 +current,Vehicle.Tachograph.VehicleSpeed,5.19921875,0.03149008750915527 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.80000305175781,0.2088639736175537 +current,Vehicle.Powertrain.CombustionEngine.Speed,894,0.03818702697753906 +current,Vehicle.CurrentOverallWeight,655350,0.45630884170532227 +current,Vehicle.Tachograph.VehicleSpeed,6.3984375,0.30019307136535645 +current,Vehicle.Speed,6.3984375,0.0013930797576904297 +current,Vehicle.Powertrain.CombustionEngine.Speed,976,0.18883705139160156 +current,Vehicle.Tachograph.VehicleSpeed,5.296875,0.7904889583587646 +current,Vehicle.Speed,5.296875,0.0015540122985839844 +current,Vehicle.TraveledDistanceHighRes,54054575,0.04601693153381348 +current,Vehicle.Powertrain.CombustionEngine.Speed,787,0.04596829414367676 +current,Vehicle.Tachograph.VehicleSpeed,4.8984375,0.7895348072052002 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.4000015258789,0.15499401092529297 +current,Vehicle.Powertrain.CombustionEngine.Speed,776,0.05765819549560547 +current,Vehicle.Speed,4.8984375,0.0009930133819580078 +current,Vehicle.Tachograph.VehicleSpeed,5.09765625,0.8321762084960938 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.0,0.10718178749084473 +current,Vehicle.Powertrain.CombustionEngine.Speed,832,0.05721306800842285 +current,Vehicle.Speed,5.19921875,0.0010890960693359375 +current,Vehicle.Exterior.AirTemperature,11.0,0.617372989654541 +current,Vehicle.Tachograph.VehicleSpeed,5.8984375,0.2638702392578125 +current,Vehicle.Powertrain.CombustionEngine.Speed,935,0.11565780639648438 +current,Vehicle.Speed,5.8984375,0.0018138885498046875 +current,Vehicle.Exterior.AirTemperature,11.03125,0.6164901256561279 +current,Vehicle.Tachograph.VehicleSpeed,6.296875,0.2642538547515869 +current,Vehicle.TraveledDistanceHighRes,54054580,0.06010627746582031 +current,Vehicle.Powertrain.CombustionEngine.Speed,973,0.05923199653625488 +current,Vehicle.Speed,6.19921875,0.0022859573364257812 +current,Vehicle.Tachograph.VehicleSpeed,6.69921875,0.8325879573822021 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,93.5999984741211,0.003412008285522461 +current,Vehicle.Powertrain.CombustionEngine.Speed,1047,0.07848119735717773 +current,Vehicle.Speed,6.69921875,0.0021772384643554688 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,93.19999694824219,0.7398109436035156 +current,Vehicle.TraveledDistanceHighRes,54054585,0.008111000061035156 +current,Vehicle.Tachograph.VehicleSpeed,7.0,0.0309600830078125 +current,Vehicle.Powertrain.CombustionEngine.Speed,1099,0.03488802909851074 +current,Vehicle.Speed,7.09765625,0.002151966094970703 +current,Vehicle.Powertrain.CombustionEngine.ECT,11,0.45639705657958984 +current,Vehicle.Tachograph.VehicleSpeed,7.5,0.3303689956665039 +current,Vehicle.Powertrain.CombustionEngine.Speed,1190,0.03701496124267578 +current,Vehicle.Speed,7.69921875,0.0015943050384521484 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,93.5999984741211,0.7393028736114502 +current,Vehicle.TraveledDistanceHighRes,54054590,0.007004976272583008 +current,Vehicle.Tachograph.VehicleSpeed,8.69921875,0.0833730697631836 +current,Vehicle.Powertrain.CombustionEngine.Speed,1364,0.0012631416320800781 +current,Vehicle.Speed,8.796875,0.0015192031860351562 +current,Vehicle.Tachograph.VehicleSpeed,9.796875,0.7368869781494141 +current,Vehicle.Powertrain.CombustionEngine.Speed,1539,0.0016169548034667969 +current,Vehicle.Speed,10.0,0.0008578300476074219 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.0,0.5417680740356445 +current,Vehicle.Tachograph.VehicleSpeed,10.796875,0.09314918518066406 +current,Vehicle.Powertrain.CombustionEngine.Speed,1689,0.010814905166625977 +current,Vehicle.Speed,10.8984375,0.0012280941009521484 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.4000015258789,0.5419900417327881 +current,Vehicle.TraveledDistanceHighRes,54054595,0.006731748580932617 +current,Vehicle.Tachograph.VehicleSpeed,11.296875,0.08631086349487305 +current,Vehicle.Powertrain.CombustionEngine.Speed,1300,0.02112603187561035 +current,Vehicle.Speed,10.59765625,0.001024007797241211 +current,Vehicle.TraveledDistanceHighRes,54054600,0.44983792304992676 +current,Vehicle.Tachograph.VehicleSpeed,13.0,0.08813214302062988 +current,Vehicle.Powertrain.CombustionEngine.Speed,1128,0.017880916595458984 +current,Vehicle.Speed,14.09765625,0.0015521049499511719 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.80000305175781,0.34066104888916016 +current,Vehicle.TraveledDistanceHighRes,54054605,0.004690885543823242 +current,Vehicle.Powertrain.CombustionEngine.Speed,1295,0.12004590034484863 +current,Vehicle.Tachograph.VehicleSpeed,15.09765625,0.014774084091186523 +current,Vehicle.Speed,15.69921875,0.002371072769165039 +current,Vehicle.Powertrain.CombustionEngine.Speed,1386,0.37176990509033203 +current,Vehicle.Tachograph.VehicleSpeed,16.19921875,0.006940126419067383 +current,Vehicle.CurrentOverallWeight,3820,0.5853369235992432 +current,Vehicle.Speed,16.59765625,0.004261970520019531 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.4000015258789,0.1323070526123047 +current,Vehicle.TraveledDistanceHighRes,54054610,0.006410121917724609 +current,Vehicle.Powertrain.CombustionEngine.Speed,1453,0.1285710334777832 +current,Vehicle.Tachograph.VehicleSpeed,17.0,0.06127214431762695 +current,Vehicle.Speed,17.5,0.00019502639770507812 +current,Vehicle.TraveledDistanceHighRes,54054615,0.049861907958984375 +current,Vehicle.Powertrain.CombustionEngine.Speed,1502,0.1385350227355957 +current,Vehicle.Tachograph.VehicleSpeed,17.59765625,0.10028314590454102 +current,Vehicle.CurrentOverallWeight,655350,0.23720383644104004 +current,Vehicle.Exterior.AirTemperature,11.0,0.1946570873260498 +current,Vehicle.Powertrain.CombustionEngine.ECT,12,0.04427814483642578 +current,Vehicle.Speed,17.796875,0.0014548301696777344 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.0,0.04323101043701172 +current,Vehicle.TraveledDistanceHighRes,54054620,0.005012989044189453 +current,Vehicle.Powertrain.CombustionEngine.Speed,1428,0.13879704475402832 +current,Vehicle.Tachograph.VehicleSpeed,16.796875,0.14538288116455078 +current,Vehicle.Speed,15.3984375,0.0015232563018798828 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,93.5999984741211,0.041240692138671875 +current,Vehicle.Powertrain.CombustionEngine.Speed,1223,0.15019536018371582 +current,Vehicle.Tachograph.VehicleSpeed,14.09765625,0.1414027214050293 +current,Vehicle.TraveledDistanceHighRes,54054630,0.7146050930023193 +current,Vehicle.Speed,12.5,0.0017039775848388672 +current,Vehicle.Powertrain.CombustionEngine.Speed,1016,0.08925294876098633 +current,Vehicle.Tachograph.VehicleSpeed,11.69921875,0.19854426383972168 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,91.19999694824219,0.6506989002227783 +current,Vehicle.Powertrain.CombustionEngine.Speed,890,0.15473389625549316 +current,Vehicle.Speed,10.59765625,0.0012547969818115234 +current,Vehicle.Tachograph.VehicleSpeed,10.296875,0.18987131118774414 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.80000305175781,0.6540536880493164 +current,Vehicle.TraveledDistanceHighRes,54054635,0.003789186477661133 +current,Vehicle.Powertrain.CombustionEngine.Speed,1495,0.15656805038452148 +current,Vehicle.Speed,9.19921875,0.001585245132446289 +current,Vehicle.Tachograph.VehicleSpeed,9.09765625,0.09042572975158691 +current,Vehicle.TraveledDistanceHighRes,54054640,0.657642126083374 +current,Vehicle.Powertrain.CombustionEngine.Speed,1243,0.16656017303466797 +current,Vehicle.Speed,8.0,0.0016791820526123047 +current,Vehicle.Tachograph.VehicleSpeed,7.8984375,0.08705282211303711 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,0.6557328701019287 +current,Vehicle.Powertrain.CombustionEngine.Speed,1340,0.1829981803894043 +current,Vehicle.Speed,8.3984375,0.0012900829315185547 +current,Vehicle.Tachograph.VehicleSpeed,8.796875,0.13250303268432617 +current,Vehicle.CurrentOverallWeight,5580,0.33353710174560547 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.80000305175781,0.27937889099121094 +current,Vehicle.Powertrain.CombustionEngine.Speed,1528,0.1942429542541504 +current,Vehicle.Speed,9.69921875,0.0007071495056152344 +current,Vehicle.Tachograph.VehicleSpeed,9.8984375,0.13566279411315918 +current,Vehicle.TraveledDistanceHighRes,54054645,0.6122009754180908 +current,Vehicle.Powertrain.CombustionEngine.Speed,1769,0.19068217277526855 +current,Vehicle.Speed,11.296875,0.0015330314636230469 +current,Vehicle.Tachograph.VehicleSpeed,11.5,0.0827329158782959 +current,Vehicle.CurrentOverallWeight,17200,0.039895057678222656 +current,Vehicle.Powertrain.CombustionEngine.ECT,13,0.23709702491760254 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,92.4000015258789,0.2798590660095215 +current,Vehicle.Powertrain.CombustionEngine.Speed,1363,0.20308589935302734 +current,Vehicle.Speed,11.3984375,0.0026009082794189453 +current,Vehicle.Tachograph.VehicleSpeed,11.8984375,0.030658245086669922 +current,Vehicle.CurrentOverallWeight,5580,0.23506879806518555 +current,Vehicle.TraveledDistanceHighRes,54054655,0.2813100814819336 +current,Vehicle.Powertrain.CombustionEngine.Speed,1242,0.19930100440979004 +current,Vehicle.Speed,14.796875,0.0019080638885498047 +current,Vehicle.Tachograph.VehicleSpeed,15.09765625,0.08203911781311035 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,93.5999984741211,0.45812368392944336 +current,Vehicle.Powertrain.CombustionEngine.Speed,1437,0.21481537818908691 +current,Vehicle.CurrentOverallWeight,17200,0.2674696445465088 +current,Vehicle.Tachograph.VehicleSpeed,17.296875,0.06383323669433594 +current,Vehicle.Speed,17.19921875,0.0014789104461669922 +current,Vehicle.TraveledDistanceHighRes,54054660,0.44665098190307617 +current,Vehicle.Powertrain.CombustionEngine.Speed,1551,0.21040892601013184 +current,Vehicle.Tachograph.VehicleSpeed,18.296875,0.37323784828186035 +current,Vehicle.Speed,18.19921875,0.002849102020263672 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,94.80000305175781,0.33446288108825684 +current,Vehicle.Powertrain.CombustionEngine.Speed,1563,0.22094011306762695 +current,Vehicle.Speed,18.3984375,0.0015728473663330078 +current,Vehicle.TraveledDistanceHighRes,54054670,0.34105706214904785 +current,Vehicle.Powertrain.CombustionEngine.Speed,1551,0.2173318862915039 +current,Vehicle.Tachograph.VehicleSpeed,18.09765625,0.36820197105407715 +current,Vehicle.Exterior.AirTemperature,11.03125,0.09152102470397949 +current,Vehicle.Speed,18.09765625,0.0015921592712402344 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,93.5999984741211,0.23827099800109863 +current,Vehicle.TraveledDistanceHighRes,54054675,0.0060427188873291016 +current,Vehicle.Powertrain.CombustionEngine.Speed,1447,0.21979117393493652 +current,Vehicle.Tachograph.VehicleSpeed,16.5,0.41382598876953125 +current,Vehicle.Powertrain.CombustionEngine.ECT,14,0.0777730941772461 +current,Vehicle.CurrentOverallWeight,5580,0.006914854049682617 +current,Vehicle.Speed,16.296875,0.002271890640258789 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,92.4000015258789,0.13785696029663086 +current,Vehicle.TraveledDistanceHighRes,54054680,0.003938913345336914 +current,Vehicle.Powertrain.CombustionEngine.Speed,1328,0.22702622413635254 +current,Vehicle.Tachograph.VehicleSpeed,15.09765625,0.41236305236816406 +current,Vehicle.Exterior.AirTemperature,11.0625,0.030163049697875977 +current,Vehicle.Speed,14.796875,0.0011959075927734375 +current,Vehicle.Powertrain.CombustionEngine.Speed,1211,0.28710412979125977 +current,Vehicle.CurrentOverallWeight,17200,0.23264265060424805 +current,Vehicle.Tachograph.VehicleSpeed,13.8984375,0.20988225936889648 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.80000305175781,0.31217002868652344 +current,Vehicle.TraveledDistanceHighRes,54054690,0.004051923751831055 +current,Vehicle.Speed,13.69921875,0.0012149810791015625 +current,Vehicle.Powertrain.CombustionEngine.Speed,1150,0.18679213523864746 +current,Vehicle.Exterior.AirTemperature,11.09375,0.4325718879699707 +current,Vehicle.Tachograph.VehicleSpeed,13.296875,0.009256839752197266 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,0.3497002124786377 +current,Vehicle.TraveledDistanceHighRes,54054695,0.028751850128173828 +current,Vehicle.Speed,13.09765625,0.017546892166137695 +current,Vehicle.Powertrain.CombustionEngine.Speed,1100,0.11982893943786621 +current,Vehicle.Tachograph.VehicleSpeed,12.796875,0.4978311061859131 +current,Vehicle.Speed,12.8984375,0.0018911361694335938 +current,Vehicle.Powertrain.CombustionEngine.Speed,1086,0.10384702682495117 +current,Vehicle.Tachograph.VehicleSpeed,12.69921875,0.5296599864959717 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,89.5999984741211,0.20343804359436035 +current,Vehicle.TraveledDistanceHighRes,54054700,0.008065938949584961 +current,Vehicle.Speed,12.69921875,0.0007729530334472656 +current,Vehicle.Powertrain.CombustionEngine.Speed,1081,0.1031179428100586 +current,Vehicle.Exterior.AirTemperature,11.125,0.41303086280822754 +current,Vehicle.Tachograph.VehicleSpeed,12.8984375,0.11822223663330078 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,89.19999694824219,0.20177292823791504 +current,Vehicle.TraveledDistanceHighRes,54054705,0.006921052932739258 +current,Vehicle.Speed,12.8984375,0.0004818439483642578 +current,Vehicle.Powertrain.CombustionEngine.Speed,1115,0.004555225372314453 +current,Vehicle.Powertrain.CombustionEngine.ECT,15,0.452150821685791 +current,Vehicle.Tachograph.VehicleSpeed,13.3984375,0.0785529613494873 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,88.80000305175781,0.20416927337646484 +current,Vehicle.Powertrain.CombustionEngine.Speed,1199,0.27753186225891113 +current,Vehicle.Speed,13.796875,0.0015132427215576172 +current,Vehicle.Exterior.AirTemperature,11.15625,0.31995582580566406 +current,Vehicle.Tachograph.VehicleSpeed,14.59765625,0.16267704963684082 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,88.4000015258789,0.15767502784729004 +current,Vehicle.TraveledDistanceHighRes,54054710,0.006272077560424805 +current,Vehicle.Powertrain.CombustionEngine.Speed,1289,0.27903199195861816 +current,Vehicle.Speed,14.8984375,0.0013871192932128906 +current,Vehicle.Tachograph.VehicleSpeed,15.5,0.5315561294555664 +current,Vehicle.TraveledDistanceHighRes,54054715,0.11374974250793457 +current,Vehicle.Powertrain.CombustionEngine.Speed,1375,0.28232908248901367 +current,Vehicle.Speed,16.09765625,0.0010318756103515625 +current,Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Level,63,0.12099695205688477 +current,Vehicle.Tachograph.VehicleSpeed,16.796875,0.31835508346557617 +current,Vehicle.Powertrain.CombustionEngine.Speed,1485,0.3976719379425049 +current,Vehicle.Speed,17.5,0.0012729167938232422 +current,Vehicle.Exterior.AirTemperature,11.1875,0.11626410484313965 +current,Vehicle.Tachograph.VehicleSpeed,18.09765625,0.2652249336242676 +current,Vehicle.TraveledDistanceHighRes,54054725,0.06413006782531738 +current,Vehicle.Powertrain.CombustionEngine.Speed,1588,0.28818821907043457 +current,Vehicle.Speed,18.69921875,0.0017590522766113281 +current,Vehicle.Tachograph.VehicleSpeed,19.09765625,0.27953505516052246 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,89.19999694824219,0.06116771697998047 +current,Vehicle.TraveledDistanceHighRes,54054730,0.0044023990631103516 +current,Vehicle.Powertrain.CombustionEngine.Speed,1626,0.2983410358428955 +current,Vehicle.Speed,19.0,0.0007238388061523438 +current,Vehicle.Tachograph.VehicleSpeed,18.8984375,0.23466825485229492 +current,Vehicle.Powertrain.CombustionEngine.Speed,1610,0.32489585876464844 +current,Vehicle.Tachograph.VehicleSpeed,18.796875,0.6739799976348877 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,89.5999984741211,0.00911712646484375 +current,Vehicle.TraveledDistanceHighRes,54054740,0.0056340694427490234 +current,Vehicle.Powertrain.CombustionEngine.Speed,1615,0.318803071975708 +current,Vehicle.Exterior.AirTemperature,11.21875,0.35190606117248535 +current,Vehicle.Tachograph.VehicleSpeed,19.09765625,0.31675291061401367 +current,Vehicle.Powertrain.CombustionEngine.Speed,1627,0.33976316452026367 +current,Vehicle.Powertrain.CombustionEngine.ECT,16,0.3847050666809082 +current,Vehicle.Speed,19.09765625,0.0014340877532958984 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.0,0.14169812202453613 +current,Vehicle.TraveledDistanceHighRes,54054750,0.0050487518310546875 +current,Vehicle.Tachograph.VehicleSpeed,19.5,0.03534579277038574 +current,Vehicle.Exterior.AirTemperature,11.25,0.634796142578125 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,0.325131893157959 +current,Vehicle.Tachograph.VehicleSpeed,19.0,0.04378390312194824 +current,Vehicle.Powertrain.CombustionEngine.Speed,1622,0.30494117736816406 +current,Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Level,62,0.22219491004943848 +current,Vehicle.CurrentOverallWeight,5400,0.15093088150024414 +current,Vehicle.TraveledDistanceHighRes,54054760,0.2799971103668213 +current,Vehicle.Speed,18.8984375,0.0017330646514892578 +current,Vehicle.Tachograph.VehicleSpeed,18.8984375,0.03194284439086914 +current,Vehicle.Powertrain.CombustionEngine.Speed,1606,0.266071081161499 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.0,0.6436500549316406 +current,Vehicle.Speed,18.69921875,0.0011408329010009766 +current,Vehicle.Tachograph.VehicleSpeed,18.59765625,0.03494405746459961 +current,Vehicle.Powertrain.CombustionEngine.Speed,1578,0.27277612686157227 +current,Vehicle.CurrentOverallWeight,17200,0.10440897941589355 +current,Vehicle.Exterior.AirTemperature,11.28125,0.20726704597473145 +current,Vehicle.TraveledDistanceHighRes,54054775,0.33029603958129883 +current,Vehicle.Tachograph.VehicleSpeed,18.19921875,0.08649706840515137 +current,Vehicle.Speed,18.19921875,0.001329183578491211 +current,Vehicle.Powertrain.CombustionEngine.Speed,1563,0.21193766593933105 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,0.6275832653045654 +current,Vehicle.Speed,18.3984375,0.0015909671783447266 +current,Vehicle.Powertrain.CombustionEngine.Speed,1575,0.2151651382446289 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.80000305175781,0.6247859001159668 +current,Vehicle.TraveledDistanceHighRes,54054785,0.0040509700775146484 +current,Vehicle.Tachograph.VehicleSpeed,18.5,0.1413421630859375 +current,Vehicle.Speed,18.5,0.0014297962188720703 +current,Vehicle.Powertrain.CombustionEngine.Speed,1582,0.11719107627868652 +current,Vehicle.TraveledDistanceHighRes,54054790,0.6284329891204834 +current,Vehicle.Tachograph.VehicleSpeed,18.69921875,0.18454194068908691 +current,Vehicle.Speed,18.59765625,0.0015659332275390625 +current,Vehicle.Powertrain.CombustionEngine.Speed,1572,0.022942066192626953 +current,Vehicle.Exterior.AirTemperature,11.3125,0.29258108139038086 +current,Vehicle.TraveledDistanceHighRes,54054795,0.32978272438049316 +current,Vehicle.Tachograph.VehicleSpeed,18.0,0.2297992706298828 +current,Vehicle.Powertrain.CombustionEngine.Speed,1537,0.14668798446655273 +current,Vehicle.Speed,18.09765625,0.0018239021301269531 +current,Vehicle.Powertrain.CombustionEngine.ECT,17,0.2604360580444336 +current,Vehicle.Tachograph.VehicleSpeed,17.69921875,0.5694351196289062 +current,Vehicle.Powertrain.CombustionEngine.Speed,1512,0.09535384178161621 +current,Vehicle.Speed,17.69921875,0.0016758441925048828 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,0.4410061836242676 +current,Vehicle.TraveledDistanceHighRes,54054805,0.004380941390991211 +current,Vehicle.Tachograph.VehicleSpeed,17.59765625,0.3323960304260254 +current,Vehicle.Powertrain.CombustionEngine.Speed,1506,0.05555462837219238 +current,Vehicle.Speed,17.59765625,0.0014579296112060547 +current,Vehicle.CurrentOverallWeight,5400,0.06596183776855469 +current,Vehicle.TraveledDistanceHighRes,54054810,0.28214406967163086 +current,Vehicle.Tachograph.VehicleSpeed,17.796875,0.33318090438842773 +current,Vehicle.Powertrain.CombustionEngine.Speed,1511,0.05199003219604492 +current,Vehicle.Speed,17.796875,0.0026972293853759766 +current,Vehicle.Exterior.AirTemperature,11.34375,0.01057887077331543 +current,Vehicle.TraveledDistanceHighRes,54054815,0.3317687511444092 +current,Vehicle.Tachograph.VehicleSpeed,18.09765625,0.33681392669677734 +current,Vehicle.Powertrain.CombustionEngine.Speed,1540,0.05259394645690918 +current,Vehicle.CurrentOverallWeight,17200,0.07027196884155273 +current,Vehicle.Exterior.AirTemperature,11.3125,0.20757603645324707 +current,Vehicle.Speed,18.0,0.0023789405822753906 +current,Vehicle.Tachograph.VehicleSpeed,18.5,0.6321201324462891 +current,Vehicle.Powertrain.CombustionEngine.Speed,1583,0.01173090934753418 +current,Vehicle.CurrentOverallWeight,5400,0.32132387161254883 +current,Vehicle.Speed,18.796875,0.0015759468078613281 +current,Vehicle.TraveledDistanceHighRes,54054825,0.14621520042419434 +current,Vehicle.Tachograph.VehicleSpeed,19.5,0.38872289657592773 +current,Vehicle.Powertrain.CombustionEngine.Speed,1674,0.020132064819335938 +current,Vehicle.Powertrain.CombustionEngine.ECT,18,0.2996091842651367 +current,Vehicle.Speed,19.796875,0.0013387203216552734 +current,Vehicle.TraveledDistanceHighRes,54054830,0.1469581127166748 +current,Vehicle.Powertrain.CombustionEngine.Speed,1705,0.40775609016418457 +current,Vehicle.Tachograph.VehicleSpeed,20.0,0.02786707878112793 +current,Vehicle.CurrentOverallWeight,17200,0.022166013717651367 +current,Vehicle.Speed,19.8984375,0.0021669864654541016 +current,Vehicle.TraveledDistanceHighRes,54054835,0.14214396476745605 +current,Vehicle.Powertrain.CombustionEngine.Speed,1700,0.4153718948364258 +current,Vehicle.Tachograph.VehicleSpeed,19.796875,0.025304079055786133 +current,Vehicle.Exterior.AirTemperature,11.34375,0.22556090354919434 +current,Vehicle.CurrentOverallWeight,5400,0.05125308036804199 +current,Vehicle.Speed,20.09765625,0.0011458396911621094 +current,Vehicle.Powertrain.CombustionEngine.Speed,1710,0.4706580638885498 +current,Vehicle.Tachograph.VehicleSpeed,20.0,0.06233716011047363 +current,Vehicle.Speed,20.296875,0.0013871192932128906 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.0,0.0416259765625 +current,Vehicle.TraveledDistanceHighRes,54054845,0.005116939544677734 +current,Vehicle.Powertrain.CombustionEngine.Speed,1734,0.43102598190307617 +current,Vehicle.CurrentOverallWeight,17200,0.022881031036376953 +current,Vehicle.Tachograph.VehicleSpeed,20.3984375,0.08124303817749023 +current,Vehicle.Exterior.AirTemperature,11.375,0.13380098342895508 +current,Vehicle.Speed,20.796875,0.002431154251098633 +current,Vehicle.Powertrain.CombustionEngine.Speed,1283,0.38282012939453125 +current,Vehicle.Tachograph.VehicleSpeed,20.09765625,0.1061408519744873 +current,Vehicle.Exterior.AirTemperature,11.40625,0.12988591194152832 +current,Vehicle.CurrentOverallWeight,5400,0.0444490909576416 +current,Vehicle.TraveledDistanceHighRes,54054855,0.28026795387268066 +current,Vehicle.Powertrain.CombustionEngine.Speed,1094,0.4401540756225586 +current,Vehicle.Tachograph.VehicleSpeed,21.8984375,0.1453251838684082 +current,Vehicle.Speed,22.19921875,0.0018219947814941406 +current,Vehicle.Powertrain.CombustionEngine.Speed,1133,0.19396281242370605 +current,Vehicle.CurrentOverallWeight,17200,0.008945941925048828 +current,Vehicle.Tachograph.VehicleSpeed,22.69921875,0.18278193473815918 +current,Vehicle.Exterior.AirTemperature,11.4375,0.033463239669799805 +current,Vehicle.Powertrain.CombustionEngine.ECT,19,0.03913593292236328 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,0.2846078872680664 +current,Vehicle.TraveledDistanceHighRes,54054870,0.007129192352294922 +current,Vehicle.Speed,23.0,0.0020661354064941406 +current,Vehicle.Powertrain.CombustionEngine.Speed,1184,0.19898414611816406 +current,Vehicle.CurrentOverallWeight,7600,0.0049097537994384766 +current,Vehicle.Tachograph.VehicleSpeed,23.5,0.17754793167114258 +current,Vehicle.Exterior.AirTemperature,11.46875,0.041350364685058594 +current,Vehicle.Speed,24.19921875,0.0018298625946044922 +current,Vehicle.Powertrain.CombustionEngine.Speed,1234,0.10636591911315918 +current,Vehicle.Tachograph.VehicleSpeed,24.5,0.1783311367034912 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,91.19999694824219,0.3604738712310791 +current,Vehicle.TraveledDistanceHighRes,54054880,0.004269123077392578 +current,Vehicle.Speed,24.69921875,0.001795053482055664 +current,Vehicle.Powertrain.CombustionEngine.Speed,1249,0.10614991188049316 +current,Vehicle.Tachograph.VehicleSpeed,24.8984375,0.22753000259399414 +current,Vehicle.Speed,25.296875,0.0011610984802246094 +current,Vehicle.Powertrain.CombustionEngine.Speed,1281,0.016552209854125977 +current,Vehicle.Exterior.AirTemperature,11.5,0.2030317783355713 +current,Vehicle.Tachograph.VehicleSpeed,25.69921875,0.010630130767822266 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,91.5999984741211,0.3105769157409668 +current,Vehicle.TraveledDistanceHighRes,54054895,0.003717184066772461 +current,Vehicle.Speed,25.796875,0.0018661022186279297 +current,Vehicle.Powertrain.CombustionEngine.Speed,1292,0.021852970123291016 +current,Vehicle.Tachograph.VehicleSpeed,25.8984375,0.21177315711975098 +current,Vehicle.TraveledDistanceHighRes,54054905,0.3097507953643799 +current,Vehicle.Powertrain.CombustionEngine.Speed,1302,0.4890151023864746 +current,Vehicle.Speed,26.8984375,0.0012989044189453125 +current,Vehicle.Tachograph.VehicleSpeed,26.09765625,0.17886590957641602 +current,Vehicle.Powertrain.CombustionEngine.Speed,1357,0.7572920322418213 +current,Vehicle.Speed,26.796875,0.001363992691040039 +current,Vehicle.Tachograph.VehicleSpeed,26.8984375,0.18561387062072754 +current,Vehicle.TraveledDistanceHighRes,54054920,0.25988006591796875 +current,Vehicle.Powertrain.CombustionEngine.Speed,1405,0.490797758102417 +current,Vehicle.Speed,27.5,0.0009899139404296875 +current,Vehicle.Tachograph.VehicleSpeed,27.8984375,0.22554612159729004 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,92.0,0.21317195892333984 +current,Vehicle.Powertrain.CombustionEngine.Speed,1417,0.5016050338745117 +current,Vehicle.Speed,28.09765625,0.0020411014556884766 +current,Vehicle.Powertrain.CombustionEngine.ECT,20,0.15406203269958496 +current,Vehicle.Tachograph.VehicleSpeed,28.296875,0.07318782806396484 +current,Vehicle.TraveledDistanceHighRes,54054935,0.21302485466003418 +current,Vehicle.Powertrain.CombustionEngine.Speed,1454,0.49937009811401367 +current,Vehicle.Speed,28.796875,0.0018279552459716797 +current,Vehicle.CurrentOverallWeight,5690,0.16250300407409668 +current,Vehicle.Tachograph.VehicleSpeed,28.8984375,0.07174992561340332 +current,Vehicle.TraveledDistanceHighRes,54054940,0.20839810371398926 +current,Vehicle.Powertrain.CombustionEngine.Speed,1449,0.4958817958831787 +current,Vehicle.Tachograph.VehicleSpeed,28.69921875,0.2905902862548828 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,91.5999984741211,0.20492792129516602 +current,Vehicle.TraveledDistanceHighRes,54054950,0.0049190521240234375 +current,Vehicle.CurrentOverallWeight,7600,0.45127296447753906 +current,Vehicle.Powertrain.CombustionEngine.Speed,1436,0.048928022384643555 +current,Vehicle.Speed,28.59765625,0.0004830360412597656 +current,Vehicle.Tachograph.VehicleSpeed,28.3984375,0.1810619831085205 +current,Vehicle.TraveledDistanceHighRes,54054960,0.15956401824951172 +current,Vehicle.Powertrain.CombustionEngine.Speed,1427,0.5009820461273193 +current,Vehicle.Speed,28.296875,0.001361846923828125 +current,Vehicle.Tachograph.VehicleSpeed,28.19921875,0.12749123573303223 +current,Vehicle.Powertrain.CombustionEngine.Speed,1423,0.6276328563690186 +current,Vehicle.Speed,28.19921875,0.0012159347534179688 +current,Vehicle.TraveledDistanceHighRes,54054975,0.14470124244689941 +current,Vehicle.Powertrain.CombustionEngine.Speed,1428,0.5241789817810059 +current,Vehicle.Exterior.AirTemperature,11.53125,0.15312719345092773 +current,Vehicle.Speed,28.3984375,0.0007040500640869141 +current,Vehicle.Tachograph.VehicleSpeed,28.3984375,0.13428878784179688 +current,Vehicle.TraveledDistanceHighRes,54054980,0.009139060974121094 +current,Vehicle.Powertrain.CombustionEngine.Speed,1432,0.5275452136993408 +current,Vehicle.Speed,28.5,0.0014247894287109375 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,92.0,0.043189048767089844 +current,Vehicle.TraveledDistanceHighRes,54054990,0.005118846893310547 +current,Vehicle.Powertrain.CombustionEngine.Speed,1431,0.5253639221191406 +current,Vehicle.Powertrain.CombustionEngine.ECT,21,0.1816389560699463 +current,Vehicle.Tachograph.VehicleSpeed,28.5,0.32999396324157715 +current,Vehicle.Powertrain.CombustionEngine.Speed,1421,0.5040948390960693 +current,Vehicle.Exterior.AirTemperature,11.5625,0.13002419471740723 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,92.4000015258789,0.32050490379333496 +current,Vehicle.TraveledDistanceHighRes,54055005,0.0039501190185546875 +current,Vehicle.Speed,28.09765625,0.0010938644409179688 +current,Vehicle.Tachograph.VehicleSpeed,27.796875,0.03246784210205078 +current,Vehicle.Powertrain.CombustionEngine.Speed,1407,0.46009325981140137 +current,Vehicle.Tachograph.VehicleSpeed,27.3984375,0.5879747867584229 +current,Vehicle.Speed,27.59765625,0.0015189647674560547 +current,Vehicle.Powertrain.CombustionEngine.Speed,1364,0.39410400390625 +current,Vehicle.TraveledDistanceHighRes,54055020,0.4499678611755371 +current,Vehicle.Tachograph.VehicleSpeed,27.0,0.1362917423248291 +current,Vehicle.Speed,27.0,0.001544952392578125 +current,Vehicle.Powertrain.CombustionEngine.Speed,1353,0.4096829891204834 +current,Vehicle.TraveledDistanceHighRes,54055025,0.437453031539917 +current,Vehicle.Tachograph.VehicleSpeed,27.09765625,0.1861860752105713 +current,Vehicle.Speed,27.09765625,0.0017671585083007812 +current,Vehicle.Powertrain.CombustionEngine.Speed,1387,0.30760884284973145 +current,Vehicle.Exterior.AirTemperature,11.59375,0.11127018928527832 +current,Vehicle.CurrentOverallWeight,5690,0.050072669982910156 +current,Vehicle.TraveledDistanceHighRes,54055035,0.28192925453186035 +current,Vehicle.Tachograph.VehicleSpeed,28.0,0.23008060455322266 +current,Vehicle.Speed,28.09765625,0.0014369487762451172 +current,Vehicle.Powertrain.CombustionEngine.Speed,1425,0.30686306953430176 +current,Vehicle.Tachograph.VehicleSpeed,28.5,0.6787488460540771 +current,Vehicle.Speed,28.5,0.0017480850219726562 +current,Vehicle.CurrentOverallWeight,7600,0.1914370059967041 +current,Vehicle.Powertrain.CombustionEngine.Speed,1447,0.11565423011779785 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,92.0,0.4335618019104004 +current,Vehicle.TraveledDistanceHighRes,54055050,0.0043141841888427734 +current,Vehicle.Speed,28.8984375,0.0017211437225341797 +current,Vehicle.Tachograph.VehicleSpeed,28.796875,0.031206846237182617 +current,Vehicle.Powertrain.CombustionEngine.Speed,1453,0.2873861789703369 +current,Vehicle.Exterior.AirTemperature,11.625,0.10310888290405273 +current,Vehicle.Powertrain.CombustionEngine.ECT,22,0.037053823471069336 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,91.5999984741211,0.28302526473999023 +current,Vehicle.TraveledDistanceHighRes,54055060,0.00426173210144043 +current,Vehicle.Tachograph.VehicleSpeed,29.19921875,0.29061007499694824 +current,Vehicle.Speed,29.09765625,0.0017559528350830078 +current,Vehicle.Powertrain.CombustionEngine.Speed,1448,0.22528886795043945 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,91.19999694824219,0.4195990562438965 +current,Vehicle.TraveledDistanceHighRes,54055065,0.003905057907104492 +current,Vehicle.Tachograph.VehicleSpeed,28.796875,0.3355388641357422 +current,Vehicle.Speed,28.69921875,0.0017771720886230469 +current,Vehicle.Powertrain.CombustionEngine.Speed,1449,0.2250828742980957 +current,Vehicle.Exterior.AirTemperature,11.65625,0.09331703186035156 +current,Vehicle.Tachograph.VehicleSpeed,28.5,0.7126748561859131 +current,Vehicle.Speed,28.5,0.0010731220245361328 +current,Vehicle.Powertrain.CombustionEngine.Speed,1415,0.13893604278564453 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.4000015258789,0.4039738178253174 +current,Vehicle.TraveledDistanceHighRes,54055085,0.0044100284576416016 +current,Vehicle.Tachograph.VehicleSpeed,27.8984375,0.38801002502441406 +current,Vehicle.Speed,27.69921875,0.0013229846954345703 +current,Vehicle.Powertrain.CombustionEngine.Speed,1390,0.04322099685668945 +current,Vehicle.TraveledDistanceHighRes,54055090,0.4055500030517578 +current,Vehicle.Tachograph.VehicleSpeed,26.5,0.43664002418518066 +current,Vehicle.Speed,26.5,0.0018470287322998047 +current,Vehicle.Powertrain.CombustionEngine.Speed,1309,0.042001962661743164 +current,Vehicle.Exterior.AirTemperature,11.6875,0.08145594596862793 +current,Vehicle.Tachograph.VehicleSpeed,24.69921875,0.8044440746307373 +current,Vehicle.Speed,24.59765625,0.0013477802276611328 +current,Vehicle.Powertrain.CombustionEngine.Speed,1209,0.0440061092376709 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,89.5999984741211,0.39768099784851074 +current,Vehicle.TraveledDistanceHighRes,54055105,0.004931926727294922 +current,Vehicle.Tachograph.VehicleSpeed,23.0,0.5373342037200928 +current,Vehicle.Powertrain.CombustionEngine.Speed,1150,0.07277679443359375 +current,Vehicle.Speed,23.0,0.0024251937866210938 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.0,0.33979177474975586 +current,Vehicle.TraveledDistanceHighRes,54055110,0.0034589767456054688 +current,Vehicle.Tachograph.VehicleSpeed,22.19921875,0.5848500728607178 +current,Vehicle.Powertrain.CombustionEngine.Speed,1122,0.03656196594238281 +current,Vehicle.Speed,22.296875,0.001237630844116211 +current,Vehicle.TraveledDistanceHighRes,54055115,0.24651527404785156 +current,Vehicle.Tachograph.VehicleSpeed,22.09765625,0.5840761661529541 +current,Vehicle.Powertrain.CombustionEngine.Speed,1112,0.04208493232727051 +current,Vehicle.Exterior.AirTemperature,11.65625,0.045736074447631836 +current,Vehicle.Powertrain.CombustionEngine.ECT,23,0.03651881217956543 +current,Vehicle.Speed,22.09765625,0.001322031021118164 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.80000305175781,0.14227700233459473 +current,Vehicle.TraveledDistanceHighRes,54055125,0.006412982940673828 +current,Vehicle.Tachograph.VehicleSpeed,22.296875,0.5814151763916016 +current,Vehicle.Powertrain.CombustionEngine.Speed,1130,0.04546689987182617 +current,Vehicle.Speed,22.3984375,0.0012311935424804688 +current,Vehicle.Tachograph.VehicleSpeed,22.5,0.7851369380950928 +current,Vehicle.Powertrain.CombustionEngine.Speed,1144,0.0022780895233154297 +current,Vehicle.Speed,22.69921875,0.0011720657348632812 +current,Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel,90.0,0.14379310607910156 +current,Vehicle.TraveledDistanceHighRes,54055135,0.005148887634277344 +current,Vehicle.Tachograph.VehicleSpeed,23.3984375,0.6308407783508301 +current,Vehicle.Powertrain.CombustionEngine.Speed,1177,0.006275177001953125 \ No newline at end of file diff --git a/csv-provider/signalsFmsRecording.csv.license b/csv-provider/signalsFmsRecording.csv.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/csv-provider/signalsFmsRecording.csv.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/csv-provider/signalsFmsRecording.csv.zip b/csv-provider/signalsFmsRecording.csv.zip new file mode 100644 index 0000000..fe1ddfc Binary files /dev/null and b/csv-provider/signalsFmsRecording.csv.zip differ diff --git a/csv-provider/signalsFmsRecording.csv.zip.license b/csv-provider/signalsFmsRecording.csv.zip.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/csv-provider/signalsFmsRecording.csv.zip.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/docs/img/architecture.png b/docs/img/architecture.png deleted file mode 100644 index 703994e..0000000 Binary files a/docs/img/architecture.png and /dev/null differ diff --git a/docs/introduction.md b/docs/introduction.md index 35a59de..b4dab22 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -3,20 +3,13 @@ sidebar_position: 1 title: Introduction --- - - -## Fleet Ops -| Truck Fleet Ops| | -|---|---| -|Short Summary | A close to "real-life" showcase for truck fleet management where trucks run SDV stacks so that logistics fleet operators can manage apps, data and services for a diverse set of vehicles.| -|What is in the showcase | Data collection from CANBus, In vehicle data brokers, VSS Signal Specification, FMS servers, Apps and Services using this data| -|SDV Projects Involved| Leda, Kuksa, Velocitas, Charriot, SommR?| -|Other interesting Technologies|InfluxDB, Prometheus, Eclipse Hono, Eclipse Kanto, Digital.Auto | -| Architecture Overview | ![FleetArchSDV.png](./img/architecture.png)| -| Distro | TBD| -| Coordinator | Kai Hudalla | - -# Getting Started -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ultrices rutrum tellus eget euismod. Nullam mauris metus, tincidunt quis scelerisque et, accumsan a ligula. Morbi eget tempus lacus. Ut sollicitudin laoreet nibh at ullamcorper. Maecenas at semper augue. Donec pulvinar bibendum lectus sit amet convallis. Vestibulum rhoncus mi in congue dictum. Proin mollis tristique elit, eu bibendum tellus pellentesque faucibus. Sed accumsan orci nisi, sollicitudin egestas neque volutpat non. Sed vulputate faucibus semper. Proin vestibulum nisl erat, sed pellentesque erat auctor et. Sed tristique sem eget urna sollicitudin maximus. - -Fusce eget magna felis. Mauris sed efficitur risus. Suspendisse potenti. Maecenas quis dapibus nulla. In ultrices ligula nec condimentum facilisis. Pellentesque ut mi et orci egestas posuere. Sed vitae massa in neque faucibus blandit sit amet id justo. Aenean consequat, neque ac pulvinar auctor, est lacus hendrerit dolor, id tristique libero augue a lacus. In aliquet ligula a odio consectetur, non ornare elit posuere. Phasellus neque purus, consequat a auctor eu, facilisis ac ante. Etiam pulvinar nunc eget neque ornare, id dictum quam viverra. Etiam eu accumsan urna, eu commodo mi. Aliquam erat volutpat. Mauris ac fermentum enim. Suspendisse leo sem, tempor tincidunt orci id, dapibus accumsan odio. +## Fleet Management + +| | | +|------------------|---| +|Short Summary | This repository contains the **Fleet Management Blueprint** which is a close to *real-life* showcase for truck fleet management where trucks run an SDV software stack so that logistics fleet operators can manage apps, data and services for a diverse set of vehicles. | +|What is in the showcase | In-vehicle data collection using VSS Signal Specification, data transfer to cloud back end, rFMS server| +|SDV Projects Involved| Eclipse Leda, Eclipse Kuksa | +|Other interesting Technologies|InfluxDB, Eclipse Hono, Eclipse Kanto, Eclipse Paho | +| Architecture Overview | ![FleetArchSDV](../img/architecture.drawio.svg)| +| Distro | TBD | diff --git a/fms-blueprint-compose-hono.yaml b/fms-blueprint-compose-hono.yaml new file mode 100644 index 0000000..f409df4 --- /dev/null +++ b/fms-blueprint-compose-hono.yaml @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +secrets: + kafka.properties: + file: "${KAFKA_PROPERTIES_FILE:-hono-kafka.properties}" + +services: + fms-consumer: + image: "ghcr.io/eclipse-sdv-blueprints/fleet-management/fms-consumer:main" + build: + context: "./components" + dockerfile: "Dockerfile.fms-consumer" + container_name: "fms-consumer" + cap_drop: + - CAP_MKNOD + - CAP_NET_RAW + - CAP_AUDIT_WRITE + networks: + - "fms-backend" + depends_on: + influxdb: + condition: service_healthy + env_file: + - "./influxdb/fms-demo.env" + - "./hono-kafka.env" + environment: + INFLUXDB_API_TOKEN_FILE: "/tmp/fms-demo.token" + KAFKA_PROPERTIES_FILE: "/app/config/kafka.properties" + RUST_LOG: "info,fms_consumer=debug,influx_client=debug" + volumes: + - type: "volume" + source: "influxdb-auth" + target: "/tmp" + read_only: true + secrets: + - source: "kafka.properties" + target: "/app/config/kafka.properties" + fms-forwarder: + command: "hono" + env_file: "${FMS_FORWARDER_PROPERTIES_FILE:-./hono-mqtt.env}" diff --git a/fms-blueprint-compose.yaml b/fms-blueprint-compose.yaml new file mode 100644 index 0000000..1f78b41 --- /dev/null +++ b/fms-blueprint-compose.yaml @@ -0,0 +1,186 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +networks: + fms-backend: + driver: overlay + attachable: true + fms-vehicle: + driver: overlay + attachable: true + +configs: + influxdb_init.sh: + file: "./influxdb/init-scripts/create-fms-token.sh" + grafana_dashboards_from_fs.yaml: + file: "./grafana/provisioning/dashboards/dashboards_from_filesystem.yaml" + grafana_fms_dashboard.json: + file: "./grafana/dashboards/FMS-Fleet.json" + vss_overlay.json: + file: "./spec/overlay/vss.json" + +volumes: + influxdb-data: + influxdb-config: + influxdb-auth: + grafana-datasources: + +services: + influxdb: + image: "docker.io/library/influxdb:2.7" + container_name: "influxDB" + healthcheck: + test: ["CMD-SHELL", "influx ping"] + interval: 5s + timeout: 3s + start_period: 5s + cap_drop: &default-drops + - CAP_MKNOD + - CAP_NET_RAW + - CAP_AUDIT_WRITE + command: influxd + env_file: "./influxdb/fms-demo.env" + environment: + DOCKER_INFLUXDB_INIT_MODE: "setup" + DOCKER_INFLUXDB_INIT_USERNAME: "fms-demo" + DOCKER_INFLUXDB_INIT_PASSWORD: "fms-demo-secret" + DOCKER_INFLUXDB_INIT_RETENTION: "1w" + DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: "fms-backend-admin-token" + networks: + - "fms-backend" + ports: + - "0.0.0.0:8086:8086" + configs: + - source: "influxdb_init.sh" + target: "/docker-entrypoint-initdb.d/influxdb_init.sh" + volumes: + - type: "volume" + source: "influxdb-data" + target: "/var/lib/influxdb2" + - type: "volume" + source: "influxdb-config" + target: "/etc/influxdb2" + - type: "volume" + source: "influxdb-auth" + target: "/tmp/out" + - type: "volume" + source: "grafana-datasources" + target: "/tmp/influxdb-datasources" + grafana: + image: "docker.io/grafana/grafana:9.5.6" + container_name: "grafana" + cap_drop: *default-drops + ports: + - "127.0.0.1:3000:3000" + networks: + - "fms-backend" + depends_on: + influxdb: + condition: service_healthy + configs: + - source: "grafana_dashboards_from_fs.yaml" + target: "/etc/grafana/provisioning/dashboards/grafana_dashboards_from_fs.yaml" + - source: "grafana_fms_dashboard.json" + target: "/etc/dashboards/grafana_fms_dashboard.json" + mode: 0644 + volumes: + - type: "volume" + source: "grafana-datasources" + target: "/etc/grafana/provisioning/datasources" + read_only: true + fms-server: + image: "ghcr.io/eclipse-sdv-blueprints/fleet-management/fms-server:main" + build: + context: "./components" + dockerfile: "Dockerfile.fms-server" + container_name: "fms-server" + cap_drop: *default-drops + networks: + - "fms-backend" + ports: + - "127.0.0.1:8081:8081" + depends_on: + influxdb: + condition: service_healthy + env_file: "./influxdb/fms-demo.env" + environment: + INFLUXDB_API_TOKEN_FILE: "/tmp/fms-demo.token" + RUST_LOG: "info" + volumes: + - type: "volume" + source: "influxdb-auth" + target: "/tmp" + read_only: true + databroker: + image: "ghcr.io/eclipse/kuksa.val/databroker:0.3.1" + container_name: "databroker" + cap_drop: *default-drops + networks: + - "fms-vehicle" + ports: + - "127.0.0.1:55555:55556" + configs: + - "vss_overlay.json" + environment: + KUKSA_DATA_BROKER_ADDR: "0.0.0.0" + KUKSA_DATA_BROKER_PORT: "55556" + KUKSA_DATA_BROKER_METADATA_FILE: "/vss_overlay.json" + RUST_LOG: "info" + fms-forwarder: + image: "ghcr.io/eclipse-sdv-blueprints/fleet-management/fms-forwarder:main" + build: &fms-forwarder-build + context: "./components" + dockerfile: "Dockerfile.fms-forwarder" + container_name: "fms-forwarder" + cap_drop: *default-drops + networks: + - "fms-backend" + - "fms-vehicle" + depends_on: + influxdb: + condition: service_healthy + databroker: + condition: service_started + command: "influx" + env_file: "${FMS_FORWARDER_PROPERTIES_FILE:-./influxdb/fms-demo.env}" + environment: + INFLUXDB_API_TOKEN_FILE: "/tmp/fms-demo.token" + KUKSA_DATA_BROKER_URI: "http://databroker:55556" + RUST_LOG: "info,fms_forwarder=info,influx_client=info" + volumes: + - type: "volume" + source: "influxdb-auth" + target: "/tmp" + read_only: true + csv-provider: + image: "ghcr.io/eclipse/kuksa.val.feeders/csv-provider:main" + container_name: "csv-provider" + cap_drop: *default-drops + networks: + - "fms-vehicle" + depends_on: + databroker: + condition: service_started + volumes: + - "./csv-provider/signalsFmsRecording.csv:/dist/signals.csv" + environment: + PROVIDER_INFINITE: 1 + PROVIDER_LOG_LEVEL: "INFO" + KUKSA_DATA_BROKER_ADDR: "databroker" + KUKSA_DATA_BROKER_PORT: "55556" diff --git a/grafana/dashboards/FMS-Fleet.json b/grafana/dashboards/FMS-Fleet.json new file mode 100644 index 0000000..08f3373 --- /dev/null +++ b/grafana/dashboards/FMS-Fleet.json @@ -0,0 +1,1064 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "basemap": { + "config": {}, + "name": "Layer 0", + "opacity": 0.5, + "type": "osm-standard" + }, + "controls": { + "mouseWheelZoom": true, + "showAttribution": true, + "showDebug": false, + "showMeasure": false, + "showScale": true, + "showZoom": true + }, + "layers": [ + { + "config": { + "showLegend": false, + "style": { + "color": { + "fixed": "text" + }, + "opacity": 1, + "rotation": { + "fixed": 0, + "max": 360, + "min": -360, + "mode": "mod" + }, + "size": { + "fixed": 6, + "max": 15, + "min": 2 + }, + "symbol": { + "fixed": "img/icons/marker/circle.svg", + "mode": "fixed" + }, + "text": { + "field": "Time", + "fixed": "", + "mode": "field" + }, + "textConfig": { + "fontSize": 16, + "offsetX": 0, + "offsetY": 10, + "textAlign": "center", + "textBaseline": "top" + } + } + }, + "location": { + "latitude": "latitude", + "longitude": "longitude", + "mode": "coords" + }, + "name": "Location", + "tooltip": true, + "type": "markers" + } + ], + "tooltip": { + "mode": "details" + }, + "view": { + "allLayers": true, + "id": "fit", + "lat": 0, + "lon": 0, + "padding": 60, + "zoom": 14 + } + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "hide": false, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"latitude\" or r[\"_field\"] == \"longitude\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_field\", \"_value\"])\n |> last()", + "refId": "A" + } + ], + "title": "Location", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "vin" + ], + "mode": "columns" + } + }, + { + "id": "merge", + "options": {} + } + ], + "type": "geomap" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "#808080", + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "velocitykmh" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 8, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"tachographSpeed\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\", \"vin\"])\n |> group(columns: [\"vin\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")", + "refId": "A" + } + ], + "title": "Tachograph Speed", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "vin" + ], + "valueLabel": "vin" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "max": 100, + "min": 0, + "noValue": "N/A", + "thresholds": { + "mode": "percentage", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 5 + }, + { + "color": "green", + "value": 30 + } + ] + }, + "unit": "percent" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "fuelLevel1" + }, + "properties": [ + { + "id": "displayName", + "value": "First Tank (${__field.labels.vin})" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "fuelLevel2" + }, + "properties": [ + { + "id": "displayName", + "value": "Second Tank (${__field.labels.vin})" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "catalystFuelLevel" + }, + "properties": [ + { + "id": "displayName", + "value": "AdBlue (${__field.labels.vin})" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 4, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"fuelLevel1\" or r._field == \"fuelLevel2\" or r[\"_field\"] == \"catalystFuelLevel\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\", \"_field\", \"vin\"])\n |> group(columns: [\"vin\", \"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")", + "refId": "A" + } + ], + "title": "Fuel Levels", + "transformations": [], + "transparent": true, + "type": "gauge" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "rotrpm" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 15, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"engineSpeed\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\", \"vin\"])\n |> group(columns: [\"vin\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")", + "refId": "A" + } + ], + "title": "Engine Speed", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "vin" + ], + "valueLabel": "vin" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "N/A", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "green", + "value": 100 + } + ] + }, + "unit": "suffix:m" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 17 + }, + "id": 14, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"estimatedDistanceToEmptyFuel\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")", + "refId": "A" + } + ], + "title": "Est. Distance to empty (Fuel)", + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "N/A", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#000000", + "value": null + }, + { + "color": "#303030", + "value": -15 + }, + { + "color": "#302e9b", + "value": -10 + }, + { + "color": "#000082", + "value": -5 + }, + { + "color": "#0001fc", + "value": 0 + }, + { + "color": "#2e65fd", + "value": 5 + }, + { + "color": "#99cdfc", + "value": 10 + }, + { + "color": "#2dd1ca", + "value": 15 + }, + { + "color": "#008001", + "value": 20 + }, + { + "color": "#9ad000", + "value": 25 + }, + { + "color": "#fed000", + "value": 30 + }, + { + "color": "#fe6700", + "value": 35 + }, + { + "color": "#c6140c", + "value": 40 + } + ] + }, + "unit": "celsius" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 18, + "y": 17 + }, + "id": 6, + "options": { + "colorMode": "background_solid", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"ambientAirTemperature\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")", + "refId": "A" + } + ], + "title": "Ambient Air Temperature", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "vin" + ], + "valueLabel": "vin" + } + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "semi-dark-red", + "mode": "fixed" + }, + "mappings": [ + { + "options": { + "false": { + "color": "green", + "index": 0, + "text": "released" + }, + "true": { + "color": "red", + "index": 1, + "text": "engaged" + } + }, + "type": "value" + } + ], + "noValue": "N/A", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bool_on_off" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 21, + "y": 17 + }, + "id": 7, + "options": { + "colorMode": "background_solid", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^Value$/", + "values": false + }, + "textMode": "value" + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "hide": false, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"parkingBrakeSwitch\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\"])\n |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n |> yield(name: \"last\")", + "refId": "A" + } + ], + "title": "Parking Brake", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "vin" + ], + "mode": "columns", + "valueLabel": "vin" + } + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "fillOpacity": 70, + "lineWidth": 0, + "spanNulls": false + }, + "mappings": [ + { + "options": { + "DRIVE": { + "color": "red", + "index": 1 + }, + "DRIVER_AVAILABLE": { + "color": "orange", + "index": 2 + }, + "REST": { + "color": "green", + "index": 0 + }, + "WORK": { + "color": "blue", + "index": 3 + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/driver1WorkingState.*/" + }, + "properties": [ + { + "id": "displayName", + "value": "Driver 1 (${__field.labels.vin})" + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/driver2WorkingState.*/" + }, + "properties": [ + { + "id": "displayName", + "value": "Driver 2 (${__field.labels.vin})" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 12, + "options": { + "alignValue": "left", + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "mergeValues": true, + "rowHeight": 0.9, + "showValue": "never", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"snapshot\")\n |> filter(fn: (r) => r[\"_field\"] == \"driver1WorkingState\" or r[\"_field\"] == \"driver2WorkingState\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"vin\", \"_value\", \"_time\", \"_field\"])\n |> group(columns: [\"vin\", \"_field\"])\n |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n |> yield(name: \"last\")", + "refId": "A" + } + ], + "title": "Driver Working State", + "transformations": [], + "type": "state-timeline" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "#ce6b43", + "mode": "fixed" + }, + "mappings": [], + "noValue": "N/A", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "suffix:m" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 25 + }, + "id": 13, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "value" + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"header\")\n |> filter(fn: (r) => r[\"_field\"] == \"hrTotalVehicleDistance\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\"])\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")", + "refId": "A" + } + ], + "title": "Total Distance Traveled", + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "#ce6b43", + "mode": "fixed" + }, + "mappings": [], + "noValue": "N/A", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "light-blue", + "value": null + } + ] + }, + "unit": "suffix:kg" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 25 + }, + "id": 10, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.5.2", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "query": "from(bucket: \"demo\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"header\")\n |> filter(fn: (r) => r[\"_field\"] == \"grossCombinationVehicleWeight\")\n |> filter(fn: (r) => contains(set: ${selected_vin:json}, value: r[\"vin\"]))\n |> keep(columns: [\"_time\", \"_value\"])\n |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n |> yield(name: \"mean\")", + "refId": "A" + } + ], + "title": "Gross combination Vehicle Weight", + "transformations": [ + { + "id": "labelsToFields", + "options": { + "keepLabels": [ + "vin" + ], + "valueLabel": "vin" + } + } + ], + "type": "stat" + } + ], + "refresh": "5s", + "revision": 1, + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": [ + "87" + ], + "value": [ + "87" + ] + }, + "datasource": { + "type": "influxdb", + "uid": "PDC312342D5DCA611" + }, + "definition": "import \"influxdata/influxdb/schema\"\n\nschema.tagValues(bucket: \"demo\", tag: \"vin\")\n", + "description": "The VIN of selected vehicle", + "hide": 0, + "includeAll": false, + "label": "VIN", + "multi": true, + "name": "selected_vin", + "options": [], + "query": "import \"influxdata/influxdb/schema\"\n\nschema.tagValues(bucket: \"demo\", tag: \"vin\")\n", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "FMS Fleet", + "uid": "OwEBnb1Vd", + "version": 1, + "weekStart": "" +} diff --git a/grafana/dashboards/FMS-Fleet.json.license b/grafana/dashboards/FMS-Fleet.json.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/grafana/dashboards/FMS-Fleet.json.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/grafana/provisioning/dashboards/dashboards_from_filesystem.yaml b/grafana/provisioning/dashboards/dashboards_from_filesystem.yaml new file mode 100644 index 0000000..349408e --- /dev/null +++ b/grafana/provisioning/dashboards/dashboards_from_filesystem.yaml @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: 1 + +providers: + - name: dashboards + type: file + updateIntervalSeconds: 30 + options: + path: /etc/dashboards + foldersFromFilesStructure: true diff --git a/img/.gitignore b/img/.gitignore new file mode 100644 index 0000000..8d71bf9 --- /dev/null +++ b/img/.gitignore @@ -0,0 +1 @@ +*.bkp diff --git a/img/architecture.drawio.svg b/img/architecture.drawio.svg new file mode 100644 index 0000000..1fec610 --- /dev/null +++ b/img/architecture.drawio.svg @@ -0,0 +1,4 @@ + + + +



Databroker
Databroker...
FMS
Forwarder
FMS...


<<get dashboard>>
<<get dashboard>>
Browser
Browser
FMS
Server
FMS...
Fleet
Management
Fleet...
Influx API 2.0
I...
rFMS
rFMS
Influx API 2.0
I...
kuksa.val.v1
kuksa.val.v1
VSS overlay
VSS overlay
In-Vehicle
In-Vehicle
Off-Vehicle
Off-Vehicle




CSV Provider
CSV Provider...
Hono MQTT (hono)  
Ho...
CSV recording from truck
CSV recording...
kuksa.val.v1  
kuksa.val.v1  
FMS
Consumer
FMS...
Influx API 2.0
In...
Kafka
Ka...
Influx
API 2.0
In...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/influxdb/fms-demo.env b/influxdb/fms-demo.env new file mode 100644 index 0000000..3751655 --- /dev/null +++ b/influxdb/fms-demo.env @@ -0,0 +1,6 @@ +DOCKER_INFLUXDB_INIT_ORG="sdv" +DOCKER_INFLUXDB_INIT_BUCKET="demo" + +INFLUXDB_URI="http://influxdb:8086" +INFLUXDB_ORG="sdv" +INFLUXDB_BUCKET="demo" diff --git a/influxdb/init-scripts/create-fms-token.sh b/influxdb/init-scripts/create-fms-token.sh new file mode 100755 index 0000000..b0f240d --- /dev/null +++ b/influxdb/init-scripts/create-fms-token.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +set -e + +token=$(influx auth create \ + --hide-headers \ + --description "Token for writing to the FMS demo bucket" \ + --user ${DOCKER_INFLUXDB_INIT_USERNAME} \ + --read-bucket ${DOCKER_INFLUXDB_INIT_BUCKET_ID} \ + --write-bucket ${DOCKER_INFLUXDB_INIT_BUCKET_ID} | awk -F '\t' '{print $3}') + +echo ${token} > /tmp/out/fms-demo.token + +cat < /tmp/influxdb-datasources/influxdb.yaml +apiVersion: 1 +datasources: +- name: "InfluxDB-SDV-Flux" + uid: "PDC312342D5DCA611" + type: influxdb + access: proxy + url: http://influxdb:8086 + jsonData: + version: Flux + organization: ${DOCKER_INFLUXDB_INIT_ORG} + defaultBucket: ${DOCKER_INFLUXDB_INIT_BUCKET} + tlsSkipVerify: true + secureJsonData: + token: ${token} +EOF + diff --git a/leda/Setup.md b/leda/Setup.md new file mode 100644 index 0000000..93716b9 --- /dev/null +++ b/leda/Setup.md @@ -0,0 +1,86 @@ + +# Setting Up a Leda Image + +The setup for this FMS scenario assumes a split into components running in the vehicles and components running in a (cloud) backend. +The following page describes how to configure a Leda instance to become part of this FMS setup. More precisely, we deploy the containers for the feedercan, the fms-forwarder, and the Kuksa.val databroker with an FMS-specific vehicle model. + +## Run Leda +The following steps assume a running instance of Eclipse Leda. For more details see the [Eclipse Leda Getting Started](https://eclipse-leda.github.io/leda/docs/general-usage/) +This guide was tested with release v0.1.0-M1 of Eclipse Leda. + +## Create GitHub Token to Read containers +The container image for the FMS-Forwarder is currently only available in a private GitHub container registry within the repository https://github.com/SoftwareDefinedVehicle/oss-tech-scouting-demo . +To enable Leda to access the container, you can create a GitHub token with the scope `read:packages`. This requires that your GitHub user has the respective access rights for that repository. +In the GitHub user settings you can generate the token under Settings -> Developer Settings -> Personal Access Tokens -> Tokens (classic). + +Afterwards, select `Configure SSO` and authorize the SoftwareDefinedVehicle organization. + +## Configure Leda to use GitHub Token +We now need to configure Leda with the newly created GitHub token, to enable the download from a private container registry. Execute in Leda: + +``` +sdv-kanto-ctl add-registry -h ghcr.io -u github -p +``` + +For more details see the [Leda documentation](https://eclipse-leda.github.io/leda/docs/device-provisioning/container-management/container-registries/) + +## Backup existing manifestes +In Leda, there are manifests to manage the execution of containers by Eclipse Kanto. During the next steps we will overwrite some of the default manifests (`databroker.json`, `feedercan.json`). Because of that, we recommend to backup the existing manifests from `/data/var/containers/mainfests`. + +## Copy manifests to Leda +To trigger the execution of the required containers for the FMS setup, copy the manifest files from `leda/data/var/containers/manifests` in the host to `/data/var/containers/manifests` in Leda: + +``` +manifests % scp -P 2222 *.json root@127.0.0.1:/data/var/containers/manifests +``` + +## create folders in Leda mounted in mainfests +The containers described within the manifests require files that are not present in Leda like the FMS-specific vehicle model. +Therefore, we need to create the paths (e.g,. `mkdir`) in Leda from which the containers try to mount these files which are: + +- `mkdir -p /data/usr/fms/dbc` +- `mkdir -p /data/usr/databroker` + +## copy required files to leda folders: +Now you can copy the files required by the containers to Leda. Execute in the root of this repository on the host: +``` +scp -P 2222 dbc-feeder/220421_MAN_Si_RIO_CAN_converted.log root@127.0.0.1:/data/usr/fms/dbc +scp -P 2222 dbc-feeder/j1939_REMODUL_v5.dbc root@127.0.0.1:/data/usr/fms/dbc +scp -P 2222 spec/overlay/vss.json root@127.0.0.1:/data/usr/fms/databroker +``` + +## start backend on host +Besides the in-vehicle containers in Leda, we still need the backend for the full FMS setup. You can start the remaining containers on the host with: + +``` +docker compose -f fms-demo-compose.yaml up influxdb grafana fms-server --detach +``` + +## configure InfluxDB token +The fms-forwarder needs a token to write data into the InfluxDB which has been started on the host. +There are multiple ways to retrieve this token, e.g., through the web-interface of InfluxDB (localhost:8086). One approach through the command line is the following: + +``` +docker exec -it influxDB cat /tmp/out/fms-demo.token +``` + +You can then insert the token in the `/data/var/containers/manifestsfms-forwarder.json` manifest in Leda at the bottom of the file as value for `config.env.INFLUXAPI_TOKEN`. \ No newline at end of file diff --git a/leda/data/var/containers/manifests/databroker.json b/leda/data/var/containers/manifests/databroker.json new file mode 100644 index 0000000..827ed12 --- /dev/null +++ b/leda/data/var/containers/manifests/databroker.json @@ -0,0 +1,60 @@ +{ + "container_id": "databroker", + "container_name": "databroker", + "image": { + "name": "ghcr.io/eclipse/kuksa.val/databroker:0.3" + }, + "mount_points": [ + { + "source": "/data/usr/fms/databroker", + "destination": "/etc/databroker", + "propagation_mode": "rprivate" + } + ], + "host_config": { + "devices": [], + "network_mode": "bridge", + "privileged": false, + "restart_policy": { + "maximum_retry_count": 0, + "retry_timeout": 0, + "type": "unless-stopped" + }, + "runtime": "io.containerd.runc.v2", + "extra_hosts": [], + "port_mappings": [ + { + "protocol": "tcp", + "container_port": 55555, + "host_ip": "localhost", + "host_port": 30555, + "host_port_end": 30555 + } + ], + "log_config": { + "driver_config": { + "type": "json-file", + "max_files": 2, + "max_size": "1M", + "root_dir": "" + }, + "mode_config": { + "mode": "blocking", + "max_buffer_size": "" + } + }, + "resources": null + }, + "io_config": { + "open_stdin": false, + "tty": false + }, + "config": { + "env": [ + "RUST_LOG=info", + "KUKSA_DATA_BROKER_METADATA_FILE=/etc/databroker/vss.json", + "vehicle_data_broker=debug" + ], + "cmd": [] + } +} diff --git a/leda/data/var/containers/manifests/databroker.json.license b/leda/data/var/containers/manifests/databroker.json.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/leda/data/var/containers/manifests/databroker.json.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/leda/data/var/containers/manifests/feedercan.json b/leda/data/var/containers/manifests/feedercan.json new file mode 100644 index 0000000..61c088e --- /dev/null +++ b/leda/data/var/containers/manifests/feedercan.json @@ -0,0 +1,56 @@ +{ + "container_id": "feedercan", + "container_name": "feedercan", + "image": { + "name": "docker.io/sophokles73/dbc-feeder:0.9" + }, + "mount_points": [ + { + "source": "/data/usr/fms", + "destination": "/tmp/fms", + "propagation_mode": "rprivate" + } + ], + "host_config": { + "devices": [], + "network_mode": "bridge", + "privileged": false, + "restart_policy": { + "maximum_retry_count": 0, + "retry_timeout": 0, + "type": "unless-stopped" + }, + "runtime": "io.containerd.runc.v2", + "extra_hosts": [ + "databroker:container_databroker-host" + ], + "log_config": { + "driver_config": { + "type": "json-file", + "max_files": 2, + "max_size": "1M", + "root_dir": "" + }, + "mode_config": { + "mode": "blocking", + "max_buffer_size": "" + } + }, + "resources": null + }, + "io_config": { + "open_stdin": false, + "tty": false + }, + "config": { + "env": [ + "DBC_FILE=/tmp/fms/dbc/j1939_REMODUL_v5.dbc", + "CANDUMP_FILE=/tmp/fms/dbc/220421_MAN_Si_RIO_CAN_converted.log", + "USE_J1939=1", + "MAPPING_FILE=/tmp/fms/databroker/vss.json", + "KUKSA_ADDRESS=databroker", + "LOG_LEVEL=INFO,dbcfeederlib.databrokerclientwrapper=INFO" + ], + "cmd": [] + } +} diff --git a/leda/data/var/containers/manifests/feedercan.json.license b/leda/data/var/containers/manifests/feedercan.json.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/leda/data/var/containers/manifests/feedercan.json.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/leda/data/var/containers/manifests/fms-forwarder.json b/leda/data/var/containers/manifests/fms-forwarder.json new file mode 100644 index 0000000..62ca995 --- /dev/null +++ b/leda/data/var/containers/manifests/fms-forwarder.json @@ -0,0 +1,49 @@ +{ + "container_id": "fms-forwarder", + "container_name": "fms-forwarder", + "image": { + "name": "ghcr.io/softwaredefinedvehicle/oss-tech-scouting-demo/fms-forwarder:main" + }, + "host_config": { + "devices": [], + "network_mode": "bridge", + "privileged": false, + "restart_policy": { + "maximum_retry_count": 0, + "retry_timeout": 0, + "type": "unless-stopped" + }, + "runtime": "io.containerd.runc.v2", + "extra_hosts": [ + "databroker:container_databroker-host" + ], + "port_mappings": [ + ], + "log_config": { + "driver_config": { + "type": "json-file", + "max_files": 2, + "max_size": "1M", + "root_dir": "" + }, + "mode_config": { + "mode": "blocking", + "max_buffer_size": "" + } + }, + "resources": null + }, + "io_config": { + "open_stdin": false, + "tty": false + }, + "config": { + "env": [ + "RUST_LOG=info,fms_forwarder=debug", + "KUKSA_DATA_BROKER_URI=http://databroker:55555", + "INFLUXDB_URI=http://10.0.2.2:8086", + "INFLUXDB_API_TOKEN=" + ], + "cmd": [] + } +} diff --git a/leda/data/var/containers/manifests/fms-forwarder.json.license b/leda/data/var/containers/manifests/fms-forwarder.json.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/leda/data/var/containers/manifests/fms-forwarder.json.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/provision-vehicle-to-hono.sh b/provision-vehicle-to-hono.sh new file mode 100755 index 0000000..da7280e --- /dev/null +++ b/provision-vehicle-to-hono.sh @@ -0,0 +1,159 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +# +# This script can be used to provision a tenant and a device to an existing +# Hono instance. +# +# By default, the device will be provisioned to the Hono sandbox. +# +set -e + +HONO_HOST="hono.eclipseprojects.io" +HONO_REGISTRY_PORT="28443" +HONO_TENANT_ID="" +HONO_DEVICE_ID="" +HONO_DEVICE_PASSWORD="" +HONO_KAFKA_BROKERS="" +HONO_KAFKA_SECURE_PORT=9094 +HONO_KAFKA_USER="hono" +HONO_KAFKA_PASSWORD="hono-secret" + +print_usage() { + echo "Usage: provision-vehicle-to-hono --tenant=TENANT --device-id=DEVICE --device-pwd=PASSWORD [--host=HOST] [--port=PORT] [--kafka-brokers=BROKERS] [--kafka-user=USER] [--kafka-pwd=PASSWORD]" + echo + echo "--tenant The identifier of the tenant to create the device for." + echo "--device-id The identifier of the device to create." + echo "--device-pwd The password that the device needs to use for authenticating to Hono's protocol adapters." + echo "--host The host name or IP address of Hono's device registry. [${HONO_HOST}]" + echo "--port The TLS port of the Hono device registry. [${HONO_REGISTRY_PORT}]" + echo "--kafka-brokers A comma separated list of host name/IP address:port tuples of the Kafka broker(s) used by Hono. [${HONO_HOST}:${HONO_KAFKA_SECURE_PORT}]" + echo "--kafka-user The username to use for authenticating to the Kafka broker(s) used by Hono. [${HONO_KAFKA_USER}]" + echo "--kafka-pwd The password to use for authenticating to the Kafka broker(s) used by Hono. [${HONO_KAFKA_PASSWORD}]" + echo +} + +for i in "$@" +do + case $i in + --tenant=*) + HONO_TENANT_ID="${i#*=}" + ;; + --device-id=*) + HONO_DEVICE_ID="${i#*=}" + ;; + --device-pwd=*) + HONO_DEVICE_PASSWORD="${i#*=}" + ;; + --host=*) + HONO_HOST="${i#*=}" + ;; + --port=*) + HONO_REGISTRY_PORT="${i#*=}" + ;; + --kafka-brokers=*) + HONO_KAFKA_BROKERS="${i#*=}" + ;; + --kafka-user=*) + HONO_KAFKA_USER="${i#*=}" + ;; + --kafka-pwd=*) + HONO_KAFKA_PASSWORD="${i#*=}" + ;; + --help) + print_usage + exit 1 + ;; + -h) + print_usage + exit 1 + ;; + *) + echo "Ignoring unknown option: $i" + echo "Run with flag -? for usage" + ;; + esac +done + +if [[ -z "${HONO_TENANT_ID}" ]]; then + echo "Missing required parameter: tenant" + print_usage + exit 1 +fi +if [[ -z "${HONO_DEVICE_ID}" ]]; then + echo "Missing required parameter: device-id" + print_usage + exit 1 +fi +if [[ -z "${HONO_DEVICE_PASSWORD}" ]]; then + echo "Missing required parameter: device-pwd" + print_usage + exit 1 +fi +if [[ -z "${HONO_KAFKA_BROKERS}" ]]; then + HONO_KAFKA_BROKERS=${HONO_HOST}:${HONO_KAFKA_SECURE_PORT} +fi + +HONO_REGISTRY_URI="https://${HONO_HOST}:${HONO_REGISTRY_PORT}/v1" + +curl --silent --show-error --fail -X POST -H "content-type: application/json" --data-binary '{ + "ext": { + "messaging-type": "kafka" + } +}' ${HONO_REGISTRY_URI}/tenants/${HONO_TENANT_ID} + +curl --silent --show-error --fail -X POST ${HONO_REGISTRY_URI}/devices/${HONO_TENANT_ID}/${HONO_DEVICE_ID} + +curl --silent --show-error --fail -X PUT -H "content-type: application/json" --data-binary '[{ + "type": "hashed-password", + "auth-id": "'${HONO_DEVICE_ID}'", + "secrets": [{ + "pwd-plain": "'${HONO_DEVICE_PASSWORD}'" + }] +}]' ${HONO_REGISTRY_URI}/credentials/${HONO_TENANT_ID}/${HONO_DEVICE_ID} + +# create file with environment variables for use with the FMS Forwarder running in the vehicle +cat < hono-mqtt.env +MQTT_URI=mqtts://${HONO_HOST}:8883 +MQTT_USERNAME=${HONO_DEVICE_ID}@${HONO_TENANT_ID} +MQTT_PASSWORD=${HONO_DEVICE_PASSWORD} +TRUST_STORE_PATH=/etc/ssl/certs/ca-certificates.crt +EOF + +cat < hono-kafka.env +KAFKA_TOPIC_NAME=hono.telemetry.${HONO_TENANT_ID} +EOF + +# create properties file for use with the FMS Consumer running in the back end +cat < hono-kafka.properties +bootstrap.servers=${HONO_KAFKA_BROKERS} +group.id=fms-demo-consumer +enable.partition.eof=false +session.timeout.ms=6000 +enable.auto.commit=true +security.protocol=SASL_SSL +sasl.mechanism=SCRAM-SHA-512 +sasl.username=${HONO_KAFKA_USER} +sasl.password=${HONO_KAFKA_PASSWORD} +ssl.ca.location=/etc/ssl/certs/ca-certificates.crt +EOF + +echo "successfully provisioned vehicle device [${HONO_DEVICE_ID}] in tenant [${HONO_TENANT_ID}] for Hono instance [${HONO_HOST}]" diff --git a/spec/.gitignore b/spec/.gitignore new file mode 100644 index 0000000..5de185a --- /dev/null +++ b/spec/.gitignore @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +vss-*/ diff --git a/spec/README.md b/spec/README.md new file mode 100644 index 0000000..1145c23 --- /dev/null +++ b/spec/README.md @@ -0,0 +1,51 @@ + +The Fleet Management Service (FMS) specification defines an HTTP based API for retrieving data gathered during operation of +fleets of trucks and/or buses. The syntax and semantics of data exchanged is defined in the rFMS 4.0 OpenAPI definition +file that can be downloaded from the [FMS website](https://www.fms-standard.com). + +The [mapping-fms4-to-vss.md file](mapping-fms4-to-vss.md) defines a mapping of the data required by FMS to VSS Data Entries. +The [overlay folder](overlay) contains a VSS overlay that defines additional VSS Data Entries for those FMS data points for +which no standard VSS Data Entry exist (yet). The folder also contains a [pre-compiled JSON model file](spec/overlay/vss.json) that +contains all of the definitions from both the standard VSS as well as the overlay vspec files. +This model file can then be read in by the kuksa.val Databroker during startup using the `--metadata` switch. + +Please refer to the [VSS documentation](https://covesa.github.io/vehicle_signal_specification/rule_set/overlay/) for details regarding VSS overlays. + +## Creating the JSON Model File + +The `vspec2json.py` program from the [COVESA VSS tools project](https://github.com/COVESA/vss-tools) can be used to (re-)create the JSON model file that +contains all of the standard VSS Data Entries plus the ones from the FMS overlay file. + +1. Clone the COVESA VSS Signal Specification repository as described in its + [Getting Started guide](https://github.com/COVESA/vehicle_signal_specification#contribute-to-vss). It is important to include the + `--recurse-submodules` in order to initialize the submodule that contains the VSS Tools. +2. Check out the `v4.0` tag: + ```sh + git checkout --recurse-submodules v4.0 + ``` +3. Follow the instructions given in the *Basic Setup* section of the `vss-tools/README.md` file. +4. Run the following command to create the JSON file: + + ```sh + # in folder spec + ${PATH_TO_CLONED_VSS_REPO}/vss-tools/vspec2json.py --strict --json-pretty -e dbc -o overlay/fms.vspec ${PATH_TO_CLONED_VSS_REPO}/spec/VehicleSignalSpecification.vspec overlay/vss.json + ``` diff --git a/spec/mapping-fms4-to-vss.md b/spec/mapping-fms4-to-vss.md new file mode 100644 index 0000000..15c00a8 --- /dev/null +++ b/spec/mapping-fms4-to-vss.md @@ -0,0 +1,144 @@ + +This document provides a mapping of data/object types used in the rFMS 4.0 OpenAPI specification +to VSS paths that either already exist in the VSS 4.0 spec or paths that are defined in the +[FMS overlay file](fms.vspec). + +In the tables below, if the *Impl* column contains `yes` for a property, then +* a mapping from the underlying j1939 signal to VSS has been defined in the [FMS overlay file](fms.vspec), +* the corresponding VSS Data Entries are getting retrieved from the Kuksa.val Databroker as part of the TIMER trigger, +* the values retrieved from the Databroker are included in the data sent by the vehicle to the back end. + +# VehiclePositionObject + +| rFMS property | M/O | rFMS type | rFMS unit | VSS/FMS Overlay path | VSS unit | Impl | +| :------------------------------ | --- | :---------- | :-------- | :---------------------------------------------- | :------- | ---- | +| vin | M | string | | VSS: Vehicle.VehicleIdentification.VIN | | yes | +| gnssPosition.latitude | M | double | WGS84 | VSS: Vehicle.CurrentLocation.Latitude | WGS84 | yes | +| gnssPosition.longitude | M | double | WGS84 | VSS: Vehicle.CurrentLocation.Longitude | WGS84 | yes | +| gnssPosition.heading | O | integer | degrees | VSS: Vehicle.CurrentLocation.Heading | degrees | yes | +| gnssPosition.altitude | O | integer | m | VSS: Vehicle.CurrentLocation.Altitude | m | yes | +| gnssPosition.speed | O | double | km/h | FMS: Vehicle.CurrentLocation.Speed | km/h | yes | +| gnssPosition.positionDateTime | M | date-time | | VSS: Vehicle.CurrentLocation.Timestamp | | yes | +| wheelBasedSpeed | M | double | km/h | VSS: Vehicle.Speed | km/h | yes | +| tachographSpeed | O | double | km/h | FMS: Vehicle.Tachograph.VehicleSpeed | km/h | yes | + +# VehicleStatusObject + +| rFMS property | M/O | rFMS type | rFMS unit | VSS/FMS Overlay path | VSS unit | Impl | +| :------------------------------ | --- | :---------- | :-------- | :---------------------------------------------------------------- | :------- | ---- | +| vin | M | string | | VSS: Vehicle.VehicleIdentification.VIN | | yes | +| hrTotalVehicleDistance | M | int64 | m | FMS: Vehicle.TraveledDistanceHighRes | m | yes | +| totalEngineHours | M/O | double | h | VSS: Vehicle.Powertrain.CombustionEngine.EngineHours | h | yes | +| totalElectricMotorHours | M/O | double | h | FMS: Vehicle.Powertrain.ElectricMotor.MotorHours | h | no | +| engineTotalFuelUsed | M/O | int64 | ml | FMS: Vehicle.Powertrain.FuelSystem.AccumulatedConsumption | ml | yes | +| totalFuelUsedGaseous | M/O | int64 | kg | | | no | +| totalElectricEnergyUsed | M/O | int64 | Wh | VSS: Vehicle.Powertrain.TractionBattery.AccumulatedConsumedEnergy | kWh | no | +| grossCombinationVehicleWeight | O | integer | kg | VSS: Vehicle.CurrentOverallWeight | kg | yes | +| driver1Id | M | [DriverIdObject](#driveridobject) | | FMS: Vehicle.Tachograph.Driver.Driver1 | | yes | +| accumulatedData | O | [AccumulatedDataObject](#accumulateddataobject) | | | | no | +| snapshotData | O | [SnapshotDataObject](#snapshotdataobject) | | | | yes | +| uptimeData | O | [UptimeDataObject](#uptimedataobject) | | | | no | +| status2OfDoors | M(B)| string | | | | no | +| doorStatus | O | array | | | | no | + +# AccumulatedDataObject + +| rFMS property | M/O | rFMS format | rFMS unit | VSS/FMS Overlay path | VSS unit | Impl | +| :------------------------------ | --- | :---------- | :-------- | :------------------------------------- | :------- | ---- | +| durationWheelbasedSpeedOverZero | M | | | | | no | + +TBD + +# SnapshotDataObject + +| rFMS property | M/O | rFMS format | rFMS unit | VSS/FMS Overlay path | VSS unit | Impl | +| :---------------------------------------- | --- | :---------- | :-------- | :--------------------------------------- | :------- | ---- | +| gnssPosition.latitude | M | double | WGS84 | VSS: Vehicle.CurrentLocation.Latitude | WGS84 | yes | +| gnssPosition.longitude | M | double | WGS84 | VSS: Vehicle.CurrentLocation.Longitude | WGS84 | yes | +| gnssPosition.heading | O | integer | degrees | VSS: Vehicle.CurrentLocation.Heading | degrees | yes | +| gnssPosition.altitude | O | integer | m | VSS: Vehicle.CurrentLocation.Altitude | m | yes | +| gnssPosition.speed | O | double | km/h | FMS: Vehicle.CurrentLocation.Speed | km/h | yes | +| gnssPosition.positionDateTime | M | date-time | | VSS: Vehicle.CurrentLocation.Timestamp | | yes | +| wheelBasedSpeed | M | double | km/h | VSS: Vehicle.Speed | km/h | yes | +| tachographSpeed | O | double | km/h | FMS: Vehicle.Tachograph.VehicleSpeed | km/h | yes | +| engineSpeed | O | double | rpm | VSS: Vehicle.Powertrain.CombustionEngine.Speed | rpm | yes | +| electricMotorSpeed | O | double | rpm | VSS: Vehicle.Powertrain.ElectricMotor.Speed | rpm | no | +| fuelType | O | string | | FMS: Vehicle.Powertrain.CurrentFuelType | enum | no | +| fuelLevel1 | M | double | % | FMS: Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel | % | yes | +| fuelLevel2 | O | double | % | FMS: Vehicle.Powertrain.FuelSystem.Tank.Second.RelativeLevel | % | yes | +| catalystFuelLevel | O | double | % | VSS: Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Level | % | yes | +| driver1WorkingState | O | string | | FMS: Vehicle.Tachograph.Driver.Driver1.WorkingState | | yes | +| driver2Id | O | [DriverIdObject](#driveridobject) | | FMS: Vehicle.Tachograph.Driver.Driver2 | | no | +| driver2WorkingState | O | string | | FMS: Vehicle.Tachograph.Driver.Driver2.WorkingState | | yes | +| ambientAirTemperature | O | double | celsius | VSS: Vehicle.Exterior.AirTemperature | celsius | yes | +| parkingBrakeSwitch | O | boolean | | VSS: Vehicle.Chassis.ParkingBrake.IsEngaged | | yes | +| hybridBatteryPackRemainingCharge | O | double | % | VSS: Vehicle.Powertrain.TractionBattery.StateOfCharge.Current | % | no | +| batteryPackChargingStatus | O | string | enum | VSS: Vehicle.Powertrain.TractionBattery.Charging.IsCharging | | no | +| batteryPackChargingConnectionStatus | O | string | enum | VSS: Vehicle.Powertrain.TractionBattery.Charging.IsChargingCableConnected | | no | +| batteryPackChargingDevice | O | string | enum | | | no | +| batteryPackChargingPower | O | double | W | VSS: Vehicle.Powertrain.TractionBattery.Charging.ChargeCurrent.DC | A | no | +| | | | | VSS: Vehicle.Powertrain.TractionBattery.Charging.ChargeVoltage.DC | V | no | +| estimatedTimeBatteryPackChargingCompleted | O | date-time | | VSS: Vehicle.Powertrain.TractionBattery.Charging.TimeToComplete | s | no | +| estimatedDistanceToEmpty.total | M | int64 | m | VSS: Vehicle.Powertrain.Range | m | yes | +| estimatedDistanceToEmpty.fuel | O | int64 | m | VSS: Vehicle.Powertrain.FuelSystem.Range | m | yes | +| estimatedDistanceToEmpty.gas | O | | | | | no | +| estimatedDistanceToEmpty.batteryPack | O | int64 | m | VSS: Vehicle.Powertrain.TractionBattery.Range | m | no | +| vehicleAxles | O | array | | | | no | +| trailers | O | array | | | | no | + +# UptimeDataObject + +| rFMS property | M/O | rFMS format | rFMS unit | VSS/FMS Overlay path | VSS unit | Impl | +| :------------------------------ | --- | :---------- | :-------- | :---------------------------------------------------------- | :------- | ---- | +| tellTaleInfo | M | array | | FMS: Vehicle.Cabin.Telltale.* | enum | no | +| serviceDistance | O | int64 | m | VSS: Vehicle.Service.DistanceToService | km | no | +| engineCoolantTemperature | O | double | celsius | VSS: Vehicle.Powertrain.CombustionEngine.ECT | celsius | no | +| hvessOutletCoolantTemperature | O | double | celsius | FMS: Vehicle.Powertrain.TractionBattery.CoolantTemperature | celsius | no | +| hvessTemperature | O | double | celsius | VSS: Vehicle.Powertrain.TractionBattery.Temperature.Average | celsius | no | +| serviceBrakeAirPressureCircuit1 | O | int64 | pascal | FMS: Vehicle.Chassis.Brake.Circuit1.AirPressure | pascal | no | +| serviceBrakeAirPressureCircuit2 | O | int64 | pascal | FMS: Vehicle.Chassis.Brake.Circuit2.AirPressure | pascal | no | +| durationAtLeastOneDoorOpen | O | | | | | no | +| alternatorInfo.alternatorStatus | M(B)| | | | | no | +| alternatorInfo.alternatorNumber | M(B)| | | | | no | +| bellowPressureFrontAxleLeft | O | | | | | no | +| bellowPressureFrontAxleRight | O | | | | | no | +| bellowPressureRearAxleLeft | O | | | | | no | +| bellowPressureRearAxleRight | O | | | | | no | + +# DriverIdObject + +## DriverIdObject.tachoDriverIdentification + +| rFMS property | M/O | VSS/FMS Overlay path | Impl | +| :------------------------------ | --- | :----------------------------------------------------- | ---- | +| driverIdentification | M | FMS: Vehicle.Tachograph.Driver.Identification | yes | +| cardIssuingMemberState | M | FMS: Vehicle.Tachograph.Driver.CardIssuingMemberState | no | +| driverAuthenticationEquipment | O | FMS: Vehicle.Tachograph.Driver.AuthenticationEquipment | no | +| cardReplacementIndex | O | FMS: Vehicle.Tachograph.Driver.CardReplacementIndex | no | +| cardRenewalIndex | O | FMS: Vehicle.Tachograph.Driver.CardRenewalIndex | no | + +## DriverIdObject.oemDriverIdentification + +| rFMS property | M/O | VSS/FMS Overlay path | Impl | +| :------------------------------ | --- | :--------------------------------------------------- | ---- | +| oemDriverIdentification | O | FMS: Vehicle.Tachograph.Driver.OemIdentification | no | +| idType | O | FMS: Vehicle.Tachograph.Driver.OemIdentificationType | no | diff --git a/spec/overlay/fms.vspec b/spec/overlay/fms.vspec new file mode 100644 index 0000000..977a951 --- /dev/null +++ b/spec/overlay/fms.vspec @@ -0,0 +1,540 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +# Overlay to provide [FMS Standard labels](http://www.fms-standard.com/Truck/index.htm) in VSS 3.0 +# Dependencies to other overlays: None +# Known conflicts with other overlays: None +# +# The Data Entries are sorted lexicographically +# + +Vehicle.ADAS.CruiseControl.IsActive: + datatype: boolean + type: sensor + description: | + Indicates if cruise control is switched on. It is not ensured that the engine is controlled by cruise control, + as in the case of a large driver's demand the engine is controlled by the driver while cruise control is active + (maximum selection of cruise control and driver's demand). The cruise control is set to false if a switch-off + condition occurs. + +Vehicle.ADAS.CruiseControl.IsBrakePressed: + datatype: boolean + type: sensor + description: | + Switch signal which indicates that the driver operated brake foot pedal is being pressed. + This brake foot pedal is controlling the vehicles' service brake (total vehicle braking application, + not park brakes). It is necessary for safe drivetrain behavior that the switch activates before the + physical braking components are activated (i.e. Disengage the cruise control function prior to the + activation of friction brakes) + +Vehicle.ADAS.CruiseControl.IsClutchPressed: + datatype: boolean + type: sensor + description: | + Switch signal which indicates that the clutch pedal is being pressed + +Vehicle.ADAS.CruiseControl.IsPowerTakeOffOn: + datatype: boolean + type: sensor + description: | + This parameter is used to indicate the current state or mode of operation by the power takeoff (PTO) device + +Vehicle.ADAS.CruiseControl.Status: + datatype: string + type: sensor + description: | + This parameter is used to indicate the current state, or mode, of operation by the cruise control device. + allowed: + - "OFF" + - "HOLD" + - "ACCELERATE" + - "DECELERATE" + - "RESUME" + - "SET" + - "ACCEL_OVERRIDE" + - "NOT_AVAILABLE" + +Vehicle.Cabin.Telltale: + type: branch + instances: ["ECT", "Engine", "EngineOil", "FuelLevel", "ParkingBrake"] + description: A set of telltale status values. + +Vehicle.Cabin.Telltale.Status: + type: sensor + datatype: string + description: The current status of a telltale. + allowed: + - "OFF" + - "RED" + - "YELLOW" + - "INFO" + - "NOT_AVAILABLE" + +Vehicle.Cabin.Telltale.ECT.Status: + datatype: string + type: sensor + description: | + The telltale indicating the status of the engine coolant temperature. + +Vehicle.Cabin.Telltale.Engine.Status: + datatype: string + type: sensor + description: | + The telltale indicating the status of the engine. + +Vehicle.Cabin.Telltale.EngineOil.Status: + datatype: string + type: sensor + description: | + The telltale indicating the status of the engine oil level. + +Vehicle.Cabin.Telltale.FuelLevel.Status: + datatype: string + type: sensor + description: | + The telltale indicating the status of the fuel level. + +Vehicle.Cabin.Telltale.ParkingBrake.Status: + datatype: string + type: sensor + description: | + The telltale indicating the status of the parking brake. + +# +# Attempt to override core Axle definition, to allow for more Axles +# +Vehicle.Chassis.Axle: + instances: + - Row[1,6] + type: branch + description: Axle signals + +Vehicle.Chassis.Brake: + type: branch + instances: Circuit[1, 2] + +Vehicle.Chassis.Brake.AirPressure: + type: sensor + datatype: uint32 + unit: kPa + description: The current air pressure in the brake circuit. + +Vehicle.Chassis.Brake.Circuit1.AirPressure: + type: sensor + datatype: uint32 + description: | + The pneumatic pressure in the primary service brake circuit or reservoir, supplying the rear axle. + +Vehicle.Chassis.Brake.Circuit2.AirPressure: + type: sensor + datatype: uint32 + description: | + The pneumatic pressure in the secondary service brake circuit or reservoir, supplying the front axle. + +Vehicle.Chassis.ParkingBrake.IsEngaged: + datatype: boolean + type: sensor + + +Vehicle.CurrentLocation.Latitude: + datatype: double + type: sensor + +Vehicle.CurrentLocation.Longitude: + datatype: double + type: sensor + +Vehicle.CurrentLocation.Speed: + datatype: double + type: sensor + unit: km/h + description: | + The vehicle's current speed as as measured by the GNSS receiver antenna. + +Vehicle.CurrentOverallWeight: + type: sensor + # expand to uint32 in order to support typical (large) weight of commercial verhicles + datatype: uint32 + +Vehicle.Exterior.AirTemperature: + datatype: float + type: sensor + +Vehicle.IsMoving: + datatype: boolean + type: sensor + +Vehicle.Powertrain.Brake: + type: branch + description: Recuperation data. + +Vehicle.Powertrain.Brake.ActualRetarderPercentage: + datatype: uint8 + type: sensor + unit: percent + min: 0 + max: 100 + description: Actual braking torque of the retarder + +Vehicle.Powertrain.CombustionEngine.ActualEnginePercentTorque: + datatype: uint8 + type: sensor + unit: percent + min: 0 + max: 100 + description: The calculated output torque of the engine; the data is transmitted in indicated torque as a percent of reference engine + +Vehicle.Powertrain.CombustionEngine.DieselExhaustFluid.Level: + datatype: uint8 + type: sensor + +Vehicle.Powertrain.CombustionEngine.ECT: + datatype: int16 + type: sensor + +Vehicle.Powertrain.CombustionEngine.EngineHours: + datatype: float + type: sensor + +Vehicle.Powertrain.CombustionEngine.Speed: + datatype: uint16 + type: sensor + +Vehicle.Powertrain.CurrentFuelType: + datatype: string + type: sensor + description: Type of fuel currently being utilized by the vehicle. + allowed: + - "NONE" + - "GAS" + - "METH" + - "ETH" + - "DSL" + - "LPG" + - "CNG" + - "PROP" + - "ELEC" + - "BI_GAS" + - "BI_METH" + - "BI_ETH" + - "BI_LPG" + - "BI_CNG" + - "BI_PROP" + - "BI_ELEC" + - "BI_MIX" + - "HYB_GAS" + - "HYB_ETH" + - "HYB_DSL" + - "HYB_ELEC" + - "HYB_MIX" + - "HYB_REG" + - "NG" + - "BI_NG" + - "BI_DSL" + - "ERROR" + - "NOT_AVAILABLE" + +Vehicle.Powertrain.Eec2AcceleratorPedalPosition: + datatype: double + type: sensor + unit: percent + min: 0 + description: | + The ratio of actual position of the analogue engine speed/torque request input device + (such as an accelerator pedal or throttle lever) to the maximum position of the input device + +Vehicle.Powertrain.Eec2EnginePercentLoad: + datatype: uint8 + type: sensor + unit: percent + min: 0 + max: 125 + description: | + The ratio of actual engine percent torque (indicated) to maximum indicated torque available at + the current engine speed, clipped to zero torque during engine braking + +Vehicle.Powertrain.ElectricMotor.MotorHours: + datatype: float + type: sensor + unit: h + min: 0.0 + description: Accumulated time during motor lifetime with 'motor speed (rpm) > 0'. + +Vehicle.Powertrain.FuelSystem.AccumulatedConsumption: + datatype: uint64 + type: sensor + unit: ml + description: Accumulated amount of fuel used during vehicle operation. + +Vehicle.Powertrain.FuelSystem.Range: + datatype: uint32 + type: sensor + +Vehicle.Powertrain.FuelSystem.Tank: + type: branch + instances: ["First","Second"] + description: Information about the first and (optional) second fuel tank. + +Vehicle.Powertrain.FuelSystem.Tank.RelativeLevel: + datatype: float + type: sensor + unit: percent + min: 0.0 + max: 100.0 + description: Level in fuel tank as percent of capacity. 0 = empty. 100 = full. + +Vehicle.Powertrain.FuelSystem.Tank.First.RelativeLevel: + datatype: float + type: sensor + +Vehicle.Powertrain.FuelSystem.Tank.Second.RelativeLevel: + datatype: float + type: sensor + +Vehicle.Powertrain.FuelSystem.Tank.Fuel: + datatype: string + type: sensor + allowed: ['GASOLINE', 'DIESEL', 'E85', 'LPG', 'CNG', 'LNG', 'H2', 'OTHER'] + description: | + Detailed information on fuel in tank. Identifiers originating from DIN EN 16942:2021-08, + appendix B, with additional suffix for octane (RON) where relevant. + +# Vehicle.Powertrain.Range: +# datatype: uint32 +# type: sensor + +Vehicle.Powertrain.TractionBattery.CoolantTemperature: + datatype: uint8 + type: sensor + unit: celsius + description: | + The temperature of the battery pack coolant. + +# We do not have a DBC mapping entry for this PGN (yet) +#Vehicle.Powertrain.TractionBattery.Range: +# datatype: uint32 +# type: sensor + +Vehicle.Powertrain.TractionBattery.StateOfCharge.Current: + datatype: float + type: sensor + + +Vehicle.Service.DistanceToService: + datatype: float + type: sensor + + +Vehicle.Speed: + type: sensor + datatype: float + + +Vehicle.Tachograph: + type: branch + description: Tachograph related data. + +Vehicle.Tachograph.DirectionIndicator: + datatype: string + type: sensor + description: | + Indicates the direction of the vehicle + +Vehicle.Tachograph.Driver: + type: branch + instances: + - Driver[1,2] + description: Information about the driver(s) of a (commercial) vehicle. + +Vehicle.Tachograph.Driver.Identification: + datatype: string + type: attribute + description: The unique identification of a driver in a Member State. + comment: | + This field is formatted according the definition for driverIdentification + in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b. + +Vehicle.Tachograph.Driver.CardIssuingMemberState: + datatype: string + type: attribute + description: The country alpha code of the Member State having issued the card. + comment: | + This field is formatted according the definition for NationAlpha + in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b. + +Vehicle.Tachograph.Driver.AuthenticationEquipment: + datatype: string + type: attribute + description: Code to distinguish different types of equipment for the tachograph application. + comment: | + See description of the field 'DriverAuthenticationEquipment' + in COMMISSION REGULATION (EC) No 1360/2002 Annex 1b. + allowed: + - RESERVED + - DRIVER_CARD + - CONTROL_CARD + - COMPANY_CARD + - MANUFACTURING_CARD + - VEHICLE_UNIT + - MOTION_SENSOR + +Vehicle.Tachograph.Driver.CardReplacementIndex: + datatype: string + type: attribute + description: A card replacement index. + comment: | + This field is formatted according the definition for CardReplacementIndex + (chap 2.26) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b. + +Vehicle.Tachograph.Driver.CardRenewalIndex: + datatype: string + type: attribute + description: A card renewal index. + comment: | + This field is formatted according the definition for CardRenewalIndex + (chap 2.25) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b. + +Vehicle.Tachograph.Driver.IsCardPresent: + datatype: boolean + type: sensor + description: Indicates the presence of a driver card + +Vehicle.Tachograph.Driver.Driver1.IsCardPresent: + datatype: boolean + type: sensor + +Vehicle.Tachograph.Driver.Driver2.IsCardPresent: + datatype: boolean + type: sensor + +# TODO maybe we do not need this flag but can instead simply rely on the fact +# that the Identification attribute has a (non-empty) value or not. +Vehicle.Tachograph.Driver.IsLoggedIn: + datatype: boolean + type: attribute + description: Indicates if the driver is currently logged in. + +Vehicle.Tachograph.Driver.OemIdentification: + datatype: string + type: attribute + description: An OEM specific driver id. + +Vehicle.Tachograph.Driver.OemIdentificationType: + datatype: string + type: attribute + description: Contains an optional id type (e.g. pin, USB, encrypted EU id). + +Vehicle.Tachograph.Driver.TimeRelatedStatus: + datatype: string + type: sensor + description: | + Indicates if the driver approaches or exceeds working time limits (or other limits). + allowed: + - "NORMAL" + - "LIMIT_1" + - "LIMIT_2" + - "LIMIT_3" + - "LIMIT_4" + - "LIMIT_5" + - "LIMIT_6" + - "OTHER" + - "ERROR" + - "NOT_AVAILABLE" + +Vehicle.Tachograph.Driver.Driver1.TimeRelatedStatus: + datatype: string + type: sensor + +Vehicle.Tachograph.Driver.Driver2.TimeRelatedStatus: + datatype: string + type: sensor + +Vehicle.Tachograph.Driver.WorkingState: + datatype: string + type: attribute + description: | + The current working state of the driver. + 0 - rest + 1 - driver available + 2 - work + 3 - drive + 6 - error + 7 - not available + allowed: + - "DRIVE" + - "WORK" + - "DRIVER_AVAILABLE" + - "REST" + - "ERROR" + - "NOT_AVAILABLE" + +Vehicle.Tachograph.Driver.Driver1.WorkingState: + datatype: string + type: attribute + +Vehicle.Tachograph.Driver.Driver2.WorkingState: + datatype: string + type: attribute + +Vehicle.Tachograph.IsAnalyzingPerformance: + datatype: boolean + type: sensor + description: | + Indicates whether the tachograph is currently analyzing its performance; + including electronic or mechanical analysis, instrument analysis, speed sensor analysis, + mass storage analysis, and printer analysis + +Vehicle.Tachograph.IsHandlingInformationPresent: + datatype: boolean + type: sensor + description: | + Indicates that handling information is present. Information could include 'no printer paper', 'no driver card', etc + +Vehicle.Tachograph.IsOverspeed: + datatype: boolean + type: sensor + description: | + Indicates whether the vehicle is exceeding the legal speed limit set in the tachograph. + +Vehicle.Tachograph.IsSystemEventAvailable: + datatype: boolean + type: sensor + description: | + Indicates that a tachograph event has occurred. This may include power supply interruption, + interruption of the speed sensor, incorrect data on the driver card, driving without a driver + card, illegal removal of a driver card, insertion of a driver card during driving, and time adjustment + +Vehicle.Tachograph.VehicleSpeed: + datatype: double + type: sensor + unit: km/h + min: 0.0 + description: Speed of the vehicle registered by the tachograph. + + +Vehicle.TraveledDistanceHighRes: + datatype: uint64 + type: sensor + unit: "m" + description: Accumulated distance travelled by the vehicle during its operation. + + +Vehicle.VehicleIdentification.VIN: + datatype: string + type: attribute diff --git a/spec/overlay/vss.json b/spec/overlay/vss.json new file mode 100644 index 0000000..a83f3c7 --- /dev/null +++ b/spec/overlay/vss.json @@ -0,0 +1,9032 @@ +{ + "Vehicle": { + "children": { + "ADAS": { + "children": { + "ABS": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if ABS is enabled. True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsEngaged": { + "datatype": "boolean", + "description": "Indicates if ABS is currently regulating brake pressure. True = Engaged. False = Not Engaged.", + "type": "sensor" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if ABS incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + } + }, + "description": "Antilock Braking System signals.", + "type": "branch" + }, + "ActiveAutonomyLevel": { + "allowed": [ + "SAE_0", + "SAE_1", + "SAE_2_DISENGAGING", + "SAE_2", + "SAE_3_DISENGAGING", + "SAE_3", + "SAE_4_DISENGAGING", + "SAE_4", + "SAE_5" + ], + "comment": "Follows https://www.sae.org/news/2019/01/sae-updates-j3016-automated-driving-graphic taxonomy. For SAE levels 3 and 4 the system is required to alert the driver before it will disengage. Level 4 systems are required to reach a safe state even if a driver does not take over. Only level 5 systems are required to not rely on a driver at all. While level 2 systems require the driver to be monitoring the system at all times, many level 2 systems, often termed \"level 2.5\" systems, do warn the driver shortly before reaching their operational limits, therefore we also support the DISENGAGING state for SAE_2.", + "datatype": "string", + "description": "Indicates the currently active level of autonomy according to SAE J3016 taxonomy.", + "type": "sensor" + }, + "CruiseControl": { + "children": { + "IsActive": { + "datatype": "boolean", + "description": "Indicates if cruise control is switched on. It is not ensured that the engine is controlled by cruise control,\nas in the case of a large driver's demand the engine is controlled by the driver while cruise control is active\n(maximum selection of cruise control and driver's demand). The cruise control is set to false if a switch-off\ncondition occurs.\n", + "type": "sensor" + }, + "IsBrakePressed": { + "datatype": "boolean", + "description": "Switch signal which indicates that the driver operated brake foot pedal is being pressed.\nThis brake foot pedal is controlling the vehicles' service brake (total vehicle braking application,\nnot park brakes). It is necessary for safe drivetrain behavior that the switch activates before the\nphysical braking components are activated (i.e. Disengage the cruise control function prior to the\nactivation of friction brakes)\n", + "type": "sensor" + }, + "IsClutchPressed": { + "datatype": "boolean", + "description": "Switch signal which indicates that the clutch pedal is being pressed\n", + "type": "sensor" + }, + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if cruise control system is enabled (e.g. ready to receive configurations and settings) True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if cruise control system incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + }, + "IsPowerTakeOffOn": { + "datatype": "boolean", + "description": "This parameter is used to indicate the current state or mode of operation by the power takeoff (PTO) device\n", + "type": "sensor" + }, + "SpeedSet": { + "datatype": "float", + "description": "Set cruise control speed in kilometers per hour.", + "type": "actuator", + "unit": "km/h" + }, + "Status": { + "allowed": [ + "OFF", + "HOLD", + "ACCELERATE", + "DECELERATE", + "RESUME", + "SET", + "ACCEL_OVERRIDE", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "This parameter is used to indicate the current state, or mode, of operation by the cruise control device.\n", + "type": "sensor" + } + }, + "description": "Signals from Cruise Control system.", + "type": "branch" + }, + "DMS": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if DMS is enabled. True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if DMS incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + }, + "IsWarning": { + "datatype": "boolean", + "description": "Indicates if DMS has registered a driver alert condition.", + "type": "sensor" + } + }, + "description": "Driver Monitoring System signals.", + "type": "branch" + }, + "EBA": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if EBA is enabled. True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsEngaged": { + "datatype": "boolean", + "description": "Indicates if EBA is currently regulating brake pressure. True = Engaged. False = Not Engaged.", + "type": "sensor" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if EBA incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + } + }, + "description": "Emergency Brake Assist (EBA) System signals.", + "type": "branch" + }, + "EBD": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if EBD is enabled. True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsEngaged": { + "datatype": "boolean", + "description": "Indicates if EBD is currently regulating vehicle brakeforce distribution. True = Engaged. False = Not Engaged.", + "type": "sensor" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if EBD incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + } + }, + "description": "Electronic Brakeforce Distribution (EBD) System signals.", + "type": "branch" + }, + "ESC": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if ESC is enabled. True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsEngaged": { + "datatype": "boolean", + "description": "Indicates if ESC is currently regulating vehicle stability. True = Engaged. False = Not Engaged.", + "type": "sensor" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if ESC incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + }, + "IsStrongCrossWindDetected": { + "datatype": "boolean", + "description": "Indicates if the ESC system is detecting strong cross winds. True = Strong cross winds detected. False = No strong cross winds detected.", + "type": "sensor" + }, + "RoadFriction": { + "children": { + "LowerBound": { + "datatype": "float", + "description": "Lower bound road friction, as calculated by the ESC system. 5% possibility that road friction is below this value. 0 = no friction, 100 = maximum friction.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "MostProbable": { + "datatype": "float", + "description": "Most probable road friction, as calculated by the ESC system. Exact meaning of most probable is implementation specific. 0 = no friction, 100 = maximum friction.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "UpperBound": { + "datatype": "float", + "description": "Upper bound road friction, as calculated by the ESC system. 95% possibility that road friction is below this value. 0 = no friction, 100 = maximum friction.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Road friction values reported by the ESC system.", + "type": "branch" + } + }, + "description": "Electronic Stability Control System signals.", + "type": "branch" + }, + "LaneDepartureDetection": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if lane departure detection system is enabled. True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if lane departure system incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + }, + "IsWarning": { + "datatype": "boolean", + "description": "Indicates if lane departure detection registered a lane departure.", + "type": "sensor" + } + }, + "description": "Signals from Lane Departure Detection System.", + "type": "branch" + }, + "ObstacleDetection": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if obstacle sensor system is enabled (i.e. monitoring for obstacles). True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if obstacle sensor system incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + }, + "IsWarning": { + "datatype": "boolean", + "description": "Indicates if obstacle sensor system registered an obstacle.", + "type": "sensor" + } + }, + "description": "Signals form Obstacle Sensor System.", + "type": "branch" + }, + "PowerOptimizeLevel": { + "datatype": "uint8", + "description": "Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.", + "max": 10, + "min": 0, + "type": "actuator" + }, + "SupportedAutonomyLevel": { + "allowed": [ + "SAE_0", + "SAE_1", + "SAE_2", + "SAE_3", + "SAE_4", + "SAE_5" + ], + "datatype": "string", + "description": "Indicates the highest level of autonomy according to SAE J3016 taxonomy the vehicle is capable of.", + "type": "attribute" + }, + "TCS": { + "children": { + "IsEnabled": { + "datatype": "boolean", + "description": "Indicates if TCS is enabled. True = Enabled. False = Disabled.", + "type": "actuator" + }, + "IsEngaged": { + "datatype": "boolean", + "description": "Indicates if TCS is currently regulating traction. True = Engaged. False = Not Engaged.", + "type": "sensor" + }, + "IsError": { + "datatype": "boolean", + "description": "Indicates if TCS incurred an error condition. True = Error. False = No Error.", + "type": "sensor" + } + }, + "description": "Traction Control System signals.", + "type": "branch" + } + }, + "description": "All Advanced Driver Assist Systems data.", + "type": "branch" + }, + "Acceleration": { + "children": { + "Lateral": { + "datatype": "float", + "description": "Vehicle acceleration in Y (lateral acceleration).", + "type": "sensor", + "unit": "m/s^2" + }, + "Longitudinal": { + "datatype": "float", + "description": "Vehicle acceleration in X (longitudinal acceleration).", + "type": "sensor", + "unit": "m/s^2" + }, + "Vertical": { + "datatype": "float", + "description": "Vehicle acceleration in Z (vertical acceleration).", + "type": "sensor", + "unit": "m/s^2" + } + }, + "description": "Spatial acceleration. Axis definitions according to ISO 8855.", + "type": "branch" + }, + "AngularVelocity": { + "children": { + "Pitch": { + "datatype": "float", + "description": "Vehicle rotation rate along Y (lateral).", + "type": "sensor", + "unit": "degrees/s" + }, + "Roll": { + "datatype": "float", + "description": "Vehicle rotation rate along X (longitudinal).", + "type": "sensor", + "unit": "degrees/s" + }, + "Yaw": { + "datatype": "float", + "description": "Vehicle rotation rate along Z (vertical).", + "type": "sensor", + "unit": "degrees/s" + } + }, + "description": "Spatial rotation. Axis definitions according to ISO 8855.", + "type": "branch" + }, + "AverageSpeed": { + "comment": "A new trip is considered to start when engine gets enabled (e.g. LowVoltageSystemState in ON or START mode). A trip is considered to end when engine is no longer enabled. The signal may however keep the value of the last trip until a new trip is started. Calculation of average speed may exclude periods when the vehicle for example is not moving or transmission is in neutral.", + "datatype": "float", + "description": "Average speed for the current trip.", + "type": "sensor", + "unit": "km/h" + }, + "Body": { + "children": { + "BodyType": { + "datatype": "string", + "description": "Body type code as defined by ISO 3779.", + "type": "attribute" + }, + "Hood": { + "children": { + "IsOpen": { + "datatype": "boolean", + "description": "Hood open or closed. True = Open. False = Closed.", + "type": "actuator" + } + }, + "comment": "The hood is the hinged cover over the engine compartment of a motor vehicles. Depending on vehicle, it can be either in the front or back of the vehicle. Luggage compartments are in VSS called trunks, even if they are located at the front of the vehicle.", + "description": "Hood status.", + "type": "branch" + }, + "Horn": { + "children": { + "IsActive": { + "datatype": "boolean", + "description": "Horn active or inactive. True = Active. False = Inactive.", + "type": "actuator" + } + }, + "description": "Horn signals.", + "type": "branch" + }, + "Lights": { + "children": { + "Backup": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "Backup lights.", + "type": "branch" + }, + "Beam": { + "children": { + "High": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "Beam lights.", + "type": "branch" + }, + "Low": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "Beam lights.", + "type": "branch" + } + }, + "description": "Beam lights.", + "type": "branch" + }, + "Brake": { + "children": { + "IsActive": { + "allowed": [ + "INACTIVE", + "ACTIVE", + "ADAPTIVE" + ], + "datatype": "string", + "description": "Indicates if break-light is active. INACTIVE means lights are off. ACTIVE means lights are on. ADAPTIVE means that break-light is indicating emergency-breaking.", + "type": "actuator" + }, + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + } + }, + "description": "Brake lights.", + "type": "branch" + }, + "DirectionIndicator": { + "children": { + "Left": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsSignaling": { + "datatype": "boolean", + "description": "Indicates if light is signaling or off. True = signaling. False = Off.", + "type": "actuator" + } + }, + "description": "Indicator lights.", + "type": "branch" + }, + "Right": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsSignaling": { + "datatype": "boolean", + "description": "Indicates if light is signaling or off. True = signaling. False = Off.", + "type": "actuator" + } + }, + "description": "Indicator lights.", + "type": "branch" + } + }, + "description": "Indicator lights.", + "type": "branch" + }, + "Fog": { + "children": { + "Front": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "Fog lights.", + "type": "branch" + }, + "Rear": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "Fog lights.", + "type": "branch" + } + }, + "description": "Fog lights.", + "type": "branch" + }, + "Hazard": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsSignaling": { + "datatype": "boolean", + "description": "Indicates if light is signaling or off. True = signaling. False = Off.", + "type": "actuator" + } + }, + "description": "Hazard lights.", + "type": "branch" + }, + "IsHighBeamSwitchOn": { + "comment": "This signal indicates the status of the switch and does not indicate if low or high beam actually are on. That typically depends on vehicle logic and other signals like Lights.LightSwitch and Vehicle.LowVoltageSystemState.", + "datatype": "boolean", + "description": "Status of the high beam switch. True = high beam enabled. False = high beam not enabled.", + "type": "actuator" + }, + "LicensePlate": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "License plate lights.", + "type": "branch" + }, + "LightSwitch": { + "allowed": [ + "OFF", + "POSITION", + "DAYTIME_RUNNING_LIGHTS", + "AUTO", + "BEAM" + ], + "comment": "A vehicle typically does not support all alternatives. Which lights that actually are lit may vary according to vehicle configuration and local legislation. OFF is typically indicated by 0. POSITION is typically indicated by ISO 7000 symbol 0456. DAYTIME_RUNNING_LIGHTS (DRL) can be indicated by ISO 7000 symbol 2611. AUTO indicates that vehicle automatically selects suitable lights. BEAM is typically indicated by ISO 7000 symbol 0083.", + "datatype": "string", + "description": "Status of the vehicle main light switch.", + "type": "actuator" + }, + "Parking": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "Parking lights.", + "type": "branch" + }, + "Running": { + "children": { + "IsDefect": { + "datatype": "boolean", + "description": "Indicates if light is defect. True = Light is defect. False = Light has no defect.", + "type": "sensor" + }, + "IsOn": { + "datatype": "boolean", + "description": "Indicates if light is on or off. True = On. False = Off.", + "type": "actuator" + } + }, + "description": "Running lights.", + "type": "branch" + } + }, + "description": "Exterior lights.", + "type": "branch" + }, + "Mirrors": { + "children": { + "DriverSide": { + "children": { + "IsHeatingOn": { + "datatype": "boolean", + "description": "Mirror Heater on or off. True = Heater On. False = Heater Off.", + "type": "actuator" + }, + "Pan": { + "datatype": "int8", + "description": "Mirror pan as a percent. 0 = Center Position. 100 = Fully Left Position. -100 = Fully Right Position.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Tilt": { + "datatype": "int8", + "description": "Mirror tilt as a percent. 0 = Center Position. 100 = Fully Upward Position. -100 = Fully Downward Position.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + } + }, + "description": "All mirrors.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "IsHeatingOn": { + "datatype": "boolean", + "description": "Mirror Heater on or off. True = Heater On. False = Heater Off.", + "type": "actuator" + }, + "Pan": { + "datatype": "int8", + "description": "Mirror pan as a percent. 0 = Center Position. 100 = Fully Left Position. -100 = Fully Right Position.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Tilt": { + "datatype": "int8", + "description": "Mirror tilt as a percent. 0 = Center Position. 100 = Fully Upward Position. -100 = Fully Downward Position.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + } + }, + "description": "All mirrors.", + "type": "branch" + } + }, + "description": "All mirrors.", + "type": "branch" + }, + "PowerOptimizeLevel": { + "datatype": "uint8", + "description": "Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.", + "max": 10, + "min": 0, + "type": "actuator" + }, + "Raindetection": { + "children": { + "Intensity": { + "datatype": "uint8", + "description": "Rain intensity. 0 = Dry, No Rain. 100 = Covered.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Rain sensor signals.", + "type": "branch" + }, + "RearMainSpoilerPosition": { + "datatype": "float", + "description": "Rear spoiler position, 0% = Spoiler fully stowed. 100% = Spoiler fully exposed.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "RefuelPosition": { + "allowed": [ + "FRONT_LEFT", + "FRONT_RIGHT", + "MIDDLE_LEFT", + "MIDDLE_RIGHT", + "REAR_LEFT", + "REAR_RIGHT" + ], + "datatype": "string", + "description": "Location of the fuel cap or charge port.", + "type": "attribute" + }, + "Trunk": { + "children": { + "Front": { + "children": { + "IsLightOn": { + "comment": "V4.0 Moved from Vehicle.Cabin.Lights.IsTrunkOn because Trunk is not defined as part of the Cabin.", + "datatype": "boolean", + "description": "Is trunk light on", + "type": "actuator" + }, + "IsLocked": { + "datatype": "boolean", + "description": "Is trunk locked or unlocked. True = Locked. False = Unlocked.", + "type": "actuator" + }, + "IsOpen": { + "datatype": "boolean", + "description": "Trunk open or closed. True = Open. False = Closed.", + "type": "actuator" + } + }, + "comment": "A trunk is a luggage compartment in a vehicle. Depending on vehicle, it can be either in the front or back of the vehicle. Some vehicles may have trunks both at the front and at the rear of the vehicle.", + "description": "Trunk status.", + "type": "branch" + }, + "Rear": { + "children": { + "IsLightOn": { + "comment": "V4.0 Moved from Vehicle.Cabin.Lights.IsTrunkOn because Trunk is not defined as part of the Cabin.", + "datatype": "boolean", + "description": "Is trunk light on", + "type": "actuator" + }, + "IsLocked": { + "datatype": "boolean", + "description": "Is trunk locked or unlocked. True = Locked. False = Unlocked.", + "type": "actuator" + }, + "IsOpen": { + "datatype": "boolean", + "description": "Trunk open or closed. True = Open. False = Closed.", + "type": "actuator" + } + }, + "comment": "A trunk is a luggage compartment in a vehicle. Depending on vehicle, it can be either in the front or back of the vehicle. Some vehicles may have trunks both at the front and at the rear of the vehicle.", + "description": "Trunk status.", + "type": "branch" + } + }, + "comment": "A trunk is a luggage compartment in a vehicle. Depending on vehicle, it can be either in the front or back of the vehicle. Some vehicles may have trunks both at the front and at the rear of the vehicle.", + "description": "Trunk status.", + "type": "branch" + }, + "Windshield": { + "children": { + "Front": { + "children": { + "IsHeatingOn": { + "datatype": "boolean", + "description": "Windshield heater status. False - off, True - on.", + "type": "actuator" + }, + "WasherFluid": { + "children": { + "IsLevelLow": { + "datatype": "boolean", + "description": "Low level indication for washer fluid. True = Level Low. False = Level OK.", + "type": "sensor" + }, + "Level": { + "datatype": "uint8", + "description": "Washer fluid level as a percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Windshield washer fluid signals", + "type": "branch" + }, + "Wiping": { + "children": { + "Intensity": { + "datatype": "uint8", + "description": "Relative intensity/sensitivity for interval and rain sensor mode as requested by user/driver. Has no significance if Windshield.Wiping.Mode is OFF/SLOW/MEDIUM/FAST 0 - wipers inactive. 1 - minimum intensity (lowest frequency/sensitivity, longest interval). 2/3/4/... - higher intensity (higher frequency/sensitivity, shorter interval). Maximum value supported is vehicle specific.", + "type": "actuator" + }, + "IsWipersWorn": { + "datatype": "boolean", + "description": "Wiper wear status. True = Worn, Replacement recommended or required. False = Not Worn.", + "type": "sensor" + }, + "Mode": { + "allowed": [ + "OFF", + "SLOW", + "MEDIUM", + "FAST", + "INTERVAL", + "RAIN_SENSOR" + ], + "datatype": "string", + "description": "Wiper mode requested by user/driver. INTERVAL indicates intermittent wiping, with fixed time interval between each wipe. RAIN_SENSOR indicates intermittent wiping based on rain intensity.", + "type": "actuator" + }, + "System": { + "children": { + "ActualPosition": { + "comment": "Default parking position might be used as reference position.", + "datatype": "float", + "description": "Actual position of main wiper blade for the wiper system relative to reference position. Location of reference position (0 degrees) and direction of positive/negative degrees is vehicle specific.", + "type": "actuator", + "unit": "degrees" + }, + "DriveCurrent": { + "comment": "May be negative in special situations.", + "datatype": "float", + "description": "Actual current used by wiper drive.", + "type": "sensor", + "unit": "A" + }, + "Frequency": { + "comment": "Examples - 0 = Wipers stopped, 80 = Wipers doing 80 cycles per minute (in WIPE mode).", + "datatype": "uint8", + "description": "Wiping frequency/speed, measured in cycles per minute. The signal concerns the actual speed of the wiper blades when moving. Intervals/pauses are excluded, i.e. the value corresponds to the number of cycles that would be completed in 1 minute if wiping permanently over default range.", + "type": "actuator", + "unit": "cpm" + }, + "IsBlocked": { + "datatype": "boolean", + "description": "Indicates if wiper movement is blocked. True = Movement blocked. False = Movement not blocked.", + "type": "sensor" + }, + "IsEndingWipeCycle": { + "comment": "In continuous wiping between A and B this sensor can be used a trigger to update TargetPosition.", + "datatype": "boolean", + "description": "Indicates if current wipe movement is completed or near completion. True = Movement is completed or near completion. Changes to RequestedPosition will be executed first after reaching previous RequestedPosition, if it has not already been reached. False = Movement is not near completion. Any change to RequestedPosition will be executed immediately. Change of direction may not be allowed.", + "type": "sensor" + }, + "IsOverheated": { + "datatype": "boolean", + "description": "Indicates if wiper system is overheated. True = Wiper system overheated. False = Wiper system not overheated.", + "type": "sensor" + }, + "IsPositionReached": { + "datatype": "boolean", + "description": "Indicates if a requested position has been reached. IsPositionReached refers to the previous position in case the TargetPosition is updated while IsEndingWipeCycle=True. True = Current or Previous TargetPosition reached. False = Position not (yet) reached, or wipers have moved away from the reached position.", + "type": "sensor" + }, + "IsWiperError": { + "datatype": "boolean", + "description": "Indicates system failure. True if wiping is disabled due to system failure.", + "type": "sensor" + }, + "IsWiping": { + "datatype": "boolean", + "description": "Indicates wiper movement. True if wiper blades are moving. Change of direction shall be considered as IsWiping if wipers will continue to move directly after the change of direction.", + "type": "sensor" + }, + "Mode": { + "allowed": [ + "STOP_HOLD", + "WIPE", + "PLANT_MODE", + "EMERGENCY_STOP" + ], + "datatype": "string", + "description": "Requested mode of wiper system. STOP_HOLD means that the wipers shall move to position given by TargetPosition and then hold the position. WIPE means that wipers shall move to the position given by TargetPosition and then hold the position if no new TargetPosition is requested. PLANT_MODE means that wiping is disabled. Exact behavior is vehicle specific. EMERGENCY_STOP means that wiping shall be immediately stopped without holding the position.", + "type": "actuator" + }, + "TargetPosition": { + "comment": "Default parking position might be used as reference position.", + "datatype": "float", + "description": "Requested position of main wiper blade for the wiper system relative to reference position. Location of reference position (0 degrees) and direction of positive/negative degrees is vehicle specific. System behavior when receiving TargetPosition depends on Mode and IsEndingWipeCycle. Supported values are vehicle specific and might be dynamically corrected. If IsEndingWipeCycle=True then wipers will complete current movement before actuating new TargetPosition. If IsEndingWipeCycle=False then wipers will directly change destination if the TargetPosition is changed.", + "type": "actuator", + "unit": "degrees" + } + }, + "comment": "These signals are typically not directly available to the user/driver of the vehicle. The overlay in overlays/extensions/dual_wiper_systems.vspec can be used to modify this branch to support two instances; Primary and Secondary.", + "description": "Signals to control behavior of wipers in detail. By default VSS expects only one instance.", + "type": "branch" + }, + "WiperWear": { + "datatype": "uint8", + "description": "Wiper wear as percent. 0 = No Wear. 100 = Worn. Replacement required. Method for calculating or estimating wiper wear is vehicle specific. For windshields with multiple wipers the wear reported shall correspond to the most worn wiper.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Windshield wiper signals.", + "type": "branch" + } + }, + "description": "Windshield signals.", + "type": "branch" + }, + "Rear": { + "children": { + "IsHeatingOn": { + "datatype": "boolean", + "description": "Windshield heater status. False - off, True - on.", + "type": "actuator" + }, + "WasherFluid": { + "children": { + "IsLevelLow": { + "datatype": "boolean", + "description": "Low level indication for washer fluid. True = Level Low. False = Level OK.", + "type": "sensor" + }, + "Level": { + "datatype": "uint8", + "description": "Washer fluid level as a percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Windshield washer fluid signals", + "type": "branch" + }, + "Wiping": { + "children": { + "Intensity": { + "datatype": "uint8", + "description": "Relative intensity/sensitivity for interval and rain sensor mode as requested by user/driver. Has no significance if Windshield.Wiping.Mode is OFF/SLOW/MEDIUM/FAST 0 - wipers inactive. 1 - minimum intensity (lowest frequency/sensitivity, longest interval). 2/3/4/... - higher intensity (higher frequency/sensitivity, shorter interval). Maximum value supported is vehicle specific.", + "type": "actuator" + }, + "IsWipersWorn": { + "datatype": "boolean", + "description": "Wiper wear status. True = Worn, Replacement recommended or required. False = Not Worn.", + "type": "sensor" + }, + "Mode": { + "allowed": [ + "OFF", + "SLOW", + "MEDIUM", + "FAST", + "INTERVAL", + "RAIN_SENSOR" + ], + "datatype": "string", + "description": "Wiper mode requested by user/driver. INTERVAL indicates intermittent wiping, with fixed time interval between each wipe. RAIN_SENSOR indicates intermittent wiping based on rain intensity.", + "type": "actuator" + }, + "System": { + "children": { + "ActualPosition": { + "comment": "Default parking position might be used as reference position.", + "datatype": "float", + "description": "Actual position of main wiper blade for the wiper system relative to reference position. Location of reference position (0 degrees) and direction of positive/negative degrees is vehicle specific.", + "type": "actuator", + "unit": "degrees" + }, + "DriveCurrent": { + "comment": "May be negative in special situations.", + "datatype": "float", + "description": "Actual current used by wiper drive.", + "type": "sensor", + "unit": "A" + }, + "Frequency": { + "comment": "Examples - 0 = Wipers stopped, 80 = Wipers doing 80 cycles per minute (in WIPE mode).", + "datatype": "uint8", + "description": "Wiping frequency/speed, measured in cycles per minute. The signal concerns the actual speed of the wiper blades when moving. Intervals/pauses are excluded, i.e. the value corresponds to the number of cycles that would be completed in 1 minute if wiping permanently over default range.", + "type": "actuator", + "unit": "cpm" + }, + "IsBlocked": { + "datatype": "boolean", + "description": "Indicates if wiper movement is blocked. True = Movement blocked. False = Movement not blocked.", + "type": "sensor" + }, + "IsEndingWipeCycle": { + "comment": "In continuous wiping between A and B this sensor can be used a trigger to update TargetPosition.", + "datatype": "boolean", + "description": "Indicates if current wipe movement is completed or near completion. True = Movement is completed or near completion. Changes to RequestedPosition will be executed first after reaching previous RequestedPosition, if it has not already been reached. False = Movement is not near completion. Any change to RequestedPosition will be executed immediately. Change of direction may not be allowed.", + "type": "sensor" + }, + "IsOverheated": { + "datatype": "boolean", + "description": "Indicates if wiper system is overheated. True = Wiper system overheated. False = Wiper system not overheated.", + "type": "sensor" + }, + "IsPositionReached": { + "datatype": "boolean", + "description": "Indicates if a requested position has been reached. IsPositionReached refers to the previous position in case the TargetPosition is updated while IsEndingWipeCycle=True. True = Current or Previous TargetPosition reached. False = Position not (yet) reached, or wipers have moved away from the reached position.", + "type": "sensor" + }, + "IsWiperError": { + "datatype": "boolean", + "description": "Indicates system failure. True if wiping is disabled due to system failure.", + "type": "sensor" + }, + "IsWiping": { + "datatype": "boolean", + "description": "Indicates wiper movement. True if wiper blades are moving. Change of direction shall be considered as IsWiping if wipers will continue to move directly after the change of direction.", + "type": "sensor" + }, + "Mode": { + "allowed": [ + "STOP_HOLD", + "WIPE", + "PLANT_MODE", + "EMERGENCY_STOP" + ], + "datatype": "string", + "description": "Requested mode of wiper system. STOP_HOLD means that the wipers shall move to position given by TargetPosition and then hold the position. WIPE means that wipers shall move to the position given by TargetPosition and then hold the position if no new TargetPosition is requested. PLANT_MODE means that wiping is disabled. Exact behavior is vehicle specific. EMERGENCY_STOP means that wiping shall be immediately stopped without holding the position.", + "type": "actuator" + }, + "TargetPosition": { + "comment": "Default parking position might be used as reference position.", + "datatype": "float", + "description": "Requested position of main wiper blade for the wiper system relative to reference position. Location of reference position (0 degrees) and direction of positive/negative degrees is vehicle specific. System behavior when receiving TargetPosition depends on Mode and IsEndingWipeCycle. Supported values are vehicle specific and might be dynamically corrected. If IsEndingWipeCycle=True then wipers will complete current movement before actuating new TargetPosition. If IsEndingWipeCycle=False then wipers will directly change destination if the TargetPosition is changed.", + "type": "actuator", + "unit": "degrees" + } + }, + "comment": "These signals are typically not directly available to the user/driver of the vehicle. The overlay in overlays/extensions/dual_wiper_systems.vspec can be used to modify this branch to support two instances; Primary and Secondary.", + "description": "Signals to control behavior of wipers in detail. By default VSS expects only one instance.", + "type": "branch" + }, + "WiperWear": { + "datatype": "uint8", + "description": "Wiper wear as percent. 0 = No Wear. 100 = Worn. Replacement required. Method for calculating or estimating wiper wear is vehicle specific. For windshields with multiple wipers the wear reported shall correspond to the most worn wiper.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Windshield wiper signals.", + "type": "branch" + } + }, + "description": "Windshield signals.", + "type": "branch" + } + }, + "description": "Windshield signals.", + "type": "branch" + } + }, + "description": "All body components.", + "type": "branch" + }, + "Cabin": { + "children": { + "Convertible": { + "children": { + "Status": { + "allowed": [ + "UNDEFINED", + "CLOSED", + "OPEN", + "CLOSING", + "OPENING", + "STALLED" + ], + "datatype": "string", + "description": "Roof status on convertible vehicles.", + "type": "sensor" + } + }, + "description": "Convertible roof.", + "type": "branch" + }, + "Door": { + "children": { + "Row1": { + "children": { + "DriverSide": { + "children": { + "IsChildLockActive": { + "datatype": "boolean", + "description": "Is door child lock active. True = Door cannot be opened from inside. False = Door can be opened from inside.", + "type": "sensor" + }, + "IsLocked": { + "datatype": "boolean", + "description": "Is door locked or unlocked. True = Locked. False = Unlocked.", + "type": "actuator" + }, + "IsOpen": { + "datatype": "boolean", + "description": "Is door open or closed", + "type": "actuator" + }, + "Shade": { + "children": { + "Position": { + "datatype": "uint8", + "description": "Position of window blind. 0 = Fully retracted. 100 = Fully deployed.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Side window shade", + "type": "branch" + }, + "Window": { + "children": { + "IsOpen": { + "datatype": "boolean", + "description": "Is window open or closed?", + "type": "sensor" + }, + "Position": { + "datatype": "uint8", + "description": "Window position. 0 = Fully closed 100 = Fully opened.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Door window status", + "type": "branch" + } + }, + "description": "All doors, including windows and switches.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "IsChildLockActive": { + "datatype": "boolean", + "description": "Is door child lock active. True = Door cannot be opened from inside. False = Door can be opened from inside.", + "type": "sensor" + }, + "IsLocked": { + "datatype": "boolean", + "description": "Is door locked or unlocked. True = Locked. False = Unlocked.", + "type": "actuator" + }, + "IsOpen": { + "datatype": "boolean", + "description": "Is door open or closed", + "type": "actuator" + }, + "Shade": { + "children": { + "Position": { + "datatype": "uint8", + "description": "Position of window blind. 0 = Fully retracted. 100 = Fully deployed.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Side window shade", + "type": "branch" + }, + "Window": { + "children": { + "IsOpen": { + "datatype": "boolean", + "description": "Is window open or closed?", + "type": "sensor" + }, + "Position": { + "datatype": "uint8", + "description": "Window position. 0 = Fully closed 100 = Fully opened.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Door window status", + "type": "branch" + } + }, + "description": "All doors, including windows and switches.", + "type": "branch" + } + }, + "description": "All doors, including windows and switches.", + "type": "branch" + }, + "Row2": { + "children": { + "DriverSide": { + "children": { + "IsChildLockActive": { + "datatype": "boolean", + "description": "Is door child lock active. True = Door cannot be opened from inside. False = Door can be opened from inside.", + "type": "sensor" + }, + "IsLocked": { + "datatype": "boolean", + "description": "Is door locked or unlocked. True = Locked. False = Unlocked.", + "type": "actuator" + }, + "IsOpen": { + "datatype": "boolean", + "description": "Is door open or closed", + "type": "actuator" + }, + "Shade": { + "children": { + "Position": { + "datatype": "uint8", + "description": "Position of window blind. 0 = Fully retracted. 100 = Fully deployed.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Side window shade", + "type": "branch" + }, + "Window": { + "children": { + "IsOpen": { + "datatype": "boolean", + "description": "Is window open or closed?", + "type": "sensor" + }, + "Position": { + "datatype": "uint8", + "description": "Window position. 0 = Fully closed 100 = Fully opened.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Door window status", + "type": "branch" + } + }, + "description": "All doors, including windows and switches.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "IsChildLockActive": { + "datatype": "boolean", + "description": "Is door child lock active. True = Door cannot be opened from inside. False = Door can be opened from inside.", + "type": "sensor" + }, + "IsLocked": { + "datatype": "boolean", + "description": "Is door locked or unlocked. True = Locked. False = Unlocked.", + "type": "actuator" + }, + "IsOpen": { + "datatype": "boolean", + "description": "Is door open or closed", + "type": "actuator" + }, + "Shade": { + "children": { + "Position": { + "datatype": "uint8", + "description": "Position of window blind. 0 = Fully retracted. 100 = Fully deployed.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Side window shade", + "type": "branch" + }, + "Window": { + "children": { + "IsOpen": { + "datatype": "boolean", + "description": "Is window open or closed?", + "type": "sensor" + }, + "Position": { + "datatype": "uint8", + "description": "Window position. 0 = Fully closed 100 = Fully opened.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Door window status", + "type": "branch" + } + }, + "description": "All doors, including windows and switches.", + "type": "branch" + } + }, + "description": "All doors, including windows and switches.", + "type": "branch" + } + }, + "description": "All doors, including windows and switches.", + "type": "branch" + }, + "DoorCount": { + "datatype": "uint8", + "default": 4, + "description": "Number of doors in vehicle.", + "type": "attribute" + }, + "DriverPosition": { + "allowed": [ + "LEFT", + "MIDDLE", + "RIGHT" + ], + "comment": "Some signals use DriverSide and PassengerSide as instances. If this signal specifies that DriverPosition is LEFT or MIDDLE, then DriverSide refers to left side and PassengerSide to right side. If this signal specifies that DriverPosition is RIGHT, then DriverSide refers to right side and PassengerSide to left side.", + "datatype": "string", + "description": "The position of the driver seat in row 1.", + "type": "attribute" + }, + "HVAC": { + "children": { + "AmbientAirTemperature": { + "datatype": "float", + "description": "Ambient air temperature inside the vehicle.", + "type": "sensor", + "unit": "celsius" + }, + "IsAirConditioningActive": { + "datatype": "boolean", + "description": "Is Air conditioning active.", + "type": "actuator" + }, + "IsFrontDefrosterActive": { + "datatype": "boolean", + "description": "Is front defroster active.", + "type": "actuator" + }, + "IsRearDefrosterActive": { + "datatype": "boolean", + "description": "Is rear defroster active.", + "type": "actuator" + }, + "IsRecirculationActive": { + "datatype": "boolean", + "description": "Is recirculation active.", + "type": "actuator" + }, + "PowerOptimizeLevel": { + "datatype": "uint8", + "description": "Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.", + "max": 10, + "min": 0, + "type": "actuator" + }, + "Station": { + "children": { + "Row1": { + "children": { + "Driver": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + }, + "Passenger": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + }, + "Row2": { + "children": { + "Driver": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + }, + "Passenger": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + }, + "Row3": { + "children": { + "Driver": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + }, + "Passenger": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + }, + "Row4": { + "children": { + "Driver": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + }, + "Passenger": { + "children": { + "AirDistribution": { + "allowed": [ + "UP", + "MIDDLE", + "DOWN" + ], + "datatype": "string", + "description": "Direction of airstream", + "type": "actuator" + }, + "FanSpeed": { + "datatype": "uint8", + "description": "Fan Speed, 0 = off. 100 = max", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Temperature": { + "datatype": "int8", + "description": "Temperature", + "type": "actuator", + "unit": "celsius" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + } + }, + "description": "HVAC for single station in the vehicle", + "type": "branch" + } + }, + "description": "Climate control", + "type": "branch" + }, + "Infotainment": { + "children": { + "HMI": { + "children": { + "Brightness": { + "comment": "The value 0 does not necessarily correspond to a turned off HMI, as it may not be allowed/supported to turn off the HMI completely.", + "datatype": "float", + "description": "Brightness of the HMI, relative to supported range. 0 = Lowest brightness possible. 100 = Maximum Brightness possible.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "CurrentLanguage": { + "datatype": "string", + "description": "ISO 639-1 standard language code for the current HMI", + "type": "sensor" + }, + "DateFormat": { + "allowed": [ + "YYYY_MM_DD", + "DD_MM_YYYY", + "MM_DD_YYYY", + "YY_MM_DD", + "DD_MM_YY", + "MM_DD_YY" + ], + "datatype": "string", + "description": "Date format used in the current HMI", + "type": "actuator" + }, + "DayNightMode": { + "allowed": [ + "DAY", + "NIGHT" + ], + "datatype": "string", + "description": "Current display theme", + "type": "actuator" + }, + "DisplayOffDuration": { + "comment": "Display shall be turned off at HMI.LastActionTime + HMI.DisplayOffDuration, unless HMI.IsScreenAlwaysOn==True.", + "datatype": "uint16", + "description": "Duration in seconds before the display is turned off. Value shall be 0 if screen never shall turn off.", + "type": "actuator", + "unit": "s" + }, + "DistanceUnit": { + "allowed": [ + "MILES", + "KILOMETERS" + ], + "datatype": "string", + "description": "Distance unit used in the current HMI", + "type": "actuator" + }, + "EVEconomyUnits": { + "allowed": [ + "MILES_PER_KILOWATT_HOUR", + "KILOMETERS_PER_KILOWATT_HOUR", + "KILOWATT_HOURS_PER_100_MILES", + "KILOWATT_HOURS_PER_100_KILOMETERS", + "WATT_HOURS_PER_MILE", + "WATT_HOURS_PER_KILOMETER" + ], + "datatype": "string", + "description": "EV fuel economy unit used in the current HMI", + "type": "actuator" + }, + "FontSize": { + "allowed": [ + "STANDARD", + "LARGE", + "EXTRA_LARGE" + ], + "datatype": "string", + "description": "Font size used in the current HMI", + "type": "actuator" + }, + "FuelEconomyUnits": { + "allowed": [ + "MPG_UK", + "MPG_US", + "MILES_PER_LITER", + "KILOMETERS_PER_LITER", + "LITERS_PER_100_KILOMETERS" + ], + "datatype": "string", + "description": "Fuel economy unit used in the current HMI", + "type": "actuator" + }, + "FuelVolumeUnit": { + "allowed": [ + "LITER", + "GALLON_US", + "GALLON_UK" + ], + "datatype": "string", + "description": "Fuel volume unit used in the current HMI", + "type": "actuator" + }, + "IsScreenAlwaysOn": { + "datatype": "boolean", + "description": "Used to prevent the screen going black if no action placed.", + "type": "actuator" + }, + "LastActionTime": { + "datatype": "string", + "description": "Time for last hmi action, formatted according to ISO 8601 with UTC time zone.", + "type": "sensor" + }, + "TemperatureUnit": { + "allowed": [ + "C", + "F" + ], + "datatype": "string", + "description": "Temperature unit used in the current HMI", + "type": "actuator" + }, + "TimeFormat": { + "allowed": [ + "HR_12", + "HR_24" + ], + "datatype": "string", + "description": "Time format used in the current HMI", + "type": "actuator" + }, + "TirePressureUnit": { + "allowed": [ + "PSI", + "KPA", + "BAR" + ], + "datatype": "string", + "description": "Tire pressure unit used in the current HMI", + "type": "actuator" + } + }, + "description": "HMI related signals", + "type": "branch" + }, + "Media": { + "children": { + "Action": { + "allowed": [ + "UNKNOWN", + "STOP", + "PLAY", + "FAST_FORWARD", + "FAST_BACKWARD", + "SKIP_FORWARD", + "SKIP_BACKWARD" + ], + "datatype": "string", + "description": "Tells if the media was", + "type": "actuator" + }, + "DeclinedURI": { + "datatype": "string", + "description": "URI of suggested media that was declined", + "type": "sensor" + }, + "Played": { + "children": { + "Album": { + "datatype": "string", + "description": "Name of album being played", + "type": "sensor" + }, + "Artist": { + "datatype": "string", + "description": "Name of artist being played", + "type": "sensor" + }, + "PlaybackRate": { + "comment": "The normal playback rate is multiplied by this value to obtain the current rate, so a value of 1.0 indicates normal speed. Values of lower than 1.0 make the media play slower than normal. Values of higher than 1.0 make the media play faster than normal.", + "datatype": "float", + "description": "Current playback rate of media being played.", + "type": "actuator" + }, + "Source": { + "allowed": [ + "UNKNOWN", + "SIRIUS_XM", + "AM", + "FM", + "DAB", + "TV", + "CD", + "DVD", + "AUX", + "USB", + "DISK", + "BLUETOOTH", + "INTERNET", + "VOICE", + "BEEP" + ], + "datatype": "string", + "description": "Media selected for playback", + "type": "actuator" + }, + "Track": { + "datatype": "string", + "description": "Name of track being played", + "type": "sensor" + }, + "URI": { + "datatype": "string", + "description": "User Resource associated with the media", + "type": "sensor" + } + }, + "description": "Collection of signals updated in concert when a new media is played", + "type": "branch" + }, + "SelectedURI": { + "datatype": "string", + "description": "URI of suggested media that was selected", + "type": "actuator" + }, + "Volume": { + "datatype": "uint8", + "description": "Current Media Volume", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "All Media actions", + "type": "branch" + }, + "Navigation": { + "children": { + "DestinationSet": { + "children": { + "Latitude": { + "datatype": "double", + "description": "Latitude of destination in WGS 84 geodetic coordinates.", + "max": 90, + "min": -90, + "type": "actuator", + "unit": "degrees" + }, + "Longitude": { + "datatype": "double", + "description": "Longitude of destination in WGS 84 geodetic coordinates.", + "max": 180, + "min": -180, + "type": "actuator", + "unit": "degrees" + } + }, + "description": "A navigation has been selected.", + "type": "branch" + }, + "GuidanceVoice": { + "allowed": [ + "STANDARD_MALE", + "STANDARD_FEMALE", + "ETC" + ], + "comment": "ETC indicates a voice alternative not covered by the explicitly listed alternatives.", + "datatype": "string", + "description": "Navigation guidance state that was selected.", + "type": "actuator" + }, + "Mute": { + "allowed": [ + "MUTED", + "ALERT_ONLY", + "UNMUTED" + ], + "datatype": "string", + "description": "Navigation mute state that was selected.", + "type": "actuator" + }, + "Volume": { + "datatype": "uint8", + "description": "Current navigation volume", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "All navigation actions", + "type": "branch" + }, + "PowerOptimizeLevel": { + "datatype": "uint8", + "description": "Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.", + "max": 10, + "min": 0, + "type": "actuator" + }, + "SmartphoneProjection": { + "children": { + "Active": { + "allowed": [ + "NONE", + "ACTIVE", + "INACTIVE" + ], + "comment": "NONE indicates that projection is not supported.", + "datatype": "string", + "description": "Projection activation info.", + "type": "actuator" + }, + "Source": { + "allowed": [ + "USB", + "BLUETOOTH", + "WIFI" + ], + "datatype": "string", + "description": "Connectivity source selected for projection.", + "type": "actuator" + }, + "SupportedMode": { + "allowed": [ + "ANDROID_AUTO", + "APPLE_CARPLAY", + "MIRROR_LINK", + "OTHER" + ], + "datatype": "string[]", + "description": "Supportable list for projection.", + "type": "attribute" + } + }, + "description": "All smartphone projection actions.", + "type": "branch" + } + }, + "description": "Infotainment system.", + "type": "branch" + }, + "IsWindowChildLockEngaged": { + "comment": "Window child lock refers to the functionality to disable the move window button next to most windows, so that they only can be operated by the driver.", + "datatype": "boolean", + "description": "Is window child lock engaged. True = Engaged. False = Disengaged.", + "type": "actuator" + }, + "Light": { + "children": { + "AmbientLight": { + "children": { + "Row1": { + "children": { + "DriverSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Decorative coloured light inside the cabin, usually mounted on the door, ceiling, etc.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Decorative coloured light inside the cabin, usually mounted on the door, ceiling, etc.", + "type": "branch" + } + }, + "description": "Decorative coloured light inside the cabin, usually mounted on the door, ceiling, etc.", + "type": "branch" + }, + "Row2": { + "children": { + "DriverSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Decorative coloured light inside the cabin, usually mounted on the door, ceiling, etc.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Decorative coloured light inside the cabin, usually mounted on the door, ceiling, etc.", + "type": "branch" + } + }, + "description": "Decorative coloured light inside the cabin, usually mounted on the door, ceiling, etc.", + "type": "branch" + } + }, + "description": "Decorative coloured light inside the cabin, usually mounted on the door, ceiling, etc.", + "type": "branch" + }, + "InteractiveLightBar": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Effect": { + "comment": "Default and allowed values are OEM-specific and should be defined accordingly (e.g. with the use of overlays).", + "datatype": "string", + "description": "Light effect selection from a predefined set of allowed values.", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Decorative coloured light bar that supports effects, usually mounted on the dashboard (e.g. BMW i7 Interactive bar).", + "type": "branch" + }, + "IsDomeOn": { + "datatype": "boolean", + "description": "Is central dome light on", + "type": "actuator" + }, + "IsGloveBoxOn": { + "datatype": "boolean", + "description": "Is glove box light on", + "type": "actuator" + }, + "PerceivedAmbientLight": { + "comment": "V4.0 named changed from \"AmbientLight\" to \"PerceivedAmbientLight\". This is a read-only property that refers to the pre-existing light (e.g., natural light). If you are looking for the in-cabin decorative lights that sometimes are also called \"AmbientLights\", please refer to the branch Vehicle.Cabin.Light.AmbientLight.", + "datatype": "uint8", + "description": "The percentage of ambient light that is measured (e.g., by a sensor) inside the cabin. 0 = No ambient light. 100 = Full brightness.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "Spotlight": { + "children": { + "Row1": { + "children": { + "DriverSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + }, + "Row2": { + "children": { + "DriverSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + }, + "Row3": { + "children": { + "DriverSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + }, + "Row4": { + "children": { + "DriverSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Color": { + "comment": "For example; \"#C0C0C0\" = Silver, \"#FFD700\" = Gold, \"#000000\" = Black, \"#FFFFFF\" = White, etc.", + "datatype": "string", + "description": "Hexadecimal color code represented as a 3-byte RGB (i.e. Red, Green, and Blue) value preceded by a hash symbol \"#\". Allowed range \"#000000\" to \"#FFFFFF\".", + "type": "actuator" + }, + "Intensity": { + "comment": "Minimum value cannot be zero as on/off is controlled by the actuator IsLightOn. V4.0 moved from Cabin.Lights.AmbientLight.Intensity to enable individual control of lights via the SingleConfigurableLight.vspec.", + "datatype": "uint8", + "description": "How much of the maximum possible brightness of the light is used. 1 = Maximum attenuation, 100 = No attenuation (i.e. full brightness).", + "max": 100, + "min": 1, + "type": "actuator", + "unit": "percent" + }, + "IsLightOn": { + "datatype": "boolean", + "description": "Indicates whether the light is turned on. True = On, False = Off.", + "type": "actuator" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + } + }, + "description": "Spotlight for a specific area in the vehicle.", + "type": "branch" + } + }, + "comment": "V4.0 branch renamed from \"Lights\" to \"Light\" to comply with singular naming of entities. Use SingleConfigurableLight.vspec to describe interior lights that can be configured.", + "description": "Light that is part of the Cabin.", + "type": "branch" + }, + "PowerOptimizeLevel": { + "datatype": "uint8", + "description": "Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.", + "max": 10, + "min": 0, + "type": "actuator" + }, + "RearShade": { + "children": { + "Position": { + "datatype": "uint8", + "description": "Position of window blind. 0 = Fully retracted. 100 = Fully deployed.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Rear window shade.", + "type": "branch" + }, + "RearviewMirror": { + "children": { + "DimmingLevel": { + "datatype": "uint8", + "description": "Dimming level of rear-view mirror. 0 = Undimmed. 100 = Fully dimmed.", + "max": 100, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Rear-view mirror.", + "type": "branch" + }, + "Seat": { + "children": { + "Row1": { + "children": { + "DriverSide": { + "children": { + "Airbag": { + "children": { + "IsDeployed": { + "datatype": "boolean", + "description": "Airbag deployment status. True = Airbag deployed. False = Airbag not deployed.", + "type": "sensor" + } + }, + "description": "Airbag signals.", + "type": "branch" + }, + "Backrest": { + "children": { + "Lumbar": { + "children": { + "Height": { + "datatype": "uint8", + "description": "Height of lumbar support. Position is relative within available movable range of the lumbar support. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Support": { + "datatype": "float", + "description": "Lumbar support (in/out position). 0 = Innermost position. 100 = Outermost position.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Adjustable lumbar support mechanisms in seats allow the user to change the seat back shape.", + "type": "branch" + }, + "Recline": { + "comment": "Seat z-axis depends on seat tilt. This means that movement of backrest due to seat tilting will not affect Backrest.Recline as long as the angle between Seating and Backrest are constant. Absolute recline relative to vehicle z-axis can be calculated as Tilt + Backrest.Recline.", + "datatype": "float", + "description": "Backrest recline compared to seat z-axis (seat vertical axis). 0 degrees = Upright/Vertical backrest. Negative degrees for forward recline. Positive degrees for backward recline.", + "type": "actuator", + "unit": "degrees" + }, + "SideBolster": { + "children": { + "Support": { + "datatype": "float", + "description": "Side bolster support. 0 = Minimum support (widest side bolster setting). 100 = Maximum support.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Backrest side bolster (lumbar side support) settings.", + "type": "branch" + } + }, + "description": "Describes signals related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "Angle": { + "datatype": "float", + "description": "Headrest angle, relative to backrest, 0 degrees if parallel to backrest, Positive degrees = tilted forward.", + "type": "actuator", + "unit": "degrees" + }, + "Height": { + "datatype": "uint8", + "description": "Position of headrest relative to movable range of the head rest. 0 = Bottommost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "description": "Headrest settings.", + "type": "branch" + }, + "Heating": { + "datatype": "int8", + "description": "Seat cooling / heating. 0 = off. -100 = max cold. +100 = max heat.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Height": { + "datatype": "uint16", + "description": "Seat position on vehicle z-axis. Position is relative within available movable range of the seating. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "IsBelted": { + "datatype": "boolean", + "description": "Is the belt engaged.", + "type": "sensor" + }, + "IsOccupied": { + "datatype": "boolean", + "description": "Does the seat have a passenger in it.", + "type": "sensor" + }, + "Massage": { + "datatype": "uint8", + "description": "Seat massage level. 0 = off. 100 = max massage.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Occupant": { + "children": { + "Identifier": { + "children": { + "Issuer": { + "datatype": "string", + "description": "Unique Issuer for the authentication of the occupant e.g. https://accounts.funcorp.com.", + "type": "sensor" + }, + "Subject": { + "datatype": "string", + "description": "Subject for the authentication of the occupant e.g. UserID 7331677.", + "type": "sensor" + } + }, + "description": "Identifier attributes based on OAuth 2.0.", + "type": "branch" + } + }, + "description": "Occupant data.", + "type": "branch" + }, + "Position": { + "datatype": "uint16", + "description": "Seat position on vehicle x-axis. Position is relative to the frontmost position supported by the seat. 0 = Frontmost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Seating": { + "children": { + "Length": { + "datatype": "uint16", + "description": "Length adjustment of seating. 0 = Adjustable part of seating in rearmost position (Shortest length of seating).", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "comment": "Seating is here considered as the part of the seat that supports the thighs. Additional cushions (if any) for support of lower legs is not covered by this branch.", + "description": "Describes signals related to the seat bottom of the seat.", + "type": "branch" + }, + "Switch": { + "children": { + "Backrest": { + "children": { + "IsReclineBackwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline backward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "IsReclineForwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline forward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "Lumbar": { + "children": { + "IsDownEngaged": { + "datatype": "boolean", + "description": "Lumbar down switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Lumbar up switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.Lumbar.", + "type": "branch" + }, + "SideBolster": { + "children": { + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.SideBolster.", + "type": "branch" + } + }, + "description": "Describes switches related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Head rest backward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Head rest down switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Head rest forward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Head rest up switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Headrest.", + "type": "branch" + }, + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Seat backward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsCoolerEngaged": { + "datatype": "boolean", + "description": "Cooler switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Seat down switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Seat forward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsTiltBackwardEngaged": { + "datatype": "boolean", + "description": "Tilt backward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsTiltForwardEngaged": { + "datatype": "boolean", + "description": "Tilt forward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Seat up switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsWarmerEngaged": { + "datatype": "boolean", + "description": "Warmer switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "Massage": { + "children": { + "IsDecreaseEngaged": { + "datatype": "boolean", + "description": "Decrease massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + }, + "IsIncreaseEngaged": { + "datatype": "boolean", + "description": "Increase massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Massage.", + "type": "branch" + }, + "Seating": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Is switch to decrease seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Is switch to increase seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + } + }, + "description": "Describes switches related to the seating of the seat.", + "type": "branch" + } + }, + "description": "Seat switch signals", + "type": "branch" + }, + "Tilt": { + "comment": "In VSS it is assumed that tilting a seat affects both seating (seat bottom) and backrest, i.e. the angle between seating and backrest will not be affected when changing Tilt.", + "datatype": "float", + "description": "Tilting of seat (seating and backrest) relative to vehicle x-axis. 0 = seat bottom is flat, seat bottom and vehicle x-axis are parallel. Positive degrees = seat tilted backwards, seat x-axis tilted upward, seat z-axis is tilted backward.", + "type": "actuator", + "unit": "degrees" + } + }, + "description": "All seats.", + "type": "branch" + }, + "Middle": { + "children": { + "Airbag": { + "children": { + "IsDeployed": { + "datatype": "boolean", + "description": "Airbag deployment status. True = Airbag deployed. False = Airbag not deployed.", + "type": "sensor" + } + }, + "description": "Airbag signals.", + "type": "branch" + }, + "Backrest": { + "children": { + "Lumbar": { + "children": { + "Height": { + "datatype": "uint8", + "description": "Height of lumbar support. Position is relative within available movable range of the lumbar support. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Support": { + "datatype": "float", + "description": "Lumbar support (in/out position). 0 = Innermost position. 100 = Outermost position.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Adjustable lumbar support mechanisms in seats allow the user to change the seat back shape.", + "type": "branch" + }, + "Recline": { + "comment": "Seat z-axis depends on seat tilt. This means that movement of backrest due to seat tilting will not affect Backrest.Recline as long as the angle between Seating and Backrest are constant. Absolute recline relative to vehicle z-axis can be calculated as Tilt + Backrest.Recline.", + "datatype": "float", + "description": "Backrest recline compared to seat z-axis (seat vertical axis). 0 degrees = Upright/Vertical backrest. Negative degrees for forward recline. Positive degrees for backward recline.", + "type": "actuator", + "unit": "degrees" + }, + "SideBolster": { + "children": { + "Support": { + "datatype": "float", + "description": "Side bolster support. 0 = Minimum support (widest side bolster setting). 100 = Maximum support.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Backrest side bolster (lumbar side support) settings.", + "type": "branch" + } + }, + "description": "Describes signals related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "Angle": { + "datatype": "float", + "description": "Headrest angle, relative to backrest, 0 degrees if parallel to backrest, Positive degrees = tilted forward.", + "type": "actuator", + "unit": "degrees" + }, + "Height": { + "datatype": "uint8", + "description": "Position of headrest relative to movable range of the head rest. 0 = Bottommost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "description": "Headrest settings.", + "type": "branch" + }, + "Heating": { + "datatype": "int8", + "description": "Seat cooling / heating. 0 = off. -100 = max cold. +100 = max heat.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Height": { + "datatype": "uint16", + "description": "Seat position on vehicle z-axis. Position is relative within available movable range of the seating. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "IsBelted": { + "datatype": "boolean", + "description": "Is the belt engaged.", + "type": "sensor" + }, + "IsOccupied": { + "datatype": "boolean", + "description": "Does the seat have a passenger in it.", + "type": "sensor" + }, + "Massage": { + "datatype": "uint8", + "description": "Seat massage level. 0 = off. 100 = max massage.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Occupant": { + "children": { + "Identifier": { + "children": { + "Issuer": { + "datatype": "string", + "description": "Unique Issuer for the authentication of the occupant e.g. https://accounts.funcorp.com.", + "type": "sensor" + }, + "Subject": { + "datatype": "string", + "description": "Subject for the authentication of the occupant e.g. UserID 7331677.", + "type": "sensor" + } + }, + "description": "Identifier attributes based on OAuth 2.0.", + "type": "branch" + } + }, + "description": "Occupant data.", + "type": "branch" + }, + "Position": { + "datatype": "uint16", + "description": "Seat position on vehicle x-axis. Position is relative to the frontmost position supported by the seat. 0 = Frontmost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Seating": { + "children": { + "Length": { + "datatype": "uint16", + "description": "Length adjustment of seating. 0 = Adjustable part of seating in rearmost position (Shortest length of seating).", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "comment": "Seating is here considered as the part of the seat that supports the thighs. Additional cushions (if any) for support of lower legs is not covered by this branch.", + "description": "Describes signals related to the seat bottom of the seat.", + "type": "branch" + }, + "Switch": { + "children": { + "Backrest": { + "children": { + "IsReclineBackwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline backward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "IsReclineForwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline forward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "Lumbar": { + "children": { + "IsDownEngaged": { + "datatype": "boolean", + "description": "Lumbar down switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Lumbar up switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.Lumbar.", + "type": "branch" + }, + "SideBolster": { + "children": { + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.SideBolster.", + "type": "branch" + } + }, + "description": "Describes switches related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Head rest backward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Head rest down switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Head rest forward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Head rest up switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Headrest.", + "type": "branch" + }, + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Seat backward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsCoolerEngaged": { + "datatype": "boolean", + "description": "Cooler switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Seat down switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Seat forward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsTiltBackwardEngaged": { + "datatype": "boolean", + "description": "Tilt backward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsTiltForwardEngaged": { + "datatype": "boolean", + "description": "Tilt forward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Seat up switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsWarmerEngaged": { + "datatype": "boolean", + "description": "Warmer switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "Massage": { + "children": { + "IsDecreaseEngaged": { + "datatype": "boolean", + "description": "Decrease massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + }, + "IsIncreaseEngaged": { + "datatype": "boolean", + "description": "Increase massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Massage.", + "type": "branch" + }, + "Seating": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Is switch to decrease seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Is switch to increase seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + } + }, + "description": "Describes switches related to the seating of the seat.", + "type": "branch" + } + }, + "description": "Seat switch signals", + "type": "branch" + }, + "Tilt": { + "comment": "In VSS it is assumed that tilting a seat affects both seating (seat bottom) and backrest, i.e. the angle between seating and backrest will not be affected when changing Tilt.", + "datatype": "float", + "description": "Tilting of seat (seating and backrest) relative to vehicle x-axis. 0 = seat bottom is flat, seat bottom and vehicle x-axis are parallel. Positive degrees = seat tilted backwards, seat x-axis tilted upward, seat z-axis is tilted backward.", + "type": "actuator", + "unit": "degrees" + } + }, + "description": "All seats.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Airbag": { + "children": { + "IsDeployed": { + "datatype": "boolean", + "description": "Airbag deployment status. True = Airbag deployed. False = Airbag not deployed.", + "type": "sensor" + } + }, + "description": "Airbag signals.", + "type": "branch" + }, + "Backrest": { + "children": { + "Lumbar": { + "children": { + "Height": { + "datatype": "uint8", + "description": "Height of lumbar support. Position is relative within available movable range of the lumbar support. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Support": { + "datatype": "float", + "description": "Lumbar support (in/out position). 0 = Innermost position. 100 = Outermost position.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Adjustable lumbar support mechanisms in seats allow the user to change the seat back shape.", + "type": "branch" + }, + "Recline": { + "comment": "Seat z-axis depends on seat tilt. This means that movement of backrest due to seat tilting will not affect Backrest.Recline as long as the angle between Seating and Backrest are constant. Absolute recline relative to vehicle z-axis can be calculated as Tilt + Backrest.Recline.", + "datatype": "float", + "description": "Backrest recline compared to seat z-axis (seat vertical axis). 0 degrees = Upright/Vertical backrest. Negative degrees for forward recline. Positive degrees for backward recline.", + "type": "actuator", + "unit": "degrees" + }, + "SideBolster": { + "children": { + "Support": { + "datatype": "float", + "description": "Side bolster support. 0 = Minimum support (widest side bolster setting). 100 = Maximum support.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Backrest side bolster (lumbar side support) settings.", + "type": "branch" + } + }, + "description": "Describes signals related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "Angle": { + "datatype": "float", + "description": "Headrest angle, relative to backrest, 0 degrees if parallel to backrest, Positive degrees = tilted forward.", + "type": "actuator", + "unit": "degrees" + }, + "Height": { + "datatype": "uint8", + "description": "Position of headrest relative to movable range of the head rest. 0 = Bottommost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "description": "Headrest settings.", + "type": "branch" + }, + "Heating": { + "datatype": "int8", + "description": "Seat cooling / heating. 0 = off. -100 = max cold. +100 = max heat.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Height": { + "datatype": "uint16", + "description": "Seat position on vehicle z-axis. Position is relative within available movable range of the seating. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "IsBelted": { + "datatype": "boolean", + "description": "Is the belt engaged.", + "type": "sensor" + }, + "IsOccupied": { + "datatype": "boolean", + "description": "Does the seat have a passenger in it.", + "type": "sensor" + }, + "Massage": { + "datatype": "uint8", + "description": "Seat massage level. 0 = off. 100 = max massage.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Occupant": { + "children": { + "Identifier": { + "children": { + "Issuer": { + "datatype": "string", + "description": "Unique Issuer for the authentication of the occupant e.g. https://accounts.funcorp.com.", + "type": "sensor" + }, + "Subject": { + "datatype": "string", + "description": "Subject for the authentication of the occupant e.g. UserID 7331677.", + "type": "sensor" + } + }, + "description": "Identifier attributes based on OAuth 2.0.", + "type": "branch" + } + }, + "description": "Occupant data.", + "type": "branch" + }, + "Position": { + "datatype": "uint16", + "description": "Seat position on vehicle x-axis. Position is relative to the frontmost position supported by the seat. 0 = Frontmost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Seating": { + "children": { + "Length": { + "datatype": "uint16", + "description": "Length adjustment of seating. 0 = Adjustable part of seating in rearmost position (Shortest length of seating).", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "comment": "Seating is here considered as the part of the seat that supports the thighs. Additional cushions (if any) for support of lower legs is not covered by this branch.", + "description": "Describes signals related to the seat bottom of the seat.", + "type": "branch" + }, + "Switch": { + "children": { + "Backrest": { + "children": { + "IsReclineBackwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline backward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "IsReclineForwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline forward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "Lumbar": { + "children": { + "IsDownEngaged": { + "datatype": "boolean", + "description": "Lumbar down switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Lumbar up switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.Lumbar.", + "type": "branch" + }, + "SideBolster": { + "children": { + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.SideBolster.", + "type": "branch" + } + }, + "description": "Describes switches related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Head rest backward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Head rest down switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Head rest forward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Head rest up switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Headrest.", + "type": "branch" + }, + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Seat backward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsCoolerEngaged": { + "datatype": "boolean", + "description": "Cooler switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Seat down switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Seat forward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsTiltBackwardEngaged": { + "datatype": "boolean", + "description": "Tilt backward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsTiltForwardEngaged": { + "datatype": "boolean", + "description": "Tilt forward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Seat up switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsWarmerEngaged": { + "datatype": "boolean", + "description": "Warmer switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "Massage": { + "children": { + "IsDecreaseEngaged": { + "datatype": "boolean", + "description": "Decrease massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + }, + "IsIncreaseEngaged": { + "datatype": "boolean", + "description": "Increase massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Massage.", + "type": "branch" + }, + "Seating": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Is switch to decrease seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Is switch to increase seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + } + }, + "description": "Describes switches related to the seating of the seat.", + "type": "branch" + } + }, + "description": "Seat switch signals", + "type": "branch" + }, + "Tilt": { + "comment": "In VSS it is assumed that tilting a seat affects both seating (seat bottom) and backrest, i.e. the angle between seating and backrest will not be affected when changing Tilt.", + "datatype": "float", + "description": "Tilting of seat (seating and backrest) relative to vehicle x-axis. 0 = seat bottom is flat, seat bottom and vehicle x-axis are parallel. Positive degrees = seat tilted backwards, seat x-axis tilted upward, seat z-axis is tilted backward.", + "type": "actuator", + "unit": "degrees" + } + }, + "description": "All seats.", + "type": "branch" + } + }, + "description": "All seats.", + "type": "branch" + }, + "Row2": { + "children": { + "DriverSide": { + "children": { + "Airbag": { + "children": { + "IsDeployed": { + "datatype": "boolean", + "description": "Airbag deployment status. True = Airbag deployed. False = Airbag not deployed.", + "type": "sensor" + } + }, + "description": "Airbag signals.", + "type": "branch" + }, + "Backrest": { + "children": { + "Lumbar": { + "children": { + "Height": { + "datatype": "uint8", + "description": "Height of lumbar support. Position is relative within available movable range of the lumbar support. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Support": { + "datatype": "float", + "description": "Lumbar support (in/out position). 0 = Innermost position. 100 = Outermost position.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Adjustable lumbar support mechanisms in seats allow the user to change the seat back shape.", + "type": "branch" + }, + "Recline": { + "comment": "Seat z-axis depends on seat tilt. This means that movement of backrest due to seat tilting will not affect Backrest.Recline as long as the angle between Seating and Backrest are constant. Absolute recline relative to vehicle z-axis can be calculated as Tilt + Backrest.Recline.", + "datatype": "float", + "description": "Backrest recline compared to seat z-axis (seat vertical axis). 0 degrees = Upright/Vertical backrest. Negative degrees for forward recline. Positive degrees for backward recline.", + "type": "actuator", + "unit": "degrees" + }, + "SideBolster": { + "children": { + "Support": { + "datatype": "float", + "description": "Side bolster support. 0 = Minimum support (widest side bolster setting). 100 = Maximum support.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Backrest side bolster (lumbar side support) settings.", + "type": "branch" + } + }, + "description": "Describes signals related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "Angle": { + "datatype": "float", + "description": "Headrest angle, relative to backrest, 0 degrees if parallel to backrest, Positive degrees = tilted forward.", + "type": "actuator", + "unit": "degrees" + }, + "Height": { + "datatype": "uint8", + "description": "Position of headrest relative to movable range of the head rest. 0 = Bottommost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "description": "Headrest settings.", + "type": "branch" + }, + "Heating": { + "datatype": "int8", + "description": "Seat cooling / heating. 0 = off. -100 = max cold. +100 = max heat.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Height": { + "datatype": "uint16", + "description": "Seat position on vehicle z-axis. Position is relative within available movable range of the seating. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "IsBelted": { + "datatype": "boolean", + "description": "Is the belt engaged.", + "type": "sensor" + }, + "IsOccupied": { + "datatype": "boolean", + "description": "Does the seat have a passenger in it.", + "type": "sensor" + }, + "Massage": { + "datatype": "uint8", + "description": "Seat massage level. 0 = off. 100 = max massage.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Occupant": { + "children": { + "Identifier": { + "children": { + "Issuer": { + "datatype": "string", + "description": "Unique Issuer for the authentication of the occupant e.g. https://accounts.funcorp.com.", + "type": "sensor" + }, + "Subject": { + "datatype": "string", + "description": "Subject for the authentication of the occupant e.g. UserID 7331677.", + "type": "sensor" + } + }, + "description": "Identifier attributes based on OAuth 2.0.", + "type": "branch" + } + }, + "description": "Occupant data.", + "type": "branch" + }, + "Position": { + "datatype": "uint16", + "description": "Seat position on vehicle x-axis. Position is relative to the frontmost position supported by the seat. 0 = Frontmost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Seating": { + "children": { + "Length": { + "datatype": "uint16", + "description": "Length adjustment of seating. 0 = Adjustable part of seating in rearmost position (Shortest length of seating).", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "comment": "Seating is here considered as the part of the seat that supports the thighs. Additional cushions (if any) for support of lower legs is not covered by this branch.", + "description": "Describes signals related to the seat bottom of the seat.", + "type": "branch" + }, + "Switch": { + "children": { + "Backrest": { + "children": { + "IsReclineBackwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline backward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "IsReclineForwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline forward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "Lumbar": { + "children": { + "IsDownEngaged": { + "datatype": "boolean", + "description": "Lumbar down switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Lumbar up switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.Lumbar.", + "type": "branch" + }, + "SideBolster": { + "children": { + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.SideBolster.", + "type": "branch" + } + }, + "description": "Describes switches related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Head rest backward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Head rest down switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Head rest forward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Head rest up switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Headrest.", + "type": "branch" + }, + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Seat backward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsCoolerEngaged": { + "datatype": "boolean", + "description": "Cooler switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Seat down switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Seat forward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsTiltBackwardEngaged": { + "datatype": "boolean", + "description": "Tilt backward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsTiltForwardEngaged": { + "datatype": "boolean", + "description": "Tilt forward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Seat up switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsWarmerEngaged": { + "datatype": "boolean", + "description": "Warmer switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "Massage": { + "children": { + "IsDecreaseEngaged": { + "datatype": "boolean", + "description": "Decrease massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + }, + "IsIncreaseEngaged": { + "datatype": "boolean", + "description": "Increase massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Massage.", + "type": "branch" + }, + "Seating": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Is switch to decrease seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Is switch to increase seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + } + }, + "description": "Describes switches related to the seating of the seat.", + "type": "branch" + } + }, + "description": "Seat switch signals", + "type": "branch" + }, + "Tilt": { + "comment": "In VSS it is assumed that tilting a seat affects both seating (seat bottom) and backrest, i.e. the angle between seating and backrest will not be affected when changing Tilt.", + "datatype": "float", + "description": "Tilting of seat (seating and backrest) relative to vehicle x-axis. 0 = seat bottom is flat, seat bottom and vehicle x-axis are parallel. Positive degrees = seat tilted backwards, seat x-axis tilted upward, seat z-axis is tilted backward.", + "type": "actuator", + "unit": "degrees" + } + }, + "description": "All seats.", + "type": "branch" + }, + "Middle": { + "children": { + "Airbag": { + "children": { + "IsDeployed": { + "datatype": "boolean", + "description": "Airbag deployment status. True = Airbag deployed. False = Airbag not deployed.", + "type": "sensor" + } + }, + "description": "Airbag signals.", + "type": "branch" + }, + "Backrest": { + "children": { + "Lumbar": { + "children": { + "Height": { + "datatype": "uint8", + "description": "Height of lumbar support. Position is relative within available movable range of the lumbar support. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Support": { + "datatype": "float", + "description": "Lumbar support (in/out position). 0 = Innermost position. 100 = Outermost position.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Adjustable lumbar support mechanisms in seats allow the user to change the seat back shape.", + "type": "branch" + }, + "Recline": { + "comment": "Seat z-axis depends on seat tilt. This means that movement of backrest due to seat tilting will not affect Backrest.Recline as long as the angle between Seating and Backrest are constant. Absolute recline relative to vehicle z-axis can be calculated as Tilt + Backrest.Recline.", + "datatype": "float", + "description": "Backrest recline compared to seat z-axis (seat vertical axis). 0 degrees = Upright/Vertical backrest. Negative degrees for forward recline. Positive degrees for backward recline.", + "type": "actuator", + "unit": "degrees" + }, + "SideBolster": { + "children": { + "Support": { + "datatype": "float", + "description": "Side bolster support. 0 = Minimum support (widest side bolster setting). 100 = Maximum support.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Backrest side bolster (lumbar side support) settings.", + "type": "branch" + } + }, + "description": "Describes signals related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "Angle": { + "datatype": "float", + "description": "Headrest angle, relative to backrest, 0 degrees if parallel to backrest, Positive degrees = tilted forward.", + "type": "actuator", + "unit": "degrees" + }, + "Height": { + "datatype": "uint8", + "description": "Position of headrest relative to movable range of the head rest. 0 = Bottommost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "description": "Headrest settings.", + "type": "branch" + }, + "Heating": { + "datatype": "int8", + "description": "Seat cooling / heating. 0 = off. -100 = max cold. +100 = max heat.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Height": { + "datatype": "uint16", + "description": "Seat position on vehicle z-axis. Position is relative within available movable range of the seating. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "IsBelted": { + "datatype": "boolean", + "description": "Is the belt engaged.", + "type": "sensor" + }, + "IsOccupied": { + "datatype": "boolean", + "description": "Does the seat have a passenger in it.", + "type": "sensor" + }, + "Massage": { + "datatype": "uint8", + "description": "Seat massage level. 0 = off. 100 = max massage.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Occupant": { + "children": { + "Identifier": { + "children": { + "Issuer": { + "datatype": "string", + "description": "Unique Issuer for the authentication of the occupant e.g. https://accounts.funcorp.com.", + "type": "sensor" + }, + "Subject": { + "datatype": "string", + "description": "Subject for the authentication of the occupant e.g. UserID 7331677.", + "type": "sensor" + } + }, + "description": "Identifier attributes based on OAuth 2.0.", + "type": "branch" + } + }, + "description": "Occupant data.", + "type": "branch" + }, + "Position": { + "datatype": "uint16", + "description": "Seat position on vehicle x-axis. Position is relative to the frontmost position supported by the seat. 0 = Frontmost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Seating": { + "children": { + "Length": { + "datatype": "uint16", + "description": "Length adjustment of seating. 0 = Adjustable part of seating in rearmost position (Shortest length of seating).", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "comment": "Seating is here considered as the part of the seat that supports the thighs. Additional cushions (if any) for support of lower legs is not covered by this branch.", + "description": "Describes signals related to the seat bottom of the seat.", + "type": "branch" + }, + "Switch": { + "children": { + "Backrest": { + "children": { + "IsReclineBackwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline backward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "IsReclineForwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline forward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "Lumbar": { + "children": { + "IsDownEngaged": { + "datatype": "boolean", + "description": "Lumbar down switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Lumbar up switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.Lumbar.", + "type": "branch" + }, + "SideBolster": { + "children": { + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.SideBolster.", + "type": "branch" + } + }, + "description": "Describes switches related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Head rest backward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Head rest down switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Head rest forward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Head rest up switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Headrest.", + "type": "branch" + }, + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Seat backward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsCoolerEngaged": { + "datatype": "boolean", + "description": "Cooler switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Seat down switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Seat forward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsTiltBackwardEngaged": { + "datatype": "boolean", + "description": "Tilt backward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsTiltForwardEngaged": { + "datatype": "boolean", + "description": "Tilt forward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Seat up switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsWarmerEngaged": { + "datatype": "boolean", + "description": "Warmer switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "Massage": { + "children": { + "IsDecreaseEngaged": { + "datatype": "boolean", + "description": "Decrease massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + }, + "IsIncreaseEngaged": { + "datatype": "boolean", + "description": "Increase massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Massage.", + "type": "branch" + }, + "Seating": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Is switch to decrease seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Is switch to increase seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + } + }, + "description": "Describes switches related to the seating of the seat.", + "type": "branch" + } + }, + "description": "Seat switch signals", + "type": "branch" + }, + "Tilt": { + "comment": "In VSS it is assumed that tilting a seat affects both seating (seat bottom) and backrest, i.e. the angle between seating and backrest will not be affected when changing Tilt.", + "datatype": "float", + "description": "Tilting of seat (seating and backrest) relative to vehicle x-axis. 0 = seat bottom is flat, seat bottom and vehicle x-axis are parallel. Positive degrees = seat tilted backwards, seat x-axis tilted upward, seat z-axis is tilted backward.", + "type": "actuator", + "unit": "degrees" + } + }, + "description": "All seats.", + "type": "branch" + }, + "PassengerSide": { + "children": { + "Airbag": { + "children": { + "IsDeployed": { + "datatype": "boolean", + "description": "Airbag deployment status. True = Airbag deployed. False = Airbag not deployed.", + "type": "sensor" + } + }, + "description": "Airbag signals.", + "type": "branch" + }, + "Backrest": { + "children": { + "Lumbar": { + "children": { + "Height": { + "datatype": "uint8", + "description": "Height of lumbar support. Position is relative within available movable range of the lumbar support. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Support": { + "datatype": "float", + "description": "Lumbar support (in/out position). 0 = Innermost position. 100 = Outermost position.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Adjustable lumbar support mechanisms in seats allow the user to change the seat back shape.", + "type": "branch" + }, + "Recline": { + "comment": "Seat z-axis depends on seat tilt. This means that movement of backrest due to seat tilting will not affect Backrest.Recline as long as the angle between Seating and Backrest are constant. Absolute recline relative to vehicle z-axis can be calculated as Tilt + Backrest.Recline.", + "datatype": "float", + "description": "Backrest recline compared to seat z-axis (seat vertical axis). 0 degrees = Upright/Vertical backrest. Negative degrees for forward recline. Positive degrees for backward recline.", + "type": "actuator", + "unit": "degrees" + }, + "SideBolster": { + "children": { + "Support": { + "datatype": "float", + "description": "Side bolster support. 0 = Minimum support (widest side bolster setting). 100 = Maximum support.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Backrest side bolster (lumbar side support) settings.", + "type": "branch" + } + }, + "description": "Describes signals related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "Angle": { + "datatype": "float", + "description": "Headrest angle, relative to backrest, 0 degrees if parallel to backrest, Positive degrees = tilted forward.", + "type": "actuator", + "unit": "degrees" + }, + "Height": { + "datatype": "uint8", + "description": "Position of headrest relative to movable range of the head rest. 0 = Bottommost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "description": "Headrest settings.", + "type": "branch" + }, + "Heating": { + "datatype": "int8", + "description": "Seat cooling / heating. 0 = off. -100 = max cold. +100 = max heat.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "Height": { + "datatype": "uint16", + "description": "Seat position on vehicle z-axis. Position is relative within available movable range of the seating. 0 = Lowermost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "IsBelted": { + "datatype": "boolean", + "description": "Is the belt engaged.", + "type": "sensor" + }, + "IsOccupied": { + "datatype": "boolean", + "description": "Does the seat have a passenger in it.", + "type": "sensor" + }, + "Massage": { + "datatype": "uint8", + "description": "Seat massage level. 0 = off. 100 = max massage.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Occupant": { + "children": { + "Identifier": { + "children": { + "Issuer": { + "datatype": "string", + "description": "Unique Issuer for the authentication of the occupant e.g. https://accounts.funcorp.com.", + "type": "sensor" + }, + "Subject": { + "datatype": "string", + "description": "Subject for the authentication of the occupant e.g. UserID 7331677.", + "type": "sensor" + } + }, + "description": "Identifier attributes based on OAuth 2.0.", + "type": "branch" + } + }, + "description": "Occupant data.", + "type": "branch" + }, + "Position": { + "datatype": "uint16", + "description": "Seat position on vehicle x-axis. Position is relative to the frontmost position supported by the seat. 0 = Frontmost position supported.", + "min": 0, + "type": "actuator", + "unit": "mm" + }, + "Seating": { + "children": { + "Length": { + "datatype": "uint16", + "description": "Length adjustment of seating. 0 = Adjustable part of seating in rearmost position (Shortest length of seating).", + "min": 0, + "type": "actuator", + "unit": "mm" + } + }, + "comment": "Seating is here considered as the part of the seat that supports the thighs. Additional cushions (if any) for support of lower legs is not covered by this branch.", + "description": "Describes signals related to the seat bottom of the seat.", + "type": "branch" + }, + "Switch": { + "children": { + "Backrest": { + "children": { + "IsReclineBackwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline backward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "IsReclineForwardEngaged": { + "datatype": "boolean", + "description": "Backrest recline forward switch engaged (SingleSeat.Backrest.Recline).", + "type": "actuator" + }, + "Lumbar": { + "children": { + "IsDownEngaged": { + "datatype": "boolean", + "description": "Lumbar down switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more lumbar support engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Lumbar up switch engaged (SingleSeat.Backrest.Lumbar.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.Lumbar.", + "type": "branch" + }, + "SideBolster": { + "children": { + "IsLessSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for less side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + }, + "IsMoreSupportEngaged": { + "datatype": "boolean", + "description": "Is switch for more side bolster support engaged (SingleSeat.Backrest.SideBolster.Support).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Backrest.SideBolster.", + "type": "branch" + } + }, + "description": "Describes switches related to the backrest of the seat.", + "type": "branch" + }, + "Headrest": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Head rest backward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Head rest down switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Head rest forward switch engaged (SingleSeat.Headrest.Angle).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Head rest up switch engaged (SingleSeat.Headrest.Height).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Headrest.", + "type": "branch" + }, + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Seat backward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsCoolerEngaged": { + "datatype": "boolean", + "description": "Cooler switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "IsDownEngaged": { + "datatype": "boolean", + "description": "Seat down switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Seat forward switch engaged (SingleSeat.Position).", + "type": "actuator" + }, + "IsTiltBackwardEngaged": { + "datatype": "boolean", + "description": "Tilt backward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsTiltForwardEngaged": { + "datatype": "boolean", + "description": "Tilt forward switch engaged (SingleSeat.Tilt).", + "type": "actuator" + }, + "IsUpEngaged": { + "datatype": "boolean", + "description": "Seat up switch engaged (SingleSeat.Height).", + "type": "actuator" + }, + "IsWarmerEngaged": { + "datatype": "boolean", + "description": "Warmer switch for Seat heater (SingleSeat.Heating).", + "type": "actuator" + }, + "Massage": { + "children": { + "IsDecreaseEngaged": { + "datatype": "boolean", + "description": "Decrease massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + }, + "IsIncreaseEngaged": { + "datatype": "boolean", + "description": "Increase massage level switch engaged (SingleSeat.Massage).", + "type": "actuator" + } + }, + "description": "Switches for SingleSeat.Massage.", + "type": "branch" + }, + "Seating": { + "children": { + "IsBackwardEngaged": { + "datatype": "boolean", + "description": "Is switch to decrease seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + }, + "IsForwardEngaged": { + "datatype": "boolean", + "description": "Is switch to increase seating length engaged (SingleSeat.Seating.Length).", + "type": "actuator" + } + }, + "description": "Describes switches related to the seating of the seat.", + "type": "branch" + } + }, + "description": "Seat switch signals", + "type": "branch" + }, + "Tilt": { + "comment": "In VSS it is assumed that tilting a seat affects both seating (seat bottom) and backrest, i.e. the angle between seating and backrest will not be affected when changing Tilt.", + "datatype": "float", + "description": "Tilting of seat (seating and backrest) relative to vehicle x-axis. 0 = seat bottom is flat, seat bottom and vehicle x-axis are parallel. Positive degrees = seat tilted backwards, seat x-axis tilted upward, seat z-axis is tilted backward.", + "type": "actuator", + "unit": "degrees" + } + }, + "description": "All seats.", + "type": "branch" + } + }, + "description": "All seats.", + "type": "branch" + } + }, + "description": "All seats.", + "type": "branch" + }, + "SeatPosCount": { + "comment": "Default value corresponds to two seats in front row and 3 seats in second row.", + "datatype": "uint8[]", + "default": [ + 2, + 3 + ], + "description": "Number of seats across each row from the front to the rear.", + "type": "attribute" + }, + "SeatRowCount": { + "comment": "Default value corresponds to two rows of seats.", + "datatype": "uint8", + "default": 2, + "description": "Number of seat rows in vehicle.", + "type": "attribute" + }, + "Sunroof": { + "children": { + "Position": { + "datatype": "int8", + "description": "Sunroof position. 0 = Fully closed 100 = Fully opened. -100 = Fully tilted.", + "max": 100, + "min": -100, + "type": "sensor", + "unit": "percent" + }, + "Shade": { + "children": { + "Position": { + "datatype": "uint8", + "description": "Position of window blind. 0 = Fully retracted. 100 = Fully deployed.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or blind.", + "type": "actuator" + } + }, + "description": "Sun roof shade status.", + "type": "branch" + }, + "Switch": { + "allowed": [ + "INACTIVE", + "CLOSE", + "OPEN", + "ONE_SHOT_CLOSE", + "ONE_SHOT_OPEN", + "TILT_UP", + "TILT_DOWN" + ], + "datatype": "string", + "description": "Switch controlling sliding action such as window, sunroof, or shade.", + "type": "actuator" + } + }, + "description": "Sun roof status.", + "type": "branch" + }, + "Telltale": { + "children": { + "ECT": { + "children": { + "Status": { + "allowed": [ + "OFF", + "RED", + "YELLOW", + "INFO", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "The telltale indicating the status of the engine coolant temperature.\n", + "type": "sensor" + } + }, + "description": "A set of telltale status values.", + "type": "branch" + }, + "Engine": { + "children": { + "Status": { + "allowed": [ + "OFF", + "RED", + "YELLOW", + "INFO", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "The telltale indicating the status of the engine.\n", + "type": "sensor" + } + }, + "description": "A set of telltale status values.", + "type": "branch" + }, + "EngineOil": { + "children": { + "Status": { + "allowed": [ + "OFF", + "RED", + "YELLOW", + "INFO", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "The telltale indicating the status of the engine oil level.\n", + "type": "sensor" + } + }, + "description": "A set of telltale status values.", + "type": "branch" + }, + "FuelLevel": { + "children": { + "Status": { + "allowed": [ + "OFF", + "RED", + "YELLOW", + "INFO", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "The telltale indicating the status of the fuel level.\n", + "type": "sensor" + } + }, + "description": "A set of telltale status values.", + "type": "branch" + }, + "ParkingBrake": { + "children": { + "Status": { + "allowed": [ + "OFF", + "RED", + "YELLOW", + "INFO", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "The telltale indicating the status of the parking brake.\n", + "type": "sensor" + } + }, + "description": "A set of telltale status values.", + "type": "branch" + } + }, + "description": "A set of telltale status values.", + "type": "branch" + } + }, + "description": "All in-cabin components, including doors.", + "type": "branch" + }, + "CargoVolume": { + "datatype": "float", + "description": "The available volume for cargo or luggage. For automobiles, this is usually the trunk volume.", + "min": 0, + "type": "attribute", + "unit": "l" + }, + "Chassis": { + "children": { + "Accelerator": { + "children": { + "PedalPosition": { + "datatype": "uint8", + "description": "Accelerator pedal position as percent. 0 = Not depressed. 100 = Fully depressed.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Accelerator signals", + "type": "branch" + }, + "Axle": { + "children": { + "Row1": { + "children": { + "AxleWidth": { + "comment": "Corresponds to SAE J1100-2009 W113.", + "datatype": "uint16", + "description": "The lateral distance between the wheel mounting faces, measured along the spindle axis.", + "type": "attribute", + "unit": "mm" + }, + "SteeringAngle": { + "comment": "Single track two-axle model steering angle refers to the angle that a centrally mounted wheel would have.", + "datatype": "float", + "description": "Single track two-axle model steering angle. Angle according to ISO 8855. Positive = degrees to the left. Negative = degrees to the right.", + "type": "sensor", + "unit": "degrees" + }, + "TireAspectRatio": { + "datatype": "uint8", + "description": "Aspect ratio between tire section height and tire section width, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "percent" + }, + "TireDiameter": { + "datatype": "float", + "description": "Outer diameter of tires, in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "TireWidth": { + "datatype": "uint16", + "description": "Nominal section width of tires, in mm, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "mm" + }, + "TrackWidth": { + "comment": "Corresponds to SAE J1100-2009 W102.", + "datatype": "uint16", + "description": "The lateral distance between the centers of the wheels, measured along the spindle, or axle axis. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "TreadWidth": { + "comment": "Corresponds to SAE J1100-2009 W101.", + "datatype": "uint16", + "description": "The lateral distance between the centerlines of the base tires at ground, including camber angle. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "Wheel": { + "children": { + "Left": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "Right": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "WheelCount": { + "datatype": "uint8", + "description": "Number of wheels on the axle", + "type": "attribute" + }, + "WheelDiameter": { + "datatype": "float", + "description": "Diameter of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "WheelWidth": { + "datatype": "float", + "description": "Width of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + } + }, + "description": "Axle signals", + "type": "branch" + }, + "Row2": { + "children": { + "AxleWidth": { + "comment": "Corresponds to SAE J1100-2009 W113.", + "datatype": "uint16", + "description": "The lateral distance between the wheel mounting faces, measured along the spindle axis.", + "type": "attribute", + "unit": "mm" + }, + "SteeringAngle": { + "comment": "Single track two-axle model steering angle refers to the angle that a centrally mounted wheel would have.", + "datatype": "float", + "description": "Single track two-axle model steering angle. Angle according to ISO 8855. Positive = degrees to the left. Negative = degrees to the right.", + "type": "sensor", + "unit": "degrees" + }, + "TireAspectRatio": { + "datatype": "uint8", + "description": "Aspect ratio between tire section height and tire section width, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "percent" + }, + "TireDiameter": { + "datatype": "float", + "description": "Outer diameter of tires, in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "TireWidth": { + "datatype": "uint16", + "description": "Nominal section width of tires, in mm, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "mm" + }, + "TrackWidth": { + "comment": "Corresponds to SAE J1100-2009 W102.", + "datatype": "uint16", + "description": "The lateral distance between the centers of the wheels, measured along the spindle, or axle axis. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "TreadWidth": { + "comment": "Corresponds to SAE J1100-2009 W101.", + "datatype": "uint16", + "description": "The lateral distance between the centerlines of the base tires at ground, including camber angle. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "Wheel": { + "children": { + "Left": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "Right": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "WheelCount": { + "datatype": "uint8", + "description": "Number of wheels on the axle", + "type": "attribute" + }, + "WheelDiameter": { + "datatype": "float", + "description": "Diameter of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "WheelWidth": { + "datatype": "float", + "description": "Width of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + } + }, + "description": "Axle signals", + "type": "branch" + }, + "Row3": { + "children": { + "AxleWidth": { + "comment": "Corresponds to SAE J1100-2009 W113.", + "datatype": "uint16", + "description": "The lateral distance between the wheel mounting faces, measured along the spindle axis.", + "type": "attribute", + "unit": "mm" + }, + "SteeringAngle": { + "comment": "Single track two-axle model steering angle refers to the angle that a centrally mounted wheel would have.", + "datatype": "float", + "description": "Single track two-axle model steering angle. Angle according to ISO 8855. Positive = degrees to the left. Negative = degrees to the right.", + "type": "sensor", + "unit": "degrees" + }, + "TireAspectRatio": { + "datatype": "uint8", + "description": "Aspect ratio between tire section height and tire section width, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "percent" + }, + "TireDiameter": { + "datatype": "float", + "description": "Outer diameter of tires, in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "TireWidth": { + "datatype": "uint16", + "description": "Nominal section width of tires, in mm, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "mm" + }, + "TrackWidth": { + "comment": "Corresponds to SAE J1100-2009 W102.", + "datatype": "uint16", + "description": "The lateral distance between the centers of the wheels, measured along the spindle, or axle axis. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "TreadWidth": { + "comment": "Corresponds to SAE J1100-2009 W101.", + "datatype": "uint16", + "description": "The lateral distance between the centerlines of the base tires at ground, including camber angle. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "Wheel": { + "children": { + "Left": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "Right": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "WheelCount": { + "datatype": "uint8", + "description": "Number of wheels on the axle", + "type": "attribute" + }, + "WheelDiameter": { + "datatype": "float", + "description": "Diameter of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "WheelWidth": { + "datatype": "float", + "description": "Width of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + } + }, + "description": "Axle signals", + "type": "branch" + }, + "Row4": { + "children": { + "AxleWidth": { + "comment": "Corresponds to SAE J1100-2009 W113.", + "datatype": "uint16", + "description": "The lateral distance between the wheel mounting faces, measured along the spindle axis.", + "type": "attribute", + "unit": "mm" + }, + "SteeringAngle": { + "comment": "Single track two-axle model steering angle refers to the angle that a centrally mounted wheel would have.", + "datatype": "float", + "description": "Single track two-axle model steering angle. Angle according to ISO 8855. Positive = degrees to the left. Negative = degrees to the right.", + "type": "sensor", + "unit": "degrees" + }, + "TireAspectRatio": { + "datatype": "uint8", + "description": "Aspect ratio between tire section height and tire section width, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "percent" + }, + "TireDiameter": { + "datatype": "float", + "description": "Outer diameter of tires, in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "TireWidth": { + "datatype": "uint16", + "description": "Nominal section width of tires, in mm, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "mm" + }, + "TrackWidth": { + "comment": "Corresponds to SAE J1100-2009 W102.", + "datatype": "uint16", + "description": "The lateral distance between the centers of the wheels, measured along the spindle, or axle axis. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "TreadWidth": { + "comment": "Corresponds to SAE J1100-2009 W101.", + "datatype": "uint16", + "description": "The lateral distance between the centerlines of the base tires at ground, including camber angle. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "Wheel": { + "children": { + "Left": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "Right": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "WheelCount": { + "datatype": "uint8", + "description": "Number of wheels on the axle", + "type": "attribute" + }, + "WheelDiameter": { + "datatype": "float", + "description": "Diameter of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "WheelWidth": { + "datatype": "float", + "description": "Width of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + } + }, + "description": "Axle signals", + "type": "branch" + }, + "Row5": { + "children": { + "AxleWidth": { + "comment": "Corresponds to SAE J1100-2009 W113.", + "datatype": "uint16", + "description": "The lateral distance between the wheel mounting faces, measured along the spindle axis.", + "type": "attribute", + "unit": "mm" + }, + "SteeringAngle": { + "comment": "Single track two-axle model steering angle refers to the angle that a centrally mounted wheel would have.", + "datatype": "float", + "description": "Single track two-axle model steering angle. Angle according to ISO 8855. Positive = degrees to the left. Negative = degrees to the right.", + "type": "sensor", + "unit": "degrees" + }, + "TireAspectRatio": { + "datatype": "uint8", + "description": "Aspect ratio between tire section height and tire section width, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "percent" + }, + "TireDiameter": { + "datatype": "float", + "description": "Outer diameter of tires, in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "TireWidth": { + "datatype": "uint16", + "description": "Nominal section width of tires, in mm, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "mm" + }, + "TrackWidth": { + "comment": "Corresponds to SAE J1100-2009 W102.", + "datatype": "uint16", + "description": "The lateral distance between the centers of the wheels, measured along the spindle, or axle axis. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "TreadWidth": { + "comment": "Corresponds to SAE J1100-2009 W101.", + "datatype": "uint16", + "description": "The lateral distance between the centerlines of the base tires at ground, including camber angle. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "Wheel": { + "children": { + "Left": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "Right": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "WheelCount": { + "datatype": "uint8", + "description": "Number of wheels on the axle", + "type": "attribute" + }, + "WheelDiameter": { + "datatype": "float", + "description": "Diameter of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "WheelWidth": { + "datatype": "float", + "description": "Width of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + } + }, + "description": "Axle signals", + "type": "branch" + }, + "Row6": { + "children": { + "AxleWidth": { + "comment": "Corresponds to SAE J1100-2009 W113.", + "datatype": "uint16", + "description": "The lateral distance between the wheel mounting faces, measured along the spindle axis.", + "type": "attribute", + "unit": "mm" + }, + "SteeringAngle": { + "comment": "Single track two-axle model steering angle refers to the angle that a centrally mounted wheel would have.", + "datatype": "float", + "description": "Single track two-axle model steering angle. Angle according to ISO 8855. Positive = degrees to the left. Negative = degrees to the right.", + "type": "sensor", + "unit": "degrees" + }, + "TireAspectRatio": { + "datatype": "uint8", + "description": "Aspect ratio between tire section height and tire section width, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "percent" + }, + "TireDiameter": { + "datatype": "float", + "description": "Outer diameter of tires, in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "TireWidth": { + "datatype": "uint16", + "description": "Nominal section width of tires, in mm, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "mm" + }, + "TrackWidth": { + "comment": "Corresponds to SAE J1100-2009 W102.", + "datatype": "uint16", + "description": "The lateral distance between the centers of the wheels, measured along the spindle, or axle axis. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "TreadWidth": { + "comment": "Corresponds to SAE J1100-2009 W101.", + "datatype": "uint16", + "description": "The lateral distance between the centerlines of the base tires at ground, including camber angle. If there are dual rear wheels, measure from the midway points between the inner and outer tires.", + "type": "attribute", + "unit": "mm" + }, + "Wheel": { + "children": { + "Left": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "Right": { + "children": { + "Brake": { + "children": { + "FluidLevel": { + "datatype": "uint8", + "description": "Brake fluid level as percent. 0 = Empty. 100 = Full.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "IsBrakesWorn": { + "datatype": "boolean", + "description": "Brake pad wear status. True = Worn. False = Not Worn.", + "type": "sensor" + }, + "IsFluidLevelLow": { + "datatype": "boolean", + "description": "Brake fluid level status. True = Brake fluid level low. False = Brake fluid level OK.", + "type": "sensor" + }, + "PadWear": { + "datatype": "uint8", + "description": "Brake pad wear as percent. 0 = No Wear. 100 = Worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake signals for wheel", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Rotational speed of a vehicle's wheel.", + "type": "sensor", + "unit": "km/h" + }, + "Tire": { + "children": { + "IsPressureLow": { + "datatype": "boolean", + "description": "Tire Pressure Status. True = Low tire pressure. False = Good tire pressure.", + "type": "sensor" + }, + "Pressure": { + "datatype": "uint16", + "description": "Tire pressure in kilo-Pascal.", + "type": "sensor", + "unit": "kPa" + }, + "Temperature": { + "datatype": "float", + "description": "Tire temperature in Celsius.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Tire signals for wheel.", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + } + }, + "description": "Wheel signals for axle", + "type": "branch" + }, + "WheelCount": { + "datatype": "uint8", + "description": "Number of wheels on the axle", + "type": "attribute" + }, + "WheelDiameter": { + "datatype": "float", + "description": "Diameter of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + }, + "WheelWidth": { + "datatype": "float", + "description": "Width of wheels (rims without tires), in inches, as per ETRTO / TRA standard.", + "type": "attribute", + "unit": "inch" + } + }, + "description": "Axle signals", + "type": "branch" + } + }, + "description": "Axle signals", + "type": "branch" + }, + "AxleCount": { + "datatype": "uint8", + "default": 2, + "description": "Number of axles on the vehicle", + "type": "attribute" + }, + "Brake": { + "children": { + "Circuit1": { + "children": { + "AirPressure": { + "datatype": "uint32", + "description": "The pneumatic pressure in the primary service brake circuit or reservoir, supplying the rear axle.\n", + "type": "sensor", + "unit": "kPa" + }, + "IsDriverEmergencyBrakingDetected": { + "comment": "Detection of emergency braking can trigger Emergency Brake Assist (EBA) to engage.", + "datatype": "boolean", + "description": "Indicates if emergency braking initiated by driver is detected. True = Emergency braking detected. False = Emergency braking not detected.", + "type": "sensor" + }, + "PedalPosition": { + "datatype": "uint8", + "description": "Brake pedal position as percent. 0 = Not depressed. 100 = Fully depressed.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake system signals", + "type": "branch" + }, + "Circuit2": { + "children": { + "AirPressure": { + "datatype": "uint32", + "description": "The pneumatic pressure in the secondary service brake circuit or reservoir, supplying the front axle.\n", + "type": "sensor", + "unit": "kPa" + }, + "IsDriverEmergencyBrakingDetected": { + "comment": "Detection of emergency braking can trigger Emergency Brake Assist (EBA) to engage.", + "datatype": "boolean", + "description": "Indicates if emergency braking initiated by driver is detected. True = Emergency braking detected. False = Emergency braking not detected.", + "type": "sensor" + }, + "PedalPosition": { + "datatype": "uint8", + "description": "Brake pedal position as percent. 0 = Not depressed. 100 = Fully depressed.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Brake system signals", + "type": "branch" + } + }, + "description": "Brake system signals", + "type": "branch" + }, + "ParkingBrake": { + "children": { + "IsAutoApplyEnabled": { + "datatype": "boolean", + "description": "Indicates if parking brake will be automatically engaged when the vehicle engine is turned off.", + "type": "actuator" + }, + "IsEngaged": { + "datatype": "boolean", + "description": "Parking brake status. True = Parking Brake is Engaged. False = Parking Brake is not Engaged.", + "type": "sensor" + } + }, + "description": "Parking brake signals", + "type": "branch" + }, + "SteeringWheel": { + "children": { + "Angle": { + "datatype": "int16", + "description": "Steering wheel angle. Positive = degrees to the left. Negative = degrees to the right.", + "type": "sensor", + "unit": "degrees" + }, + "Extension": { + "datatype": "uint8", + "description": "Steering wheel column extension from dashboard. 0 = Closest to dashboard. 100 = Furthest from dashboard.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "Tilt": { + "datatype": "uint8", + "description": "Steering wheel column tilt. 0 = Lowest position. 100 = Highest position.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + } + }, + "description": "Steering wheel signals", + "type": "branch" + }, + "Wheelbase": { + "datatype": "uint16", + "default": 0, + "description": "Overall wheelbase, in mm.", + "type": "attribute", + "unit": "mm" + } + }, + "description": "All data concerning steering, suspension, wheels, and brakes.", + "type": "branch" + }, + "Connectivity": { + "children": { + "IsConnectivityAvailable": { + "comment": "This signal can be used by onboard vehicle services to decide what features that shall be offered to the driver, for example disable the 'check for update' button if vehicle does not have connectivity.", + "datatype": "boolean", + "description": "Indicates if connectivity between vehicle and cloud is available. True = Connectivity is available. False = Connectivity is not available.", + "type": "sensor" + } + }, + "description": "Connectivity data.", + "type": "branch" + }, + "CurbWeight": { + "datatype": "uint16", + "default": 0, + "description": "Vehicle curb weight, including all liquids and full tank of fuel, but no cargo or passengers.", + "type": "attribute", + "unit": "kg" + }, + "CurrentLocation": { + "children": { + "Altitude": { + "datatype": "double", + "description": "Current altitude relative to WGS 84 reference ellipsoid, as measured at the position of GNSS receiver antenna.", + "type": "sensor", + "unit": "m" + }, + "GNSSReceiver": { + "children": { + "FixType": { + "allowed": [ + "NONE", + "TWO_D", + "TWO_D_SATELLITE_BASED_AUGMENTATION", + "TWO_D_GROUND_BASED_AUGMENTATION", + "TWO_D_SATELLITE_AND_GROUND_BASED_AUGMENTATION", + "THREE_D", + "THREE_D_SATELLITE_BASED_AUGMENTATION", + "THREE_D_GROUND_BASED_AUGMENTATION", + "THREE_D_SATELLITE_AND_GROUND_BASED_AUGMENTATION" + ], + "datatype": "string", + "description": "Fix status of GNSS receiver.", + "type": "sensor" + }, + "MountingPosition": { + "children": { + "X": { + "datatype": "int16", + "description": "Mounting position of GNSS receiver antenna relative to vehicle coordinate system. Axis definitions according to ISO 8855. Origin at center of (first) rear axle. Positive values = forward of rear axle. Negative values = backward of rear axle.", + "type": "attribute", + "unit": "mm" + }, + "Y": { + "datatype": "int16", + "description": "Mounting position of GNSS receiver antenna relative to vehicle coordinate system. Axis definitions according to ISO 8855. Origin at center of (first) rear axle. Positive values = left of origin. Negative values = right of origin. Left/Right is as seen from driver perspective, i.e. by a person looking forward.", + "type": "attribute", + "unit": "mm" + }, + "Z": { + "datatype": "int16", + "description": "Mounting position of GNSS receiver on Z-axis. Axis definitions according to ISO 8855. Origin at center of (first) rear axle. Positive values = above center of rear axle. Negative values = below center of rear axle.", + "type": "attribute", + "unit": "mm" + } + }, + "description": "Mounting position of GNSS receiver antenna relative to vehicle coordinate system. Axis definitions according to ISO 8855. Origin at center of (first) rear axle.", + "type": "branch" + } + }, + "description": "Information on the GNSS receiver used for determining current location.", + "type": "branch" + }, + "Heading": { + "datatype": "double", + "description": "Current heading relative to geographic north. 0 = North, 90 = East, 180 = South, 270 = West.", + "max": 360, + "min": 0, + "type": "sensor", + "unit": "degrees" + }, + "HorizontalAccuracy": { + "datatype": "double", + "description": "Accuracy of the latitude and longitude coordinates.", + "type": "sensor", + "unit": "m" + }, + "Latitude": { + "datatype": "double", + "description": "Current latitude of vehicle in WGS 84 geodetic coordinates, as measured at the position of GNSS receiver antenna.", + "max": 90, + "min": -90, + "type": "sensor", + "unit": "degrees" + }, + "Longitude": { + "datatype": "double", + "description": "Current longitude of vehicle in WGS 84 geodetic coordinates, as measured at the position of GNSS receiver antenna.", + "max": 180, + "min": -180, + "type": "sensor", + "unit": "degrees" + }, + "Speed": { + "datatype": "double", + "description": "The vehicle's current speed as as measured by the GNSS receiver antenna.\n", + "type": "sensor", + "unit": "km/h" + }, + "Timestamp": { + "datatype": "string", + "description": "Timestamp from GNSS system for current location, formatted according to ISO 8601 with UTC time zone.", + "type": "sensor" + }, + "VerticalAccuracy": { + "datatype": "double", + "description": "Accuracy of altitude.", + "type": "sensor", + "unit": "m" + } + }, + "description": "The current latitude and longitude of the vehicle.", + "type": "branch" + }, + "CurrentOverallWeight": { + "datatype": "uint32", + "description": "Current overall Vehicle weight. Including passengers, cargo and other load inside the car.", + "type": "sensor", + "unit": "kg" + }, + "Driver": { + "children": { + "AttentiveProbability": { + "datatype": "float", + "description": "Probability of attentiveness of the driver.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "DistractionLevel": { + "datatype": "float", + "description": "Distraction level of the driver, which can be evaluated by multiple factors e.g. driving situation, acoustical or optical signals inside the cockpit, ongoing phone calls.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "FatigueLevel": { + "datatype": "float", + "description": "Fatigue level of the driver, which can be evaluated by multiple factors e.g. trip time, behaviour of steering, eye status.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "HeartRate": { + "datatype": "uint16", + "description": "Heart rate of the driver.", + "type": "sensor", + "unit": "bpm" + }, + "Identifier": { + "children": { + "Issuer": { + "datatype": "string", + "description": "Unique Issuer for the authentication of the occupant e.g. https://accounts.funcorp.com.", + "type": "sensor" + }, + "Subject": { + "datatype": "string", + "description": "Subject for the authentication of the occupant e.g. UserID 7331677.", + "type": "sensor" + } + }, + "description": "Identifier attributes based on OAuth 2.0.", + "type": "branch" + }, + "IsEyesOnRoad": { + "datatype": "boolean", + "description": "Has driver the eyes on road or not?", + "type": "sensor" + }, + "IsHandsOnWheel": { + "datatype": "boolean", + "description": "Are the driver's hands on the steering wheel or not?", + "type": "sensor" + } + }, + "description": "Driver data.", + "type": "branch" + }, + "EmissionsCO2": { + "datatype": "int16", + "description": "The CO2 emissions.", + "type": "attribute", + "unit": "g/km" + }, + "Exterior": { + "children": { + "AirTemperature": { + "datatype": "float", + "description": "Air temperature outside the vehicle.", + "type": "sensor", + "unit": "celsius" + }, + "Humidity": { + "datatype": "float", + "description": "Relative humidity outside the vehicle. 0 = Dry, 100 = Air fully saturated.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "LightIntensity": { + "comment": "Mapping to physical units and calculation method is sensor specific.", + "datatype": "float", + "description": "Light intensity outside the vehicle. 0 = No light detected, 100 = Fully lit.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Information about exterior measured by vehicle.", + "type": "branch" + }, + "GrossWeight": { + "datatype": "uint16", + "default": 0, + "description": "Curb weight of vehicle, including all liquids and full tank of fuel and full load of cargo and passengers.", + "type": "attribute", + "unit": "kg" + }, + "Height": { + "datatype": "uint16", + "default": 0, + "description": "Overall vehicle height.", + "type": "attribute", + "unit": "mm" + }, + "IsBrokenDown": { + "comment": "Actual criteria and method used to decide if a vehicle is broken down is implementation specific.", + "datatype": "boolean", + "description": "Vehicle breakdown or any similar event causing vehicle to stop on the road, that might pose a risk to other road users. True = Vehicle broken down on the road, due to e.g. engine problems, flat tire, out of gas, brake problems. False = Vehicle not broken down.", + "type": "sensor" + }, + "IsMoving": { + "datatype": "boolean", + "description": "Indicates whether the vehicle is stationary or moving.", + "type": "sensor" + }, + "Length": { + "datatype": "uint16", + "default": 0, + "description": "Overall vehicle length.", + "type": "attribute", + "unit": "mm" + }, + "LowVoltageBattery": { + "children": { + "CurrentCurrent": { + "datatype": "float", + "description": "Current current flowing in/out of the low voltage battery. Positive = Current flowing in to battery, e.g. during charging or driving. Negative = Current flowing out of battery, e.g. when using the battery to start a combustion engine.", + "type": "sensor", + "unit": "A" + }, + "CurrentVoltage": { + "datatype": "float", + "description": "Current Voltage of the low voltage battery.", + "type": "sensor", + "unit": "V" + }, + "NominalCapacity": { + "datatype": "uint16", + "description": "Nominal capacity of the low voltage battery.", + "type": "attribute", + "unit": "Ah" + }, + "NominalVoltage": { + "comment": "Nominal voltage typically refers to voltage of fully charged battery when delivering rated capacity.", + "datatype": "uint16", + "description": "Nominal Voltage of the battery.", + "type": "attribute", + "unit": "V" + } + }, + "description": "Signals related to low voltage battery.", + "type": "branch" + }, + "LowVoltageSystemState": { + "allowed": [ + "UNDEFINED", + "LOCK", + "OFF", + "ACC", + "ON", + "START" + ], + "datatype": "string", + "description": "State of the supply voltage of the control units (usually 12V).", + "type": "sensor" + }, + "MaxTowBallWeight": { + "datatype": "uint16", + "default": 0, + "description": "Maximum vertical weight on the tow ball of a trailer.", + "type": "attribute", + "unit": "kg" + }, + "MaxTowWeight": { + "datatype": "uint16", + "default": 0, + "description": "Maximum weight of trailer.", + "type": "attribute", + "unit": "kg" + }, + "OBD": { + "children": { + "AbsoluteLoad": { + "datatype": "float", + "description": "PID 43 - Absolute load value", + "type": "sensor", + "unit": "percent" + }, + "AcceleratorPositionD": { + "datatype": "float", + "description": "PID 49 - Accelerator pedal position D", + "type": "sensor", + "unit": "percent" + }, + "AcceleratorPositionE": { + "datatype": "float", + "description": "PID 4A - Accelerator pedal position E", + "type": "sensor", + "unit": "percent" + }, + "AcceleratorPositionF": { + "datatype": "float", + "description": "PID 4B - Accelerator pedal position F", + "type": "sensor", + "unit": "percent" + }, + "AirStatus": { + "datatype": "string", + "description": "PID 12 - Secondary air status", + "type": "sensor" + }, + "AmbientAirTemperature": { + "datatype": "float", + "description": "PID 46 - Ambient air temperature", + "type": "sensor", + "unit": "celsius" + }, + "BarometricPressure": { + "datatype": "float", + "description": "PID 33 - Barometric pressure", + "type": "sensor", + "unit": "kPa" + }, + "Catalyst": { + "children": { + "Bank1": { + "children": { + "Temperature1": { + "datatype": "float", + "description": "PID 3C - Catalyst temperature from bank 1, sensor 1", + "type": "sensor", + "unit": "celsius" + }, + "Temperature2": { + "datatype": "float", + "description": "PID 3E - Catalyst temperature from bank 1, sensor 2", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Catalyst bank 1 signals", + "type": "branch" + }, + "Bank2": { + "children": { + "Temperature1": { + "datatype": "float", + "description": "PID 3D - Catalyst temperature from bank 2, sensor 1", + "type": "sensor", + "unit": "celsius" + }, + "Temperature2": { + "datatype": "float", + "description": "PID 3F - Catalyst temperature from bank 2, sensor 2", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Catalyst bank 2 signals", + "type": "branch" + } + }, + "description": "Catalyst signals", + "type": "branch" + }, + "CommandedEGR": { + "datatype": "float", + "description": "PID 2C - Commanded exhaust gas recirculation (EGR)", + "type": "sensor", + "unit": "percent" + }, + "CommandedEVAP": { + "datatype": "float", + "description": "PID 2E - Commanded evaporative purge (EVAP) valve", + "type": "sensor", + "unit": "percent" + }, + "CommandedEquivalenceRatio": { + "datatype": "float", + "description": "PID 44 - Commanded equivalence ratio", + "type": "sensor", + "unit": "ratio" + }, + "ControlModuleVoltage": { + "datatype": "float", + "description": "PID 42 - Control module voltage", + "type": "sensor", + "unit": "V" + }, + "CoolantTemperature": { + "datatype": "float", + "description": "PID 05 - Coolant temperature", + "type": "sensor", + "unit": "celsius" + }, + "DTCList": { + "datatype": "string[]", + "description": "List of currently active DTCs formatted according OBD II (SAE-J2012DA_201812) standard ([P|C|B|U]XXXXX )", + "type": "sensor" + }, + "DistanceSinceDTCClear": { + "datatype": "float", + "description": "PID 31 - Distance traveled since codes cleared", + "type": "sensor", + "unit": "km" + }, + "DistanceWithMIL": { + "datatype": "float", + "description": "PID 21 - Distance traveled with MIL on", + "type": "sensor", + "unit": "km" + }, + "DriveCycleStatus": { + "children": { + "DTCCount": { + "datatype": "uint8", + "description": "Number of sensor Trouble Codes (DTC)", + "type": "sensor" + }, + "IgnitionType": { + "allowed": [ + "SPARK", + "COMPRESSION" + ], + "datatype": "string", + "description": "Type of the ignition for ICE - spark = spark plug ignition, compression = self-igniting (Diesel engines)", + "type": "sensor" + }, + "IsMILOn": { + "datatype": "boolean", + "description": "Malfunction Indicator Light (MIL) - False = Off, True = On", + "type": "sensor" + } + }, + "description": "PID 41 - OBD status for the current drive cycle", + "type": "branch" + }, + "EGRError": { + "datatype": "float", + "description": "PID 2D - Exhaust gas recirculation (EGR) error", + "type": "sensor", + "unit": "percent" + }, + "EVAPVaporPressure": { + "datatype": "float", + "description": "PID 32 - Evaporative purge (EVAP) system pressure", + "type": "sensor", + "unit": "Pa" + }, + "EVAPVaporPressureAbsolute": { + "datatype": "float", + "description": "PID 53 - Absolute evaporative purge (EVAP) system pressure", + "type": "sensor", + "unit": "kPa" + }, + "EVAPVaporPressureAlternate": { + "datatype": "float", + "description": "PID 54 - Alternate evaporative purge (EVAP) system pressure", + "type": "sensor", + "unit": "Pa" + }, + "EngineLoad": { + "datatype": "float", + "description": "PID 04 - Engine load in percent - 0 = no load, 100 = full load", + "type": "sensor", + "unit": "percent" + }, + "EngineSpeed": { + "datatype": "float", + "description": "PID 0C - Engine speed measured as rotations per minute", + "type": "sensor", + "unit": "rpm" + }, + "EthanolPercent": { + "datatype": "float", + "description": "PID 52 - Percentage of ethanol in the fuel", + "type": "sensor", + "unit": "percent" + }, + "FreezeDTC": { + "datatype": "string", + "description": "PID 02 - DTC that triggered the freeze frame", + "type": "sensor" + }, + "FuelInjectionTiming": { + "datatype": "float", + "description": "PID 5D - Fuel injection timing", + "type": "sensor", + "unit": "degrees" + }, + "FuelLevel": { + "datatype": "float", + "description": "PID 2F - Fuel level in the fuel tank", + "type": "sensor", + "unit": "percent" + }, + "FuelPressure": { + "datatype": "float", + "description": "PID 0A - Fuel pressure", + "type": "sensor", + "unit": "kPa" + }, + "FuelRailPressureAbsolute": { + "datatype": "float", + "description": "PID 59 - Absolute fuel rail pressure", + "type": "sensor", + "unit": "kPa" + }, + "FuelRailPressureDirect": { + "datatype": "float", + "description": "PID 23 - Fuel rail pressure direct inject", + "type": "sensor", + "unit": "kPa" + }, + "FuelRailPressureVac": { + "datatype": "float", + "description": "PID 22 - Fuel rail pressure relative to vacuum", + "type": "sensor", + "unit": "kPa" + }, + "FuelRate": { + "datatype": "float", + "description": "PID 5E - Engine fuel rate", + "type": "sensor", + "unit": "l/h" + }, + "FuelStatus": { + "datatype": "string", + "description": "PID 03 - Fuel status", + "type": "sensor" + }, + "FuelType": { + "datatype": "uint8", + "description": "PID 51 - Fuel type", + "max": 23, + "min": 0, + "type": "attribute" + }, + "HybridBatteryRemaining": { + "datatype": "float", + "description": "PID 5B - Remaining life of hybrid battery", + "type": "sensor", + "unit": "percent" + }, + "IntakeTemp": { + "datatype": "float", + "description": "PID 0F - Intake temperature", + "type": "sensor", + "unit": "celsius" + }, + "IsPTOActive": { + "datatype": "boolean", + "description": "PID 1E - Auxiliary input status (power take off)", + "type": "sensor" + }, + "LongTermFuelTrim1": { + "datatype": "float", + "description": "PID 07 - Long Term (learned) Fuel Trim - Bank 1 - negative percent leaner, positive percent richer", + "type": "sensor", + "unit": "percent" + }, + "LongTermFuelTrim2": { + "datatype": "float", + "description": "PID 09 - Long Term (learned) Fuel Trim - Bank 2 - negative percent leaner, positive percent richer", + "type": "sensor", + "unit": "percent" + }, + "LongTermO2Trim1": { + "datatype": "float", + "description": "PID 56 (byte A) - Long term secondary O2 trim - Bank 1", + "type": "sensor", + "unit": "percent" + }, + "LongTermO2Trim2": { + "datatype": "float", + "description": "PID 58 (byte A) - Long term secondary O2 trim - Bank 2", + "type": "sensor", + "unit": "percent" + }, + "LongTermO2Trim3": { + "datatype": "float", + "description": "PID 56 (byte B) - Long term secondary O2 trim - Bank 3", + "type": "sensor", + "unit": "percent" + }, + "LongTermO2Trim4": { + "datatype": "float", + "description": "PID 58 (byte B) - Long term secondary O2 trim - Bank 4", + "type": "sensor", + "unit": "percent" + }, + "MAF": { + "datatype": "float", + "description": "PID 10 - Grams of air drawn into engine per second", + "type": "sensor", + "unit": "g/s" + }, + "MAP": { + "datatype": "float", + "description": "PID 0B - Intake manifold pressure", + "type": "sensor", + "unit": "kPa" + }, + "MaxMAF": { + "datatype": "float", + "description": "PID 50 - Maximum flow for mass air flow sensor", + "type": "sensor", + "unit": "g/s" + }, + "O2": { + "children": { + "Sensor1": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "Sensor2": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "Sensor3": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "Sensor4": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "Sensor5": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "Sensor6": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "Sensor7": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "Sensor8": { + "children": { + "ShortTermFuelTrim": { + "datatype": "float", + "description": "PID 1x (byte B) - Short term fuel trim", + "type": "sensor", + "unit": "percent" + }, + "Voltage": { + "datatype": "float", + "description": "PID 1x (byte A) - Sensor voltage", + "type": "sensor", + "unit": "V" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + } + }, + "description": "Oxygen sensors (PID 14 - PID 1B)", + "type": "branch" + }, + "O2WR": { + "children": { + "Sensor1": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "Sensor2": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "Sensor3": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "Sensor4": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "Sensor5": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "Sensor6": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "Sensor7": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "Sensor8": { + "children": { + "Current": { + "datatype": "float", + "description": "PID 3x (byte CD) - Current for wide range/band oxygen sensor", + "type": "sensor", + "unit": "A" + }, + "Lambda": { + "datatype": "float", + "description": "PID 2x (byte AB) and PID 3x (byte AB) - Lambda for wide range/band oxygen sensor", + "type": "sensor" + }, + "Voltage": { + "datatype": "float", + "description": "PID 2x (byte CD) - Voltage for wide range/band oxygen sensor", + "type": "sensor", + "unit": "V" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + } + }, + "description": "Wide range/band oxygen sensors (PID 24 - 2B and PID 34 - 3B)", + "type": "branch" + }, + "OBDStandards": { + "datatype": "uint8", + "description": "PID 1C - OBD standards this vehicle conforms to", + "type": "attribute" + }, + "OilTemperature": { + "datatype": "float", + "description": "PID 5C - Engine oil temperature", + "type": "sensor", + "unit": "celsius" + }, + "OxygenSensorsIn2Banks": { + "datatype": "uint8", + "description": "PID 13 - Presence of oxygen sensors in 2 banks. [A0..A3] == Bank 1, Sensors 1-4. [A4..A7] == Bank 2, Sensors 1-4", + "type": "sensor" + }, + "OxygenSensorsIn4Banks": { + "datatype": "uint8", + "description": "PID 1D - Presence of oxygen sensors in 4 banks. Similar to PID 13, but [A0..A7] == [B1S1, B1S2, B2S1, B2S2, B3S1, B3S2, B4S1, B4S2]", + "type": "sensor" + }, + "PidsA": { + "allowed": [ + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "0A", + "0B", + "0C", + "0D", + "0E", + "0F", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "1A", + "1B", + "1C", + "1D", + "1E", + "1F", + "20" + ], + "datatype": "string[]", + "description": "PID 00 - Array of the supported PIDs 01 to 20 in Hexadecimal.", + "type": "attribute" + }, + "PidsB": { + "allowed": [ + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "2A", + "2B", + "2C", + "2D", + "2E", + "2F", + "30", + "31", + "32", + "33", + "34", + "35", + "36", + "37", + "38", + "39", + "3A", + "3B", + "3C", + "3D", + "3E", + "3F", + "40" + ], + "datatype": "string[]", + "description": "PID 20 - Array of the supported PIDs 21 to 40 in Hexadecimal.", + "type": "attribute" + }, + "PidsC": { + "allowed": [ + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "4A", + "4B", + "4C", + "4D", + "4E", + "4F", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "57", + "58", + "59", + "5A", + "5B", + "5C", + "5D", + "5E", + "5F", + "60" + ], + "datatype": "string[]", + "description": "PID 40 - Array of the supported PIDs 41 to 60 in Hexadecimal.", + "type": "attribute" + }, + "RelativeAcceleratorPosition": { + "datatype": "float", + "description": "PID 5A - Relative accelerator pedal position", + "type": "sensor", + "unit": "percent" + }, + "RelativeThrottlePosition": { + "datatype": "float", + "description": "PID 45 - Relative throttle position", + "type": "sensor", + "unit": "percent" + }, + "RunTime": { + "datatype": "float", + "description": "PID 1F - Engine run time", + "type": "sensor", + "unit": "s" + }, + "RunTimeMIL": { + "datatype": "float", + "description": "PID 4D - Run time with MIL on", + "type": "sensor", + "unit": "min" + }, + "ShortTermFuelTrim1": { + "datatype": "float", + "description": "PID 06 - Short Term (immediate) Fuel Trim - Bank 1 - negative percent leaner, positive percent richer", + "type": "sensor", + "unit": "percent" + }, + "ShortTermFuelTrim2": { + "datatype": "float", + "description": "PID 08 - Short Term (immediate) Fuel Trim - Bank 2 - negative percent leaner, positive percent richer", + "type": "sensor", + "unit": "percent" + }, + "ShortTermO2Trim1": { + "datatype": "float", + "description": "PID 55 (byte A) - Short term secondary O2 trim - Bank 1", + "type": "sensor", + "unit": "percent" + }, + "ShortTermO2Trim2": { + "datatype": "float", + "description": "PID 57 (byte A) - Short term secondary O2 trim - Bank 2", + "type": "sensor", + "unit": "percent" + }, + "ShortTermO2Trim3": { + "datatype": "float", + "description": "PID 55 (byte B) - Short term secondary O2 trim - Bank 3", + "type": "sensor", + "unit": "percent" + }, + "ShortTermO2Trim4": { + "datatype": "float", + "description": "PID 57 (byte B) - Short term secondary O2 trim - Bank 4", + "type": "sensor", + "unit": "percent" + }, + "Speed": { + "datatype": "float", + "description": "PID 0D - Vehicle speed", + "type": "sensor", + "unit": "km/h" + }, + "Status": { + "children": { + "DTCCount": { + "datatype": "uint8", + "description": "Number of Diagnostic Trouble Codes (DTC)", + "type": "sensor" + }, + "IgnitionType": { + "allowed": [ + "SPARK", + "COMPRESSION" + ], + "datatype": "string", + "description": "Type of the ignition for ICE - spark = spark plug ignition, compression = self-igniting (Diesel engines)", + "type": "attribute" + }, + "IsMILOn": { + "datatype": "boolean", + "description": "Malfunction Indicator Light (MIL) False = Off, True = On", + "type": "sensor" + } + }, + "description": "PID 01 - OBD status", + "type": "branch" + }, + "ThrottleActuator": { + "datatype": "float", + "description": "PID 4C - Commanded throttle actuator", + "type": "sensor", + "unit": "percent" + }, + "ThrottlePosition": { + "datatype": "float", + "description": "PID 11 - Throttle position - 0 = closed throttle, 100 = open throttle", + "type": "sensor", + "unit": "percent" + }, + "ThrottlePositionB": { + "datatype": "float", + "description": "PID 47 - Absolute throttle position B", + "type": "sensor", + "unit": "percent" + }, + "ThrottlePositionC": { + "datatype": "float", + "description": "PID 48 - Absolute throttle position C", + "type": "sensor", + "unit": "percent" + }, + "TimeSinceDTCCleared": { + "datatype": "float", + "description": "PID 4E - Time since trouble codes cleared", + "type": "sensor", + "unit": "min" + }, + "TimingAdvance": { + "datatype": "float", + "description": "PID 0E - Time advance", + "type": "sensor", + "unit": "degrees" + }, + "WarmupsSinceDTCClear": { + "datatype": "uint8", + "description": "PID 30 - Number of warm-ups since codes cleared", + "type": "sensor" + } + }, + "description": "OBD data.", + "type": "branch" + }, + "PowerOptimizeLevel": { + "datatype": "uint8", + "description": "Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.", + "max": 10, + "min": 0, + "type": "actuator" + }, + "Powertrain": { + "children": { + "AccumulatedBrakingEnergy": { + "datatype": "float", + "description": "The accumulated energy from regenerative braking over lifetime.", + "type": "sensor", + "unit": "kWh" + }, + "Brake": { + "children": { + "ActualRetarderPercentage": { + "datatype": "uint8", + "description": "Actual braking torque of the retarder", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Recuperation data.", + "type": "branch" + }, + "CombustionEngine": { + "children": { + "ActualEnginePercentTorque": { + "datatype": "uint8", + "description": "The calculated output torque of the engine; the data is transmitted in indicated torque as a percent of reference engine", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "AspirationType": { + "allowed": [ + "UNKNOWN", + "NATURAL", + "SUPERCHARGER", + "TURBOCHARGER" + ], + "datatype": "string", + "default": "UNKNOWN", + "description": "Type of aspiration (natural, turbocharger, supercharger etc).", + "type": "attribute" + }, + "Bore": { + "datatype": "float", + "description": "Bore in millimetres.", + "type": "attribute", + "unit": "mm" + }, + "CompressionRatio": { + "datatype": "string", + "description": "Engine compression ratio, specified in the format 'X:1', e.g. '9.2:1'.", + "type": "attribute" + }, + "Configuration": { + "allowed": [ + "UNKNOWN", + "STRAIGHT", + "V", + "BOXER", + "W", + "ROTARY", + "RADIAL", + "SQUARE", + "H", + "U", + "OPPOSED", + "X" + ], + "datatype": "string", + "default": "UNKNOWN", + "description": "Engine configuration.", + "type": "attribute" + }, + "DieselExhaustFluid": { + "children": { + "Capacity": { + "datatype": "float", + "description": "Capacity in liters of the Diesel Exhaust Fluid Tank.", + "type": "attribute", + "unit": "l" + }, + "IsLevelLow": { + "datatype": "boolean", + "description": "Indicates if the Diesel Exhaust Fluid level is low. True if level is low. Definition of low is vehicle dependent.", + "type": "sensor" + }, + "Level": { + "datatype": "uint8", + "description": "Level of the Diesel Exhaust Fluid tank as percent of capacity. 0 = empty. 100 = full.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "Range": { + "datatype": "uint32", + "description": "Remaining range in meters of the Diesel Exhaust Fluid present in the vehicle.", + "type": "sensor", + "unit": "m" + } + }, + "comment": "In retail and marketing other names are typically used for the fluid.", + "description": "Signals related to Diesel Exhaust Fluid (DEF). DEF is called AUS32 in ISO 22241.", + "type": "branch" + }, + "DieselParticulateFilter": { + "children": { + "DeltaPressure": { + "datatype": "float", + "description": "Delta Pressure of Diesel Particulate Filter.", + "type": "sensor", + "unit": "Pa" + }, + "InletTemperature": { + "datatype": "float", + "description": "Inlet temperature of Diesel Particulate Filter.", + "type": "sensor", + "unit": "celsius" + }, + "OutletTemperature": { + "datatype": "float", + "description": "Outlet temperature of Diesel Particulate Filter.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Diesel Particulate Filter signals.", + "type": "branch" + }, + "Displacement": { + "datatype": "uint16", + "description": "Displacement in cubic centimetres.", + "type": "attribute", + "unit": "cm^3" + }, + "ECT": { + "datatype": "int16", + "description": "Engine coolant temperature.", + "type": "sensor", + "unit": "celsius" + }, + "EOP": { + "datatype": "uint16", + "description": "Engine oil pressure.", + "type": "sensor", + "unit": "kPa" + }, + "EOT": { + "datatype": "int16", + "description": "Engine oil temperature.", + "type": "sensor", + "unit": "celsius" + }, + "EngineCode": { + "comment": "For hybrid vehicles the engine code may refer to the combination of combustion and electric engine.", + "datatype": "string", + "description": "Engine code designation, as specified by vehicle manufacturer.", + "type": "attribute" + }, + "EngineCoolantCapacity": { + "datatype": "float", + "description": "Engine coolant capacity in liters.", + "type": "attribute", + "unit": "l" + }, + "EngineHours": { + "datatype": "float", + "description": "Accumulated time during engine lifetime with 'engine speed (rpm) > 0'.", + "type": "sensor", + "unit": "h" + }, + "EngineOilCapacity": { + "datatype": "float", + "description": "Engine oil capacity in liters.", + "type": "attribute", + "unit": "l" + }, + "EngineOilLevel": { + "allowed": [ + "CRITICALLY_LOW", + "LOW", + "NORMAL", + "HIGH", + "CRITICALLY_HIGH" + ], + "datatype": "string", + "description": "Engine oil level.", + "type": "sensor" + }, + "IdleHours": { + "comment": "Vehicles may calculate accumulated idle time for an engine. It might be based on engine speed (rpm) below a certain limit or any other mechanism.", + "datatype": "float", + "description": "Accumulated idling time during engine lifetime. Definition of idling is not standardized.", + "type": "sensor", + "unit": "h" + }, + "IsRunning": { + "datatype": "boolean", + "description": "Engine Running. True if engine is rotating (Speed > 0).", + "type": "sensor" + }, + "MAF": { + "datatype": "uint16", + "description": "Grams of air drawn into engine per second.", + "type": "sensor", + "unit": "g/s" + }, + "MAP": { + "datatype": "uint16", + "description": "Manifold absolute pressure possibly boosted using forced induction.", + "type": "sensor", + "unit": "kPa" + }, + "MaxPower": { + "datatype": "uint16", + "default": 0, + "description": "Peak power, in kilowatts, that engine can generate.", + "type": "attribute", + "unit": "kW" + }, + "MaxTorque": { + "datatype": "uint16", + "default": 0, + "description": "Peak torque, in newton meter, that the engine can generate.", + "type": "attribute", + "unit": "Nm" + }, + "NumberOfCylinders": { + "datatype": "uint16", + "description": "Number of cylinders.", + "type": "attribute" + }, + "NumberOfValvesPerCylinder": { + "datatype": "uint16", + "description": "Number of valves per cylinder.", + "type": "attribute" + }, + "OilLifeRemaining": { + "comment": "In addition to this a signal a vehicle can report remaining time to service (including e.g. oil change) by Vehicle.Service.TimeToService.", + "datatype": "int32", + "description": "Remaining engine oil life in seconds. Negative values can be used to indicate that lifetime has been exceeded.", + "type": "sensor", + "unit": "s" + }, + "Power": { + "datatype": "uint16", + "description": "Current engine power output. Shall be reported as 0 during engine breaking.", + "type": "sensor", + "unit": "kW" + }, + "Speed": { + "datatype": "uint16", + "description": "Engine speed measured as rotations per minute.", + "type": "sensor", + "unit": "rpm" + }, + "StrokeLength": { + "datatype": "float", + "description": "Stroke length in millimetres.", + "type": "attribute", + "unit": "mm" + }, + "TPS": { + "datatype": "uint8", + "description": "Current throttle position.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "Torque": { + "comment": "During engine breaking the engine delivers a negative torque to the transmission. This negative torque shall be ignored, instead 0 shall be reported.", + "datatype": "uint16", + "description": "Current engine torque. Shall be reported as 0 during engine breaking.", + "type": "sensor", + "unit": "Nm" + } + }, + "description": "Engine-specific data, stopping at the bell housing.", + "type": "branch" + }, + "CurrentFuelType": { + "allowed": [ + "NONE", + "GAS", + "METH", + "ETH", + "DSL", + "LPG", + "CNG", + "PROP", + "ELEC", + "BI_GAS", + "BI_METH", + "BI_ETH", + "BI_LPG", + "BI_CNG", + "BI_PROP", + "BI_ELEC", + "BI_MIX", + "HYB_GAS", + "HYB_ETH", + "HYB_DSL", + "HYB_ELEC", + "HYB_MIX", + "HYB_REG", + "NG", + "BI_NG", + "BI_DSL", + "ERROR", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "Type of fuel currently being utilized by the vehicle.", + "type": "sensor" + }, + "Eec2AcceleratorPedalPosition": { + "datatype": "double", + "description": "The ratio of actual position of the analogue engine speed/torque request input device\n(such as an accelerator pedal or throttle lever) to the maximum position of the input device\n", + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "Eec2EnginePercentLoad": { + "datatype": "uint8", + "description": "The ratio of actual engine percent torque (indicated) to maximum indicated torque available at\nthe current engine speed, clipped to zero torque during engine braking\n", + "max": 125, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "ElectricMotor": { + "children": { + "CoolantTemperature": { + "datatype": "int16", + "description": "Motor coolant temperature (if applicable).", + "type": "sensor", + "unit": "celsius" + }, + "EngineCode": { + "datatype": "string", + "description": "Engine code designation, as specified by vehicle manufacturer.", + "type": "attribute" + }, + "MaxPower": { + "datatype": "uint16", + "default": 0, + "description": "Peak power, in kilowatts, that motor(s) can generate.", + "type": "attribute", + "unit": "kW" + }, + "MaxRegenPower": { + "datatype": "uint16", + "default": 0, + "description": "Peak regen/brake power, in kilowatts, that motor(s) can generate.", + "type": "attribute", + "unit": "kW" + }, + "MaxRegenTorque": { + "datatype": "uint16", + "default": 0, + "description": "Peak regen/brake torque, in newton meter, that the motor(s) can generate.", + "type": "attribute", + "unit": "Nm" + }, + "MaxTorque": { + "datatype": "uint16", + "default": 0, + "description": "Peak power, in newton meter, that the motor(s) can generate.", + "type": "attribute", + "unit": "Nm" + }, + "MotorHours": { + "datatype": "float", + "description": "Accumulated time during motor lifetime with 'motor speed (rpm) > 0'.", + "min": 0.0, + "type": "sensor", + "unit": "h" + }, + "Power": { + "datatype": "int16", + "description": "Current motor power output. Negative values indicate regen mode.", + "type": "sensor", + "unit": "kW" + }, + "Speed": { + "datatype": "int32", + "description": "Motor rotational speed measured as rotations per minute. Negative values indicate reverse driving mode.", + "type": "sensor", + "unit": "rpm" + }, + "Temperature": { + "datatype": "int16", + "description": "Motor temperature.", + "type": "sensor", + "unit": "celsius" + }, + "Torque": { + "datatype": "int16", + "description": "Current motor torque. Negative values indicate regen mode.", + "type": "sensor", + "unit": "Nm" + } + }, + "description": "Electric Motor specific data.", + "type": "branch" + }, + "FuelSystem": { + "children": { + "AbsoluteLevel": { + "datatype": "float", + "description": "Current available fuel in the fuel tank expressed in liters.", + "type": "sensor", + "unit": "l" + }, + "AccumulatedConsumption": { + "datatype": "uint64", + "description": "Accumulated amount of fuel used during vehicle operation.", + "type": "sensor", + "unit": "ml" + }, + "AverageConsumption": { + "datatype": "float", + "description": "Average consumption in liters per 100 km.", + "min": 0, + "type": "sensor", + "unit": "l/100km" + }, + "ConsumptionSinceStart": { + "comment": "A new trip is considered to start when engine gets enabled (e.g. LowVoltageSystemState in ON or START mode). A trip is considered to end when engine is no longer enabled. The signal may however keep the value of the last trip until a new trip is started.", + "datatype": "float", + "description": "Fuel amount in liters consumed since start of current trip.", + "type": "sensor", + "unit": "l" + }, + "HybridType": { + "allowed": [ + "UNKNOWN", + "NOT_APPLICABLE", + "STOP_START", + "BELT_ISG", + "CIMG", + "PHEV" + ], + "datatype": "string", + "default": "UNKNOWN", + "description": "Defines the hybrid type of the vehicle.", + "type": "attribute" + }, + "InstantConsumption": { + "datatype": "float", + "description": "Current consumption in liters per 100 km.", + "min": 0, + "type": "sensor", + "unit": "l/100km" + }, + "IsEngineStopStartEnabled": { + "datatype": "boolean", + "description": "Indicates whether eco start stop is currently enabled.", + "type": "sensor" + }, + "IsFuelLevelLow": { + "datatype": "boolean", + "description": "Indicates that the fuel level is low (e.g. <50km range).", + "type": "sensor" + }, + "Range": { + "datatype": "uint32", + "description": "Remaining range in meters using only liquid fuel.", + "type": "sensor", + "unit": "m" + }, + "RelativeLevel": { + "datatype": "uint8", + "description": "Level in fuel tank as percent of capacity. 0 = empty. 100 = full.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "SupportedFuel": { + "allowed": [ + "E5_95", + "E5_98", + "E10_95", + "E10_98", + "E85", + "B7", + "B10", + "B20", + "B30", + "B100", + "XTL", + "LPG", + "CNG", + "LNG", + "H2", + "OTHER" + ], + "comment": "RON 95 is sometimes referred to as Super, RON 98 as Super Plus.", + "datatype": "string[]", + "description": "Detailed information on fuels supported by the vehicle. Identifiers originating from DIN EN 16942:2021-08, appendix B, with additional suffix for octane (RON) where relevant.", + "type": "attribute" + }, + "SupportedFuelTypes": { + "allowed": [ + "GASOLINE", + "DIESEL", + "E85", + "LPG", + "CNG", + "LNG", + "H2", + "OTHER" + ], + "comment": "If a vehicle also has an electric drivetrain (e.g. hybrid) that will be obvious from the PowerTrain.Type signal.", + "datatype": "string[]", + "description": "High level information of fuel types supported", + "type": "attribute" + }, + "Tank": { + "children": { + "First": { + "children": { + "Fuel": { + "allowed": [ + "GASOLINE", + "DIESEL", + "E85", + "LPG", + "CNG", + "LNG", + "H2", + "OTHER" + ], + "datatype": "string", + "description": "Detailed information on fuel in tank. Identifiers originating from DIN EN 16942:2021-08,\nappendix B, with additional suffix for octane (RON) where relevant.\n", + "type": "sensor" + }, + "RelativeLevel": { + "datatype": "float", + "description": "Level in fuel tank as percent of capacity. 0 = empty. 100 = full.", + "max": 100.0, + "min": 0.0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Information about the first and (optional) second fuel tank.", + "type": "branch" + }, + "Second": { + "children": { + "Fuel": { + "allowed": [ + "GASOLINE", + "DIESEL", + "E85", + "LPG", + "CNG", + "LNG", + "H2", + "OTHER" + ], + "datatype": "string", + "description": "Detailed information on fuel in tank. Identifiers originating from DIN EN 16942:2021-08,\nappendix B, with additional suffix for octane (RON) where relevant.\n", + "type": "sensor" + }, + "RelativeLevel": { + "datatype": "float", + "description": "Level in fuel tank as percent of capacity. 0 = empty. 100 = full.", + "max": 100.0, + "min": 0.0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Information about the first and (optional) second fuel tank.", + "type": "branch" + } + }, + "description": "Information about the first and (optional) second fuel tank.", + "type": "branch" + }, + "TankCapacity": { + "datatype": "float", + "description": "Capacity of the fuel tank in liters.", + "type": "attribute", + "unit": "l" + } + }, + "description": "Fuel system data.", + "type": "branch" + }, + "PowerOptimizeLevel": { + "datatype": "uint8", + "description": "Power optimization level for this branch/subsystem. A higher number indicates more aggressive power optimization. Level 0 indicates that all functionality is enabled, no power optimization enabled. Level 10 indicates most aggressive power optimization mode, only essential functionality enabled.", + "max": 10, + "min": 0, + "type": "actuator" + }, + "Range": { + "datatype": "uint32", + "description": "Remaining range in meters using all energy sources available in the vehicle.", + "type": "sensor", + "unit": "m" + }, + "TractionBattery": { + "children": { + "AccumulatedChargedEnergy": { + "datatype": "float", + "description": "The accumulated energy delivered to the battery during charging over lifetime of the battery.", + "type": "sensor", + "unit": "kWh" + }, + "AccumulatedChargedThroughput": { + "datatype": "float", + "description": "The accumulated charge throughput delivered to the battery during charging over lifetime of the battery.", + "type": "sensor", + "unit": "Ah" + }, + "AccumulatedConsumedEnergy": { + "datatype": "float", + "description": "The accumulated energy leaving HV battery for propulsion and auxiliary loads over lifetime of the battery.", + "type": "sensor", + "unit": "kWh" + }, + "AccumulatedConsumedThroughput": { + "datatype": "float", + "description": "The accumulated charge throughput leaving HV battery for propulsion and auxiliary loads over lifetime of the battery.", + "type": "sensor", + "unit": "Ah" + }, + "CellVoltage": { + "children": { + "Max": { + "datatype": "float", + "description": "Current voltage of the battery cell with highest voltage.", + "type": "sensor", + "unit": "V" + }, + "Min": { + "datatype": "float", + "description": "Current voltage of the battery cell with lowest voltage.", + "type": "sensor", + "unit": "V" + } + }, + "description": "Voltage information for cells in the battery pack.", + "type": "branch" + }, + "Charging": { + "children": { + "ChargeCurrent": { + "children": { + "DC": { + "datatype": "float", + "description": "Current DC charging current at inlet. Negative if returning energy to grid.", + "type": "sensor", + "unit": "A" + }, + "Phase1": { + "datatype": "float", + "description": "Current AC charging current (rms) at inlet for Phase 1. Negative if returning energy to grid.", + "type": "sensor", + "unit": "A" + }, + "Phase2": { + "datatype": "float", + "description": "Current AC charging current (rms) at inlet for Phase 2. Negative if returning energy to grid.", + "type": "sensor", + "unit": "A" + }, + "Phase3": { + "datatype": "float", + "description": "Current AC charging current (rms) at inlet for Phase 3. Negative if returning energy to grid.", + "type": "sensor", + "unit": "A" + } + }, + "description": "Current charging current.", + "type": "branch" + }, + "ChargeLimit": { + "datatype": "uint8", + "default": 100, + "description": "Target charge limit (state of charge) for battery.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "ChargePlugType": { + "allowed": [ + "IEC_TYPE_1_AC", + "IEC_TYPE_2_AC", + "IEC_TYPE_3_AC", + "IEC_TYPE_4_DC", + "IEC_TYPE_1_CCS_DC", + "IEC_TYPE_2_CCS_DC", + "TESLA_ROADSTER", + "TESLA_HPWC", + "TESLA_SUPERCHARGER", + "GBT_AC", + "GBT_DC", + "OTHER" + ], + "comment": "A vehicle may have multiple charging inlets. IEC_TYPE_1_AC refers to Type 1 as defined in IEC 62196-2. Also known as Yazaki or J1772 connector. IEC_TYPE_2_AC refers to Type 2 as defined in IEC 62196-2. Also known as Mennekes connector. IEC_TYPE_3_AC refers to Type 3 as defined in IEC 62196-2. Also known as Scame connector. IEC_TYPE_4_DC refers to AA configuration as defined in IEC 62196-3. Also known as Type 4 or CHAdeMO connector. IEC_TYPE_1_CCS_DC refers to EE Configuration as defined in IEC 62196-3. Also known as CCS1 or Combo1 connector. IEC_TYPE_2_CCS_DC refers to FF Configuration as defined in IEC 62196-3. Also known as CCS2 or Combo2 connector. TESLA_ROADSTER, TESLA_HPWC (High Power Wall Connector) and TESLA_SUPERCHARGER refer to non-standardized charging inlets/methods used by Tesla. GBT_AC refers to connector specified in GB/T 20234.2. GBT_DC refers to connector specified in GB/T 20234.3. Also specified as BB Configuration in IEC 62196-3. OTHER shall be used if the vehicle has a charging connector, but not one of the connectors listed above. For additional information see https://en.wikipedia.org/wiki/IEC_62196.", + "datatype": "string[]", + "description": "Type of charge plug (charging inlet) available on the vehicle. IEC types refer to IEC 62196, GBT refers to GB/T 20234.", + "type": "attribute" + }, + "ChargePortFlap": { + "allowed": [ + "OPEN", + "CLOSED" + ], + "datatype": "string", + "description": "Status of the charge port cover, can potentially be controlled manually.", + "type": "actuator" + }, + "ChargeRate": { + "datatype": "float", + "description": "Current charging rate, as in kilometers of range added per hour.", + "type": "sensor", + "unit": "km/h" + }, + "ChargeVoltage": { + "children": { + "DC": { + "datatype": "float", + "description": "Current DC charging voltage at charging inlet.", + "type": "sensor", + "unit": "V" + }, + "Phase1": { + "datatype": "float", + "description": "Current AC charging voltage (rms) at inlet for Phase 1.", + "type": "sensor", + "unit": "V" + }, + "Phase2": { + "datatype": "float", + "description": "Current AC charging voltage (rms) at inlet for Phase 2.", + "type": "sensor", + "unit": "V" + }, + "Phase3": { + "datatype": "float", + "description": "Current AC charging voltage (rms) at inlet for Phase 3.", + "type": "sensor", + "unit": "V" + } + }, + "description": "Current charging voltage, as measured at the charging inlet.", + "type": "branch" + }, + "IsCharging": { + "datatype": "boolean", + "description": "True if charging is ongoing. Charging is considered to be ongoing if energy is flowing from charger to vehicle.", + "type": "sensor" + }, + "IsChargingCableConnected": { + "datatype": "boolean", + "description": "Indicates if a charging cable is physically connected to the vehicle or not.", + "type": "sensor" + }, + "IsChargingCableLocked": { + "comment": "Locking of charging cable can be used to prevent unintentional removing during charging.", + "datatype": "boolean", + "description": "Is charging cable locked to prevent removal.", + "type": "actuator" + }, + "IsDischarging": { + "datatype": "boolean", + "description": "True if discharging (vehicle to grid) is ongoing. Discharging is considered to be ongoing if energy is flowing from vehicle to charger/grid.", + "type": "sensor" + }, + "MaximumChargingCurrent": { + "children": { + "DC": { + "datatype": "float", + "description": "Maximum DC charging current at inlet that can be accepted by the system.", + "type": "sensor", + "unit": "A" + }, + "Phase1": { + "datatype": "float", + "description": "Maximum AC charging current (rms) at inlet for Phase 1 that can be accepted by the system.", + "type": "sensor", + "unit": "A" + }, + "Phase2": { + "datatype": "float", + "description": "Maximum AC charging current (rms) at inlet for Phase 2 that can be accepted by the system.", + "type": "sensor", + "unit": "A" + }, + "Phase3": { + "datatype": "float", + "description": "Maximum AC charging current (rms) at inlet for Phase 3 that can be accepted by the system.", + "type": "sensor", + "unit": "A" + } + }, + "description": "Maximum charging current that can be accepted by the system, as measured at the charging inlet.", + "type": "branch" + }, + "Mode": { + "allowed": [ + "MANUAL", + "TIMER", + "GRID", + "PROFILE" + ], + "comment": "The mechanism to provide a profile to the vehicle is currently not covered by VSS.", + "datatype": "string", + "description": "Control of the charge process. MANUAL means manually initiated (plug-in event, companion app, etc). TIMER means timer-based. GRID means grid-controlled (e.g. ISO 15118). PROFILE means controlled by profile download to vehicle.", + "type": "actuator" + }, + "PowerLoss": { + "datatype": "float", + "description": "Electrical energy lost by power dissipation to heat inside the AC/DC converter.", + "type": "sensor", + "unit": "W" + }, + "StartStopCharging": { + "allowed": [ + "START", + "STOP" + ], + "datatype": "string", + "description": "Start or stop the charging process.", + "type": "actuator" + }, + "Temperature": { + "datatype": "float", + "description": "Current temperature of AC/DC converter converting grid voltage to battery voltage.", + "type": "sensor", + "unit": "celsius" + }, + "TimeToComplete": { + "comment": "Shall consider time set by Charging.Timer.Time. E.g. if charging shall start in 3 hours and 2 hours of charging is needed, then Charging.TimeToComplete shall report 5 hours.", + "datatype": "uint32", + "description": "The time needed for the current charging process to reach Charging.ChargeLimit. 0 if charging is complete or no charging process is active or planned.", + "type": "sensor", + "unit": "s" + }, + "Timer": { + "children": { + "Mode": { + "allowed": [ + "INACTIVE", + "START_TIME", + "END_TIME" + ], + "datatype": "string", + "description": "Defines timer mode for charging: INACTIVE - no timer set, charging may start as soon as battery is connected to a charger. START_TIME - charging shall start at Charging.Timer.Time. END_TIME - charging shall be finished (reach Charging.ChargeLimit) at Charging.Timer.Time. When charging is completed the vehicle shall change mode to 'inactive' or set a new Charging.Timer.Time. Charging shall start immediately if mode is 'starttime' or 'endtime' and Charging.Timer.Time is a time in the past.", + "type": "actuator" + }, + "Time": { + "datatype": "string", + "description": "Time for next charging-related action, formatted according to ISO 8601 with UTC time zone. Value has no significance if Charging.Timer.Mode is 'inactive'.", + "type": "actuator" + } + }, + "description": "Properties related to timing of battery charging sessions.", + "type": "branch" + } + }, + "description": "Properties related to battery charging.", + "type": "branch" + }, + "CoolantTemperature": { + "datatype": "uint8", + "description": "The temperature of the battery pack coolant.\n", + "type": "sensor", + "unit": "celsius" + }, + "CurrentCurrent": { + "datatype": "float", + "description": "Current current flowing in/out of battery. Positive = Current flowing in to battery, e.g. during charging. Negative = Current flowing out of battery, e.g. during driving.", + "type": "sensor", + "unit": "A" + }, + "CurrentPower": { + "datatype": "float", + "description": "Current electrical energy flowing in/out of battery. Positive = Energy flowing in to battery, e.g. during charging. Negative = Energy flowing out of battery, e.g. during driving.", + "type": "sensor", + "unit": "W" + }, + "CurrentVoltage": { + "datatype": "float", + "description": "Current Voltage of the battery.", + "type": "sensor", + "unit": "V" + }, + "DCDC": { + "children": { + "PowerLoss": { + "datatype": "float", + "description": "Electrical energy lost by power dissipation to heat inside DC/DC converter.", + "type": "sensor", + "unit": "W" + }, + "Temperature": { + "datatype": "float", + "description": "Current temperature of DC/DC converter converting battery high voltage to vehicle low voltage (typically 12 Volts).", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Properties related to DC/DC converter converting high voltage (from high voltage battery) to vehicle low voltage (supply voltage, typically 12 Volts).", + "type": "branch" + }, + "GrossCapacity": { + "datatype": "uint16", + "description": "Gross capacity of the battery.", + "type": "attribute", + "unit": "kWh" + }, + "Id": { + "comment": "This could be serial number, part number plus serial number, UUID, or any other identifier that the OEM want to use to uniquely identify the battery individual.", + "datatype": "string", + "description": "Battery Identification Number as assigned by OEM.", + "type": "attribute" + }, + "IsGroundConnected": { + "comment": "It might be possible to disconnect the traction battery used by an electric powertrain. This is achieved by connectors, typically one for plus and one for minus.", + "datatype": "boolean", + "description": "Indicating if the ground (negative terminator) of the traction battery is connected to the powertrain.", + "type": "sensor" + }, + "IsPowerConnected": { + "comment": "It might be possible to disconnect the traction battery used by an electric powertrain. This is achieved by connectors, typically one for plus and one for minus.", + "datatype": "boolean", + "description": "Indicating if the power (positive terminator) of the traction battery is connected to the powertrain.", + "type": "sensor" + }, + "MaxVoltage": { + "datatype": "uint16", + "description": "Max allowed voltage of the battery, e.g. during charging.", + "type": "attribute", + "unit": "V" + }, + "NetCapacity": { + "datatype": "uint16", + "description": "Total net capacity of the battery considering aging.", + "type": "sensor", + "unit": "kWh" + }, + "NominalVoltage": { + "comment": "Nominal voltage typically refers to voltage of fully charged battery when delivering rated capacity.", + "datatype": "uint16", + "description": "Nominal Voltage of the battery.", + "type": "attribute", + "unit": "V" + }, + "PowerLoss": { + "datatype": "float", + "description": "Electrical energy lost by power dissipation to heat inside the battery.", + "type": "sensor", + "unit": "W" + }, + "ProductionDate": { + "datatype": "string", + "description": "Production date of battery in ISO8601 format, e.g. YYYY-MM-DD.", + "type": "attribute" + }, + "Range": { + "datatype": "uint32", + "description": "Remaining range in meters using only battery.", + "type": "sensor", + "unit": "m" + }, + "StateOfCharge": { + "children": { + "Current": { + "datatype": "float", + "description": "Physical state of charge of the high voltage battery, relative to net capacity. This is not necessarily the state of charge being displayed to the customer.", + "max": 100.0, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "CurrentEnergy": { + "comment": "Current energy could be calculated as .StateOfCharge.Current * .NetCapacity.", + "datatype": "float", + "description": "Physical state of charge of high voltage battery expressed in kWh.", + "type": "sensor", + "unit": "kWh" + }, + "Displayed": { + "datatype": "float", + "description": "State of charge displayed to the customer.", + "max": 100.0, + "min": 0, + "type": "sensor", + "unit": "percent" + } + }, + "description": "Information on the state of charge of the vehicle's high voltage battery.", + "type": "branch" + }, + "StateOfHealth": { + "comment": "Exact formula is implementation dependent. Could be e.g. current capacity at 20 degrees Celsius divided with original capacity at the same temperature.", + "datatype": "float", + "description": "Calculated battery state of health at standard conditions.", + "max": 100, + "min": 0, + "type": "sensor", + "unit": "percent" + }, + "Temperature": { + "children": { + "Average": { + "datatype": "float", + "description": "Current average temperature of the battery cells.", + "type": "sensor", + "unit": "celsius" + }, + "Max": { + "datatype": "float", + "description": "Current maximum temperature of the battery cells, i.e. temperature of the hottest cell.", + "type": "sensor", + "unit": "celsius" + }, + "Min": { + "datatype": "float", + "description": "Current minimum temperature of the battery cells, i.e. temperature of the coldest cell.", + "type": "sensor", + "unit": "celsius" + } + }, + "description": "Temperature Information for the battery pack.", + "type": "branch" + } + }, + "description": "Battery Management data.", + "type": "branch" + }, + "Transmission": { + "children": { + "ClutchEngagement": { + "datatype": "float", + "description": "Clutch engagement. 0% = Clutch fully disengaged. 100% = Clutch fully engaged.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "ClutchWear": { + "datatype": "uint8", + "description": "Clutch wear as a percent. 0 = no wear. 100 = worn.", + "max": 100, + "type": "sensor", + "unit": "percent" + }, + "CurrentGear": { + "datatype": "int8", + "description": "The current gear. 0=Neutral, 1/2/..=Forward, -1/-2/..=Reverse.", + "type": "sensor" + }, + "DiffLockFrontEngagement": { + "datatype": "float", + "description": "Front Diff Lock engagement. 0% = Diff lock fully disengaged. 100% = Diff lock fully engaged.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "DiffLockRearEngagement": { + "datatype": "float", + "description": "Rear Diff Lock engagement. 0% = Diff lock fully disengaged. 100% = Diff lock fully engaged.", + "max": 100, + "min": 0, + "type": "actuator", + "unit": "percent" + }, + "DriveType": { + "allowed": [ + "UNKNOWN", + "FORWARD_WHEEL_DRIVE", + "REAR_WHEEL_DRIVE", + "ALL_WHEEL_DRIVE" + ], + "datatype": "string", + "default": "UNKNOWN", + "description": "Drive type.", + "type": "attribute" + }, + "GearChangeMode": { + "allowed": [ + "MANUAL", + "AUTOMATIC" + ], + "datatype": "string", + "description": "Is the gearbox in automatic or manual (paddle) mode.", + "type": "actuator" + }, + "GearCount": { + "datatype": "int8", + "default": 0, + "description": "Number of forward gears in the transmission. -1 = CVT.", + "type": "attribute" + }, + "IsElectricalPowertrainEngaged": { + "comment": "In some hybrid solutions it is possible to disconnect/disengage the electrical powertrain mechanically to avoid induced voltage reaching a too high level when driving at high speed.", + "datatype": "boolean", + "description": "Is electrical powertrain mechanically connected/engaged to the drivetrain or not. False = Disconnected/Disengaged. True = Connected/Engaged.", + "type": "actuator" + }, + "IsLowRangeEngaged": { + "comment": "The possibility to switch between low and high gear range is typically only available in heavy vehicles and off-road vehicles.", + "datatype": "boolean", + "description": "Is gearbox in low range mode or not. False = Normal/High range engaged. True = Low range engaged.", + "type": "actuator" + }, + "IsParkLockEngaged": { + "datatype": "boolean", + "description": "Is the transmission park lock engaged or not. False = Disengaged. True = Engaged.", + "type": "actuator" + }, + "PerformanceMode": { + "allowed": [ + "NORMAL", + "SPORT", + "ECONOMY", + "SNOW", + "RAIN" + ], + "datatype": "string", + "description": "Current gearbox performance mode.", + "type": "actuator" + }, + "SelectedGear": { + "datatype": "int8", + "description": "The selected gear. 0=Neutral, 1/2/..=Forward, -1/-2/..=Reverse, 126=Park, 127=Drive.", + "type": "actuator" + }, + "Temperature": { + "datatype": "int16", + "description": "The current gearbox temperature.", + "type": "sensor", + "unit": "celsius" + }, + "TorqueDistribution": { + "datatype": "float", + "description": "Torque distribution between front and rear axle in percent. -100% = Full torque to front axle, 0% = 50:50 Front/Rear, 100% = Full torque to rear axle.", + "max": 100, + "min": -100, + "type": "actuator", + "unit": "percent" + }, + "TravelledDistance": { + "datatype": "float", + "description": "Odometer reading, total distance travelled during the lifetime of the transmission.", + "type": "sensor", + "unit": "km" + }, + "Type": { + "allowed": [ + "UNKNOWN", + "SEQUENTIAL", + "H", + "AUTOMATIC", + "DSG", + "CVT" + ], + "datatype": "string", + "default": "UNKNOWN", + "description": "Transmission type.", + "type": "attribute" + } + }, + "description": "Transmission-specific data, stopping at the drive shafts.", + "type": "branch" + }, + "Type": { + "allowed": [ + "COMBUSTION", + "HYBRID", + "ELECTRIC" + ], + "comment": "For vehicles with a combustion engine (including hybrids) more detailed information on fuels supported can be found in FuelSystem.SupportedFuelTypes and FuelSystem.SupportedFuels.", + "datatype": "string", + "description": "Defines the powertrain type of the vehicle.", + "type": "attribute" + } + }, + "description": "Powertrain data for battery management, etc.", + "type": "branch" + }, + "RoofLoad": { + "datatype": "int16", + "description": "The permitted total weight of cargo and installations (e.g. a roof rack) on top of the vehicle.", + "type": "attribute", + "unit": "kg" + }, + "Service": { + "children": { + "DistanceToService": { + "datatype": "float", + "description": "Remaining distance to service (of any kind). Negative values indicate service overdue.", + "type": "sensor", + "unit": "km" + }, + "IsServiceDue": { + "datatype": "boolean", + "description": "Indicates if vehicle needs service (of any kind). True = Service needed now or in the near future. False = No known need for service.", + "type": "sensor" + }, + "TimeToService": { + "datatype": "int32", + "description": "Remaining time to service (of any kind). Negative values indicate service overdue.", + "type": "sensor", + "unit": "s" + } + }, + "description": "Service data.", + "type": "branch" + }, + "Speed": { + "datatype": "float", + "description": "Vehicle speed.", + "type": "sensor", + "unit": "km/h" + }, + "StartTime": { + "comment": "This signal is supposed to be set whenever a new trip starts. A new trip is considered to start when engine gets enabled (e.g. LowVoltageSystemState in ON or START mode). A trip is considered to end when engine is no longer enabled. The default value indicates that the vehicle never has been started, or that latest start time is unknown.", + "datatype": "string", + "default": "0000-01-01T00:00Z", + "description": "Start time of current or latest trip, formatted according to ISO 8601 with UTC time zone.", + "type": "attribute" + }, + "Tachograph": { + "children": { + "DirectionIndicator": { + "datatype": "string", + "description": "Indicates the direction of the vehicle\n", + "type": "sensor" + }, + "Driver": { + "children": { + "Driver1": { + "children": { + "AuthenticationEquipment": { + "allowed": [ + "RESERVED", + "DRIVER_CARD", + "CONTROL_CARD", + "COMPANY_CARD", + "MANUFACTURING_CARD", + "VEHICLE_UNIT", + "MOTION_SENSOR" + ], + "comment": "See description of the field 'DriverAuthenticationEquipment'\nin COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "Code to distinguish different types of equipment for the tachograph application.", + "type": "attribute" + }, + "CardIssuingMemberState": { + "comment": "This field is formatted according the definition for NationAlpha\nin COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "The country alpha code of the Member State having issued the card.", + "type": "attribute" + }, + "CardRenewalIndex": { + "comment": "This field is formatted according the definition for CardRenewalIndex\n(chap 2.25) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "A card renewal index.", + "type": "attribute" + }, + "CardReplacementIndex": { + "comment": "This field is formatted according the definition for CardReplacementIndex\n(chap 2.26) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "A card replacement index.", + "type": "attribute" + }, + "Identification": { + "comment": "This field is formatted according the definition for driverIdentification\nin COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "The unique identification of a driver in a Member State.", + "type": "attribute" + }, + "IsCardPresent": { + "datatype": "boolean", + "description": "Indicates the presence of a driver card", + "type": "sensor" + }, + "IsLoggedIn": { + "datatype": "boolean", + "description": "Indicates if the driver is currently logged in.", + "type": "attribute" + }, + "OemIdentification": { + "datatype": "string", + "description": "An OEM specific driver id.", + "type": "attribute" + }, + "OemIdentificationType": { + "datatype": "string", + "description": "Contains an optional id type (e.g. pin, USB, encrypted EU id).", + "type": "attribute" + }, + "TimeRelatedStatus": { + "allowed": [ + "NORMAL", + "LIMIT_1", + "LIMIT_2", + "LIMIT_3", + "LIMIT_4", + "LIMIT_5", + "LIMIT_6", + "OTHER", + "ERROR", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "Indicates if the driver approaches or exceeds working time limits (or other limits).\n", + "type": "sensor" + }, + "WorkingState": { + "allowed": [ + "DRIVE", + "WORK", + "DRIVER_AVAILABLE", + "REST", + "ERROR", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "The current working state of the driver.\n0 - rest\n1 - driver available\n2 - work\n3 - drive\n6 - error\n7 - not available\n", + "type": "attribute" + } + }, + "description": "Information about the driver(s) of a (commercial) vehicle.", + "type": "branch" + }, + "Driver2": { + "children": { + "AuthenticationEquipment": { + "allowed": [ + "RESERVED", + "DRIVER_CARD", + "CONTROL_CARD", + "COMPANY_CARD", + "MANUFACTURING_CARD", + "VEHICLE_UNIT", + "MOTION_SENSOR" + ], + "comment": "See description of the field 'DriverAuthenticationEquipment'\nin COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "Code to distinguish different types of equipment for the tachograph application.", + "type": "attribute" + }, + "CardIssuingMemberState": { + "comment": "This field is formatted according the definition for NationAlpha\nin COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "The country alpha code of the Member State having issued the card.", + "type": "attribute" + }, + "CardRenewalIndex": { + "comment": "This field is formatted according the definition for CardRenewalIndex\n(chap 2.25) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "A card renewal index.", + "type": "attribute" + }, + "CardReplacementIndex": { + "comment": "This field is formatted according the definition for CardReplacementIndex\n(chap 2.26) in: COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "A card replacement index.", + "type": "attribute" + }, + "Identification": { + "comment": "This field is formatted according the definition for driverIdentification\nin COMMISSION REGULATION (EC) No 1360/2002 Annex 1b.\n", + "datatype": "string", + "description": "The unique identification of a driver in a Member State.", + "type": "attribute" + }, + "IsCardPresent": { + "datatype": "boolean", + "description": "Indicates the presence of a driver card", + "type": "sensor" + }, + "IsLoggedIn": { + "datatype": "boolean", + "description": "Indicates if the driver is currently logged in.", + "type": "attribute" + }, + "OemIdentification": { + "datatype": "string", + "description": "An OEM specific driver id.", + "type": "attribute" + }, + "OemIdentificationType": { + "datatype": "string", + "description": "Contains an optional id type (e.g. pin, USB, encrypted EU id).", + "type": "attribute" + }, + "TimeRelatedStatus": { + "allowed": [ + "NORMAL", + "LIMIT_1", + "LIMIT_2", + "LIMIT_3", + "LIMIT_4", + "LIMIT_5", + "LIMIT_6", + "OTHER", + "ERROR", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "Indicates if the driver approaches or exceeds working time limits (or other limits).\n", + "type": "sensor" + }, + "WorkingState": { + "allowed": [ + "DRIVE", + "WORK", + "DRIVER_AVAILABLE", + "REST", + "ERROR", + "NOT_AVAILABLE" + ], + "datatype": "string", + "description": "The current working state of the driver.\n0 - rest\n1 - driver available\n2 - work\n3 - drive\n6 - error\n7 - not available\n", + "type": "attribute" + } + }, + "description": "Information about the driver(s) of a (commercial) vehicle.", + "type": "branch" + } + }, + "description": "Information about the driver(s) of a (commercial) vehicle.", + "type": "branch" + }, + "IsAnalyzingPerformance": { + "datatype": "boolean", + "description": "Indicates whether the tachograph is currently analyzing its performance;\nincluding electronic or mechanical analysis, instrument analysis, speed sensor analysis,\nmass storage analysis, and printer analysis\n", + "type": "sensor" + }, + "IsHandlingInformationPresent": { + "datatype": "boolean", + "description": "Indicates that handling information is present. Information could include 'no printer paper', 'no driver card', etc\n", + "type": "sensor" + }, + "IsOverspeed": { + "datatype": "boolean", + "description": "Indicates whether the vehicle is exceeding the legal speed limit set in the tachograph.\n", + "type": "sensor" + }, + "IsSystemEventAvailable": { + "datatype": "boolean", + "description": "Indicates that a tachograph event has occurred. This may include power supply interruption,\ninterruption of the speed sensor, incorrect data on the driver card, driving without a driver\ncard, illegal removal of a driver card, insertion of a driver card during driving, and time adjustment\n", + "type": "sensor" + }, + "VehicleSpeed": { + "datatype": "double", + "description": "Speed of the vehicle registered by the tachograph.", + "min": 0.0, + "type": "sensor", + "unit": "km/h" + } + }, + "description": "Tachograph related data.", + "type": "branch" + }, + "Trailer": { + "children": { + "IsConnected": { + "datatype": "boolean", + "description": "Signal indicating if trailer is connected or not.", + "type": "sensor" + } + }, + "description": "Trailer signals.", + "type": "branch" + }, + "TraveledDistance": { + "datatype": "float", + "description": "Odometer reading, total distance traveled during the lifetime of the vehicle.", + "type": "sensor", + "unit": "km" + }, + "TraveledDistanceHighRes": { + "datatype": "uint64", + "description": "Accumulated distance travelled by the vehicle during its operation.", + "type": "sensor", + "unit": "m" + }, + "TraveledDistanceSinceStart": { + "comment": "A new trip is considered to start when engine gets enabled (e.g. LowVoltageSystemState in ON or START mode). A trip is considered to end when engine is no longer enabled. The signal may however keep the value of the last trip until a new trip is started.", + "datatype": "float", + "description": "Distance traveled since start of current trip.", + "type": "sensor", + "unit": "km" + }, + "TripDuration": { + "comment": "This signal is not assumed to be continuously updated, but instead set to 0 when a trip starts and set to the actual duration of the trip when a trip ends. A new trip is considered to start when engine gets enabled (e.g. LowVoltageSystemState in ON or START mode). A trip is considered to end when engine is no longer enabled.", + "datatype": "float", + "description": "Duration of latest trip.", + "type": "sensor", + "unit": "s" + }, + "TripMeterReading": { + "comment": "The trip meter is an odometer that can be manually reset by the driver", + "datatype": "float", + "description": "Trip meter reading.", + "type": "actuator", + "unit": "km" + }, + "VehicleIdentification": { + "children": { + "AcrissCode": { + "datatype": "string", + "description": "The ACRISS Car Classification Code is a code used by many car rental companies.", + "type": "attribute" + }, + "BodyType": { + "datatype": "string", + "description": "Indicates the design and body style of the vehicle (e.g. station wagon, hatchback, etc.).", + "type": "attribute" + }, + "Brand": { + "datatype": "string", + "description": "Vehicle brand or manufacturer.", + "type": "attribute" + }, + "DateVehicleFirstRegistered": { + "datatype": "string", + "description": "The date in ISO 8601 format of the first registration of the vehicle with the respective public authorities.", + "type": "attribute" + }, + "KnownVehicleDamages": { + "datatype": "string", + "description": "A textual description of known damages, both repaired and unrepaired.", + "type": "attribute" + }, + "MeetsEmissionStandard": { + "datatype": "string", + "description": "Indicates that the vehicle meets the respective emission standard.", + "type": "attribute" + }, + "Model": { + "datatype": "string", + "description": "Vehicle model.", + "type": "attribute" + }, + "OptionalExtras": { + "comment": "Allowed values are not standardized, each OEM can specify detail descriptions of array elements.", + "datatype": "string[]", + "description": "Optional extras refers to all car equipment options that are not installed as standard by the manufacturer.", + "type": "attribute" + }, + "ProductionDate": { + "datatype": "string", + "description": "The date in ISO 8601 format of production of the item, e.g. vehicle.", + "type": "attribute" + }, + "PurchaseDate": { + "datatype": "string", + "description": "The date in ISO 8601 format of the item e.g. vehicle was purchased by the current owner.", + "type": "attribute" + }, + "VIN": { + "datatype": "string", + "description": "17-character Vehicle Identification Number (VIN) as defined by ISO 3779.", + "type": "attribute" + }, + "VehicleConfiguration": { + "datatype": "string", + "description": "A short text indicating the configuration of the vehicle, e.g. '5dr hatchback ST 2.5 MT 225 hp' or 'limited edition'.", + "type": "attribute" + }, + "VehicleInteriorColor": { + "datatype": "string", + "description": "The color or color combination of the interior of the vehicle.", + "type": "attribute" + }, + "VehicleInteriorType": { + "datatype": "string", + "description": "The type or material of the interior of the vehicle (e.g. synthetic fabric, leather, wood, etc.).", + "type": "attribute" + }, + "VehicleModelDate": { + "datatype": "string", + "description": "The release date in ISO 8601 format of a vehicle model (often used to differentiate versions of the same make and model).", + "type": "attribute" + }, + "VehicleSeatingCapacity": { + "datatype": "uint16", + "description": "The number of passengers that can be seated in the vehicle, both in terms of the physical space available, and in terms of limitations set by law.", + "type": "attribute" + }, + "VehicleSpecialUsage": { + "datatype": "string", + "description": "Indicates whether the vehicle has been used for special purposes, like commercial rental, driving school.", + "type": "attribute" + }, + "WMI": { + "datatype": "string", + "description": "3-character World Manufacturer Identification (WMI) as defined by ISO 3780.", + "type": "attribute" + }, + "Year": { + "datatype": "uint16", + "description": "Model year of the vehicle.", + "type": "attribute" + } + }, + "description": "Attributes that identify a vehicle.", + "type": "branch" + }, + "VersionVSS": { + "children": { + "Label": { + "datatype": "string", + "description": "Label to further describe the version.", + "type": "attribute" + }, + "Major": { + "datatype": "uint32", + "default": 4, + "description": "Supported Version of VSS - Major version.", + "type": "attribute" + }, + "Minor": { + "datatype": "uint32", + "default": 0, + "description": "Supported Version of VSS - Minor version.", + "type": "attribute" + }, + "Patch": { + "datatype": "uint32", + "default": 0, + "description": "Supported Version of VSS - Patch version.", + "type": "attribute" + } + }, + "description": "Supported Version of VSS.", + "type": "branch" + }, + "Width": { + "datatype": "uint16", + "default": 0, + "description": "Overall vehicle width.", + "type": "attribute", + "unit": "mm" + } + }, + "description": "High-level vehicle data.", + "type": "branch" + } +} \ No newline at end of file diff --git a/spec/overlay/vss.json.license b/spec/overlay/vss.json.license new file mode 100644 index 0000000..59baed3 --- /dev/null +++ b/spec/overlay/vss.json.license @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0