Support Schneider wiser CCTFR6700

Bonjour,

Mon chauffage est piloté par les schneider wiser: https://www.leroymerlin.fr/produits/electricite-domotique/domotique-et-objets-connectes/domotique/accessoires-de-gestion-du-chauffage/kit-thermostat-connecte-radiateur-electrique-wiser-schneider-electric-ccrftr6905-83421944.html

J’utilise actuellement le hub wiser mais j’aimerai tout passer sous Jeedom.

J’ai donc essayé le plugin zigbee beta et voici ce qui ne fonctionne pas:

  • Pas de réglage fil pilote/contacteur
  • Le CCTFR6700 clignote rouge
  • La température mesurée par le CCTFR6700 est -327.7 °C

Note j’ai aussi des problème avec le thermostat, mais je traiterai ça dans un autre sujet si je n’y arrive pas tout seul.

Comme j’ai un sniffer zigbee et que je connais pas mal le python, j’ai apporté quelques modifications au plugin pour ajouter le contrôle du fil pilote.
J’ai également fait d’autres modifications:

  • Copie du reporting observé lors du sniff avec le hub officiel
    => Note: lors de mon sniff, les trame de configuration de reporting sont indiquées comme malformées, a investiguer peut-être. J’ai comparé avec la norme, tout me semble bon
  • Ajout de paramètre d’identification spécifiques (Cluster basic 0xE007 et 0xE009)

Ajout d’un "specific": dans plugins/zigbee/resources/zigbeed/specifics/schneider

  • Dans __init__.py:
import logging
from . import details
import shared

class SchneiderSpecifics():
	def __init__(self):
		self.manuf = 'Schneider Electric'
		self.specific = ['init','reporting']

	def isvalid(self,manufacturer):
		if manufacturer == self.manuf:
			return True

	def init(self,device):
		if (device.model in ['CCTFR6700']):
			endpoints = device.endpoints.items()
			logging.debug('Found Schneider heater controller Specifics')
			for endpoint_id, ep in device.endpoints.items():
				if endpoint_id == 1:
					cluster = details.SchneiderPilotModeCluster(ep, is_server=True)
					for oldcluster in ep.in_clusters.values():
						if oldcluster.cluster_id == cluster.cluster_id:
							cluster._attr_cache=oldcluster._attr_cache
							break
					ep.add_input_cluster(cluster.cluster_id, cluster)

					cluster = details.SchneiderBasicCluster(ep, is_server=True)
					for oldcluster in ep.out_clusters.values():
						if oldcluster.cluster_id == cluster.cluster_id:
							cluster._attr_cache=oldcluster._attr_cache
							break
					ep.add_output_cluster(cluster.cluster_id, cluster)


	async def reporting(self, model, cluster_id, ep_id, cluster):
		logging.debug('Checking specific reporting for device '+str(model)+' '+str(cluster_id)+' '+str(ep_id))
		if model in details.REPORTING_SPECIFIC and cluster_id in details.REPORTING_SPECIFIC[model] and ep_id in details.REPORTING_SPECIFIC[model][cluster_id]:
			logging.debug('Found specific reporting ' + str(details.REPORTING_SPECIFIC[model][cluster_id][ep_id]))
			for reporting in details.REPORTING_SPECIFIC[model][cluster_id][ep_id]:
				logging.debug('Setting specific reporting ' + str(reporting))
				await cluster.configure_reporting(reporting["attr"], reporting["min"],reporting["max"], reporting["report"])
		else:
			logging.debug('No specific reporting found')

shared.JEEDOM_SPECIFIC.append(SchneiderSpecifics)
  • Dans details.py:
import logging
from zigpy.zcl.clusters.general import Basic
from zigpy.zcl.clusters.smartenergy import Metering
from zigpy.zcl.clusters.hvac import Thermostat 
from zigpy.quirks import CustomCluster
import zigpy.types as types

