You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
3.3 KiB
JavaScript
180 lines
3.3 KiB
JavaScript
|
|
/**
|
|
* @type {{
|
|
* DISCONNECTED: Symbol,
|
|
* CONNECTING: Symbol,
|
|
* CONNECTED: Symbol,
|
|
* }}
|
|
*/
|
|
const ConnectionState = new Enum(
|
|
'ConnectionState',
|
|
'DISCONNECTED',
|
|
'CONNECTING',
|
|
'CONNECTED',
|
|
);
|
|
|
|
class ConnectionStateChangeEvent extends Event {
|
|
constructor(type, connection, state) {
|
|
super(type)
|
|
this.connection = connection;
|
|
this.state = state;
|
|
}
|
|
}
|
|
|
|
class Connection extends EventEmitter {
|
|
#state;
|
|
#discovering;
|
|
#discoverTimer;
|
|
|
|
/** @type {GyverHub} */
|
|
hub;
|
|
/** @type {object} */
|
|
options;
|
|
|
|
/**
|
|
* @param {GyverHub} hub
|
|
*/
|
|
constructor(hub) {
|
|
super();
|
|
this.#state = ConnectionState.DISCONNECTED;
|
|
|
|
this.#discovering = false;
|
|
this.#discoverTimer = new AsyncTimer(undefined, () => {
|
|
this.#discovering = false;
|
|
this.hub._checkDiscoverEnd();
|
|
});
|
|
|
|
this.hub = hub;
|
|
this.options = this.hub.config.getConnection(this.name);
|
|
|
|
this.options.discover_timeout = 3000;
|
|
}
|
|
|
|
/**
|
|
* Имя соединения.
|
|
* @type {string}
|
|
*/
|
|
get name() {
|
|
return this.constructor.name;
|
|
}
|
|
|
|
/**
|
|
* Приоритет соединения.
|
|
* @type {number}
|
|
*/
|
|
get priority() {
|
|
return this.constructor.priority;
|
|
}
|
|
|
|
_setState(state) {
|
|
if (this.#state === state)
|
|
return;
|
|
this.#state = state;
|
|
this.dispatchEvent(new ConnectionStateChangeEvent('statechange', this, state));
|
|
}
|
|
|
|
_discoverTimer() {
|
|
this.#discovering = true;
|
|
this.#discoverTimer.restart(this.options.discover_timeout);
|
|
}
|
|
|
|
/**
|
|
* Check if connection is currently discovering for new devices
|
|
* @returns {boolean}
|
|
*/
|
|
isDiscovering() {
|
|
return this.#discovering;
|
|
}
|
|
|
|
/**
|
|
* Get connection state.
|
|
* @returns {ConnectionState}
|
|
*/
|
|
getState() {
|
|
return this.#state;
|
|
}
|
|
|
|
/**
|
|
* Check if device is connected.
|
|
* @returns {boolean}
|
|
*/
|
|
isConnected() {
|
|
return this.options.enabled && this.#state === ConnectionState.CONNECTED;
|
|
}
|
|
|
|
/**
|
|
* Get current device display name, if available.
|
|
* @returns {string}
|
|
*/
|
|
getName() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Send discover request to known device(s).
|
|
*/
|
|
async discover() {
|
|
if (this.discovering || !this.isConnected()) return;
|
|
this._discoverTimer();
|
|
for (let pref of this.hub.getAllPrefixes()) await this.send(pref);
|
|
}
|
|
|
|
|
|
/**
|
|
* Send discover request to all devices.
|
|
*/
|
|
async search() {
|
|
if (this.discovering || !this.isConnected()) return;
|
|
this._discoverTimer();
|
|
await this.send(this.hub.prefix);
|
|
}
|
|
|
|
/**
|
|
* Initialize device connection (ex. autoconnect)
|
|
*/
|
|
async begin() {
|
|
if (this.options.enabled)
|
|
await this.connect();
|
|
}
|
|
|
|
/**
|
|
* Connnect to device.
|
|
*/
|
|
async connect() {}
|
|
|
|
/**
|
|
* Disconnect from device.
|
|
*/
|
|
async disconnect() {}
|
|
|
|
/**
|
|
* Request user to select device (if applicable).
|
|
*/
|
|
async select() {}
|
|
|
|
/**
|
|
* Send raw request
|
|
* @param {string} data
|
|
*/
|
|
async send(data) {}
|
|
|
|
/**
|
|
* Send command to device.
|
|
* @param {Device} device
|
|
* @param {string} command
|
|
* @param {string} name
|
|
* @param {string} value
|
|
*/
|
|
async post(device, command, name = '', value = '') {
|
|
let uri = device.info.prefix + '/' + device.info.id + '/' + this.hub.clientId + '/' + command;
|
|
if (name) {
|
|
uri += '/' + name;
|
|
if (value) {
|
|
uri += '=' + value;
|
|
}
|
|
}
|
|
|
|
await this.send(uri);
|
|
}
|
|
}
|