Skip to content

Commit

Permalink
cleanup error handling, capture multi broadcast devices
Browse files Browse the repository at this point in the history
  • Loading branch information
jessedp committed Sep 1, 2022
1 parent 4a6719f commit 5fbbbb3
Showing 1 changed file with 44 additions and 29 deletions.
73 changes: 44 additions & 29 deletions src/discovery.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import Timeout = NodeJS.Timeout;
import axios from 'axios';
import bytes = require('byte-data');
import * as Debug from 'debug'
import * as Debug from 'debug';
import dgram = require('dgram');

const debug = Debug('tablo-api:discovery');

const debug = Debug('discovery');

import Device from "./Device";
import Device from './Device';

export default class Discover {
private readonly sendPort: number = 8881;
Expand All @@ -18,7 +17,7 @@ export default class Discover {
/**
* Attempt discovery via UDP broadcast. Will only return a single device.
*/
public async broadcast(): Promise<[Device]> {
public async broadcast(): Promise<Device[]> {
const server = dgram.createSocket('udp4');

server.on('error', (error) => {
Expand Down Expand Up @@ -46,7 +45,7 @@ export default class Discover {
});
});

let outerDevice:Device;
const outerDevices: Device[] = [];

server.on('message', (msg, info) => {
if (msg.length !== 140) {
Expand All @@ -59,27 +58,28 @@ export default class Discover {
// s = struct.format('b').unpack()

const trunc = (txt: string) => txt.split('\0', 1)[0];
const device:Device = {
const device: Device = {
host: trunc(bytes.unpackString(msg, 4, 68)),
private_ip: trunc(bytes.unpackString(msg, 68, 100)),
// resp_code: trunc(bytes.unpackString(msg, 0, 4)),
server_id: trunc(bytes.unpackString(msg, 100, 120)),
dev_type: trunc(bytes.unpackString(msg, 120, 130)),
board: trunc(bytes.unpackString(msg, 130, 140)),
via: 'broadcast'
via: 'broadcast',
};
clearTimeout(this.watcher);
server.close();

debug('server.on.message received:');
debug(device);
debug('device found: ', device);
// I feel like this shouldn't work, but...
outerDevice = device;

outerDevices.push(device);
// eslint wanted a return, this works but may be wrong
return device;
});

server.bind(this.recvPort);

// allows us to leave the server open to wait for multiple device replies
this.watcher = setTimeout(() => {
server.close();
}, 250); // should be 250
Expand All @@ -88,36 +88,51 @@ export default class Discover {
return new Promise((resolve) => {
server.on('close', () => {
debug('broadcast : close');
debug('broadcast, data:');
debug(outerDevice);
resolve([outerDevice]);
debug('outerDevices resolved: ', outerDevices);
// resolve([outerDevice]);
resolve(outerDevices);
});
});
}

/**
* Attempt discovery via HTTP broadcast using Tablo discovery service
*/
public async http(): Promise<Device[]>{
public async http(): Promise<Device[]> {
return new Promise(async (resolve, reject) => {

let data: Device[];
let devices: Device[] = [];
try {
type Response = { data: { cpes: Device[]}};
const response:Response = await axios.get(this.discoveryUrl);
data = response.data.cpes;
data.forEach((part, index, arr) => {
if (arr[index]) {
arr[index].via = 'http';
}
}, data); // use arr as this
type Response = { data: { success?: boolean; error?: { code: number; message: string }; cpes: Device[] } };
const response: Response = await axios.get(this.discoveryUrl);
const data = response.data;
if (!data.success) {
debug('HTTP Response Not succcess', data);
return resolve(devices);
}

if (typeof data.error !== 'undefined') {
debug('HTTP Response Error', data);
return resolve(devices);
}

devices = response.data.cpes;
if (typeof devices === 'undefined') {
debug('HTTP device data in successful response? ', response.data);
} else {
devices.forEach((part, index, arr) => {
if (arr[index]) {
arr[index].via = 'http';
}
}, devices); // use arr as this
}
return resolve(devices);
} catch (error) {
debug('Http Error:', error);
reject( new Error(`Http Error: ${error}`) );
reject(new Error(`Http Error: ${error}`));
}
resolve(data);
resolve(devices);
});
}
}

export const discovery = new Discover();
export const discovery = new Discover();

0 comments on commit 5fbbbb3

Please sign in to comment.