Skip to content

Commit

Permalink
Initial commit of PDK
Browse files Browse the repository at this point in the history
  • Loading branch information
nabeelio committed Sep 10, 2024
0 parents commit 430f42a
Show file tree
Hide file tree
Showing 18 changed files with 2,329 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Hold some settings that are used by the build

# This is the profile name to use when exporting
ACARS_PROFILE_NAME=

# This is the path to the configuration root
ACARS_CONFIG_PATH=$HOME/Documents/vmsacars

# This is the path to where the scripts, etc are stored
# It's used in the live-watch
ACARS_SCRIPTS_PATH=$HOME/Documents/vmsacars/data/$ACARS_PROFILE_NAME/config

# Name of the distribution zip file that's created
ACARS_DIST_ZIP=dist.zip
68 changes: 68 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.env
node_modules/
.node_modules/
built/*
dist/
tests/cases/rwc/*
tests/cases/perf/*
!tests/cases/webharness/compilerToString.js
test-args.txt
~*.docx
\#*\#
.\#*
tests/baselines/local/*
tests/baselines/local.old/*
tests/services/baselines/local/*
tests/baselines/prototyping/local/*
tests/baselines/rwc/*
tests/baselines/reference/projectOutput/*
tests/baselines/local/projectOutput/*
tests/baselines/reference/testresults.tap
tests/baselines/symlinks/*
tests/services/baselines/prototyping/local/*
tests/services/browser/typescriptServices.js
src/harness/*.js
src/compiler/diagnosticInformationMap.generated.ts
src/compiler/diagnosticMessages.generated.json
src/parser/diagnosticInformationMap.generated.ts
src/parser/diagnosticMessages.generated.json
rwc-report.html
*.swp
build.json
*.actual
tests/webTestServer.js
tests/webTestServer.js.map
tests/webhost/*.d.ts
tests/webhost/webtsc.js
tests/cases/**/*.js
tests/cases/**/*.js.map
*.config
scripts/eslint/built/
scripts/debug.bat
scripts/run.bat
scripts/**/*.js
scripts/**/*.js.map
coverage/
internal/
**/.DS_Store
.settings
**/.vs
**/.vscode/*
!**/.vscode/tasks.json
!**/.vscode/settings.template.json
!**/.vscode/launch.template.json
!**/.vscode/extensions.json
!tests/cases/projects/projectOption/**/node_modules
!tests/cases/projects/NodeModulesSearch/**/*
!tests/baselines/reference/project/nodeModules*/**/*
.idea
yarn.lock
yarn-error.log
.parallelperf.*
tests/baselines/reference/dt
.failed-tests
TEST-results.xml
package-lock.json
.eslintcache
*v8.log
/lib/
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
This file explains how Visual Studio created the project.

The following tools were used to generate this project:
- TypeScript Compiler (tsc)

The following steps were used to generate this project:
- Create project file (`Content.Source.esproj`).
- Create `launch.json` to enable debugging.
- Create `nuget.config` to specify location of the JavaScript Project System SDK (which is used in the first line in `Content.Source.esproj`).
- Install npm packages and create `tsconfig.json`: `npm init && npm i --save-dev eslint typescript @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser && npx tsc --init --sourceMap true`.
- Create `app.ts`.
- Update `package.json` entry point.
- Update TypeScript build scripts in `package.json`.
- Create `.eslintrc.json` to enable linting.
- Add project to solution.
- Write this file.
288 changes: 288 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
# vmsACARS Plugin Development Kit (PDK)

## Overview

The plugins and scripts for vmsACARS are written in Typescript, and then transpiled to JS.
Typescript ensures that the interfaces required are following, and that the proper things
are returned so ACARS can run them. While Typescript isn't required, it's best to use it to
ensure proper values are passed - especially around enums.

---

# Setup

## Required:

- nodejs/npm
- Typescript
- Gulp

Run:

```shell
npm install
```

### Customizing using the `.env` file:

Next, copy the `.env.default` to `.env`. Then edit this file to change the profile name.

The available options:

- `ACARS_PROFILE_NAME` - The default profile to use for testing
- `ACARS_CONFIG_PATH` - The default usually works, but you can change this to the path where you put ACARS, if you did a
local install
- `ACARS_SCRIPTS_PATH` - Uses the `ACARS_PROFILE_NAME` to build the path to where the scripts should be sent after a
build
- `ACARS_DIST_ZIP` - The distribution filename

---

### Commands

Then there are multiple commands you can use:

#### To run a build:

This creates a `dist` directory, with all of the JS files in it

```shell
npm run build
```

This doesn't copy it anywhere, just runs a compile and build

### Create a distribution file

This creates a `dist.zip` (you can rename it in the `.env` file) after running a compile.
You can modify the `gulpfile.mjs` to include other files in the `dist/` directory - this
directory is simply zipped and placed into the `dist/` directory. You can then configure
Github Actions to then upload this zip somewhere for ACARS to download.

#### Automatically build and copy to ACARS

This will setup a watch, and then automatically transpile and then copy the contents of the `dist` folder
into the `ACARS_PROFILE_PATH` directory that's defined in the `.env` file.

```shell
npm run dev
```

It's recommended to run this *after* you've started ACARS, or, in the ACARS configuration, disable the
remote-download of configs:

> TODO: Guide on how to disable remote config downloading

---

# Development Documentation

There are several core files/interfaces that are included:

### `src/global.d.ts`

This describes the globally available functions, including the logging methods available through `console` and
`Acars`.

### `src/types.d.ts`

This contains all of the base types:

- `Pirep` - data that's available about a PIREP, and it's associated interfaces (`Airport`, `Runway`, etc)
- `Telemetry` - telemetry information that's come out of the simulator
- `User` - information about the current user

It also includes other detailed type information, for example `Length`, so you can retrieve that type of information.

## Aircraft Rules:

Aircraft rules are required to inherit the `AircraftConfig` abstract class. An example class would look like:

```typescript
import { AircraftConfigSimType, AircraftFeature, FeatureType } from '../defs'
// Additional mports are left out for now

export default class FenixA320 extends AircraftConfig {
meta: Meta = {
id: 'fenix_a320',
name: 'Fenix A320',
sim: AircraftConfigSimType.MsFs,
enabled: true,
priority: 2,
}

features: FeatureAddresses = {
// Aircraft feature
[AircraftFeature.BeaconLights]: {
'lvar name': FeatureType.Int,
},
}

flapNames: FlapNames = {
0: 'UP',
1: 'CONF 1',
2: 'CONF 1+F',
3: 'CONF 2',
4: 'CONF 3',
5: 'FULL',
}

match(title: string, icao: string, config_path: string): boolean {
// Check the aircraft title and return true/false if this matches
}

beaconLights(lvar_value: number): FeatureState {
// Check the lvar_value if the
}
}
```

The configuration is a class which has a few different components.

1. `meta`, which gives some general information about the configuration:
- `name` - a name for this script
- `sim` - The simulator it's for
- `AircraftConfigSimType.XPlane`
- `AircraftConfigSimType.Fsuipc`
- `AircraftConfigSimType.MsFs`
- `enabled`
- `priority` - from 1 (lowest) to 10 (highest). If there are multiple rules which match this, then which one takes
priority. All the built-in rules are at a priority 1, and aircraft specifics rules are priority 2. I recommend
using a priority of 3 or higher. More on this below

2. `features` - this is the type `FeatureAddresses` - see `defs.ts` for the definitions
- MSFS - the lookups you enter are LVars
- X-Plane - the looks ups are via datarefs
- FSUIPC - the lookups are offsets
3. `match()`
- This needs to return a boolean
- A method (`match()`) which passes some information about the starting aircraft
- For MSFS, it's the aircraft ICAO
- For FSX/P3d, the value looked at is the aircraft title field, offset `0x3D00`
- For X-Plane, the value looked at is `sim/aircraft/view/acf_descrip`
- This method can be used to determine if this rule should match
4. Methods for the different features (see below)
- The maps - a group of datarefs or offsets which constitute that feature being "on" or "enabled"

In the above example, for the Fenix A320, the landing lights are controlled by two datarefs, both of which the
values need to be 1 or 2 for the landing lights to be considered "on".

### Features

Features are essentially stored in a dictionary of dictionaries, of type `FeatureAddresses`:

```typescript
features: FeatureAddresses = {
// Aircraft feature
[AircraftFeature.BeaconLights]: {
'lvar name': FeatureType.Int,
},
}
```

In the above example:

- `AircraftFeature.BeaconLights` is an enum value of the feature type. It's put in `[]` because it's a variable name
- It's set to an object, where the keys are the lookup address or lvar.
- `FeatureType.Int` - is the type of value that's returned.

The different features available are:

- beaconLights
- landingLights
- logoLights
- navigationLights
- strobeLights
- taxiLights
- wingLights
- flaps

The different features contain how to look up the value, and the type. You can have multiple variables to be
read and looked at for a feature. Each feature then corresponds to a method which is called to return if
that feature is on or off. That method will have the equivalent number of arguments for each data reference

Example:

```typescript

export default class Example extends AircraftConfig {
features: FeatureAddresses = {
// Aircraft feature
[AircraftFeature.BeaconLights]: {
'sample/dataref/1': FeatureType.Bool,
'sample/dataref/2': FeatureType.Bool,
},
}

beaconLights(dataref_1: boolean, dataref_2: boolean): FeatureState {
if (dataref_1 && dataref_2) {
return true;
}

return false;
}
}
```

### Ignoring Features

To ignore a feature in the rules (for example, if a feature doesn't work properly), set the feature to false:

```typescript
import { AircraftFeature } from './defs'

features: FeatureAddresses = {
// Aircraft feature
[AircraftFeature.BeaconLights]: {
'lvar name': FeatureType.Int,
},
[AircraftFeature.LandingLights]: false,
}
```

### Mixed priorities

If there are two scripts which match a particular aircraft, and a feature is omitted, it will use the lower priority
one in place. For example:

```typescript
import { FeatureAddresses } from './aircraft'

export default class Example extends AircraftConfig {
meta: Meta = {
// ...
priority: 1
}

features: FeatureAddresses = {
[AircraftFeature.BeaconLights]: {
'sample/dataref/1': FeatureType.Bool,
'sample/dataref/2': FeatureType.Bool,
},
[AircraftFeature.LandingLights]: {
'sample/landing/light/1': FeatureType.Bool,
'sample/landing/light/2': FeatureType.Bool,
},
}
}

export default class ExampleOverride {
meta: Meta = {
// ...
priority: 10
}

features: FeatureAddresses = {
[AircraftFeature.LandingLights]: {
'override/landing/light/1': FeatureType.Bool,
'override/landing/light/2': FeatureType.Bool,
},
}
}
```

In this case, the lookups used for the rules will be:

- beaconLights - `sample/dataref/1|2`
- landingLights - `override/landing/light/1|2`
Loading

0 comments on commit 430f42a

Please sign in to comment.