Giter Club home page Giter Club logo

node-simconnect's People

Contributors

aaronrobertson222 avatar calyhre avatar crazyfluffypony avatar dependabot[bot] avatar evenar avatar flighttlv avatar knokbak avatar pomax avatar robsonmi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-simconnect's Issues

64bit (P3Dv4) compat?

Hey, this looks awesome! I'm guessing it won't work with the P3D v4? I'm just starting to mess with this library, did you have any ideas (for the future) on how to handle cross-compatibility?

Uncaught Error: node-loader

BRAZILIAN PORTUGUESE
Eu instalei a biblioteca, instalei as dependências descritas na sessão "build", porém não está funcionando devido a um erro no arquivo de pré build (bin/win_ia32/node_simconnect.node).

UNITED STATES ENGLISH
I installed the library, installed the dependencies described in the "build" section, but it is not working due to an error in the pre build file (bin / win_ia32 / node_simconnect.node).

Translated by Google Translator

Captura de tela 2021-04-02 203247

Having some issues with `unSubscribeToFacilitiesEx1`

I'm using the (idiotically named, thanks MS!) node-simconnect equivalent of the SimConnect_SubscribeToFacilities_EX1 call, and can successfully register for "nearby" airport updates, but if I want to do this as a one-time affair, unsubscribing after the initial response, using the equivalent unsubscribe function, SimConnect throws up an exception. Any idea what I'm doing wrong here?

const SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT = 0;
const type = SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT;
const NEW_EVENT_ID = 1;
const OLD_EVENT_ID = -1;
  
handle.on("airportList", (recvAirportList) => {
  console.log(recvAirportList);
  // we got our data, unsubscribe again, with both "new" and "old" set to unsubscribe:
  const packetId = handle.unSubscribeToFacilitiesEx1(type, true, true);
  // this will cause a simconnect exception, with the `sendId` number as the packet we just sent
  console.log(`unsubscribe sendId: ${packetId}`);
});

handle.subscribeToFacilitiesEx1(type, NEW_EVENT_ID, OLD_EVENT_ID);

Running this with a plane sitting at NTMN, I get the following output:

RecvAirportList {
  requestID: 1,
  arraySize: 4,
  entryNumber: 0,
  outOf: 1,
  aiports: [
    FacilityAirport {
      icao: 'NTMU',
      latitude: -8.936111256480217,
      longitude: -139.5550002157688,
      altitude: 45.415000915527344
    },
    FacilityAirport {
      icao: 'NTMD',
      latitude: -8.793333247303963,
      longitude: -140.2230553328991,
      altitude: 64.00800323486328
    },
    FacilityAirport {
      icao: 'NTMN',
      latitude: -9.768055714666843,
      longitude: -139.01111125946045,
      altitude: 453.8470153808594
    },
    FacilityAirport {
      icao: 'NTMP',
      latitude: -9.350555464625359,
      longitude: -140.07805556058884,
      altitude: 22.860000610351562
    }
  ]
}
unsubscribe sendId: 4
RecvException { exception: 1, sendId: 4, index: 1 }

Looking at the code for this function in https://github.com/EvenAR/node-simconnect/blob/master/src/SimConnectConnection.ts#L1289-L1301 it looks like there's a magic number 0x48 for indicating that this is an unsubscribe, is that the correct number? Is there a list in the SimConnect docs to verify this is the correct number?

Is it possible to read pmdg CDU screen data?

by doing this, i can get swicth values in pmdg 737

.then(({ recvOpen, handle }) => {
    console.log('Connected:', recvOpen);
    handle.addToDataDefinition(
      DefinitionID.LIVE_DATA,
      'L:switch_573_73X', // A key in CDU
      'bool',
      SimConnectDataType.STRING32,
      0,
      Tag.CDU_KEY 
    );

so how can i get the screen data? or is it possible? (example c++ code block from pmdg sdk document)

HRESULT hr;
if (SUCCEEDED(SimConnect_Open(&hSimConnect, "PMDG NG3 CDU Test", NULL, 0,0, 0)))
// Associate an ID with the PMDG data area name
hr = SimConnect_MapClientDataNameToID (hSimConnect,PMDG_NG3_CDU_0_NAME, PMDG_NG3_CDU_0_ID);
// Define the data area structure - this is a required step
hr = SimConnect_AddToClientDataDefinition (hSimConnect,PMDG_NG3_CDU_0_DEFINITION, 0,sizeof(PMDG_NG3_CDU_Screen), 0, 0);
// Sign up for notification of data change.
// SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED flag asks for the data
// to be sent only when some of the data is changed.
hr = SimConnect_RequestClientData(
  hSimConnect, 
  PMDG_NG3_CDU_0_ID,
  CDU_DATA_REQUEST, PMDG_NG3_CDU_0_DEFINITION,
  SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET,
  SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED, 0, 0, 0
);

plane data not correct

The plane data I get back is not correct, the lat/long don't match where I am at or based on GPS coordinates. The head and altitude are off as well. I am close this airport KSAN. "latitude_deg":"32.7336006165","longitude_deg":"-117.190002441"

node v15
electron v12

but I get the following. not even close.

{
'PLANE LATITUDE': 0.5713108235067251,
'PLANE LONGITUDE': -2.045507739457583,
'PLANE ALTITUDE': 5.963584736748746,
'PLANE HEADING DEGREES MAGNETIC': 2.393217942901961
}

And here is my test code:

    var success = simConnect.open("FlyMap", 
        (name, version) => {
            console.log("Connected to: " + name + "\nSimConnect version: " + version);
            // Safe to start interacting with SimConnect here (request data, etc)

            var navInfoDefId = simConnect.createDataDefinition([
                ["PLANE LATITUDE", "Degrees"],
                ["PLANE LONGITUDE", "Degrees"],
                ["PLANE ALTITUDE", "Feet"],
                ["PLANE HEADING DEGREES MAGNETIC", "Degrees"]
            ]);

            setInterval(() => {
                simConnect.requestDataOnSimObjectType(navInfoDefId, (data) => {
                    console.log(data);
                }, 0, 
                    simConnect.simobjectType.USER,
                    simConnect.period.SIM_FRAME,
                    simConnect.dataRequestFlag.CHANGED
                )
            },100)

        }, () => {
            console.log("Simulator exited by user");
        }, (exception) => {
            console.log("SimConnect exception: " + exception.name + " (" + exception.dwException + ", " + exception.dwSendID + ", " + exception.dwIndex + ", " + exception.cbData + ")");
        }, (error) => {
            console.log("Undexpected disconnect/error: " + error); // Look up error code in ntstatus.h for details
    });

Pressing the cdu buttons.

First of all, thank you for your help here. However, now I'm facing another issue. It's quite easy to interact with switches like landing lights because they only take a value of 1 or 0. But buttons don't work like that. When I press a button, its value becomes 100, and when I release it, it becomes 0. I can do this with my node app, but it only creates a pressing animation. There's no change on the screen.

const enum DefinitionID {
    CDU_A,
    LIVE_DATA
}

const dataToSet = new RawBuffer(0);
   dataToSet.clear();
   dataToSet.writeInt32(100);
   handle.setDataOnSimObject(DefinitionID.CDU_A, SimConnectConstants.OBJECT_ID_USER, {
     buffer: dataToSet,
     arrayCount: 0,
     tagged: false
   });

"%1 is not a valid win32 application" on require after successful compile?

Hi Even,

I'm getting a

Error: %1 is not a valid win32 application ...\node-simconnect\build\Release\node-simconnect.node

at the require('../../build/Release/node-simconnect');
after comiling it via node-gyp configure rebuild --msvs_version=2015 --arch=ia32 when i run node .\examples\nodejs\example.js

Did i probably miss anything on installation or build? I'm using the MS c++ 2015 standalone build tools for building the node file.

node-gyp configure shows:

<pre>
[email protected]
[email protected] | win32 | x64
C:\Python27\python.exe
[ 'C:\\Users\\me\\AppData\\Roaming\\npm\\node_modules\\node-gyp\\gyp\\gyp_main.py',
'binding.gyp',
'-f',
'msvs',
'-G',
'msvs_version=2015',
'-I',
'C:\\Users\\me\\GitHub\\node-simconnect\\build\\config.gypi',
'-I',
'C:\\Users\\me\\AppData\\Roaming\\npm\\node_modules\\node-gyp\\addon.gypi',
'-I',
'C:\\Users\\me\\.node-gyp\\8.2.1\\include\\node\\common.gypi',
'-Dlibrary=shared_library',
'-Dvisibility=default',
'-Dnode_root_dir=C:\\Users\\me\\.node-gyp\\8.2.1',
'-Dnode_gyp_dir=C:\\Users\\me\\AppData\\Roaming\\npm\\node_modules\\node-gyp',
'-Dnode_lib_file=C:\\Users\\me\\.node-gyp\\8.2.1\\<(target_arch)\\node.lib',
'-Dmodule_root_dir=C:\\Users\\me\\GitHub\\node-simconnect',
'-Dnode_engine=v8',
'--depth=.',
'--no-parallel',
'--generator-output',
'C:\\Users\\me\\GitHub\\node-simconnect\\build',
'-Goutput_dir=.' ]</pre>```

Any suggestions?

Busy-loop caused by subscribeToFacilitiesEx1

First of all, huge thanks for this project, everything has worked remarkably well.

I do have issues with subscribeToFacilitiesEx1 though. It usually works fine for all types except for waypoints (waypoints always fail, the others fail like 5-10% of the time). Although, if I add the "subscription" while in the world wap, I do get a small number of waypoints (<10), which is wierd in it self, because that doesn't happen for the other types.

I'm on the "current" version of MSFS 2020 Premium, steam install, all updates/packages installed, running over network. I've had this issue running the code below on a Mac, and in a docker-container on a Mac, and in a docker-container running on a linux server.

Example code (place in existing samples dir)

import { Protocol, open, FacilityListType } from '../../src';

const enum REQUEST_ID {
    NEW_WAYPOINTS = 42,
    OLD_WAYPOINTS = 43,
}

open('SimConnect sample client', Protocol.KittyHawk, {
    remote: {
        host: 'games.my-domain.se',
        port: 5151,
    }
})
    .then(({ recvOpen, handle }) => {
        console.log('Connected to sim!');

        handle.subscribeToFacilitiesEx1(
            FacilityListType.WAYPOINT,
            REQUEST_ID.NEW_WAYPOINTS,
            REQUEST_ID.OLD_WAYPOINTS
        );

        handle.on('waypointList', recvWaypointList => {
            switch (recvWaypointList.requestID) {
                case REQUEST_ID.NEW_WAYPOINTS:
                    console.log('These waypoints appeared', recvWaypointList.waypoints);
                    break;
                case REQUEST_ID.OLD_WAYPOINTS:
                    console.log('These waypoints disappeared', recvWaypointList.waypoints);
                    break;
            }
        });

        handle.on('exception', exception => {
            console.log(exception);
        });
    })
    .catch(error => {
        console.log('Failed to connect', error);
    });

I tracked the issue to here: https://github.com/EvenAR/node-simconnect/blob/master/src/SimConnectSocket.ts#L107

Changing that to:

            // Read message body
            const body: Buffer = this._socket.read(bodyLength);

            console.log(lenBuf, bodyLength, body)
            if (body === null) {
                throw new Error("STOP");
            }

            if (!body) {
                // Put header back in read buffer
                this._socket.unshift(lenBuf);
                return;
            }

Provides me with:

<Buffer 34 01 00 00> 304 <Buffer 05 00 00 00 02 00 00 00 4b 69 74 74 79 48 61 77 6b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 254 more bytes>
Connected to sim!
<Buffer 65 a0 00 00> 41057 null
/path-to-my/node-simconnect/src/SimConnectSocket.ts:110
                throw new Error("STOP");

Notice the "null", that cause the while to turn into a busy-loop, completely locking up the node process.

Any idea what's going on here? Is this just me? Can it be because I'm running over network?

Btw, this expamle was tested with the current master (2efbe09) but I have the same issue with the latest release.

Thanks again for all your work!

Missing HKCU registry value

When starting 3.0.1-3.0.4 version I am getting this error:
Zrzut ekranu 2022-09-28 233517

It still connects to sim (MSFS Steam in this case) but why would it need to check SimConnect port in registry?

Post NZ World Update 11 - FaclityDataRequest issue crashes sim

Hi @EvenAR - i'm having an issue retrieving core MSFS navdata after the recent World Update. I've logged a ticket with Asobo but as yet no answer - https://devsupport.flightsimulator.com/questions/14922/simconnect-nav-data-api-sim-freeze-with-default-ms.html

I just wondered if you could think of anything in the node-simconnect client that could be causing this - over just the navdata being wrong. Its the FIX_LATITUDE and FIX_LONGITUDE from APPROACH_LEG that for some airports now causes the sim to completely freeze and all simconnect calls to stop (for all addons).

EDIT: t actually seems to be a volume issue rather than airport specific - i have code that can cause it repeatedly. 330 sets of airport facility data requested. With Core MSFS nav data - always crashes (freezes for ever) after 276. With the only difference being Navigraph in the community - successfully processes and returns data for all 330.

I suspect it isn't node-simconnect - but if you did have any ideas that would be great :-)

Reading TITLE value crashes electron app

A simple read of TITLE value often crashes simconnect node module (according to Event Viewer).

Since removal of TITLE from array of retrieved values problems are gone. Any suggestions as to how I should debug actual cause of error and attempt a fix? I am moderately familiar with simconnect and C++ so I might be able to fix this. Just not sure how to setup debugging to break on problem. Instructions would be gold.

Not a real issue, just a heck of a lot of appreciation.

Hey @EvenAR, just wanted to say thank you again, your project allowed me to play around with MSFS so much more than I would have even imagined possible, culminating in this: https://www.youtube.com/watch?v=0aV6WtY6zJE

(though the "real" culmination is probably this ~35k work tutorial that explains how the plane in the video's doing all the things it's doing ;)

But yeah, that's a fully pure JS autopilot with auto-takeoff and auto-landing.

I have no idea how I would have ever gotten to this if it weren't for node-simconnect. Do you have a donation link or patreon or something? Because yeah "thanks are nice" but you know what's even nicer? Money. And I have a donation to make =)

Inconsistent increment/decrement when sending input events

.... I'm running the webpage on an iPad and can control the keypad and autopilot without moving the view. I'm struggling a with knobs still. Considering these events aren't documented, it's hard to know exactly what to send. AS1000_ControlPad_1_Heading sometimes makes it increment and sometimes decrements which seems strange. I can probably use a different sim connect event for changing the heading bug, but some of the other FMS knobs might not be so easy.

Originally posted by @bstudtma in Pomax/msfs-simconnect-api-wrapper#29 (reply in thread)

It looks like open() logs a registry key on failure

When running the following code, the library seems to log the MSFS Windows registry key to the console:

import { open, Protocol } from "node-simconnect";
try {
    await open("My app", Protocol.KittyHawk);
} catch (e) {
    // ignore the error
}

Logs:

D:\temp>node test.js
{"HKCU\\Software\\Microsoft\\Microsoft Games\\Flight Simulator": "

D:\temp>

When MSFS isn't running, or loading in.

When MSFS is fully loaded, that console log does not occur.

node-simconnect Does not compile for Electron

Hello,

I cloned the master branch and was able to successfully compile node-simconnect as a 64bit module against the P3D V5 SDK. I tested it and it worked perfectly!

I then tried to rebuild node-simconnect for Electron and ran into a slew of errors.
nodejs version = 12.6.2
electron version = 8.2.4

Admittedly, this is my venture into node js and electron so I may be making a newbie mistake. I used the following command: .\node_modules.bin\electron-rebuild

Log is here:
https://pastebin.com/Mf77u5PJ

Thanks!

Multibyte chars in Paths - Size Mismatch

Hi Even,

not sure if this is actually an overal simconnect issue or with the node implementation - but keen for your thoughts.

We pass paths for flight plans to the aICreateEnrouteATCAircraft and aISetAircraftFlightPlan functions. We store these in the users profile and we are finding for users that have usernames with non default chars like C:\Users\Øystein - then we get a size mismatch exception.

There are some claims it worked previously for these users when we were using a pure c++ implementation.

Thanks :-)

"Title" causes a node-simconnect crash

It looks like there might be some lingering problems with the TITLE simvar, despite fixes in #34:

I tried to pull PLANE LATITUDE, PLANE LATITUDE, and TITLE, by extending the aircraftPosition.mjs sample, and that seems to error out in v3.3.0 when it tries to read the title:

import {
  open,
  Protocol,
  SimConnectDataType,
  SimConnectPeriod,
  SimConnectConstants,
} from "node-simconnect";

const POSITION_DATA = 1;
const REQUEST_ID_POSITION_DATA = 1;
const EVENT_ID_PAUSE = 1;

open("My app", Protocol.FSX_SP2)
  .then(function ({ recvOpen, handle }) {
    console.log("Connected to", recvOpen.applicationName);

    handle.addToDataDefinition(
      POSITION_DATA,
      "Plane Latitude",
      "degrees",
      SimConnectDataType.FLOAT64,
      0.0,
      SimConnectConstants.UNUSED
    );
    handle.addToDataDefinition(
      POSITION_DATA,
      "Plane Longitude",
      "degrees",
      SimConnectDataType.FLOAT64,
      0.0,
      SimConnectConstants.UNUSED
    );


    // -----------------added-----------------------
    handle.addToDataDefinition(
      POSITION_DATA,
      "Title",
      "string",
      SimConnectDataType.STRING128,
      0.0,
      SimConnectConstants.UNUSED
    );
    // ----------------------------------------------

    handle.requestDataOnSimObject(
      REQUEST_ID_POSITION_DATA,
      POSITION_DATA,
      SimConnectConstants.OBJECT_ID_USER,
      SimConnectPeriod.SECOND,
      0,
      0,
      0,
      0
    );
    handle.subscribeToSystemEvent(EVENT_ID_PAUSE, "Pause");

    handle.on("event", function (recvEvent) {
      switch (recvEvent.eventID) {
        case EVENT_ID_PAUSE:
          console.log(recvEvent.data === 1 ? "Sim paused" : "Sim unpaused");
          break;
      }
    });

    handle.on("simObjectData", function (recvSimObjectData) {
      switch (recvSimObjectData.requestID) {
        case POSITION_DATA:
          console.log({
            latitude: recvSimObjectData.data.readFloat64(),
            longitude: recvSimObjectData.data.readFloat64(),

            // -----------------added-----------------------
            title:  recvSimObjectData.data.readString128(),
            // ----------------------------------------------

          });
          break;
      }
    });
    handle.on("quit", function () {
      console.log("Quit");
    });
  })
  .catch(function (error) {
    console.log("Connection failed:", error);
  });

This yields the following error in the console:

d:\temp>node repro.js
Connected to KittyHawk
d:\temp\node_modules\bytebuffer\dist\bytebuffer-node.js:1861
                throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.length);
                ^

RangeError: Illegal offset: 0 <= 44 (+1) <= 44
    at ByteBuffer.module.exports.ByteBufferPrototype.readCString (d:\temp\node_modules\bytebuffer\dist\bytebuffer-node.js:1861:23)
    at makeString (d:\temp\node_modules\node-simconnect\dist\RawBuffer.js:150:24)
    at RawBuffer.readString128 (d:\temp\node_modules\node-simconnect\dist\RawBuffer.js:105:16)
    at SimConnectConnection.<anonymous> (file:///d:/temp/repro.js:69:44)
    at SimConnectConnection.emit (node:events:513:28)
    at SimConnectConnection.emit (d:\temp\node_modules\node-simconnect\dist\SimConnectConnection.js:78:22)
    at SimConnectConnection._handleMessage (d:\temp\node_modules\node-simconnect\dist\SimConnectConnection.js:1031:22)
    at SimConnectSocket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)

Just to double check I tried this with uppercase simvar names, too, but that has the same result.

add .once and .off to SimConnectConnection?

Currently the SimConnectConnection explicitly supports .on and .emit, but to prevent "dead" event handlers from hanging around it would be good to also add wrappers for the .off and maybe .once EventEmitter functions.

They technically work right now, but it might be nicer to have the code make that explicit?

Doesn't "reconnect" if you restart the sim whilst code is running

So if you run your code that connects to the sim.

var success = simConnect.open("SomeName", (name, version) => {

  • Open the sim
  • it connects
  • Close the sim (safe quit as apposed to CTD)
  • it disconnects
  • Open the sim

It "connects" but the .open callback doesn't fire, but var success is true

It's a new issue in MSFS 1.12.13.0. I fed in the latest SDK (0.9.0.0) but it didn't help

Not sure if it's a new MSFS bug or something with node-simconnect? I'm trying to poke about and see if I can find out what's occurring but wanted to open this issue.

I am using westlakem modification for the Electron Compile. But I anticipate it's MSFS at fault here. As it didn't do this until todays update.

If you taskill MSFS, you get a an abnormal disconnect and it will reconnect (call the open callback) fine.

Pre todays update or if you taskkill today, code generates a SimConnect error: 0xC000014B

Basically any "normal" close of MSFS results in not being able to reconnect to the sim, without restarting the node process.

Issues when sim not running or shut down normally

NodeSimconnect: v3.0.1
Platform: Windows
Node: v18.9.0
Electron: v20.2.0
Simulator: Technically none but MSFS.

If I do not start the simulator
if I run the following code:

    try {
        console.log('Trying simconnect');
        // simulator time
        //import { open, Protocol } from 'node-simconnect';
        let simconnect = require('node-simconnect');

        let { SimConnectConstants, SimConnectPeriod, SimObjectType } = simconnect;

        console.log('Required simconnect');

        console.log('opening');
        simconnect.open('FlightSimTrack', simconnect.Protocol.FSX_SP2)
            .then(({ recvOpen, handle }) => {
                handle.on('quit', function () {
                    console.log('Simulator quit');
                });

                handle.subscribeToSystemEvent(1, 'Pause');
                handle.subscribeToSystemEvent(2, 'Paused');
                handle.subscribeToSystemEvent(3, 'FlightLoaded');
                handle.subscribeToSystemEvent(4, 'FlightSaved');
                handle.subscribeToSystemEvent(5, 'FlightPlanActivated');
                handle.subscribeToSystemEvent(6, 'FlightPlanDeactivated');
                handle.subscribeToSystemEvent(7, 'View');

                handle.on('event', function (recvEvent) {
                    console.log('event', recvEvent);
                    switch (recvEvent.clientEventId) {
                        case 1:
                        case 2:
                            console.log(recvEvent.data === 1 ? 'Sim paused' : 'Sim unpaused');
                            break;
                        case 3:
                        case 4:
                            console.log('Flight Loaded/Saved');
                            break;
                        case 5:
                        case 6:
                            console.log('Flight Plan');
                            break;
                        case 7:
                            console.log('view');
                            break;
                    }
                });
            })
            .catch(err => {
                console.log('Sim Connection Failed', err);
            });
    } catch (e) {
        console.log('Sim Connection Bad Failed', e);
    }

The result is

image

And console.log('Sim Connection Bad Failed', e); doesn't trigger.

or if caught by BugSnag

[bugsnag] Event not sent due to releaseStage/enabledReleaseStages configuration
[bugsnag] Uncaught exception, the process will now terminate
Error: connect EADDRNOTAVAIL 127.0.0.1 - Local (0.0.0.0:64249)
    at internalConnect (node:net:953:16)
    at defaultTriggerAsyncIdScope (node:internal/async_hooks:465:18)
    at GetAddrInfoReqWrap.emitLookup [as callback] (node:net:1097:9)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:73:8)

And the electron app CTD's

I just can't "catch" the error.

In a similar vein on normal sim shutdown: where I have a timer function calling requestDataOnSimObjectType somewhere. the following occurs:

Simulator quit
[bugsnag] Event not sent due to releaseStage/enabledReleaseStages configuration
[bugsnag] Uncaught exception, the process will now terminate
Error: read EPIPE
    at Pipe.onStreamRead (node:internal/stream_base_commons:217:20)

And the electron app CTD's

In my testing my simconnect app has caused the sim to CTD and the app doesn't error/CTD (but doesn't reconnect and pick back up, but thats handle just being weird all over the place. but I need to test

However in a test just now that caused a CTD of the sim

event RecvEvent { groupID: -1, clientEventId: 7, data: 0 }
view
states { twitch: 1, sim: 0, discord: 0 }
Connecting to twitch socket
Them
Connected to socket
states { twitch: 2, sim: 0, discord: 0 }
Them
Them
Them
Them
[bugsnag] Event not sent due to releaseStage/enabledReleaseStages configuration
[bugsnag] Uncaught exception, the process will now terminate
Error: This socket has been ended by the other party
    at Socket.writeAfterFIN [as write] (node:net:487:14)
    at SimConnectSocket._write (E:\Work\FlightSim\electron\node_modules\node-simconnect\dist\SimConnectSocket.js:110:22)
    at writeOrBuffer (node:internal/streams/writable:389:12)
    at _write (node:internal/streams/writable:330:10)
    at Writable.write (node:internal/streams/writable:334:10)
    at SimConnectConnection.sendPacket (E:\Work\FlightSim\electron\node_modules\node-simconnect\dist\SimConnectConnection.js:156:27)
    at SimConnectConnection.requestDataOnSimObjectType (E:\Work\FlightSim\electron\node_modules\node-simconnect\dist\SimConnectConnection.js:226:14)
    at them (E:\Work\FlightSim\electron\app\modules\app.js:188:16)
    at Timeout._onTimeout (E:\Work\FlightSim\electron\app\modules\app.js:195:13)
PS E:\Work\FlightSim\electron>

And the app CTD's to desktop with an uncatchable.

I'm off to try and add a process uncuaght to prevent my app ctd's. but it's odd my try/catch isn't catching (or the code examples catch in the then/catch loop), and it's backing up to a uncuaght

Additional notes:

This is similar to #25

Possible deadlock in DispatchWorker

The DispatchWorker, which is a subclass of Nan::AsyncWorker (runs on a separate thread), some times stops receiving data. Not very often - it happens like 1 out of 50 times after I start example.js

The DispatchWorker has an infinite loop where it reads data from the active connection (if any) and notifies the main thread once it receieves something interesting (data or an NT_ERROR). The main thread is notified using uv_async_send (libuv), which later at some time wakes up the messageReceiver which extracts the data received from SimConnect. A SimConnect dispatch contains pointers and data which only lives until the next dispatch is loaded. Therefore, after DispatcWorker has notified the main thread, it must wait for the main thread to signal that it has finished reading the data before it proceeds with receiving dispatces.

It looks like the while(true)-loop stops running, as VS no longer stops if I set a breakpoint in the loop.

I'm not too experienced with multithreading, so if anyone have an idea of what is wrong, I'll be very thankful! I suspect there is a deadlock which is caused by uv_cond_signal(&cv) not being called. Some possible reasons I can think of:

  • Something wrong is going on in the extraction of the dispatch data (messageReceiver). The strange thing is, there are no errors or exceptions that I can see. I am running the debug-version of Node.JS through Visual Studio.
  • The mutex and condition variable is used incorrectly.
  • The V8 SDK is used incorrectly, which causes a break before uv_cond_signal(&cv) is called. Still, I have no indication from Visual Studio about any errors.

I have pasted a short version of the code below. Full code here


class DispatchWorker : public Nan::AsyncWorker {
public:
	DispatchWorker(Nan::Callback *callback) : AsyncWorker(callback) {

	}
	~DispatchWorker() {}

	void Execute() {
		uv_async_init(loop, &async, messageReceiver); // Must be called from worker thread

		while (true) {

			if (ghSimConnect) {
				SIMCONNECT_RECV* pData;
				DWORD cbData;

				HRESULT hr = SimConnect_GetNextDispatch(ghSimConnect, &pData, &cbData);

				if (SUCCEEDED(hr))
				{
					CallbackData data;
					data.pData = pData;
					data.cbData = cbData;
					data.ntstatus = STATUS_SUCCESS;
					async.data = &data;
					uv_mutex_lock(&mutex);
					uv_async_send(&async);
				
					// Wait for main thread to process the dispatch 
					uv_cond_wait(&cv, &mutex);
				}
				else if (NT_ERROR(hr)) {
					CallbackData data;
					data.ntstatus = (NTSTATUS)hr;
					async.data = &data;
					uv_mutex_lock(&mutex);
					uv_async_send(&async);

					// Wait for main thread to process the dispatch 
					uv_cond_wait(&cv, &mutex);
				}
			}
			else {
				Sleep(10);
			}
		}
	}
};

Runs on main thread (some time) after uv_async_send() is called

void messageReceiver(uv_async_t* handle) {

	Nan::HandleScope scope;
	v8::Isolate* isolate = v8::Isolate::GetCurrent();

	CallbackData* data = (CallbackData*)handle->data;

	// ..... extract data ....

	// The dispatch-worker can now continue
	uv_mutex_unlock(&mutex);
	uv_cond_signal(&cv);
}

Can't compile with FSX SDK

I've tried over the course of the last 12 months to try and compile manually with the FSX SDK but I have never been able to make any progress. Whenever I run npm run rebuild I get the following output:

c:\node-simconnect\src\addon.h(59): error C2065: 'SIMCONNECT_EXCEPTION_ALREADY_CREA TED': undeclared identifier (compiling source file ..\src\addon.cc) [C:\node-simcon nect\build\node-simconnect.vcxproj]
c:\node-simconnect\src\addon.h(60): error C2065: 'SIMCONNECT_EXCEPTION_OBJECT_OUTSI DE_REALITY_BUBBLE': undeclared identifier (compiling source file ..\src\addon.cc) [C:\node-simconnect\build\node-simconnect.vcxproj]
c:\node-simconnect\src\addon.h(61): error C2065: 'SIMCONNECT_EXCEPTION_OBJECT_CONTA INER': undeclared identifier (compiling source file ..\src\addon.cc) [C:\node-simco nnect\build\node-simconnect.vcxproj]
c:\node-simconnect\src\addon.h(62): error C2065: 'SIMCONNECT_EXCEPTION_OBJECT_AI':
undeclared identifier (compiling source file ..\src\addon.cc) [C:\node-simconnect\b uild\node-simconnect.vcxproj]
c:\node-simconnect\src\addon.h(63): error C2065: 'SIMCONNECT_EXCEPTION_OBJECT_ATC':  undeclared identifier (compiling source file ..\src\addon.cc) [C:\node-simconnect\ build\node-simconnect.vcxproj]
c:\node-simconnect\src\addon.h(64): error C2065: 'SIMCONNECT_EXCEPTION_OBJECT_SCHED ULE': undeclared identifier (compiling source file ..\src\addon.cc) [C:\node-simcon nect\build\node-simconnect.vcxproj]

This appears to be because the addon.h file contains exception variables that are specific to P3D and are therefore not present in the FSX Simconnect SDK. Has anyone managed to get this successfully compiling with the FSX SDK?

SimConnect licence

Hi,

Sorry for asking like this, I'll close the issue immediately, but just to know, as this is the first time I see this:

What is the deal with the SimConnect licence, I can't figure this out. For example, if I make an app, I cannot ship the simconnect.dll with it, or it's just that I cannot leave it in the npm or Github? How do you make an app then?
Because I just made a version for MSFS, with the automatic build and can ship it as an npm package, but now reading the readme, I'm kind of worried.

How to call transmitClientEvent

I'm trying to send events into MSFS, and looking at the docs over on https://docs.flightsimulator.com/html/Programming_Tools/SimConnect/API_Reference/Events_And_Data/SimConnect_TransmitClientEvent.htm paired with the code over in https://github.com/EvenAR/node-simconnect/blob/master/src/SimConnectConnection.ts#L384-L400 I wrote the following code to trigger the tail wheel lock:

    handle.transmitClientEvent(
      SimConnectConstants.OBJECT_ID_USER, // object id
      0x00010000 + 1005, // event id
      0, // event does not use data, so any value will do
      0, // group id
      0 // flags
    );

(using the KEY_TOGGLE_TAILWHEEL_LOCK event id found in the SDK's WASM\include\MSFS\Legacy\gauges.h file)

Unfortunately, that seems to throw an exception (RecvException { exception: 1, sendId: 4, index: 2 }) but I'm not quite sure what I need to fix to make this work, and I don't see any of the examples trying to send events into the sim to use as reference.

Cannot Rebuild

Hello,
I have tried to build the node-simconnect module. I got this error:

gyp: Call to 'node -e "require('nan')"' returned exit status 0 while in binding.gyp. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\node-gyp\lib\configure.js:351:16)
gyp ERR! stack     at ChildProcess.emit (node:events:376:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:284:12)
gyp ERR! System Windows_NT 10.0.19041

I have executed this npm run rebuild
in the node-simconncet directory and i use the 32-bit version of Node (v15.5.0) on Windows.

I have no idea what else I can do.
Note: I am using the SDK from Microsoft Flight Simulator 2020.

I thank you in advance for your help

Module Not Found | Electron v11.2.0

image

Hello!
I have an electron build for MSFS2020. It builds successfully, I copy the SimConnect.dll to build/Release folder, however it fails to import the module.

Here's what I run for my build
HOME=~/.electron-gyp node-gyp rebuild --target=11.2.0 --arch=x64 --msvs_version=2019 --dist-url=https://electronjs.org/headers

Using node x64.

I am using the refactor branch.

This command works perfectly:
node examples/nodejs/example.js

The pre-built binary only works with the 32-bit version of Node.js

Hi, i getting this error in console when executes the code, i checked the installation of node, the command

node -p "process.arch"

returns ia32

and command node -p "process.platform"

return win32

So I don't understand if I have node 32 bits because it keeps telling me no?

thanks for any help

setDataOnSimObject with Waypoints Array

When trying to send a set of (or even one) waypoints to a non-atc aircraft simobject (created with aICreateNonATCAircraft) - i get size mismatch exception.

Looking at setDataOnSimObject the array item size seems to be forced to 0 in all cases?

    if (data instanceof Array) {
          this._writeBuffer.writeInt(DataSetFlag.DEFAULT);
          this._writeBuffer.writeInt(data.length);
          this._writeBuffer.writeInt(0); // size
          data.forEach(simConnectData => {
              simConnectData.write(this._writeBuffer);
          });
          this._writeBuffer.writeInt(this._writeBuffer.getOffset() - 36, 32);

In my code i'm basically createing a single waypoint then sending it to a data definition that just includes AI Wapoint List. Example below:

let newWaypointValue: Waypoint = new Waypoint();
                  newWaypointValue.speed = 100;
                  newWaypointValue.altitude = 1000;
                  newWaypointValue.latitude = 34.03684;
                  newWaypointValue.longitude = -118.22659;
                  newWaypointValue.throttle = 90.0;
                  newWaypointValue.flags =  SimConnectConstants.WAYPOINT_SPEED_REQUESTED;

handle.setDataOnSimObject(
                    dataDefinitions.waypoints,
                    aircraft.objectid,
                    [newWaypointValue]
                  );

Write data variables into created ia aircraft not working

When I try setDataOnSimObject into create iaAircraft nothing happened.

To try it I created an example on my fork.

  • Open the simulator(msfs), put the aircraft preferred C152 into ground into some airport.
  • Case you aren't using msfs, need change the containerTitle for the aircraft into your simulator.
  • Run the script npx ts-node samples/typescript/iaAircraftWriteSimulationVariables.ts
  • Press Y and slew an aircraft to the side to see both aircraft.

BONUS:

  • I tried to slew the aircraft by simconnect and didn't have success the code is commented too.
  • If I try to set the aiAircraft object and user object at the same time I have an exception 2.

Readme: api vs examples mismatch

Your Readme currently lists the api as

open(function, function, function, function)

but your example has

open(string, function, function, function, function)

I haven't used the package yet to know which is the correct api, I am just doing the Typescript boilerplate for it, but just noticed the inconsistency.

PS: expect a PR for typescript typings.

node fail start

Hello,

i have a problem when trying to start the example script, i have node 32bits.

node examples/nodejs/example.js

node-simconnect: Loading pre-built binary
internal/modules/cjs/loader.js:1208
return process.dlopen(module, path.toNamespacedPath(filename));
^

Error: The application could not be started; The parallel configuration is not correct. Check the application event log or use the sxstrace.exe tool on the command line for more details.

\?\test_simconnect\watt\simconnect\bin\win_ia32\node-simconnect.node
at Object.Module._extensions..node (internal/modules/cjs/loader.js:1208:18)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Module.require (internal/modules/cjs/loader.js:1044:19)
at require (internal/modules/cjs/helpers.js:77:18)
at Object. (C:test_simconnect\watt\simconnect\index.js:16:22)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)

Bytebuffer format on electron.

I'm trying to use this excellent lib on the electron. But I have a weird bug.

I'm receiving this error on electron;

Screenshot 2023-02-11 at 13 42 44

So I started to investigate and I found the main point of the error, basically, it looked like running two different versions of bytebuffer.

  • on electron
    Screenshot 2023-02-11 at 13 39 32

  • on node
    Screenshot 2023-02-11 at 13 39 47

I tried to investigate the package-lock but I don't find anything relevant.

Do you have any idea what could be?

Why GPL instead of LGPL?

Hi, just noticed license change from MIT to GPL 3 which is very unfortunate as GPL 3 basically prevents usage in any proprietary projects that can't go open source.

Can't the LGPL be used instead as it is on jsimconnect (https://github.com/mharj/jsimconnect/blob/master/LICENSE)? This would still force any changes and developments of the lib to be open source while allowing any proprietary software to use it as is.

Hope this can be changed ;)

Error on require

I'm running Windows 10 and installed the 32-bit version of Node via the official installer at https://nodejs.org/en/download/ including the extra build-tools via Chocolatey.

After npm intall node-simconnect and running const simConnect = require("node-simconnect") I get the following error:

node-simconnect: Loading pre-built binary
internal/modules/cjs/loader.js:1187
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
\\?\C:\Users\duztd\code\msfs2020\node_modules\node-simconnect\bin\win_ia32\node-simconnect.node
    at Object.Module._extensions..node (internal/modules/cjs/loader.js:1187:18)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at Module.require (internal/modules/cjs/loader.js:1025:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (C:\Users\duztd\code\msfs2020\node_modules\node-simconnect\index.js:16:22)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)

No idea how to proceed.

Also: My use-case is to integrate with Microsoft Flight Simulator 2020. Will this package work with the SimConnect provided by MSFS2020?

Unresolved external symbol

I've been trying to get this to work within a node/vue/electron environment, but every way I try to rebuild this, I end up getting an error. This is as far as I've been able to get to, using:

node-gyp rebuild --target=11.0.5 --arch=ia32 --dist-url=https://electronjs.org/headers

I get the error below:

simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_RequestSystemState@12 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\
node_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_AddToDataDefinition@28 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build 
\node_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_GetNextDispatch@12 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\nod 
e_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_RequestDataOnSimObjectType@20 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnec 
t\build\node_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_Open@24 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\node_simconnec 
t.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_Close@4 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\node_simconnec 
t.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_RetrieveString@20 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\node 
_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_FlightLoad@8 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\node_simc 
onnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_SetDataOnSimObject@28 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\ 
node_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_SubscribeToSystemEvent@12 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\bu 
ild\node_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_MapClientEventToSimEvent@12 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\ 
build\node_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_TransmitClientEvent@24 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build 
\node_simconnect.vcxproj]
simconnect_session.obj : error LNK2001: unresolved external symbol _SimConnect_RequestDataOnSimObject@36 [C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\bu 
ild\node_simconnect.vcxproj]
C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect\build\Release\node_simconnect.node : fatal error LNK1120: 13 unresolved externals [C:\Users\user\Documents\ 
VueJS\project\node_modules\node-simconnect\build\node_simconnect.vcxproj]
gyp ERR! build error 
gyp ERR! stack Error: `C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onExit (C:\Users\user\AppData\Roaming\npm\node_modules\node-gyp\lib\build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:315:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:277:12)
gyp ERR! System Windows_NT 10.0.19042
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\user\\AppData\\Roaming\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" "--target=11.0.5" "--arch=ia32" "--dist-url=https://electronjs.org/headers"
gyp ERR! cwd C:\Users\user\Documents\VueJS\project\node_modules\node-simconnect
gyp ERR! node -v v14.15.4
gyp ERR! node-gyp -v v7.1.2
gyp ERR! not ok

I also tried changing the arch to x64, which builds successfully, but then when I run the app, I get:

ERROR  Failed to compile with 1 error                                                                                                                                     11:38:08 AM
This relative module was not found:

* ./bin/win_ia32/node_simconnect in ./node_modules/node-simconnect/index.js

Am I completely missing something here? This was done using the refactor branch btw.

Issue rebuilding for Electron

@EvenAR

First, thanks for your hard work on this. We would love to use this module for an electron sideproject a couple of us are working on but we're having a hell of a time getting it to work. We have tried building with electron-rebuild but we run into a bunch of errors like:

[path]\node_modules\node-simconnect\src\addon.cc(327,97): error C2661:
'v8::Object::Set': no overloaded function takes 2 arguments [path]\node_modules\node-simconnect\build\node-simconnect.vcxproj]

We can build using this method: #27 (comment)

However, then we get a warning about the module being built against a different version of NODE_MODULES than electron (something like version 73 vs version 76. Any ideas?

Subscribe to 'CustomMissionActionExecuted' event

Hi Even!

I have some problem when calling the subscribeToSystemEvent('CustomMissionActionExecuted') function. I can get all the Crash, Start, Stop, Pause events, but not this one. I know, that there is a Custom Action in the mission, but this function never returns any value.

Here is an example of the function: https://www.prepar3d.com/SDKv4/sdk/simconnect_api/samples/mission_action.html.

My code looks like this:

simConnect.subscribeToSystemEvent('CustomMissionActionExecuted', (customAction) => {
  console.log('customAction', customAction);
});

Am I doing something wrong? Can you help me please?

Thanks!

Multiple "no overloaded function" errors when trying to compile

I'm trying to compile for 64bit with p3d v4.5 SDK. I get a lot of "not overloaded function" erros.

As I'm fairly new to Node, and practically clueless with this compilation process on windows, I was hoping you might have some insight.

I'm using master branch code and It have taken me a few hours just to get rid of all the windows compiler errors.

here are just a few examples.
addon.cc(328,50): error C2661: 'v8::Value::ToString': no overloaded function takes 0 arguments
addon.cc(437,58): error C2660: 'v8::Value::Int32Value': function does not take 0 arguments
node-simconnect\src\addon.cc(511,29): error C2512: 'v8::String::Utf8Value::Utf8Value': no appropriate default constructor available

Thanks,
Uri

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.