Diferenciación de los paneles/estores/puertas

Hola,
con todo mi equipo Somfy, tengo persianas exteriores, toldos interiores y exteriores y ahora una puerta de garaje.
En la integración Matter, solo tengo persianas para los comandos y estados:




¿Es posible diferenciarlos?
Y llegaré incluso a añadir ventana y portal más adelante.
Posición de la persiana / Estado de la persiana
Posición del toldo / Estado del toldo
Posición de la puerta / Estado de la puerta
Posición de la ventana / Estado de la ventana

Si es necesario, puedo proporcionar los identificadores de Matterbridge (para los que tengo).
Posición del portal / Estado del portal

Hola :slight_smile:

No estoy seguro de que sea posible, en el lado de Matter estos 3 dispositivos son clústeres « WindowCovering »

Habría que ver si en el lado de Matterbridge hay un atributo que se comunica y que indica de qué tipo es cada funcionalidad.

¿Puedes hacerme capturas de pantalla de Matterbridge?

Tienes razón, solo envía 0x0202-MA-windowCovering en Matter para todos mis dispositivos :frowning:
Por otro lado, tenemos más información en el plugin matterbridge-somfy y está bien diferenciado.

Ejemplo de persiana de techo Velux:

[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] Device: Velux Bureau 
[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] - uniqueName RollerShutterVeluxIOComponent 
[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] - uiClass RollerShutter 
[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] - serial 612f437f-xxxx-xxxx-xxxx 
[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] - deviceURL io://xxxx-xxxx-xxxx/2602070 
[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] - commands [ 'addLockLevel', 'advancedRefresh', 'close', 'delayedStopIdentify', 'down', 'getName', 'identify', 'my', 'open', 'refreshMemorized1Position', 'removeLockLevel', 'resetLockLevels', 'setClosureAndLinearSpeed', 'setClosure', 'setDeployment', 'setMemorized1Position', 'setName', 'setPositionAndLinearSpeed', 'setPosition', 'setSecuredPosition', 'startIdentify', 'stop', 'stopIdentify', 'up', 'wink', 'pairOneWayController', 'setConfigState', 'unpairAllOneWayControllers', 'unpairOneWayController' ] 
[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] - states [ { name: 'core:NameState', type: 3, value: 'Velux Bureau' }, { name: 'core:PriorityLockTimerState', type: 1, value: 0 }, { name: 'core:CommandLockLevelsState', type: 3, value: '[]', lastUpdateTime: 1747209967000 }, { name: 'core:StatusState', type: 3, value: 'available' }, { name: 'core:DiscreteRSSILevelState', type: 3, value: 'normal' }, { name: 'core:RSSILevelState', type: 2, value: 62 }, { name: 'core:BatteryDiscreteLevelState', type: 3, value: 'good' }, { name: 'core:ClosureState', type: 1, value: 100 }, { name: 'core:OpenClosedState', type: 3, value: 'closed' }, { name: 'core:Memorized1PositionState', type: 1, value: 0 } ] 
[23:12:22.667] [Matterbridge somfy tahoma plugin] [debug] - added with uiClass
[23:12:22.992] [Matterbridge somfy tahoma plugin] [debug] Adding device: Velux Bureau 
[23:12:22.992] [Matterbridge somfy tahoma plugin] [debug] - uniqueName RollerShutterVeluxIOComponent 
[23:12:22.992] [Matterbridge somfy tahoma plugin] [debug] - uiClass RollerShutter 
[23:12:22.992] [Matterbridge somfy tahoma plugin] [debug] - serial 612f437f-xxxx-xxxx-xxxx 
[23:12:22.992] [Matterbridge somfy tahoma plugin] [debug] - deviceURL io://xxxx-xxxx-xxxx/2602070 
[23:12:22.992] [Matterbridge somfy tahoma plugin] [debug] - commands [ 'addLockLevel', 'advancedRefresh', 'close', 'delayedStopIdentify', 'down', 'getName', 'identify', 'my', 'open', 'refreshMemorized1Position', 'removeLockLevel', 'resetLockLevels', 'setClosureAndLinearSpeed', 'setClosure', 'setDeployment', 'setMemorized1Position', 'setName', 'setPositionAndLinearSpeed', 'setPosition', 'setSecuredPosition', 'startIdentify', 'stop', 'stopIdentify', 'up', 'wink', 'pairOneWayController', 'setConfigState', 'unpairAllOneWayControllers', 'unpairOneWayController' ] 
[23:12:22.993] [Matterbridge somfy tahoma plugin] [debug] - states [ { name: 'core:NameState', type: 3, value: 'Velux Bureau' }, { name: 'core:PriorityLockTimerState', type: 1, value: 0 }, { name: 'core:CommandLockLevelsState', type: 3, value: '[]', lastUpdateTime: 1747209967000 }, { name: 'core:StatusState', type: 3, value: 'available' }, { name: 'core:DiscreteRSSILevelState', type: 3, value: 'normal' }, { name: 'core:RSSILevelState', type: 2, value: 62 }, { name: 'core:BatteryDiscreteLevelState', type: 3, value: 'good' }, { name: 'core:ClosureState', type: 1, value: 100 }, { name: 'core:OpenClosedState', type: 3, value: 'closed' }, { name: 'core:Memorized1PositionState', type: 1, value: 0 } ] 
[23:12:23.007] [Matterbridge somfy tahoma plugin] [debug] - duration 30 
[23:12:23.007] [Velux Bureau] [debug] new MatterbridgeEndpoint: 0x0202-MA-windowCovering id: Velux Bureau number: undefined taglist: undefined 
[23:12:23.009] [Matterbridge] [debug] Adding bridged endpoint matterbridge-somfy-tahoma:Velux Bureau to Matterbridge aggregator node 
[23:12:23.057] [Endpoint] [info] Matterbridge.Matterbridge.VeluxBureau ready endpoint#: 37 type: MA_windowCovering (0x202) behaviors: ✓descriptor 💤matterbridge ✓identify ✓groups ✓windowCovering ✓bridgedDeviceBasicInformation ✓powerSource 
[23:12:23.108] [Matterbridge] [info] Subscribing attributes for endpoint Velux Bureau (VeluxBureau) plugin matterbridge-somfy-tahoma 
[23:12:23.116] [Matterbridge] [info] Added and registered bridged endpoint (7/7) Velux Bureau (VeluxBureau) for plugin matterbridge-somfy-tahoma

