[RELEASE] Home Assistant Device Bridge (HADB)

I'm running the latest (hit reset and re-setup HA from scratch over he weekend). HassOS 5.13, Core:core-2021.4.3.

just did a little more testing with all my fan devices.

I have 5 different fans I'm trying to integrate.

2 of them are Dyson fans using the dyson HA integration - these 2 work fine with hubitat (on and off correctly)

The other 3 area Tuya based fan integrated to HA using TuyaLocal. They work fine in HA, just would not turn on in HE. Sound like its an issue with TuyaLocal rather than this app?

Same versions here. I just retested the Fan support using my Caseta Fan controller, and it appears to still work fine. I can change the fan from on to off, and vice versa using Hubitat, the Lutron App, or Home Assistant dashboard and all stay in synch correctly.

So, it may be the Tuya integration for Hass needs some updates? :man_shrugging: Just a guess on my part.

I turned on debug and this is what happens when I turn on the problem fan

dev:8122021-04-13 01:00:21.438 pm debugmessOn = {"id":12,"type":"call_service","domain":"fan","service":"set_percentage","service_data":{"entity_id":"fan.living_room_fan","percentage":"50"}}
dev:8122021-04-13 01:00:21.434 pm inforeceived setSpeed request from Living Room Fan, with speed = on

I did some test on the HA side. For the LocalTuya integration, if the fan is in the off state, changing the speed slider does not turn it on. (I'm guessing this is that the 'set_percentage' is doing?).

In contrast the for dyson integration, setting the percentage does turn the fan. So this one works well.

Is there an easy way to have the on command send just the 'on' command rather than the set_percentage command?

Can you please try replacing the "componentSetSpeed" function in your current Parent Driver with the following one? I have added fan_on and fan_off commands in addition to the set_percentage call to Home Assistant to see if this help with your LocalTuya devices. If this works, then I'll add it to the GitHub repo.

def componentSetSpeed(ch, speed) {
    if (logEnable) log.info("received setSpeed request from ${ch.label}, with speed = ${speed}")
    int percentage = 0
    switch (speed) {
        case "off":
            percentage = 0
            break
        case "low":
        case "medium-low":
            percentage = 25
            break
        case "on":
        case "auto":
        case "medium":
            percentage = 50
            break
        case "medium-high":
            percentage = 75
            break
        case "high":
            percentage = 100
            break
        default:
            if (logEnable) log.info "No case defined for Fan setSpeed(${speed})"
    }
    state.id = state.id + 1
    entity = ch.name
    domain = entity.tokenize(".")[0]
    messPCT = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "set_percentage", service_data: [entity_id: "${entity}", percentage: "${percentage}"]])        
    if (logEnable) log.debug("messOn = ${messPCT}")
    interfaces.webSocket.sendMessage("${messPCT}")
    
    //added per user request to help will fan devices on Hass that do not turn on/off properly when set_percentage is called.
    if (percentage != 0) {
        messOn = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "turn_on", service_data: [entity_id: "${entity}"]])
        interfaces.webSocket.sendMessage("${messOn}")
    } else {
        messOff = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "turn_off", service_data: [entity_id: "${entity}"]])
        interfaces.webSocket.sendMessage("${messOff}")
    }
    
}
2 Likes

Thanks. I've replaced the code and re-initialised the driver. Looks like its still calling set_percentage when 'on' is pressed.

dev:8122021-04-14 02:47:25.993 pm debugparse(): description = {"id": 4, "type": "result", "success": true, "result": {"context": {"id": "4571155054581dff3b477c78759f3b65", "parent_id": null, "user_id": "7636bdd23e114092b751450d40cb2d20"}}}
dev:8122021-04-14 02:47:25.951 pm debugparse(): description = {"id": 4, "type": "result", "success": false, "error": {"code": "id_reuse", "message": "Identifier values have to increase."}}
dev:8122021-04-14 02:47:25.899 pm debugmessOn = {"id":4,"type":"call_service","domain":"fan","service":"set_percentage","service_data":{"entity_id":"fan.living_room_fan","percentage":"50"}}
dev:8122021-04-14 02:47:25.895 pm inforeceived setSpeed request from Living Room Fan, with speed = on

Yes, it will still call 'set_percentage', as that is what Hass expects. It will also call 'fan_on', which I was hoping would help with your Tuya fan device. Did your fan turn on?

I have made another change to try and improve the behavior. Please try the following code and let me know if that resolves the Tuya issue. I am not a Home Assistant expert, but I am learning... :wink: This version still works fine with my Caseta fan controllers.

def componentSetSpeed(ch, speed) {
    if (logEnable) log.info("received setSpeed request from ${ch.label}, with speed = ${speed}")
    int percentage = 0
    switch (speed) {
        case "off":
            percentage = 0
            break
        case "low":
        case "medium-low":
            percentage = 25
            break
        case "on":
        case "auto":
        case "medium":
            percentage = 50
            break
        case "medium-high":
            percentage = 75
            break
        case "high":
            percentage = 100
            break
        default:
            if (logEnable) log.info "No case defined for Fan setSpeed(${speed})"
    }
    state.id = state.id + 1
    entity = ch.name
    domain = entity.tokenize(".")[0]
//    messPCT = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "set_percentage", service_data: [entity_id: "${entity}", percentage: "${percentage}"]])        
//    if (logEnable) log.debug("messOn = ${messPCT}")
//    interfaces.webSocket.sendMessage("${messPCT}")
    
    //added per user request to help will fan devices on Hass that do not turn on/off properly when set_percentage is called.
    if (percentage != 0) {
        messOn = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "turn_on", service_data: [entity_id: "${entity}", percentage: "${percentage}"]])
        interfaces.webSocket.sendMessage("${messOn}")
    } else {
        messOff = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "turn_off", service_data: [entity_id: "${entity}"]])
        interfaces.webSocket.sendMessage("${messOff}")
    }
    
}

Thanks very much. The it's working now. Set Speed from the off state also works. Just curious, the 'On' in the HE side works a little differently from the HA side. Hitting 'On' in HE always sets the fan to medium where as in HA it just turns it on to its last set speed. Is this due to some limitation on the HE built in fan driver?

Well....it was a design decision I made when I was trying to figure things out for this integration. I am going to continue to tweak the design to try and improve it. Your assistance in testing will be appreciated, as I only have the Caseta fan controller to test with.

Thanks for the quick feedback!

2 Likes

This is the classic conundrum .. should a level change turn the device on if it was off. Same with lighting.

I prefer it doesn’t as then you can preset the brightness that a bulb will come on at when next turned on. Eg set bathroom lights to 50% after midnight till waking time. It also retains last brightness when turned off. The on off controls power and the level just sets the brightness or speed for when power is next applied. This means you can have a device off at 50% or on at 0%. An automation system can manage this giving you the preset feature but it’s not as basically intuitive.

Thanks. Happy to help. Let me know if you need anything tested.

Please give this one a try and let me know if it retains your previous speed setting when simply using the ON and OFF commands...

def componentSetSpeed(ch, speed) {
    if (logEnable) log.info("received setSpeed request from ${ch.label}, with speed = ${speed}")
    int percentage = 0
    entity = ch.name
    domain = entity.tokenize(".")[0]
    switch (speed) {
        case "on":
            state.id = state.id + 1
            messOn = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "turn_on", service_data: [entity_id: "${entity}"]])
            interfaces.webSocket.sendMessage("${messOn}")
            break
        case "off":
            state.id = state.id + 1    
            messOff = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "turn_off", service_data: [entity_id: "${entity}"]])
            interfaces.webSocket.sendMessage("${messOff}")
            break
        case "low":
        case "medium-low":
            percentage = 25
            break
        case "auto":
        case "medium":
            percentage = 50
            break
        case "medium-high":
            percentage = 75
            break
        case "high":
            percentage = 100
            break
        default:
            if (logEnable) log.info "No case defined for Fan setSpeed(${speed})"
    }

    if (percentage != 0) {
        state.id = state.id + 1
        messOn = JsonOutput.toJson([id: state.id, type: "call_service", domain: "${domain}", service: "turn_on", service_data: [entity_id: "${entity}", percentage: "${percentage}"]])
        interfaces.webSocket.sendMessage("${messOn}")
    }
}

Yep. It now retains previous setting. Thanks!

2 Likes

I have just pushed version 0.1.28 of the Parent Driver to the GitHub repo which includes the Fan device changes that @bendarklighter has helped to debug.

2 Likes

[quote] Home Assistant Device Bridge parent device (or the custom name you set in the app) and all the compatible devices from Home Assistant will begin to populate with child devices in Hubitat, upon each device update.
[/quote]

Any updates to the device? Like I want to transfer my Nest Protects. I have some that are battery powered. Do I have to set the smoke and CO off to get them to move over? lol. I selected them to have them cross the Bridge to my Hubitat but they aren't showing up.

I thought maybe doing a test on them, changing their name in HA, but none of it is working lol. Ok I can set off the smoke sensors but how the heck do I trigger the CO and do I have to each one? LOL. Or will just setting off one get the others to be sent over? I guess I could have my emergency switch just go to home bridge and set up a rule in HA LOL.

Smoke detectors are not in the supported list...yet.

Ahhh that makes it easy just move my ER switch across the Bridge lol.

I have a pair of Garage doors that do not show up in the list of available HA devices/entities to expose to Hubitat. They are actually integrated into HA through the HA SmartThings integration, though I can’t see how this would affect the Device Bridge, but thought I should mention it.

In HA, they are device class “door”, with device entity ID “cover.left_garage_door”. See the attached screenshot below from HA. Can’t figure out if there’s something else I need to do to pick this up in HE as a Generic Component Contact Sensor. I’m open to ideas, and can provide additional logs if needed, but I don’t see anything wrong—it just doesn’t show up, even with debug logging turned on for the HE Device (“Home Assistant Device Bridge”).

Any thoughts as to the inclusion of a mapping from an HA-discovered/integrated Lock device to a Generic Component Switch in HE?

It looks like you're using a template cover and that isn't supported by the driver. You can create a simple automation in HA to turn ON a virtual switch when your door sensor is open and OFF when it's closed and that virtual switch should be recognized by Home Assistant Device Bridge.

Another way you can do this is to add @jason0x43 's integration to HA and share a virtual device from HE to HA. Then create the two simple automations so your real device in HA controls the virtual device on HE.

1 Like