REPORTING_SPECIFIC = {
	'CCTFR6700' :{
		Metering.cluster_id:{
			2:[
				{"attr":"current_summ_delivered","min":60,"max":60,"report": 1},
			 	{"attr":"instantaneous_demand","min":60,"max":60,"report": 1}
			]
		},
		Thermostat.cluster_id:{
			1:[	{"attr":"occupied_heating_setpoint","min":60,"max":60,"report": 1}]
		}
	}
}


class SchneiderBasicCluster(CustomCluster, Basic):
	"""Schneider basics cluster."""
	manufacturer_attributes = {
		0xE007: ("tb0", types.enum16),
		0xE009: ("tb1", types.CharacterString)
	}

class SchneiderPilotModeCluster(CustomCluster):
	"""Schneider Pilot mode cluster."""
	cluster_id = 0xFF23
	name = "Schneider Pilot Mode"
	ep_attribute = "pilot_mode"
	manufacturer_attributes = {
		0x0031: ("controller_pilot_mode", types.enum8)
	}

Enfin dans igbee/core/config/devices/schneider/Schneider_Electric.CCTFR6700.json j’ai ajouté

  • config:
"config" : [
     {"endpoint" : 1,"cluster":65315,"attribute":49, "name":"Command Type","type":"select","values":
      [
        {"value":1,"name":"Contactor"},
        {"value":3,"name":"Fil Pilot"}
      ] 
    } 
  ],

Ce qui marche:

  • Je peux régler le fonctionnement contacteur/fil pilote
  • Le contrôleur a l’air de réguler correctement autour de son setpoint

Ce qui ne marche pas:

  • Le contrôleur clignote toujours rouge
  • La température mesurée est toujours à -327.7 °C
2 « J'aime »

Bonjour,
Belle analyse c’est rare d’aller jusque la bravo. J’ai rajouté tes fichiers dans le plugin ca sera disponible en beta demain et dans la prochaine stable

Pour le soucis de temperature je pense que c’est du à l’absence de sonde (de mémoire sur ce module faut en acheter une a coté et la brancher sur la sortie sonde, je sais par contre pas comment le systeme fait en mode wiser hub)

Pour la led rouge de mémoire c’est quand le module a pas fait une full inclusion doit falloir lui envoyer un attribut pour lui dire c’est bon inclusion fini.

Merci pour ton retour.

La sonde existe, elle revoit bien la température dans la communication sniffé avec le Hub Schneider.

Il doit y avoir un truc que je loupe dans l’inclusion qui doit entraîner les deux problèmes (LED rouge et température mesurée), mais j’ai beau éplucher le sniff, je ne vois pas ce que fait le Hub en plus. Mises à part peut-être ces trames de reporting malformées…

Ca serait fourbe quand meme de volontairement devoir mettre des trame malformée pour que ca marche…

Il y a un autre truc bizarre dans le sniff, le contrôleur demande une autre clé après l’inclusion « Key Type: Trust Center Link Key (0x04) », que lui fournit le Hub.
Mais je ne vois aucune trame chiffrée avec cette clé ensuite.

Voir ici pour la TCL Key

Je ne suis pas sur que cela réponde à mon histoire de clé, mais je n’ai pas été très clair:

  • Lors de l’association le module et le hub échangent un première clé de chiffrement « Key Type: Standard Network Key (0x01) » avec laquelle sont chiffrés tous le messages suivant.
  • Ensuite le module et hub dialoguent, puis, juste après le bind des clusters (environ 3s après l’association), le module émet un
ZigBee Application Support Layer Command
    Frame Control Field: Command (0x21)
    Counter: 194
    ZigBee Security Header
    Command Frame: Request Key
        Command Identifier: Request Key (0x08)
        Key Type: Trust Center Link Key (0x04)

Auquel le hub répond avec une clé qui n’est pas la même clé que lors de l’appairage, et ne semble pas utilisée ensuite pour du chiffrement de message.

ZigBee Application Support Layer Command
    Frame Control Field: Command (0x21)
    Counter: 16
    ZigBee Security Header
    Command Frame: Transport Key
        Command Identifier: Transport Key (0x05)
        Key Type: Trust Center Link Key (0x04)
        Key: <blablabla>
        Extended Destination: SiliconL_ff:fe:3e:fe:4d (68:0a:e2:ff:fe:3e:fe:4d)
        Extended Source: SiliconL_ff:fe:df:b3:ac (08:6b:d7:ff:fe:df:b3:ac)

Du coup je me demande si ce n’est pas une sécurité tordue en plus de la part de Schneider.

Bon pour la température j’ai avancé, la température est remontée par un reporting du cluster TemperatureMeasurement (0x0402), attribut 0x0000. Ce n’est donc pas le LocalTemperature du cluster Thermostat (0x201).

Cependant quand j’essaie de lire, ou de configurer le reporting, j’ai l’erreur « Unsupported attribute ».

Dans la com’ avec le hub officiel, l’attribut est envoyé automatiquement par le contacteur, sans configuration de reporting préalable.
Le reporting démarre juste après l’échange de « seconde » clé et puis l’écriture de l’attribut « fil pilote ».

Est-il possible de forcer la valeur de cette seconde clé (Trust Center Link Key (0x04))?

Je peux pas te dire la ça se passe dans zigpy. En théorie oui mais faut modifier zigpy ce qui est compliqué…

1 « J'aime »

Selon la doc zigate, c’est la commande 0x0022; j’ai regardé le code de Zigpy-zigate et la commande n’est pas implémentée.
Je pense qu’il doit être possible d’appeler directement Zigate.command si on a accès à l’instance de la classe Zigate.

J’essaierai de de faire ça demain, ça va être du code dégueu mais c’est pour voir si c’est bien ça le problème.

Bon test après ça sera pure zigate a voir comment le faire avec tout type de contrôleur. Après avec zigpy tu as accès à la couche zdo donc ça doit être possible

Bon ben je me suis cassé les dents.
A priori le SDK NXP utilisé par la zigate ne permet pas de configurer la Trust Center Link Key, qui est générée aléatoirement. https://www.nxp.com/docs/en/user-guide/JN-UG-3113.pdf#G9.1050981

Du coup je ne sais plus trop quoi tester…

Salut, j’ai refait quelque essais et il me semble avoir mis le doigt sur ce qui diffère entre l’appairage officiel et le plugin.

A un moment, le contacteur envoie une requête « Node Descriptor Request » au coordinateur et la réponse diffère.
C’est suite à cette réponse le contacteur devrait demander la « Trust Center Link Key (0x04) », ce qu’il ne fait pas avec le plugin.

La réponse avec le hub du constructeur:

ZigBee Device Profile, Node Descriptor Response, Rev: 22, Nwk Addr: 0x0000, Status: Success
    Sequence Number: 130
    Status: Success (0)
    Nwk Addr of Interest: 0x0000
    Node Descriptor
        .... .... .... .000 = Type: 0 (Coordinator)
        .... .... .... 0... = Complex Descriptor: False
        .... .... ...0 .... = User Descriptor: False
        .... 0... .... .... = 868MHz BPSK Band: False
        ..0. .... .... .... = 902MHz BPSK Band: False
        .1.. .... .... .... = 2.4GHz OQPSK Band: True
        0... .... .... .... = EU Sub-GHz FSK Band: False
        Capability Information: 0x8f
            .... ...1 = Alternate Coordinator: True
            .... ..1. = Full-Function Device: True
            .... .1.. = AC Power: True
            .... 1... = Rx On When Idle: True
            .0.. .... = Security Capability: False
            1... .... = Allocate Short Address: True
        Manufacturer Code: 0x1010
        Max Buffer Size: 82
        Max Incoming Transfer Size: 82
        Server Flags: 0x2c41
            .... .... .... ...1 = Primary Trust Center: True
            .... .... .... ..0. = Backup Trust Center: False
            .... .... .... .0.. = Primary Binding Table Cache: False
            .... .... .... 0... = Backup Binding Table Cache: False
            .... .... ...0 .... = Primary Discovery Cache: False
            .... .... ..0. .... = Backup Discovery Cache: False
            .... .... .1.. .... = Network Manager: True
            0010 110. .... .... = Stack Compliance Revision: 22
        Max Outgoing Transfer Size: 82
        Descriptor Capability Field: 0x00
            .... ...0 = Extended Active Endpoint List Available: False
            .... ..0. = Extended Simple Descriptor List Available: False