Ejemplo de persiana interior:

[23:12:22.671] [Matterbridge somfy tahoma plugin] [debug] Device: Velux Store 
[23:12:22.671] [Matterbridge somfy tahoma plugin] [debug] - uniqueName VerticalInteriorBlindVeluxIOComponent 
[23:12:22.672] [Matterbridge somfy tahoma plugin] [debug] - uiClass Screen 
[23:12:22.672] [Matterbridge somfy tahoma plugin] [debug] - serial 04064452-xxxx-xxxx-xxxx 
[23:12:22.672] [Matterbridge somfy tahoma plugin] [debug] - deviceURL io://xxxx-xxxx-xxxx/9733440 
[23:12:22.672] [Matterbridge somfy tahoma plugin] [debug] - commands [ 'addLockLevel', 'advancedRefresh', 'close', 'delayedStopIdentify', 'down', 'getName', 'identify', 'my', 'open', 'refreshMemorized1Position', 'removeLockLevel', 'resetLockLevels', 'setClosure', 'setMemorized1Position', 'setName', 'setPosition', 'setSecuredPosition', 'startIdentify', 'stop', 'stopIdentify', 'up', 'wink', 'pairOneWayController', 'setConfigState', 'unpairAllOneWayControllers', 'unpairOneWayController' ] 
[23:12:22.673] [Matterbridge somfy tahoma plugin] [debug] - states [ { name: 'core:NameState', type: 3, value: 'Velux Store' }, { name: 'core:PriorityLockTimerState', type: 1, value: 0 }, { name: 'core:CommandLockLevelsState', type: 3, value: '[]', lastUpdateTime: 1747209968000 }, { name: 'core:StatusState', type: 3, value: 'available' }, { name: 'core:DiscreteRSSILevelState', type: 3, value: 'normal' }, { name: 'core:RSSILevelState', type: 2, value: 80 }, { name: 'core:ClosureState', type: 1, value: 100 }, { name: 'core:OpenClosedState', type: 3, value: 'closed' } ] 
[23:12:22.673] [Matterbridge somfy tahoma plugin] [debug] - added with uiClass 
[23:12:23.184] [Matterbridge somfy tahoma plugin] [debug] Añadiendo dispositivo: Velux Store 
[23:12:23.184] [Matterbridge somfy tahoma plugin] [debug] - uniqueName VerticalInteriorBlindVeluxIOComponent 
[23:12:23.184] [Matterbridge somfy tahoma plugin] [debug] - uiClass Screen 
[23:12:23.184] [Matterbridge somfy tahoma plugin] [debug] - serial 04064452-xxxx-xxxx-xxxx 
[23:12:23.184] [Matterbridge somfy tahoma plugin] [debug] - deviceURL io://xxxx-xxxx-xxxx/9733440 
[23:12:23.185] [Matterbridge somfy tahoma plugin] [debug] - commands [ 'addLockLevel', 'advancedRefresh', 'close', 'delayedStopIdentify', 'down', 'getName', 'identify', 'my', 'open', 'refreshMemorized1Position', 'removeLockLevel', 'resetLockLevels', 'setClosure', 'setMemorized1Position', 'setName', 'setPosition', 'setSecuredPosition', 'startIdentify', 'stop', 'stopIdentify', 'up', 'wink', 'pairOneWayController', 'setConfigState', 'unpairAllOneWayControllers', 'unpairOneWayController' ] 
[23:12:23.185] [Matterbridge somfy tahoma plugin] [debug] - states [ { name: 'core:NameState', type: 3, value: 'Velux Store' }, { name: 'core:PriorityLockTimerState', type: 1, value: 0 }, { name: 'core:CommandLockLevelsState', type: 3, value: '[]', lastUpdateTime: 1747209968000 }, { name: 'core:StatusState', type: 3, value: 'available' }, { name: 'core:DiscreteRSSILevelState', type: 3, value: 'normal' }, { name: 'core:RSSILevelState', type: 2, value: 80 }, { name: 'core:ClosureState', type: 1, value: 100 }, { name: 'core:OpenClosedState', type: 3, value: 'closed' } ] 
[23:12:23.185] [Matterbridge somfy tahoma plugin] [debug] - duration 30 
[23:12:23.185] [Velux Store] [debug] new MatterbridgeEndpoint: 0x0202-MA-windowCovering id: Velux Store number: undefined taglist: undefined 
[23:12:23.189] [Matterbridge] [debug] Añadiendo punto final puenteado matterbridge-somfy-tahoma:Velux Store al nodo agregador de Matterbridge 
[23:12:23.199] [Endpoint] [info] Matterbridge.Matterbridge.VeluxStore endpoint listo#: 40 tipo: MA_windowCovering (0x202) comportamientos: ✓descriptor 💤matterbridge ✓identify ✓groups ✓windowCovering ✓bridgedDeviceBasicInformation ✓powerSource 
[23:12:23.221] [Matterbridge] [info] Suscribiendo atributos para el punto final Velux Store (VeluxStore) plugin matterbridge-somfy-tahoma 
[23:12:23.221] [Matterbridge] [info] Añadido y registrado punto final puenteado (10/10) Velux Store (VeluxStore) para el plugin matterbridge-somfy-tahoma

