Réseau domotique en ESP8266: Début d'un projet avec PReact

Pour mon projet domotique, j'ai besoin d'un dashboard. C'est à dire un endroit ou toutes les informations importantes seront accessibles. Comme je compte servir ce dashboard depuis un ESP8266 pour éviter d'installer un raspberry pi juste pour un serveur web, je dois garder une taille de fichiers la plus minimale possible.

Pourquoi preact ?

Le projet sera réalisé en React. Tout d'abord parce que je travaille tous les jours avec depuis 5 ans, et donc c'est la technologie avec laquelle je suis le plus efficace. Mais aussi parce qu'un dashboard c'est bien, mais un dashboard réactif et rapide c'est mieux! Enfin, comme dis dans l'intro, la puissance coté "serveur" sera limitée puisque tout sera hébergé sur un ESP8266. Du coup avoir un affichage 100% coté client est un must dont on ne peut pas se passer !

Toujours pour cette histoire de limiter les besoins en serveur, j'ai choisi Preact. Preact est une version allégée de React (seulement 12% !).

Preact fait 16K, en comparaison React a besoin de 133K, soit 12% seulement, pour les mêmes fonctionnalités.

Pourquoi héberger sur un ESP ?

Je ne vois pas la domotique comme une aide au jour le jour. Je trouve que le contrôle des lumières et autres surprises du genre ne sont rien de plus que des gadgets. Par contre là ou, pour moi, la domotique à sa place, c'est dans les économies d'énergie. Pouvoir surveiller sa maison à longueur de journée est un atout majeur pour réduire notre impact écologique.

En gardant cette vision-là, il est difficile de justifier une base domotique écologique, tout en rajoutant l'empreinte énergétique d'un raspberry pi (environ 5W) qui tourne h24 pour se servir du serveur web environ 5 jours par mois?

Partant de la, étant donné qu'on a déjà un réseau wifi en ligne, et des ESP connectés dessus pour les capteurs, on peut plus facilement justifier d'en rajouter juste un pour centraliser le tout !

Mise en place du projet

Création d'un nouveau projet preact

Pour notre application, on va partir d'un starter de create-preact-app (comme create-react-app, mais en preact quoi!)

npm install preact-cli --global
preact create default dashboard

On va ensuite lancer l'application que l'on vient juste de créer:

cd dashboard
yarn start dev

Et voila! Si on ouvre http://localhost:8080/ on obtient l'application d'exemple:

btVDQ3L

Customisation de l'architecture

Actuellement, notre arborescence contient un dossier src (source), avec des components (sous composants, donc sous parties), des routes (les composants qui définissent les pages), un dossier style (pour le design) et enfin un index qui branche tout ça ensemble.

Notre objectif final est d'avoir un design de ce genre-là:

luke-chesser-JKUTrJ4vK00-unsplash

Pour ce faire, on utilisera un moteur de CSS-in-JS: PicoStyle. L'ajout de cette librairies dans notre projet se fait avec la commande:

yarn add preact-fluid picostyle

Pour notre projet, le dossier composant va contenir nos graphiques et les widgets de notre dashboard. Le dossier route contiendra notre seule page (pour l'instant).

Passons au code

Mise en place du design de base

Dans la suite, je vais citer les parties de code les plus intéressantes, mais le code complet est disponible sur github.

À la base de l'application, il y aura un fichier App.js. C'est le composant de base de notre arborescence Preact et notre point d'entrée unique dans l'application. Il se chargera d'inclure et d'organiser tous les autres.

class App extends Component {

	render() {
		return (
			<StyledBody id="app">
				<StyledContainer>
					<Header />
					<Routes />
				</StyledContainer>
			</StyledBody>
		);
	}
}
export default App

Le code est relativement simple, on déclare que notre app sera composée d'un Body, qui contient un conteneur, qui contient lui-même le Header et les Routes. Le Header sera le titre et le menu de notre application, c'est à dire qu'il sera commun a toutes nos pages. Le composant routes se chargera, en fonction de l'url, d'afficher la bonne route à l'utilisateur.

Si on s'attarde sur le composant Header (dans components/Header), on retrouve une partie fonctionnelle dans index.js et une partie visuelle dans styles.js. Cette séparation ajoute pas mal de clarté.

La partie fonctionnelle ne fait que placer les composants visuels dans une arborescence logique. C'est dans ce fichier que l'on intégrera plus tard les actions des différents boutons.

const Header = ({}) => (
  <HeaderWrapper>
    <HeaderWrapperInner>
      <HeaderTitle>
        <h1>Dashboard</h1>
      </HeaderTitle>
      <HeaderActions>
        <RoundButton>Logout</RoundButton>
      </HeaderActions>
    </HeaderWrapperInner>
  </HeaderWrapper>
)

export default Header

La partie visuelle définie des micro composants avec picostyle. Ici on indique simplement notre style sous forme d'un objet JS. Picostyle se chargera ensuite de créer les classes css adéquates pour que notre affichage fonctionne.

import { h } from "preact"
import picostyle from "picostyle"
const style = picostyle(h)

const HeaderWrapper = style("div")({
  height: '90px',
  width: '100%',
  display: 'flex',
  alignItems: 'stretch',
  marginBottom: '10px',
})

const HeaderWrapperInner = style("div")({
  display: 'flex',
  width: '100%',
  justifyContent: 'space-between',
  alignItems: 'center',
})

const HeaderTitle = style("h1")({
  display: 'flex',
  padding: 0,
  alignItems: 'stretch',
  alignContent: 'flex-end',
  '> h1': {
    color: 'white',
    fontSize: '1.2em',
    margin: '0',
    padding: '0',
  }
})

const HeaderActions = style("div")({

})

export {
  HeaderWrapper,
  HeaderWrapperInner,
  HeaderTitle,
  HeaderActions,
}

Et voila ! Notre rendu est le suivant:

2019-08-22 11-21-22

Je vous épargne les autres fichiers dans cet article mais pour ceux qui veulent consulter le projet complet, rendez vous sur github!

Dans un prochain article, nous créeront un composant graphique pour meubler un peu notre nouveau dashboard !