Et celle avec le coordinateur du plugin:

ZigBee Device Profile, Node Descriptor Response, Nwk Addr: 0x0000, Status: Success
    Sequence Number: 130
    Status: Success (0)
    Nwk Addr of Interest: 0x0000
    Node Descriptor
        .... .... .... .000 = Type: 0 (Coordinator)
        .... .... .... 0... = Complex Descriptor: False
        .... .... ...1 .... = User Descriptor: True
        .... 0... .... .... = 868MHz BPSK Band: False
        ..0. .... .... .... = 902MHz BPSK Band: False
        .1.. .... .... .... = 2.4GHz OQPSK Band: True
        0... .... .... .... = EU Sub-GHz FSK Band: False
        Capability Information: 0x0f
            .... ...1 = Alternate Coordinator: True
            .... ..1. = Full-Function Device: True
            .... .1.. = AC Power: True
            .... 1... = Rx On When Idle: True
            .0.. .... = Security Capability: False
            0... .... = Allocate Short Address: False
        Manufacturer Code: 0x1135
        Max Buffer Size: 89
        Max Incoming Transfer Size: 61
        Server Flags: 0x0040
            .... .... .... ...0 = Primary Trust Center: False
            .... .... .... ..0. = Backup Trust Center: False
            .... .... .... .0.. = Primary Binding Table Cache: False
            .... .... .... 0... = Backup Binding Table Cache: False
            .... .... ...0 .... = Primary Discovery Cache: False
            .... .... ..0. .... = Backup Discovery Cache: False
            .... .... .1.. .... = Network Manager: True
            0000 000. .... .... = Stack Compliance Revision: 0
        Max Outgoing Transfer Size: 61
        Descriptor Capability Field: 0x00

Je vois deux différence qui me semble pouvoir impacter le comportement du contacteur:

  • User Descriptor = False avec le hub officiel
  • Primary Trust Center = True avec le hub officiel

Il y a d’autres différences mais j’aimerai pouvoir changer ce Primary Trust Center, saurais-tu comment faire?

Salut,
Impressionnant… Mais la je saurais pas te dire pour changer ca ni même ce que c’est… La c’est dans le méandre de zigpy mais j’ai peur qu’il n’est pas prévu de le changer par device (si c’est changeable).

La TCLK est fournie par le coordinateur et ne peut être changée que pour tout le réseau et pas équipement par équipement. Cette clef de sécurité doit faire partie de la configuration du coordinateur (facile à faire sous deCONZ mais avec Ziggpy je n’ai pas encore testé).
Dans le cas qui nous concerne ici il n’y a pas besoin de changer la TCLK mais de savoir pourquoi le coordinateur autre que la passerelle Schneider ne semble pas la retourner sur requête de l’équipement. Le coordinateur non officiel n’est pas déclaré comme Primary Trust Center ce doit être la cause principale. As tu bien fait un reset de ton équipement avant de l’intégrer dans le nouveau réseau ?
Ce fut la même galère voici un certain temps avec les équipements Legrand. Je serais étonné quand même que Schneider ait mis en place un échange via des clusters spécifiques basé sur le code manufacturier pour brider toute inclusion ailleurs que sur un réseau maison.

1 « J'aime »

Je fais bien un reset de l’équipement avant inclusion.

J’ai remarqué que la Z-Stack 3.0.2 de TI devrait activer ce bit.
Je suis entrain de faire des essais avec ma CC2531 en forçant également le manufacturer code du coordinateur.

Le soucis c’est que c’est cette clé qui me servait de sniffeur. Du coup je suis aveugle sur le réseau, c’est pas super.

Salut,

J’ai fini par faire marcher ce CCTFR6700. En fait le truc sioux c’est que le thermostat n’a pas de mesure de température interne, et doit donc recevoir la température via un ‹ report attribute ›.
Après ça, le réglage du setPoint et du mode fil pilote, tout fonctionne au nominal.

