Gathering detailed insights and metrics for @trippnology/lib-js8call
Gathering detailed insights and metrics for @trippnology/lib-js8call
Gathering detailed insights and metrics for @trippnology/lib-js8call
Gathering detailed insights and metrics for @trippnology/lib-js8call
npm install @trippnology/lib-js8call
Typescript
Module System
Min. Node Version
Node Version
NPM Version
70.3
Supply Chain
97.8
Quality
75.7
Maintenance
100
Vulnerability
99.6
License
Cumulative downloads
Total Downloads
Last day
3,300%
Compared to previous day
Last week
800%
Compared to previous week
Last month
38.2%
Compared to previous month
Last year
-10.5%
Compared to previous year
3
A library to help you interface your NodeJS app with JS8Call (tested with JS8Call v2.2.0).
Integrate JS8Call into your existing app, or come up with something entirely new! Here are a couple of apps that use this library:
How about an LED "ON AIR" light to show when you are transmitting? A Rasperry Pi and the Johnny Five library are an easy way to hook up all sorts of hardware. The only limit is your imagination! If you make something cool, create an issue with the details, and I'll add you to the list.
npm install @trippnology/lib-js8call
1const js8 = require('@trippnology/lib-js8call')(); 2// Note the extra () at the end
You can now listen to events and act on them as you wish. It's a good idea to wait for a tcp.connected
event before you try to interact with JS8Call:
1js8.on('tcp.connected', (connection) => { 2 // At this point, we have setup the connection 3 console.log( 4 'Server listening %s:%s Mode: %s', 5 connection.address, 6 connection.port, 7 connection.mode 8 ); 9 // You can now safely do your thing! 10 MyApp.init(); 11});
If you don't want to auto connect, disable TCP and connect when you're ready:
1const js8 = require('@trippnology/lib-js8call')({ tcp: { enabled: false } }); 2// Later, when your app is ready... 3js8.tcp.connect().then((connection) => { 4 console.log(connection); 5});
You can either listen to the "firehose" packet
event, emitted on every message we get from JS8Call:
1js8.on('packet', (packet) => { 2 // Do your custom stuff 3 processPacket(packet); 4});
... or individual events you are interested in:
1js8.on('rig.ptt', (packet) => { 2 console.log('[Rig] PTT is %s', packet.value); 3});
You can find runnable examples of both approaches in demo/manual-processing.js and demo/individual-events.js respectively.
Don't forget to handle errors:
1js8.on('error', (err) => { 2 console.log('Something went wrong:'); 3 console.error(err); 4});
Individual event names mirror the JS8Call JSON API, with a few additions:
Name | Description |
---|---|
error | Something went wrong |
rig.ptt.on | PTT has been enabled |
rig.ptt.off | PTT has been disabled |
rig.safe_to_tx | Returns true when PTT is off AND the send buffer is empty. |
rx.directed.to_me | Received a RX.DIRECTED packet addressed to the station callsign. Will change to rx.directed.me when enabled in JS8Call. See #5 |
tcp.connected | Successfully connected to JS8Call via TCP. Returns a connection object with address , port , and mode keys. |
tcp.disconnected | The connection to JS8Call has been closed or dropped. |
tcp.error | Something went wrong with the TCP connection. Returns an error. |
udp.connected | Listening for messages from JS8Call. Returns a connection object with address , port , and mode keys. |
udp.error | Something went wrong with the UDP connection. Returns an error. |
Please note that while JS8Call uses FULL CAPS for message types, event names are in all lower case.
You can pass in any options you wish to set manually when you require the module. Sensible defaults will be provided for anything you omit.
1const js8 = require('@trippnology/lib-js8call')({ 2 debug: true, 3 tcp: { host: '192.168.1.123', port: 12345 }, 4});
Option | Type | Default | Description |
---|---|---|---|
debug | boolean | false | Enables verbose output |
exit_when_js8call_closed | boolean | true | End the process when we receive a CLOSE message from JS8Call |
get_metadata_at_launch | boolean | true | Queries JS8Call for station metadata at launch. Only available when using TCP. Disable for cli use. |
tcp | object | { auto_reconnect: false, enabled: true, host: 'localhost', port: 2442, seconds_between_reconnect: 5 } | Options for the TCP server |
udp | object | { enabled: false, port: 2332 } | Options for the UDP server |
This is a low level feature that allows you to construct the request to your own requirements.
1// You can send your own JSON string 2js8.send( 3 '{ "type": "INBOX.STORE_MESSAGE", "params": { "CALLSIGN": "M7GMT", "TEXT": "Testing JSON API" } }' 4); 5// Or just send an object and it will be converted for you 6js8.send({ 7 type: 'INBOX.STORE_MESSAGE', 8 params: { CALLSIGN: 'M7GMT', TEXT: 'Testing JSON API' }, 9});
As well as being able to construct your own API messages, some convenience methods and properties have been provided.
Name | Type | Description |
---|---|---|
js8.help.valid_message_types | property | Object with 2 keys; incoming and outgoing that list valid API message types. |
Name | Type | Description |
---|---|---|
js8.inbox.getMessages() | function | Promise that resolves with an array of message objects |
js8.inbox.storeMessage(callsign, text) | function | Promise that resolves with an INBOX.MESSAGE packet |
Name | Type | Description |
---|---|---|
js8.mode.getSpeed() | function | Promise that resolves with a number representing the current speed. 0 = normal, 1 = fast, 2 = turbo, 4 = slow |
js8.mode.getSpeedDetailed() | function | Promise that resolves with an object with both the setting and a name: { setting: 0, name: 'normal' } |
js8.mode.setSpeed(speed) | function | Promise that resolves with a number representing the current speed. speed should be a number, one of: 0 = normal, 1 = fast, 2 = turbo, 4 = slow |
Name | Type | Description |
---|---|---|
js8.rig.getFreq() | function | Promise that resolves with an object containing properties about the current operating frequency |
js8.rig.setFreq(options) | function | Promise that resolves with an object containing properties about the current operating frequency. options should be an object containing at least an OFFSET property, and optional properties DIAL and FREQ |
js8.rig.getPTT() | function | Currently unreliable Promise that resolves with one of; null - the status is unknown, 0 - the PTT is off, or 1 - the PTT is on. |
js8.rig.ptt | property | Currently unreliable The status of the PTT. One of; null - the status is unknown, 0 - the PTT is off, or 1 - the PTT is on. |
js8.rig.safe_to_tx | property | Returns true when PTT is off AND the send buffer is empty. |
Name | Type | Description |
---|---|---|
js8.rx.getBandActivity() | function | Promise that resolves with an object representing the band activity window. |
js8.rx.getCallActivity() | function | Promise that resolves with an object representing the call window. |
js8.rx.getCallSelected() | function | Promise that resolves with a string containing the currently selected callsign. |
js8.rx.getText() | function | Promise that resolves with a string containing the contents of the QSO window. |
Name | Type | Description |
---|---|---|
js8.station.callsign | property | String containing the station callsign |
js8.station.grid | property | String containing the station grid |
js8.station.info | property | String containing the station info |
js8.station.status | property | The last STATION.STATUS packet received |
js8.station.getMetadata() | function | Promise that resolves with an object with the keys; callsign , grid , info , status . |
js8.station.getCallsign() | function | Promise that resolves with a string containing the station callsign. |
js8.station.getGrid() | function | Promise that resolves with a string containing the station grid. |
js8.station.setGrid(grid) | function | Promise that resolves with a string containing the new station grid. grid should be a string containing a valid Maidenhead locator. |
js8.station.getInfo() | function | Promise that resolves with a string containing the station info. |
js8.station.setInfo(info) | function | Promise that resolves with a string containing the new station info. info should be a string containing the station QTH/info. |
js8.station.getStatus() | function | Promise that resolves with a string containing the station status. |
js8.station.setStatus(status) | function | Promise that resolves with a string containing the new station status. status should be a string containing the station status. |
Name | Type | Description |
---|---|---|
js8.tcp.connect() | function | Tries to establish a TCP connection. Promise that resolves with a connection object. |
Name | Type | Description |
---|---|---|
js8.tx.getText() | function | Promise that resolves with a string containing the contents of the TX window. |
js8.tx.sendMessage(text) | function | Promise that resolves when the message has been transmitted. text should be the string you wish to TX. Will reject if the rig is in use. |
js8.tx.setText(text) | function | Promise that resolves with a TX.TEXT packet. text should be the string you wish to place into the TX window. |
Name | Type | Description |
---|---|---|
js8.utils.messageIsToMe(packet) | function | Returns true if the packet is addressed to the configured station callsign. packet should be a packet object. |
Most functions return a promise, so you can do stuff once it resolves or rejects, if you need to:
1js8.tx 2 .sendMessage('Your custom text') 3 .then(() => { 4 console.log('TX finished'); 5 }) 6 .catch((err) => { 7 console.log('Something went wrong:'); 8 console.error(err); 9 });
You will get at error if both TCP and UDP interfaces are enabled at the same time. While this does technically work, it will likely lead to duplicate traffic and headaches for you! TCP only is preferred.
Detecting when JS8Call is TXing is currently unreliable. We currently listen for RIG.PTT
messages and cache the value, but a RIG.PTT
with a value of off
doesn't mean that the
send buffer is empty. As a workaround, we manually check the buffer with js8.tx.getText()
when we receive a rig.ptt.off
, and if the buffer is empty, we set rig.safe_to_tx
to true
.
js8.tx.sendMessage()
will check the value of rig.safe_to_tx
before sending a message:
1js8.tx 2 .sendMessage('Hello, world!') 3 // If it's safe to TX, message is sent and promise resolves 4 .then((message) => { 5 console.log('Message sent: %s', message); 6 }) 7 // If the rig is busy, the promise rejects 8 .catch((err) => { 9 console.log(err); // Prints: 'Rig busy' 10 });
You can also listen to the rig.safe_to_tx
event to monitor this value in your app:
1js8.on('rig.safe_to_tx', (safety) => { 2 console.log('Is it safe to TX? %s', safety ? 'yes' : 'no'); 3});
Hopefully, in the future, there will be additional API methods that allow us to check
if it is safe to TX before trying to do so. Maybe JS8Call could send a TX.START
message
when it starts sending a message, and then a TX.END
message once the whole transmission
has finished or been aborted?
A future enhancement could be a message queue, so users could call js8.tx.sendMessage()
,
and the message would be sent once the rig becomes available.
The JS8Call API documentation is incomplete, so we are implementing API features as they are understood. API handling starts here in the source code.
For message types discovered so far, see JS8Call JSON API or console.log(js8.help.valid_message_types)
from within your app.
git checkout -b my-new-feature develop
git commit -am 'Add some feature'
git push origin my-new-feature
The bulk of this project was written over the Christmas break 2020. Future additions and changes will be noted here.
Copyright (c) 2021 Rikki Tripp.
A huge thanks to Rick VA1UAV for his feedback, feature suggestions, testing, and bug reports.
See LICENSE
No vulnerabilities found.
No security vulnerabilities found.