DDF Widow Covering Device - Tilt even if not "supported"

I’m using Ubisys J1 devices with blinds. They’re calibrated and everything works. But they report a value for tilt:

{
  "config": {
    "groups": [
      "31",
      "40"
    ]
  },
  "etag": "fb00a7b18388834be41b970b62c51956",
  "hascolor": false,
  "lastannounced": "2025-02-08T06:31:06Z",
  "lastseen": "2025-02-24T08:40Z",
  "manufacturername": "ubisys",
  "modelid": "J1 (5502)",
  "name": "Dachfensterrollo",
  "state": {
    "bri": 0,
    "lift": 0,
    "on": false,
    "open": true,
    "reachable": true,
    **"tilt": 255**
  },
  "swversion": "2.5.0",
  "type": "Window covering device",
  "uniqueid": "00:1f:ee:00:00:00:64:ce-01"
}

but I don’t have blinds supporting tilt. I guess 255 is the value for “disabled” because it should be 0 - 100.

This causes a problem in Home Assistant: becaue there is a value for tilt the integration assumes tilt is supported (see discussion here: Deconz: Window Covering Device: invalid value for current_tilt_position · Issue #139169 · home-assistant/core · GitHub).

Is it possible to alter the DDF so that the tilt is only reported when its not 255?

IMHO it should depend on the Device Type (Window Covering Cluster (Server), Attribute 0x0000: WindowCoveringType) see https://www.ubisys.de/wp-content/uploads/ubisys-j1-technical-reference.pdf pages 15 and 18/19. Only type 8 has Lift & Tilt. Should be the same for lift and Tilt only types.

Is it possible to add or remove “items” based on this cluster? Is there an example for this?

Hello, you are lucky ^^, this device is supported using DDF > deconz-rest-plugin/devices/ubisys/j1_5502.json at master · dresden-elektronik/deconz-rest-plugin · GitHub

So can make all you want, if you want to remove state/titlt, just remove

         {
          "name": "state/tilt"
        },

And restart deconz, new fields are added automaticaly and I think removed fields are automatic too.

If I m right you can too remove

        {
          "at": "0x0009",
          "dt": "0x20",
          "min": 1,
          "max": 300,
          "change": "0x00000001"
        },

Its the bind for the attribute 0x0009, the titlt, but if you have the GUI, better to take a look first in the Cluster 0x0102 to be sure it’s not used.

Helll,

yes, I know I can do this. My question was: is it possible to create one DDF that, based on the type or the value (255), only exposes tilt if it’s supported in the setup. Or whats the idea how an API Consumer (like the Home Assistant Integration) can find out if a specific device can tilt or not?

DDF is based on the device, and if I m right this device can use different blind, so different configuration ?

if I m right Home assistant ignore a field if the value is null ? What is the maximum value for lift 255 or 254 ? Can use a null value if the value is 255, but not sure it will work.

I don’t see how to make a field visible or no on the same DDF. Some bulbs have a special field to say wich one feature are available or not, “cap/color/capabilities” for exemple.

It’s possible to make many DDF, with a check to select wich one to use, but from my memory not possible to use an attribute value to select the DDF (because the attribute is asked after the DDF is selected)

As tilt should only be 0-100, maybe it would be appropriate at a central point to ignore values that are out of range

It’s tilt in percent so 0 - 100. I guess 255 is used when it’s in „no tilt“ mode.

Right, so it possible to make a null value.

@Robban the HA plugin ignore field if the value is null if I remember, no ?

Thats correct.

1 Like

I could test this in my setup (no tilt) when you tell me what to edit in the DDF

Can try something like

        {
          "name": "state/tilt",
          "parse": {
            "at": "0x0009",
            "cl": "0x0102",
            "ep": 1,
            "eval": "if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = null; }",
            "fn": "zcl:attr"
          },
          "default": null
        },

If it work, you will probably need to remove and re-add the device to HA, the plugin make his “magic” when it detect the device, so if the field is created, it’s probably too late.

hm, does not work:

but still

  "state": {
    "bri": 0,
    "lift": 0,
    "on": false,
    "open": true,
    "reachable": true,
    "tilt": 255
  },

Try to read again the attribute using the GUI.
Can you enable logs, in deconz/help/debug view, flag “DDF”, before making this request.

07:17:31:705 JS failed to set Item.val for state/tilt
07:17:31:706 failed to evaluate expression for 00:1f:ee:00:00:00:64:ce-01/state/tilt: if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = null; }, err: TypeError: failed to set Item.val
07:17:33:023 JS failed to set Item.val for state/tilt
07:17:33:025 failed to evaluate expression for 00:1f:ee:00:00:00:5a:d1-01/state/tilt: if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = null; }, err: TypeError: failed to set Item.val

No idea, Have tried this code on my side without problem

Attr={};
Item={};
Attr.val = 150;
if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = null; }
window.alert(Item.val);

I think if you use else { Item.val = 0; } it will remove the error message, but IDK how to set a null value in this situation.

I will try to ask to others devs.

Perhaps a tips, can you make a try with

"eval": "if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = undefined; }",

same error

06:51:53:478 JS failed to set Item.val for state/tilt
06:51:53:480 failed to evaluate expression for 00:1f:ee:00:00:00:51:4a-01/state/tilt: if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = undefined; }, err: TypeError: failed to set Item.val

it works with

if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = -1; }

but this does not really help…

I tried

if (Attr.val <= 100) { Item.val = Attr.val; } else { delete Item.val; }

this does not end up in an error:

06:58:19:664 00:1f:ee:00:00:00:64:ce-01/state/tilt expression: if (Attr.val <= 100) { Item.val = Attr.val; } else { delete Item.val; } --> true

but just leaves the last value

if (Attr.val <= 100) { Item.val = Attr.val; } else { Item.val = false; }

leads to

"tilt": 0 (boolean converted to int?)

all in all: no success…

EDIT: i think delete should be the right thing. But it does not work in deCONZ DDF. Maybe this should be implemented?

Attr={};
Item={};
Attr.val = 150;
console.log(Attr);
console.log(Item);
Item.val = Attr.val;
console.log(Attr);
console.log(Item);
if (Attr.val <= 100) { Item.val = Attr.val; } else { delete Item.val; }
console.log(Attr);
console.log(Item);
{val: 150}
{}
{val: 150}
{val: 150}
{val: 150}
{}

Yeah, in fact there is a C++ engine that run the JS code, but it have probably limitations not present in pure JS.
It seem one time the variable is created, here as int, it’s no more possible to “put” inside other type, like a bool or null type.

So, what can we do?

On my side no idea for the moment.