Voy a ver si encuentro información sobre Matter para la diferenciación.

¿Puedes hacerme capturas de pantalla de la interfaz de Matterbridge?

Acabo de encontrar en los registros de Matter de Matterbridge una « línea » que parece estar expuesta para obtener el tipo de dispositivo que también aparece en la interfaz de Matterbridge:
MA_windowCovering(0x33)/BridgedDeviceBasicInformation(0x39)/productName(0x3)="GarageDoor" (por ejemplo)






No estoy seguro de que sea estándar Matter, es solo un campo abierto (productName) que se rellena con Matterbridge.

Para poder diferenciarlo, debe haber un método oficial para identificar el tipo de dispositivo.

¿Puedes hacerme una captura de pantalla completa? ^^

¿Necesitas todas las líneas Clusters for device de uno de los dispositivos?
El caso es que probé las diferentes líneas y solo uniqueId, productName, nodeLabel y serialNumber son diferentes, todos los demás absolutamente idénticos :confused:







En ese caso hay que hablar con el desarrollador de la integración de Somfy Matterbridge. :slight_smile:

A menudo, es el atributo « featureMap » el que contiene booleanos para identificar de qué se trata.

Algunos termostatos, por ejemplo, diferencian las calefacciones de los sistemas de aire acondicionado poniendo un atributo « heating: true » frente a « cooling: true ».

