From 41d7100edcd0b7fbc76b9d8ae5d4e264858f3c05 Mon Sep 17 00:00:00 2001 From: GermanBluefox Date: Mon, 23 Oct 2023 15:30:24 +0200 Subject: [PATCH] Check subscription --- README.md | 2 +- io-package.json | 2 +- src-admin/src/App.js | 47 ++++++- src-admin/src/{components => Tabs}/Bridges.js | 43 ++++-- .../src/{components => Tabs}/Controller.js | 10 +- src-admin/src/{components => Tabs}/Devices.js | 2 + src-admin/src/{components => Tabs}/Options.js | 62 +++++++-- src-admin/src/components/ConfigHandler.js | 3 +- src/ioBrokerStorageTypes.ts | 2 +- src/lib/{DeviceFabric.ts => deviceFabric.ts} | 8 +- src/lib/devices/Dimmer.ts | 37 +++++- src/lib/devices/GenericDevice.ts | 53 ++++---- src/lib/index.ts | 4 +- src/main.ts | 123 ++++++++++-------- src/matter/devices/MappingDimmer.ts | 55 ++++++++ 15 files changed, 324 insertions(+), 129 deletions(-) rename src-admin/src/{components => Tabs}/Bridges.js (94%) rename src-admin/src/{components => Tabs}/Controller.js (90%) rename src-admin/src/{components => Tabs}/Devices.js (99%) rename src-admin/src/{components => Tabs}/Options.js (75%) rename src/lib/{DeviceFabric.ts => deviceFabric.ts} (90%) create mode 100644 src/matter/devices/MappingDimmer.ts diff --git a/README.md b/README.md index 6b541f7e..8a59707b 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ ### **WORK IN PROGRESS** --> ## ToDo -- Dimmer - Controller - Devices - Add device without room or function (by ID) +- Get login & pass from iot (new js-controller version) may be ## Changelog ### **WORK IN PROGRESS** diff --git a/io-package.json b/io-package.json index 74d67718..771edce9 100644 --- a/io-package.json +++ b/io-package.json @@ -67,7 +67,7 @@ "native": { "interface": "", "login": "", - "password": "" + "pass": "" }, "objects": [], "instanceObjects": [ diff --git a/src-admin/src/App.js b/src-admin/src/App.js index 59afa944..d0d4bc3f 100644 --- a/src-admin/src/App.js +++ b/src-admin/src/App.js @@ -18,10 +18,10 @@ import GenericApp from '@iobroker/adapter-react-v5/GenericApp'; import { I18n, Loader, AdminConnection } from '@iobroker/adapter-react-v5'; import ConfigHandler from './components/ConfigHandler'; -import Devices from './components/Devices'; -import Controller from './components/Controller'; -import Bridges from './components/Bridges'; -import Options from './components/Options'; +import Options from './Tabs/Options'; +import Controller from './Tabs/Controller'; +import Bridges from './Tabs/Bridges'; +import Devices from './Tabs/Devices'; const productIDs = []; for (let i = 0x8000; i <= 0x801F; i++) { @@ -235,6 +235,7 @@ class App extends GenericApp { matter={this.state.matter} updateConfig={this.onChanged} showToast={text => this.showToast(text)} + checkLicenseOnAdd={type => this.checkLicenseOnAdd(type)} />; } @@ -250,9 +251,47 @@ class App extends GenericApp { matter={this.state.matter} updateConfig={this.onChanged} showToast={text => this.showToast(text)} + checkLicenseOnAdd={() => this.checkLicenseOnAdd('addDevice')} />; } + async getLicense() { + if (this.state.native.login && this.state.native.pass) { + if (this.state.alive) { + // ask the instance + const result = await this.socket.sendTo(`matter.${this.instance}`, 'getLicense', { login: this.state.native.login, pass: this.state.native.pass }); + if (result.error) { + this.showToast(result.error); + return false; + } + return result.result; + } + this.showToast('You need a running matter instance to add more than one bridge or more than 2 devices'); + return false; + } + return false; + } + + async checkLicenseOnAdd(type) { + if (type === 'addBridge') { + if (this.state.matter.bridges.filter(bridge => bridge.enabled).length >= 1) { + return this.getLicense(); + } + } else if (type === 'addDevice') { + if (this.state.matter.devices.filter(device => device.enabled).length >= 2) { + return this.getLicense(); + } + } else if (type === 'addDeviceToBridge') { + if (this.state.matter.bridges.filter(bridge => bridge.enabled && bridge.list.filter(dev => dev.enabled).length >= 5)) { + return this.getLicense(); + } + } else { + return false; + } + + return true; // User may add one bridge or one device + } + onSave(isClose) { super.onSave && super.onSave(isClose); diff --git a/src-admin/src/components/Bridges.js b/src-admin/src/Tabs/Bridges.js similarity index 94% rename from src-admin/src/components/Bridges.js rename to src-admin/src/Tabs/Bridges.js index d75b3e3f..dcaa0d07 100644 --- a/src-admin/src/components/Bridges.js +++ b/src-admin/src/Tabs/Bridges.js @@ -108,7 +108,7 @@ class Bridges extends React.Component { list: [], uuid: uuidv4(), }); - this.props.updateConfig(matter) + this.props.updateConfig(matter); }, 100); } } @@ -378,7 +378,14 @@ class Bridges extends React.Component { {data.connectionInfo.map((info, i) => - {info.vendor}{info.label ? ({info.label}) : null} + + {info.vendor} + {info.label ? + ( + {info.label} + ) + : null} + {info.connected ? {I18n.t('Connected')} : I18n.t('Not connected')} @@ -454,7 +461,7 @@ class Bridges extends React.Component { type: 'device', name: getText(device.name), originalName: getText(device.name), - bridgeIndex: bridgeIndex, + bridgeIndex, device: devIndex, vendorID: false, productID: false, @@ -704,7 +711,7 @@ class Bridges extends React.Component { type: 'bridge', name: getText(bridge.name), originalName: getText(bridge.name), - bridgeIndex: bridgeIndex, + bridgeIndex, vendorID: bridge.vendorID, originalVendorID: bridge.vendorID, productID: bridge.productID, @@ -721,9 +728,11 @@ class Bridges extends React.Component { - + - { e.stopPropagation(); @@ -750,8 +759,13 @@ class Bridges extends React.Component { {I18n.t('Devices')} - this.setState( - { + { + const isLicenseOk = await this.props.checkLicenseOnAdd('addDeviceToBridge'); + if (!isLicenseOk) { + this.props.alive && this.props.showToast('You need ioBroker.pro assistant or remote subscription to have more than 5 devices in bridge'); + return; + } + this.setState({ dialog: { type: 'bridge', name: getText(bridge.name), @@ -759,8 +773,8 @@ class Bridges extends React.Component { devices: bridge.list, addDevices: this.addDevicesToBridge, }, - }, - )} + }); + }} > @@ -781,7 +795,12 @@ class Bridges extends React.Component { {this.renderDebugDialog()} { + onClick={async () => { + const isLicenseOk = await this.props.checkLicenseOnAdd('addBridge'); + if (!isLicenseOk) { + this.props.alive && this.props.showToast('You need ioBroker.pro assistant or remote subscription to have more than one bridge'); + return; + } let i = 1; const name = `${I18n.t('New bridge')} `; while (this.props.matter.bridges.find(b => b.name === name + i)) { @@ -851,6 +870,7 @@ class Bridges extends React.Component { } Bridges.propTypes = { + alive: PropTypes.bool, matter: PropTypes.object, socket: PropTypes.object, productIDs: PropTypes.array, @@ -861,6 +881,7 @@ Bridges.propTypes = { bridgeStates: PropTypes.object, showToast: PropTypes.func, commissioning: PropTypes.object, + checkLicenseOnAdd: PropTypes.func, }; export default withStyles(styles)(Bridges); diff --git a/src-admin/src/components/Controller.js b/src-admin/src/Tabs/Controller.js similarity index 90% rename from src-admin/src/components/Controller.js rename to src-admin/src/Tabs/Controller.js index c8bc21bf..471ab623 100644 --- a/src-admin/src/components/Controller.js +++ b/src-admin/src/Tabs/Controller.js @@ -3,11 +3,7 @@ import PropTypes from 'prop-types'; import { withStyles } from '@mui/styles'; import { - FormControl, - InputLabel, - MenuItem, - Select, - Switch, TextField, + Switch, } from '@mui/material'; import { I18n } from '@iobroker/adapter-react-v5'; @@ -31,10 +27,6 @@ const styles = () => ({ }); class Controller extends React.Component { - constructor(props) { - super(props); - } - render() { return
diff --git a/src-admin/src/components/Devices.js b/src-admin/src/Tabs/Devices.js similarity index 99% rename from src-admin/src/components/Devices.js rename to src-admin/src/Tabs/Devices.js index 1eb4d1c6..cbb614fc 100644 --- a/src-admin/src/components/Devices.js +++ b/src-admin/src/Tabs/Devices.js @@ -390,6 +390,7 @@ class Devices extends React.Component { } Devices.propTypes = { + alive: PropTypes.bool, matter: PropTypes.object, socket: PropTypes.object, productIDs: PropTypes.array, @@ -398,6 +399,7 @@ Devices.propTypes = { detectedDevices: PropTypes.array, setDetectedDevices: PropTypes.func, commissioning: PropTypes.object, + checkLicenseOnAdd: PropTypes.func, }; export default withStyles(styles)(Devices); diff --git a/src-admin/src/components/Options.js b/src-admin/src/Tabs/Options.js similarity index 75% rename from src-admin/src/components/Options.js rename to src-admin/src/Tabs/Options.js index 37ce3dd6..bc88d347 100644 --- a/src-admin/src/components/Options.js +++ b/src-admin/src/Tabs/Options.js @@ -14,7 +14,7 @@ import { TextField, } from '@mui/material'; -import {I18n, Logo} from '@iobroker/adapter-react-v5'; +import { I18n, Logo } from '@iobroker/adapter-react-v5'; import { Check, Close, LayersClear } from '@mui/icons-material'; const styles = () => ({ @@ -39,7 +39,10 @@ class Options extends React.Component { super(props); this.state = { showDialog: false, - dialogLevel: 0 + dialogLevel: 0, + iotLogin: '', + iotPassword: '', + iotInstance: '', }; } @@ -59,27 +62,27 @@ class Options extends React.Component {
{I18n.t('The configuration of controller, bridges and devices will stay unchanged.')}
- {this.state.level ? I18n.t('Are you really sure?') :I18n.t('Are you sure?')} + {this.state.dialogLevel ? I18n.t('Are you really sure?') : I18n.t('Are you sure?')} : null}