[RESOLU] Gladys Gateway Forward Websocket

Quand je démarre mon service, tout va bien. Le premier poll récupere les valeur que j’attends, etc.
Quand je change la couleur de l’ampoule, mon service recoit bien les nouvelles valeurs de l’ampoule mais c’est gladys.event.emit qui envoi ca:

2019-11-17T20:06:06+0100 <debug> gateway.forwardWebsockets.js:21 (Gateway.forwardWebsockets) Unable to forward websocket to Gladys Gateway
2019-11-17T20:06:06+0100 <debug> gateway.forwardWebsockets.js:22 (Gateway.forwardWebsockets) Error: Not connected to socket, cannot send message
    at GladysGatewayJs.sendMessageAllUsers (/home/renaiku/repo/Gladys/server/node_modules/@gladysassistant/gladys-gateway-js/index.js:848:13)
    at GladysGatewayJs.newEventInstance (/home/renaiku/repo/Gladys/server/node_modules/@gladysassistant/gladys-gateway-js/index.js:878:17)
    at Gateway.forwardWebsockets (/home/renaiku/repo/Gladys/server/lib/gateway/gateway.forwardWebsockets.js:18:38)
    at EventEmitter.<anonymous> (/home/renaiku/repo/Gladys/server/utils/functionsWrapper.js:13:13)
    at EventEmitter.emit (events.js:194:15)
    at Event.emit (/home/renaiku/repo/Gladys/server/lib/event/index.js:8:16)
    at db.sequelize.transaction (/home/renaiku/repo/Gladys/server/lib/device/device.saveState.js:54:23)
2019-11-17T20:06:06+0100 <debug> gateway.forwardWebsockets.js:13 (Gateway.forwardWebsockets) Gateway : Forward websocket message : device.new-state

Le code qui produit ça (après avoir changé la valeur. La premiere récuperation du premier poll ne declenche pas d’erreur):

// COLOR
    const colorFeature = getDeviceFeature(device, DEVICE_FEATURE_CATEGORIES.LIGHT, DEVICE_FEATURE_TYPES.LIGHT.COLOR);
    const lastValue = colorFeature ? colorFeature.last_value : null;

    const currentColorState = convert.rgb.hex([response.color.red, response.color.green, response.color.blue]);
    const intColor = parseInt(`0x${currentColorState}`);
    console.debug('intColor: ' + intColor);
   
    console.debug('lastValue: ' + lastValue);
    console.debug('currentColorState: ' + currentColorState + ":" + parseInt(`0x${currentColorState}`) + ":" + convert.hex.keyword(currentColorState));    
    
    
    if (colorFeature && lastValue !== intColor) {
      this.gladys.event.emit(EVENTS.DEVICE.NEW_STATE, {
        device_feature_external_id: `magic-devices:${macAdress}:${DEVICE_FEATURE_TYPES.LIGHT.COLOR}`,
        state: intColor,
      });
    } else {
      logger.debug('COLOR FEATURE HAS THE SAME VALUE THAN BEFORE: ' + currentColorState);
    }

EDIT:
Pour info voici les console.debug que l’on voit dans la portion de code avant que je change de valeur (premier poll, et les suivant tant que je ne change pas la couleur de l’ampoule depuis mon smartphone) et après que je change la valeur (et que l’erreur s’affiche a chaque poll ensuite).

intColor: 16729645
lastValue: 16729645
currentColorState: FF462D:16729645:tomato

intColor: 3887359
lastValue: 16729645
currentColorState: 3B50FF:3887359:royalblue

Ton instance n’arrive pas à contacter Gladys gateway via websocket.
En dev ca me paraît pas choquant.

Niquel alors.

Mais du coup pourquoi la variable lastValue ne se met pas à jour ?
l’event est fired pourtant ?!

Ou alors je dois créer mes propres EVENTS.XXXX comme le service Xiaomi car EVENTS.DEVICE.NEW_STATE est reservé pour Gladys Gateway ?

On dirait bien que l’erreur empêche la transaction sequelize d’aboutir.
Je regarde sur mobile, donc pas très fiable, mais Check le fichier lib/device/device.saveState.js

Ce message n’est qu’un “debug”, ce n’est pas une erreur bloquante normalement. Cela bloque quelque chose dans ton cas?

Es-tu sur qu’il n’y a pas une erreur autre part?

Je vois que tu travaille sur les couleurs, est-ce qu’on pourrait en discuter aussi? ^^ C’est un sujet qui a été longuement débattu dans la v4, et on compte partir sur du HSL, pas des couleurs en int !

Ah !

Pour ce qui est de l’event, je ne suis pas encore allé voir dans le saveState.js que m’a conseillé d’aller voir @Boimb. Dans tous les cas, ma dernière observation c’est que last_value de la feature ne se mettait à jour qu’une seule fois (la première). Je fouillerais plus ce soir si je peux.

J’ai bien vu des fonction rgb to hsl dans Gladys je me demandais justement.
Je suis partis sur du int car le lint me demandait un Number pour le state dans le event.emit, j’ai pas réfléchis plus je voulais surtout bidouiller.

