├── .editorconfig ├── .github └── workflows │ ├── branch-master.yml │ └── release.yml ├── .gitignore ├── .nvmrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── TODO.md ├── jest.config.js ├── nodemon.json ├── package.json ├── scripts └── clean-pkg.js ├── src ├── api.ts ├── lib │ ├── convert │ │ ├── apply-conversion.ts │ │ ├── helpers │ │ │ └── hexadecimal.ts │ │ └── mappings │ │ │ ├── applied-brakes.ts │ │ │ ├── cloud-type.ts │ │ │ ├── engine-type.ts │ │ │ ├── fuel-tank.ts │ │ │ ├── index.ts │ │ │ ├── lights.ts │ │ │ ├── nav-back-course-flags.ts │ │ │ ├── nav-capabilities.ts │ │ │ ├── nearest-airports-ids.ts │ │ │ ├── precipitation-type.ts │ │ │ ├── runway-surface-condition.ts │ │ │ ├── seasons.ts │ │ │ ├── spoilers-control.ts │ │ │ ├── time-of-day.ts │ │ │ ├── units │ │ │ ├── ftsec-kt.ts │ │ │ └── index.ts │ │ │ └── vor-to-from.ts │ └── offsets │ │ ├── airport │ │ ├── pushback.ts │ │ └── runway.ts │ │ ├── environment │ │ ├── environment.ts │ │ ├── weather.ts │ │ └── weather │ │ │ ├── at-aircraft.ts │ │ │ └── settings.ts │ │ ├── failure │ │ └── failure.ts │ │ ├── index.ts │ │ ├── plane │ │ ├── apu.ts │ │ ├── autopilot.ts │ │ ├── cockpit.ts │ │ ├── controls.ts │ │ ├── electric.ts │ │ ├── engines.ts │ │ ├── engines │ │ │ ├── engine1.ts │ │ │ ├── engine2.ts │ │ │ ├── engine3.ts │ │ │ ├── engine4.ts │ │ │ ├── propeller1.ts │ │ │ ├── propeller2.ts │ │ │ ├── propeller3.ts │ │ │ └── propeller4.ts │ │ ├── fuel.ts │ │ ├── helicopter.ts │ │ ├── icing.ts │ │ ├── plane.ts │ │ ├── pressurisation.ts │ │ ├── radios.ts │ │ └── radios │ │ │ ├── adf1.ts │ │ │ ├── adf2.ts │ │ │ ├── ils.ts │ │ │ ├── nav1.ts │ │ │ └── nav2.ts │ │ ├── position-attitude │ │ └── position-attitude.ts │ │ └── simulation │ │ └── simulation.ts ├── shared │ ├── converted-offset-values.ts │ ├── environment │ │ └── time-of-day.ts │ ├── offset-category.ts │ ├── offset-list.ts │ ├── offset-values.ts │ ├── offset.ts │ ├── plane │ │ ├── brakes.ts │ │ ├── engine-type.ts │ │ └── fuel-tank.ts │ ├── radios │ │ └── vor-to-from.ts │ ├── runway │ │ └── runway-surface-condition.ts │ └── weather │ │ ├── cloud-type.ts │ │ ├── precipitation-type.ts │ │ └── season.ts ├── tsconfig.app.json └── tsconfig.prod.json ├── tests ├── api.spec.ts ├── convert │ ├── apply-conversion.spec.ts │ ├── helpers │ │ └── hexadecimal.spec.ts │ └── mappings │ │ ├── __snapshots__ │ │ └── mappings.spec.ts.snap │ │ ├── applied-brakes.spec.ts │ │ ├── cloud-type.spec.ts │ │ ├── engine-type.spec.ts │ │ ├── fuel-tank.spec.ts │ │ ├── lights.spec.ts │ │ ├── mappings.spec.ts │ │ ├── nav-backcourse-flags.spec.ts │ │ ├── nav-capabilities.spec.ts │ │ ├── nearest-airport-id.spec.ts │ │ ├── precipitation-type.spec.ts │ │ ├── runway-surface-condition.spec.ts │ │ ├── seasons.spec.ts │ │ ├── spoilers-control.spec.ts │ │ ├── time-of-day.spec.ts │ │ ├── units │ │ └── ftsec-kt.spec.ts │ │ └── vor-to-from.spec.ts ├── offsets │ ├── __snapshots__ │ │ ├── apu.spec.ts.snap │ │ └── offset.spec.ts.snap │ ├── airport │ │ ├── __snapshots__ │ │ │ ├── pushback.spec.ts.snap │ │ │ └── runway.spec.ts.snap │ │ ├── pushback.spec.ts │ │ └── runway.spec.ts │ ├── apu.spec.ts │ ├── environment │ │ ├── __snapshots__ │ │ │ ├── environment.spec.ts.snap │ │ │ └── weather.spec.ts.snap │ │ ├── environment.spec.ts │ │ ├── weather.spec.ts │ │ └── weather │ │ │ ├── __snapshots__ │ │ │ ├── at-aircraft.spec.ts.snap │ │ │ └── settings.spec.ts.snap │ │ │ ├── at-aircraft.spec.ts │ │ │ └── settings.spec.ts │ ├── failure │ │ ├── __snapshots__ │ │ │ └── failure.spec.ts.snap │ │ └── failure.spec.ts │ ├── offset.spec.ts │ ├── plane │ │ ├── __snapshots__ │ │ │ ├── autopilot.spec.ts.snap │ │ │ ├── cockpit.spec.ts.snap │ │ │ ├── controls.spec.ts.snap │ │ │ ├── electric.spec.ts.snap │ │ │ ├── engines.spec.ts.snap │ │ │ ├── fuel.spec.ts.snap │ │ │ ├── helicopter.spec.ts.snap │ │ │ ├── icing.spec.ts.snap │ │ │ ├── plane.spec.ts.snap │ │ │ ├── pressurisation.spec.ts.snap │ │ │ └── radios.spec.ts.snap │ │ ├── autopilot.spec.ts │ │ ├── cockpit.spec.ts │ │ ├── controls.spec.ts │ │ ├── electric.spec.ts │ │ ├── engines.spec.ts │ │ ├── engines │ │ │ ├── __snapshots__ │ │ │ │ ├── engine1.spec.ts.snap │ │ │ │ ├── engine2.spec.ts.snap │ │ │ │ ├── engine3.spec.ts.snap │ │ │ │ ├── engine4.spec.ts.snap │ │ │ │ ├── propeller1.spec.ts.snap │ │ │ │ ├── propeller2.spec.ts.snap │ │ │ │ ├── propeller3.spec.ts.snap │ │ │ │ └── propeller4.spec.ts.snap │ │ │ ├── engine1.spec.ts │ │ │ ├── engine2.spec.ts │ │ │ ├── engine3.spec.ts │ │ │ ├── engine4.spec.ts │ │ │ ├── propeller1.spec.ts │ │ │ ├── propeller2.spec.ts │ │ │ ├── propeller3.spec.ts │ │ │ └── propeller4.spec.ts │ │ ├── fuel.spec.ts │ │ ├── helicopter.spec.ts │ │ ├── icing.spec.ts │ │ ├── plane.spec.ts │ │ ├── pressurisation.spec.ts │ │ ├── radios.spec.ts │ │ └── radios │ │ │ ├── __snapshots__ │ │ │ ├── adf1.spec.ts.snap │ │ │ ├── adf2.spec.ts.snap │ │ │ ├── ils.spec.ts.snap │ │ │ ├── nav1.spec.ts.snap │ │ │ └── nav2.spec.ts.snap │ │ │ ├── adf1.spec.ts │ │ │ ├── adf2.spec.ts │ │ │ ├── ils.spec.ts │ │ │ ├── nav1.spec.ts │ │ │ └── nav2.spec.ts │ ├── position-attitude │ │ ├── __snapshots__ │ │ │ └── position-attitude.spec.ts.snap │ │ └── position-attitude.spec.ts │ └── simulation │ │ ├── __snapshots__ │ │ └── simulation.spec.ts.snap │ │ └── simulation.spec.ts ├── shared │ └── offset.spec.ts └── tsconfig.spec.json ├── tsconfig.json ├── tslint.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/workflows/branch-master.yml: -------------------------------------------------------------------------------- 1 | name: branch-master 2 | on: 3 | pull_request: 4 | branches: 5 | - master 6 | push: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | lint: 12 | name: lint 13 | runs-on: windows-latest 14 | timeout-minutes: 5 15 | steps: 16 | - name: setup:checkout 17 | uses: actions/checkout@master 18 | - name: setup:python3.7 19 | uses: actions/setup-python@v1 20 | with: 21 | python-version: '3.7' 22 | architecture: x64 23 | - name: setup:cache:node 24 | uses: actions/cache@v1.1.0 25 | with: 26 | path: ${{ github.workspace }}/node_modules 27 | key: ${{ runner.os }}-api-test-node-${{ hashFiles('yarn.lock') }} 28 | restore-keys: | 29 | ${{ runner.os }}-api-test-node- 30 | ${{ runner.os }}-api- 31 | - name: deps:install 32 | shell: bash 33 | run: | 34 | yarn 35 | - name: test:lint 36 | shell: bash 37 | run: | 38 | yarn tslint 39 | 40 | test: 41 | name: test 42 | runs-on: windows-latest 43 | timeout-minutes: 5 44 | steps: 45 | - name: setup:checkout 46 | uses: actions/checkout@master 47 | - name: setup:python3.7 48 | uses: actions/setup-python@v1 49 | with: 50 | python-version: '3.7' 51 | architecture: x64 52 | - name: setup:cache:node 53 | uses: actions/cache@v1.1.0 54 | with: 55 | path: ${{ github.workspace }}/node_modules 56 | key: ${{ runner.os }}-api-test-node-${{ hashFiles('yarn.lock') }} 57 | restore-keys: | 58 | ${{ runner.os }}-api-test-node- 59 | ${{ runner.os }}-api- 60 | - name: deps:install 61 | shell: bash 62 | run: | 63 | yarn 64 | - name: test:unit 65 | shell: bash 66 | run: | 67 | yarn test:ci 68 | - name: test:coverage 69 | uses: coverallsapp/github-action@master 70 | with: 71 | github-token: ${{ secrets.GITHUB_TOKEN }} 72 | path-to-lcov: ${{ github.workspace }}/coverage/lcov.info 73 | 74 | build: 75 | name: build 76 | runs-on: windows-latest 77 | timeout-minutes: 5 78 | steps: 79 | - name: setup:checkout 80 | uses: actions/checkout@master 81 | - name: setup:python3.7 82 | uses: actions/setup-python@v1 83 | with: 84 | python-version: '3.7' 85 | architecture: x64 86 | - name: setup:cache 87 | uses: actions/cache@v1.1.0 88 | with: 89 | path: ${{ github.workspace }}/node_modules 90 | key: ${{ runner.os }}-api-build-node-${{ hashFiles('yarn.lock') }} 91 | restore-keys: | 92 | ${{ runner.os }}-api-build-node- 93 | ${{ runner.os }}-api- 94 | - name: deps:install 95 | shell: bash 96 | run: | 97 | yarn 98 | - name: build:prod 99 | shell: bash 100 | run: | 101 | yarn compile:prod 102 | - name: build:upload:artifacts 103 | if: github.base_ref == 0 104 | uses: actions/upload-artifact@v1 105 | with: 106 | name: fsuipc-api-${{ github.sha }} 107 | path: ${{ github.workspace }}/dist 108 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | on: 3 | push: 4 | tags: 5 | - '*' 6 | 7 | jobs: 8 | build: 9 | name: build 10 | runs-on: windows-latest 11 | timeout-minutes: 5 12 | steps: 13 | - name: setup:checkout 14 | uses: actions/checkout@master 15 | - name: setup:python3.7 16 | uses: actions/setup-python@v1 17 | with: 18 | python-version: '3.7' 19 | architecture: x64 20 | - name: setup:cache 21 | uses: actions/cache@v1.1.0 22 | with: 23 | path: ${{ github.workspace }}/node_modules 24 | key: ${{ runner.os }}-api-build-node-${{ hashFiles('yarn.lock') }} 25 | restore-keys: | 26 | ${{ runner.os }}-api-build-node- 27 | ${{ runner.os }}-api- 28 | - name: deps:install 29 | shell: bash 30 | run: | 31 | yarn 32 | - name: build:prod 33 | shell: bash 34 | run: | 35 | yarn compile:prod 36 | - name: build:upload:artifacts 37 | uses: actions/upload-artifact@v1 38 | with: 39 | name: fsuipc-api-release 40 | path: ${{ github.workspace }}/dist 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | dist/ 4 | .jest-cache/ 5 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 12.12.0 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.4.1](https://github.com/fsuipc-node/api/compare/0.4.0...0.4.1) (2021-02-01) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * allow connexion to MSFS ([#9](https://github.com/fsuipc-node/api/issues/9)) ([9b21f19](https://github.com/fsuipc-node/api/commit/9b21f197cb6a9ef8eceee7d85e3f6b3f0a5c20aa)) 7 | 8 | 9 | 10 | # [0.4.0](https://github.com/fsuipc-node/api/compare/0.3.0...0.4.0) (2020-02-04) 11 | 12 | 13 | ### Features 14 | 15 | * add offsets up to 0x28F0 ([#4](https://github.com/fsuipc-node/api/issues/4)) ([3e0e76a](https://github.com/fsuipc-node/api/commit/3e0e76aa396e2d113ddf061b23cb37e12f7bc965)) 16 | 17 | 18 | 19 | # [0.3.0](https://github.com/fsuipc-node/api/compare/0.2.0...0.3.0) (2020-01-26) 20 | 21 | 22 | ### Features 23 | 24 | * add offsets up to 0xE92 ([#2](https://github.com/fsuipc-node/api/issues/2)) ([82941e8](https://github.com/fsuipc-node/api/commit/82941e8e71cf85995f9ca5a0c346f1f5c330524b)) 25 | 26 | 27 | 28 | # [0.2.0](https://github.com/fsuipc-node/api/compare/0.1.0...0.2.0) (2020-01-24) 29 | 30 | 31 | ### Features 32 | 33 | * add engine offsets ([#1](https://github.com/fsuipc-node/api/issues/1)) ([546e8e1](https://github.com/fsuipc-node/api/commit/546e8e15d5f427775daeac3446dfb1ab42273656)) 34 | 35 | 36 | 37 | # [0.1.0](https://github.com/fsuipc-node/api/compare/2160bf540ee04f2f6cd8870da5e6ce28b7228215...0.1.0) (2020-01-20) 38 | 39 | 40 | ### Features 41 | 42 | * **init:** create api ([2160bf5](https://github.com/fsuipc-node/api/commit/2160bf540ee04f2f6cd8870da5e6ce28b7228215)) 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2017-2020 Exalif Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | 24 | ----- 25 | 26 | This repository and its package are not related and not affialiated with original FSUIPC/WIDEFS creator or FSUIPC/WIDEFS software. 27 | 28 | You can find information about FSUIPC on their official website: http://www.fsuipc.com/ or on dedicated forum: https://forum.simflight.com/forum/30-fsuipc-support-pete-dowson-modules/ 29 | 30 | Please use this current library in accordance with FSUIPC terms, conditions and license. 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @fsuipc/api - FSUIPC Node API 2 | 3 | Tooling to use FSUIPC external application interface, with nodeJS. 4 | 5 | [![Coverage Status](https://coveralls.io/repos/github/fsuipc-node/api/badge.svg?branch=master)](https://coveralls.io/github/fsuipc-node/api?branch=master) 6 | [![npm version](https://badge.fury.io/js/%40fsuipc%2Fapi.svg)](https://badge.fury.io/js/%40fsuipc%2Fapi) 7 | ![branch-master](https://github.com/fsuipc-node/api/workflows/branch-master/badge.svg?branch=master) 8 | 9 | ## Disclamer 10 | 11 | This API is a wrapper around [fsuipc-node adapter by koesie10](https://github.com/koesie10/fsuipc-node) meant to create a simple API around all available fsuipc offsets. 12 | 13 | Please find any information about FSUIPC on [their website](http://www.fsuipc.com/). 14 | 15 | ## Requirements 16 | In order for [`fsuipc`](https://github.com/koesie10/fsuipc-node) (fsuipc-node) and `@fsuipc/api` (this package) to work, and so this API, you must have on your machine: 17 | - Windows 10 64bits 18 | - node 12+ 19 | - python 3.7 (don't forget to add it to your PATH) 20 | - visualstudio 2017+ with desktop C++ package 21 | - fsuipc installed as flight simulator plugin 22 | 23 | Node API usage requirements: 24 | - `rxjs` >= 6.5.0 25 | 26 | ## Installation 27 | ``` 28 | npm i --save @fsuipc/api 29 | or 30 | yarn add @fsuipc/api 31 | ``` 32 | 33 | ## API Usage 34 | 35 | After import, you can use `FsuipcApi` to listen to provided values. 36 | 37 | ### Import 38 | 39 | ```typescript 40 | import { FsuipcApi } from '@fsuipc/api'; 41 | ``` 42 | 43 | ### Instantiate 44 | 45 | ```typescript 46 | const fsuipcApi = new FsuipcApi(Simulator.FSX); 47 | ``` 48 | ### Init 49 | 50 | `FsuipcApi.init()` returns a promise when you are properly connected to FSUIPC stream. In case your flight simulator isn't running, this will throw an error. 51 | 52 | ### Listen to offsets values 53 | 54 | `FsuipcApi.listen()` methods takes 2-3 arguments: 55 | - `interval` [*number*]: interval at which values will be polled from FSUIPC stream 56 | - `offsetsList` [*string[]*]: a list of string representing offsets you want to subscribe on 57 | - `terminateOnError` [*boolean* = *true*]: if set to true, if any value is errored, you will be disconnected from FSUIPC stream 58 | 59 | This method returns a `ConvertedOffsetValues` observable. You can subscribe to this observable to handle values polled from stream. 60 | 61 | ### Complete example 62 | 63 | ```typescript 64 | import { FsuipcApi } from '@fsuipc/api'; 65 | 66 | const fsuipcApi = new FsuipcApi(Simulator.FSX); 67 | 68 | fsuipcApi.init().then(() => { 69 | fsuipcApi.listen(1000, [ 70 | 'gs', 71 | 'altitude', 72 | 'comFreq', 73 | 'lights', 74 | ]).subscribe((result) => { 75 | // Use the result here 76 | console.log(JSON.stringify(result)); 77 | }); 78 | }).catch((e) => 79 | console.error(e) 80 | ); 81 | ``` 82 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # Feature 2 | 3 | ## Offsets depending on others offset value to be converted: 4 | - `0xBDC`: flaps levels 5 | - `0xBE0`: flaps position indicator 6 | - `0xBE4`: flaps position indicator 7 | - `0xB50`: bleed air source control, value depending on aircraft model 8 | - `0x892`, `0x92A`, `0x9C2`, `0xA5A`: engine 1-4 starter switch position value depending on propulsion type 9 | - `0x898`: require engineRPMScaler for proper calculation 10 | - `0xC52`: VOR or ILS depending value for signal strength percent? 11 | 12 | ## Write offsets 13 | 14 | Convert should varies depending on write or read mode 15 | 16 | ## Offset missing mappings: 17 | - `0xAF8`: fuel tank selected 18 | - `0xE84`: cloud type 19 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | globals: { 5 | 'ts-jest': { 6 | tsConfig: 'tests/tsconfig.spec.json', 7 | } 8 | }, 9 | cacheDirectory: '.jest-cache', 10 | moduleNameMapper: { 11 | '@shared/(.*)': '/src/shared/$1', 12 | '@offsets/(.*)': '/src/lib/offsets/$1', 13 | '@offsets': '/src/lib/offsets/index.ts', 14 | '@mappings/(.*)': '/src/lib/convert/mappings/$1', 15 | '@convert/(.*)': '/src/lib/convert/$1', 16 | }, 17 | collectCoverageFrom: [ 18 | '**/*.ts', 19 | '!**/node_modules/**', 20 | '!**/*.d.ts', 21 | '!**/index.ts', 22 | '!**/types/**/*.ts', 23 | ], 24 | }; 25 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "NODE_ENV": "development" 4 | }, 5 | "watch": [ 6 | "tsconfig.json", 7 | "tsconfig.app.json", 8 | "tslint.json", 9 | "src/**/*.ts" 10 | ], 11 | "execMap": { 12 | "ts": "ts-node --files --type-check --project tsconfig.app.json -r tsconfig-paths/register" 13 | }, 14 | "events": { 15 | "start": "tslint -p tsconfig.app.json -c tslint.json", 16 | "restart": "tslint -p tsconfig.app.json -c tslint.json" 17 | }, 18 | "delay": "500" 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fsuipc/api", 3 | "version": "0.4.1", 4 | "author": { 5 | "name": "FSUIPC-Node Opensource Team", 6 | "url": "https://github.com/fsuipc-node" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/fsuipc-node/api" 11 | }, 12 | "homepage": "https://github.com/fsuipc-node", 13 | "license": "MIT", 14 | "main": "./api.js", 15 | "types": "./lib/index.d.ts", 16 | "scripts": { 17 | "start": "nodemon --exec cross-env TS_NODE_FILES=true TS_NODE_TYPE_CHECK=true TS_NODE_PROJECT=src/tsconfig.app.json node --inspect -r tsconfig-paths/register -r ts-node/register ./src/api.ts", 18 | "compile:dev": "tsc --declaration -p src/tsconfig.app.json", 19 | "compile:prod": "tsc --declaration -p src/tsconfig.prod.json", 20 | "postcompile:dev": "npx tscpaths -v -r -p src/tsconfig.app.json -s ./dist", 21 | "postcompile:prod": "npx tscpaths -v -r -p src/tsconfig.prod.json -s ./dist && yarn copy:docs && yarn copy:package", 22 | "copy:docs": "cp README.md LICENSE dist/", 23 | "copy:package": "node scripts/clean-pkg", 24 | "test": "jest --watch", 25 | "test:ci": "jest --coverage", 26 | "tslint": "tslint -p src/tsconfig.app.json -c tslint.json && tslint -p tests/tsconfig.spec.json -c tslint.json", 27 | "changelog": "npx conventional-changelog -p angular -i CHANGELOG.md -s", 28 | "changelog:generate": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0" 29 | }, 30 | "dependencies": { 31 | "fsuipc": "^0.5.0", 32 | "rxjs": "^7.5.6", 33 | "vm2": "^3.8.0" 34 | }, 35 | "peerDependencies": { 36 | "vm2": "^3.8.0" 37 | }, 38 | "devDependencies": { 39 | "@exalif/tscpaths": "0.1.3", 40 | "@types/jest": "25.1.1", 41 | "@types/node": "13.5.3", 42 | "conventional-changelog-cli": "2.0.31", 43 | "cross-env": "7.0.0", 44 | "jest": "25.1.0", 45 | "nodemon": "2.0.2", 46 | "ts-jest": "25.1.0", 47 | "ts-node": "8.6.2", 48 | "tsconfig-paths": "3.9.0", 49 | "tslint": "6.0.0", 50 | "typescript": "3.7.5" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /scripts/clean-pkg.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const ORIG_PKG_PATH = path.resolve(__dirname, '../package.json'); 5 | const DEST = path.resolve(__dirname, '../dist/package.json'); 6 | 7 | const pkgData = require(ORIG_PKG_PATH); 8 | 9 | delete pkgData.scripts; 10 | delete pkgData.devDependencies; 11 | delete pkgData.dependencies; 12 | 13 | fs.writeFileSync(DEST, JSON.stringify(pkgData, null, 2), (err) => { 14 | if (err) throw err; 15 | }); 16 | -------------------------------------------------------------------------------- /src/api.ts: -------------------------------------------------------------------------------- 1 | import { FSUIPC, Simulator, Type, FSUIPCError } from 'fsuipc'; 2 | import { timer, from, Observable, throwError } from 'rxjs'; 3 | import { switchMap, catchError, map } from 'rxjs/operators'; 4 | 5 | import { Offset } from '@shared/offset'; 6 | import { OffsetValues } from '@shared/offset-values'; 7 | import { ConvertedOffsetValues } from '@shared/converted-offset-values'; 8 | import { OFFSETS } from '@offsets'; 9 | import { applyConversion } from '@convert/apply-conversion'; 10 | 11 | export class FsuipcApi { 12 | private fsuipcGlobalInstance: FSUIPC; 13 | private fsuipc: FSUIPC; 14 | private watchedOffsetCache: any[] = []; 15 | 16 | constructor(private simulator?: Simulator) {} 17 | 18 | public async init() { 19 | this.fsuipcGlobalInstance = new FSUIPC(); 20 | 21 | try { 22 | if (this.simulator){ 23 | this.fsuipc = await this.fsuipcGlobalInstance.open(this.simulator); 24 | } else { 25 | this.fsuipc = await this.fsuipcGlobalInstance.open(); 26 | } 27 | return true; 28 | } catch (error) { 29 | throw new FSUIPCError(error.message, error.code); 30 | } 31 | } 32 | 33 | public listen(interval: number, offsetList: string[], terminateOnError: boolean = true): Observable { 34 | if (!this.fsuipc) { 35 | return throwError('NO_FSUIPC_INSTANCE'); 36 | } 37 | 38 | this.watchOffsets(offsetList); 39 | 40 | return timer(interval, interval).pipe( 41 | switchMap(() => 42 | from(this.fsuipc.process()).pipe( 43 | map((result: object) => { 44 | const rawOffsetValues: OffsetValues = { ...result }; 45 | let offsetValues: ConvertedOffsetValues = {}; 46 | 47 | for (let offsetName of Object.keys(rawOffsetValues)) { 48 | offsetValues = { ...offsetValues, [offsetName]: applyConversion(OFFSETS[offsetName], rawOffsetValues[offsetName]) }; 49 | } 50 | 51 | return offsetValues; 52 | }), 53 | catchError((error: FSUIPCError) => { 54 | if (terminateOnError) { 55 | this.fsuipc.close(); 56 | } 57 | 58 | return throwError(error); 59 | }), 60 | ) 61 | ) 62 | ); 63 | } 64 | 65 | private watchOffsets(offsetList: string[]): void { 66 | if (this.shouldUpdateCache(offsetList)) { 67 | this.watchedOffsetCache = offsetList; 68 | } 69 | 70 | for (const offsetName of this.watchedOffsetCache) { 71 | const offset: Offset = OFFSETS[offsetName]; 72 | 73 | if (offset.type === Type.ByteArray || offset.type === Type.String || offset.type === Type.BitArray ) { 74 | const offsetType = offset.type as Type.ByteArray | Type.String | Type.BitArray; 75 | this.fsuipc.add(offset.name, offset.value, offsetType, offset.length); 76 | } else { 77 | const offsetType = offset.type as Type.Byte | Type.SByte | Type.Int16 | Type.Int32 | Type.Int64 | Type.UInt16 | Type.UInt32 | Type.UInt64 | Type.Double | Type.Single; 78 | this.fsuipc.add(offset.name, offset.value, offsetType); 79 | } 80 | } 81 | } 82 | 83 | private shouldUpdateCache(offsetList: string[] = []): boolean { 84 | return offsetList.length > 0 && ( 85 | !this.watchedOffsetCache.length || 86 | !this.watchedOffsetCache.every(item => offsetList.includes(item) ) 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/lib/convert/apply-conversion.ts: -------------------------------------------------------------------------------- 1 | import { VM } from 'vm2'; 2 | 3 | import { Offset } from '@shared/offset'; 4 | import { RawOffsetValue } from '@shared/offset-values'; 5 | import { ConvertedOffsetValue } from '@shared/converted-offset-values'; 6 | 7 | export const applyConversion = (offset: Offset, rawOffsetValue: RawOffsetValue): ConvertedOffsetValue => { 8 | if (!offset.convert) { 9 | return rawOffsetValue; 10 | } 11 | 12 | if (offset.hasMapping) { 13 | if (offset.isMappingInvalid) { 14 | return 'INVALID_MAPPING_FUNCTION'; 15 | } 16 | 17 | return offset.mappingFunction(rawOffsetValue); 18 | } else { 19 | // tslint:disable-next-line:no-eval 20 | if (offset.isInvalidConvertExpression) { 21 | return 'UNSUPPORTED_CONVERSION_EXPRESSION'; 22 | } 23 | 24 | return new VM().run( 25 | replaceOffsetExpressionValue(offset, rawOffsetValue) 26 | ); 27 | } 28 | }; 29 | 30 | export const replaceOffsetExpressionValue = (offset: Offset, rawOffsetValue: RawOffsetValue): string => { 31 | return offset.convert.replace( 32 | new RegExp(/{VAL}/g), 33 | Array.isArray(rawOffsetValue) 34 | ? `${JSON.stringify(rawOffsetValue)}` 35 | : typeof rawOffsetValue === 'string' 36 | ? `'${rawOffsetValue}'` 37 | : rawOffsetValue.toString() 38 | ); 39 | }; 40 | -------------------------------------------------------------------------------- /src/lib/convert/helpers/hexadecimal.ts: -------------------------------------------------------------------------------- 1 | export class HexadecimalHelper { 2 | public static binToHex(value: number): string { 3 | return value.toString(16); 4 | } 5 | 6 | public static hex2string(hex: string | number): string { 7 | const hexStr = hex.toString(); 8 | let str = ''; 9 | 10 | for (let i = 0; i < hexStr.length; i += 2) { 11 | str += String.fromCharCode(parseInt(hexStr.substr(i, 2), 16)); 12 | } 13 | 14 | return str; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/applied-brakes.ts: -------------------------------------------------------------------------------- 1 | import { Brakes } from '@shared/plane/brakes'; 2 | 3 | export const appliedBrakes = (value: number): Brakes => { 4 | switch (value) { 5 | case 1: 6 | return Brakes.LEFT; 7 | case 2: 8 | return Brakes.RIGHT; 9 | case 3: 10 | return Brakes.BOTH; 11 | default: 12 | return null; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/cloud-type.ts: -------------------------------------------------------------------------------- 1 | import { CloudType } from '@shared/weather/cloud-type'; 2 | 3 | export const cloudType = (value: number): CloudType => { 4 | switch (value) { 5 | case 1: 6 | return CloudType.CIRRUS; 7 | case 8: 8 | return CloudType.STRATUS; 9 | case 9: 10 | return CloudType.CUMULUS; 11 | default: 12 | return CloudType.USER; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/engine-type.ts: -------------------------------------------------------------------------------- 1 | import { EngineType } from '@shared/plane/engine-type'; 2 | 3 | export const engineType = (value: number): EngineType => { 4 | switch (value) { 5 | case 0: 6 | return EngineType.PISTON; 7 | case 1: 8 | return EngineType.JET; 9 | case 2: 10 | return EngineType.SAILPLANE; 11 | case 3: 12 | return EngineType.HELO; 13 | case 4: 14 | return EngineType.ROCKET; 15 | case 5: 16 | return EngineType.TURBOPROP; 17 | default: 18 | return null; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/fuel-tank.ts: -------------------------------------------------------------------------------- 1 | import { FuelTank } from '@shared/plane/fuel-tank'; 2 | 3 | export const fuelTank = (value: number): FuelTank => { 4 | switch (value) { 5 | case 0: 6 | return FuelTank.NONE; 7 | case 1: 8 | return FuelTank.ALL; 9 | case 2: 10 | return FuelTank.LEFT; 11 | case 3: 12 | return FuelTank.RIGHT; 13 | case 4: 14 | return FuelTank.LEFT_AUX; 15 | case 5: 16 | return FuelTank.RIGHT_AUX; 17 | case 6: 18 | return FuelTank.CENTER; 19 | case 7: 20 | return FuelTank.CENTER2; 21 | case 8: 22 | return FuelTank.CENTER3; 23 | case 9: 24 | return FuelTank.EXT1; 25 | case 10: 26 | return FuelTank.EXT2; 27 | case 11: 28 | return FuelTank.RIGHT_TIP; 29 | case 12: 30 | return FuelTank.LEFT_TIP; 31 | case 13: 32 | return FuelTank.CROSS_FEED; 33 | case 14: 34 | return FuelTank.CROSS_FEED_LTR; 35 | case 15: 36 | return FuelTank.CROSS_FEED_RTL; 37 | case 16: 38 | return FuelTank.CROSS_FEED_BOTH; 39 | case 17: 40 | return FuelTank.EXTERNAL; 41 | case 18: 42 | return FuelTank.ISOLATE; 43 | case 19: 44 | return FuelTank.LEFT_MAIN; 45 | case 20: 46 | return FuelTank.RIGHT_MAIN; 47 | default: 48 | return null; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/index.ts: -------------------------------------------------------------------------------- 1 | import { lightsMapping } from './lights'; 2 | import { runwaySurfaceCondition } from './runway-surface-condition'; 3 | import { precipitationType } from './precipitation-type'; 4 | import { cloudType } from './cloud-type'; 5 | import { seasons } from './seasons'; 6 | import { ftsecToKt, ktToFtsec } from './units'; 7 | import { engineType } from './engine-type'; 8 | import { nearestAirportsIds } from './nearest-airports-ids'; 9 | import { appliedBrakes } from './applied-brakes'; 10 | import { spoilersControl } from './spoilers-control'; 11 | import { vorToFrom } from './vor-to-from'; 12 | import { navBackCourseFlags } from './nav-back-course-flags'; 13 | import { navCapabilities } from './nav-capabilities'; 14 | import { fuelTank } from './fuel-tank'; 15 | 16 | export const MAPPINGS: { [key: string]: (_: any) => any } = { 17 | lightsMapping, 18 | runwaySurfaceCondition, 19 | 20 | // weather 21 | precipitationType, 22 | seasons, 23 | cloudType, 24 | 25 | // units 26 | ftsecToKt, 27 | ktToFtsec, 28 | 29 | // plane 30 | engineType, 31 | appliedBrakes, 32 | spoilersControl, 33 | fuelTank, 34 | 35 | // environment 36 | nearestAirportsIds, 37 | 38 | // radios, 39 | vorToFrom, 40 | navBackCourseFlags, 41 | navCapabilities, 42 | }; 43 | 44 | export * from './lights'; 45 | export * from './runway-surface-condition'; 46 | export * from './precipitation-type'; 47 | export * from './seasons'; 48 | export * from './units'; 49 | export * from './engine-type'; 50 | export * from './applied-brakes'; 51 | export * from './spoilers-control'; 52 | export * from './vor-to-from'; 53 | export * from './nav-back-course-flags'; 54 | export * from './nav-capabilities'; 55 | export * from './fuel-tank'; 56 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/lights.ts: -------------------------------------------------------------------------------- 1 | const Lights = ['nav', 'beacon', 'land', 'taxi', 'strobe', 'panel', 'recognition', 'wing', 'logo', 'cabin']; 2 | 3 | export const lightsMapping = (values: number[]): { [key: string]: boolean } => { 4 | const lights: { [key: string]: boolean } = {}; 5 | 6 | values.forEach((value, index) => { 7 | const lightName: string = Lights[index]; 8 | 9 | if (!lightName) { 10 | return; 11 | } 12 | 13 | lights[lightName] = !!value; 14 | }); 15 | 16 | return lights; 17 | }; 18 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/nav-back-course-flags.ts: -------------------------------------------------------------------------------- 1 | const BackCourseFlags = [ 2 | { name: 'backCourseAvailable', index: 0 }, 3 | { name: 'localiserTunedIn', index: 1 }, 4 | { name: 'onBackCourse', index: 2 }, 5 | { name: 'stationActive', index: 7 }, 6 | ]; 7 | 8 | export const navBackCourseFlags = (values: number[]): { [key: string]: boolean } => { 9 | const flags: { [key: string]: boolean } = {}; 10 | 11 | values.forEach((value, index) => { 12 | const flagName = BackCourseFlags.find(flag => flag.index === index); 13 | 14 | if (!flagName) { 15 | return; 16 | } 17 | 18 | flags[flagName.name] = !!value; 19 | }); 20 | 21 | return flags; 22 | }; 23 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/nav-capabilities.ts: -------------------------------------------------------------------------------- 1 | const Capabilities = ['dme', 'tacan', 'voice', 'noSignal', 'dmeGlideslope', 'noBackCourse', 'glideslope', 'isLocaliser']; 2 | 3 | export const navCapabilities = (values: number[]): { [key: string]: boolean } => { 4 | const capabilities: { [key: string]: boolean } = {}; 5 | 6 | values.forEach((value, index) => { 7 | const capability: string = Capabilities[index]; 8 | 9 | if (!capability) { 10 | return; 11 | } 12 | 13 | capabilities[capability] = !!value; 14 | }); 15 | 16 | return capabilities; 17 | }; 18 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/nearest-airports-ids.ts: -------------------------------------------------------------------------------- 1 | import { HexadecimalHelper } from '@convert/helpers/hexadecimal'; 2 | 3 | const NEAREST_AIRPORTS_COUNT = 6; 4 | const AIRPORT_OFFSET_SIZE = 4; 5 | const PADDING = 16; 6 | const TOTAL_AIRPORT_OFFSET_SIZE = AIRPORT_OFFSET_SIZE + PADDING; 7 | 8 | export const nearestAirportsIds = (values: number[]): string[] => { 9 | let airports: string[] = []; 10 | 11 | for (let i = 0; i < TOTAL_AIRPORT_OFFSET_SIZE * NEAREST_AIRPORTS_COUNT; i += TOTAL_AIRPORT_OFFSET_SIZE) { 12 | 13 | const airportBinValue = values.slice(i, i + AIRPORT_OFFSET_SIZE); 14 | if (airportBinValue.join('') === '0000') { 15 | airports.push(''); 16 | } else { 17 | const airportCode = values 18 | .slice(i, i + AIRPORT_OFFSET_SIZE) 19 | .map(HexadecimalHelper.binToHex) 20 | .map(HexadecimalHelper.hex2string) 21 | .join(''); 22 | airports.push(airportCode); 23 | } 24 | } 25 | 26 | return airports; 27 | }; 28 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/precipitation-type.ts: -------------------------------------------------------------------------------- 1 | import { PrecipitationType } from '@shared/weather/precipitation-type'; 2 | 3 | export const precipitationType = (value: number): PrecipitationType => { 4 | switch (value) { 5 | case 0: 6 | return PrecipitationType.NONE; 7 | case 1: 8 | return PrecipitationType.RAIN; 9 | case 2: 10 | return PrecipitationType.SNOW; 11 | default: 12 | return null; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/runway-surface-condition.ts: -------------------------------------------------------------------------------- 1 | import { SurfaceCondition } from '@shared/runway/runway-surface-condition'; 2 | 3 | export const runwaySurfaceCondition = (value: number): SurfaceCondition => { 4 | switch (value) { 5 | case 0: 6 | return SurfaceCondition.NORMAL; 7 | case 1: 8 | return SurfaceCondition.WET; 9 | case 2: 10 | return SurfaceCondition.ICY; 11 | case 3: 12 | return SurfaceCondition.SNOW; 13 | default: 14 | return null; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/seasons.ts: -------------------------------------------------------------------------------- 1 | import { Season } from '@shared/weather/season'; 2 | 3 | export const seasons = (value: number): Season => { 4 | switch (value) { 5 | case 0: 6 | return Season.WINTER; 7 | case 1: 8 | return Season.SPRING; 9 | case 2: 10 | return Season.SUMMER; 11 | case 3: 12 | return Season.AUTUMN; 13 | default: 14 | return null; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/spoilers-control.ts: -------------------------------------------------------------------------------- 1 | export const spoilersControl = (value: number): number => { 2 | if (value < 4800) { 3 | return 0; 4 | } 5 | 6 | return Math.round((value - 4800) / (16383 - 4800) * 100); 7 | }; 8 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/time-of-day.ts: -------------------------------------------------------------------------------- 1 | import { TimeOfDay } from '@shared/environment/time-of-day'; 2 | 3 | export const timeOfDay = (value: number): TimeOfDay => { 4 | switch (value) { 5 | case 1: 6 | return TimeOfDay.DAY; 7 | case 2: 8 | return TimeOfDay.DUSK_DAWN; 9 | case 3: 10 | return TimeOfDay.NIGHT; 11 | default: 12 | return null; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/units/ftsec-kt.ts: -------------------------------------------------------------------------------- 1 | const FEET_BY_SEC_TO_KT: number = 0.592484; 2 | 3 | export const ftsecToKt = (value: number): number => { 4 | return +(value * FEET_BY_SEC_TO_KT).toFixed(2); 5 | }; 6 | 7 | export const ktToFtsec = (value: number): number => { 8 | return +(value / FEET_BY_SEC_TO_KT).toFixed(2); 9 | }; 10 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/units/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ftsec-kt'; 2 | -------------------------------------------------------------------------------- /src/lib/convert/mappings/vor-to-from.ts: -------------------------------------------------------------------------------- 1 | import { VorToFrom } from '@shared/radios/vor-to-from'; 2 | 3 | export const vorToFrom = (value: number): VorToFrom => { 4 | switch (value) { 5 | case 0: 6 | return VorToFrom.OFF; 7 | case 1: 8 | return VorToFrom.TO; 9 | case 2: 10 | return VorToFrom.FROM; 11 | default: 12 | return null; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /src/lib/offsets/airport/pushback.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const pushback: OffsetList = { 8 | pushbackAngle: new Offset({ 9 | value: 0x334, 10 | name: 'pushbackAngle', 11 | category: OffsetCategory.PUSHBACK, 12 | description: 'pushback angle - radians', 13 | type: Type.Single, 14 | permission: 'r', 15 | }), 16 | pushbackXContact: new Offset({ 17 | value: 0x338, 18 | name: 'pushbackXContact', 19 | category: OffsetCategory.PUSHBACK, 20 | description: 'pushback X contact - ft', 21 | type: Type.Single, 22 | permission: 'r', 23 | }), 24 | pushbackYContact: new Offset({ 25 | value: 0x33C, 26 | name: 'pushbackYContact', 27 | category: OffsetCategory.PUSHBACK, 28 | description: 'pushback Y contact - ft', 29 | type: Type.Single, 30 | permission: 'r', 31 | }), 32 | pushbackZContact: new Offset({ 33 | value: 0x340, 34 | name: 'pushbackZContact', 35 | category: OffsetCategory.PUSHBACK, 36 | description: 'pushback Z contact - ft', 37 | type: Type.Single, 38 | permission: 'r', 39 | }), 40 | pushbackWaitFlag: new Offset({ 41 | value: 0x344, 42 | name: 'pushbackWaitFlag', 43 | category: OffsetCategory.PUSHBACK, 44 | description: 'pushback wait flag', 45 | convert: '!!{VAL}', 46 | type: Type.UInt16, 47 | permission: 'r', 48 | }), 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /src/lib/offsets/airport/runway.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const runway: OffsetList = { 8 | runwaySurfaceCondition: new Offset({ 9 | value: 0x346, 10 | name: 'runwaySurfaceCondition', 11 | category: OffsetCategory.RUNWAY, 12 | description: 'surface condition', 13 | type: Type.Byte, 14 | mapping: true, 15 | convert: 'runwaySurfaceCondition', 16 | permission: 'r', 17 | }), 18 | runwaySurfaceConditionValid: new Offset({ 19 | value: 0x347, 20 | name: 'runwaySurfaceConditionValid', 21 | category: OffsetCategory.RUNWAY, 22 | description: 'surface condition valid flag', 23 | type: Type.Byte, 24 | convert: '!!{VAL}', 25 | permission: 'r', 26 | }), 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /src/lib/offsets/index.ts: -------------------------------------------------------------------------------- 1 | import { OffsetList } from '@shared/offset-list'; 2 | 3 | import { positionAttitude } from './position-attitude/position-attitude'; 4 | import { simulation } from './simulation/simulation'; 5 | import { runway } from './airport/runway'; 6 | import { pushback } from './airport/pushback'; 7 | import { environment } from './environment/environment'; 8 | import { weather } from './environment/weather'; 9 | import { plane } from './plane/plane'; 10 | import { APU } from './plane/apu'; 11 | import { controls } from './plane/controls'; 12 | import { fuel } from './plane/fuel'; 13 | import { cockpit } from './plane/cockpit'; 14 | import { radios } from './plane/radios'; 15 | import { pressurisation } from './plane/pressurisation'; 16 | import { icing } from './plane/icing'; 17 | import { engines } from './plane/engines'; 18 | import { autopilot } from './plane/autopilot'; 19 | import { failure } from './failure/failure'; 20 | import { electric } from './plane/electric'; 21 | 22 | export const OFFSETS: OffsetList = { 23 | // Position and Attitude 24 | ...positionAttitude, 25 | 26 | // Simulation 27 | ...simulation, 28 | 29 | // Airport 30 | ...pushback, 31 | ...runway, 32 | 33 | // Environment 34 | ...environment, 35 | ...weather, 36 | 37 | // Failures 38 | ...failure, 39 | 40 | // Plane 41 | ...plane, 42 | ...APU, 43 | ...controls, 44 | ...cockpit, 45 | ...fuel, 46 | ...radios, 47 | ...pressurisation, 48 | ...icing, 49 | ...engines, 50 | ...autopilot, 51 | ...electric, 52 | }; 53 | 54 | export * from './airport/runway'; 55 | export * from './airport/pushback'; 56 | export * from './environment/environment'; 57 | export * from './environment/weather'; 58 | export * from './position-attitude/position-attitude'; 59 | export * from './plane/plane'; 60 | export * from './plane/apu'; 61 | export * from './plane/controls'; 62 | export * from './plane/cockpit'; 63 | export * from './plane/fuel'; 64 | export * from './plane/radios'; 65 | export * from './plane/pressurisation'; 66 | export * from './plane/icing'; 67 | export * from './plane/engines'; 68 | export * from './plane/autopilot'; 69 | export * from './simulation/simulation'; 70 | export * from './plane/electric'; 71 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/apu.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const APU: OffsetList = { 8 | APUGeneratorSwitch: new Offset({ 9 | value: 0xB51, 10 | name: 'APUGeneratorSwitch', 11 | category: OffsetCategory.APU, 12 | description: 'APU generator switch', 13 | convert: '!!{VAL}', 14 | type: Type.Byte, 15 | permission: 'rw', 16 | }), 17 | APUGeneratorActive: new Offset({ 18 | value: 0xB52, 19 | name: 'APUGeneratorActive', 20 | category: OffsetCategory.APU, 21 | description: 'APU generator active', 22 | convert: '!!{VAL}', 23 | type: Type.Byte, 24 | permission: 'r', 25 | }), 26 | APUOnFire: new Offset({ 27 | value: 0xB53, 28 | name: 'APUOnFire', 29 | category: OffsetCategory.APU, 30 | description: 'APU generator active', 31 | convert: '!!{VAL}', 32 | type: Type.Byte, 33 | permission: 'r', 34 | }), 35 | APUMaxRPM: new Offset({ 36 | value: 0xB54, 37 | name: 'APUMaxRPM', 38 | category: OffsetCategory.APU, 39 | description: 'APU generator max RPM percent', 40 | convert: '+({VAL}).toFixed(2)', 41 | type: Type.Single, 42 | permission: 'r', 43 | }), 44 | APUStarter: new Offset({ 45 | value: 0xB58, 46 | name: 'APUStarter', 47 | category: OffsetCategory.APU, 48 | description: 'APU starter', 49 | convert: '{VAL} ? 1 : 0', 50 | type: Type.Single, 51 | permission: 'rw', 52 | }), 53 | APUVoltage: new Offset({ 54 | value: 0xB5C, 55 | name: 'APUVoltage', 56 | category: OffsetCategory.APU, 57 | description: 'APU generator voltage', 58 | convert: '+({VAL}).toFixed(2)', 59 | type: Type.Single, 60 | permission: 'rw', 61 | }), 62 | }; 63 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/engines.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | import { engine1 } from './engines/engine1'; 8 | import { engine2 } from './engines/engine2'; 9 | import { engine3 } from './engines/engine3'; 10 | import { engine4 } from './engines/engine4'; 11 | import { propeller1 } from './engines/propeller1'; 12 | 13 | export const engines: OffsetList = { 14 | engineType: new Offset({ 15 | value: 0x609, 16 | name: 'engineType', 17 | category: OffsetCategory.ENGINE, 18 | description: 'engine type', 19 | convert: 'engineType', 20 | mapping: true, 21 | type: Type.Byte, 22 | permission: 'r', 23 | }), 24 | hasMixtureControl: new Offset({ 25 | value: 0x780, 26 | name: 'hasMixtureControl', 27 | category: OffsetCategory.ENGINE, 28 | description: 'has mixture control', 29 | convert: '!!{VAL}', 30 | type: Type.UInt32, 31 | permission: 'r', 32 | }), 33 | hasCarbHeat: new Offset({ 34 | value: 0x784, 35 | name: 'hasCarbHeat', 36 | category: OffsetCategory.ENGINE, 37 | description: 'has carb heat', 38 | convert: '!!{VAL}', 39 | type: Type.UInt32, 40 | permission: 'r', 41 | }), 42 | activeEngine: new Offset({ 43 | value: 0x888, 44 | name: 'activeEngine', 45 | category: OffsetCategory.ENGINE, 46 | description: 'active engine pattern', 47 | type: Type.BitArray, 48 | length: 1, 49 | permission: 'rw', 50 | }), 51 | enginesCount: new Offset({ 52 | value: 0xAEC, 53 | name: 'enginesCount', 54 | category: OffsetCategory.ENGINE, 55 | description: 'engines count', 56 | type: Type.Int16, 57 | permission: 'r', 58 | }), 59 | throttleLowerLimit: new Offset({ 60 | value: 0xB00, 61 | name: 'throttleLowerLimit', 62 | category: OffsetCategory.ENGINE, 63 | description: 'throttle lower limit - percent - negative = reverse capable', 64 | convert: 'Math.round({VAL} < 0 ? {VAL} / 4096 * 100 : {VAL} / 16384 * 100)', 65 | type: Type.Int16, 66 | permission: 'r', 67 | }), 68 | ...engine1, 69 | ...engine2, 70 | ...engine3, 71 | ...engine4, 72 | ...propeller1, 73 | }; 74 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/engines/propeller1.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetList } from '@shared/offset-list'; 4 | import { Offset } from '@shared/offset'; 5 | import { OffsetCategory } from '@shared/offset-category'; 6 | 7 | export const propeller1: OffsetList = { 8 | propeller1RPM: new Offset({ 9 | value: 0x2400, 10 | name: 'propeller1RPM', 11 | category: OffsetCategory.ENGINE, 12 | description: 'propeller 1 RPM', 13 | type: Type.Double, 14 | permission: 'r', 15 | }), 16 | propeller1RPMPercent: new Offset({ 17 | value: 0x2408, 18 | name: 'propeller1RPMPercent', 19 | category: OffsetCategory.ENGINE, 20 | description: 'propeller 1 RPM percent', 21 | convert: 'Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))', 22 | type: Type.Double, 23 | permission: 'r', 24 | }), 25 | propeller1Thrust: new Offset({ 26 | value: 0x2410, 27 | name: 'propeller1Thrust', 28 | category: OffsetCategory.ENGINE, 29 | description: 'propeller 1 thrust - lb', 30 | convert: '+({VAL}).toFixed(2)', 31 | type: Type.Double, 32 | permission: 'r', 33 | }), 34 | propeller1BetaBladeAngle: new Offset({ 35 | value: 0x2418, 36 | name: 'propeller1BetaBladeAngle', 37 | category: OffsetCategory.ENGINE, 38 | description: 'propeller 1 beta blade angle - rad', 39 | convert: '+({VAL}).toFixed(4)', 40 | type: Type.Double, 41 | permission: 'r', 42 | }), 43 | propeller1FeatheringInhibit: new Offset({ 44 | value: 0x2420, 45 | name: 'propeller1FeatheringInhibit', 46 | category: OffsetCategory.ENGINE, 47 | description: 'propeller 1 feathering inhibit', 48 | convert: '!!{VAL}', 49 | type: Type.UInt32, 50 | permission: 'rw', 51 | }), 52 | propeller1Feathered: new Offset({ 53 | value: 0x2424, 54 | name: 'propeller1Feathered', 55 | category: OffsetCategory.ENGINE, 56 | description: 'propeller 1 feathered', 57 | convert: '!!{VAL}', 58 | type: Type.UInt32, 59 | permission: 'r', 60 | }), 61 | propeller1SyncDeltaLever: new Offset({ 62 | value: 0x2428, 63 | name: 'propeller1SyncDeltaLever', 64 | category: OffsetCategory.ENGINE, 65 | description: 'propeller 1 sync delta lever', 66 | type: Type.Double, 67 | permission: 'r', 68 | }), 69 | propeller1AutofeatherArmed: new Offset({ 70 | value: 0x2430, 71 | name: 'propeller1AutofeatherArmed', 72 | category: OffsetCategory.ENGINE, 73 | description: 'propeller 1 autofeather armed flag', 74 | convert: '!!{VAL}', 75 | type: Type.UInt32, 76 | permission: 'rw', 77 | }), 78 | propeller1FeatherSwitch: new Offset({ 79 | value: 0x2434, 80 | name: 'propeller1FeatherSwitch', 81 | category: OffsetCategory.ENGINE, 82 | description: 'propeller 1 feather switch', 83 | convert: '!!{VAL}', 84 | type: Type.UInt32, 85 | permission: 'rw', 86 | }), 87 | propeller1PanelAutofeatherSwitch: new Offset({ 88 | value: 0x2438, 89 | name: 'propeller1PanelAutofeatherSwitch', 90 | category: OffsetCategory.ENGINE, 91 | description: 'propeller 1 panel autofeather switch', 92 | convert: '!!{VAL}', 93 | type: Type.UInt32, 94 | permission: 'rw', 95 | }), 96 | propeller1Sync: new Offset({ 97 | value: 0x243C, 98 | name: 'propeller1Sync', 99 | category: OffsetCategory.ENGINE, 100 | description: 'propeller 1 sync active', 101 | convert: '!!{VAL}', 102 | type: Type.UInt32, 103 | permission: 'rw', 104 | }), 105 | propeller1DeiceSwitch: new Offset({ 106 | value: 0x2440, 107 | name: 'propeller1DeiceSwitch', 108 | category: OffsetCategory.ENGINE, 109 | description: 'propeller 1 de-ice active', 110 | convert: '!!{VAL}', 111 | type: Type.UInt32, 112 | permission: 'rw', 113 | }), 114 | }; 115 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/engines/propeller2.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetList } from '@shared/offset-list'; 4 | import { Offset } from '@shared/offset'; 5 | import { OffsetCategory } from '@shared/offset-category'; 6 | 7 | export const propeller2: OffsetList = { 8 | propeller2RPM: new Offset({ 9 | value: 0x2500, 10 | name: 'propeller2RPM', 11 | category: OffsetCategory.ENGINE, 12 | description: 'propeller 2 RPM', 13 | type: Type.Double, 14 | permission: 'r', 15 | }), 16 | propeller2RPMPercent: new Offset({ 17 | value: 0x2508, 18 | name: 'propeller2RPMPercent', 19 | category: OffsetCategory.ENGINE, 20 | description: 'propeller 2 RPM percent', 21 | convert: 'Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))', 22 | type: Type.Double, 23 | permission: 'r', 24 | }), 25 | propeller2Thrust: new Offset({ 26 | value: 0x2510, 27 | name: 'propeller2Thrust', 28 | category: OffsetCategory.ENGINE, 29 | description: 'propeller 2 thrust - lb', 30 | convert: '+({VAL}).toFixed(2)', 31 | type: Type.Double, 32 | permission: 'r', 33 | }), 34 | propeller2BetaBladeAngle: new Offset({ 35 | value: 0x2518, 36 | name: 'propeller2BetaBladeAngle', 37 | category: OffsetCategory.ENGINE, 38 | description: 'propeller 2 beta blade angle - rad', 39 | convert: '+({VAL}).toFixed(4)', 40 | type: Type.Double, 41 | permission: 'r', 42 | }), 43 | propeller2FeatheringInhibit: new Offset({ 44 | value: 0x2520, 45 | name: 'propeller2FeatheringInhibit', 46 | category: OffsetCategory.ENGINE, 47 | description: 'propeller 2 feathering inhibit', 48 | convert: '!!{VAL}', 49 | type: Type.UInt32, 50 | permission: 'rw', 51 | }), 52 | propeller2Feathered: new Offset({ 53 | value: 0x2524, 54 | name: 'propeller2Feathered', 55 | category: OffsetCategory.ENGINE, 56 | description: 'propeller 2 feathered', 57 | convert: '!!{VAL}', 58 | type: Type.UInt32, 59 | permission: 'r', 60 | }), 61 | propeller2SyncDeltaLever: new Offset({ 62 | value: 0x2528, 63 | name: 'propeller2SyncDeltaLever', 64 | category: OffsetCategory.ENGINE, 65 | description: 'propeller 2 sync delta lever', 66 | type: Type.Double, 67 | permission: 'r', 68 | }), 69 | propeller2AutofeatherArmed: new Offset({ 70 | value: 0x2530, 71 | name: 'propeller2AutofeatherArmed', 72 | category: OffsetCategory.ENGINE, 73 | description: 'propeller 2 autofeather armed flag', 74 | convert: '!!{VAL}', 75 | type: Type.UInt32, 76 | permission: 'rw', 77 | }), 78 | propeller2FeatherSwitch: new Offset({ 79 | value: 0x2534, 80 | name: 'propeller2FeatherSwitch', 81 | category: OffsetCategory.ENGINE, 82 | description: 'propeller 2 feather switch', 83 | convert: '!!{VAL}', 84 | type: Type.UInt32, 85 | permission: 'rw', 86 | }), 87 | propeller2PanelAutofeatherSwitch: new Offset({ 88 | value: 0x2538, 89 | name: 'propeller2PanelAutofeatherSwitch', 90 | category: OffsetCategory.ENGINE, 91 | description: 'propeller 2 panel autofeather switch', 92 | convert: '!!{VAL}', 93 | type: Type.UInt32, 94 | permission: 'rw', 95 | }), 96 | propeller2Sync: new Offset({ 97 | value: 0x253C, 98 | name: 'propeller2Sync', 99 | category: OffsetCategory.ENGINE, 100 | description: 'propeller 2 sync active', 101 | convert: '!!{VAL}', 102 | type: Type.UInt32, 103 | permission: 'rw', 104 | }), 105 | propeller2DeiceSwitch: new Offset({ 106 | value: 0x2540, 107 | name: 'propeller2DeiceSwitch', 108 | category: OffsetCategory.ENGINE, 109 | description: 'propeller 2 de-ice active', 110 | convert: '!!{VAL}', 111 | type: Type.UInt32, 112 | permission: 'rw', 113 | }), 114 | }; 115 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/engines/propeller3.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetList } from '@shared/offset-list'; 4 | import { Offset } from '@shared/offset'; 5 | import { OffsetCategory } from '@shared/offset-category'; 6 | 7 | export const propeller3: OffsetList = { 8 | propeller3RPM: new Offset({ 9 | value: 0x2600, 10 | name: 'propeller3RPM', 11 | category: OffsetCategory.ENGINE, 12 | description: 'propeller 3 RPM', 13 | type: Type.Double, 14 | permission: 'r', 15 | }), 16 | propeller3RPMPercent: new Offset({ 17 | value: 0x2608, 18 | name: 'propeller3RPMPercent', 19 | category: OffsetCategory.ENGINE, 20 | description: 'propeller 3 RPM percent', 21 | convert: 'Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))', 22 | type: Type.Double, 23 | permission: 'r', 24 | }), 25 | propeller3Thrust: new Offset({ 26 | value: 0x2610, 27 | name: 'propeller3Thrust', 28 | category: OffsetCategory.ENGINE, 29 | description: 'propeller 3 thrust - lb', 30 | convert: '+({VAL}).toFixed(2)', 31 | type: Type.Double, 32 | permission: 'r', 33 | }), 34 | propeller3BetaBladeAngle: new Offset({ 35 | value: 0x2618, 36 | name: 'propeller3BetaBladeAngle', 37 | category: OffsetCategory.ENGINE, 38 | description: 'propeller 3 beta blade angle - rad', 39 | convert: '+({VAL}).toFixed(4)', 40 | type: Type.Double, 41 | permission: 'r', 42 | }), 43 | propeller3FeatheringInhibit: new Offset({ 44 | value: 0x2620, 45 | name: 'propeller3FeatheringInhibit', 46 | category: OffsetCategory.ENGINE, 47 | description: 'propeller 3 feathering inhibit', 48 | convert: '!!{VAL}', 49 | type: Type.UInt32, 50 | permission: 'rw', 51 | }), 52 | propeller3Feathered: new Offset({ 53 | value: 0x2624, 54 | name: 'propeller3Feathered', 55 | category: OffsetCategory.ENGINE, 56 | description: 'propeller 3 feathered', 57 | convert: '!!{VAL}', 58 | type: Type.UInt32, 59 | permission: 'r', 60 | }), 61 | propeller3SyncDeltaLever: new Offset({ 62 | value: 0x2628, 63 | name: 'propeller3SyncDeltaLever', 64 | category: OffsetCategory.ENGINE, 65 | description: 'propeller 3 sync delta lever', 66 | type: Type.Double, 67 | permission: 'r', 68 | }), 69 | propeller3AutofeatherArmed: new Offset({ 70 | value: 0x2630, 71 | name: 'propeller3AutofeatherArmed', 72 | category: OffsetCategory.ENGINE, 73 | description: 'propeller 3 autofeather armed flag', 74 | convert: '!!{VAL}', 75 | type: Type.UInt32, 76 | permission: 'rw', 77 | }), 78 | propeller3FeatherSwitch: new Offset({ 79 | value: 0x2634, 80 | name: 'propeller3FeatherSwitch', 81 | category: OffsetCategory.ENGINE, 82 | description: 'propeller 3 feather switch', 83 | convert: '!!{VAL}', 84 | type: Type.UInt32, 85 | permission: 'rw', 86 | }), 87 | propeller3PanelAutofeatherSwitch: new Offset({ 88 | value: 0x2638, 89 | name: 'propeller3PanelAutofeatherSwitch', 90 | category: OffsetCategory.ENGINE, 91 | description: 'propeller 3 panel autofeather switch', 92 | convert: '!!{VAL}', 93 | type: Type.UInt32, 94 | permission: 'rw', 95 | }), 96 | propeller3Sync: new Offset({ 97 | value: 0x263C, 98 | name: 'propeller3Sync', 99 | category: OffsetCategory.ENGINE, 100 | description: 'propeller 3 sync active', 101 | convert: '!!{VAL}', 102 | type: Type.UInt32, 103 | permission: 'rw', 104 | }), 105 | propeller3DeiceSwitch: new Offset({ 106 | value: 0x2640, 107 | name: 'propeller3DeiceSwitch', 108 | category: OffsetCategory.ENGINE, 109 | description: 'propeller 3 de-ice active', 110 | convert: '!!{VAL}', 111 | type: Type.UInt32, 112 | permission: 'rw', 113 | }), 114 | }; 115 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/engines/propeller4.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetList } from '@shared/offset-list'; 4 | import { Offset } from '@shared/offset'; 5 | import { OffsetCategory } from '@shared/offset-category'; 6 | 7 | export const propeller4: OffsetList = { 8 | propeller4RPM: new Offset({ 9 | value: 0x2700, 10 | name: 'propeller4RPM', 11 | category: OffsetCategory.ENGINE, 12 | description: 'propeller 4 RPM', 13 | type: Type.Double, 14 | permission: 'r', 15 | }), 16 | propeller4RPMPercent: new Offset({ 17 | value: 0x2708, 18 | name: 'propeller4RPMPercent', 19 | category: OffsetCategory.ENGINE, 20 | description: 'propeller 4 RPM percent', 21 | convert: 'Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))', 22 | type: Type.Double, 23 | permission: 'r', 24 | }), 25 | propeller4Thrust: new Offset({ 26 | value: 0x2710, 27 | name: 'propeller4Thrust', 28 | category: OffsetCategory.ENGINE, 29 | description: 'propeller 4 thrust - lb', 30 | convert: '+({VAL}).toFixed(2)', 31 | type: Type.Double, 32 | permission: 'r', 33 | }), 34 | propeller4BetaBladeAngle: new Offset({ 35 | value: 0x2718, 36 | name: 'propeller4BetaBladeAngle', 37 | category: OffsetCategory.ENGINE, 38 | description: 'propeller 4 beta blade angle - rad', 39 | convert: '+({VAL}).toFixed(4)', 40 | type: Type.Double, 41 | permission: 'r', 42 | }), 43 | propeller4FeatheringInhibit: new Offset({ 44 | value: 0x2720, 45 | name: 'propeller4FeatheringInhibit', 46 | category: OffsetCategory.ENGINE, 47 | description: 'propeller 4 feathering inhibit', 48 | convert: '!!{VAL}', 49 | type: Type.UInt32, 50 | permission: 'rw', 51 | }), 52 | propeller4Feathered: new Offset({ 53 | value: 0x2724, 54 | name: 'propeller4Feathered', 55 | category: OffsetCategory.ENGINE, 56 | description: 'propeller 4 feathered', 57 | convert: '!!{VAL}', 58 | type: Type.UInt32, 59 | permission: 'r', 60 | }), 61 | propeller4SyncDeltaLever: new Offset({ 62 | value: 0x2728, 63 | name: 'propeller4SyncDeltaLever', 64 | category: OffsetCategory.ENGINE, 65 | description: 'propeller 4 sync delta lever', 66 | type: Type.Double, 67 | permission: 'r', 68 | }), 69 | propeller4AutofeatherArmed: new Offset({ 70 | value: 0x2730, 71 | name: 'propeller4AutofeatherArmed', 72 | category: OffsetCategory.ENGINE, 73 | description: 'propeller 4 autofeather armed flag', 74 | convert: '!!{VAL}', 75 | type: Type.UInt32, 76 | permission: 'rw', 77 | }), 78 | propeller4FeatherSwitch: new Offset({ 79 | value: 0x2734, 80 | name: 'propeller4FeatherSwitch', 81 | category: OffsetCategory.ENGINE, 82 | description: 'propeller 4 feather switch', 83 | convert: '!!{VAL}', 84 | type: Type.UInt32, 85 | permission: 'rw', 86 | }), 87 | propeller4PanelAutofeatherSwitch: new Offset({ 88 | value: 0x2738, 89 | name: 'propeller4PanelAutofeatherSwitch', 90 | category: OffsetCategory.ENGINE, 91 | description: 'propeller 4 panel autofeather switch', 92 | convert: '!!{VAL}', 93 | type: Type.UInt32, 94 | permission: 'rw', 95 | }), 96 | propeller4Sync: new Offset({ 97 | value: 0x273C, 98 | name: 'propeller4Sync', 99 | category: OffsetCategory.ENGINE, 100 | description: 'propeller 4 sync active', 101 | convert: '!!{VAL}', 102 | type: Type.UInt32, 103 | permission: 'rw', 104 | }), 105 | propeller4DeiceSwitch: new Offset({ 106 | value: 0x2740, 107 | name: 'propeller4DeiceSwitch', 108 | category: OffsetCategory.ENGINE, 109 | description: 'propeller 4 de-ice active', 110 | convert: '!!{VAL}', 111 | type: Type.UInt32, 112 | permission: 'rw', 113 | }), 114 | }; 115 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/helicopter.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const helicopter: OffsetList = { 8 | rotorbreakActive: new Offset({ 9 | value: 0x81E, 10 | name: 'rotorbreakActive', 11 | category: OffsetCategory.HELICOPTER, 12 | description: 'rotor brake active - Robinson only', 13 | convert: '!!{VAL}', 14 | type: Type.Byte, 15 | permission: 'rw', 16 | }), 17 | rotorClutchActive: new Offset({ 18 | value: 0x81F, 19 | name: 'rotorClutchActive', 20 | category: OffsetCategory.HELICOPTER, 21 | description: 'rotor clutch active - Robinson only', 22 | convert: '!!{VAL}', 23 | type: Type.Byte, 24 | permission: 'rw', 25 | }), 26 | rotorChipWarning: new Offset({ 27 | value: 0x820, 28 | name: 'rotorChipWarning', 29 | category: OffsetCategory.HELICOPTER, 30 | description: 'rotor chip detected - Rbinson only', 31 | convert: '!!{VAL}', 32 | type: Type.Byte, 33 | permission: 'rw', 34 | }), 35 | rotorGovWarning: new Offset({ 36 | value: 0x821, 37 | name: 'rotorGovWarning', 38 | category: OffsetCategory.HELICOPTER, 39 | description: 'rotor gov active - Rbinson only', 40 | convert: '!!{VAL}', 41 | type: Type.Byte, 42 | permission: 'rw', 43 | }), 44 | rotorBreakApplication: new Offset({ 45 | value: 0x822, 46 | name: 'rotorBreakApplication', 47 | category: OffsetCategory.HELICOPTER, 48 | description: 'rotor brake application - percent - Robinson only', 49 | convert: 'Math.round({VAL} / 16384 * 100)', 50 | type: Type.UInt16, 51 | permission: 'rw', 52 | }), 53 | rotorLateralTrim: new Offset({ 54 | value: 0x824, 55 | name: 'rotorLateralTrim', 56 | category: OffsetCategory.HELICOPTER, 57 | description: 'rotor lateral trim - percent - Robinson only', 58 | convert: 'Math.round({VAL} / 16384 * 100)', 59 | type: Type.UInt16, 60 | permission: 'rw', 61 | }), 62 | governorSwitch: new Offset({ 63 | value: 0x826, 64 | name: 'governorSwitch', 65 | category: OffsetCategory.HELICOPTER, 66 | description: 'governor switch activated - Robinson only', 67 | convert: '!!{VAL}', 68 | type: Type.Byte, 69 | permission: 'rw', 70 | }), 71 | rotorTransmissionTemp: new Offset({ 72 | value: 0x828, 73 | name: 'rotorTransmissionTemp', 74 | category: OffsetCategory.HELICOPTER, 75 | description: 'rotor transmission temp - degrees Rankine - read only', 76 | type: Type.Double, 77 | permission: 'r', 78 | }), 79 | helicopterEngine1RPM: new Offset({ 80 | value: 0x896, 81 | name: 'helicopterEngine1RPM', 82 | category: OffsetCategory.HELICOPTER, 83 | description: 'engine 1 RPM %', 84 | type: Type.UInt16, 85 | permission: 'rw', 86 | }), 87 | helicopterEngine1RPMUnscaled: new Offset({ 88 | value: 0x898, 89 | name: 'helicopterEngine1RPMUnscaled', 90 | category: OffsetCategory.HELICOPTER, 91 | description: 'engine 1 RPM unscalled - multiply by engineRPMScaler to obtain derivated RPM', 92 | type: Type.UInt16, 93 | permission: 'rw', 94 | }), 95 | helicopterEngine1ElectricalLoad: new Offset({ 96 | value: 0x8FC, 97 | name: 'helicopterEngine1ElectricalLoad', 98 | category: OffsetCategory.HELICOPTER, 99 | description: 'engine1 electrical load - trust only for helo - percent', 100 | convert: '{VAL} / 16384 * 100', 101 | type: Type.UInt32, 102 | permission: 'r', 103 | }), 104 | helicopterEngine1TransmOilPres: new Offset({ 105 | value: 0x900, 106 | name: 'helicopterEngine1TransmOilPres', 107 | category: OffsetCategory.HELICOPTER, 108 | description: 'engine1 transmission oil pressure - trust only for helo - PSI', 109 | convert: '{VAL} / 16384', 110 | type: Type.UInt32, 111 | permission: 'r', 112 | }), 113 | helicopterEngine1TransmOilTemp: new Offset({ 114 | value: 0x904, 115 | name: 'helicopterEngine1TransmOilTemp', 116 | category: OffsetCategory.HELICOPTER, 117 | description: 'engine1 transmission oil temperature - trust only for helo - C', 118 | convert: '{VAL} / 16384', 119 | type: Type.UInt32, 120 | permission: 'r', 121 | }), 122 | helicopterEngine1RotorRPM: new Offset({ 123 | value: 0x908, 124 | name: 'helicopterEngine1RotorRPM', 125 | category: OffsetCategory.HELICOPTER, 126 | description: 'engine1 rotor RPM - percent', 127 | convert: '{VAL} / 16384 * 100', 128 | type: Type.UInt32, 129 | permission: 'r', 130 | }), 131 | helicopterPitchTrim: new Offset({ 132 | value: 0xBBE, 133 | name: 'helicopterPitchTrim', 134 | description: 'helicopter pitch trim', 135 | category: OffsetCategory.HELICOPTER, 136 | convert: 'Math.round({VAL} / 16383 * 100)', 137 | type: Type.Int16, 138 | permission: 'rw', 139 | }), 140 | helicopterBankTrim: new Offset({ 141 | value: 0xC06, 142 | name: 'helicopterBankTrim', 143 | description: 'helicopter bank trim - only when apply hello trim to both', 144 | category: OffsetCategory.HELICOPTER, 145 | convert: 'Math.round({VAL} / 16383 * 100)', 146 | type: Type.Int16, 147 | permission: 'rw', 148 | }), 149 | }; 150 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/icing.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const icing: OffsetList = { 8 | structuralIce: new Offset({ 9 | value: 0x348, 10 | name: 'structuralIce', 11 | category: OffsetCategory.ICING, 12 | description: 'structural ice - decimal percent', 13 | type: Type.UInt16, 14 | convert: '+({VAL} / 16384 * 100).toFixed(2)', 15 | permission: 'r', 16 | }), 17 | pitotIce: new Offset({ 18 | value: 0x34A, 19 | name: 'pitotIce', 20 | category: OffsetCategory.ICING, 21 | description: 'structural ice - decimal percent', 22 | type: Type.UInt16, 23 | convert: '+({VAL} / 16384 * 100).toFixed(2)', 24 | permission: 'r', 25 | }), 26 | }; 27 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/pressurisation.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const pressurisation: OffsetList = { 8 | pressCabinAlt: new Offset({ 9 | value: 0x318, 10 | name: 'pressCabinAlt', 11 | category: OffsetCategory.PRESSURISATION, 12 | description: 'pressurisation: cabin altitude - ft', 13 | type: Type.Int32, 14 | permission: 'r', 15 | }), 16 | pressCabinAltTarget: new Offset({ 17 | value: 0x31C, 18 | name: 'pressCabinAltTarget', 19 | category: OffsetCategory.PRESSURISATION, 20 | description: 'pressurisation: target cabin altitude - ft', 21 | type: Type.Int32, 22 | permission: 'r', 23 | }), 24 | pressCabinAltChange: new Offset({ 25 | value: 0x320, 26 | name: 'pressCabinAltChange', 27 | category: OffsetCategory.PRESSURISATION, 28 | description: 'pressurisation: cabin altitude change set - ft/s', 29 | type: Type.Single, 30 | permission: 'r', 31 | }), 32 | pressCabinAltPressDiff: new Offset({ 33 | value: 0x324, 34 | name: 'pressCabinAltPressDiff', 35 | category: OffsetCategory.PRESSURISATION, 36 | description: 'pressurisation: cabin altitude change set - lb/sqft', 37 | type: Type.Single, 38 | permission: 'r', 39 | }), 40 | pressDumpSwitch: new Offset({ 41 | value: 0x328, 42 | name: 'pressDumpSwitch', 43 | category: OffsetCategory.PRESSURISATION, 44 | description: 'pressurisation: dump switch', 45 | convert: '!!{VAL}', 46 | type: Type.UInt32, 47 | permission: 'rw', 48 | }), 49 | }; 50 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/radios.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const radios: OffsetList = { 8 | comFreq: new Offset({ 9 | value: 0x34E, 10 | name: 'comFreq', 11 | category: OffsetCategory.RADIOS, 12 | description: 'Com frequency', 13 | type: Type.UInt16, 14 | convert: 'parseInt(`1` + ({VAL}).toString(16))', 15 | permission: 'rw', 16 | }), 17 | transponderFreq: new Offset({ 18 | value: 0x354, 19 | name: 'transponderFreq', 20 | category: OffsetCategory.RADIOS, 21 | description: 'XPND transponder frequency', 22 | type: Type.UInt16, 23 | convert: 'parseInt(`1` + ({VAL}).toString(16))', 24 | permission: 'rw', 25 | }), 26 | nav12Select: new Offset({ 27 | value: 0x374, 28 | name: 'nav12Select', 29 | category: OffsetCategory.RADIOS, 30 | description: 'NAV1/NAV2 select', 31 | type: Type.UInt16, 32 | permission: 'rw', 33 | }), 34 | dme12Select: new Offset({ 35 | value: 0x378, 36 | name: 'dme12Select', 37 | category: OffsetCategory.RADIOS, 38 | description: 'DME1/DME2 select', 39 | type: Type.UInt16, 40 | permission: 'rw', 41 | }), 42 | navAdfActivate: new Offset({ 43 | value: 0x388, 44 | name: 'navAdfActivate', 45 | category: OffsetCategory.RADIOS, 46 | description: 'NAV and ADF activate < FS2000', 47 | type: Type.UInt16, 48 | permission: 'w', 49 | }), 50 | comAtisActivate: new Offset({ 51 | value: 0x38A, 52 | name: 'comAtisActivate', 53 | category: OffsetCategory.RADIOS, 54 | description: 'COM/ATIS activate < FS2000', 55 | type: Type.UInt16, 56 | permission: 'w', 57 | }), 58 | innerMarker: new Offset({ 59 | value: 0xBAC, 60 | name: 'innerMarker', 61 | category: OffsetCategory.RADIOS, 62 | description: 'inner marker - activated when TRUE', 63 | type: Type.Int16, 64 | permission: 'r', 65 | }), 66 | middleMarker: new Offset({ 67 | value: 0xBAE, 68 | name: 'middleMarker', 69 | category: OffsetCategory.RADIOS, 70 | description: 'middle marker - activated when TRUE', 71 | type: Type.Int16, 72 | permission: 'r', 73 | }), 74 | outerMarker: new Offset({ 75 | value: 0xBB0, 76 | name: 'outerMarker', 77 | category: OffsetCategory.RADIOS, 78 | description: 'outer marker - activated when TRUE', 79 | type: Type.Int16, 80 | permission: 'r', 81 | }), 82 | }; 83 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/radios/adf1.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const ADF1: OffsetList = { 8 | adfFreq: new Offset({ 9 | value: 0x34C, 10 | name: 'adfFreq', 11 | category: OffsetCategory.RADIOS, 12 | description: 'ADF frequency show as Binary Coded Decimal. The thousands digit and the fractional parts are provided in adfFreqExtended', 13 | type: Type.UInt16, 14 | convert: '+({VAL}).toString(16)', 15 | permission: 'rw', 16 | }), 17 | adfFreqExtended: new Offset({ 18 | value: 0x356, 19 | name: 'adfFreqExtended', 20 | category: OffsetCategory.RADIOS, 21 | description: 'ADF frequency extended', 22 | type: Type.UInt16, 23 | permission: 'rw', 24 | }), 25 | adf1SignalStrength: new Offset({ 26 | value: 0xC1C, 27 | name: 'adf1SignalStrength', 28 | category: OffsetCategory.RADIOS, 29 | description: 'ADF1 signal strength', 30 | type: Type.UInt32, 31 | permission: 'r', 32 | }), 33 | adf1BearingToNDB: new Offset({ 34 | value: 0xC6A, 35 | name: 'adf1BearingToNDB', 36 | category: OffsetCategory.RADIOS, 37 | description: 'ADF1 relative bearing to NDB - degrees - -ve left, +ve right', 38 | convert: 'Math.round({VAL} * 360 / 65536)', 39 | type: Type.Int16, 40 | permission: 'r', 41 | }), 42 | adf1DialBearing: new Offset({ 43 | value: 0xC6C, 44 | name: 'adf1DialBearing', 45 | category: OffsetCategory.RADIOS, 46 | description: 'ADF1 dial bearing - degrees', 47 | type: Type.UInt16, 48 | permission: 'rw', 49 | }), 50 | adf1Latitude: new Offset({ 51 | value: 0x1124, 52 | name: 'adf1Latitude', 53 | category: OffsetCategory.RADIOS, 54 | description: 'adf1 latitude', 55 | type: Type.Int32, 56 | convert: '{VAL} * 90 / 10001750', 57 | permission: 'r', 58 | }), 59 | adf1Longitude: new Offset({ 60 | value: 0x1128, 61 | name: 'adf1Longitude', 62 | category: OffsetCategory.RADIOS, 63 | description: 'adf1 longitude', 64 | type: Type.Int32, 65 | convert: '{VAL} * 360 / (65536 * 65536)', 66 | permission: 'r', 67 | }), 68 | adf1Altitude: new Offset({ 69 | value: 0x112C, 70 | name: 'adf1Altitude', 71 | category: OffsetCategory.RADIOS, 72 | description: 'adf1 altitude - ft', 73 | type: Type.Int32, 74 | convert: '+({VAL} * 3.28084).toFixed(2)', 75 | permission: 'r', 76 | }), 77 | }; 78 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/radios/adf2.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const ADF2: OffsetList = { 8 | adf2Freq: new Offset({ 9 | value: 0x2D4, 10 | name: 'adf2Freq', 11 | category: OffsetCategory.RADIOS, 12 | description: 'ADF 2 freq - Main 3 digits in BCD - FS2004', 13 | type: Type.UInt16, 14 | convert: '+({VAL}).toString(16)', 15 | permission: 'rw', 16 | }), 17 | adf2ExtendedFreq: new Offset({ 18 | value: 0x2D6, 19 | name: 'adf2ExtendedFreq', 20 | category: OffsetCategory.RADIOS, 21 | description: 'ADF 2 extended freq - in BCD - FS2004', 22 | type: Type.UInt16, 23 | permission: 'rw', 24 | }), 25 | adf2RelBearing: new Offset({ 26 | value: 0x2D8, 27 | name: 'adf2RelBearing', 28 | category: OffsetCategory.RADIOS, 29 | description: 'ADF2 Rel Bearing - FS2004', 30 | convert: 'Math.round({VAL} * 360 / 65536)', 31 | type: Type.Int16, 32 | permission: 'r', 33 | }), 34 | ndb2Identity: new Offset({ 35 | value: 0x2DC, 36 | name: 'ndb2Identity', 37 | category: OffsetCategory.RADIOS, 38 | description: 'NDB2 identity - FS2004', 39 | type: Type.String, 40 | length: 6, 41 | permission: 'r', 42 | }), 43 | ndb2Name: new Offset({ 44 | value: 0x2E2, 45 | name: 'ndb2Name', 46 | category: OffsetCategory.RADIOS, 47 | description: 'NDB2 name - FS2004', 48 | type: Type.String, 49 | length: 25, 50 | permission: 'r', 51 | }), 52 | ndb2IdentSoundSwitch: new Offset({ 53 | value: 0x2FB, 54 | name: 'ndb2IdentSoundSwitch', 55 | category: OffsetCategory.RADIOS, 56 | description: 'NDB2 ident sound switch - FS2004', 57 | type: Type.Byte, 58 | convert: '!!{VAL}', 59 | permission: 'rw', 60 | }), 61 | adf2SignalStrength: new Offset({ 62 | value: 0xC14, 63 | name: 'adf2SignalStrength', 64 | category: OffsetCategory.RADIOS, 65 | description: 'ADF2 signal strength', 66 | type: Type.UInt32, 67 | permission: 'r', 68 | }), 69 | adf2Latitude: new Offset({ 70 | value: 0x1130, 71 | name: 'adf2Latitude', 72 | category: OffsetCategory.RADIOS, 73 | description: 'adf2 latitude', 74 | type: Type.Int32, 75 | convert: '{VAL} * 90 / 10001750', 76 | permission: 'r', 77 | }), 78 | adf2Longitude: new Offset({ 79 | value: 0x1134, 80 | name: 'adf2Longitude', 81 | category: OffsetCategory.RADIOS, 82 | description: 'adf2 longitude', 83 | type: Type.Int32, 84 | convert: '{VAL} * 360 / (65536 * 65536)', 85 | permission: 'r', 86 | }), 87 | adf2Altitude: new Offset({ 88 | value: 0x1138, 89 | name: 'adf2Altitude', 90 | category: OffsetCategory.RADIOS, 91 | description: 'adf2 altitude - ft', 92 | type: Type.Int32, 93 | convert: '+({VAL} * 3.28084).toFixed(2)', 94 | permission: 'r', 95 | }), 96 | }; 97 | -------------------------------------------------------------------------------- /src/lib/offsets/plane/radios/ils.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from '@shared/offset-category'; 4 | import { OffsetList } from '@shared/offset-list'; 5 | import { Offset } from '@shared/offset'; 6 | 7 | export const ILS: OffsetList = { 8 | innerMarkerLatitude: new Offset({ 9 | value: 0x1100, 10 | name: 'innerMarkerLatitude', 11 | category: OffsetCategory.RADIOS, 12 | description: 'inner marker latitude', 13 | type: Type.Int32, 14 | convert: '{VAL} * 90 / 10001750', 15 | permission: 'r', 16 | }), 17 | innerMarkerLongitude: new Offset({ 18 | value: 0x1104, 19 | name: 'innerMarkerLongitude', 20 | category: OffsetCategory.RADIOS, 21 | description: 'inner marker longitude', 22 | type: Type.Int32, 23 | convert: '{VAL} * 360 / (65536 * 65536)', 24 | permission: 'r', 25 | }), 26 | innerMarkerAltitude: new Offset({ 27 | value: 0x1108, 28 | name: 'innerMarkerAltitude', 29 | category: OffsetCategory.RADIOS, 30 | description: 'inner marker altitude - ft', 31 | type: Type.Int32, 32 | convert: '+({VAL} * 3.28084).toFixed(2)', 33 | permission: 'r', 34 | }), 35 | middleMarkerLatitude: new Offset({ 36 | value: 0x110C, 37 | name: 'middleMarkerLatitude', 38 | category: OffsetCategory.RADIOS, 39 | description: 'middle marker latitude', 40 | type: Type.Int32, 41 | convert: '{VAL} * 90 / 10001750', 42 | permission: 'r', 43 | }), 44 | middleMarkerLongitude: new Offset({ 45 | value: 0x1110, 46 | name: 'middleMarkerLongitude', 47 | category: OffsetCategory.RADIOS, 48 | description: 'middle marker longitude', 49 | type: Type.Int32, 50 | convert: '{VAL} * 360 / (65536 * 65536)', 51 | permission: 'r', 52 | }), 53 | middleMarkerAltitude: new Offset({ 54 | value: 0x1114, 55 | name: 'middleMarkerAltitude', 56 | category: OffsetCategory.RADIOS, 57 | description: 'middle marker altitude - ft', 58 | type: Type.Int32, 59 | convert: '+({VAL} * 3.28084).toFixed(2)', 60 | permission: 'r', 61 | }), 62 | outerMarkerLatitude: new Offset({ 63 | value: 0x1118, 64 | name: 'outerMarkerLatitude', 65 | category: OffsetCategory.RADIOS, 66 | description: 'outer marker latitude', 67 | type: Type.Int32, 68 | convert: '{VAL} * 90 / 10001750', 69 | permission: 'r', 70 | }), 71 | outerMarkerLongitude: new Offset({ 72 | value: 0x111C, 73 | name: 'outerMarkerLongitude', 74 | category: OffsetCategory.RADIOS, 75 | description: 'outer marker longitude', 76 | type: Type.Int32, 77 | convert: '{VAL} * 360 / (65536 * 65536)', 78 | permission: 'r', 79 | }), 80 | outerMarkerAltitude: new Offset({ 81 | value: 0x1120, 82 | name: 'outerMarkerAltitude', 83 | category: OffsetCategory.RADIOS, 84 | description: 'outer marker altitude - ft', 85 | type: Type.Int32, 86 | convert: '+({VAL} * 3.28084).toFixed(2)', 87 | permission: 'r', 88 | }), 89 | }; 90 | -------------------------------------------------------------------------------- /src/shared/converted-offset-values.ts: -------------------------------------------------------------------------------- 1 | export type ConvertedOffsetValue = string | number | boolean | string[] | number[] | boolean[]; 2 | 3 | export interface ConvertedOffsetValues { 4 | [key: string]: ConvertedOffsetValue; 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/environment/time-of-day.ts: -------------------------------------------------------------------------------- 1 | export enum TimeOfDay { 2 | DAY = 'day', 3 | DUSK_DAWN = 'duskDawn', 4 | NIGHT = 'night', 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/offset-category.ts: -------------------------------------------------------------------------------- 1 | export enum OffsetCategory { 2 | APU = 'APU', 3 | AUTOPILOT = 'autopilot', 4 | COCKPIT = 'cockpit', 5 | CONTROLS = 'controls', 6 | ELECTRIC = 'electric', 7 | ENGINE = 'engine', 8 | ENVIRONMENT = 'environment', 9 | FAILURE = 'failure', 10 | FUEL = 'fuel', 11 | HELICOPTER = 'helicopter', 12 | ICING = 'icing', 13 | PLANE = 'plane', 14 | POSITION_ATTITUDE = 'position_attitude', 15 | PRESSURISATION = 'pressurisation', 16 | PUSHBACK = 'pushback', 17 | RADIOS = 'radios', 18 | RUNWAY = 'runway', 19 | SIMULATION = 'simulation', 20 | WEATHER = 'weather', 21 | } 22 | -------------------------------------------------------------------------------- /src/shared/offset-list.ts: -------------------------------------------------------------------------------- 1 | import { Offset } from './offset'; 2 | 3 | export interface OffsetList { 4 | [key: string]: Offset; 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/offset-values.ts: -------------------------------------------------------------------------------- 1 | export type RawOffsetValue = string | number | boolean | string[] | number[] | boolean[]; 2 | 3 | export interface OffsetValues { 4 | [key: string]: RawOffsetValue; 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/offset.ts: -------------------------------------------------------------------------------- 1 | import { Type } from 'fsuipc'; 2 | 3 | import { OffsetCategory } from './offset-category'; 4 | import { MAPPINGS } from '@mappings/index'; 5 | 6 | export interface OffsetData { 7 | value: number; 8 | name: string; 9 | category: OffsetCategory; 10 | type: Type; 11 | 12 | mapping?: boolean; 13 | length?: number; 14 | description?: string; 15 | convert?: string; 16 | permission?: 'r' | 'w' | 'rw'; 17 | } 18 | 19 | export class Offset { 20 | public value: number = undefined; 21 | public name: string = undefined; 22 | public category: OffsetCategory = undefined; 23 | public type: Type = undefined; 24 | public mapping: boolean = undefined; 25 | public length: number = undefined; 26 | public description: string = undefined; 27 | public convert: string = undefined; 28 | public permission: string = undefined; 29 | 30 | constructor(offsetData: Partial) { 31 | Object.keys(offsetData).forEach((key: string) => { 32 | if (key in this) { 33 | this[key] = offsetData[key]; 34 | } 35 | }); 36 | } 37 | 38 | public get hasMapping(): boolean { 39 | return !!(this.mapping && this.convert); 40 | } 41 | 42 | public get isMappingInvalid(): boolean { 43 | return !MAPPINGS[this.convert]; 44 | } 45 | 46 | public get isInvalidConvertExpression(): boolean { 47 | return typeof this.convert !== 'string'; 48 | } 49 | 50 | public get mappingFunction(): (_: any) => any { 51 | return MAPPINGS[this.convert]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/shared/plane/brakes.ts: -------------------------------------------------------------------------------- 1 | export enum Brakes { 2 | LEFT = 'left', 3 | RIGHT = 'right', 4 | BOTH = 'both', 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/plane/engine-type.ts: -------------------------------------------------------------------------------- 1 | export enum EngineType { 2 | PISTON = 'piston', 3 | JET = 'jet', 4 | SAILPLANE = 'sailplane', 5 | HELO = 'helo', 6 | ROCKET = 'rocket', 7 | TURBOPROP = 'turboprop', 8 | } 9 | -------------------------------------------------------------------------------- /src/shared/plane/fuel-tank.ts: -------------------------------------------------------------------------------- 1 | export enum FuelTank { 2 | NONE = 'none', 3 | ALL = 'all', 4 | LEFT = 'left', 5 | RIGHT = 'right', 6 | LEFT_AUX = 'leftAux', 7 | RIGHT_AUX = 'rightAux', 8 | CENTER = 'center', 9 | CENTER2 = 'center2', 10 | CENTER3 = 'center3', 11 | EXT1 = 'ext1', 12 | EXT2 = 'ext2', 13 | RIGHT_TIP = 'rightTip', 14 | LEFT_TIP = 'leftTip', 15 | CROSS_FEED = 'crossFeed', 16 | CROSS_FEED_LTR = 'crossFeedLTR', 17 | CROSS_FEED_RTL = 'crossFeedRTL', 18 | CROSS_FEED_BOTH = 'crossFeedBoth', 19 | EXTERNAL = 'external', 20 | ISOLATE = 'isolate', 21 | LEFT_MAIN = 'leftMain', 22 | RIGHT_MAIN = 'rightMain', 23 | } 24 | -------------------------------------------------------------------------------- /src/shared/radios/vor-to-from.ts: -------------------------------------------------------------------------------- 1 | export enum VorToFrom { 2 | OFF = 'off', 3 | TO = 'to', 4 | FROM = 'from', 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/runway/runway-surface-condition.ts: -------------------------------------------------------------------------------- 1 | export enum SurfaceCondition { 2 | NORMAL = 'normal', 3 | WET = 'wet', 4 | ICY = 'icy', 5 | SNOW = 'snow', 6 | } 7 | -------------------------------------------------------------------------------- /src/shared/weather/cloud-type.ts: -------------------------------------------------------------------------------- 1 | export enum CloudType { 2 | USER = 'user', 3 | CIRRUS = 'cirrus', 4 | STRATUS = 'stratus', 5 | CUMULUS = 'cumulus', 6 | } 7 | -------------------------------------------------------------------------------- /src/shared/weather/precipitation-type.ts: -------------------------------------------------------------------------------- 1 | export enum PrecipitationType { 2 | NONE = 'none', 3 | RAIN = 'rain', 4 | SNOW = 'snow', 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/weather/season.ts: -------------------------------------------------------------------------------- 1 | export enum Season { 2 | WINTER = 'winter', 3 | SPRING = 'spring', 4 | SUMMER = 'summer', 5 | AUTUMN = 'autumn', 6 | } 7 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "include": [ 4 | "./api.ts", 5 | "**/*.d.ts" 6 | ], 7 | "compilerOptions": { 8 | "declaration": true, 9 | "outDir": "../dist", 10 | "module": "commonjs", 11 | "baseUrl": "./", 12 | "paths": { 13 | "@shared": ["shared/index"], 14 | "@shared/*": ["shared/*"], 15 | "@offsets": ["lib/offsets/index"], 16 | "@offsets/*": ["lib/offsets/*"], 17 | "@mappings": ["lib/convert/mappings/index"], 18 | "@mappings/*": ["lib/convert/mappings/*"], 19 | "@convert": ["lib/convert/index"], 20 | "@convert/*": ["lib/convert/*"] 21 | } 22 | }, 23 | "exclude": [ 24 | "**/*.spec.ts", 25 | "**/*.test.ts", 26 | "**/*.stub.ts", 27 | "**/*.mock.ts", 28 | "node_modules" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /src/tsconfig.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "include": [ 4 | "./api.ts", 5 | "**/*.d.ts" 6 | ], 7 | "compilerOptions": { 8 | "declaration": true, 9 | "outDir": "../dist", 10 | "module": "commonjs", 11 | "sourceMap": false, 12 | "baseUrl": "./", 13 | "paths": { 14 | "@shared": ["shared/index"], 15 | "@shared/*": ["shared/*"], 16 | "@offsets": ["lib/offsets/index"], 17 | "@offsets/*": ["lib/offsets/*"], 18 | "@mappings": ["lib/convert/mappings/index"], 19 | "@mappings/*": ["lib/convert/mappings/*"], 20 | "@convert": ["lib/convert/index"], 21 | "@convert/*": ["lib/convert/*"] 22 | } 23 | }, 24 | "exclude": [ 25 | "**/*.spec.ts", 26 | "**/*.test.ts", 27 | "**/*.stub.ts", 28 | "**/*.mock.ts", 29 | "node_modules" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /tests/convert/helpers/hexadecimal.spec.ts: -------------------------------------------------------------------------------- 1 | import { HexadecimalHelper } from '@convert/helpers/hexadecimal'; 2 | 3 | describe('hexadecimal helper', () => { 4 | describe('binToHex', () => { 5 | it('should number to hexadecimal', () => { 6 | expect(HexadecimalHelper.binToHex(67)).toEqual('43'); 7 | }); 8 | }); 9 | 10 | describe('hex2String', () => { 11 | it('should hexadecimal character code to string', () => { 12 | expect(HexadecimalHelper.hex2string(43)).toEqual('C'); 13 | expect(HexadecimalHelper.hex2string('43')).toEqual('C'); 14 | }); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/convert/mappings/__snapshots__/mappings.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`mappings list should import all mappings 1`] = ` 4 | Object { 5 | "appliedBrakes": [Function], 6 | "cloudType": [Function], 7 | "engineType": [Function], 8 | "ftsecToKt": [Function], 9 | "fuelTank": [Function], 10 | "ktToFtsec": [Function], 11 | "lightsMapping": [Function], 12 | "navBackCourseFlags": [Function], 13 | "navCapabilities": [Function], 14 | "nearestAirportsIds": [Function], 15 | "precipitationType": [Function], 16 | "runwaySurfaceCondition": [Function], 17 | "seasons": [Function], 18 | "spoilersControl": [Function], 19 | "vorToFrom": [Function], 20 | } 21 | `; 22 | -------------------------------------------------------------------------------- /tests/convert/mappings/applied-brakes.spec.ts: -------------------------------------------------------------------------------- 1 | import { appliedBrakes } from '@mappings/applied-brakes'; 2 | import { Brakes } from '@shared/plane/brakes'; 3 | 4 | const TESTS = [ 5 | { value: null, result: null }, 6 | { value: 0, result: null }, 7 | { value: 1, result: Brakes.LEFT }, 8 | { value: 2, result: Brakes.RIGHT }, 9 | { value: 3, result: Brakes.BOTH }, 10 | ]; 11 | 12 | describe('applied-brakes mapping', () => { 13 | TESTS.forEach(test => { 14 | it(`should map value ${test.value} to applied-brakes ${test.result}`, () => { 15 | expect(appliedBrakes(test.value)).toEqual(test.result); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/convert/mappings/cloud-type.spec.ts: -------------------------------------------------------------------------------- 1 | import { cloudType } from '@mappings/cloud-type'; 2 | import { CloudType } from '@shared/weather/cloud-type'; 3 | 4 | const TESTS = [ 5 | { value: 0, result: CloudType.USER }, 6 | { value: 1, result: CloudType.CIRRUS }, 7 | { value: 8, result: CloudType.STRATUS }, 8 | { value: 9, result: CloudType.CUMULUS }, 9 | ]; 10 | 11 | describe('cloud type mapping', () => { 12 | TESTS.forEach(test => { 13 | it(`should map value ${test.value} to cloud type ${test.result}`, () => { 14 | expect(cloudType(test.value)).toEqual(test.result); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /tests/convert/mappings/engine-type.spec.ts: -------------------------------------------------------------------------------- 1 | import { engineType } from '@mappings/engine-type'; 2 | import { EngineType } from '@shared/plane/engine-type'; 3 | 4 | const TESTS = [ 5 | { value: 0, result: EngineType.PISTON }, 6 | { value: 1, result: EngineType.JET }, 7 | { value: 2, result: EngineType.SAILPLANE }, 8 | { value: 3, result: EngineType.HELO }, 9 | { value: 4, result: EngineType.ROCKET }, 10 | { value: 5, result: EngineType.TURBOPROP }, 11 | { value: 6, result: null }, 12 | { value: null, result: null }, 13 | ]; 14 | 15 | describe('engine-type mapping', () => { 16 | TESTS.forEach(test => { 17 | it(`should map value ${test.value} to engine-type ${test.result}`, () => { 18 | expect(engineType(test.value)).toEqual(test.result); 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /tests/convert/mappings/fuel-tank.spec.ts: -------------------------------------------------------------------------------- 1 | import { FuelTank } from '@shared/plane/fuel-tank'; 2 | import { fuelTank } from '@mappings/fuel-tank'; 3 | 4 | const TESTS = [ 5 | { value: 0, result: FuelTank.NONE }, 6 | { value: 1, result: FuelTank.ALL }, 7 | { value: 2, result: FuelTank.LEFT }, 8 | { value: 3, result: FuelTank.RIGHT }, 9 | { value: 4, result: FuelTank.LEFT_AUX }, 10 | { value: 5, result: FuelTank.RIGHT_AUX }, 11 | { value: 6, result: FuelTank.CENTER }, 12 | { value: 7, result: FuelTank.CENTER2 }, 13 | { value: 8, result: FuelTank.CENTER3 }, 14 | { value: 9, result: FuelTank.EXT1 }, 15 | { value: 10, result: FuelTank.EXT2 }, 16 | { value: 11, result: FuelTank.RIGHT_TIP }, 17 | { value: 12, result: FuelTank.LEFT_TIP }, 18 | { value: 13, result: FuelTank.CROSS_FEED }, 19 | { value: 14, result: FuelTank.CROSS_FEED_LTR }, 20 | { value: 15, result: FuelTank.CROSS_FEED_RTL }, 21 | { value: 16, result: FuelTank.CROSS_FEED_BOTH }, 22 | { value: 17, result: FuelTank.EXTERNAL }, 23 | { value: 18, result: FuelTank.ISOLATE }, 24 | { value: 19, result: FuelTank.LEFT_MAIN }, 25 | { value: 20, result: FuelTank.RIGHT_MAIN }, 26 | { value: 21, result: null }, 27 | { value: null, result: null }, 28 | ]; 29 | 30 | describe('fuel-tank mapping', () => { 31 | TESTS.forEach(test => { 32 | it(`should map value ${test.value} to engine-type ${test.result}`, () => { 33 | expect(fuelTank(test.value)).toEqual(test.result); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /tests/convert/mappings/lights.spec.ts: -------------------------------------------------------------------------------- 1 | import { lightsMapping } from '@mappings/lights'; 2 | 3 | const VALUES = [0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0]; 4 | const EXPECTED_RESULT = { 5 | nav: false, 6 | beacon: true, 7 | land: true, 8 | taxi: false, 9 | strobe: false, 10 | panel: false, 11 | recognition: true, 12 | wing: true, 13 | logo: true, 14 | cabin: true 15 | }; 16 | 17 | describe('lights mapping', () => { 18 | it('should map values to lights object', () => { 19 | expect(lightsMapping(VALUES)).toEqual(EXPECTED_RESULT); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /tests/convert/mappings/mappings.spec.ts: -------------------------------------------------------------------------------- 1 | import { MAPPINGS } from '@mappings/index'; 2 | 3 | describe('mappings list', () => { 4 | it('should import all mappings', () => { 5 | expect(MAPPINGS).toMatchSnapshot(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/convert/mappings/nav-backcourse-flags.spec.ts: -------------------------------------------------------------------------------- 1 | import { navBackCourseFlags } from '@mappings/nav-back-course-flags'; 2 | 3 | const VALUES = [0, 1, 1, 0, 0, 0, 1, 1]; 4 | const EXPECTED_RESULT = { 5 | backCourseAvailable: false, 6 | localiserTunedIn: true, 7 | onBackCourse: true, 8 | stationActive: true, 9 | }; 10 | 11 | describe('nav backcourse flags mapping', () => { 12 | it('should map values to nav backcourse flags object', () => { 13 | expect(navBackCourseFlags(VALUES)).toEqual(EXPECTED_RESULT); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/convert/mappings/nav-capabilities.spec.ts: -------------------------------------------------------------------------------- 1 | import { navCapabilities } from '@mappings/nav-capabilities'; 2 | 3 | const VALUES = [0, 1, 1, 0, 0, 0, 1, 1, 1, 1]; 4 | const EXPECTED_RESULT = { 5 | dme: false, 6 | tacan: true, 7 | voice: true, 8 | noSignal: false, 9 | dmeGlideslope: false, 10 | noBackCourse: false, 11 | glideslope: true, 12 | isLocaliser: true, 13 | }; 14 | 15 | describe('nav capabilities mapping', () => { 16 | it('should map values to nav capabilities object', () => { 17 | expect(navCapabilities(VALUES)).toEqual(EXPECTED_RESULT); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/convert/mappings/nearest-airport-id.spec.ts: -------------------------------------------------------------------------------- 1 | import { nearestAirportsIds } from '@mappings/nearest-airports-ids'; 2 | 3 | /* tslint:disable */ 4 | const BYTE_ARRAY = [ 5 | 67,89,81,66, 6 | 25,42,59,66,99,201,142,194,214,255,115,67,10,5,233,61, 7 | 67,83,71,53, 8 | 185,189,58,66,167,77,142,194,1,128,162,67,149,233,60,65, 9 | 67,83,84,55, 10 | 185,61,58,66,113,93,142,194,2,128,237,67,41,121,130,65, 11 | 67,83,75,53, 12 | 123,148,59,66,89,146,143,194,224,127,17,68,255,229,137,65, 13 | 67,84,82,54, 14 | 107,34,59,66,28,167,143,194,1,0,150,67,90,200,141,65, 15 | 67,84,81,54, 16 | 223,124,58,66,246,232,141,194,0,0,12,68,194,184,165,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,10,51,1,0,100,0,50,0,2,32,0,0,0,0,0,0,0,0,0,0,0,128,0,0,10,51,1,0,100,0,50,0,2,0,0,0,0,0,0,0,0,0,0,0,0,51,0,0,30,77,2,176,29,16,14,153,57,204,12,0,0,0,0,0,0,0,0,0,0,10,0,0,7,0,1 17 | ]; 18 | /* tslint:enable */ 19 | 20 | let EMPTY_BYTE_ARRAY = Array(128).fill(0); 21 | 22 | const EXPECTED_AIRPORTS = [ 23 | 'CYQB', 24 | 'CSG5', 25 | 'CST7', 26 | 'CSK5', 27 | 'CTR6', 28 | 'CTQ6' 29 | ]; 30 | 31 | let EMPTY_ARRAY = Array(6).fill(''); 32 | 33 | describe('nearest airport ids', () => { 34 | it('should convert byte array to airport OACI code list', () => { 35 | expect(nearestAirportsIds(BYTE_ARRAY)).toEqual(EXPECTED_AIRPORTS); 36 | }); 37 | 38 | it('should convert empty byte array to an empty OACI code list', () => { 39 | expect(nearestAirportsIds(EMPTY_BYTE_ARRAY)).toEqual(EMPTY_ARRAY); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/convert/mappings/precipitation-type.spec.ts: -------------------------------------------------------------------------------- 1 | import { precipitationType } from '@mappings/precipitation-type'; 2 | import { PrecipitationType } from '@shared/weather/precipitation-type'; 3 | 4 | const TESTS = [ 5 | { value: 0, result: PrecipitationType.NONE }, 6 | { value: 1, result: PrecipitationType.RAIN }, 7 | { value: 2, result: PrecipitationType.SNOW }, 8 | { value: 3, result: null }, 9 | { value: null, result: null }, 10 | ]; 11 | 12 | describe('precipitation type mapping', () => { 13 | TESTS.forEach(test => { 14 | it(`should map value ${test.value} to precipitation type ${test.result}`, () => { 15 | expect(precipitationType(test.value)).toEqual(test.result); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/convert/mappings/runway-surface-condition.spec.ts: -------------------------------------------------------------------------------- 1 | import { runwaySurfaceCondition } from '@mappings/runway-surface-condition'; 2 | import { SurfaceCondition } from '@shared/runway/runway-surface-condition'; 3 | 4 | const TESTS = [ 5 | { value: 0, result: SurfaceCondition.NORMAL }, 6 | { value: 1, result: SurfaceCondition.WET }, 7 | { value: 2, result: SurfaceCondition.ICY }, 8 | { value: 3, result: SurfaceCondition.SNOW }, 9 | { value: 4, result: null }, 10 | { value: null, result: null }, 11 | ]; 12 | 13 | describe('runway surface condition mapping', () => { 14 | TESTS.forEach(test => { 15 | it(`should map value ${test.value} to runway surface condition ${test.result}`, () => { 16 | expect(runwaySurfaceCondition(test.value)).toEqual(test.result); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/convert/mappings/seasons.spec.ts: -------------------------------------------------------------------------------- 1 | import { seasons } from '@mappings/seasons'; 2 | import { Season } from '@shared/weather/season'; 3 | 4 | const TESTS = [ 5 | { value: 0, result: Season.WINTER }, 6 | { value: 1, result: Season.SPRING }, 7 | { value: 2, result: Season.SUMMER }, 8 | { value: 3, result: Season.AUTUMN }, 9 | { value: 4, result: null }, 10 | { value: null, result: null }, 11 | ]; 12 | 13 | describe('seasons mapping', () => { 14 | TESTS.forEach(test => { 15 | it(`should map value ${test.value} to season ${test.result}`, () => { 16 | expect(seasons(test.value)).toEqual(test.result); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/convert/mappings/spoilers-control.spec.ts: -------------------------------------------------------------------------------- 1 | import { spoilersControl } from '@mappings/spoilers-control'; 2 | 3 | const TESTS = [ 4 | { value: 0, result: 0 }, 5 | { value: 4799, result: 0 }, 6 | { value: 4800, result: 0 }, 7 | { value: 5620, result: 7 }, 8 | { value: 16383, result: 100 }, 9 | ]; 10 | 11 | describe('spoilers control mapping', () => { 12 | TESTS.forEach(test => { 13 | it(`should map value ${test.value} to spoilers-control ${test.result}`, () => { 14 | expect(spoilersControl(test.value)).toEqual(test.result); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /tests/convert/mappings/time-of-day.spec.ts: -------------------------------------------------------------------------------- 1 | import { timeOfDay } from '@mappings/time-of-day'; 2 | import { TimeOfDay } from '@shared/environment/time-of-day'; 3 | 4 | const TESTS = [ 5 | { value: 1, result: TimeOfDay.DAY }, 6 | { value: 2, result: TimeOfDay.DUSK_DAWN }, 7 | { value: 3, result: TimeOfDay.NIGHT }, 8 | { value: 4, result: null }, 9 | { value: null, result: null }, 10 | ]; 11 | 12 | describe('time-of-day mapping', () => { 13 | TESTS.forEach(test => { 14 | it(`should map value ${test.value} to time-of-day ${test.result}`, () => { 15 | expect(timeOfDay(test.value)).toEqual(test.result); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/convert/mappings/units/ftsec-kt.spec.ts: -------------------------------------------------------------------------------- 1 | import { ftsecToKt, ktToFtsec } from '@mappings/units'; 2 | 3 | describe('ft/s to knots', () => { 4 | it('should convert unit properly', () => { 5 | expect(ftsecToKt(100)).toEqual(59.25); 6 | }); 7 | }); 8 | 9 | describe('knots to ft/s', () => { 10 | it('should convert unit properly', () => { 11 | expect(ktToFtsec(59.253)).toEqual(100.01); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /tests/convert/mappings/vor-to-from.spec.ts: -------------------------------------------------------------------------------- 1 | import { vorToFrom } from '@mappings/vor-to-from'; 2 | import { VorToFrom } from '@shared/radios/vor-to-from'; 3 | 4 | const TESTS = [ 5 | { value: 0, result: VorToFrom.OFF }, 6 | { value: 1, result: VorToFrom.TO }, 7 | { value: 2, result: VorToFrom.FROM }, 8 | { value: 3, result: null }, 9 | { value: null, result: null }, 10 | ]; 11 | 12 | describe('vor-to-from mapping', () => { 13 | TESTS.forEach(test => { 14 | it(`should map value ${test.value} to vor-to-from ${test.result}`, () => { 15 | expect(vorToFrom(test.value)).toEqual(test.result); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/offsets/__snapshots__/apu.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/APU offsets list should have required properties 1`] = ` 4 | Object { 5 | "APUGeneratorActive": Offset { 6 | "category": "APU", 7 | "convert": "!!{VAL}", 8 | "description": "APU generator active", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "APUGeneratorActive", 12 | "permission": "r", 13 | "type": 0, 14 | "value": 2898, 15 | }, 16 | "APUGeneratorSwitch": Offset { 17 | "category": "APU", 18 | "convert": "!!{VAL}", 19 | "description": "APU generator switch", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "APUGeneratorSwitch", 23 | "permission": "rw", 24 | "type": 0, 25 | "value": 2897, 26 | }, 27 | "APUMaxRPM": Offset { 28 | "category": "APU", 29 | "convert": "+({VAL}).toFixed(2)", 30 | "description": "APU generator max RPM percent", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "APUMaxRPM", 34 | "permission": "r", 35 | "type": 9, 36 | "value": 2900, 37 | }, 38 | "APUOnFire": Offset { 39 | "category": "APU", 40 | "convert": "!!{VAL}", 41 | "description": "APU generator active", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "APUOnFire", 45 | "permission": "r", 46 | "type": 0, 47 | "value": 2899, 48 | }, 49 | "APUStarter": Offset { 50 | "category": "APU", 51 | "convert": "{VAL} ? 1 : 0", 52 | "description": "APU starter", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "APUStarter", 56 | "permission": "rw", 57 | "type": 9, 58 | "value": 2904, 59 | }, 60 | "APUVoltage": Offset { 61 | "category": "APU", 62 | "convert": "+({VAL}).toFixed(2)", 63 | "description": "APU generator voltage", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "APUVoltage", 67 | "permission": "rw", 68 | "type": 9, 69 | "value": 2908, 70 | }, 71 | } 72 | `; 73 | -------------------------------------------------------------------------------- /tests/offsets/airport/__snapshots__/pushback.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - airport/pushback offsets list should have required properties 1`] = ` 4 | Object { 5 | "pushbackAngle": Offset { 6 | "category": "pushback", 7 | "convert": undefined, 8 | "description": "pushback angle - radians", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "pushbackAngle", 12 | "permission": "r", 13 | "type": 9, 14 | "value": 820, 15 | }, 16 | "pushbackWaitFlag": Offset { 17 | "category": "pushback", 18 | "convert": "!!{VAL}", 19 | "description": "pushback wait flag", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "pushbackWaitFlag", 23 | "permission": "r", 24 | "type": 5, 25 | "value": 836, 26 | }, 27 | "pushbackXContact": Offset { 28 | "category": "pushback", 29 | "convert": undefined, 30 | "description": "pushback X contact - ft", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "pushbackXContact", 34 | "permission": "r", 35 | "type": 9, 36 | "value": 824, 37 | }, 38 | "pushbackYContact": Offset { 39 | "category": "pushback", 40 | "convert": undefined, 41 | "description": "pushback Y contact - ft", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "pushbackYContact", 45 | "permission": "r", 46 | "type": 9, 47 | "value": 828, 48 | }, 49 | "pushbackZContact": Offset { 50 | "category": "pushback", 51 | "convert": undefined, 52 | "description": "pushback Z contact - ft", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "pushbackZContact", 56 | "permission": "r", 57 | "type": 9, 58 | "value": 832, 59 | }, 60 | } 61 | `; 62 | -------------------------------------------------------------------------------- /tests/offsets/airport/__snapshots__/runway.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - airport/runway offsets list should have required properties 1`] = ` 4 | Object { 5 | "runwaySurfaceCondition": Offset { 6 | "category": "runway", 7 | "convert": "runwaySurfaceCondition", 8 | "description": "surface condition", 9 | "length": undefined, 10 | "mapping": true, 11 | "name": "runwaySurfaceCondition", 12 | "permission": "r", 13 | "type": 0, 14 | "value": 838, 15 | }, 16 | "runwaySurfaceConditionValid": Offset { 17 | "category": "runway", 18 | "convert": "!!{VAL}", 19 | "description": "surface condition valid flag", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "runwaySurfaceConditionValid", 23 | "permission": "r", 24 | "type": 0, 25 | "value": 839, 26 | }, 27 | } 28 | `; 29 | -------------------------------------------------------------------------------- /tests/offsets/airport/pushback.spec.ts: -------------------------------------------------------------------------------- 1 | import { pushback as offsets } from '@offsets/airport/pushback'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - airport/pushback', () => { 5 | const offsetsTestCases = [ 6 | { name: 'pushbackWaitFlag', value: 0, expectedResult: false }, 7 | { name: 'pushbackWaitFlag', value: 1, expectedResult: true }, 8 | ]; 9 | 10 | describe('offsets list', () => { 11 | it('should have required properties', () => { 12 | expect(offsets).toMatchSnapshot(); 13 | }); 14 | }); 15 | 16 | offsetsTestCases.forEach(testedOffset => { 17 | describe(testedOffset.name, () => { 18 | it('should convert data properly', () => { 19 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 20 | 21 | // tslint:disable-next-line:no-eval 22 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/offsets/airport/runway.spec.ts: -------------------------------------------------------------------------------- 1 | import { runway as offsets } from '@offsets/airport/runway'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - airport/runway', () => { 5 | const offsetsTestCases = [ 6 | { name: 'runwaySurfaceConditionValid', value: 0, expectedResult: false }, 7 | { name: 'runwaySurfaceConditionValid', value: 1, expectedResult: true }, 8 | ]; 9 | 10 | describe('offsets list', () => { 11 | it('should have required properties', () => { 12 | expect(offsets).toMatchSnapshot(); 13 | }); 14 | }); 15 | 16 | offsetsTestCases.forEach(testedOffset => { 17 | describe(testedOffset.name, () => { 18 | it('should convert data properly', () => { 19 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 20 | 21 | // tslint:disable-next-line:no-eval 22 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/offsets/apu.spec.ts: -------------------------------------------------------------------------------- 1 | import { APU as offsets } from '@offsets/plane/apu'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/APU', () => { 5 | const offsetsTestCases = [ 6 | { name: 'APUGeneratorSwitch', value: 0, expectedResult: false }, 7 | { name: 'APUGeneratorSwitch', value: 1, expectedResult: true }, 8 | { name: 'APUGeneratorActive', value: 0, expectedResult: false }, 9 | { name: 'APUGeneratorActive', value: 1, expectedResult: true }, 10 | { name: 'APUOnFire', value: 0, expectedResult: false }, 11 | { name: 'APUOnFire', value: 1, expectedResult: true }, 12 | { name: 'APUMaxRPM', value: 1.05666, expectedResult: 1.06 }, 13 | { name: 'APUStarter', value: true, expectedResult: 1 }, 14 | { name: 'APUStarter', value: false, expectedResult: 0 }, 15 | { name: 'APUVoltage', value: 12.05666, expectedResult: 12.06 }, 16 | ]; 17 | 18 | describe('offsets list', () => { 19 | it('should have required properties', () => { 20 | expect(offsets).toMatchSnapshot(); 21 | }); 22 | }); 23 | 24 | offsetsTestCases.forEach(testedOffset => { 25 | describe(testedOffset.name, () => { 26 | it('should convert data properly', () => { 27 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 28 | 29 | // tslint:disable-next-line:no-eval 30 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 31 | }); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/offsets/environment/environment.spec.ts: -------------------------------------------------------------------------------- 1 | import { environment as offsets } from '@offsets/environment/environment'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - environment/environment', () => { 5 | const offsetsTestCases = [ 6 | { name: 'towerLatitude', value: 2.2329449e+16, expectedResult: 46.78263288720104 }, 7 | { name: 'towerLongitude', value: -3.6582626e+18, expectedResult: -71.39333265196446 }, 8 | { name: 'towerAltitude', value: 392731796979, expectedResult: 300 }, 9 | ]; 10 | 11 | describe('offsets list', () => { 12 | it('should have required properties', () => { 13 | expect(offsets).toMatchSnapshot(); 14 | }); 15 | }); 16 | 17 | offsetsTestCases.forEach(testedOffset => { 18 | describe(testedOffset.name, () => { 19 | it('should convert data properly', () => { 20 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 21 | 22 | // tslint:disable-next-line:no-eval 23 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 24 | }); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/offsets/environment/weather/at-aircraft.spec.ts: -------------------------------------------------------------------------------- 1 | import { weatherAtAircraft as offsets } from '@offsets/environment/weather/at-aircraft'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - environment/weather/at-aircraft', () => { 5 | const offsetsTestCases = [ 6 | { name: 'upperCloudCeiling', value: 914, expectedResult: 2998.69 }, 7 | { name: 'upperCloudBase', value: 914, expectedResult: 2998.69 }, 8 | { name: 'upperCloudCoverage', value: 32768 , expectedResult: 4 }, 9 | { name: 'upperCloudVariation', value: 914, expectedResult: 2998.69 }, 10 | { name: 'lowerCloudCeiling', value: 914, expectedResult: 2998.69 }, 11 | { name: 'lowerCloudBase', value: 914, expectedResult: 2998.69 }, 12 | { name: 'lowerCloudCoverage', value: 32768 , expectedResult: 4 }, 13 | { name: 'lowerCloudVariation', value: 914, expectedResult: 2998.69 }, 14 | { name: 'stormCloudCeiling', value: 914, expectedResult: 2998.69 }, 15 | { name: 'stormCloudBase', value: 914, expectedResult: 2998.69 }, 16 | { name: 'stormCloudCoverage', value: 32768 , expectedResult: 4 }, 17 | { name: 'stormCloudVariation', value: 914, expectedResult: 2998.69 }, 18 | { name: 'upperTemperatureLevel', value: 914, expectedResult: 2998.69 }, 19 | { name: 'upperTemperature', value: 512, expectedResult: 2 }, 20 | { name: 'middleTemperatureLevel', value: 914, expectedResult: 2998.69 }, 21 | { name: 'middleTemperature', value: 512, expectedResult: 2 }, 22 | { name: 'lowerTemperatureLevel', value: 914, expectedResult: 2998.69 }, 23 | { name: 'lowerTemperature', value: 512, expectedResult: 2 }, 24 | { name: 'surfaceTemperatureLevel', value: 914, expectedResult: 2998.69 }, 25 | { name: 'surfaceTemperature', value: 512, expectedResult: 2 }, 26 | { name: 'temperatureDrift', value: 512, expectedResult: 2 }, 27 | { name: 'temperatureDayNightVariation', value: 512, expectedResult: 2 }, 28 | { name: 'pressureQNH', value: 32, expectedResult: 2 }, 29 | { name: 'pressureDrift', value: 32, expectedResult: 2 }, 30 | { name: 'upperWindCeiling', value: 914, expectedResult: 2998.69 }, 31 | { name: 'upperWindBase', value: 914, expectedResult: 2998.69 }, 32 | { name: 'upperWindDirection', value: 32768, expectedResult: 180 }, 33 | { name: 'upperWindGustEnabled', value: 1, expectedResult: true }, 34 | { name: 'upperWindGustEnabled', value: 0, expectedResult: false }, 35 | { name: 'middleWindCeiling', value: 914, expectedResult: 2998.69 }, 36 | { name: 'middleWindBase', value: 914, expectedResult: 2998.69 }, 37 | { name: 'middleWindDirection', value: 32768, expectedResult: 180 }, 38 | { name: 'middleWindGustEnabled', value: 1, expectedResult: true }, 39 | { name: 'middleWindGustEnabled', value: 0, expectedResult: false }, 40 | { name: 'lowerWindCeiling', value: 914, expectedResult: 2998.69 }, 41 | { name: 'lowerWindBase', value: 914, expectedResult: 2998.69 }, 42 | { name: 'lowerWindDirection', value: 32768, expectedResult: 180 }, 43 | { name: 'lowerWindGustEnabled', value: 1, expectedResult: true }, 44 | { name: 'lowerWindGustEnabled', value: 0, expectedResult: false }, 45 | { name: 'surfaceWindCeiling', value: 914, expectedResult: 2998.69 }, 46 | { name: 'surfaceWindGustEnabled', value: 1, expectedResult: true }, 47 | { name: 'surfaceWindGustEnabled', value: 0, expectedResult: false }, 48 | { name: 'upperCloudIcing', value: 1, expectedResult: true }, 49 | { name: 'upperCloudIcing', value: 0, expectedResult: false }, 50 | { name: 'lowerCloudIcing', value: 1, expectedResult: true }, 51 | { name: 'lowerCloudIcing', value: 0, expectedResult: false }, 52 | { name: 'stormCloudIcing', value: 1, expectedResult: true }, 53 | { name: 'stormCloudIcing', value: 0, expectedResult: false }, 54 | ]; 55 | 56 | describe('offsets list', () => { 57 | it('should have required properties', () => { 58 | expect(offsets).toMatchSnapshot(); 59 | }); 60 | }); 61 | 62 | offsetsTestCases.forEach(testedOffset => { 63 | describe(testedOffset.name, () => { 64 | it('should convert data properly', () => { 65 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 66 | 67 | // tslint:disable-next-line:no-eval 68 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 69 | }); 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /tests/offsets/environment/weather/settings.spec.ts: -------------------------------------------------------------------------------- 1 | import { weatherSettings as offsets } from '@offsets/environment/weather/settings'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - environment/weather/settings', () => { 5 | const offsetsTestCases = [ 6 | { name: 'upperCloudCeilingSetting', value: 914, expectedResult: 2998.69 }, 7 | { name: 'upperCloudBaseSetting', value: 914, expectedResult: 2998.69 }, 8 | { name: 'upperCloudCoverageSetting', value: 32768 , expectedResult: 4 }, 9 | { name: 'upperCloudVariationSetting', value: 914, expectedResult: 2998.69 }, 10 | { name: 'lowerCloudCeilingSetting', value: 914, expectedResult: 2998.69 }, 11 | { name: 'lowerCloudBaseSetting', value: 914, expectedResult: 2998.69 }, 12 | { name: 'lowerCloudCoverageSetting', value: 32768 , expectedResult: 4 }, 13 | { name: 'lowerCloudVariationSetting', value: 914, expectedResult: 2998.69 }, 14 | { name: 'stormCloudCeilingSetting', value: 914, expectedResult: 2998.69 }, 15 | { name: 'stormCloudBaseSetting', value: 914, expectedResult: 2998.69 }, 16 | { name: 'stormCloudCoverageSetting', value: 32768 , expectedResult: 4 }, 17 | { name: 'stormCloudVariationSetting', value: 914, expectedResult: 2998.69 }, 18 | { name: 'upperTemperatureLevelSetting', value: 914, expectedResult: 2998.69 }, 19 | { name: 'upperTemperatureSetting', value: 512, expectedResult: 2 }, 20 | { name: 'middleTemperatureLevelSetting', value: 914, expectedResult: 2998.69 }, 21 | { name: 'middleTemperatureSetting', value: 512, expectedResult: 2 }, 22 | { name: 'lowerTemperatureLevelSetting', value: 914, expectedResult: 2998.69 }, 23 | { name: 'lowerTemperatureSetting', value: 512, expectedResult: 2 }, 24 | { name: 'surfaceTemperatureLevelSetting', value: 914, expectedResult: 2998.69 }, 25 | { name: 'surfaceTemperatureSetting', value: 512, expectedResult: 2 }, 26 | { name: 'temperatureDriftSetting', value: 512, expectedResult: 2 }, 27 | { name: 'temperatureDayNightVariationSetting', value: 512, expectedResult: 2 }, 28 | { name: 'pressureQNHSetting', value: 32, expectedResult: 2 }, 29 | { name: 'pressureDriftSetting', value: 32, expectedResult: 2 }, 30 | { name: 'upperWindCeilingSetting', value: 914, expectedResult: 2998.69 }, 31 | { name: 'upperWindBaseSetting', value: 914, expectedResult: 2998.69 }, 32 | { name: 'upperWindDirectionSetting', value: 32768, expectedResult: 180 }, 33 | { name: 'upperWindGustEnabledSetting', value: 1, expectedResult: true }, 34 | { name: 'upperWindGustEnabledSetting', value: 0, expectedResult: false }, 35 | { name: 'middleWindCeilingSetting', value: 914, expectedResult: 2998.69 }, 36 | { name: 'middleWindBaseSetting', value: 914, expectedResult: 2998.69 }, 37 | { name: 'middleWindDirectionSetting', value: 32768, expectedResult: 180 }, 38 | { name: 'middleWindGustEnabledSetting', value: 1, expectedResult: true }, 39 | { name: 'middleWindGustEnabledSetting', value: 0, expectedResult: false }, 40 | { name: 'lowerWindCeilingSetting', value: 914, expectedResult: 2998.69 }, 41 | { name: 'lowerWindBaseSetting', value: 914, expectedResult: 2998.69 }, 42 | { name: 'lowerWindDirectionSetting', value: 32768, expectedResult: 180 }, 43 | { name: 'lowerWindGustEnabledSetting', value: 1, expectedResult: true }, 44 | { name: 'lowerWindGustEnabledSetting', value: 0, expectedResult: false }, 45 | { name: 'surfaceWindCeilingSetting', value: 914, expectedResult: 2998.69 }, 46 | { name: 'surfaceWindDirectionSetting', value: 32768, expectedResult: 180 }, 47 | { name: 'surfaceWindGustEnabledSetting', value: 1, expectedResult: true }, 48 | { name: 'surfaceWindGustEnabledSetting', value: 0, expectedResult: false }, 49 | { name: 'upperCloudIcingSetting', value: 1, expectedResult: true }, 50 | { name: 'upperCloudIcingSetting', value: 0, expectedResult: false }, 51 | { name: 'lowerCloudIcingSetting', value: 1, expectedResult: true }, 52 | { name: 'lowerCloudIcingSetting', value: 0, expectedResult: false }, 53 | { name: 'stormCloudIcingSetting', value: 1, expectedResult: true }, 54 | { name: 'stormCloudIcingSetting', value: 0, expectedResult: false }, 55 | { name: 'visibilitySetting', value: 1000, expectedResult: 10 }, 56 | ]; 57 | 58 | describe('offsets list', () => { 59 | it('should have required properties', () => { 60 | expect(offsets).toMatchSnapshot(); 61 | }); 62 | }); 63 | 64 | offsetsTestCases.forEach(testedOffset => { 65 | describe(testedOffset.name, () => { 66 | it('should convert data properly', () => { 67 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 68 | 69 | // tslint:disable-next-line:no-eval 70 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 71 | }); 72 | }); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /tests/offsets/failure/failure.spec.ts: -------------------------------------------------------------------------------- 1 | import { failure as offsets } from '@offsets/failure/failure'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/failures', () => { 5 | const offsetsTestCases = [ 6 | { name: 'hydFailure', value: true, expectedResult: 1 }, 7 | { name: 'hydFailure', value: false, expectedResult: 0 }, 8 | { name: 'brakeFailure', value: 'left', expectedResult: 0 }, 9 | { name: 'brakeFailure', value: 'right', expectedResult: 1 }, 10 | { name: 'brakeFailure', value: 'all', expectedResult: 2 }, 11 | { name: 'brakeFailure', value: 'total', expectedResult: 2 }, 12 | { name: 'ADFFailure', value: true, expectedResult: 1 }, 13 | { name: 'ADFFailure', value: false, expectedResult: 0 }, 14 | { name: 'ADFFailure', value: 1, expectedResult: true }, 15 | { name: 'ADFFailure', value: 0, expectedResult: false }, 16 | { name: 'ASIFailure', value: true, expectedResult: 1 }, 17 | { name: 'ASIFailure', value: false, expectedResult: 0 }, 18 | { name: 'ASIFailure', value: 1, expectedResult: true }, 19 | { name: 'ASIFailure', value: 0, expectedResult: false }, 20 | { name: 'altimeterFailure', value: true, expectedResult: 1 }, 21 | { name: 'altimeterFailure', value: false, expectedResult: 0 }, 22 | { name: 'altimeterFailure', value: 1, expectedResult: true }, 23 | { name: 'altimeterFailure', value: 0, expectedResult: false }, 24 | { name: 'attitudeIndicatorFailure', value: true, expectedResult: 1 }, 25 | { name: 'attitudeIndicatorFailure', value: false, expectedResult: 0 }, 26 | { name: 'attitudeIndicatorFailure', value: 1, expectedResult: true }, 27 | { name: 'attitudeIndicatorFailure', value: 0, expectedResult: false }, 28 | { name: 'com1Failure', value: true, expectedResult: 1 }, 29 | { name: 'com1Failure', value: false, expectedResult: 0 }, 30 | { name: 'com1Failure', value: 1, expectedResult: true }, 31 | { name: 'com1Failure', value: 0, expectedResult: false }, 32 | { name: 'compassFailure', value: true, expectedResult: 1 }, 33 | { name: 'compassFailure', value: false, expectedResult: 0 }, 34 | { name: 'compassFailure', value: 1, expectedResult: true }, 35 | { name: 'compassFailure', value: 0, expectedResult: false }, 36 | { name: 'electricsFailure', value: true, expectedResult: 1 }, 37 | { name: 'electricsFailure', value: false, expectedResult: 0 }, 38 | { name: 'electricsFailure', value: 1, expectedResult: true }, 39 | { name: 'electricsFailure', value: 0, expectedResult: false }, 40 | { name: 'fuelIndicatorFailure', value: true, expectedResult: 1 }, 41 | { name: 'fuelIndicatorFailure', value: false, expectedResult: 0 }, 42 | { name: 'fuelIndicatorFailure', value: 1, expectedResult: true }, 43 | { name: 'fuelIndicatorFailure', value: 0, expectedResult: false }, 44 | { name: 'headingFailure', value: true, expectedResult: 1 }, 45 | { name: 'headingFailure', value: false, expectedResult: 0 }, 46 | { name: 'headingFailure', value: 1, expectedResult: true }, 47 | { name: 'headingFailure', value: 0, expectedResult: false }, 48 | { name: 'VSIFailure', value: true, expectedResult: 1 }, 49 | { name: 'VSIFailure', value: false, expectedResult: 0 }, 50 | { name: 'VSIFailure', value: 1, expectedResult: true }, 51 | { name: 'VSIFailure', value: 0, expectedResult: false }, 52 | { name: 'transponderFailure', value: true, expectedResult: 1 }, 53 | { name: 'transponderFailure', value: false, expectedResult: 0 }, 54 | { name: 'transponderFailure', value: 1, expectedResult: true }, 55 | { name: 'transponderFailure', value: 0, expectedResult: false }, 56 | { name: 'NAVFailure', value: true, expectedResult: 1 }, 57 | { name: 'NAVFailure', value: false, expectedResult: 0 }, 58 | { name: 'NAVFailure', value: 1, expectedResult: true }, 59 | { name: 'NAVFailure', value: 0, expectedResult: false }, 60 | { name: 'pitotFailure', value: true, expectedResult: 1 }, 61 | { name: 'pitotFailure', value: false, expectedResult: 0 }, 62 | { name: 'pitotFailure', value: 1, expectedResult: true }, 63 | { name: 'pitotFailure', value: 0, expectedResult: false }, 64 | { name: 'turnCoordinatorFailure', value: true, expectedResult: 1 }, 65 | { name: 'turnCoordinatorFailure', value: false, expectedResult: 0 }, 66 | { name: 'turnCoordinatorFailure', value: 1, expectedResult: true }, 67 | { name: 'turnCoordinatorFailure', value: 0, expectedResult: false }, 68 | { name: 'vacuumFailure', value: true, expectedResult: 1 }, 69 | { name: 'vacuumFailure', value: false, expectedResult: 0 }, 70 | { name: 'vacuumFailure', value: 1, expectedResult: true }, 71 | { name: 'vacuumFailure', value: 0, expectedResult: false }, 72 | ]; 73 | 74 | describe('offsets list', () => { 75 | it('should have required properties', () => { 76 | expect(offsets).toMatchSnapshot(); 77 | }); 78 | }); 79 | 80 | offsetsTestCases.forEach(testedOffset => { 81 | describe(testedOffset.name, () => { 82 | it('should convert data properly', () => { 83 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 84 | 85 | // tslint:disable-next-line:no-eval 86 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 87 | }); 88 | }); 89 | }); 90 | }); 91 | -------------------------------------------------------------------------------- /tests/offsets/offset.spec.ts: -------------------------------------------------------------------------------- 1 | import { OFFSETS } from '@offsets/index'; 2 | 3 | describe('offsets list', () => { 4 | it('should resolve full list', () => { 5 | expect(OFFSETS).toMatchSnapshot(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/offsets/plane/__snapshots__/icing.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/icing offsets list should have required properties 1`] = ` 4 | Object { 5 | "pitotIce": Offset { 6 | "category": "icing", 7 | "convert": "+({VAL} / 16384 * 100).toFixed(2)", 8 | "description": "structural ice - decimal percent", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "pitotIce", 12 | "permission": "r", 13 | "type": 5, 14 | "value": 842, 15 | }, 16 | "structuralIce": Offset { 17 | "category": "icing", 18 | "convert": "+({VAL} / 16384 * 100).toFixed(2)", 19 | "description": "structural ice - decimal percent", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "structuralIce", 23 | "permission": "r", 24 | "type": 5, 25 | "value": 840, 26 | }, 27 | } 28 | `; 29 | -------------------------------------------------------------------------------- /tests/offsets/plane/__snapshots__/pressurisation.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/pressurisation offsets list should have required properties 1`] = ` 4 | Object { 5 | "pressCabinAlt": Offset { 6 | "category": "pressurisation", 7 | "convert": undefined, 8 | "description": "pressurisation: cabin altitude - ft", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "pressCabinAlt", 12 | "permission": "r", 13 | "type": 3, 14 | "value": 792, 15 | }, 16 | "pressCabinAltChange": Offset { 17 | "category": "pressurisation", 18 | "convert": undefined, 19 | "description": "pressurisation: cabin altitude change set - ft/s", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "pressCabinAltChange", 23 | "permission": "r", 24 | "type": 9, 25 | "value": 800, 26 | }, 27 | "pressCabinAltPressDiff": Offset { 28 | "category": "pressurisation", 29 | "convert": undefined, 30 | "description": "pressurisation: cabin altitude change set - lb/sqft", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "pressCabinAltPressDiff", 34 | "permission": "r", 35 | "type": 9, 36 | "value": 804, 37 | }, 38 | "pressCabinAltTarget": Offset { 39 | "category": "pressurisation", 40 | "convert": undefined, 41 | "description": "pressurisation: target cabin altitude - ft", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "pressCabinAltTarget", 45 | "permission": "r", 46 | "type": 3, 47 | "value": 796, 48 | }, 49 | "pressDumpSwitch": Offset { 50 | "category": "pressurisation", 51 | "convert": "!!{VAL}", 52 | "description": "pressurisation: dump switch", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "pressDumpSwitch", 56 | "permission": "rw", 57 | "type": 6, 58 | "value": 808, 59 | }, 60 | } 61 | `; 62 | -------------------------------------------------------------------------------- /tests/offsets/plane/__snapshots__/radios.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/radios offsets list should have required properties 1`] = ` 4 | Object { 5 | "comAtisActivate": Offset { 6 | "category": "radios", 7 | "convert": undefined, 8 | "description": "COM/ATIS activate < FS2000", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "comAtisActivate", 12 | "permission": "w", 13 | "type": 5, 14 | "value": 906, 15 | }, 16 | "comFreq": Offset { 17 | "category": "radios", 18 | "convert": "parseInt(\`1\` + ({VAL}).toString(16))", 19 | "description": "Com frequency", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "comFreq", 23 | "permission": "rw", 24 | "type": 5, 25 | "value": 846, 26 | }, 27 | "dme12Select": Offset { 28 | "category": "radios", 29 | "convert": undefined, 30 | "description": "DME1/DME2 select", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "dme12Select", 34 | "permission": "rw", 35 | "type": 5, 36 | "value": 888, 37 | }, 38 | "innerMarker": Offset { 39 | "category": "radios", 40 | "convert": undefined, 41 | "description": "inner marker - activated when TRUE", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "innerMarker", 45 | "permission": "r", 46 | "type": 2, 47 | "value": 2988, 48 | }, 49 | "middleMarker": Offset { 50 | "category": "radios", 51 | "convert": undefined, 52 | "description": "middle marker - activated when TRUE", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "middleMarker", 56 | "permission": "r", 57 | "type": 2, 58 | "value": 2990, 59 | }, 60 | "nav12Select": Offset { 61 | "category": "radios", 62 | "convert": undefined, 63 | "description": "NAV1/NAV2 select", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "nav12Select", 67 | "permission": "rw", 68 | "type": 5, 69 | "value": 884, 70 | }, 71 | "navAdfActivate": Offset { 72 | "category": "radios", 73 | "convert": undefined, 74 | "description": "NAV and ADF activate < FS2000", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "navAdfActivate", 78 | "permission": "w", 79 | "type": 5, 80 | "value": 904, 81 | }, 82 | "outerMarker": Offset { 83 | "category": "radios", 84 | "convert": undefined, 85 | "description": "outer marker - activated when TRUE", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "outerMarker", 89 | "permission": "r", 90 | "type": 2, 91 | "value": 2992, 92 | }, 93 | "transponderFreq": Offset { 94 | "category": "radios", 95 | "convert": "parseInt(\`1\` + ({VAL}).toString(16))", 96 | "description": "XPND transponder frequency", 97 | "length": undefined, 98 | "mapping": undefined, 99 | "name": "transponderFreq", 100 | "permission": "rw", 101 | "type": 5, 102 | "value": 852, 103 | }, 104 | } 105 | `; 106 | -------------------------------------------------------------------------------- /tests/offsets/plane/autopilot.spec.ts: -------------------------------------------------------------------------------- 1 | import { autopilot as offsets } from '@offsets/plane/autopilot'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/autopilot', () => { 5 | const offsetsTestCases = [ 6 | { name: 'autoPilotAvailable', value: 0, expectedResult: false }, 7 | { name: 'autoPilotAvailable', value: 1, expectedResult: true }, 8 | { name: 'flyByWireELACSwitch', value: 0, expectedResult: false }, 9 | { name: 'flyByWireELACSwitch', value: 1, expectedResult: true }, 10 | { name: 'flyByWireELACCompFailFlag', value: 0, expectedResult: false }, 11 | { name: 'flyByWireELACCompFailFlag', value: 1, expectedResult: true }, 12 | { name: 'flyByWireFACSwitch', value: 0, expectedResult: false }, 13 | { name: 'flyByWireFACSwitch', value: 1, expectedResult: true }, 14 | { name: 'flyByWireFACCompFailFlag', value: 0, expectedResult: false }, 15 | { name: 'flyByWireFACCompFailFlag', value: 1, expectedResult: true }, 16 | { name: 'flyByWireSECSwitch', value: 0, expectedResult: false }, 17 | { name: 'flyByWireSECSwitch', value: 1, expectedResult: true }, 18 | { name: 'flyByWireSECCompFailFlag', value: 0, expectedResult: false }, 19 | { name: 'flyByWireSECCompFailFlag', value: 1, expectedResult: true }, 20 | { name: 'apMasterSwitch', value: 0, expectedResult: false }, 21 | { name: 'apMasterSwitch', value: 1, expectedResult: true }, 22 | { name: 'apWingLevel', value: 0, expectedResult: false }, 23 | { name: 'apWingLevel', value: 1, expectedResult: true }, 24 | { name: 'apNav1Hold', value: 0, expectedResult: false }, 25 | { name: 'apNav1Hold', value: 1, expectedResult: true }, 26 | { name: 'apHeadingHold', value: 0, expectedResult: false }, 27 | { name: 'apHeadingHold', value: 1, expectedResult: true }, 28 | { name: 'apHeadingValue', value: 32768, expectedResult: 180 }, 29 | { name: 'apAltitudeHold', value: 0, expectedResult: false }, 30 | { name: 'apAltitudeHold', value: 1, expectedResult: true }, 31 | { name: 'apAltitudeValue', value: 19975000, expectedResult: 999.98 }, 32 | { name: 'apAsHold', value: 0, expectedResult: false }, 33 | { name: 'apAsHold', value: 1, expectedResult: true }, 34 | { name: 'apMachHold', value: 0, expectedResult: false }, 35 | { name: 'apMachHold', value: 1, expectedResult: true }, 36 | { name: 'apMachValue', value: 229376, expectedResult: 3.5 }, 37 | { name: 'apVsHold', value: 0, expectedResult: false }, 38 | { name: 'apVsHold', value: 1, expectedResult: true }, 39 | { name: 'apRPMN1Hold', value: 0, expectedResult: false }, 40 | { name: 'apRPMN1Hold', value: 1, expectedResult: true }, 41 | { name: 'apRPMN1Value', value: 9175, expectedResult: 56 }, 42 | { name: 'apGlideSlopeHold', value: 0, expectedResult: false }, 43 | { name: 'apGlideSlopeHold', value: 1, expectedResult: true }, 44 | { name: 'apApproachHold', value: 0, expectedResult: false }, 45 | { name: 'apApproachHold', value: 1, expectedResult: true }, 46 | { name: 'apBackCourseHold', value: 0, expectedResult: false }, 47 | { name: 'apBackCourseHold', value: 1, expectedResult: true }, 48 | { name: 'apYawDamperHold', value: 0, expectedResult: false }, 49 | { name: 'apYawDamperHold', value: 1, expectedResult: true }, 50 | { name: 'apTOGAAutoThrottle', value: 0, expectedResult: false }, 51 | { name: 'apTOGAAutoThrottle', value: 1, expectedResult: true }, 52 | { name: 'apAutoThrottleArm', value: 0, expectedResult: false }, 53 | { name: 'apAutoThrottleArm', value: 1, expectedResult: true }, 54 | ]; 55 | 56 | describe('offsets list', () => { 57 | it('should have required properties', () => { 58 | expect(offsets).toMatchSnapshot(); 59 | }); 60 | }); 61 | 62 | offsetsTestCases.forEach(testedOffset => { 63 | describe(testedOffset.name, () => { 64 | it('should convert data properly', () => { 65 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 66 | 67 | // tslint:disable-next-line:no-eval 68 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 69 | }); 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /tests/offsets/plane/cockpit.spec.ts: -------------------------------------------------------------------------------- 1 | import { cockpit as offsets } from '@offsets/plane/cockpit'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/cockpit', () => { 5 | const offsetsTestCases = [ 6 | { name: 'navLights', value: 0, expectedResult: false }, 7 | { name: 'navLights', value: 1, expectedResult: true }, 8 | { name: 'strobeLights', value: 0, expectedResult: false }, 9 | { name: 'strobeLights', value: 1, expectedResult: true }, 10 | { name: 'landingLights', value: 0, expectedResult: false }, 11 | { name: 'landingLights', value: 1, expectedResult: true }, 12 | { name: 'alternateStaticAirSource', value: 0, expectedResult: false }, 13 | { name: 'alternateStaticAirSource', value: 1, expectedResult: true }, 14 | { name: 'pitotHeat', value: 0, expectedResult: false }, 15 | { name: 'pitotHeat', value: 1, expectedResult: true }, 16 | { name: 'altimeterSettings', value: 32, expectedResult: 2 }, 17 | { name: 'altimeterSettingsG1000', value: 32, expectedResult: 2 }, 18 | { name: 'turnRate', value: 2765, expectedResult: 3 }, 19 | { name: 'turnRate', value: 2055, expectedResult: 2 }, 20 | { name: 'stallWarning', value: 0, expectedResult: false }, 21 | { name: 'stallWarning', value: 1, expectedResult: true }, 22 | { name: 'overspeedWarning', value: 0, expectedResult: false }, 23 | { name: 'overspeedWarning', value: 1, expectedResult: true }, 24 | { name: 'gyroDrift', value: 9102, expectedResult: 50 }, 25 | { name: 'autopilotSpeedSwitch738EFIS', value: 0, expectedResult: false }, 26 | { name: 'autopilotSpeedSwitch738EFIS', value: 1, expectedResult: true }, 27 | { name: 'NDILSSwitchA321EFIS', value: 0, expectedResult: false }, 28 | { name: 'NDILSSwitchA321EFIS', value: 1, expectedResult: true }, 29 | { name: 'autopilotSpeedSwitch321EFIS', value: 0, expectedResult: false }, 30 | { name: 'autopilotSpeedSwitch321EFIS', value: 1, expectedResult: true }, 31 | { name: 'altitudeChangeRate321EFIS', value: 0, expectedResult: 100 }, 32 | { name: 'altitudeChangeRate321EFIS', value: 1, expectedResult: 1000 }, 33 | ]; 34 | 35 | describe('offsets list', () => { 36 | it('should have required properties', () => { 37 | expect(offsets).toMatchSnapshot(); 38 | }); 39 | }); 40 | 41 | offsetsTestCases.forEach(testedOffset => { 42 | describe(testedOffset.name, () => { 43 | it('should convert data properly', () => { 44 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 45 | 46 | // tslint:disable-next-line:no-eval 47 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 48 | }); 49 | }); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /tests/offsets/plane/controls.spec.ts: -------------------------------------------------------------------------------- 1 | import { controls as offsets } from '@offsets/plane/controls'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/controls', () => { 5 | const offsetsTestCases = [ 6 | { name: 'autoRudder', value: 0, expectedResult: false }, 7 | { name: 'autoRudder', value: 1, expectedResult: true }, 8 | { name: 'rotorClutchSwitch', value: 0, expectedResult: false }, 9 | { name: 'rotorClutchSwitch', value: 1, expectedResult: true }, 10 | { name: 'elevatorPositionControl', value: -16000, expectedResult: -98 }, 11 | { name: 'aileronPositionControl', value: -16000, expectedResult: -98 }, 12 | { name: 'rudderPositionControl', value: -16000, expectedResult: -98 }, 13 | { name: 'elevatorPositionControl', value: -16000, expectedResult: -98 }, 14 | { name: 'leftBrakeApplication', value: -16000, expectedResult: -98 }, 15 | { name: 'rightBrakeApplication', value: -16000, expectedResult: -98 }, 16 | { name: 'parkingBrake', value: 32767, expectedResult: true }, 17 | { name: 'parkingBrake', value: 32768, expectedResult: true }, 18 | { name: 'parkingBrake', value: 0, expectedResult: false }, 19 | { name: 'parkingBrake', value: true, expectedResult: 32767 }, 20 | { name: 'parkingBrake', value: false, expectedResult: 0 }, 21 | { name: 'spoilersArm', value: 0, expectedResult: false }, 22 | { name: 'spoilersArm', value: 1, expectedResult: true }, 23 | { name: 'spoilerLeftPosition', value: 16383, expectedResult: 100 }, 24 | { name: 'spoilerRightPosition', value: 16383, expectedResult: 100 }, 25 | { name: 'flapsControl', value: 16383, expectedResult: 100 }, 26 | { name: 'flapsLeftPosition', value: 16383, expectedResult: 100 }, 27 | { name: 'flapsRightPosition', value: 16383, expectedResult: 100 }, 28 | { name: 'gearControl', value: 16383, expectedResult: 100 }, 29 | { name: 'gearNosePosition', value: 16383, expectedResult: 100 }, 30 | { name: 'gearRightPosition', value: 16383, expectedResult: 100 }, 31 | { name: 'gearLeftPosition', value: 16383, expectedResult: 100 }, 32 | { name: 'rightToeBrakeControl', value: 200, expectedResult: 100 }, 33 | { name: 'leftToeBrakeControl', value: 200, expectedResult: 100 }, 34 | { name: 'aileronTrimPosition', value: 16383, expectedResult: 100 }, 35 | { name: 'aileronTrimPosition', value: -16383, expectedResult: -100 }, 36 | { name: 'rudderTrimPosition', value: 16383, expectedResult: 100 }, 37 | { name: 'rudderTrimPosition', value: -16383, expectedResult: -100 }, 38 | { name: 'steeringTillerCalibratedValue', value: 16383, expectedResult: 100 }, 39 | { name: 'steeringTillerCalibratedValue', value: -16383, expectedResult: -100 }, 40 | { name: 'rudderCalibratedvalue', value: 16383, expectedResult: 100 }, 41 | { name: 'rudderCalibratedvalue', value: -16383, expectedResult: -100 }, 42 | ]; 43 | 44 | describe('offsets list', () => { 45 | it('should have required properties', () => { 46 | expect(offsets).toMatchSnapshot(); 47 | }); 48 | }); 49 | 50 | offsetsTestCases.forEach(testedOffset => { 51 | describe(testedOffset.name, () => { 52 | it('should convert data properly', () => { 53 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 54 | 55 | // tslint:disable-next-line:no-eval 56 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 57 | }); 58 | }); 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /tests/offsets/plane/electric.spec.ts: -------------------------------------------------------------------------------- 1 | import { electric as offsets } from '@offsets/plane/electric'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/electric', () => { 5 | const offsetsTestCases = [ 6 | { name: 'masterBatterySwitch', value: 0, expectedResult: false }, 7 | { name: 'masterBatterySwitch', value: 1, expectedResult: true }, 8 | ]; 9 | 10 | describe('offsets list', () => { 11 | it('should have required properties', () => { 12 | expect(offsets).toMatchSnapshot(); 13 | }); 14 | }); 15 | 16 | offsetsTestCases.forEach(testedOffset => { 17 | describe(testedOffset.name, () => { 18 | it('should convert data properly', () => { 19 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 20 | 21 | // tslint:disable-next-line:no-eval 22 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines.spec.ts: -------------------------------------------------------------------------------- 1 | import { engines as offsets } from '@offsets/plane/engines'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines', () => { 5 | const offsetsTestCases = [ 6 | { name: 'hasMixtureControl', value: 0, expectedResult: false }, 7 | { name: 'hasMixtureControl', value: 1, expectedResult: true }, 8 | { name: 'hasCarbHeat', value: 0, expectedResult: false }, 9 | { name: 'hasCarbHeat', value: 1, expectedResult: true }, 10 | { name: 'throttleLowerLimit', value: -2048, expectedResult: -50 }, 11 | { name: 'throttleLowerLimit', value: 0, expectedResult: 0 }, 12 | { name: 'throttleLowerLimit', value: 8192, expectedResult: 50 }, 13 | ]; 14 | 15 | describe('offsets list', () => { 16 | it('should have required properties', () => { 17 | expect(offsets).toMatchSnapshot(); 18 | }); 19 | }); 20 | 21 | offsetsTestCases.forEach(testedOffset => { 22 | describe(testedOffset.name, () => { 23 | it('should convert data properly', () => { 24 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 25 | 26 | // tslint:disable-next-line:no-eval 27 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 28 | }); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/__snapshots__/propeller1.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/engines/propeller1 offsets list should have required properties 1`] = ` 4 | Object { 5 | "propeller1AutofeatherArmed": Offset { 6 | "category": "engine", 7 | "convert": "!!{VAL}", 8 | "description": "propeller 1 autofeather armed flag", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "propeller1AutofeatherArmed", 12 | "permission": "rw", 13 | "type": 6, 14 | "value": 9264, 15 | }, 16 | "propeller1BetaBladeAngle": Offset { 17 | "category": "engine", 18 | "convert": "+({VAL}).toFixed(4)", 19 | "description": "propeller 1 beta blade angle - rad", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "propeller1BetaBladeAngle", 23 | "permission": "r", 24 | "type": 8, 25 | "value": 9240, 26 | }, 27 | "propeller1DeiceSwitch": Offset { 28 | "category": "engine", 29 | "convert": "!!{VAL}", 30 | "description": "propeller 1 de-ice active", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "propeller1DeiceSwitch", 34 | "permission": "rw", 35 | "type": 6, 36 | "value": 9280, 37 | }, 38 | "propeller1FeatherSwitch": Offset { 39 | "category": "engine", 40 | "convert": "!!{VAL}", 41 | "description": "propeller 1 feather switch", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "propeller1FeatherSwitch", 45 | "permission": "rw", 46 | "type": 6, 47 | "value": 9268, 48 | }, 49 | "propeller1Feathered": Offset { 50 | "category": "engine", 51 | "convert": "!!{VAL}", 52 | "description": "propeller 1 feathered", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "propeller1Feathered", 56 | "permission": "r", 57 | "type": 6, 58 | "value": 9252, 59 | }, 60 | "propeller1FeatheringInhibit": Offset { 61 | "category": "engine", 62 | "convert": "!!{VAL}", 63 | "description": "propeller 1 feathering inhibit", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "propeller1FeatheringInhibit", 67 | "permission": "rw", 68 | "type": 6, 69 | "value": 9248, 70 | }, 71 | "propeller1PanelAutofeatherSwitch": Offset { 72 | "category": "engine", 73 | "convert": "!!{VAL}", 74 | "description": "propeller 1 panel autofeather switch", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "propeller1PanelAutofeatherSwitch", 78 | "permission": "rw", 79 | "type": 6, 80 | "value": 9272, 81 | }, 82 | "propeller1RPM": Offset { 83 | "category": "engine", 84 | "convert": undefined, 85 | "description": "propeller 1 RPM", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "propeller1RPM", 89 | "permission": "r", 90 | "type": 8, 91 | "value": 9216, 92 | }, 93 | "propeller1RPMPercent": Offset { 94 | "category": "engine", 95 | "convert": "Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))", 96 | "description": "propeller 1 RPM percent", 97 | "length": undefined, 98 | "mapping": undefined, 99 | "name": "propeller1RPMPercent", 100 | "permission": "r", 101 | "type": 8, 102 | "value": 9224, 103 | }, 104 | "propeller1Sync": Offset { 105 | "category": "engine", 106 | "convert": "!!{VAL}", 107 | "description": "propeller 1 sync active", 108 | "length": undefined, 109 | "mapping": undefined, 110 | "name": "propeller1Sync", 111 | "permission": "rw", 112 | "type": 6, 113 | "value": 9276, 114 | }, 115 | "propeller1SyncDeltaLever": Offset { 116 | "category": "engine", 117 | "convert": undefined, 118 | "description": "propeller 1 sync delta lever", 119 | "length": undefined, 120 | "mapping": undefined, 121 | "name": "propeller1SyncDeltaLever", 122 | "permission": "r", 123 | "type": 8, 124 | "value": 9256, 125 | }, 126 | "propeller1Thrust": Offset { 127 | "category": "engine", 128 | "convert": "+({VAL}).toFixed(2)", 129 | "description": "propeller 1 thrust - lb", 130 | "length": undefined, 131 | "mapping": undefined, 132 | "name": "propeller1Thrust", 133 | "permission": "r", 134 | "type": 8, 135 | "value": 9232, 136 | }, 137 | } 138 | `; 139 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/__snapshots__/propeller2.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/engines/propeller2 offsets list should have required properties 1`] = ` 4 | Object { 5 | "propeller2AutofeatherArmed": Offset { 6 | "category": "engine", 7 | "convert": "!!{VAL}", 8 | "description": "propeller 2 autofeather armed flag", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "propeller2AutofeatherArmed", 12 | "permission": "rw", 13 | "type": 6, 14 | "value": 9520, 15 | }, 16 | "propeller2BetaBladeAngle": Offset { 17 | "category": "engine", 18 | "convert": "+({VAL}).toFixed(4)", 19 | "description": "propeller 2 beta blade angle - rad", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "propeller2BetaBladeAngle", 23 | "permission": "r", 24 | "type": 8, 25 | "value": 9496, 26 | }, 27 | "propeller2DeiceSwitch": Offset { 28 | "category": "engine", 29 | "convert": "!!{VAL}", 30 | "description": "propeller 2 de-ice active", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "propeller2DeiceSwitch", 34 | "permission": "rw", 35 | "type": 6, 36 | "value": 9536, 37 | }, 38 | "propeller2FeatherSwitch": Offset { 39 | "category": "engine", 40 | "convert": "!!{VAL}", 41 | "description": "propeller 2 feather switch", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "propeller2FeatherSwitch", 45 | "permission": "rw", 46 | "type": 6, 47 | "value": 9524, 48 | }, 49 | "propeller2Feathered": Offset { 50 | "category": "engine", 51 | "convert": "!!{VAL}", 52 | "description": "propeller 2 feathered", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "propeller2Feathered", 56 | "permission": "r", 57 | "type": 6, 58 | "value": 9508, 59 | }, 60 | "propeller2FeatheringInhibit": Offset { 61 | "category": "engine", 62 | "convert": "!!{VAL}", 63 | "description": "propeller 2 feathering inhibit", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "propeller2FeatheringInhibit", 67 | "permission": "rw", 68 | "type": 6, 69 | "value": 9504, 70 | }, 71 | "propeller2PanelAutofeatherSwitch": Offset { 72 | "category": "engine", 73 | "convert": "!!{VAL}", 74 | "description": "propeller 2 panel autofeather switch", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "propeller2PanelAutofeatherSwitch", 78 | "permission": "rw", 79 | "type": 6, 80 | "value": 9528, 81 | }, 82 | "propeller2RPM": Offset { 83 | "category": "engine", 84 | "convert": undefined, 85 | "description": "propeller 2 RPM", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "propeller2RPM", 89 | "permission": "r", 90 | "type": 8, 91 | "value": 9472, 92 | }, 93 | "propeller2RPMPercent": Offset { 94 | "category": "engine", 95 | "convert": "Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))", 96 | "description": "propeller 2 RPM percent", 97 | "length": undefined, 98 | "mapping": undefined, 99 | "name": "propeller2RPMPercent", 100 | "permission": "r", 101 | "type": 8, 102 | "value": 9480, 103 | }, 104 | "propeller2Sync": Offset { 105 | "category": "engine", 106 | "convert": "!!{VAL}", 107 | "description": "propeller 2 sync active", 108 | "length": undefined, 109 | "mapping": undefined, 110 | "name": "propeller2Sync", 111 | "permission": "rw", 112 | "type": 6, 113 | "value": 9532, 114 | }, 115 | "propeller2SyncDeltaLever": Offset { 116 | "category": "engine", 117 | "convert": undefined, 118 | "description": "propeller 2 sync delta lever", 119 | "length": undefined, 120 | "mapping": undefined, 121 | "name": "propeller2SyncDeltaLever", 122 | "permission": "r", 123 | "type": 8, 124 | "value": 9512, 125 | }, 126 | "propeller2Thrust": Offset { 127 | "category": "engine", 128 | "convert": "+({VAL}).toFixed(2)", 129 | "description": "propeller 2 thrust - lb", 130 | "length": undefined, 131 | "mapping": undefined, 132 | "name": "propeller2Thrust", 133 | "permission": "r", 134 | "type": 8, 135 | "value": 9488, 136 | }, 137 | } 138 | `; 139 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/__snapshots__/propeller3.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/engines/propeller3 offsets list should have required properties 1`] = ` 4 | Object { 5 | "propeller3AutofeatherArmed": Offset { 6 | "category": "engine", 7 | "convert": "!!{VAL}", 8 | "description": "propeller 3 autofeather armed flag", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "propeller3AutofeatherArmed", 12 | "permission": "rw", 13 | "type": 6, 14 | "value": 9776, 15 | }, 16 | "propeller3BetaBladeAngle": Offset { 17 | "category": "engine", 18 | "convert": "+({VAL}).toFixed(4)", 19 | "description": "propeller 3 beta blade angle - rad", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "propeller3BetaBladeAngle", 23 | "permission": "r", 24 | "type": 8, 25 | "value": 9752, 26 | }, 27 | "propeller3DeiceSwitch": Offset { 28 | "category": "engine", 29 | "convert": "!!{VAL}", 30 | "description": "propeller 3 de-ice active", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "propeller3DeiceSwitch", 34 | "permission": "rw", 35 | "type": 6, 36 | "value": 9792, 37 | }, 38 | "propeller3FeatherSwitch": Offset { 39 | "category": "engine", 40 | "convert": "!!{VAL}", 41 | "description": "propeller 3 feather switch", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "propeller3FeatherSwitch", 45 | "permission": "rw", 46 | "type": 6, 47 | "value": 9780, 48 | }, 49 | "propeller3Feathered": Offset { 50 | "category": "engine", 51 | "convert": "!!{VAL}", 52 | "description": "propeller 3 feathered", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "propeller3Feathered", 56 | "permission": "r", 57 | "type": 6, 58 | "value": 9764, 59 | }, 60 | "propeller3FeatheringInhibit": Offset { 61 | "category": "engine", 62 | "convert": "!!{VAL}", 63 | "description": "propeller 3 feathering inhibit", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "propeller3FeatheringInhibit", 67 | "permission": "rw", 68 | "type": 6, 69 | "value": 9760, 70 | }, 71 | "propeller3PanelAutofeatherSwitch": Offset { 72 | "category": "engine", 73 | "convert": "!!{VAL}", 74 | "description": "propeller 3 panel autofeather switch", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "propeller3PanelAutofeatherSwitch", 78 | "permission": "rw", 79 | "type": 6, 80 | "value": 9784, 81 | }, 82 | "propeller3RPM": Offset { 83 | "category": "engine", 84 | "convert": undefined, 85 | "description": "propeller 3 RPM", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "propeller3RPM", 89 | "permission": "r", 90 | "type": 8, 91 | "value": 9728, 92 | }, 93 | "propeller3RPMPercent": Offset { 94 | "category": "engine", 95 | "convert": "Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))", 96 | "description": "propeller 3 RPM percent", 97 | "length": undefined, 98 | "mapping": undefined, 99 | "name": "propeller3RPMPercent", 100 | "permission": "r", 101 | "type": 8, 102 | "value": 9736, 103 | }, 104 | "propeller3Sync": Offset { 105 | "category": "engine", 106 | "convert": "!!{VAL}", 107 | "description": "propeller 3 sync active", 108 | "length": undefined, 109 | "mapping": undefined, 110 | "name": "propeller3Sync", 111 | "permission": "rw", 112 | "type": 6, 113 | "value": 9788, 114 | }, 115 | "propeller3SyncDeltaLever": Offset { 116 | "category": "engine", 117 | "convert": undefined, 118 | "description": "propeller 3 sync delta lever", 119 | "length": undefined, 120 | "mapping": undefined, 121 | "name": "propeller3SyncDeltaLever", 122 | "permission": "r", 123 | "type": 8, 124 | "value": 9768, 125 | }, 126 | "propeller3Thrust": Offset { 127 | "category": "engine", 128 | "convert": "+({VAL}).toFixed(2)", 129 | "description": "propeller 3 thrust - lb", 130 | "length": undefined, 131 | "mapping": undefined, 132 | "name": "propeller3Thrust", 133 | "permission": "r", 134 | "type": 8, 135 | "value": 9744, 136 | }, 137 | } 138 | `; 139 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/__snapshots__/propeller4.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/engines/propeller4 offsets list should have required properties 1`] = ` 4 | Object { 5 | "propeller4AutofeatherArmed": Offset { 6 | "category": "engine", 7 | "convert": "!!{VAL}", 8 | "description": "propeller 4 autofeather armed flag", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "propeller4AutofeatherArmed", 12 | "permission": "rw", 13 | "type": 6, 14 | "value": 10032, 15 | }, 16 | "propeller4BetaBladeAngle": Offset { 17 | "category": "engine", 18 | "convert": "+({VAL}).toFixed(4)", 19 | "description": "propeller 4 beta blade angle - rad", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "propeller4BetaBladeAngle", 23 | "permission": "r", 24 | "type": 8, 25 | "value": 10008, 26 | }, 27 | "propeller4DeiceSwitch": Offset { 28 | "category": "engine", 29 | "convert": "!!{VAL}", 30 | "description": "propeller 4 de-ice active", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "propeller4DeiceSwitch", 34 | "permission": "rw", 35 | "type": 6, 36 | "value": 10048, 37 | }, 38 | "propeller4FeatherSwitch": Offset { 39 | "category": "engine", 40 | "convert": "!!{VAL}", 41 | "description": "propeller 4 feather switch", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "propeller4FeatherSwitch", 45 | "permission": "rw", 46 | "type": 6, 47 | "value": 10036, 48 | }, 49 | "propeller4Feathered": Offset { 50 | "category": "engine", 51 | "convert": "!!{VAL}", 52 | "description": "propeller 4 feathered", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "propeller4Feathered", 56 | "permission": "r", 57 | "type": 6, 58 | "value": 10020, 59 | }, 60 | "propeller4FeatheringInhibit": Offset { 61 | "category": "engine", 62 | "convert": "!!{VAL}", 63 | "description": "propeller 4 feathering inhibit", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "propeller4FeatheringInhibit", 67 | "permission": "rw", 68 | "type": 6, 69 | "value": 10016, 70 | }, 71 | "propeller4PanelAutofeatherSwitch": Offset { 72 | "category": "engine", 73 | "convert": "!!{VAL}", 74 | "description": "propeller 4 panel autofeather switch", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "propeller4PanelAutofeatherSwitch", 78 | "permission": "rw", 79 | "type": 6, 80 | "value": 10040, 81 | }, 82 | "propeller4RPM": Offset { 83 | "category": "engine", 84 | "convert": undefined, 85 | "description": "propeller 4 RPM", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "propeller4RPM", 89 | "permission": "r", 90 | "type": 8, 91 | "value": 9984, 92 | }, 93 | "propeller4RPMPercent": Offset { 94 | "category": "engine", 95 | "convert": "Math.round(+(+({VAL}).toFixed(4) * 100).toFixed(2))", 96 | "description": "propeller 4 RPM percent", 97 | "length": undefined, 98 | "mapping": undefined, 99 | "name": "propeller4RPMPercent", 100 | "permission": "r", 101 | "type": 8, 102 | "value": 9992, 103 | }, 104 | "propeller4Sync": Offset { 105 | "category": "engine", 106 | "convert": "!!{VAL}", 107 | "description": "propeller 4 sync active", 108 | "length": undefined, 109 | "mapping": undefined, 110 | "name": "propeller4Sync", 111 | "permission": "rw", 112 | "type": 6, 113 | "value": 10044, 114 | }, 115 | "propeller4SyncDeltaLever": Offset { 116 | "category": "engine", 117 | "convert": undefined, 118 | "description": "propeller 4 sync delta lever", 119 | "length": undefined, 120 | "mapping": undefined, 121 | "name": "propeller4SyncDeltaLever", 122 | "permission": "r", 123 | "type": 8, 124 | "value": 10024, 125 | }, 126 | "propeller4Thrust": Offset { 127 | "category": "engine", 128 | "convert": "+({VAL}).toFixed(2)", 129 | "description": "propeller 4 thrust - lb", 130 | "length": undefined, 131 | "mapping": undefined, 132 | "name": "propeller4Thrust", 133 | "permission": "r", 134 | "type": 8, 135 | "value": 10000, 136 | }, 137 | } 138 | `; 139 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/engine1.spec.ts: -------------------------------------------------------------------------------- 1 | import { engine1 as offsets } from '@offsets/plane/engines/engine1'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/engine1', () => { 5 | const offsetsTestCases = [ 6 | { name: 'engine1ThrottleLever', value: -2048, expectedResult: -50 }, 7 | { name: 'engine1ThrottleLever', value: 0, expectedResult: 0 }, 8 | { name: 'engine1ThrottleLever', value: 8192, expectedResult: 50 }, 9 | { name: 'engine1PropLever', value: -2048, expectedResult: -50 }, 10 | { name: 'engine1PropLever', value: 0, expectedResult: 0 }, 11 | { name: 'engine1PropLever', value: 8192, expectedResult: 50 }, 12 | { name: 'engine1MixtureLever', value: 8192, expectedResult: 50 }, 13 | { name: 'engine1Firing', value: 0, expectedResult: false }, 14 | { name: 'engine1Firing', value: 1, expectedResult: true }, 15 | { name: 'engine1N2', value: 8192, expectedResult: 50 }, 16 | { name: 'engine1N1', value: 8192, expectedResult: 50 }, 17 | { name: 'engine1PropRPM', value: 107374182400, expectedResult: 100 }, 18 | { name: 'engine1FuelFlowLbHourSSL', value: 256, expectedResult: 2 }, 19 | { name: 'engine1AntiIce', value: 0, expectedResult: false }, 20 | { name: 'engine1AntiIce', value: 1, expectedResult: true }, 21 | { name: 'engine1OilTemp', value: 10532, expectedResult: 90 }, 22 | { name: 'engine1OilPres', value: 22342, expectedResult: 75 }, 23 | { name: 'engine1PressureRatio', value: 20480, expectedResult: 2 }, 24 | { name: 'engine1EGT', value: 14281, expectedResult: 750 }, 25 | { name: 'engine1MP', value: 20480, expectedResult: 20 }, 26 | { name: 'engine1OilQuantity', value: 8167, expectedResult: 50 }, 27 | { name: 'engine1Vibration', value: 6553, expectedResult: 2 }, 28 | { name: 'engine1HydPres', value: 64, expectedResult: 16 }, 29 | { name: 'engine1HydQuantity', value: 8192, expectedResult: 50 }, 30 | { name: 'engine1ITT', value: 3276800, expectedResult: 200 }, 31 | { name: 'engine1Torque', value: 8192, expectedResult: 50 }, 32 | { name: 'engine1FuelPres', value: 288, expectedResult: 2 }, 33 | { name: 'engine1TurbineAfterburnerActive', value: 0, expectedResult: false }, 34 | { name: 'engine1TurbineAfterburnerActive', value: 1, expectedResult: true }, 35 | { name: 'engine1TurbineIsFuelAvailable', value: 0, expectedResult: false }, 36 | { name: 'engine1TurbineIsFuelAvailable', value: 1, expectedResult: true }, 37 | { name: 'engine1TurbineReverser', value: 0.02386, expectedResult: 2 }, 38 | { name: 'engine1TurbineIgnition', value: 0, expectedResult: false }, 39 | { name: 'engine1TurbineIgnition', value: 1, expectedResult: true }, 40 | ]; 41 | 42 | describe('offsets list', () => { 43 | it('should have required properties', () => { 44 | expect(offsets).toMatchSnapshot(); 45 | }); 46 | }); 47 | 48 | offsetsTestCases.forEach(testedOffset => { 49 | describe(testedOffset.name, () => { 50 | it('should convert data properly', () => { 51 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 52 | 53 | // tslint:disable-next-line:no-eval 54 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 55 | }); 56 | }); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/engine2.spec.ts: -------------------------------------------------------------------------------- 1 | import { engine2 as offsets } from '@offsets/plane/engines/engine2'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/engine2', () => { 5 | const offsetsTestCases = [ 6 | { name: 'engine2ThrottleLever', value: -2048, expectedResult: -50 }, 7 | { name: 'engine2ThrottleLever', value: 0, expectedResult: 0 }, 8 | { name: 'engine2ThrottleLever', value: 8192, expectedResult: 50 }, 9 | { name: 'engine2PropLever', value: -2048, expectedResult: -50 }, 10 | { name: 'engine2PropLever', value: 0, expectedResult: 0 }, 11 | { name: 'engine2PropLever', value: 8192, expectedResult: 50 }, 12 | { name: 'engine2MixtureLever', value: 8192, expectedResult: 50 }, 13 | { name: 'engine2Firing', value: 0, expectedResult: false }, 14 | { name: 'engine2Firing', value: 1, expectedResult: true }, 15 | { name: 'engine2N2', value: 8192, expectedResult: 50 }, 16 | { name: 'engine2N1', value: 8192, expectedResult: 50 }, 17 | { name: 'engine2PropRPM', value: 107374182400, expectedResult: 100 }, 18 | { name: 'engine2FuelFlowLbHourSSL', value: 256, expectedResult: 2 }, 19 | { name: 'engine2AntiIce', value: 0, expectedResult: false }, 20 | { name: 'engine2AntiIce', value: 1, expectedResult: true }, 21 | { name: 'engine2OilTemp', value: 10532, expectedResult: 90 }, 22 | { name: 'engine2OilPres', value: 22342, expectedResult: 75 }, 23 | { name: 'engine2PressureRatio', value: 20480, expectedResult: 2 }, 24 | { name: 'engine2EGT', value: 14281, expectedResult: 750 }, 25 | { name: 'engine2MP', value: 20480, expectedResult: 20 }, 26 | { name: 'engine2OilQuantity', value: 8167, expectedResult: 50 }, 27 | { name: 'engine2Vibration', value: 6553, expectedResult: 2 }, 28 | { name: 'engine2HydPres', value: 64, expectedResult: 16 }, 29 | { name: 'engine2HydQuantity', value: 8192, expectedResult: 50 }, 30 | { name: 'engine2ITT', value: 3276800, expectedResult: 200 }, 31 | { name: 'engine2Torque', value: 8192, expectedResult: 50 }, 32 | { name: 'engine2FuelPres', value: 288, expectedResult: 2 }, 33 | { name: 'engine2TurbineAfterburnerActive', value: 0, expectedResult: false }, 34 | { name: 'engine2TurbineAfterburnerActive', value: 1, expectedResult: true }, 35 | { name: 'engine2TurbineIsFuelAvailable', value: 0, expectedResult: false }, 36 | { name: 'engine2TurbineIsFuelAvailable', value: 1, expectedResult: true }, 37 | { name: 'engine2TurbineReverser', value: 0.02386, expectedResult: 2 }, 38 | { name: 'engine2TurbineIgnition', value: 0, expectedResult: false }, 39 | { name: 'engine2TurbineIgnition', value: 1, expectedResult: true }, 40 | ]; 41 | 42 | describe('offsets list', () => { 43 | it('should have required properties', () => { 44 | expect(offsets).toMatchSnapshot(); 45 | }); 46 | }); 47 | 48 | offsetsTestCases.forEach(testedOffset => { 49 | describe(testedOffset.name, () => { 50 | it('should convert data properly', () => { 51 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 52 | 53 | // tslint:disable-next-line:no-eval 54 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 55 | }); 56 | }); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/engine3.spec.ts: -------------------------------------------------------------------------------- 1 | import { engine3 as offsets } from '@offsets/plane/engines/engine3'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/engine3', () => { 5 | const offsetsTestCases = [ 6 | { name: 'engine3ThrottleLever', value: -2048, expectedResult: -50 }, 7 | { name: 'engine3ThrottleLever', value: 0, expectedResult: 0 }, 8 | { name: 'engine3ThrottleLever', value: 8192, expectedResult: 50 }, 9 | { name: 'engine3PropLever', value: -2048, expectedResult: -50 }, 10 | { name: 'engine3PropLever', value: 0, expectedResult: 0 }, 11 | { name: 'engine3PropLever', value: 8192, expectedResult: 50 }, 12 | { name: 'engine3MixtureLever', value: 8192, expectedResult: 50 }, 13 | { name: 'engine3Firing', value: 0, expectedResult: false }, 14 | { name: 'engine3Firing', value: 1, expectedResult: true }, 15 | { name: 'engine3N2', value: 8192, expectedResult: 50 }, 16 | { name: 'engine3N1', value: 8192, expectedResult: 50 }, 17 | { name: 'engine3PropRPM', value: 107374182400, expectedResult: 100 }, 18 | { name: 'engine3FuelFlowLbHourSSL', value: 256, expectedResult: 2 }, 19 | { name: 'engine3AntiIce', value: 0, expectedResult: false }, 20 | { name: 'engine3AntiIce', value: 1, expectedResult: true }, 21 | { name: 'engine3OilTemp', value: 10532, expectedResult: 90 }, 22 | { name: 'engine3OilPres', value: 22342, expectedResult: 75 }, 23 | { name: 'engine3PressureRatio', value: 20480, expectedResult: 2 }, 24 | { name: 'engine3EGT', value: 14281, expectedResult: 750 }, 25 | { name: 'engine3MP', value: 20480, expectedResult: 20 }, 26 | { name: 'engine3OilQuantity', value: 8167, expectedResult: 50 }, 27 | { name: 'engine3Vibration', value: 6553, expectedResult: 2 }, 28 | { name: 'engine3HydPres', value: 64, expectedResult: 16 }, 29 | { name: 'engine3HydQuantity', value: 8192, expectedResult: 50 }, 30 | { name: 'engine3ITT', value: 3276800, expectedResult: 200 }, 31 | { name: 'engine3Torque', value: 8192, expectedResult: 50 }, 32 | { name: 'engine3FuelPres', value: 288, expectedResult: 2 }, 33 | { name: 'engine3TurbineAfterburnerActive', value: 0, expectedResult: false }, 34 | { name: 'engine3TurbineAfterburnerActive', value: 1, expectedResult: true }, 35 | { name: 'engine3TurbineIsFuelAvailable', value: 0, expectedResult: false }, 36 | { name: 'engine3TurbineIsFuelAvailable', value: 1, expectedResult: true }, 37 | { name: 'engine3TurbineReverser', value: 0.02386, expectedResult: 2 }, 38 | { name: 'engine3TurbineIgnition', value: 0, expectedResult: false }, 39 | { name: 'engine3TurbineIgnition', value: 1, expectedResult: true }, 40 | ]; 41 | 42 | describe('offsets list', () => { 43 | it('should have required properties', () => { 44 | expect(offsets).toMatchSnapshot(); 45 | }); 46 | }); 47 | 48 | offsetsTestCases.forEach(testedOffset => { 49 | describe(testedOffset.name, () => { 50 | it('should convert data properly', () => { 51 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 52 | 53 | // tslint:disable-next-line:no-eval 54 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 55 | }); 56 | }); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/engine4.spec.ts: -------------------------------------------------------------------------------- 1 | import { engine4 as offsets } from '@offsets/plane/engines/engine4'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/engine4', () => { 5 | const offsetsTestCases = [ 6 | { name: 'engine4ThrottleLever', value: -2048, expectedResult: -50 }, 7 | { name: 'engine4ThrottleLever', value: 0, expectedResult: 0 }, 8 | { name: 'engine4ThrottleLever', value: 8192, expectedResult: 50 }, 9 | { name: 'engine4PropLever', value: -2048, expectedResult: -50 }, 10 | { name: 'engine4PropLever', value: 0, expectedResult: 0 }, 11 | { name: 'engine4PropLever', value: 8192, expectedResult: 50 }, 12 | { name: 'engine4MixtureLever', value: 8192, expectedResult: 50 }, 13 | { name: 'engine4Firing', value: 0, expectedResult: false }, 14 | { name: 'engine4Firing', value: 1, expectedResult: true }, 15 | { name: 'engine4N2', value: 8192, expectedResult: 50 }, 16 | { name: 'engine4N1', value: 8192, expectedResult: 50 }, 17 | { name: 'engine4PropRPM', value: 107374182400, expectedResult: 100 }, 18 | { name: 'engine4FuelFlowLbHourSSL', value: 256, expectedResult: 2 }, 19 | { name: 'engine4AntiIce', value: 0, expectedResult: false }, 20 | { name: 'engine4AntiIce', value: 1, expectedResult: true }, 21 | { name: 'engine4OilTemp', value: 10532, expectedResult: 90 }, 22 | { name: 'engine4OilPres', value: 22342, expectedResult: 75 }, 23 | { name: 'engine4PressureRatio', value: 20480, expectedResult: 2 }, 24 | { name: 'engine4EGT', value: 14281, expectedResult: 750 }, 25 | { name: 'engine4MP', value: 20480, expectedResult: 20 }, 26 | { name: 'engine4OilQuantity', value: 8167, expectedResult: 50 }, 27 | { name: 'engine4Vibration', value: 6553, expectedResult: 2 }, 28 | { name: 'engine4HydPres', value: 64, expectedResult: 16 }, 29 | { name: 'engine4HydQuantity', value: 8192, expectedResult: 50 }, 30 | { name: 'engine4ITT', value: 3276800, expectedResult: 200 }, 31 | { name: 'engine4Torque', value: 8192, expectedResult: 50 }, 32 | { name: 'engine4FuelPres', value: 288, expectedResult: 2 }, 33 | { name: 'engine4TurbineAfterburnerActive', value: 0, expectedResult: false }, 34 | { name: 'engine4TurbineAfterburnerActive', value: 1, expectedResult: true }, 35 | { name: 'engine4TurbineIsFuelAvailable', value: 0, expectedResult: false }, 36 | { name: 'engine4TurbineIsFuelAvailable', value: 1, expectedResult: true }, 37 | { name: 'engine4TurbineReverser', value: 0.02386, expectedResult: 2 }, 38 | { name: 'engine4TurbineIgnition', value: 0, expectedResult: false }, 39 | { name: 'engine4TurbineIgnition', value: 1, expectedResult: true }, 40 | ]; 41 | 42 | describe('offsets list', () => { 43 | it('should have required properties', () => { 44 | expect(offsets).toMatchSnapshot(); 45 | }); 46 | }); 47 | 48 | offsetsTestCases.forEach(testedOffset => { 49 | describe(testedOffset.name, () => { 50 | it('should convert data properly', () => { 51 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 52 | 53 | // tslint:disable-next-line:no-eval 54 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 55 | }); 56 | }); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/propeller1.spec.ts: -------------------------------------------------------------------------------- 1 | import { propeller1 as offsets } from '@offsets/plane/engines/propeller1'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/propeller1', () => { 5 | const offsetsTestCases = [ 6 | { name: 'propeller1RPMPercent', value: 0.02386, expectedResult: 2 }, 7 | { name: 'propeller1Thrust', value: 23.8601932, expectedResult: 23.86 }, 8 | { name: 'propeller1BetaBladeAngle', value: 23.8601932, expectedResult: 23.8602 }, 9 | { name: 'propeller1FeatheringInhibit', value: 0, expectedResult: false }, 10 | { name: 'propeller1FeatheringInhibit', value: 1, expectedResult: true }, 11 | { name: 'propeller1Feathered', value: 0, expectedResult: false }, 12 | { name: 'propeller1Feathered', value: 1, expectedResult: true }, 13 | { name: 'propeller1AutofeatherArmed', value: 0, expectedResult: false }, 14 | { name: 'propeller1AutofeatherArmed', value: 1, expectedResult: true }, 15 | { name: 'propeller1FeatherSwitch', value: 0, expectedResult: false }, 16 | { name: 'propeller1FeatherSwitch', value: 1, expectedResult: true }, 17 | { name: 'propeller1PanelAutofeatherSwitch', value: 0, expectedResult: false }, 18 | { name: 'propeller1PanelAutofeatherSwitch', value: 1, expectedResult: true }, 19 | { name: 'propeller1Sync', value: 0, expectedResult: false }, 20 | { name: 'propeller1Sync', value: 1, expectedResult: true }, 21 | { name: 'propeller1DeiceSwitch', value: 0, expectedResult: false }, 22 | { name: 'propeller1DeiceSwitch', value: 1, expectedResult: true }, 23 | ]; 24 | 25 | describe('offsets list', () => { 26 | it('should have required properties', () => { 27 | expect(offsets).toMatchSnapshot(); 28 | }); 29 | }); 30 | 31 | offsetsTestCases.forEach(testedOffset => { 32 | describe(testedOffset.name, () => { 33 | it('should convert data properly', () => { 34 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 35 | 36 | // tslint:disable-next-line:no-eval 37 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 38 | }); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/propeller2.spec.ts: -------------------------------------------------------------------------------- 1 | import { propeller2 as offsets } from '@offsets/plane/engines/propeller2'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/propeller2', () => { 5 | const offsetsTestCases = [ 6 | { name: 'propeller2RPMPercent', value: 0.02386, expectedResult: 2 }, 7 | { name: 'propeller2Thrust', value: 23.8601932, expectedResult: 23.86 }, 8 | { name: 'propeller2BetaBladeAngle', value: 23.8601932, expectedResult: 23.8602 }, 9 | { name: 'propeller2FeatheringInhibit', value: 0, expectedResult: false }, 10 | { name: 'propeller2FeatheringInhibit', value: 1, expectedResult: true }, 11 | { name: 'propeller2Feathered', value: 0, expectedResult: false }, 12 | { name: 'propeller2Feathered', value: 1, expectedResult: true }, 13 | { name: 'propeller2AutofeatherArmed', value: 0, expectedResult: false }, 14 | { name: 'propeller2AutofeatherArmed', value: 1, expectedResult: true }, 15 | { name: 'propeller2FeatherSwitch', value: 0, expectedResult: false }, 16 | { name: 'propeller2FeatherSwitch', value: 1, expectedResult: true }, 17 | { name: 'propeller2PanelAutofeatherSwitch', value: 0, expectedResult: false }, 18 | { name: 'propeller2PanelAutofeatherSwitch', value: 1, expectedResult: true }, 19 | { name: 'propeller2Sync', value: 0, expectedResult: false }, 20 | { name: 'propeller2Sync', value: 1, expectedResult: true }, 21 | { name: 'propeller2DeiceSwitch', value: 0, expectedResult: false }, 22 | { name: 'propeller2DeiceSwitch', value: 1, expectedResult: true }, 23 | ]; 24 | 25 | describe('offsets list', () => { 26 | it('should have required properties', () => { 27 | expect(offsets).toMatchSnapshot(); 28 | }); 29 | }); 30 | 31 | offsetsTestCases.forEach(testedOffset => { 32 | describe(testedOffset.name, () => { 33 | it('should convert data properly', () => { 34 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 35 | 36 | // tslint:disable-next-line:no-eval 37 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 38 | }); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/propeller3.spec.ts: -------------------------------------------------------------------------------- 1 | import { propeller3 as offsets } from '@offsets/plane/engines/propeller3'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/propeller3', () => { 5 | const offsetsTestCases = [ 6 | { name: 'propeller3RPMPercent', value: 0.02386, expectedResult: 2 }, 7 | { name: 'propeller3Thrust', value: 23.8601932, expectedResult: 23.86 }, 8 | { name: 'propeller3BetaBladeAngle', value: 23.8601932, expectedResult: 23.8602 }, 9 | { name: 'propeller3FeatheringInhibit', value: 0, expectedResult: false }, 10 | { name: 'propeller3FeatheringInhibit', value: 1, expectedResult: true }, 11 | { name: 'propeller3Feathered', value: 0, expectedResult: false }, 12 | { name: 'propeller3Feathered', value: 1, expectedResult: true }, 13 | { name: 'propeller3AutofeatherArmed', value: 0, expectedResult: false }, 14 | { name: 'propeller3AutofeatherArmed', value: 1, expectedResult: true }, 15 | { name: 'propeller3FeatherSwitch', value: 0, expectedResult: false }, 16 | { name: 'propeller3FeatherSwitch', value: 1, expectedResult: true }, 17 | { name: 'propeller3PanelAutofeatherSwitch', value: 0, expectedResult: false }, 18 | { name: 'propeller3PanelAutofeatherSwitch', value: 1, expectedResult: true }, 19 | { name: 'propeller3Sync', value: 0, expectedResult: false }, 20 | { name: 'propeller3Sync', value: 1, expectedResult: true }, 21 | { name: 'propeller3DeiceSwitch', value: 0, expectedResult: false }, 22 | { name: 'propeller3DeiceSwitch', value: 1, expectedResult: true }, 23 | ]; 24 | 25 | describe('offsets list', () => { 26 | it('should have required properties', () => { 27 | expect(offsets).toMatchSnapshot(); 28 | }); 29 | }); 30 | 31 | offsetsTestCases.forEach(testedOffset => { 32 | describe(testedOffset.name, () => { 33 | it('should convert data properly', () => { 34 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 35 | 36 | // tslint:disable-next-line:no-eval 37 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 38 | }); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/offsets/plane/engines/propeller4.spec.ts: -------------------------------------------------------------------------------- 1 | import { propeller4 as offsets } from '@offsets/plane/engines/propeller4'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/engines/propeller4', () => { 5 | const offsetsTestCases = [ 6 | { name: 'propeller4RPMPercent', value: 0.02386, expectedResult: 2 }, 7 | { name: 'propeller4Thrust', value: 23.8601932, expectedResult: 23.86 }, 8 | { name: 'propeller4BetaBladeAngle', value: 23.8601932, expectedResult: 23.8602 }, 9 | { name: 'propeller4FeatheringInhibit', value: 0, expectedResult: false }, 10 | { name: 'propeller4FeatheringInhibit', value: 1, expectedResult: true }, 11 | { name: 'propeller4Feathered', value: 0, expectedResult: false }, 12 | { name: 'propeller4Feathered', value: 1, expectedResult: true }, 13 | { name: 'propeller4AutofeatherArmed', value: 0, expectedResult: false }, 14 | { name: 'propeller4AutofeatherArmed', value: 1, expectedResult: true }, 15 | { name: 'propeller4FeatherSwitch', value: 0, expectedResult: false }, 16 | { name: 'propeller4FeatherSwitch', value: 1, expectedResult: true }, 17 | { name: 'propeller4PanelAutofeatherSwitch', value: 0, expectedResult: false }, 18 | { name: 'propeller4PanelAutofeatherSwitch', value: 1, expectedResult: true }, 19 | { name: 'propeller4Sync', value: 0, expectedResult: false }, 20 | { name: 'propeller4Sync', value: 1, expectedResult: true }, 21 | { name: 'propeller4DeiceSwitch', value: 0, expectedResult: false }, 22 | { name: 'propeller4DeiceSwitch', value: 1, expectedResult: true }, 23 | ]; 24 | 25 | describe('offsets list', () => { 26 | it('should have required properties', () => { 27 | expect(offsets).toMatchSnapshot(); 28 | }); 29 | }); 30 | 31 | offsetsTestCases.forEach(testedOffset => { 32 | describe(testedOffset.name, () => { 33 | it('should convert data properly', () => { 34 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 35 | 36 | // tslint:disable-next-line:no-eval 37 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 38 | }); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /tests/offsets/plane/fuel.spec.ts: -------------------------------------------------------------------------------- 1 | import { fuel as offsets } from '@offsets/plane/fuel'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/fuel', () => { 5 | const offsetsTestCases = [ 6 | { name: 'fuelWeight', value: 512, expectedResult: 2 }, 7 | { name: 'fuelCenterTankLevel', value: 4194304, expectedResult: 50 }, 8 | { name: 'fuelLeftMainTankLevel', value: 4194304, expectedResult: 50 }, 9 | { name: 'fuelLeftAuxTankLevel', value: 4194304, expectedResult: 50 }, 10 | { name: 'fuelLeftTipTankLevel', value: 4194304, expectedResult: 50 }, 11 | { name: 'fuelRightMainTankLevel', value: 4194304, expectedResult: 50 }, 12 | { name: 'fuelRightAuxTankLevel', value: 4194304, expectedResult: 50 }, 13 | { name: 'fuelRightTipTankLevel', value: 4194304, expectedResult: 50 }, 14 | { name: 'fuelCenter2TankLevel', value: 4194304, expectedResult: 50 }, 15 | { name: 'fuelCenter3TankLevel', value: 4194304, expectedResult: 50 }, 16 | { name: 'fuelExternal1TankLevel', value: 4194304, expectedResult: 50 }, 17 | { name: 'fuelExternal2TankLevel', value: 4194304, expectedResult: 50 }, 18 | ]; 19 | 20 | describe('offsets list', () => { 21 | it('should have required properties', () => { 22 | expect(offsets).toMatchSnapshot(); 23 | }); 24 | }); 25 | 26 | offsetsTestCases.forEach(testedOffset => { 27 | describe(testedOffset.name, () => { 28 | it('should convert data properly', () => { 29 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 30 | 31 | // tslint:disable-next-line:no-eval 32 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 33 | }); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /tests/offsets/plane/helicopter.spec.ts: -------------------------------------------------------------------------------- 1 | import { helicopter as offsets } from '@offsets/plane/helicopter'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/helicopter', () => { 5 | const offsetsTestCases = [ 6 | { name: 'rotorBreakApplication', value: 13107, expectedResult: 80 }, 7 | { name: 'rotorLateralTrim', value: 13107, expectedResult: 80 }, 8 | { name: 'governorSwitch', value: 0, expectedResult: false }, 9 | { name: 'governorSwitch', value: 1, expectedResult: true }, 10 | { name: 'helicopterEngine1ElectricalLoad', value: 8192, expectedResult: 50 }, 11 | { name: 'helicopterEngine1TransmOilPres', value: 3276800, expectedResult: 200 }, 12 | { name: 'helicopterEngine1TransmOilTemp', value: 3276800, expectedResult: 200 }, 13 | { name: 'helicopterEngine1RotorRPM', value: 8192, expectedResult: 50 }, 14 | { name: 'helicopterPitchTrim', value: -16000, expectedResult: -98 }, 15 | { name: 'helicopterBankTrim', value: 16383, expectedResult: 100 }, 16 | { name: 'helicopterBankTrim', value: -16383, expectedResult: -100 }, 17 | ]; 18 | 19 | describe('offsets list', () => { 20 | it('should have required properties', () => { 21 | expect(offsets).toMatchSnapshot(); 22 | }); 23 | }); 24 | 25 | offsetsTestCases.forEach(testedOffset => { 26 | describe(testedOffset.name, () => { 27 | it('should convert data properly', () => { 28 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 29 | 30 | // tslint:disable-next-line:no-eval 31 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 32 | }); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/offsets/plane/icing.spec.ts: -------------------------------------------------------------------------------- 1 | import { icing as offsets } from '@offsets/plane/icing'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/icing', () => { 5 | const offsetsTestCases = [ 6 | { name: 'structuralIce', value: 5730, expectedResult: 34.97 }, 7 | { name: 'pitotIce', value: 5730, expectedResult: 34.97 }, 8 | ]; 9 | 10 | describe('offsets list', () => { 11 | it('should have required properties', () => { 12 | expect(offsets).toMatchSnapshot(); 13 | }); 14 | }); 15 | 16 | offsetsTestCases.forEach(testedOffset => { 17 | describe(testedOffset.name, () => { 18 | it('should convert data properly', () => { 19 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 20 | 21 | // tslint:disable-next-line:no-eval 22 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/offsets/plane/plane.spec.ts: -------------------------------------------------------------------------------- 1 | import { plane as offsets } from '@offsets/plane/plane'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/plane', () => { 5 | const offsetsTestCases = [ 6 | { name: 'smokeSystemControl', value: 0, expectedResult: false }, 7 | { name: 'smokeSystemControl', value: 1, expectedResult: true }, 8 | { name: 'retractableGear', value: 0, expectedResult: false }, 9 | { name: 'retractableGear', value: 1, expectedResult: true }, 10 | { name: 'retractableLeftFloatExtension', value: 13200, expectedResult: 80 }, 11 | { name: 'retractableRightFloatExtension', value: 13200, expectedResult: 80 }, 12 | { name: 'hasFlaps', value: 0, expectedResult: false }, 13 | { name: 'hasFlaps', value: 1, expectedResult: true }, 14 | { name: 'hasStallHorn', value: 0, expectedResult: false }, 15 | { name: 'hasStallHorn', value: 1, expectedResult: true }, 16 | { name: 'hasSpoilers', value: 0, expectedResult: false }, 17 | { name: 'hasSpoilers', value: 1, expectedResult: true }, 18 | { name: 'isTailDragger', value: 0, expectedResult: false }, 19 | { name: 'isTailDragger', value: 1, expectedResult: true }, 20 | { name: 'hasStrobes', value: 0, expectedResult: false }, 21 | { name: 'hasStrobes', value: 1, expectedResult: true }, 22 | { name: 'hasToeBrakes', value: 0, expectedResult: false }, 23 | { name: 'hasToeBrakes', value: 1, expectedResult: true }, 24 | { name: 'maxMach', value: 13200, expectedResult: 0.65 }, 25 | { name: 'aircraftEmptyWeight', value: 512060, expectedResult: 2000.23 }, 26 | { name: 'aircraftMaxGrossWeight', value: 512060, expectedResult: 2000.23 }, 27 | ]; 28 | 29 | describe('offsets list', () => { 30 | it('should have required properties', () => { 31 | expect(offsets).toMatchSnapshot(); 32 | }); 33 | }); 34 | 35 | offsetsTestCases.forEach(testedOffset => { 36 | describe(testedOffset.name, () => { 37 | it('should convert data properly', () => { 38 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 39 | 40 | // tslint:disable-next-line:no-eval 41 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 42 | }); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /tests/offsets/plane/pressurisation.spec.ts: -------------------------------------------------------------------------------- 1 | import { pressurisation as offsets } from '@offsets/plane/pressurisation'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/pressurisation', () => { 5 | const offsetsTestCases = [ 6 | { name: 'pressDumpSwitch', value: 0, expectedResult: false }, 7 | { name: 'pressDumpSwitch', value: 1, expectedResult: true }, 8 | ]; 9 | 10 | describe('offsets list', () => { 11 | it('should have required properties', () => { 12 | expect(offsets).toMatchSnapshot(); 13 | }); 14 | }); 15 | 16 | offsetsTestCases.forEach(testedOffset => { 17 | describe(testedOffset.name, () => { 18 | it('should convert data properly', () => { 19 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 20 | 21 | // tslint:disable-next-line:no-eval 22 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios.spec.ts: -------------------------------------------------------------------------------- 1 | import { radios as offsets } from '@offsets/plane/radios'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/radios', () => { 5 | const offsetsTestCases = [ 6 | { name: 'comFreq', value: 13584, expectedResult: 13510 }, 7 | { name: 'transponderFreq', value: 13584, expectedResult: 13510 }, 8 | ]; 9 | 10 | describe('offsets list', () => { 11 | it('should have required properties', () => { 12 | expect(offsets).toMatchSnapshot(); 13 | }); 14 | }); 15 | 16 | offsetsTestCases.forEach(testedOffset => { 17 | describe(testedOffset.name, () => { 18 | it('should convert data properly', () => { 19 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 20 | 21 | // tslint:disable-next-line:no-eval 22 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 23 | }); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/__snapshots__/adf1.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/radios/adf1 offsets list should have required properties 1`] = ` 4 | Object { 5 | "adf1Altitude": Offset { 6 | "category": "radios", 7 | "convert": "+({VAL} * 3.28084).toFixed(2)", 8 | "description": "adf1 altitude - ft", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "adf1Altitude", 12 | "permission": "r", 13 | "type": 3, 14 | "value": 4396, 15 | }, 16 | "adf1BearingToNDB": Offset { 17 | "category": "radios", 18 | "convert": "Math.round({VAL} * 360 / 65536)", 19 | "description": "ADF1 relative bearing to NDB - degrees - -ve left, +ve right", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "adf1BearingToNDB", 23 | "permission": "r", 24 | "type": 2, 25 | "value": 3178, 26 | }, 27 | "adf1DialBearing": Offset { 28 | "category": "radios", 29 | "convert": undefined, 30 | "description": "ADF1 dial bearing - degrees", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "adf1DialBearing", 34 | "permission": "rw", 35 | "type": 5, 36 | "value": 3180, 37 | }, 38 | "adf1Latitude": Offset { 39 | "category": "radios", 40 | "convert": "{VAL} * 90 / 10001750", 41 | "description": "adf1 latitude", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "adf1Latitude", 45 | "permission": "r", 46 | "type": 3, 47 | "value": 4388, 48 | }, 49 | "adf1Longitude": Offset { 50 | "category": "radios", 51 | "convert": "{VAL} * 360 / (65536 * 65536)", 52 | "description": "adf1 longitude", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "adf1Longitude", 56 | "permission": "r", 57 | "type": 3, 58 | "value": 4392, 59 | }, 60 | "adf1SignalStrength": Offset { 61 | "category": "radios", 62 | "convert": undefined, 63 | "description": "ADF1 signal strength", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "adf1SignalStrength", 67 | "permission": "r", 68 | "type": 6, 69 | "value": 3100, 70 | }, 71 | "adfFreq": Offset { 72 | "category": "radios", 73 | "convert": "+({VAL}).toString(16)", 74 | "description": "ADF frequency show as Binary Coded Decimal. The thousands digit and the fractional parts are provided in adfFreqExtended", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "adfFreq", 78 | "permission": "rw", 79 | "type": 5, 80 | "value": 844, 81 | }, 82 | "adfFreqExtended": Offset { 83 | "category": "radios", 84 | "convert": undefined, 85 | "description": "ADF frequency extended", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "adfFreqExtended", 89 | "permission": "rw", 90 | "type": 5, 91 | "value": 854, 92 | }, 93 | } 94 | `; 95 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/__snapshots__/adf2.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/radios/adf2 offsets list should have required properties 1`] = ` 4 | Object { 5 | "adf2Altitude": Offset { 6 | "category": "radios", 7 | "convert": "+({VAL} * 3.28084).toFixed(2)", 8 | "description": "adf2 altitude - ft", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "adf2Altitude", 12 | "permission": "r", 13 | "type": 3, 14 | "value": 4408, 15 | }, 16 | "adf2ExtendedFreq": Offset { 17 | "category": "radios", 18 | "convert": undefined, 19 | "description": "ADF 2 extended freq - in BCD - FS2004", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "adf2ExtendedFreq", 23 | "permission": "rw", 24 | "type": 5, 25 | "value": 726, 26 | }, 27 | "adf2Freq": Offset { 28 | "category": "radios", 29 | "convert": "+({VAL}).toString(16)", 30 | "description": "ADF 2 freq - Main 3 digits in BCD - FS2004", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "adf2Freq", 34 | "permission": "rw", 35 | "type": 5, 36 | "value": 724, 37 | }, 38 | "adf2Latitude": Offset { 39 | "category": "radios", 40 | "convert": "{VAL} * 90 / 10001750", 41 | "description": "adf2 latitude", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "adf2Latitude", 45 | "permission": "r", 46 | "type": 3, 47 | "value": 4400, 48 | }, 49 | "adf2Longitude": Offset { 50 | "category": "radios", 51 | "convert": "{VAL} * 360 / (65536 * 65536)", 52 | "description": "adf2 longitude", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "adf2Longitude", 56 | "permission": "r", 57 | "type": 3, 58 | "value": 4404, 59 | }, 60 | "adf2RelBearing": Offset { 61 | "category": "radios", 62 | "convert": "Math.round({VAL} * 360 / 65536)", 63 | "description": "ADF2 Rel Bearing - FS2004", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "adf2RelBearing", 67 | "permission": "r", 68 | "type": 2, 69 | "value": 728, 70 | }, 71 | "adf2SignalStrength": Offset { 72 | "category": "radios", 73 | "convert": undefined, 74 | "description": "ADF2 signal strength", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "adf2SignalStrength", 78 | "permission": "r", 79 | "type": 6, 80 | "value": 3092, 81 | }, 82 | "ndb2IdentSoundSwitch": Offset { 83 | "category": "radios", 84 | "convert": "!!{VAL}", 85 | "description": "NDB2 ident sound switch - FS2004", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "ndb2IdentSoundSwitch", 89 | "permission": "rw", 90 | "type": 0, 91 | "value": 763, 92 | }, 93 | "ndb2Identity": Offset { 94 | "category": "radios", 95 | "convert": undefined, 96 | "description": "NDB2 identity - FS2004", 97 | "length": 6, 98 | "mapping": undefined, 99 | "name": "ndb2Identity", 100 | "permission": "r", 101 | "type": 11, 102 | "value": 732, 103 | }, 104 | "ndb2Name": Offset { 105 | "category": "radios", 106 | "convert": undefined, 107 | "description": "NDB2 name - FS2004", 108 | "length": 25, 109 | "mapping": undefined, 110 | "name": "ndb2Name", 111 | "permission": "r", 112 | "type": 11, 113 | "value": 738, 114 | }, 115 | } 116 | `; 117 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/__snapshots__/ils.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`offset - plane/radios/ils offsets list should have required properties 1`] = ` 4 | Object { 5 | "innerMarkerAltitude": Offset { 6 | "category": "radios", 7 | "convert": "+({VAL} * 3.28084).toFixed(2)", 8 | "description": "inner marker altitude - ft", 9 | "length": undefined, 10 | "mapping": undefined, 11 | "name": "innerMarkerAltitude", 12 | "permission": "r", 13 | "type": 3, 14 | "value": 4360, 15 | }, 16 | "innerMarkerLatitude": Offset { 17 | "category": "radios", 18 | "convert": "{VAL} * 90 / 10001750", 19 | "description": "inner marker latitude", 20 | "length": undefined, 21 | "mapping": undefined, 22 | "name": "innerMarkerLatitude", 23 | "permission": "r", 24 | "type": 3, 25 | "value": 4352, 26 | }, 27 | "innerMarkerLongitude": Offset { 28 | "category": "radios", 29 | "convert": "{VAL} * 360 / (65536 * 65536)", 30 | "description": "inner marker longitude", 31 | "length": undefined, 32 | "mapping": undefined, 33 | "name": "innerMarkerLongitude", 34 | "permission": "r", 35 | "type": 3, 36 | "value": 4356, 37 | }, 38 | "middleMarkerAltitude": Offset { 39 | "category": "radios", 40 | "convert": "+({VAL} * 3.28084).toFixed(2)", 41 | "description": "middle marker altitude - ft", 42 | "length": undefined, 43 | "mapping": undefined, 44 | "name": "middleMarkerAltitude", 45 | "permission": "r", 46 | "type": 3, 47 | "value": 4372, 48 | }, 49 | "middleMarkerLatitude": Offset { 50 | "category": "radios", 51 | "convert": "{VAL} * 90 / 10001750", 52 | "description": "middle marker latitude", 53 | "length": undefined, 54 | "mapping": undefined, 55 | "name": "middleMarkerLatitude", 56 | "permission": "r", 57 | "type": 3, 58 | "value": 4364, 59 | }, 60 | "middleMarkerLongitude": Offset { 61 | "category": "radios", 62 | "convert": "{VAL} * 360 / (65536 * 65536)", 63 | "description": "middle marker longitude", 64 | "length": undefined, 65 | "mapping": undefined, 66 | "name": "middleMarkerLongitude", 67 | "permission": "r", 68 | "type": 3, 69 | "value": 4368, 70 | }, 71 | "outerMarkerAltitude": Offset { 72 | "category": "radios", 73 | "convert": "+({VAL} * 3.28084).toFixed(2)", 74 | "description": "outer marker altitude - ft", 75 | "length": undefined, 76 | "mapping": undefined, 77 | "name": "outerMarkerAltitude", 78 | "permission": "r", 79 | "type": 3, 80 | "value": 4384, 81 | }, 82 | "outerMarkerLatitude": Offset { 83 | "category": "radios", 84 | "convert": "{VAL} * 90 / 10001750", 85 | "description": "outer marker latitude", 86 | "length": undefined, 87 | "mapping": undefined, 88 | "name": "outerMarkerLatitude", 89 | "permission": "r", 90 | "type": 3, 91 | "value": 4376, 92 | }, 93 | "outerMarkerLongitude": Offset { 94 | "category": "radios", 95 | "convert": "{VAL} * 360 / (65536 * 65536)", 96 | "description": "outer marker longitude", 97 | "length": undefined, 98 | "mapping": undefined, 99 | "name": "outerMarkerLongitude", 100 | "permission": "r", 101 | "type": 3, 102 | "value": 4380, 103 | }, 104 | } 105 | `; 106 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/adf1.spec.ts: -------------------------------------------------------------------------------- 1 | import { ADF1 as offsets } from '@offsets/plane/radios/adf1'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/radios/adf1', () => { 5 | const offsetsTestCases = [ 6 | { name: 'adfFreq', value: 74528, expectedResult: 12320 }, 7 | { name: 'adf1BearingToNDB', value: 9102, expectedResult: 50 }, 8 | { name: 'adf1Latitude', value: 5198687, expectedResult: 46.77999650061239 }, 9 | { name: 'adf1Longitude', value: -851715875, expectedResult: -71.38999993912876 }, 10 | { name: 'adf1Altitude', value: 92, expectedResult: 301.84 }, 11 | ]; 12 | 13 | describe('offsets list', () => { 14 | it('should have required properties', () => { 15 | expect(offsets).toMatchSnapshot(); 16 | }); 17 | }); 18 | 19 | offsetsTestCases.forEach(testedOffset => { 20 | describe(testedOffset.name, () => { 21 | it('should convert data properly', () => { 22 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 23 | 24 | // tslint:disable-next-line:no-eval 25 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 26 | }); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/adf2.spec.ts: -------------------------------------------------------------------------------- 1 | import { ADF2 as offsets } from '@offsets/plane/radios/adf2'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/radios/adf2', () => { 5 | const offsetsTestCases = [ 6 | { name: 'adf2Freq', value: 74528, expectedResult: 12320 }, 7 | { name: 'adf2RelBearing', value: 38229, expectedResult: 210 }, 8 | { name: 'ndb2IdentSoundSwitch', value: 0, expectedResult: false }, 9 | { name: 'ndb2IdentSoundSwitch', value: 1, expectedResult: true }, 10 | { name: 'adf2Latitude', value: 5198687, expectedResult: 46.77999650061239 }, 11 | { name: 'adf2Longitude', value: -851715875, expectedResult: -71.38999993912876 }, 12 | { name: 'adf2Altitude', value: 92, expectedResult: 301.84 }, 13 | ]; 14 | 15 | describe('offsets list', () => { 16 | it('should have required properties', () => { 17 | expect(offsets).toMatchSnapshot(); 18 | }); 19 | }); 20 | 21 | offsetsTestCases.forEach(testedOffset => { 22 | describe(testedOffset.name, () => { 23 | it('should convert data properly', () => { 24 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 25 | 26 | // tslint:disable-next-line:no-eval 27 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 28 | }); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/ils.spec.ts: -------------------------------------------------------------------------------- 1 | import { ILS as offsets } from '@offsets/plane/radios/ils'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/radios/ils', () => { 5 | const offsetsTestCases = [ 6 | { name: 'innerMarkerLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 7 | { name: 'innerMarkerLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 8 | { name: 'innerMarkerAltitude', value: 92, expectedResult: 301.84 }, 9 | { name: 'middleMarkerLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 10 | { name: 'middleMarkerLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 11 | { name: 'middleMarkerAltitude', value: 92, expectedResult: 301.84 }, 12 | { name: 'outerMarkerLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 13 | { name: 'outerMarkerLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 14 | { name: 'outerMarkerAltitude', value: 92, expectedResult: 301.84 }, 15 | ]; 16 | 17 | describe('offsets list', () => { 18 | it('should have required properties', () => { 19 | expect(offsets).toMatchSnapshot(); 20 | }); 21 | }); 22 | 23 | offsetsTestCases.forEach(testedOffset => { 24 | describe(testedOffset.name, () => { 25 | it('should convert data properly', () => { 26 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 27 | 28 | // tslint:disable-next-line:no-eval 29 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 30 | }); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/nav1.spec.ts: -------------------------------------------------------------------------------- 1 | import { NAV1 as offsets } from '@offsets/plane/radios/nav1'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/radios/nav1', () => { 5 | const offsetsTestCases = [ 6 | { name: 'vor1DMEDistance', value: 250, expectedResult: 25 }, 7 | { name: 'vor1DMESpeed', value: 350, expectedResult: 35 }, 8 | { name: 'vor1DMETimeToStation', value: 450, expectedResult: 45 }, 9 | { name: 'nav1Freq', value: 13584, expectedResult: 13510 }, 10 | { name: 'hasNav1', value: 0, expectedResult: false }, 11 | { name: 'hasNav1', value: 1, expectedResult: true }, 12 | { name: 'vor1OrILSGlideSlopeLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 13 | { name: 'vor1OrILSGlideSlopeLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 14 | { name: 'vor1OrILSGlideSlopeElevation', value: 92, expectedResult: 301.84 }, 15 | { name: 'vor1ILSLocHeadingTrue', value: 27346, expectedResult: 150.22 }, 16 | { name: 'vor1GlideSlopeAngle', value: 27346, expectedResult: 150.22 }, 17 | { name: 'vor1LocLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 18 | { name: 'vor1LocLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 19 | { name: 'vor1LocElevation', value: 92, expectedResult: 301.84 }, 20 | { name: 'vor1DmeLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 21 | { name: 'vor1DmeLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 22 | { name: 'vor1DmeElevation', value: 92, expectedResult: 301.84 }, 23 | { name: 'dme1Distance', value: '92.5', expectedResult: 92.5 }, 24 | { name: 'dme1Distance', value: '92.5 ', expectedResult: 92.5 }, 25 | { name: 'dme1Distance', value: '92.50', expectedResult: 92.5 }, 26 | { name: 'dme1Distance', value: '112.5', expectedResult: 112.5 }, 27 | { name: 'dme1Distance', value: '112.0', expectedResult: 112 }, 28 | { name: 'dme1Distance', value: '112. ', expectedResult: 112 }, 29 | { name: 'dme1Speed', value: '92.5', expectedResult: 92.5 }, 30 | { name: 'dme1Speed', value: '92.5 ', expectedResult: 92.5 }, 31 | { name: 'dme1Speed', value: '92.50', expectedResult: 92.5 }, 32 | { name: 'dme1Speed', value: '112.5', expectedResult: 112.5 }, 33 | { name: 'dme1Speed', value: '112.0', expectedResult: 112 }, 34 | { name: 'dme1Speed', value: '112. ', expectedResult: 112 }, 35 | { name: 'nav1MagVar', value: 9102, expectedResult: 50 }, 36 | { name: 'nav1LocNeedlePosition', value: 127, expectedResult: 100 }, 37 | { name: 'nav1LocNeedlePosition', value: -127, expectedResult: -100 }, 38 | { name: 'nav1GlideslopeNeedlePosition', value: 127, expectedResult: 100 }, 39 | { name: 'nav1GlideslopeNeedlePosition', value: -127, expectedResult: -100 }, 40 | { name: 'nav1GlideslopeActive', value: 0, expectedResult: false }, 41 | { name: 'nav1GlideslopeActive', value: 1, expectedResult: true }, 42 | { name: 'nav1Radial', value: 9102, expectedResult: 50 }, 43 | ]; 44 | 45 | describe('offsets list', () => { 46 | it('should have required properties', () => { 47 | expect(offsets).toMatchSnapshot(); 48 | }); 49 | }); 50 | 51 | offsetsTestCases.forEach(testedOffset => { 52 | describe(testedOffset.name, () => { 53 | it('should convert data properly', () => { 54 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 55 | 56 | // tslint:disable-next-line:no-eval 57 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 58 | }); 59 | }); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /tests/offsets/plane/radios/nav2.spec.ts: -------------------------------------------------------------------------------- 1 | import { NAV2 as offsets } from '@offsets/plane/radios/nav2'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/radios/nav2', () => { 5 | const offsetsTestCases = [ 6 | { name: 'vor2DMEDistance', value: 550, expectedResult: 55 }, 7 | { name: 'vor2DMESpeed', value: 650, expectedResult: 65 }, 8 | { name: 'vor2DMETimeToStation', value: 750, expectedResult: 75 }, 9 | { name: 'nav2Freq', value: 13584, expectedResult: 13510 }, 10 | { name: 'hasNav2', value: 0, expectedResult: false }, 11 | { name: 'hasNav2', value: 1, expectedResult: true }, 12 | { name: 'vor2DmeLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 13 | { name: 'vor2DmeLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 14 | { name: 'vor2DmeElevation', value: 92, expectedResult: 301.84 }, 15 | { name: 'vor2ILSLocHeadingTrue', value: 27346, expectedResult: 150.22 }, 16 | { name: 'vor2ILSGlideSlopeAngle', value: 27346, expectedResult: 150.22 }, 17 | { name: 'vor2LocLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 18 | { name: 'vor2LocLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 19 | { name: 'vor2LocElevation', value: 92, expectedResult: 301.84 }, 20 | { name: 'vor2OrILSGlideSlopeLatitude', value: 5198687, expectedResult: 46.77999650061239 }, 21 | { name: 'vor2OrILSGlideSlopeLongitude', value: -851715875, expectedResult: -71.38999993912876 }, 22 | { name: 'vor2OrILSGlideSlopeElevation', value: 92, expectedResult: 301.84 }, 23 | { name: 'dme2Distance', value: '92.5', expectedResult: 92.5 }, 24 | { name: 'dme2Distance', value: '92.5 ', expectedResult: 92.5 }, 25 | { name: 'dme2Distance', value: '92.50', expectedResult: 92.5 }, 26 | { name: 'dme2Distance', value: '112.5', expectedResult: 112.5 }, 27 | { name: 'dme2Distance', value: '112.0', expectedResult: 112 }, 28 | { name: 'dme2Distance', value: '112. ', expectedResult: 112 }, 29 | { name: 'dme2Speed', value: '92.5', expectedResult: 92.5 }, 30 | { name: 'dme2Speed', value: '92.5 ', expectedResult: 92.5 }, 31 | { name: 'dme2Speed', value: '92.50', expectedResult: 92.5 }, 32 | { name: 'dme2Speed', value: '112.5', expectedResult: 112.5 }, 33 | { name: 'dme2Speed', value: '112.0', expectedResult: 112 }, 34 | { name: 'dme2Speed', value: '112. ', expectedResult: 112 }, 35 | { name: 'nav2MagVar', value: 9102, expectedResult: 50 }, 36 | { name: 'nav2LocNeedlePosition', value: 127, expectedResult: 100 }, 37 | { name: 'nav2LocNeedlePosition', value: -127, expectedResult: -100 }, 38 | { name: 'nav2Radial', value: 9102, expectedResult: 50 }, 39 | { name: 'nav2GlideslopeNeedlePosition', value: 127, expectedResult: 100 }, 40 | { name: 'nav2GlideslopeNeedlePosition', value: -127, expectedResult: -100 }, 41 | { name: 'nav2GlideslopeActive', value: 0, expectedResult: false }, 42 | { name: 'nav2GlideslopeActive', value: 1, expectedResult: true }, 43 | ]; 44 | 45 | describe('offsets list', () => { 46 | it('should have required properties', () => { 47 | expect(offsets).toMatchSnapshot(); 48 | }); 49 | }); 50 | 51 | offsetsTestCases.forEach(testedOffset => { 52 | describe(testedOffset.name, () => { 53 | it('should convert data properly', () => { 54 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 55 | 56 | // tslint:disable-next-line:no-eval 57 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 58 | }); 59 | }); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /tests/offsets/position-attitude/position-attitude.spec.ts: -------------------------------------------------------------------------------- 1 | import { positionAttitude as offsets } from '@offsets/position-attitude/position-attitude'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - position-attitude/position-attitude', () => { 5 | const offsetsTestCases = [ 6 | { name: 'groundElevation', value: 18726, expectedResult: 240 }, 7 | { name: 'magVar', value: 38229, expectedResult: 210.00 }, 8 | { name: 'gs', value: 674292, expectedResult: 19 }, 9 | { name: 'tas', value: 257, expectedResult: 2 }, 10 | { name: 'ias', value: 520, expectedResult: 4 }, 11 | { name: 'bpa', value: 390, expectedResult: 3 }, 12 | { name: 'vs', value: 14, expectedResult: 10 }, 13 | { name: 'vsAtTouchdown', value: 13, expectedResult: 9 }, 14 | { name: 'planeOnground', value: 0, expectedResult: false }, 15 | { name: 'planeOnground', value: 1, expectedResult: true }, 16 | { name: 'latitude', value: 2.2329449e+16, expectedResult: 46.78263288720104 }, 17 | { name: 'longitude', value: -3.6582626e+18, expectedResult: -71.39333265196446 }, 18 | { name: 'altitude', value: 392731796979, expectedResult: 300 }, 19 | { name: 'pitch', value: -238609294, expectedResult: -20 }, 20 | { name: 'bank', value: -238609294, expectedResult: -20 }, 21 | { name: 'heading', value: -238609294, expectedResult: -20 }, 22 | { name: 'viewpointLatitude', value: 2.2329449e+16, expectedResult: 46.78263288720104 }, 23 | { name: 'viewpointLongitude', value: -3.6582626e+18, expectedResult: -71.39333265196446 }, 24 | { name: 'viewpointAltitude', value: 392731796979, expectedResult: 300 }, 25 | { name: 'viewpointPitch', value: -238609294, expectedResult: -20 }, 26 | { name: 'viewpointBank', value: -238609294, expectedResult: -20 }, 27 | { name: 'viewpointHeading', value: 2147483648, expectedResult: 180 }, 28 | { name: 'verticalSpeed', value: -46, expectedResult: 150.92 }, 29 | { name: 'gForceTouchDown', value: 1250, expectedResult: 2 }, 30 | { name: 'gForceAlt', value: 1250, expectedResult: 2 }, 31 | { name: 'angleOfAttack', value: 25456, expectedResult: 22.31 }, 32 | { name: 'machSpeed', value: 61440, expectedResult: 3 }, 33 | ]; 34 | 35 | describe('offsets list', () => { 36 | it('should have required properties', () => { 37 | expect(offsets).toMatchSnapshot(); 38 | }); 39 | }); 40 | 41 | offsetsTestCases.forEach(testedOffset => { 42 | describe(testedOffset.name, () => { 43 | it('should convert data properly', () => { 44 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 45 | 46 | // tslint:disable-next-line:no-eval 47 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 48 | }); 49 | }); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /tests/offsets/simulation/simulation.spec.ts: -------------------------------------------------------------------------------- 1 | import { simulation as offsets } from '@offsets/simulation/simulation'; 2 | import { replaceOffsetExpressionValue } from '@convert/apply-conversion'; 3 | 4 | describe('offset - plane/simulation', () => { 5 | const offsetsTestCases = [ 6 | { name: 'cloudComplex', value: 0, expectedResult: false }, 7 | { name: 'cloudComplex', value: 1, expectedResult: true }, 8 | { name: 'pauseFlag', value: 0, expectedResult: false }, 9 | { name: 'pauseFlag', value: 1, expectedResult: true }, 10 | { name: 'framerate', value: 354, expectedResult: 92 }, 11 | { name: 'zoomfactor', value: 128, expectedResult: 2 }, 12 | { name: 'fuelBoxFlag', value: 0, expectedResult: false }, 13 | { name: 'fuelBoxFlag', value: 1, expectedResult: true }, 14 | { name: 'comFreqInc', value: 0, expectedResult: 50 }, 15 | { name: 'comFreqInc', value: 1, expectedResult: 25 }, 16 | { name: 'adfFreqInc', value: 0, expectedResult: 1.0 }, 17 | { name: 'adfFreqInc', value: 1, expectedResult: 0.1 }, 18 | { name: 'smokeSystemAvailable', value: 0, expectedResult: false }, 19 | { name: 'smokeSystemAvailable', value: 1, expectedResult: true }, 20 | { name: 'slewMode', value: 0, expectedResult: false }, 21 | { name: 'slewMode', value: 1, expectedResult: true }, 22 | { name: 'replayInAction', value: 0, expectedResult: false }, 23 | { name: 'replayInAction', value: 1, expectedResult: true }, 24 | { name: 'videoRecording', value: 0, expectedResult: false }, 25 | { name: 'videoRecording', value: 1, expectedResult: true }, 26 | { name: 'crashed', value: 0, expectedResult: false }, 27 | { name: 'crashed', value: 1, expectedResult: true }, 28 | { name: 'soundControl', value: 0, expectedResult: false }, 29 | { name: 'soundControl', value: 1, expectedResult: true }, 30 | { name: 'soundActive', value: 0, expectedResult: false }, 31 | { name: 'soundActive', value: 1, expectedResult: true }, 32 | { name: 'internationalUnit', value: 0, expectedResult: 'us' }, 33 | { name: 'internationalUnit', value: 1, expectedResult: 'metric_feet' }, 34 | { name: 'internationalUnit', value: 2, expectedResult: 'metric_meters' }, 35 | { name: 'simulationRate', value: 512, expectedResult: 2 }, 36 | { name: 'simulationRate', value: 384, expectedResult: 1.5 }, 37 | { name: 'groundSceneryShadows', value: 0, expectedResult: false }, 38 | { name: 'groundSceneryShadows', value: 1, expectedResult: true }, 39 | { name: 'groundSceneryShadows', value: 2, expectedResult: false }, 40 | { name: 'aircraftShadows', value: 0, expectedResult: false }, 41 | { name: 'aircraftShadows', value: 1, expectedResult: true }, 42 | { name: 'aircraftReflections', value: 0, expectedResult: false }, 43 | { name: 'aircraftReflections', value: 1, expectedResult: false }, 44 | { name: 'aircraftReflections', value: 2, expectedResult: true }, 45 | { name: 'unlimitedFuel', value: 0, expectedResult: false }, 46 | { name: 'unlimitedFuel', value: 1, expectedResult: true }, 47 | ]; 48 | 49 | describe('offsets list', () => { 50 | it('should have required properties', () => { 51 | expect(offsets).toMatchSnapshot(); 52 | }); 53 | }); 54 | 55 | offsetsTestCases.forEach(testedOffset => { 56 | describe(testedOffset.name, () => { 57 | it('should convert data properly', () => { 58 | const convertExpression = replaceOffsetExpressionValue(offsets[testedOffset.name], testedOffset.value); 59 | 60 | // tslint:disable-next-line:no-eval 61 | expect(eval(convertExpression)).toEqual(testedOffset.expectedResult); 62 | }); 63 | }); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /tests/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "include": [ 4 | "**/*.spec.ts", 5 | "**/*.d.ts" 6 | ], 7 | "exclude": [ 8 | "node_modules" 9 | ], 10 | "compilerOptions": { 11 | "outDir": "../dist/spec", 12 | "module": "commonjs", 13 | "baseUrl": "./", 14 | "allowJs": true, 15 | "types": [ 16 | "jest", 17 | "node" 18 | ], 19 | "paths": { 20 | "@shared": ["../src/shared/index"], 21 | "@shared/*": ["../src/shared/*"], 22 | "@offsets": ["../src/lib/offsets/index"], 23 | "@offsets/*": ["../src/lib/offsets/*"], 24 | "@mappings": ["../src/lib/convert/mappings/index"], 25 | "@mappings/*": ["../src/lib/convert/mappings/*"], 26 | "@convert": ["../src/lib/convert/index"], 27 | "@convert/*": ["../src/lib/convert/*"] 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "outDir": "./dist", 5 | "baseUrl": "./", 6 | "allowJs": true, 7 | "sourceMap": true, 8 | "strict": true, 9 | "strictNullChecks": false, 10 | "moduleResolution": "node", 11 | "resolveJsonModule": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "experimentalDecorators": true, 15 | "emitDecoratorMetadata": true, 16 | "noImplicitAny": false, 17 | "target": "es2017", 18 | "typeRoots": [ 19 | "node_modules/@types" 20 | ], 21 | "types": [ 22 | "jest", 23 | "node" 24 | ], 25 | "lib": [ 26 | "es2019" 27 | ], 28 | "paths": { 29 | "@shared": ["src/shared/index"], 30 | "@shared/*": ["src/shared/*"], 31 | "@offsets": ["src/lib/offsets/index"], 32 | "@offsets/*": ["src/lib/offsets/*"], 33 | "@mappings": ["src/lib/convert/mappings/index"], 34 | "@mappings/*": ["src/lib/convert/mappings/*"], 35 | "@convert": ["src/lib/convert/index"], 36 | "@convert/*": ["src/lib/convert/*"] 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "arrow-parens": false, 9 | "curly": [ 10 | true, 11 | "ignore-same-line" 12 | ], 13 | "interface-name": false, 14 | "linebreak-style": false, 15 | "max-line-length": false, 16 | "no-consecutive-blank-lines": false, 17 | "no-require-imports": false, 18 | "no-string-literal": false, 19 | "object-literal-sort-keys": false, 20 | "one-variable-per-declaration": false, 21 | "only-arrow-functions": false, 22 | "ordered-imports": false, 23 | "prefer-const": false, 24 | "quotemark": [ 25 | true, 26 | "single" 27 | ], 28 | "semicolon": true, 29 | "space-before-function-paren": false, 30 | "trailing-comma": false, 31 | "variable-name": [ 32 | true, 33 | "check-format", 34 | "allow-leading-underscore", 35 | "allow-trailing-underscore", 36 | "allow-pascal-case" 37 | ] 38 | }, 39 | "rulesDirectory": [] 40 | } 41 | --------------------------------------------------------------------------------