Hola @pierre-gilles
¿Te suenan los EndProductTypeEnum en tu integración de Matter?

Es lo que permite potencialmente diferenciar los tipos de dispositivos.

¡No me dice nada!

¿Es un atributo que encuentras al descargar los nodos Matter en JSON?

Busca con diferentes tipos de mayúsculas y minúsculas.

He tomado un ejemplo y veo bien el EndProductType:

              {
                "id": "258",
                "name": "WindowCovering",
                "attributes": [
                  "0",
                  "1",
                  "2",
                  "3",
                  "4",
                  "5",
                  "6",
                  "7",
                  "8",
                  "9",
                  "10",
                  "11",
                  "12",
                  "13",
                  "14",
                  "15",
                  "16",
                  "17",
                  "18",
                  "19",
                  "23",
                  "26",
                  "65528",
                  "65529",
                  "65531",
                  "65532",
                  "65533",
-->>              "type",
                  "configStatus",
                  "operationalStatus",
-->>              "endProductType",
                  "mode",
                  "safetyStatus",
                  "physicalClosedLimitLift",
                  "physicalClosedLimitTilt",
                  "currentPositionLift",
                  "currentPositionTilt",
                  "numberOfActuationsLift",
                  "numberOfActuationsTilt",
                  "currentPositionLiftPercentage",
                  "currentPositionTiltPercentage",
                  "targetPositionLiftPercent100ths",
                  "targetPositionTiltPercent100ths",
                  "currentPositionLiftPercent100ths",
                  "currentPositionTiltPercent100ths",
                  "installedOpenLimitLift",
                  "installedClosedLimitLift",
                  "installedOpenLimitTilt",
                  "installedClosedLimitTilt",
                  "clusterRevision",
                  "featureMap",
                  "attributeList",
                  "acceptedCommandList",
                  "generatedCommandList"
                ],
                "commands": [
                  "0",
                  "1",
                  "2",
                  "4",
                  "5",
                  "7",
                  "8",
                  "upOrOpen",
                  "downOrClose",
                  "stopMotion",
                  "goToLiftValue",
                  "goToLiftPercentage",
                  "goToTiltValue",
                  "goToTiltPercentage"
                ],
                "all_keys": [
                  "id",
                  "name",
                  "revision",
                  "_type",
                  "supportedFeatures",
                  "isUnknown",
                  "endpointId",
                  "attributes",
                  "events",
                  "commands",
                  "subscribeAllAttributes",
                  "_triggerAttributeUpdate",
                  "_triggerEventUpdate",
                  "isAttributeSupported",
                  "isAttributeSupportedByName",
                  "isCommandSupported",
                  "isCommandSupportedByName",
                  "getTypeAttribute",
                  "setTypeAttribute",
                  "subscribeTypeAttribute",
                  "addTypeAttributeListener",
                  "removeTypeAttributeListener",
                  "getConfigStatusAttribute",
                  "setConfigStatusAttribute",
                  "subscribeConfigStatusAttribute",
                  "addConfigStatusAttributeListener",
                  "removeConfigStatusAttributeListener",
                  "getOperationalStatusAttribute",
                  "setOperationalStatusAttribute",
                  "subscribeOperationalStatusAttribute",
                  "addOperationalStatusAttributeListener",
                  "removeOperationalStatusAttributeListener",
                  "getEndProductTypeAttribute",
                  "setEndProductTypeAttribute",
                  "subscribeEndProductTypeAttribute",
                  "addEndProductTypeAttributeListener",
                  "removeEndProductTypeAttributeListener",
                  "getModeAttribute",
                  "setModeAttribute",
                  "subscribeModeAttribute",
                  "addModeAttributeListener",
                  "removeModeAttributeListener",
                  "getSafetyStatusAttribute",
                  "setSafetyStatusAttribute",
                  "subscribeSafetyStatusAttribute",
                  "addSafetyStatusAttributeListener",
                  "removeSafetyStatusAttributeListener",
                  "getPhysicalClosedLimitLiftAttribute",
                  "setPhysicalClosedLimitLiftAttribute",
                  "subscribePhysicalClosedLimitLiftAttribute",
                  "addPhysicalClosedLimitLiftAttributeListener",
                  "removePhysicalClosedLimitLiftAttributeListener",
                  "getPhysicalClosedLimitTiltAttribute",
                  "setPhysicalClosedLimitTiltAttribute",
                  "subscribePhysicalClosedLimitTiltAttribute",
                  "addPhysicalClosedLimitTiltAttributeListener",
                  "removePhysicalClosedLimitTiltAttributeListener",
                  "getCurrentPositionLiftAttribute",
                  "setCurrentPositionLiftAttribute",
                  "subscribeCurrentPositionLiftAttribute",
                  "addCurrentPositionLiftAttributeListener",
                  "removeCurrentPositionLiftAttributeListener",
                  "getCurrentPositionTiltAttribute",
                  "setCurrentPositionTiltAttribute",
                  "subscribeCurrentPositionTiltAttribute",
                  "addCurrentPositionTiltAttributeListener",
                  "removeCurrentPositionTiltAttributeListener",
                  "getNumberOfActuationsLiftAttribute",
                  "setNumberOfActuationsLiftAttribute",
                  "subscribeNumberOfActuationsLiftAttribute",
                  "addNumberOfActuationsLiftAttributeListener",
                  "removeNumberOfActuationsLiftAttributeListener",
                  "getNumberOfActuationsTiltAttribute",
                  "setNumberOfActuationsTiltAttribute",
                  "subscribeNumberOfActuationsTiltAttribute",
                  "addNumberOfActuationsTiltAttributeListener",
                  "removeNumberOfActuationsTiltAttributeListener",
                  "getCurrentPositionLiftPercentageAttribute",
                  "setCurrentPositionLiftPercentageAttribute",
                  "subscribeCurrentPositionLiftPercentageAttribute",
                  "addCurrentPositionLiftPercentageAttributeListener",
                  "removeCurrentPositionLiftPercentageAttributeListener",
                  "getCurrentPositionTiltPercentageAttribute",
                  "setCurrentPositionTiltPercentageAttribute",
                  "subscribeCurrentPositionTiltPercentageAttribute",
                  "addCurrentPositionTiltPercentageAttributeListener",
                  "removeCurrentPositionTiltPercentageAttributeListener",
                  "getTargetPositionLiftPercent100thsAttribute",
                  "setTargetPositionLiftPercent100thsAttribute",
                  "subscribeTargetPositionLiftPercent100thsAttribute",
                  "addTargetPositionLiftPercent100thsAttributeListener",
                  "removeTargetPositionLiftPercent100thsAttributeListener",
                  "getTargetPositionTiltPercent100thsAttribute",
                  "setTargetPositionTiltPercent100thsAttribute",
                  "subscribeTargetPositionTiltPercent100thsAttribute",
                  "addTargetPositionTiltPercent100thsAttributeListener",
                  "removeTargetPositionTiltPercent100thsAttributeListener",
                  "getCurrentPositionLiftPercent100thsAttribute",
                  "setCurrentPositionLiftPercent100thsAttribute",
                  "subscribeCurrentPositionLiftPercent100thsAttribute",
                  "addCurrentPositionLiftPercent100thsAttributeListener",
                  "removeCurrentPositionLiftPercent100thsAttributeListener",
                  "getCurrentPositionTiltPercent100thsAttribute"},
                  "setCurrentPositionTiltPercent100thsAttribute",
                  "subscribeCurrentPositionTiltPercent100thsAttribute",
                  "addCurrentPositionTiltPercent100thsAttributeListener",
                  "removeCurrentPositionTiltPercent100thsAttributeListener",
                  "getInstalledOpenLimitLiftAttribute",
                  "setInstalledOpenLimitLiftAttribute",
                  "subscribeInstalledOpenLimitLiftAttribute",
                  "addInstalledOpenLimitLiftAttributeListener",
                  "removeInstalledOpenLimitLiftAttributeListener",
                  "getInstalledClosedLimitLiftAttribute",
                  "setInstalledClosedLimitLiftAttribute",
                  "subscribeInstalledClosedLimitLiftAttribute",
                  "addInstalledClosedLimitLiftAttributeListener",
                  "removeInstalledClosedLimitLiftAttributeListener",
                  "getInstalledOpenLimitTiltAttribute",
                  "setInstalledOpenLimitTiltAttribute",
                  "subscribeInstalledOpenLimitTiltAttribute",
                  "addInstalledOpenLimitTiltAttributeListener",
                  "removeInstalledOpenLimitTiltAttributeListener",
                  "getInstalledClosedLimitTiltAttribute",
                  "setInstalledClosedLimitTiltAttribute",
                  "subscribeInstalledClosedLimitTiltAttribute",
                  "addInstalledClosedLimitTiltAttributeListener",
                  "removeInstalledClosedLimitTiltAttributeListener",
                  "getClusterRevisionAttribute",
                  "setClusterRevisionAttribute",
                  "subscribeClusterRevisionAttribute",
                  "addClusterRevisionAttributeListener",
                  "removeClusterRevisionAttributeListener",
                  "getFeatureMapAttribute",
                  "setFeatureMapAttribute",
                  "subscribeFeatureMapAttribute",
                  "addFeatureMapAttributeListener",
                  "removeFeatureMapAttributeListener",
                  "getAttributeListAttribute",
                  "setAttributeListAttribute",
                  "subscribeAttributeListAttribute",
                  "addAttributeListAttributeListener",
                  "removeAttributeListAttributeListener",
                  "getAcceptedCommandListAttribute",
                  "setAcceptedCommandListAttribute",
                  "subscribeAcceptedCommandListAttribute",
                  "addAcceptedCommandListAttributeListener",
                  "removeAcceptedCommandListAttributeListener",
                  "getGeneratedCommandListAttribute",
                  "setGeneratedCommandListAttribute",
                  "subscribeGeneratedCommandListAttribute",
                  "addGeneratedCommandListAttributeListener",
                  "removeGeneratedCommandListAttributeListener",
                  "upOrOpen",
                  "downOrClose",
                  "stopMotion",
                  "goToLiftValue",
                  "goToLiftPercentage",
                  "goToTiltValue",
                  "goToTiltPercentage"
                ]
              }

Al revisar un poco el código de Matterbridge, me parece que estos 2 parámetros (Type y EndProductType) permanecen en el mismo valor por defecto, lo que corresponde a Roller Shade en la especificación Matter 1.4.1:


Excelente :heart_eyes:

¿Puedes crear una solicitud de función « Matter: Diferenciar persianas/estores/puertas con el endProductType »? :slight_smile:

et voilà : [Matter] Différencier les volets/stores/portes avec le endProductType