Skip to content

Commit

Permalink
Merge pull request #26 from Luligu/dev
Browse files Browse the repository at this point in the history
Release 0.7.5
  • Loading branch information
Luligu authored Jul 28, 2024
2 parents 76fbe15 + 097d8e4 commit bae0ac1
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 82 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,5 @@ bridge-devices.json
bridge-groups.json

# other stuff
matterbridge-shelly
TODO.md
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,6 @@ jest.config.js
screenshot

# other stuff
matterbridge-shelly
TODO.md
yellow-button.png
24 changes: 12 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@
"ws": "^8.18.0"
},
"devDependencies": {
"@eslint/js": "^9.7.0",
"@eslint/js": "^9.8.0",
"@types/eslint__js": "^8.42.3",
"@types/jest": "^29.5.12",
"@types/multicast-dns": "^7.2.4",
"@types/node": "^20.14.12",
"@types/node": "^22.0.0",
"@types/ws": "^8.5.11",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jest": "^28.6.0",
Expand Down
18 changes: 6 additions & 12 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,17 @@ describe('initializePlugin', () => {

beforeEach(() => {
mockMatterbridge = { addBridgedDevice: jest.fn() } as unknown as Matterbridge;
mockLog = { error: jest.fn(), warn: jest.fn(), info: jest.fn(), debug: jest.fn() } as unknown as AnsiLogger;
mockLog = { fatal: jest.fn(), error: jest.fn(), warn: jest.fn(), notice: jest.fn(), info: jest.fn(), debug: jest.fn() } as unknown as AnsiLogger;
mockConfig = {
'name': 'matterbridge-test',
'name': 'matterbridge-shelly',
'type': 'DynamicPlatform',
'noDevices': false,
'throwLoad': false,
'throwStart': false,
'throwConfigure': false,
'throwShutdown': false,
'debug': false,
'unregisterOnShutdown': false,
'delayStart': false,
} as PlatformConfig;
});

it('should return an instance of TestPlatform', () => {
const result = initializePlugin(mockMatterbridge, mockLog, mockConfig);

expect(result).toBeInstanceOf(ShellyPlatform);
it('should return an instance of ShellyPlatform', () => {
const platform = initializePlugin(mockMatterbridge, mockLog, mockConfig);
expect(platform).toBeInstanceOf(ShellyPlatform);
});
});
21 changes: 15 additions & 6 deletions src/mdnsScanner.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable jest/no-done-callback */
import { LogLevel } from 'node-ansi-logger';
import { MdnsScanner, DiscoveredDeviceListener, DiscoveredDevice } from './mdnsScanner';
import { jest } from '@jest/globals';

describe('Shellies test', () => {
const mdns = new MdnsScanner();
describe('Shellies MdnsScanner test', () => {
let consoleLogSpy: jest.SpiedFunction<typeof console.log>;

const mdns = new MdnsScanner(LogLevel.INFO);

const discoveredDeviceListener: DiscoveredDeviceListener = async (device: DiscoveredDevice) => {
// eslint-disable-next-line no-console
console.log(`Discovered shelly device: ${device.id} at ${device.host} port ${device.port} gen ${device.gen}`);
console.log(`Shellies MdnsScanner test: discovered shelly device: ${device.id} at ${device.host} port ${device.port} gen ${device.gen}`);
};

beforeAll(() => {
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation((...args: any[]) => {
// console.error(`Mocked console.log: ${args}`);
});
mdns.on('discovered', discoveredDeviceListener);
});

Expand Down Expand Up @@ -40,14 +49,14 @@ describe('Shellies test', () => {
});

test('Start discover', (done) => {
mdns.start(60, true);
mdns.start(3000, true);
expect(mdns.isScanning).toBeTruthy();
setTimeout(() => {
mdns.stop();
done();
expect(mdns.isScanning).toBeFalsy();
}, 65000);
}, 70000);
}, 5000);
}, 10000);

test('Log discovered', () => {
const size = mdns.logPeripheral();
Expand Down
45 changes: 36 additions & 9 deletions src/mdnsScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export interface DiscoveredDevice {

export type DiscoveredDeviceListener = (data: DiscoveredDevice) => void;

/**
* Creates an instance of MdnsScanner.
* @param {LogLevel} logLevel - The log level for the scanner. Defaults to LogLevel.INFO.
*/
export class MdnsScanner extends EventEmitter {
private discoveredDevices = new Map<string, DiscoveredDevice>();
public readonly log;
Expand All @@ -47,20 +51,34 @@ export class MdnsScanner extends EventEmitter {
this.log = new AnsiLogger({ logName: 'ShellyMdnsDiscover', logTimestampFormat: TimestampFormat.TIME_MILLIS, logLevel });
}

/**
* Gets a value indicating whether the MdnsScanner is currently scanning.
*
* @returns {boolean} A boolean value indicating whether the MdnsScanner is scanning.
*/
get isScanning() {
return this._isScanning;
}

/**
* Sends an mDNS query for shelly devices.
*/
private sendQuery() {
this.scanner?.query([
{ name: '_http._tcp.local', type: 'PTR' },
{ name: '_shelly._tcp.local', type: 'PTR' },
]);
this.log.info('Sent mDNS query for shelly devices.');
this.log.debug('Sent mDNS query for shelly devices.');
}

/**
* Starts the mDNS query service for shelly devices.
*
* @param {number} shutdownTimeout - The timeout value in milliseconds to stop the MdnsScanner (optional, if not provided the MdnsScanner will not stop).
* @param {boolean} debug - Indicates whether to enable debug mode (default: false).
*/
start(shutdownTimeout?: number, debug = false) {
this.log.info('Starting mDNS query service for shelly devices...');
this.log.debug('Starting mDNS query service for shelly devices...');
this._isScanning = true;

this.scanner = mdns();
Expand Down Expand Up @@ -150,34 +168,43 @@ export class MdnsScanner extends EventEmitter {
if (debug) this.log.debug(`--- end ---`);
});

// Send the query and set the timeout to send it again every 60 seconds
this.sendQuery();

this.queryTimeout = setInterval(() => {
this.sendQuery();
}, 60 * 1000);

// Set the timeout to stop the scanner if it is defined
if (shutdownTimeout && shutdownTimeout > 0) {
this.scannerTimeout = setTimeout(() => {
this.stop();
}, shutdownTimeout * 1000);
}, shutdownTimeout);
}
this.log.info('Started mDNS query service for shelly devices.');
this.log.debug('Started mDNS query service for shelly devices.');
}

/**
* Stops the MdnsScanner query service.
*/
stop() {
this.log.info('Stopping mDNS query service...');
this.log.debug('Stopping mDNS query service...');
if (this.scannerTimeout) clearTimeout(this.scannerTimeout);
if (this.queryTimeout) clearTimeout(this.queryTimeout);
this._isScanning = false;
this.scannerTimeout = undefined;
if (this.queryTimeout) clearTimeout(this.queryTimeout);
this.queryTimeout = undefined;
this._isScanning = false;
this.scanner?.removeAllListeners();
this.scanner?.destroy();
this.scanner = undefined;
this.removeAllListeners();
this.logPeripheral();
this.log.info('Stopped mDNS query service.');
this.log.debug('Stopped mDNS query service.');
}

/**
* Logs information about discovered shelly devices.
* @returns The number of discovered devices.
*/
logPeripheral() {
this.log.info(`Discovered ${this.discoveredDevices.size} shelly devices:`);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
Loading

0 comments on commit bae0ac1

Please sign in to comment.