Skip to content

Commit

Permalink
Fix #722: MQTT broker is now automatically started by Gladys
Browse files Browse the repository at this point in the history
* Embedded mqtt broker

* MQTT: use configuration method

* Docker pull + system tests

* Clean up caldav tests

* Embedded broker configuration

* Embeeded broker password display

* Remove unsued

* Auto-config embedded broker on install

* Embedded docker magic url + restart policy

* Fix merge issues

* Rollback to localhost url + connect container to network

* Embedded broker network mode info

* Fix read network mode

* Fix MQTT API URL

* Replace everything linked to Caldav

* Increase before/beforeEach timeout

* Fix tests: stop using global sinon in caldav tests

* Fix race condition

* Improve MQTT error handling in UI

* Add more timeout to mqtt.saveConfiguration tests

* Fix system.exec test

* Add more timout to tests

Co-authored-by: atrovato <1839717+atrovato@users.noreply.github.com>
  • Loading branch information
Pierre-Gilles and atrovato committed Aug 10, 2020
1 parent 82b6785 commit a787736
Show file tree
Hide file tree
Showing 70 changed files with 3,236 additions and 749 deletions.
6 changes: 6 additions & 0 deletions front/src/config/demo.json
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,12 @@
"configured": true,
"connected": true
},
"get /api/v1/service/mqtt/config": {
"useEmbeddedBroker": true,
"dockerBased": true,
"networkModeValid": true,
"brokerContainerAvailable": false
},
"get /api/v1/service/tasmota": {},
"get /api/v1/service/tasmota/device": [
{
Expand Down
11 changes: 10 additions & 1 deletion front/src/config/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,14 @@
"setup": {
"title": "MQTT configuration",
"mqttDescription": "You can connect Gladys to a MQTT broker to send & receive MQTT messages. Learn more about Gladys MQTT API <a href=\"https://gladysassistant.com/en/docs/api/mqtt-api\">here</a>.",
"embeddedBrokerLabel": "Broker Docker container",
"nonDockerEnv": "Gladys is not running on Docker, you cannot install a MQTT broker from here.",
"invalidDockerNetwork": "Gladys is under custom installation, to install broker from here, Gladys container should be configured with \"host\" network mode.",
"installBrokerContainer": "Use broker in a Docker container.",
"brokerDockerNotInstalled": "No broker is available yet on current Docker environment, continue to install and configure <a href=\"https://mosquitto.org/\">eclipse-mosquitto</a> broker inside a Docker container.",
"installBrokerButton": "Install broker on Docker",
"installingBrokerButton": "Installation in progress...",
"installBrokerError": "An error occured while installing Docker container, please consult Gladys logs.",
"urlLabel": "Broker URL",
"urlPlaceholder": "Ex: mqtt://[mqtt-broker-address]:[port]",
"userLabel": "Username",
Expand All @@ -473,7 +481,8 @@
"error": "An error occured while saving configuration.",
"connecting": "Configuration saved. Now connecting to your MQTT broker...",
"connected": "Connected to the MQTT broker with success !",
"connectionError": "Error while connecting, please check your configuration."
"connectionError": "Error while connecting, please check your configuration.",
"disconnected": "Disconnected from MQTT broker."
}
},
"xiaomi": {
Expand Down
13 changes: 11 additions & 2 deletions front/src/config/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,15 @@
},
"setup": {
"title": "Configuration MQTT",
"mqttDescription": "Vous pouvez connecter Gladys à un broker (courtier) MQTT pour envoyer et recevoir des messages MQTT. En savoir plus sur l'API Gladys MQTT <a href=\"https://gladysassistant.com/fr/docs/api/mqtt-api\">ici</a>.",
"mqttDescription": "Vous pouvez connecter Gladys à un broker (courtier) MQTT pour envoyer et recevoir des messages MQTT. En savoir plus sur l'API Gladys MQTT <a href=\"https://gladysassistant.com/fr/docs/api/mqtt-api/\">ici</a>.",
"embeddedBrokerLabel": "Broker dans un conteneur Docker",
"nonDockerEnv": "Gladys ne s'exécute actuellement pas Docker, il est impossible d'installer le broker MQTT depuis Gladys.",
"invalidDockerNetwork": "Gladys est basée sur une installation personalisée, pour installer le broker depuis cette page, le conteneur Docker de Gladys doit être démarré avec l'option \"network=host\".",
"installBrokerContainer": "Utiliser un broker dans un conteneur Docker.",
"brokerDockerNotInstalled": "Aucun broker n'est disponible actuellement sur votre environnement Docker, continuez pour installer and configurer le broker <a href=\"https://mosquitto.org/\">eclipse-mosquitto</a> dans un conteneur Docker.",
"installBrokerButton": "Installez le broker sur Docker",
"installingBrokerButton": "Installation en cours...",
"installBrokerError": "Une erreur est survenue lors de l'installation du conteneur Docker, veuillez consulter les logs Gladys.",
"urlLabel": "URL du broker",
"urlPlaceholder": "Ex: mqtt://[adresse-broker-mqtt]:[port]",
"userLabel": "Nom d'utilisateur",
Expand All @@ -535,7 +543,8 @@
"error": "Une erreur s'est produite lors de l'enregistrement de la configuration.",
"connecting": "Configuration enregistrée. Maintenant, connectez-vous à votre broker MQTT...",
"connected": "Connecté au broker MQTT avec succès !",
"connectionError": "Erreur lors de la connexion, veuillez vérifier votre configuration."
"connectionError": "Erreur lors de la connexion, veuillez vérifier votre configuration.",
"disconnected": "Déconnecté du broker MQTT."
}
},
"xiaomi": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Component } from 'preact';
import { Text, MarkupText } from 'preact-i18n';
import { RequestStatus } from '../../../../../utils/consts';

