Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save interfaces to the settings object, and try to restore on app load. #18

Merged
merged 13 commits into from
Jun 10, 2024
2 changes: 1 addition & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class KNXApp extends Homey.App {
const homeyIP = address.split(':', 1).toString();

this.log('Homey IP + Parsed IP', address, homeyIP);
this.knxInterfaceManager = new KNXInterfaceManager(homeyIP);
this.knxInterfaceManager = new KNXInterfaceManager(homeyIP, this.homey);
}

/**
Expand Down
21 changes: 3 additions & 18 deletions lib/GenericKNXDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,6 @@ class GenericKNXDriver extends Homey.Driver {
this.knxInterfaceManager = this.homey.app.getKNXInterfaceManager();
}

/**
* Return a list of KNX interfaces
*
* @returns {{ip: *, name: *, mac: *}[]}
*/
getInterfaceList() {
return Object.values(this.knxInterfaceManager.getKNXInterfaceList()).map((knxInterface) => {
return {
name: knxInterface.name,
mac: knxInterface.macAddress,
ip: knxInterface.ipAddress,
};
});
}

// Obtain a stored ETS export for the selected IP interface.
getGroupAddressList() {
// console.log('Getting ga for interface:', this.selectedInterfaceMAC);
Expand Down Expand Up @@ -56,15 +41,15 @@ class GenericKNXDriver extends Homey.Driver {

// List al the found or added IP interfaces.
session.setHandler('list_interfaces', async () => {
return this.getInterfaceList();
return this.knxInterfaceManager.getSimpleInterfaceList();
});

// However the structure seems to be the same as the manual entry, which does work.
// Trigger the interface manager to search for KNX IP interfaces
session.setHandler('search_interfaces', async () => {
try {
await this.knxInterfaceManager.searchInterfaces();
return this.getInterfaceList();
return this.knxInterfaceManager.getSimpleInterfaceList();
} catch (error) {
throw new Error(this.homey.__(`errors.ip.${error.message}`));
}
Expand All @@ -74,7 +59,7 @@ class GenericKNXDriver extends Homey.Driver {
session.setHandler('manual_ip_address', async (manualIPAddress) => {
try {
await this.knxInterfaceManager.discoverKNXInterfaceOnIP(manualIPAddress);
return this.getInterfaceList();
return this.knxInterfaceManager.getSimpleInterfaceList();
} catch (error) {
throw new Error(this.homey.__(`errors.ip.${error.message}`));
}
Expand Down
38 changes: 37 additions & 1 deletion lib/KNXInterfaceManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ const KNXInterface = require('./KNXInterface');

class KNXInterfaceManager extends EventEmitter {

constructor(localIP) {
constructor(localIP, homey) {
super();

this.homey = homey;

// Formatted logging
this.log = console.log.bind(this, '[KNX interface manager]');
this.errorLog = console.error.bind(this, '[KNX interface manager] ERROR:');
Expand All @@ -23,10 +26,22 @@ class KNXInterfaceManager extends EventEmitter {

if (ip.isV4Format(localIP)) {
this.localIPBuffer = ip.toBuffer(ip.address());
const interfaces = this.homey.settings.get('interfaces') || [];

this.findKNXInterfaces()
.catch((error) => {
this.log('findKNXinterfaces error', error);
}).finally(async () => {
for (const savedInterface of interfaces) {
// Force recheck interfaces from previous session if they are not found by the UDP search
if (savedInterface && savedInterface.mac && savedInterface.ip && !this.KNXInterfaces[savedInterface.mac]) {
try {
await this.discoverKNXInterfaceOnIP(savedInterface.ip);
} catch (error) {
this.errorLog('Error checking interface', savedInterface.ip, error);
}
}
}
});
} else {
this.errorLog('IP address is not a valid IPv4 format');
Expand Down Expand Up @@ -60,6 +75,21 @@ class KNXInterfaceManager extends EventEmitter {
return this.KNXInterfaces;
}

/**
* Returns a simplified list of KNX interfaces used to store interfaces in the settings
*
* @returns {{ip: *, name: *, mac: *}[]}
*/
getSimpleInterfaceList() {
return Object.values(this.KNXInterfaces).map((knxInterface) => {
return {
name: knxInterface.name,
mac: knxInterface.macAddress,
ip: knxInterface.ipAddress,
};
});
}

// Check if a given IP is a KNX IP Interface
async discoverKNXInterfaceOnIP(ipAddress) {
// Check if the given address is a valid IPv4 address
Expand Down Expand Up @@ -199,6 +229,10 @@ class KNXInterfaceManager extends EventEmitter {
// Use the Interface MAC as the key value
this.KNXInterfaces[knxInterface.interfaceMac] = new KNXInterface(knxInterface);
}

const interfaces = this.getSimpleInterfaceList();
this.homey.settings.set('interfaces', interfaces);

this.emit('interface_found', this.KNXInterfaces[knxInterface.interfaceMac]);
return resolve(this.KNXInterfaces[knxInterface.interfaceMac]);
} catch (error) {
Expand Down Expand Up @@ -313,6 +347,8 @@ class KNXInterfaceManager extends EventEmitter {
try {
// Use the Interface MAC as the key value
this.KNXInterfaces[knxInterface.interfaceMac] = new KNXInterface(knxInterface);
const interfaces = this.getSimpleInterfaceList();
this.homey.settings.set('interfaces', interfaces);
this.emit('interface_found', this.KNXInterfaces[knxInterface.interfaceMac]);
return resolve(this.KNXInterfaces[knxInterface.interfaceMac]);
} catch (err) {
Expand Down
6 changes: 3 additions & 3 deletions test/TestInterfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ const InterfaceManager = require('../lib/KNXInterfaceManager');
const KNXManager = new InterfaceManager('192.168.87.250'); // localhost works as well as an normal IP
this.KNXInterfaces = KNXManager.getKNXInterfaceList();

KNXManager.on('interface_found', (interface) => {
if (interface.macAddress.startsWith('000e8c')) {
KNXManager.on('interface_found', (foundInterface) => {
if (foundInterface.macAddress.startsWith('000e8c')) {
// hager filtering
interface._connectKNX();
foundInterface._connectKNX();
}
});