Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Controllers
  3. OpenHAB
  4. openHAB 2.5 binding and V_VARx

openHAB 2.5 binding and V_VARx

Scheduled Pinned Locked Moved OpenHAB
5 Posts 2 Posters 65 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • syntacrscS Offline
    syntacrscS Offline
    syntacrsc
    wrote on last edited by
    #1

    Hello.

    I hope someone can help me with an issue I'm facing while using mySensors binding for rolling shutters and using V_VAR channels.

    My Setup:
    Software:
    openHAB 2.5.5 stable release
    MySensors openHAB binding 2.5.0.202002161928
    Hardware:
    MySensors Ethernet gateway
    Rollershutters with functions UP/DOWN and TILT UP/TILT DOWN (7 TILT positions, like horizontal blinds) (no KNX!)

    The plan:
    Whenever openHAB starts I want openHAB to request the status of my rollershutter positions (UP or DOWN) and blind positions (1/7, 2/7 ... 7/7).
    Whenever the rollershutter position or blind position changes the node is supposed to send the new status to the controller/openHAB.

    Implementation:
    On the mySensors node I keep variables for rollershutter positions (0% = open to 100% = closed) and tilt-position (1/7 = min tilt to 7/7 fully tilt).
    The node sends both positions either when a command has been executed to change them (UP/DOWN or TILT-UP/TILT-DOWN) or when the controller requests them (via request command = message type = C_REQ).
    I've implemented an openHAB rule which priodically (for testing purposes every minute) requests the positions of the rollershutters and blind-position from the node, the node responds with both positions using V_VAR3 (rollershutter position) and V_VAR4 (tilt position).
    These requests cprrectly arrive at the node and the node responds with its position-values.

    Problem:
    When replying with the rollershutter position to the openhab rule request with e.g. 100 I get error "value must be between 0 and 100.
    When replying with the tilt position to the openhab rule request with e.g. 1 (for 1/7) or 0.14 (for 1/7th) the openHAB log shows error "value must be between 0 and 100.
    Whenever the node sends values 0 or 1 openhab accepts the values!

    What I tried so far:
    I assumed openHAB expects a percent value hence requiring a value between 0 and 1 (even though it says it must be between 0 and 100) so I tried to adjust my mySensors code to send decimals bt. 0 and 1 to represent values bt. 0 and 100 (percent) - no luck though!
    The log only shows 1.0 or 0.0 being received from node eventhough the node sends float(shutter position) / 100.0 for rollershutter position or float(tilt position) / 7.0 for tilt position.
    I've tried different formatting in the items file ([%.2f], [%d], none and many others) - no help!

    Is it possible that there is a bug in the binding implementation of V_VAR1 to V_VAR4 ?
    It seems to only accept values 0 and 1 for the V_VAR channels.
    Is it me? Am I missing anything here?

    Any help is highly appreciated!

    Thanks,
    Ralph...

    Things:

    Bridge mysensors:bridge-eth:gateway @ "Wohnzimmer" [  ipAddress="10.0.0.11",
                                           tcpPort=5003, 
                                           startupCheckEnabled=true, 
                                           imperial=false,
                                           sendDelay=200, 
                                           networkSanCheckSendHeartbeat=false, 
                                           networkSanCheckInterval=3,
                                           networkSanCheckSendHeartbeatFailAttempts=10,
                                           networkSanCheckEnabled=true,
                                           networkSanCheckConnectionFailAttempts=3 ]
    
    {
        cover BueroRalphJalousie                                        "Jalousie"                                  @ "Büro Ralph"          [ nodeId=7,    childId=4,     requestAck=false ]
    }
    

    Items:

    Rollershutter   BueroRalphJalousieAufAb      "Auf/ab"                      { channel="mysensors:cover:gateway:BueroRalphJalousie:cover" }
    Number BueroRalphJalousieStatusAufAb     "Status Auf/ab [%d]"   { channel="mysensors:cover:gateway:BueroRalphJalousie:var3" }
    Number BueroRalphJalousieStatusTilt          "Status Tilt [%.2f]"       { channel="mysensors:cover:gateway:BueroRalphJalousie:var4" }                                                 
    

    Rule:

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Stati von Node erfragen:
    rule HoleUnbekannteStati
    when 
        Time cron "0 0/1 * 1/1 * ? *"   //alle 1 Minuten   
    then 
    //  Jalousiesteuerung - UG:  
        if ( BueroRalphJalousieStatusAufAb.state == NULL 
            || BueroRalphJalousieStatusTilt.state == NULL  ) 
        {  
    //      make the node send in positions for rollershutters and blinds (yes it sends both even though only one (V_VAR3) is being requested!):
            sendCommand(mySMsg01, "7;4;2;0;26");  //erfrage Jalousie-AufAb-Status Buero Ralph von Node 7, Child 4, 2=request, 0 = kein acknowlege, 26 = V_VAR3 
            if ( DebugLogger.state == ON )  
            {  
                logInfo( "Jalousien.Rules.HoleUnbekannteStati", "Jalousie-Stati Buero Ralph werden von Node erfragt")
            }
        }    
    end 
    
    

    mySensors code (excerpt):

    void receive(const MyMessage &IncomingMessage)
    {
    //	Eingehende Anfrage:
    	if (IncomingMessage.destination == MY_NODE_ID
    		&& IncomingMessage.getCommand() == C_REQ )		//Wert fuer ein Child wird abgefragt!
    	{
    		for (byte i = 1; i <= AnzahlRaeume; i++) {
    			if (i == IncomingMessage.sensor)
    			{
    				if (IncomingMessage.type == V_VAR3
    					|| IncomingMessage.type == V_VAR4)
    				{
    					send(Jalousien[i - 1].MessageStatusAufAb.set(Jalousien[i - 1].StatusAufAb, 1), false);
    					send(Jalousien[i - 1].MessageStatusTilt.set(Jalousien[i - 1].StatusTilt, 1), false);
    				}
    			}
    		}
    	}
    }
    

    mySensors code (full copy):

    #include <Arduino.h>
    
    //#define MY_DEBUG
    #define MY_RADIO_RF24
    #define MY_NODE_ID 7
    #define MY_REPEATER_FEATURE
    
    #include <MySensors.h>
    #define MY_RF24_PA_LEVEL RF24_PA_HIGH
    
    //#define ACTIVE_LOW // comment out this line if your relays are active high
    
    #ifdef ACTIVE_LOW
    #define BitShiftRelaisNummer ~(1U << (RelaisNummer-1))
    #define AlleRelaisAus 0xFFFF
    #else
    #define BitShiftRelaisNummer (1U << (RelaisNummer-1))
    #define AlleRelaisAus 0U
    #endif
    
    int RelaisNummer;
    
    #define AnzahlRaeume 8  // Anzahl der Raeume
    
    //Setup Shift Register:
    const int clockPin		  = 4;
    const int outputEnablePin = 6;
    const int dataPin 	      = 7;
    const int latchPin		  = 8;
    
    typedef enum
    {
    	V_TILT_UP  = 90, V_TILT_DOWN  = 91, V_TILT_UP3 = 92, V_TILT_DOWN3 = 93,
    } custom_mysensors_data_t;
    
    typedef struct Jalousie
    {
    	uint8_t RaumNummer;
    	char *RaumName;
    	int RelaisNummerAuf;
    	int RelaisNummerAb;
    	int Fahrzeit;
    	int TiltSchritte;
    	int Command;
    	uint8_t StatusAufAb;	// (0=UP, 100=DOWN, 99=unknown), StatusTilt (0=UP)
    	uint8_t StatusTilt;		// (0=OPEN, 7=CLOSE, 9=unknown), StatusTilt (0=UP)
    	MyMessage MessageStatusAufAb;
    	MyMessage MessageStatusTilt;
    } JalousieTyp;
    
    JalousieTyp Jalousien[AnzahlRaeume] = //RaumNummer, RaumName, RalaisNummer Funktion "AUF", RelaisNummer Funktion "AB", Fahrzeit in Sek., TiltSchritte, Command, StatusAufAb (0=UP, 100=DOWN, 99=unknown), StatusTilt (0=UP, 100=DOWN, 99=unknown)
    {
    	{ 1, "Büro Christine", 		 1,  2, 45, 7, 0, 99, 0 },
    	{ 2, "Spielzimmer", 		 3,  4, 65, 7, 0, 99, 0 },
    	{ 3, "Nebenküche",			 5,  6, 45, 7, 0, 99, 0 },
    	{ 4, "Büro Ralph",			 7,  8, 45, 7, 0, 99, 0 },
    	{ 5, "Esszimmer",			 9, 10, 65, 7, 0, 99, 0 },
    	{ 6, "Wohnzimmer Terrasse",	11, 12, 65, 7, 0, 99, 0 },
    	{ 7, "Wohnzimmer Garten", 	13, 14, 65, 7, 0, 99, 0 },
    	{ 8, "Küche",				15, 16, 65, 7, 0, 99, 0 }
    };
    
    
    ////////////////////////////////////////////////////////////////////////////////
    void setup()
    {
    #ifdef DEBUG_ON
    	Serial.println();
    	Serial.println("SETUP - BEGIN");
    #endif
    
    //  BitShiftRegister vorbereiten:
    	pinMode(latchPin, OUTPUT);
    	pinMode(clockPin, OUTPUT);
    	pinMode(dataPin, OUTPUT);
    	pinMode(outputEnablePin, OUTPUT);
    	digitalWrite(outputEnablePin, LOW);
    
    //  BitShiftRegister auf "alles aus" schalten:
    	digitalWrite(latchPin, LOW); 							//DatenPipeline fuer BitShiftRegister "lahm" legen
    	shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus); 	//DatenPipeline in das BitShiftRegister laden:
    	shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus);
    	digitalWrite(latchPin, HIGH);  							//neue Daten im BitShiftRegister aktivieren:
    
    //  Jalousie-Messages vorbereiten:
    #ifdef DEBUG_ON
    	Serial.println();
    	Serial.println("RaumNummer, RelaisName, RelaisNr-AUF, RelaisNr-AB, Fahrzeit, Command, StatusAufAb, StatusTilt");
    #endif
    	for (byte i = 1; i <= AnzahlRaeume; i++) {
    		Jalousien[i - 1].MessageStatusAufAb.setSensor(Jalousien[i - 1].RaumNummer);	//ChildID
    		Jalousien[i - 1].MessageStatusAufAb.setType(V_VAR3);
    
    		Jalousien[i - 1].MessageStatusTilt.setSensor(Jalousien[i - 1].RaumNummer); 	//ChildID
    		Jalousien[i - 1].MessageStatusTilt.setType(V_VAR4);
    
    #ifdef DEBUG_ON
    		Serial.println(Jalousien[i - 1].RaumNummer + ", " + Jalousien[i - 1].RaumName, + ", " + Jalousien[i - 1].RelaisNummerAuf + ", " + Jalousien[i - 1].RelaisNummerAb + ", " + Jalousien[i - 1].Fahrzeit + ", " + Jalousien[i - 1].Command + ", " + Jalousien[i - 1].StatusAuf + ", " + Jalousien[i - 1].StatusAb);
    #endif
    	}
    
    #ifdef MY_DEBUG
    	Serial.println();
    	Serial.println("SETUP - END");
    #endif
    }
    
    //////////////////////////////////////////////////////////////////////////////////////
    void presentation()
    {
    
    #ifdef MY_DEBUG
    	Serial.println();
    	Serial.println("PRESENTATION - BEGIN");
    #endif
    
    	sendSketchInfo("Jalousie-Controller EG", "1.1");
    	for (byte i = 1; i <= AnzahlRaeume; i++) {
    		present(Jalousien[i - 1].RaumNummer, S_COVER, Jalousien[i - 1].RaumName, false);  //Jalousie
    	}
    
    #ifdef MY_DEBUG
    	Serial.println();
    	Serial.println("PRESENTATION - END");
    #endif
    }
    
    //////////////////////////////////////////////////////////////////////////////
    void JalousieBewegen(int RaumNummer, uint8_t Command)
    {
    	const int DauerTilt   = 150;
    	const int DauerFahren = 1100;
    	int Signaldauer 	  = DauerTilt;
    	int cycles 	 	      = 1;
    
    #ifdef MY_DEBUG
    	Serial.println();
    	Serial.println("JalousieFahren - BEGIN");
    	Serial.print("Command: ");
    	Serial.println(Command);
    #endif
    
    //  RelaisNummer (Funktion also AUF- oder AB-Relais) ermitteln und Signaldauer (Fahren oder TILT) festlegen:
    	switch (Command) {
    	case V_UP:
    		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
    		Signaldauer = DauerFahren;
    		Jalousien[RaumNummer - 1].StatusAufAb = 0;
    		Jalousien[RaumNummer - 1].StatusTilt = 0;
    		break;
    	case V_DOWN:
    		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAb;
    		Signaldauer = DauerFahren;
    		Jalousien[RaumNummer - 1].StatusAufAb = 100;
    		Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].TiltSchritte;
    		break;
    	case V_STOP:
    		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
    		Jalousien[RaumNummer - 1].StatusAufAb = 99;
    		break;
    	case V_PERCENTAGE:
    		// Hole Prozentsatz (0-100 oder STOP):
    		// to be implemented
    		RelaisNummer = 0;
    		break;
    	case V_TILT_UP:     //90 TILT-UP
    		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
    		if (Jalousien[RaumNummer - 1].StatusTilt >= cycles)
    		{
    			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt - cycles;
    		}
    		break;
    	case V_TILT_DOWN:  //"91 TILT-DOWN"
    		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAb;
    		if (Jalousien[RaumNummer - 1].StatusTilt <= ( Jalousien[RaumNummer - 1].TiltSchritte - cycles ))
    		{
    			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt + 1;
    		}
    		break;
    	case V_TILT_UP3:   //"92 TILT-UP3"
    		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
    		cycles       = 3;
    		if (Jalousien[RaumNummer - 1].StatusTilt >= cycles)
    		{
    			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt - cycles;
    		}
    		break;
    	case V_TILT_DOWN3: //"93 TILT-DOWN3"
    		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAb;
    		cycles       = 3;
    		if (Jalousien[RaumNummer - 1].StatusTilt <= (Jalousien[RaumNummer - 1].TiltSchritte - cycles))
    		{
    			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt + cycles;
    		}
    		break;
    	};
    
    #ifdef MY_DEBUG
    	Serial.print("Raumnummer: ");
    	Serial.println(RaumNummer);
    	Serial.print("JalousieRelaisNummer: ");
    	Serial.println(RelaisNummer);
    	Serial.print("BitShift-Relais-Nummer: ");
    	Serial.println(BitShiftRelaisNummer);
    #endif
    
    //  Relais (FunktionsNummer) fuer Signaldauer schalten:
    	if (RelaisNummer != 0)
    	{
    		for (int i = 1; i <= cycles; i++)
    		{
    //  		Relais einschalten:
    #ifdef MY_DEBUG
    			Serial.println("Schaltet ein");
    #endif
    			digitalWrite(latchPin, LOW);  											//DatenPipeline fuer BitShiftRegister "lahm" legen
    			shiftOut(dataPin, clockPin, MSBFIRST, highByte(BitShiftRelaisNummer)); 	//DatenPipeline in das BitShiftRegister laden
    			shiftOut(dataPin, clockPin, MSBFIRST, lowByte(BitShiftRelaisNummer));
    			digitalWrite(latchPin, HIGH);  											//neue Daten im BitShiftRegister aktivieren
    
    	//      Relais "gedrueckt" lassen:
    #ifdef MY_DEBUG
    			Serial.print("wartet ");
    			Serial.print(Signaldauer);
    			Serial.println(" ms");
    #endif
    			wait(Signaldauer);
    
    	//  	Relais ausschalten:
    #ifdef MY_DEBUG
    			Serial.println("Schaltet aus");
    #endif
    			digitalWrite(latchPin, LOW); 							//DatenPipeline fuer BitShiftRegister "lahm" legen
    			shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus);	//DatenPipeline in das BitShiftRegister laden
    			shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus);   //doppelt???
    			digitalWrite(latchPin, HIGH);  							//neue Daten im BitShiftRegister aktivieren
    
    			if (cycles > 1) {
    				wait(750);
    			}
    		}
    	}
    
    //	Neuen Zustand an Controller melden:
    	send(Jalousien[RaumNummer - 1].MessageStatusAufAb.set(Jalousien[RaumNummer - 1].StatusAufAb, 1), false);
    	send(Jalousien[RaumNummer - 1].MessageStatusTilt.set(Jalousien[RaumNummer - 1].StatusTilt, 1), false);
    
    #ifdef MY_DEBUG
    	Serial.println("JalousieFahren - END");
    #endif
    }
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////
    void loop()
    {
    
    #ifdef MY_DEBUG
    	Serial.println();
    	Serial.println("LOOP - BEGIN");
    #endif
    
    	for (byte i = 1; i <= AnzahlRaeume; i++)
    	{
    #ifdef MY_DEBUG
    		Serial.print('RaumNummer / Kommando: ');
    		Serial.print('  ');
    		Serial.print(i);
    		Serial.print(' / ');
    		Serial.println(Jalousien[i-1].Command);
    #endif
    		if (Jalousien[i - 1].Command != 0)
    		{
    			JalousieBewegen(Jalousien[i - 1].RaumNummer, Jalousien[i - 1].Command); 	//RaumNummer, Kommando
    			Jalousien[i - 1].Command = 0;
    		}
    	}
    #ifdef MY_DEBUG
    	Serial.println();
    	Serial.println("LOOP - END");
    	wait(4000);
    #endif
    }
    
    
    ////////////////////////////////////////////////////////////////////////////////
    void receive(const MyMessage &IncomingMessage)
    {
    	String Payload;
    
    	Payload = IncomingMessage.getString();
    
    #ifdef MY_DEBUG
    	Serial.println();
    	Serial.println("RECEIVE - BEGIN");
    	Serial.println();
    	Serial.println("Nachricht empfangen");
    	Serial.print("f�r Sensor: ");
    	Serial.println(IncomingMessage.sensor);
    	Serial.print("Typ: ");
    	Serial.println(IncomingMessage.type);
    	Serial.print("Sender: ");
    	Serial.println(IncomingMessage.sender);
    	Serial.print("Command: ");
    	Serial.println(IncomingMessage.getCommand() + "(1 = SET, 2 = REQUEST)");
    	Serial.print("IsAcknowledge: ");
    	Serial.println(IncomingMessage.isAck());
    	Serial.print("Payload als String: ");
    	Serial.println(Payload);
    	Serial.print("Message data: ");
    	Serial.println(IncomingMessage.data);
    #endif
    
    //	Eingehendes Kommando:
    	if (IncomingMessage.destination == MY_NODE_ID
    		&& IncomingMessage.getCommand() == C_SET )	//Wert fuer ein Child soll gesetzt werden!
    	{
    		Jalousien[IncomingMessage.sensor - 1].Command = IncomingMessage.type;
    		//  �ndere Command f�r % AUF/AB auf jeweils 0%, 100% bzw. STOP:
    		if ( IncomingMessage.type == V_PERCENTAGE and Payload == "0") {
    			Jalousien[IncomingMessage.sensor - 1].Command = V_UP;		//29
    		};
    		if ( IncomingMessage.type == V_PERCENTAGE and Payload == "100") {
    			Jalousien[IncomingMessage.sensor - 1].Command = V_DOWN;		//30
    		};
    		if ( IncomingMessage.type == V_PERCENTAGE and Payload == "STOP") {
    			Jalousien[IncomingMessage.sensor - 1].Command = V_STOP;		//31
    		};
    
    		//�ndere Command f�r TILT-AUF/TILT-AB jeweils mit 0%, 100% und STOP:
    		if ( IncomingMessage.type == V_VAR1 and ( Payload == "0" || Payload == "UP" ) )
    		{
    			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_UP;		//90 TILT-UP
    		};
    		if ( IncomingMessage.type == V_VAR1 and ( Payload == "100" || Payload == "DOWN" ) )
    		{
    			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_DOWN;	//91 TILT-DOWN
    		};
    		if ( IncomingMessage.type == V_VAR1 and Payload == "STOP") {
    			Jalousien[IncomingMessage.sensor - 1].Command = V_STOP;			//31
    		};
    
    		//�ndere Command f�r 3xTILT-AUF/3xTILT-AB jeweils mit 0%, 100% und STOP:
    		if ( IncomingMessage.type == V_VAR2 and ( Payload == "0" || Payload == "UP" ) )
    		{
    			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_UP3;		//92 3xTILT-UP
    		};
    		if ( IncomingMessage.type == V_VAR2 and ( Payload == "100"  || Payload == "DOWN" ) )
    		{
    			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_DOWN3;	//93 3xTILT-DOWN
    		};
    		if ( IncomingMessage.type == V_VAR2 and Payload == "STOP")
    		{
    			Jalousien[IncomingMessage.sensor - 1].Command = V_STOP;			//31
    		};
    
    #ifdef MY_DEBUG
    	Serial.print("Aus Message-Type abgeleitetes Jalousie-Kommando: ");
    	Serial.println(Jalousien[IncomingMessage.sensor - 1].Command);
    	Serial.println();
    #endif
    
    	}
    
    //	Eingehende Anfrage:
    	if (IncomingMessage.destination == MY_NODE_ID
    		&& IncomingMessage.getCommand() == C_REQ )		//Wert fuer ein Child wird abgefragt!
    	{
    		for (byte i = 1; i <= AnzahlRaeume; i++) {
    			if (i == IncomingMessage.sensor)
    			{
    				if (IncomingMessage.type == V_VAR3
    					|| IncomingMessage.type == V_VAR4)
    				{
    					send(Jalousien[i - 1].MessageStatusAufAb.set(Jalousien[i - 1].StatusAufAb, 1), false);
    					send(Jalousien[i - 1].MessageStatusTilt.set(Jalousien[i - 1].StatusTilt, 1), false);
    				}
    			}
    		}
    	}
    
    #ifdef MY_DEBUG
    	Serial.println("RECEIVE - END");
    #endif
    }
    
    
    syntacrscS 1 Reply Last reply
    1
    • syntacrscS syntacrsc

      Hello.

      I hope someone can help me with an issue I'm facing while using mySensors binding for rolling shutters and using V_VAR channels.

      My Setup:
      Software:
      openHAB 2.5.5 stable release
      MySensors openHAB binding 2.5.0.202002161928
      Hardware:
      MySensors Ethernet gateway
      Rollershutters with functions UP/DOWN and TILT UP/TILT DOWN (7 TILT positions, like horizontal blinds) (no KNX!)

      The plan:
      Whenever openHAB starts I want openHAB to request the status of my rollershutter positions (UP or DOWN) and blind positions (1/7, 2/7 ... 7/7).
      Whenever the rollershutter position or blind position changes the node is supposed to send the new status to the controller/openHAB.

      Implementation:
      On the mySensors node I keep variables for rollershutter positions (0% = open to 100% = closed) and tilt-position (1/7 = min tilt to 7/7 fully tilt).
      The node sends both positions either when a command has been executed to change them (UP/DOWN or TILT-UP/TILT-DOWN) or when the controller requests them (via request command = message type = C_REQ).
      I've implemented an openHAB rule which priodically (for testing purposes every minute) requests the positions of the rollershutters and blind-position from the node, the node responds with both positions using V_VAR3 (rollershutter position) and V_VAR4 (tilt position).
      These requests cprrectly arrive at the node and the node responds with its position-values.

      Problem:
      When replying with the rollershutter position to the openhab rule request with e.g. 100 I get error "value must be between 0 and 100.
      When replying with the tilt position to the openhab rule request with e.g. 1 (for 1/7) or 0.14 (for 1/7th) the openHAB log shows error "value must be between 0 and 100.
      Whenever the node sends values 0 or 1 openhab accepts the values!

      What I tried so far:
      I assumed openHAB expects a percent value hence requiring a value between 0 and 1 (even though it says it must be between 0 and 100) so I tried to adjust my mySensors code to send decimals bt. 0 and 1 to represent values bt. 0 and 100 (percent) - no luck though!
      The log only shows 1.0 or 0.0 being received from node eventhough the node sends float(shutter position) / 100.0 for rollershutter position or float(tilt position) / 7.0 for tilt position.
      I've tried different formatting in the items file ([%.2f], [%d], none and many others) - no help!

      Is it possible that there is a bug in the binding implementation of V_VAR1 to V_VAR4 ?
      It seems to only accept values 0 and 1 for the V_VAR channels.
      Is it me? Am I missing anything here?

      Any help is highly appreciated!

      Thanks,
      Ralph...

      Things:

      Bridge mysensors:bridge-eth:gateway @ "Wohnzimmer" [  ipAddress="10.0.0.11",
                                             tcpPort=5003, 
                                             startupCheckEnabled=true, 
                                             imperial=false,
                                             sendDelay=200, 
                                             networkSanCheckSendHeartbeat=false, 
                                             networkSanCheckInterval=3,
                                             networkSanCheckSendHeartbeatFailAttempts=10,
                                             networkSanCheckEnabled=true,
                                             networkSanCheckConnectionFailAttempts=3 ]
      
      {
          cover BueroRalphJalousie                                        "Jalousie"                                  @ "Büro Ralph"          [ nodeId=7,    childId=4,     requestAck=false ]
      }
      

      Items:

      Rollershutter   BueroRalphJalousieAufAb      "Auf/ab"                      { channel="mysensors:cover:gateway:BueroRalphJalousie:cover" }
      Number BueroRalphJalousieStatusAufAb     "Status Auf/ab [%d]"   { channel="mysensors:cover:gateway:BueroRalphJalousie:var3" }
      Number BueroRalphJalousieStatusTilt          "Status Tilt [%.2f]"       { channel="mysensors:cover:gateway:BueroRalphJalousie:var4" }                                                 
      

      Rule:

      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      // Stati von Node erfragen:
      rule HoleUnbekannteStati
      when 
          Time cron "0 0/1 * 1/1 * ? *"   //alle 1 Minuten   
      then 
      //  Jalousiesteuerung - UG:  
          if ( BueroRalphJalousieStatusAufAb.state == NULL 
              || BueroRalphJalousieStatusTilt.state == NULL  ) 
          {  
      //      make the node send in positions for rollershutters and blinds (yes it sends both even though only one (V_VAR3) is being requested!):
              sendCommand(mySMsg01, "7;4;2;0;26");  //erfrage Jalousie-AufAb-Status Buero Ralph von Node 7, Child 4, 2=request, 0 = kein acknowlege, 26 = V_VAR3 
              if ( DebugLogger.state == ON )  
              {  
                  logInfo( "Jalousien.Rules.HoleUnbekannteStati", "Jalousie-Stati Buero Ralph werden von Node erfragt")
              }
          }    
      end 
      
      

      mySensors code (excerpt):

      void receive(const MyMessage &IncomingMessage)
      {
      //	Eingehende Anfrage:
      	if (IncomingMessage.destination == MY_NODE_ID
      		&& IncomingMessage.getCommand() == C_REQ )		//Wert fuer ein Child wird abgefragt!
      	{
      		for (byte i = 1; i <= AnzahlRaeume; i++) {
      			if (i == IncomingMessage.sensor)
      			{
      				if (IncomingMessage.type == V_VAR3
      					|| IncomingMessage.type == V_VAR4)
      				{
      					send(Jalousien[i - 1].MessageStatusAufAb.set(Jalousien[i - 1].StatusAufAb, 1), false);
      					send(Jalousien[i - 1].MessageStatusTilt.set(Jalousien[i - 1].StatusTilt, 1), false);
      				}
      			}
      		}
      	}
      }
      

      mySensors code (full copy):

      #include <Arduino.h>
      
      //#define MY_DEBUG
      #define MY_RADIO_RF24
      #define MY_NODE_ID 7
      #define MY_REPEATER_FEATURE
      
      #include <MySensors.h>
      #define MY_RF24_PA_LEVEL RF24_PA_HIGH
      
      //#define ACTIVE_LOW // comment out this line if your relays are active high
      
      #ifdef ACTIVE_LOW
      #define BitShiftRelaisNummer ~(1U << (RelaisNummer-1))
      #define AlleRelaisAus 0xFFFF
      #else
      #define BitShiftRelaisNummer (1U << (RelaisNummer-1))
      #define AlleRelaisAus 0U
      #endif
      
      int RelaisNummer;
      
      #define AnzahlRaeume 8  // Anzahl der Raeume
      
      //Setup Shift Register:
      const int clockPin		  = 4;
      const int outputEnablePin = 6;
      const int dataPin 	      = 7;
      const int latchPin		  = 8;
      
      typedef enum
      {
      	V_TILT_UP  = 90, V_TILT_DOWN  = 91, V_TILT_UP3 = 92, V_TILT_DOWN3 = 93,
      } custom_mysensors_data_t;
      
      typedef struct Jalousie
      {
      	uint8_t RaumNummer;
      	char *RaumName;
      	int RelaisNummerAuf;
      	int RelaisNummerAb;
      	int Fahrzeit;
      	int TiltSchritte;
      	int Command;
      	uint8_t StatusAufAb;	// (0=UP, 100=DOWN, 99=unknown), StatusTilt (0=UP)
      	uint8_t StatusTilt;		// (0=OPEN, 7=CLOSE, 9=unknown), StatusTilt (0=UP)
      	MyMessage MessageStatusAufAb;
      	MyMessage MessageStatusTilt;
      } JalousieTyp;
      
      JalousieTyp Jalousien[AnzahlRaeume] = //RaumNummer, RaumName, RalaisNummer Funktion "AUF", RelaisNummer Funktion "AB", Fahrzeit in Sek., TiltSchritte, Command, StatusAufAb (0=UP, 100=DOWN, 99=unknown), StatusTilt (0=UP, 100=DOWN, 99=unknown)
      {
      	{ 1, "Büro Christine", 		 1,  2, 45, 7, 0, 99, 0 },
      	{ 2, "Spielzimmer", 		 3,  4, 65, 7, 0, 99, 0 },
      	{ 3, "Nebenküche",			 5,  6, 45, 7, 0, 99, 0 },
      	{ 4, "Büro Ralph",			 7,  8, 45, 7, 0, 99, 0 },
      	{ 5, "Esszimmer",			 9, 10, 65, 7, 0, 99, 0 },
      	{ 6, "Wohnzimmer Terrasse",	11, 12, 65, 7, 0, 99, 0 },
      	{ 7, "Wohnzimmer Garten", 	13, 14, 65, 7, 0, 99, 0 },
      	{ 8, "Küche",				15, 16, 65, 7, 0, 99, 0 }
      };
      
      
      ////////////////////////////////////////////////////////////////////////////////
      void setup()
      {
      #ifdef DEBUG_ON
      	Serial.println();
      	Serial.println("SETUP - BEGIN");
      #endif
      
      //  BitShiftRegister vorbereiten:
      	pinMode(latchPin, OUTPUT);
      	pinMode(clockPin, OUTPUT);
      	pinMode(dataPin, OUTPUT);
      	pinMode(outputEnablePin, OUTPUT);
      	digitalWrite(outputEnablePin, LOW);
      
      //  BitShiftRegister auf "alles aus" schalten:
      	digitalWrite(latchPin, LOW); 							//DatenPipeline fuer BitShiftRegister "lahm" legen
      	shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus); 	//DatenPipeline in das BitShiftRegister laden:
      	shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus);
      	digitalWrite(latchPin, HIGH);  							//neue Daten im BitShiftRegister aktivieren:
      
      //  Jalousie-Messages vorbereiten:
      #ifdef DEBUG_ON
      	Serial.println();
      	Serial.println("RaumNummer, RelaisName, RelaisNr-AUF, RelaisNr-AB, Fahrzeit, Command, StatusAufAb, StatusTilt");
      #endif
      	for (byte i = 1; i <= AnzahlRaeume; i++) {
      		Jalousien[i - 1].MessageStatusAufAb.setSensor(Jalousien[i - 1].RaumNummer);	//ChildID
      		Jalousien[i - 1].MessageStatusAufAb.setType(V_VAR3);
      
      		Jalousien[i - 1].MessageStatusTilt.setSensor(Jalousien[i - 1].RaumNummer); 	//ChildID
      		Jalousien[i - 1].MessageStatusTilt.setType(V_VAR4);
      
      #ifdef DEBUG_ON
      		Serial.println(Jalousien[i - 1].RaumNummer + ", " + Jalousien[i - 1].RaumName, + ", " + Jalousien[i - 1].RelaisNummerAuf + ", " + Jalousien[i - 1].RelaisNummerAb + ", " + Jalousien[i - 1].Fahrzeit + ", " + Jalousien[i - 1].Command + ", " + Jalousien[i - 1].StatusAuf + ", " + Jalousien[i - 1].StatusAb);
      #endif
      	}
      
      #ifdef MY_DEBUG
      	Serial.println();
      	Serial.println("SETUP - END");
      #endif
      }
      
      //////////////////////////////////////////////////////////////////////////////////////
      void presentation()
      {
      
      #ifdef MY_DEBUG
      	Serial.println();
      	Serial.println("PRESENTATION - BEGIN");
      #endif
      
      	sendSketchInfo("Jalousie-Controller EG", "1.1");
      	for (byte i = 1; i <= AnzahlRaeume; i++) {
      		present(Jalousien[i - 1].RaumNummer, S_COVER, Jalousien[i - 1].RaumName, false);  //Jalousie
      	}
      
      #ifdef MY_DEBUG
      	Serial.println();
      	Serial.println("PRESENTATION - END");
      #endif
      }
      
      //////////////////////////////////////////////////////////////////////////////
      void JalousieBewegen(int RaumNummer, uint8_t Command)
      {
      	const int DauerTilt   = 150;
      	const int DauerFahren = 1100;
      	int Signaldauer 	  = DauerTilt;
      	int cycles 	 	      = 1;
      
      #ifdef MY_DEBUG
      	Serial.println();
      	Serial.println("JalousieFahren - BEGIN");
      	Serial.print("Command: ");
      	Serial.println(Command);
      #endif
      
      //  RelaisNummer (Funktion also AUF- oder AB-Relais) ermitteln und Signaldauer (Fahren oder TILT) festlegen:
      	switch (Command) {
      	case V_UP:
      		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
      		Signaldauer = DauerFahren;
      		Jalousien[RaumNummer - 1].StatusAufAb = 0;
      		Jalousien[RaumNummer - 1].StatusTilt = 0;
      		break;
      	case V_DOWN:
      		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAb;
      		Signaldauer = DauerFahren;
      		Jalousien[RaumNummer - 1].StatusAufAb = 100;
      		Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].TiltSchritte;
      		break;
      	case V_STOP:
      		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
      		Jalousien[RaumNummer - 1].StatusAufAb = 99;
      		break;
      	case V_PERCENTAGE:
      		// Hole Prozentsatz (0-100 oder STOP):
      		// to be implemented
      		RelaisNummer = 0;
      		break;
      	case V_TILT_UP:     //90 TILT-UP
      		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
      		if (Jalousien[RaumNummer - 1].StatusTilt >= cycles)
      		{
      			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt - cycles;
      		}
      		break;
      	case V_TILT_DOWN:  //"91 TILT-DOWN"
      		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAb;
      		if (Jalousien[RaumNummer - 1].StatusTilt <= ( Jalousien[RaumNummer - 1].TiltSchritte - cycles ))
      		{
      			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt + 1;
      		}
      		break;
      	case V_TILT_UP3:   //"92 TILT-UP3"
      		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAuf;
      		cycles       = 3;
      		if (Jalousien[RaumNummer - 1].StatusTilt >= cycles)
      		{
      			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt - cycles;
      		}
      		break;
      	case V_TILT_DOWN3: //"93 TILT-DOWN3"
      		RelaisNummer = Jalousien[RaumNummer - 1].RelaisNummerAb;
      		cycles       = 3;
      		if (Jalousien[RaumNummer - 1].StatusTilt <= (Jalousien[RaumNummer - 1].TiltSchritte - cycles))
      		{
      			Jalousien[RaumNummer - 1].StatusTilt = Jalousien[RaumNummer - 1].StatusTilt + cycles;
      		}
      		break;
      	};
      
      #ifdef MY_DEBUG
      	Serial.print("Raumnummer: ");
      	Serial.println(RaumNummer);
      	Serial.print("JalousieRelaisNummer: ");
      	Serial.println(RelaisNummer);
      	Serial.print("BitShift-Relais-Nummer: ");
      	Serial.println(BitShiftRelaisNummer);
      #endif
      
      //  Relais (FunktionsNummer) fuer Signaldauer schalten:
      	if (RelaisNummer != 0)
      	{
      		for (int i = 1; i <= cycles; i++)
      		{
      //  		Relais einschalten:
      #ifdef MY_DEBUG
      			Serial.println("Schaltet ein");
      #endif
      			digitalWrite(latchPin, LOW);  											//DatenPipeline fuer BitShiftRegister "lahm" legen
      			shiftOut(dataPin, clockPin, MSBFIRST, highByte(BitShiftRelaisNummer)); 	//DatenPipeline in das BitShiftRegister laden
      			shiftOut(dataPin, clockPin, MSBFIRST, lowByte(BitShiftRelaisNummer));
      			digitalWrite(latchPin, HIGH);  											//neue Daten im BitShiftRegister aktivieren
      
      	//      Relais "gedrueckt" lassen:
      #ifdef MY_DEBUG
      			Serial.print("wartet ");
      			Serial.print(Signaldauer);
      			Serial.println(" ms");
      #endif
      			wait(Signaldauer);
      
      	//  	Relais ausschalten:
      #ifdef MY_DEBUG
      			Serial.println("Schaltet aus");
      #endif
      			digitalWrite(latchPin, LOW); 							//DatenPipeline fuer BitShiftRegister "lahm" legen
      			shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus);	//DatenPipeline in das BitShiftRegister laden
      			shiftOut(dataPin, clockPin, MSBFIRST, AlleRelaisAus);   //doppelt???
      			digitalWrite(latchPin, HIGH);  							//neue Daten im BitShiftRegister aktivieren
      
      			if (cycles > 1) {
      				wait(750);
      			}
      		}
      	}
      
      //	Neuen Zustand an Controller melden:
      	send(Jalousien[RaumNummer - 1].MessageStatusAufAb.set(Jalousien[RaumNummer - 1].StatusAufAb, 1), false);
      	send(Jalousien[RaumNummer - 1].MessageStatusTilt.set(Jalousien[RaumNummer - 1].StatusTilt, 1), false);
      
      #ifdef MY_DEBUG
      	Serial.println("JalousieFahren - END");
      #endif
      }
      
      /////////////////////////////////////////////////////////////////////////////////////////////////////
      void loop()
      {
      
      #ifdef MY_DEBUG
      	Serial.println();
      	Serial.println("LOOP - BEGIN");
      #endif
      
      	for (byte i = 1; i <= AnzahlRaeume; i++)
      	{
      #ifdef MY_DEBUG
      		Serial.print('RaumNummer / Kommando: ');
      		Serial.print('  ');
      		Serial.print(i);
      		Serial.print(' / ');
      		Serial.println(Jalousien[i-1].Command);
      #endif
      		if (Jalousien[i - 1].Command != 0)
      		{
      			JalousieBewegen(Jalousien[i - 1].RaumNummer, Jalousien[i - 1].Command); 	//RaumNummer, Kommando
      			Jalousien[i - 1].Command = 0;
      		}
      	}
      #ifdef MY_DEBUG
      	Serial.println();
      	Serial.println("LOOP - END");
      	wait(4000);
      #endif
      }
      
      
      ////////////////////////////////////////////////////////////////////////////////
      void receive(const MyMessage &IncomingMessage)
      {
      	String Payload;
      
      	Payload = IncomingMessage.getString();
      
      #ifdef MY_DEBUG
      	Serial.println();
      	Serial.println("RECEIVE - BEGIN");
      	Serial.println();
      	Serial.println("Nachricht empfangen");
      	Serial.print("f�r Sensor: ");
      	Serial.println(IncomingMessage.sensor);
      	Serial.print("Typ: ");
      	Serial.println(IncomingMessage.type);
      	Serial.print("Sender: ");
      	Serial.println(IncomingMessage.sender);
      	Serial.print("Command: ");
      	Serial.println(IncomingMessage.getCommand() + "(1 = SET, 2 = REQUEST)");
      	Serial.print("IsAcknowledge: ");
      	Serial.println(IncomingMessage.isAck());
      	Serial.print("Payload als String: ");
      	Serial.println(Payload);
      	Serial.print("Message data: ");
      	Serial.println(IncomingMessage.data);
      #endif
      
      //	Eingehendes Kommando:
      	if (IncomingMessage.destination == MY_NODE_ID
      		&& IncomingMessage.getCommand() == C_SET )	//Wert fuer ein Child soll gesetzt werden!
      	{
      		Jalousien[IncomingMessage.sensor - 1].Command = IncomingMessage.type;
      		//  �ndere Command f�r % AUF/AB auf jeweils 0%, 100% bzw. STOP:
      		if ( IncomingMessage.type == V_PERCENTAGE and Payload == "0") {
      			Jalousien[IncomingMessage.sensor - 1].Command = V_UP;		//29
      		};
      		if ( IncomingMessage.type == V_PERCENTAGE and Payload == "100") {
      			Jalousien[IncomingMessage.sensor - 1].Command = V_DOWN;		//30
      		};
      		if ( IncomingMessage.type == V_PERCENTAGE and Payload == "STOP") {
      			Jalousien[IncomingMessage.sensor - 1].Command = V_STOP;		//31
      		};
      
      		//�ndere Command f�r TILT-AUF/TILT-AB jeweils mit 0%, 100% und STOP:
      		if ( IncomingMessage.type == V_VAR1 and ( Payload == "0" || Payload == "UP" ) )
      		{
      			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_UP;		//90 TILT-UP
      		};
      		if ( IncomingMessage.type == V_VAR1 and ( Payload == "100" || Payload == "DOWN" ) )
      		{
      			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_DOWN;	//91 TILT-DOWN
      		};
      		if ( IncomingMessage.type == V_VAR1 and Payload == "STOP") {
      			Jalousien[IncomingMessage.sensor - 1].Command = V_STOP;			//31
      		};
      
      		//�ndere Command f�r 3xTILT-AUF/3xTILT-AB jeweils mit 0%, 100% und STOP:
      		if ( IncomingMessage.type == V_VAR2 and ( Payload == "0" || Payload == "UP" ) )
      		{
      			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_UP3;		//92 3xTILT-UP
      		};
      		if ( IncomingMessage.type == V_VAR2 and ( Payload == "100"  || Payload == "DOWN" ) )
      		{
      			Jalousien[IncomingMessage.sensor - 1].Command = V_TILT_DOWN3;	//93 3xTILT-DOWN
      		};
      		if ( IncomingMessage.type == V_VAR2 and Payload == "STOP")
      		{
      			Jalousien[IncomingMessage.sensor - 1].Command = V_STOP;			//31
      		};
      
      #ifdef MY_DEBUG
      	Serial.print("Aus Message-Type abgeleitetes Jalousie-Kommando: ");
      	Serial.println(Jalousien[IncomingMessage.sensor - 1].Command);
      	Serial.println();
      #endif
      
      	}
      
      //	Eingehende Anfrage:
      	if (IncomingMessage.destination == MY_NODE_ID
      		&& IncomingMessage.getCommand() == C_REQ )		//Wert fuer ein Child wird abgefragt!
      	{
      		for (byte i = 1; i <= AnzahlRaeume; i++) {
      			if (i == IncomingMessage.sensor)
      			{
      				if (IncomingMessage.type == V_VAR3
      					|| IncomingMessage.type == V_VAR4)
      				{
      					send(Jalousien[i - 1].MessageStatusAufAb.set(Jalousien[i - 1].StatusAufAb, 1), false);
      					send(Jalousien[i - 1].MessageStatusTilt.set(Jalousien[i - 1].StatusTilt, 1), false);
      				}
      			}
      		}
      	}
      
      #ifdef MY_DEBUG
      	Serial.println("RECEIVE - END");
      #endif
      }
      
      
      syntacrscS Offline
      syntacrscS Offline
      syntacrsc
      wrote on last edited by
      #2

      I missed to append the log excerpt with the error message:

      2020-05-26 10:21:35.268 [DEBUG] [rs.internal.gateway.MySensorsGateway] - Child 4 found in node 7
      2020-05-26 10:21:35.273 [DEBUG] [ensors.handler.MySensorsThingHandler] - **Updating channel: var4(V_VAR4) value to: 3**
      2020-05-26 10:21:35.277 [ERROR] [nternal.event.MySensorsEventRegister] - Event broadcasting throw an exception
      java.lang.IllegalArgumentException: **Value must be between 0 and 100**
      	at org.eclipse.smarthome.core.library.types.PercentType.validateValue(PercentType.java:57) ~[?:?]
      	at org.eclipse.smarthome.core.library.types.PercentType.<init>(PercentType.java:52) ~[?:?]
      	at org.eclipse.smarthome.core.library.types.DecimalType.as(DecimalType.java:152) ~[?:?]
      	at org.eclipse.smarthome.core.internal.items.ItemStateConverterImpl.convertToAcceptedState(ItemStateConverterImpl.java:64) ~[?:?]
      	at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.sendUpdate(ProfileCallbackImpl.java:134) ~[?:?]
      	at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onStateUpdateFromHandler(SystemDefaultProfile.java:53) ~[?:?]
      	at org.eclipse.smarthome.core.thing.internal.CommunicationManager.lambda$9(CommunicationManager.java:467) ~[?:?]
      	at org.eclipse.smarthome.core.thing.internal.CommunicationManager.lambda$11(CommunicationManager.java:487) ~[?:?]
      	at java.lang.Iterable.forEach(Iterable.java:75) ~[?:1.8.0_252]
      	at org.eclipse.smarthome.core.thing.internal.CommunicationManager.handleCallFromHandler(CommunicationManager.java:483) ~[?:?]
      	at org.eclipse.smarthome.core.thing.internal.CommunicationManager.stateUpdated(CommunicationManager.java:465) ~[?:?]
      	at org.eclipse.smarthome.core.thing.internal.ThingManagerImpl$1.stateUpdated(ThingManagerImpl.java:168) ~[?:?]
      	at org.eclipse.smarthome.core.thing.binding.BaseThingHandler.updateState(BaseThingHandler.java:245) ~[?:?]
      	at org.eclipse.smarthome.core.thing.binding.BaseThingHandler.updateState(BaseThingHandler.java:264) ~[?:?]
      	at org.openhab.binding.mysensors.handler.MySensorsThingHandler.handleChildUpdateEvent(MySensorsThingHandler.java:305) ~[?:?]
      	at org.openhab.binding.mysensors.handler.MySensorsThingHandler.sensorUpdateEvent(MySensorsThingHandler.java:221) ~[?:?]
      	at org.openhab.binding.mysensors.internal.event.MySensorsEventRegister.lambda$4(MySensorsEventRegister.java:130) ~[?:?]
      	at java.lang.Iterable.forEach(Iterable.java:75) ~[?:1.8.0_252]
      	at org.openhab.binding.mysensors.internal.event.MySensorsEventRegister.notifyNodeUpdateEvent(MySensorsEventRegister.java:126) ~[?:?]
      	at org.openhab.binding.mysensors.internal.gateway.MySensorsGateway.handleSetReqMessage(MySensorsGateway.java:564) ~[?:?]
      	at org.openhab.binding.mysensors.internal.gateway.MySensorsGateway.handleIncomingMessage(MySensorsGateway.java:462) ~[?:?]
      	at org.openhab.binding.mysensors.internal.gateway.MySensorsGateway.messageReceived(MySensorsGateway.java:375) ~[?:?]
      	at org.openhab.binding.mysensors.internal.event.MySensorsEventRegister.lambda$1(MySensorsEventRegister.java:87) ~[?:?]
      	at java.lang.Iterable.forEach(Iterable.java:75) [?:1.8.0_252]
      	at org.openhab.binding.mysensors.internal.event.MySensorsEventRegister.notifyMessageReceived(MySensorsEventRegister.java:83) [bundleFile:?]
      	at org.openhab.binding.mysensors.internal.protocol.MySensorsAbstractConnection$MySensorsReader.run(MySensorsAbstractConnection.java:362) [bundleFile:?]
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_252]
      	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_252]
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_252]
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_252]
      	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_252]
      
      
      1 Reply Last reply
      0
      • syntacrscS Offline
        syntacrscS Offline
        syntacrsc
        wrote on last edited by
        #3

        It's getting more and more wierd:
        Just changed the mySensors code to send a fixed value e.g. 0.14 on V_VAR4

        send(Jalousien[i - 1].MessageStatusTilt.set(float(0.14), 2), false);
        

        Result in openHAB is that the rollershutter value shows as 14 and the item connected to channel VAR4 shows as 0.14 (see screen shot).
        Apprently all the VAR channels are connected to the cover channel in the openHAB mySensors binding.
        That doesn't seem correct to me.
        ??
        VAR_issue.jpg

        1 Reply Last reply
        0
        • syntacrscS Offline
          syntacrscS Offline
          syntacrsc
          wrote on last edited by syntacrsc
          #4

          Solved it by changing the definition (typeId) of both V_VAR1 and V_VAR2 in the binding file for S_Cover (.XML file in folder /usr/share/openhab -> org.openhab.binding.mysensors-2.5.0-SNAPSHOT.jar -> ESH-INF/thing/S_Cover.xml) from "var1-channel" resp. "var2-channel" to "cover-channel" (see XML excerpt below).
          This allows me to setup two additional rollershutter items to control the tilt of the cover blade (V_VAR1 = single tilt and V_VAR2 = tripple tilt at a time) and to send back the position of the tilt blades stored in the node to openHAB.

          Items:

          Rollershutter   BueroRalphJalousieAufAb                      "Auf/ab"   { channel="mysensors:cover:gateway:BueroRalphJalousie:cover", 
          Rollershutter   BueroRalphJalousieTilt                           "Tilt"         { channel="mysensors:cover:gateway:BueroRalphJalousie:var1" } 
          Rollershutter   BueroRalphJalousieTilt3X                       "3x Tilt"    { channel="mysensors:cover:gateway:BueroRalphJalousie:var2" }  
          

          **Binding .XML file in folder /usr/share/openhab -> org.openhab.binding.mysensors-2.5.0-SNAPSHOT.jar -> ESH-INF/thing/S_Cover.xml
          I changed from:

          <channel id="var1" typeId="var1-channel" />
          <channel id="var2" typeId="var2-channel" />**
          

          to

          <channel id="var1" typeId="cover-channel" />
          <channel id="var2" typeId="cover-channel" />
          

          like this:

          <thing:thing-descriptions bindingId="mysensors"
          	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          	xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
          	xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
          
          	<thing-type id="cover">
          		<supported-bridge-type-refs>
          			<bridge-type-ref id="bridge-ser" />
          			<bridge-type-ref id="bridge-eth" />
                      <bridge-type-ref id="bridge-mqtt" />
          		</supported-bridge-type-refs>
          
          		<label>RollerShutter</label>
          		<description>RollerShutter</description>
          
          		<channels>
          			<channel id="cover" typeId="cover-channel" />
          			<channel id="var1" typeId="cover-channel" />
          			<channel id="var2" typeId="cover-channel" />
          			<channel id="var3" typeId="var3-channel" />
          			<channel id="var4" typeId="var4-channel" />
          			<channel id="var5" typeId="var5-channel" />
          			<channel id="battery" typeId="battery-channel" />
          			<channel id="lastupdate" typeId="lastupdate-channel" />
          		</channels>
          
          		<config-description>
          			<parameter name="nodeId" typ...
          

          mySensors code (excerpt):

          //     Prepare Messages:
          			Jalousien[i - 1].MessageStatusAufAb.setSensor(Jalousien[i - 1].RaumNummer);		//ChildID
          			Jalousien[i - 1].MessageStatusAufAb.setType(V_PERCENTAGE);						//UpDown-Position
          			Jalousien[i - 1].MessageStatusTilt.setSensor(Jalousien[i - 1].RaumNummer);		//ChildID
          			Jalousien[i - 1].MessageStatusTilt.setType(V_VAR1);								//Tilt-Position
          			Jalousien[i - 1].MessageStatusTilt3X.setSensor(Jalousien[i - 1].RaumNummer);	//ChildID
          			Jalousien[i - 1].MessageStatusTilt3X.setType(V_VAR2);							//Tilt3x-Position
          ...
          ...
          //	Neuen Zustand an Controller melden / Send cover and tilt positions back to controller:	
          	send(Jalousien[i - 1].MessageStatusTilt.set((Jalousien[i - 1].StatusTilt / Jalousien[i - 1].TiltSchritte), 2), false);
          	send(Jalousien[i - 1].MessageStatusTilt3X.set((Jalousien[i - 1].StatusTilt / Jalousien[i - 1].TiltSchritte), 2), false);
          	send(Jalousien[i - 1].MessageStatusAufAb.set(Jalousien[i - 1].StatusAufAb, 0), false);
          
          

          Make sure to send the V_PERCENTAGE last since V_VAR1 and V_VAR2 for some unknown reason (and as far as I feel totally unnecessarily) still updates V_PERCENTAGE!

          Result:
          VAR_issue2.jpg

          P 1 Reply Last reply
          0
          • syntacrscS syntacrsc

            Solved it by changing the definition (typeId) of both V_VAR1 and V_VAR2 in the binding file for S_Cover (.XML file in folder /usr/share/openhab -> org.openhab.binding.mysensors-2.5.0-SNAPSHOT.jar -> ESH-INF/thing/S_Cover.xml) from "var1-channel" resp. "var2-channel" to "cover-channel" (see XML excerpt below).
            This allows me to setup two additional rollershutter items to control the tilt of the cover blade (V_VAR1 = single tilt and V_VAR2 = tripple tilt at a time) and to send back the position of the tilt blades stored in the node to openHAB.

            Items:

            Rollershutter   BueroRalphJalousieAufAb                      "Auf/ab"   { channel="mysensors:cover:gateway:BueroRalphJalousie:cover", 
            Rollershutter   BueroRalphJalousieTilt                           "Tilt"         { channel="mysensors:cover:gateway:BueroRalphJalousie:var1" } 
            Rollershutter   BueroRalphJalousieTilt3X                       "3x Tilt"    { channel="mysensors:cover:gateway:BueroRalphJalousie:var2" }  
            

            **Binding .XML file in folder /usr/share/openhab -> org.openhab.binding.mysensors-2.5.0-SNAPSHOT.jar -> ESH-INF/thing/S_Cover.xml
            I changed from:

            <channel id="var1" typeId="var1-channel" />
            <channel id="var2" typeId="var2-channel" />**
            

            to

            <channel id="var1" typeId="cover-channel" />
            <channel id="var2" typeId="cover-channel" />
            

            like this:

            <thing:thing-descriptions bindingId="mysensors"
            	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            	xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
            	xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
            
            	<thing-type id="cover">
            		<supported-bridge-type-refs>
            			<bridge-type-ref id="bridge-ser" />
            			<bridge-type-ref id="bridge-eth" />
                        <bridge-type-ref id="bridge-mqtt" />
            		</supported-bridge-type-refs>
            
            		<label>RollerShutter</label>
            		<description>RollerShutter</description>
            
            		<channels>
            			<channel id="cover" typeId="cover-channel" />
            			<channel id="var1" typeId="cover-channel" />
            			<channel id="var2" typeId="cover-channel" />
            			<channel id="var3" typeId="var3-channel" />
            			<channel id="var4" typeId="var4-channel" />
            			<channel id="var5" typeId="var5-channel" />
            			<channel id="battery" typeId="battery-channel" />
            			<channel id="lastupdate" typeId="lastupdate-channel" />
            		</channels>
            
            		<config-description>
            			<parameter name="nodeId" typ...
            

            mySensors code (excerpt):

            //     Prepare Messages:
            			Jalousien[i - 1].MessageStatusAufAb.setSensor(Jalousien[i - 1].RaumNummer);		//ChildID
            			Jalousien[i - 1].MessageStatusAufAb.setType(V_PERCENTAGE);						//UpDown-Position
            			Jalousien[i - 1].MessageStatusTilt.setSensor(Jalousien[i - 1].RaumNummer);		//ChildID
            			Jalousien[i - 1].MessageStatusTilt.setType(V_VAR1);								//Tilt-Position
            			Jalousien[i - 1].MessageStatusTilt3X.setSensor(Jalousien[i - 1].RaumNummer);	//ChildID
            			Jalousien[i - 1].MessageStatusTilt3X.setType(V_VAR2);							//Tilt3x-Position
            ...
            ...
            //	Neuen Zustand an Controller melden / Send cover and tilt positions back to controller:	
            	send(Jalousien[i - 1].MessageStatusTilt.set((Jalousien[i - 1].StatusTilt / Jalousien[i - 1].TiltSchritte), 2), false);
            	send(Jalousien[i - 1].MessageStatusTilt3X.set((Jalousien[i - 1].StatusTilt / Jalousien[i - 1].TiltSchritte), 2), false);
            	send(Jalousien[i - 1].MessageStatusAufAb.set(Jalousien[i - 1].StatusAufAb, 0), false);
            
            

            Make sure to send the V_PERCENTAGE last since V_VAR1 and V_VAR2 for some unknown reason (and as far as I feel totally unnecessarily) still updates V_PERCENTAGE!

            Result:
            VAR_issue2.jpg

            P Offline
            P Offline
            Parkeexant
            wrote on last edited by
            #5

            @syntacrsc good job man

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            28

            Online

            11.7k

            Users

            11.2k

            Topics

            113.1k

            Posts


            Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • MySensors
            • OpenHardware.io
            • Categories
            • Recent
            • Tags
            • Popular