class SetupBrokerContainer extends Component {
installContainer = async () => {
this.setState({ installing: RequestStatus.Getting });
try {
await this.props.httpClient.post('/api/v1/service/mqtt/config/docker');
await this.props.loadProps();
this.props.updateConfiguration({ useEmbeddedBroker: true });
this.setState({ installing: RequestStatus.Success });
} catch (e) {
this.setState({ installing: RequestStatus.Error });
}
};

render({}, { installing }) {
return (
<div>
<div class="alert alert-info">
<MarkupText id="integration.mqtt.setup.brokerDockerNotInstalled" />
</div>
{installing === RequestStatus.Error && (
<div class="alert alert-danger">
<MarkupText id="integration.mqtt.setup.installBrokerError" />
</div>
)}
<div class="form-group">
{installing !== RequestStatus.Getting && (
<button type="button" class="btn btn-primary" onClick={this.installContainer}>
<Text id="integration.mqtt.setup.installBrokerButton" />
</button>
)}
{installing === RequestStatus.Getting && (
<button type="button" class="btn btn-primary btn-loading" disabled>
<Text id="integration.mqtt.setup.installingBrokerButton" />
</button>
)}
</div>
</div>
);
}
}

export default SetupBrokerContainer;
100 changes: 100 additions & 0 deletions front/src/routes/integration/all/mqtt/setup-page/SetupForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Component } from 'preact';
import { Text, Localizer } from 'preact-i18n';
import cx from 'classnames';

class SetupForm extends Component {
updateUrl = e => {
this.props.updateConfiguration({ mqttUrl: e.target.value });
};

updateUsername = e => {
this.props.updateConfiguration({ mqttUsername: e.target.value });
};

updatePassword = e => {
this.props.updateConfiguration({ mqttPassword: e.target.value, passwordChanges: true });
};

showPassword = () => {
this.setState({ showPassword: true });
setTimeout(() => this.setState({ showPassword: false }), 5000);
};

render(props, { showPassword }) {
return (
<form>
<div class="form-group">
<label for="mqttUrl" class="form-label">
<Text id={`integration.mqtt.setup.urlLabel`} />
</label>
<Localizer>
<input
id="mqttUrl"
name="mqttUrl"
placeholder={<Text id="integration.mqtt.setup.urlPlaceholder" />}
value={props.mqttUrl}
class="form-control"
onInput={this.updateUrl}
disabled={props.useEmbeddedBroker}
/>
</Localizer>
</div>

<div class="form-group">
<label for="mqttUsername" class="form-label">
<Text id={`integration.mqtt.setup.userLabel`} />
</label>
<Localizer>
<input
id="mqttUsername"
name="mqttUsername"
placeholder={<Text id="integration.mqtt.setup.userPlaceholder" />}
value={props.mqttUsername}
class="form-control"
onInput={this.updateUsername}
autoComplete="no"
/>
</Localizer>
</div>

<div class="form-group">
<label for="mqttPassword" class="form-label">
<Text id={`integration.mqtt.setup.passwordLabel`} />
</label>
<div class="input-icon mb-3">
<Localizer>
<input
id="mqttPassword"
name="mqttPassword"
type={props.useEmbeddedBroker && showPassword ? 'text' : 'password'}
placeholder={<Text id="integration.mqtt.setup.passwordPlaceholder" />}
value={props.mqttPassword}
class="form-control"
onInput={this.updatePassword}
autoComplete="new-password"
/>
</Localizer>
{props.useEmbeddedBroker && (
<span class="input-icon-addon cursor-pointer" onClick={this.showPassword}>
<i
class={cx('fe', {
'fe-eye': !showPassword,
'fe-eye-off': showPassword
})}
/>
</span>
)}
</div>
</div>

<div class="form-group">
<button type="submit" class="btn btn-success" onClick={props.saveConfiguration}>
<Text id="integration.mqtt.setup.saveLabel" />
</button>
</div>
</form>
);
}
}

export default SetupForm;
Loading

0 comments on commit a787736

Please sign in to comment.