fldigi-node
Version:
node.js wrapper for fldigi's XML-RPC interface.
117 lines (96 loc) • 2.61 kB
text/typescript
import xmlRpc from "xmlrpc";
export class flDigi {
private client: xmlRpc.Client;
private host: string;
private port: number;
public receive: { (data: string): void; } | undefined;
public receiveInterval: any;
public receiveRate = 1000;
public txCheckRate = 1000;
constructor(host = "localhost", port = 7362) {
this.host = host;
this.port = port;
this.client = xmlRpc.createClient({ host: this.host, port: this.port });
}
async xmlRpcPromise(method: string, args: any[] = []): Promise<string> {
return new Promise((resolve, reject) => {
this.client.methodCall(method, args, (err, result) => {
if (err) throw err;
try {
const msg = result.toString();
resolve(msg);
} catch (error) {
throw new Error("Result is not a string");
}
});
});
}
startReceiveInterval() {
this.receiveInterval = setInterval(() => {
const getDataPromise = this.xmlRpcPromise('rx.get_data');
getDataPromise.then((data) => {
if (data.length > 0 && this.receive !== undefined) {
this.receive(data);
}
});
}, this.receiveRate);
}
stopReceiveInterval() {
clearInterval(this.receiveInterval);
}
async mainTx() {
const prom = await this.xmlRpcPromise('main.tx');
this.stopReceiveInterval();
return prom;
}
async mainRx() {
const prom = await this.xmlRpcPromise('main.rx');
this.startReceiveInterval();
return prom;
}
async textAddTx(content: string) {
return this.xmlRpcPromise('text.add_tx', [content]);
}
async txGetData() {
return this.xmlRpcPromise('tx.get_data');
}
async getModems() {
return this.xmlRpcPromise('modem.get_names');
}
async setModem(modem: string) {
return this.xmlRpcPromise('modem.set_by_name', [modem]);
}
async setCarrier(carrier: number) {
return this.xmlRpcPromise('modem.set_carrier', [carrier]);
}
async waitForTxComplete() {
return new Promise((resolve, reject) => {
const bytesTransmitted = (cb: { (err: Object, dataLength: number): void; }) => {
this.client.methodCall('tx.get_data', [], function(err, lastData) {
cb(err, lastData.length);
});
};
const checkForData = () => {
bytesTransmitted((err, bytes) => {
if (bytes > 0) {
setTimeout(checkForData, this.txCheckRate);
} else {
resolve(true);
}
});
};
setTimeout(checkForData, this.txCheckRate);
});
}
async transmit(content: string) {
try {
await this.mainTx();
await this.textAddTx(content);
await this.waitForTxComplete();
await this.mainRx();
} catch (e) {
throw e;
}
return true;
}
}