@@ -28,66 +28,52 @@ async def async_setup_entry(
2828) -> None :
2929 """Set up the Fibaro covers."""
3030 controller = entry .runtime_data
31- async_add_entities (
32- [FibaroCover (device ) for device in controller .fibaro_devices [Platform .COVER ]],
33- True ,
34- )
3531
32+ entities : list [FibaroEntity ] = []
33+ for device in controller .fibaro_devices [Platform .COVER ]:
34+ # Positionable covers report the position over value
35+ if device .value .has_value :
36+ entities .append (PositionableFibaroCover (device ))
37+ else :
38+ entities .append (FibaroCover (device ))
39+ async_add_entities (entities , True )
3640
37- class FibaroCover (FibaroEntity , CoverEntity ):
38- """Representation a Fibaro Cover."""
41+
42+ class PositionableFibaroCover (FibaroEntity , CoverEntity ):
43+ """Representation of a fibaro cover which supports positioning."""
3944
4045 def __init__ (self , fibaro_device : DeviceModel ) -> None :
41- """Initialize the Vera device."""
46+ """Initialize the device."""
4247 super ().__init__ (fibaro_device )
4348 self .entity_id = ENTITY_ID_FORMAT .format (self .ha_id )
4449
45- if self ._is_open_close_only ():
46- self ._attr_supported_features = (
47- CoverEntityFeature .OPEN | CoverEntityFeature .CLOSE
48- )
49- if "stop" in self .fibaro_device .actions :
50- self ._attr_supported_features |= CoverEntityFeature .STOP
51-
5250 @staticmethod
53- def bound (position ) :
51+ def bound (position : int | None ) -> int | None :
5452 """Normalize the position."""
5553 if position is None :
5654 return None
57- position = int (position )
5855 if position <= 5 :
5956 return 0
6057 if position >= 95 :
6158 return 100
6259 return position
6360
64- def _is_open_close_only (self ) -> bool :
65- """Return if only open / close is supported."""
66- # Normally positionable devices report the position over value,
67- # so if it is missing we have a device which supports open / close only
68- return not self .fibaro_device .value .has_value
69-
7061 def update (self ) -> None :
7162 """Update the state."""
7263 super ().update ()
7364
7465 self ._attr_current_cover_position = self .bound (self .level )
7566 self ._attr_current_cover_tilt_position = self .bound (self .level2 )
7667
77- device_state = self .fibaro_device .state
78-
7968 # Be aware that opening and closing is only available for some modern
8069 # devices.
8170 # For example the Fibaro Roller Shutter 4 reports this correctly.
82- if device_state . has_value :
83- self ._attr_is_opening = device_state . str_value (). lower () == "opening"
84- self ._attr_is_closing = device_state . str_value (). lower () == "closing"
71+ device_state = self . fibaro_device . state . str_value ( default = "" ). lower ()
72+ self ._attr_is_opening = device_state == "opening"
73+ self ._attr_is_closing = device_state == "closing"
8574
8675 closed : bool | None = None
87- if self ._is_open_close_only ():
88- if device_state .has_value and device_state .str_value ().lower () != "unknown" :
89- closed = device_state .str_value ().lower () == "closed"
90- elif self .current_cover_position is not None :
76+ if self .current_cover_position is not None :
9177 closed = self .current_cover_position == 0
9278 self ._attr_is_closed = closed
9379
@@ -96,7 +82,7 @@ def set_cover_position(self, **kwargs: Any) -> None:
9682 self .set_level (cast (int , kwargs .get (ATTR_POSITION )))
9783
9884 def set_cover_tilt_position (self , ** kwargs : Any ) -> None :
99- """Move the cover to a specific position."""
85+ """Move the slats to a specific position."""
10086 self .set_level2 (cast (int , kwargs .get (ATTR_TILT_POSITION )))
10187
10288 def open_cover (self , ** kwargs : Any ) -> None :
@@ -118,3 +104,62 @@ def close_cover_tilt(self, **kwargs: Any) -> None:
118104 def stop_cover (self , ** kwargs : Any ) -> None :
119105 """Stop the cover."""
120106 self .action ("stop" )
107+
108+
109+ class FibaroCover (FibaroEntity , CoverEntity ):
110+ """Representation of a fibaro cover which supports only open / close commands."""
111+
112+ def __init__ (self , fibaro_device : DeviceModel ) -> None :
113+ """Initialize the device."""
114+ super ().__init__ (fibaro_device )
115+ self .entity_id = ENTITY_ID_FORMAT .format (self .ha_id )
116+
117+ self ._attr_supported_features = (
118+ CoverEntityFeature .OPEN | CoverEntityFeature .CLOSE
119+ )
120+ if "stop" in self .fibaro_device .actions :
121+ self ._attr_supported_features |= CoverEntityFeature .STOP
122+ if "rotateSlatsUp" in self .fibaro_device .actions :
123+ self ._attr_supported_features |= CoverEntityFeature .OPEN_TILT
124+ if "rotateSlatsDown" in self .fibaro_device .actions :
125+ self ._attr_supported_features |= CoverEntityFeature .CLOSE_TILT
126+ if "stopSlats" in self .fibaro_device .actions :
127+ self ._attr_supported_features |= CoverEntityFeature .STOP_TILT
128+
129+ def update (self ) -> None :
130+ """Update the state."""
131+ super ().update ()
132+
133+ device_state = self .fibaro_device .state .str_value (default = "" ).lower ()
134+
135+ self ._attr_is_opening = device_state == "opening"
136+ self ._attr_is_closing = device_state == "closing"
137+
138+ closed : bool | None = None
139+ if device_state not in {"" , "unknown" }:
140+ closed = device_state == "closed"
141+ self ._attr_is_closed = closed
142+
143+ def open_cover (self , ** kwargs : Any ) -> None :
144+ """Open the cover."""
145+ self .action ("open" )
146+
147+ def close_cover (self , ** kwargs : Any ) -> None :
148+ """Close the cover."""
149+ self .action ("close" )
150+
151+ def stop_cover (self , ** kwargs : Any ) -> None :
152+ """Stop the cover."""
153+ self .action ("stop" )
154+
155+ def open_cover_tilt (self , ** kwargs : Any ) -> None :
156+ """Open the cover slats."""
157+ self .action ("rotateSlatsUp" )
158+
159+ def close_cover_tilt (self , ** kwargs : Any ) -> None :
160+ """Close the cover slats."""
161+ self .action ("rotateSlatsDown" )
162+
163+ def stop_cover_tilt (self , ** kwargs : Any ) -> None :
164+ """Stop the cover slats turning."""
165+ self .action ("stopSlats" )
0 commit comments