Open lankhaar opened 5 days ago
@make-all , judging on the tags you've added/removed I don't think I made myself 100% clear.
The id that I mentioned (for Kabum Smart 700 Rev 2023) was just an example, but for me the search seems broken entirely, I can't seem to find ANY product. The search result will always be the same (19% match on asc_wifi_circuit_breaker
).
To clarify what I said in the issue itself; no matter the input I provide, I will never enter the else clause in the following code nor will I get actual usefull results. The result I get appear to be static. https://github.com/make-all/tuya-local/blob/80b014167f436147a31e934f5b57715258fbfcff/custom_components/tuya_local/config_flow.py#L492-L505
I hope that clears things up now :-)
You are correct that you are not making yourself clear. You say "I can't seem to find ANY product", but your screenshot shows six possible matches found. And now your complaint seems to be that you are not able to enter the else clause, which is the "can't find ANY product" case.
@make-all , I'm sorry for all the confusion, let me start over (I've updated the OP in case other people read this issue and get confused as well, so I recommend you read that again since all details are there);
In my very specific case, I want to add a robot vacuum; brand Zedar, model R600 (see Zedar R600). I added my own yaml file for this (which looks a lot like the one from "Kabum Smart 700 Rev 2023" and I'll make a PR for it once I've got it to work).
Now the problem: when I connect to the device, I see indeed 6 devices, but not the device I expected to find, even though the dps I see in the logs match with the ones in the yaml.
There is a script utils/match_against.py
which you can use at the command line (after setting up your python environment to include all the requirements-dev.txt requirements, and including the tuya-local base directory in your PYTHONPATH). It takes two arguments: the name of the config file to match against, and the dps list in the json format output in the logs (enclose it in single quotes to ensure it goes through as a single argument)
That was really helpfull, thanks @make-all !
This helped me doing some debugging and I managed to add the device now. I'm only left with a few more issues. Perhaps you could guide me into the right direction?
The vacuum is in an idle state, but here there's some sort of state which says error, however I'm not even sure what that card entry is;
Also none of the commands work yet. I'll continue my troubleshooting, but I'd love to hear if you've got an idea :-D
I'm almost there, but I'm gonna need help with the final part. I think I've mapped all data, everything is showing correctly (except for that error from previous comment, but I'm not sure what you'd need for that). From what I can see my issues are only in the action (sending it out to clean, sending it to it's dock, etc.). On every action change, Tuya seems to be doing 3 things.. Changing the status (DP ID 5), changing the mode (DP ID 4), changing the power_go (DP ID 1)
Hope you can help!
yiarxtixzkmnegxk
name: Robot vacuum
products:
- id: yiarxtixzkmnegxk
name: Zedar R600
primary_entity:
entity: vacuum
dps:
- id: 1
type: boolean
optional: true
name: activate
mapping:
- dps_val: false
constraint: pause
conditions:
- dps_val: true
value: false
- dps_val: false
value: false
hidden: true
- dps_val: null
value: false
hidden: true
- dps_val: true
constraint: pause
conditions:
- dps_val: false
value: true
- dps_val: true
value: true
hidden: true
- dps_val: null
value: true
hidden: true
- dps_val: null
value: false
hidden: true
- id: 2
type: boolean
optional: true
name: pause
- id: 3
name: return_to_base
type: boolean
optional: true
- id: 4
type: string
name: command
mapping:
- dps_val: smart
value: smart
- dps_val: chargego
value: return_to_base
- dps_val: zone
value: zone
- dps_val: pose
value: go_to_position
- dps_val: part
value: room
- id: 5
type: string
name: status
mapping:
- dps_val: standby
value: standby
- dps_val: smart
value: cleaning
- dps_val: smart_clean
value: cleaning
- dps_val: zone_clean
value: cleaning
- dps_val: part_clean
value: cleaning
- dps_val: cleaning
value: cleaning
- dps_val: paused
value: paused
- dps_val: goto_pos
value: going_to_location
- dps_val: pos_arrived
value: on_location
- dps_val: pos_unarrive
value: cannot_find_location
- dps_val: goto_charge
value: returning
- dps_val: charging
value: charging
- dps_val: charge_done
value: charged
- dps_val: sleep
value: sleep
- dps_val: select_room
value: select_room
- dps_val: wall_follow
value: wall_follow
- dps_val: direction_control
value: direction_control
- id: 9
type: string
name: fan_speed
mapping:
- dps_val: turnoff
value: "Off"
- dps_val: gentle
value: Low
- dps_val: normal
value: Medium
- dps_val: strong
value: High
- id: 11
type: boolean
optional: true
name: locate
- id: 12
type: string
optional: true
name: direction_control
mapping:
- dps_val: forward
value: forward
- dps_val: backward
value: reverse
- dps_val: turn_left
value: left
- dps_val: turn_right
value: right
- dps_val: stop
value: stop
- id: 14
type: string
optional: true
name: path_data
- id: 15
type: base64
optional: true
name: complex_command
- id: 16
type: string
optional: true
name: request
mapping:
- dps_val: get_map
value: Get map
- dps_val: get_path
value: Get path
- dps_val: get_both
value: Get both
- id: 28
type: bitfield
name: error
mapping:
- dps_val: 2
value: left_wheel_hang
- dps_val: 4
value: main_brush_stuck
- dps_val: 8
value: right_wheel_hang
- dps_val: 16
value: left_wheel_stuck
- dps_val: 32
value: right_wheel_stuck
- dps_val: 64
value: cliff
- dps_val: 128
value: side_brush_stuck
- dps_val: 512
value: collision
- dps_val: 1024
value: dust_box_stuck
- dps_val: 4096
value: ground_check_failure
- dps_val: 32768
value: vacuum_motor_stuck
- dps_val: 65536
value: high_current
- dps_val: 131072
value: charge_port_closed
- id: 32
type: string
optional: true
name: device_timer
- id: 33
type: string
optional: true
name: disturb_time_set
- id: 34
type: string
optional: true
name: device_info
- id: 35
type: string
optional: true
name: voice_data
- id: 36
name: language
type: string
optional: true
secondary_entities:
# - entity: button
# name: Start
# icon: "mdi:play"
# category: config
# dps:
# - id: 1
# type: boolean
# name: button
# optional: true
# - entity: button
# name: Pause
# category: config
# icon: "mdi:pause"
# dps:
# - id: 2
# type: boolean
# name: button
# optional: true
# - entity: button
# name: Dock
# category: config
# icon: "mdi:lightning-bolt"
# dps:
# - id: 3
# type: boolean
# name: button
# optional: true
- entity: sensor
name: Cleaning time
class: duration
category: diagnostic
dps:
- id: 6
type: integer
name: sensor
unit: min
class: measurement
- entity: sensor
name: Cleaned area
category: diagnostic
icon: "mdi:floor-plan"
dps:
- id: 7
type: integer
name: sensor
unit: m2
- entity: sensor
class: battery
dps:
- id: 8
type: integer
name: sensor
unit: "%"
class: measurement
- entity: select
name: Mopping
icon: "mdi:cup-water"
category: config
dps:
- id: 10
type: string
name: option
optional: true
mapping:
- dps_val: closed
value: "Off"
- dps_val: low
value: Low
- dps_val: middle
value: Medium
- dps_val: high
value: High
- dps_val: null
value: "Off"
hidden: true
- entity: button
name: Reset map
category: config
dps:
- id: 13
type: boolean
name: button
optional: true
- entity: sensor
name: Edge brush life
class: duration
category: diagnostic
dps:
- id: 17
type: integer
name: sensor
unit: min
- entity: button
name: Edge brush reset
class: restart
category: config
dps:
- id: 18
type: boolean
name: button
optional: true
- entity: sensor
name: Roll brush life
class: duration
category: diagnostic
dps:
- id: 19
type: integer
name: sensor
unit: min
- entity: button
name: Roll brush reset
class: restart
category: config
dps:
- id: 20
type: boolean
name: button
optional: true
- entity: sensor
name: Filter life
class: duration
category: diagnostic
dps:
- id: 21
type: integer
name: sensor
unit: min
- entity: button
name: Filter reset
class: restart
category: config
dps:
- id: 22
type: boolean
name: button
optional: true
- entity: sensor
name: Mop life
class: duration
category: diagnostic
dps:
- id: 23
type: integer
name: sensor
unit: min
- entity: button
name: Mop reset
class: restart
category: config
dps:
- id: 24
type: boolean
name: button
optional: true
- entity: switch
name: Do not disturb
category: config
dps:
- id: 25
type: boolean
name: switch
optional: true
mapping:
- dps_val: null
value: false
hidden: true
- entity: number
name: Volume
category: config
icon: "mdi:volume-high"
dps:
- id: 26
type: integer
name: value
range:
min: 0
max: 10
unit: "%"
mapping:
- scale: 0.1
@make-all , I can tell by the amount of "new device requests" that you're a busy man, so I'm happy to add support for this myself. It would be amazing if you could push me into the direction on how to debug though, because it could take me days finding it out on my own lol.
If I can get the commands to work, that would be amazing already. I already shared what's needed for that in my last comment.
Currently I have to get 2 things done I guess. When play button is hit, I should update the command
to "smart" and switch power_go
(aka activate
) to true. I assume this is done through the mapping on the command? Would that look something like the following snippet? Or should this be configured on it's primary entity instead of on the command?
- entity: button
name: Start
icon: "mdi:play"
category: config
dps:
- id: 1
type: boolean
name: button
optional: true
mapping:
- dps_val: true
constraint: command
value: smart
Also I see one weird thing in the activate
command. If I click the play button, you'll see that it will turn itself off again, I assume because it updates data from the device which never turned on. Not sure whether that is or is not intended. Could be intended because it technically never turns on (it never starts executing any kind of command).
https://github.com/make-all/tuya-local/assets/107768491/f9471125-ffae-47da-861b-81de68def70e
I do not see any messages in the log either, is there some kind of way to debug this? Maybe a way to see a response from the device after sending it a command?
Hi @make-all , sorry for pinging you again.
I've finished the mapping so all data is showing correctly (inculding the error I mentioned 2 comment earlier).
Now I'm only stuck with the commands not working. I did my research and I'm fairly certain that my entity is configured correctly, but my device doesn't really seem to pickup the commands it should recieve. I have enabled debug logs and here's what I've got:
2024-07-05 16:26:09.587 DEBUG (MainThread) [custom_components.tuya_local.helpers.device_config] Robot vacuum: Mapped dps 1 to True from True
2024-07-05 16:26:09.587 DEBUG (MainThread) [custom_components.tuya_local.helpers.device_config] Considering mapping for range of activate
2024-07-05 16:26:09.588 DEBUG (MainThread) [custom_components.tuya_local.device] Zedar vacuum new pending updates: {"2": {"value": false, "updated_at": 1720189569.5880642, "sent": false}, "1": {"value": true, "updated_at": 1720189569.5880642, "sent": false}}
2024-07-05 16:26:09.589 DEBUG (MainThread) [custom_components.tuya_local.device] Zedar vacuum sending dps update: {"1": true, "2": false}
2024-07-05 16:26:09.705 DEBUG (MainThread) [custom_components.tuya_local.device] Zedar vacuum received {"1": false, "2": true, "4": "chargego", "5": "charge_done", "6": 0, "7": 0, "8": 100, "9": "strong", "17": 7371, "19": 12771, "21": 7371, "23": 13678, "26": 4, "27": false, "28": 0, "45": true, "102": false, "105": false, "106": false, "107": false, "108": false, "full_poll": true}
I'm not entirely sure what's happening here. It mentions it's sending the dps update as I expect it to send, but the dps aren't updated. Anything that you know of I can do?
Sorry didn't mean to close it...
@make-all , I can confirm that the commands I have configured do work (mapping is correct), but they never actually get to the device. I have wrote a custom script which worked instantly
% cat zedar.py
import tinytuya
import sys
device = tinytuya.Device('DEVICE_ID', 'IP_ADDRESS', 'LOCAL_KEY')
device.set_version(3.3)
data = device.status()
request = sys.argv[1]
if (request == 'status'):
print('Datapoints %r' % data)
if (request == 'start'):
payload=device.generate_payload(tinytuya.CONTROL, {'1': True, '2': False})
if (request == 'pause'):
payload=device.generate_payload(tinytuya.CONTROL, {'2': True})
if (request == 'charge'):
payload=device.generate_payload(tinytuya.CONTROL, {'4': 'chargego'})
device._send_receive(payload)
With that script, I can run the following commands with no problem and the vacuum will follow up the commands;
python3 zedar.py start
python3 zedar.py pause
python3 zedar.py charge
Do you have any idea why these commands aren't received by the device if sent through your integration?
Describe the bug After a clean install of tuya-local (and a fairly clean install of HA), I can't find the device I expected to find. I fill in all data (ip, protocol 3.3, local key) for my device (a robot vacuum cleaner) and the dps that are logged are in fact the dps I would expect from my robot vacuum so no issues there it seems, yet it will always suggest the same 6 devices (see screenshot) with none of them being a robot vacuum.
I have also added my own yaml file with my device id and configured all dps (it's almost identical to the device ID
kljjvealoaepeysi
, device "Kabum Smart 700 Rev 2023").All the dps I find in the log match the one from the yaml file, yet it's not suggested as a device type.
Additional context Logs: