Custom Driver Abnormal Behavior

I have successfully integrated my Tuya Vertical Blinds using a custom driver provided by @holand.ivar. The integration is fully local, and the driver works as expected in most cases. However, I’ve noticed some abnormal behaviors that I’m struggling to understand or resolve. I’ve reached out to the driver’s author, but they’re also confused about why these issues are occurring. I’m hoping the community can shed some light on what might be going wrong.

The Issue

The driver works perfectly for basic operations like opening and closing the blinds. However, I’ve encountered two main problems:

  1. Command Execution via Rule Machine (RM): When I trigger the Close command directly from the RM, nothing happens, and the logs show an error. However, if I use the close() custom attribute command or the Close button on the Device Driver page, everything works fine. I’m not sure why there’s a discrepancy here.

  2. Status Detection in RM: My RM rule periodically sends a Status command to update the device’s state. While the status updates correctly on the Device Driver page, the RM rule can’t detect the open/closed status. Interestingly, if I use the Position value as a proxy for open/closed detection, the rule works perfectly. This inconsistency is puzzling.

What I’ve Tried

  • I’ve thoroughly reviewed the driver code and compared how commands are generated through different methods (RM vs. custom attributes).
  • I’ve tested the device with different commands and scenarios to isolate the issue.
  • I’ve ensured that the device firmware and Hubitat software are up to date.

The Code

Here’s a snippet of the driver code that handles the close() command:
groovy
void close() {
send(generate_payload(“set”, [“1”:“close”]))
}

And here’s the device status update logic:
groovy
void parse_tuya_payload(status) {
def jsonSlurper = new groovy.json.JsonSlurper()
def status_object = jsonSlurper.parseText(status)
sendEvent(name: “availableEndpoints”, value: status_object.dps)
if (status_object.dps[“1”] == “open”) {
sendEvent(name: “windowBlind”, value : “open”)
} else if (status_object.dps[“1”] == “close”) {
sendEvent(name: “windowBlind”, value : “closed”)
}
}

The Test Rule

Here’s the RM rule I’m using to test the functionality:
groovy
alias: Blind Control Test
triggers:

  • platform: time
    at: “*:00”
    conditions:
    actions:
  • service: input_boolean.toggle
    entity_id: input_boolean.blind_control
  • service: switch.close
    entity_id: switch.blind

The Results

  • When using the Close command from RM, the device doesn’t respond, and the logs show an error.
  • When using the close() command or the Device Driver button, everything works as expected.
  • The RM rule can’t detect the open/closed status directly but works when using the Position value as a proxy.

My Final Working Rule

Here’s the rule that works reliably:
groovy
alias: Blind Control Final
triggers:

  • platform: time
    at: “*:00”
    conditions:
    actions:
  • service: input_boolean.toggle
    entity_id: input_boolean.blind_control
  • service: switch.close
    entity_id: switch.blind
  • service: switch.open
    entity_id: switch.blind

Conclusion

I’m hoping someone with more experience in driver development or command execution can spot what’s causing these issues. Why does the RM command behave differently from the custom attribute or Device Driver button? And why can’t the RM rule detect the open/closed status directly? Any insights would be greatly appreciated!

Thanks in advance for your help!

P.S. All testing and debugging were done on my spare C-5 and workhorse C-7, both running the latest 2.3.3.140 software. I don’t believe this is a hardware-specific issue.