Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 41 additions & 9 deletions custom_components/xiaomi_miot/core/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ async def init_miot_coordinators(self, interval=60):

all_mapping = {**self.miot_mapping()}
chunks = self.custom_config_list('chunk_coordinators') or []
if self.miio2miot:
if self.miio2miot and not self.miio2miot.config.get('extend_miot_props'):
chunks = []

def update_factory(mapping, notify=False, chunk_services=None):
Expand Down Expand Up @@ -856,7 +856,25 @@ async def update_miot_status(
if use_local:
try:
if self.miio2miot:
results = await self.miio2miot.async_get_miot_props(self.local, mapping)
if self.miio2miot.config.get('extend_miot_props'):
miio_specs = self.miio2miot.specs
local_mapping = {
k: v for k, v in mapping.items()
if MiotSpec.unique_prop(v, valid=True) not in miio_specs
}
if not max_properties:
max_properties = self.custom_config_integer('chunk_properties')
if not max_properties:
max_properties = self.local.get_max_properties(local_mapping)
if local_mapping:
results = await self.local.async_get_properties_for_mapping(
max_properties=max_properties,
did=self.did,
mapping=local_mapping,
)
results.extend(await self.miio2miot.async_get_miot_props(self.local, mapping))
else:
results = await self.miio2miot.async_get_miot_props(self.local, mapping)
if attrs := self.miio2miot.entity_attrs():
self.props.update(attrs)
self.dispatch(self.decode_attrs(attrs))
Expand Down Expand Up @@ -1049,13 +1067,19 @@ async def async_set_properties(self, params):
if not self._local_state or self.cloud_only or cloud_write:
cloud_params = params
elif self.miio2miot:
local_params = []
for param in params:
siid = param['siid']
piid = param['piid']
if not self.miio2miot.has_setter(siid, piid=piid):
cloud_params.append(param)
if self.miio2miot.config.get('extend_miot_props'):
local_params.append(param)
else:
cloud_params.append(param)
continue
results.append(await self.miio2miot.async_set_property(self.local, siid, piid, param['value']))
if self.local and local_params:
results.extend(await self.local.async_send('set_properties', local_params) or [])
elif self.local:
results = await self.local.async_send('set_properties', params)
if self.cloud and cloud_params:
Expand Down Expand Up @@ -1306,22 +1330,30 @@ async def update_miio_props(self, props=None):
return
if props is None:
props = self.custom_miio_properties
if not props:
return
if self.miio2miot:
attrs = self.miio2miot.only_miio_props(props)
raw = self.miio2miot.only_miio_props(props)
if not isinstance(raw, dict):
raw = dict(zip(props, raw))
else:
try:
num = self.custom_config_integer('chunk_properties') or 15
attrs = await self.local.async_get_properties(props, max_properties=num)
raw = await self.local.async_get_properties(props, max_properties=num)
except DeviceException as exc:
self.log.warning('%s: Got miio properties %s failed: %s', self.name_model, props, exc)
return
if len(props) != len(attrs):
if len(props) != len(raw):
self.props.update({
'miio.props': attrs,
'miio.props': raw,
})
return
attrs = dict(zip(map(lambda x: f'miio.{x}', props), attrs))
self.props.update(attrs)
raw = dict(zip(props, raw))
attrs = dict(zip(map(lambda x: f'miio.{x}', props), raw.values()))
if attrs:
self.props.update(attrs)
self.data['updated'] = dt.now()
self.dispatch(self.decode_attrs(attrs))
self.log.info('%s: Got miio properties: %s', self.name_model, attrs)

@cached_property
Expand Down
3 changes: 3 additions & 0 deletions custom_components/xiaomi_miot/core/device_customizes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2703,6 +2703,9 @@
'yeelink.curtain.ctmt2': {
**CHUNK_1,
'chunk_coordinators': [],
'sensor_properties': 'battery_level,battery_level_2',
'miio_cloud_props': 'get_child,battery,battery2',
'miio_cloud_props_template': 'yeelink_curtain_ctmt2_cloud_props',
},
'yeelink.bhf_light.v1': {
'interval_seconds': 30,
Expand Down
12 changes: 12 additions & 0 deletions custom_components/xiaomi_miot/core/miio2miot_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,18 @@ def cbk(prop, params, props, **kwargs):
},
},

'yeelink.curtain.ctmt2': {
'extend_miot_props': True,
'miio_props': ['get_child'],
'miio_specs': {
'prop.3.100': {'prop': 'battery'},
'prop.3.101': {
'prop': 'battery2',
'template': '{{ value|int(0) if props.get_child|int(1) == 2 else none }}',
},
},
},

'yeelink.light._base': {
'miio_specs': {
'prop.2.1': {'prop': 'power', 'setter': True, 'format': 'onoff'},
Expand Down
26 changes: 26 additions & 0 deletions custom_components/xiaomi_miot/core/miot_specs_extend.json
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,32 @@
}
]
}
],

"yeelink.curtain.ctmt2": [
{
"iid": 3,
"properties": [
{
"iid": 100,
"type": "urn:miot-spec-v2:property:battery-level",
"format": "uint8",
"access": ["read"],
"unit": "percentage",
"value-range": [0, 100, 1],
"description": "Left"
},
{
"iid": 101,
"type": "urn:miot-spec-v2:property:battery-level-2",
"format": "uint8",
"access": ["read"],
"unit": "percentage",
"value-range": [0, 100, 1],
"description": "Right"
}
]
}
]

}
8 changes: 8 additions & 0 deletions custom_components/xiaomi_miot/core/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@
"'coolwind_gear': val[1],"
"'venting_gear': val[2],"
"} }}",
'yeelink_curtain_ctmt2_cloud_props': "{%- set child = props.get('prop.get_child', 1) | int(1) %}"
"{%- set bat = props.get('prop.battery') %}"
"{%- set bat2 = props.get('prop.battery2') %}"
"{{ {"
"'yl_curtain.battery_level': bat | int(0) if bat is not none else none,"
"'yl_curtain.battery_level_2': bat2 | int(0)"
" if child == 2 and bat2 is not none else none,"
"} }}",
'zimi_powerstrip_v2_power_cost': "{%- set val = (result.0 | default({})).get('value','[0]') %}"
"{%- set day = now().day %}"
"{%- set vls = (val | from_json)[0-day:] %}"
Expand Down
Loading