Avec un thermostat externe qui supporte le bind ça devrait aller tout seul. Pour mes tests, le coordinateur transmet les repport attribute du thermostat (car le thermostat CCTFR6400 qui va avec refuse le bind).

Bonjour H3bu ,

je suis aussi acheter ce module «  » CCTFR6700 «  »,
j’avais déjà commencer par essayer de le faire fonctionner avec le plugin
Deconz , sans succès même pas inclusion .

Je vient de tester avec le plugin Zigbee et effectivement j’ai ce petit souci, je vois que beaucoup de boulot dessus a déjà été fait.
Donc déja merci !

Mais serai t’il possible plus explication au sujet de la solution « report attribute », un petit tuto serai super coool.

Merci d’avance

cordialement.

My config :
Jeedom 4.1.22
Clé Conbee2
Raspeberry4 pi 2go

Salut,

J’ai ajouté le support de ce module CCTFR6700 ainsi que le CCTFR6400 sur zigbee2mqtt (Add CCTFR6400 (#2558) · Koenkk/zigbee-herdsman-converters@d0fb06c · GitHub)

Le support du CCTFR6400 est partiel (par d’affichage température cible) car il faut un firmware particulier pour cela.

Pour que le CCTFR6700 fonctionne, il faut lui faire des « set » régulier (sur changement et toutes les 5mn environ) de température mesurée, pour cela il faut un capteur de température. J’ai fais un petit plugin sur home assistant pour ça, mais ça doit être faisable sans soucis sur jeedom.

Salut,
merci pour la réponse rapide!
Désoler pour le retour tardif.
J’ai réussi a l’inclure sur Zigbee2mqtt

Mais ,ce j’ai message
L’équipement n’a pas pu être complètement intégré.

Modèle : CCTFR6700
Fabricant : Schneider Electric
-------------------------
### Property inconnue : "schneider_pilot_mode. Commande : {"access":7,"description":"Controls piloting mode","name":"schneider_pilot_mode","property":"schneider_pilot_mode","type":"enum","values":["contactor","pilot"]}
-------------------------
### Property inconnue : "temperature_measured_value. Commande : {"access":2,"name":"temperature_measured_value","property":"temperature_measured_value","type":"numeric"}


#### Last Payload : 
{"device":{"friendlyName":"0x000b3cfffeff8f77","ieeeAddr":"0x000b3cfffeff8f77","manufacturerID":4190,"manufacturerName":"Schneider Electric","model":"CCTFR6700","networkAddress":35182,"powerSource":"Mains (single phase)","type":"Router","zclVersion":3},"linkquality":143,"local_temperature":-327.68,"pi_heating_demand":0,"power":0}

En parallèle j’ai envoyer un message a « MrGreen »
``
Désoler mais je n’est pas tous compris, mais je vais voir ce que je peut faire pour instant , je suis en train de migrer tous mes modules « deconz » sur « Zigbee2mqtt », de plus je vois que le travaille fait par Mr green est vraiment beaucoup plus complet sur sont plugin :grinning:

Après ça je vais voir comment, la température de mes capteur température.

Ps configuration " Piece Salon, Salle a Manger, Cuisine Ouverte ":
*Thermostat contrôler par Jeedom
*Température pris par plusieurs capteur Ouverture/Température « Aqara »
*Capteur Ouverture de Porte
*Capteur de présence
*Gestion de la consigne via Google Nest Hub Max
*Et Contrôleur radiateur par fils pilote

Ce que j’ai compris :
*C’est qu’il faut que j’arrive a renvoyer la température de mes capteurs ((moyenne)) vers Contrôleur radiateur.
*Je devrait faire une requête tous les 5min.(set)

Ce que j’ai Pas compris :
*Le support du module que tu a créer est t’il déjà intégrer a « Zigbee2mqtt » ou
dois je le copier coller quelque part.
*La requête (SET) dois je le faire par Jeedom ou par « Zigbee2mqtt ».

Merci
Cordialement :grinning:

1 « J'aime »