C’est vrai qu’il y a un débat possible sur les couleurs. IMO il suffit d’utiliser color-convert. Si Gladys utilise HSL ben suffit de faire

var convert = require('color-convert');

const currentDeviceColor ={
	red: 255,
	green: 0,
	blue: 0
};

this.gladys.event.emit(EVENTS.DEVICE.NEW_STATE, {
	device_feature_external_id: featureId,
	state: convert.rgb.hsl(currentDeviceColor),
});

Du moment que Gladys prend le format HSL de l’objet que renvois color-convert ben y’a pas de soucis. Surtout qu’en plus dans le front, cette lib retourne des keywords (au plus proche) pour le css. On peux imaginer le header d’une card d’un device qui change en fonction de la couleur et que la conversion soit simple a faire en dév !

// hsl(9,100%,64%)
setHeaderColor(state) {
	this.headerColor = convert.hsl.keyword(state.currentDeviceColor) // should return "tomato" as css keyword color
}

Je veux bien ! Vérifie bien que tes commandent s’exécute bien l’une après l’autre, il peut y avoir un soucis de concurrency.

Alors pour l’instant on est encore au stade de “débat” aha, rien n’a été implémenté étant donné qu’aucun service ne gère des couleurs pour l’instant. C’est en réflexion.

Mais effectivement ce qu’on veut dans Gladys:

  • Tout est au format HSL: dans Gladys, dans l’API, dans l’UI
  • Les services utilisent des fonctions de conversions si ils ont besoins d’un autre format (RGB, Int, etc…)

Ok, je vais tout gérer en HSL du coup ça restera compatible quoi qu’il se passe.
Par contre quand je regarde les constantes, je vois BRIGHTNESS mais pas LIGHTNESS. Je supposes que c’est la même chose ici du coup ?

En fait on va juste utiliser la variable COLOR. Séparer les 3 variables n’a pas d’intérêt. Je n’ai pas encore codé cette partie, le BRIGHTNESS est outdated, c’est du 100% work in progress.

Ca marche. Je vais utiliser HUE, SATURATION et BRIGHTNESS pour le moment histoire de pouvoir continuer a développer mon service. Je mapperais tout comme il faut quand COLOR sera prêt.

Le problème par contre avec certaines ampoules connectées… c’est que y’a pas que RGB, mais aussi W1 et W2 (blanc chaud et blanc froid). Donc les services qui devront gérer ce genre d’ampoules auront surement une interface a envisager.

L’ampoule à partir de laquelle je développe le service dispose par exemple de W1. Pour le moment je le gère comme TEMPERATURE (car la doc technique du device parle de warm_white). Je testerais voir si SET une valeur au warm_white change la valeur RGB. Si c’est pas le cas, je pense remplacer warm_white par une deuxieme feature de type COLOR. En tout cas, l’appli android a l’air de le gérer comme ca, quand je clique sur WARM ca met RGB a 0 … :sweat_smile: Bref, je dois continuer a creuser.

Je te recommande de passer par “COLOR” ! Il n’y a pas de “prêt”, si tu développe un service, alors c’est à toi de le faire c’est tout :slight_smile: Je voulais juste dire que je n’avais pas encore codé de service qui gérait les couleurs.

Après tu peux mettre plusieurs features qui derrière touche au même paramètres.

Exemple: dans philips hue, on a color + brightness + temperature, les trois touchent plus ou moins au mêmes paramètres de la lampe, mais brightness permet un contrôle de l’intensité lumineuse, et température de la température dans l’UI. Le service fait sa tambouille ensuite :slight_smile:

Haaaaaan. Ah ben si j’ai le droit d’aller toucher dans le “core” de Gladys pour creer COLOR j’y vais de ce pas ! (Enfin… quand je serais sortis du bureau).

Il existe déjà :slight_smile:

@pierre-gilles J’avais pas vraiment compris que je pouvais deja stocker autre chose qu’un INT dans COLOR … en vrai j’avais même pas essayé car le lint de VSCODE m’en demandait un … (J’ai du mal configurer les règles quelque part :thinking:)

Du coup ca marche niquel en mettant ce que je veux dedant :angel: !

Je rajoutes que j’ai corrigé le problème de websocket, il y avait un accès concurent … => [RESOLU] Comment récupérer les devices en RAM

En fait tu noteras que dans la table “t_device_feature”, il y a un attribut “last_value_string”. Dans certains cas, certains périphériques peuvent renvoyer une valeur non-numérique (image de caméra, couleur, etc…)

Attention comme pour l’instant on a jamais fais ça, je pense qu’il y a quelques modifications à réfléchir côté core ! Je ne suis pas sur que ça fonctionne out of the box comme ça ^^

Et pourtant … ca marche niquel chrome, je peux changer les valeur depuis l’appli android de mon device et le poll détecte tout comme il faut et me renvois les nouvelles valeurs dans le front.

A savoir que pour le moment COLOR est un array avec 3 valeurs [ hue, saturation, lightness ].
Ce n’est pas un objet { hue: value, saturation: value, lightness: value }
Au final un objet serait mieux, mais je n’ai pas encore essayé