OpenZWave / python-openzwave

Python wrapper for openzwave
Other
200 stars 141 forks source link

1.6 Update - SwitchMultiLevel Command Class (python-openzwave) #171

Open Fishwaldo opened 5 years ago

Fishwaldo commented 5 years ago

As per the OZW 1.6 Release Notes - The SwitchMultiLevel CommandClass now exports a Target Level ValueID

This ValueID, if present, should be prefered over the existing Level ValueID, as the level valueID reports "instant" levels, rather than a final level. This causes users issues on devices such as dimmers, where the Value ramps up/down over a period of time, but the level value does not represent what the final value will be.

Just need to confirm no changes are necessary here. If there are, we still need to handle the old 1.4 way (with just a level valueID) as not all devices support the Target ValueID.

kdschlosser commented 5 years ago

What I can do is I can check for the existence of the new value, if it is not found then fallback to the original value.

Fishwaldo commented 5 years ago

Yep - Sounds good :)

kdschlosser commented 5 years ago

This is also done.

kdschlosser commented 5 years ago

@Fishwaldo

I have a few questions regarding this command class and it's values.

This is the code from SwitchMultilevel.cpp It outlines the values that are available

switch( GetVersion() )
        {
            case 4:
            {
                node->CreateValueByte( ValueID::ValueGenre_System, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::TargetValue, "Target Value", "", true, false, 0, 0 );
                // Fall through to version 3
            }
            case 3:
            {
                node->CreateValueByte( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::Step, "Step Size", "", false, false, 0, 0 );
                node->CreateValueButton( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::Inc, "Inc", 0 );
                node->CreateValueButton( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::Dec, "Dec", 0 );
                // Fall through to version 2
            }
            case 2:
            {
                node->CreateValueByte( ValueID::ValueGenre_System, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::Duration, "Dimming Duration", "", false, false, 0xff, 0 );
                // Fall through to version 1
            }
            case 1:
            {
                node->CreateValueByte( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::Level, "Level", "", false, false, 0, 0 );
                node->CreateValueButton( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::Bright, "Bright", 0 );
                node->CreateValueButton( ValueID::ValueGenre_User, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::Dim, "Dim", 0 );
                node->CreateValueBool( ValueID::ValueGenre_System, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::IgnoreStartLevel, "Ignore Start Level", "", false, false, true, 0 );
                node->CreateValueByte( ValueID::ValueGenre_System, GetCommandClassId(), _instance, ValueID_Index_SwitchMultiLevel::StartLevel, "Start Level", "", false, false, 0, 0 );
                break;
            }
        }
    }
}

in version 1 of the specification you have these value indexes Level = 0 Bright = 1 Dim = 2 IgnoreStartLevel = 3 StartLevel = 4

version 2 has Duration = 5

version 3 has Step = 6 Inc = 7 Dec = 8

and version 4 TargetValue = 9

I am going to walk through each of the versions. Again tell me if I am wrong (and I most likely am.. no this is not about associations either LOL)

version 1 I am not entirely sure what the Bright and Dim are as I do not find any reference to these values in the specification. I am thinking they have something to do with the SWITCH_MULTILEVEL_START_LEVEL_CHANGE command. These 2 values also have to deal with that command as well. IgnoreStartLevel StartLevel

My question is this. the command is a single command. and that command takes all of the above parameters. How does this command get issued without all of the parameters being set at the same time? How does one go about using these values correctly. It appears as tho this command is to start the light in a ramp up / down until it reaches full on or full off. The ramping can be stopped by using the SWITCH_MULTILEVEL_STOP_LEVEL_CHANGE command. Which I am not sure if this is even available. I do not see a "button" value set up for it.

I am thinking in order to use this ability all of the parameters would have to be set at the same time. and at that point the light would do it's thing. This can be useful if an application wanted to use timer values on how long to run a light ramp for.

version 2 there is the addition of a duration parameter added to SWITCH_MULTILEVEL_SET. I would hazard a guess that the light would internally change any step and loop values to achieve the length of time requested. again This is another one I am not sure how it gets used. as the duration and the level (value) are set separately. there is also a duration parameter added to the SWITCH_MULTILEVEL_START_LEVEL_CHANGE command

version 3 Step, Inc, Dec I believe are for a secondary switch am I correct in this assumption? they would be the equivalent to Inc = Bright, Dec = Dim, and Step is the number of "levels" to change per iteration with a delay specified in Duration.

version 4 you added the target_value which is fantastic. what would be a nice addition to it is the Duration that is supplied in the SWITCH_MULTILEVEL_REPORT command that comes from the node. This supplies the total amount of time it is going to take to make the change. whether it be from a local (manual) change or from a ZWave command. I believe it should also account for any firmware setting that are set for the speed and step values as well when dealing with light dimmers.

If you could clarify the use of these values It may lead to a better mechanism in python-openzwave for handling this command class.