How to program Zigbee breakers

First, I am using a C-7 updated last week.

I know they can be programmed for 1a to 63a, I just don't know how on Hubitat.

Application 45
Endpoint Id 01
Manufacturer _TZ3000_qeuvnohg
Model TS011F

And the driver it uses is
Tuya Zigbee metering plug

Any help is greatly appreciated.

Paul

Added
All
online , on , 10 W, 124 V, 0.16 A, 1.26 kWh,
Amperage
0.16
Energy
1.26
Energy Cost
0.15
Energy Duration
1.19 Days
Health Status
online
Hourly Energy
0.01
Power
10
Rtt
0
Switch
on
Voltage
124
State Variables
Current Polling Supported
true
Destination EP
01
Driver Version
2.0.2 2025/08/19 8:29 PM
Energy Polling Supported
true
Is Digital
false
Is Refresh Request
false
Last Energy Cost
0.15000000000000013
Last Energy Raw
0.27
Last Hourly Energy
1.26
Last Reset Date
2026-04-15 21:03:28.831
Last Reset Energy
-0.99
Last Rx
{}
Last Switch State
on
Last Tx
{}
Model
TS011F
Not Present Counter
0
Power Polling Supported
true
Rejoin Counter
0
Rx Counter
21336
Switch Debouncing
false
Switch Polling Supported
true
Tx Counter
22
Voltage Polling Supported
true

I have no idea if this will work. I asked AI to make a driver that will only set the over_current_threshold in the device, The idea is to switch to this driver, set the threshold, and then switch back to the Metering Plug driver.

/*
 * Driver: Tuya TS011F Amperage Config
 * Purpose: Set over-current threshold (trip point) via cluster 0xE001, attribute 0x0012.
 * Usage: 1. Pair device (use any generic driver first if needed).
 *        2. Change driver to this one.
 *        3. Run "setTripAmps" with desired value (1‑64 Amps).
 *        4. Switch back to a monitoring driver (the threshold persists).
 */

import hubitat.zigbee.zcl.DataType

metadata {
    definition (name: "Tuya TS011F Amperage Config", namespace: "custom", author: "YourName") {
        capability "Initialize"
        command "setTripAmps", [[name:"Amps", type:"NUMBER", description:"Trip current in Amps (1‑64)"]]
        command "getTripAmps"   // reads the current threshold from the device
    }
    preferences {
        input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true
    }
}

// Tuya custom cluster and attribute for over-current threshold (DP 18)
private static final Integer CLUSTER_OVER_CURRENT = 0xE001
private static final Integer ATTR_THRESHOLD_MA   = 0x0012   // attribute ID for DP 18
private static final Integer DATA_TYPE_UINT32    = 0x21

def installed() {
    initialize()
}

def updated() {
    initialize()
}

def initialize() {
    if (logEnable) log.debug "Initializing Tuya TS011F config driver"
    // Optional: read current threshold on start
    runIn(2, "getTripAmps")
}

// Command to set the trip threshold (Amps -> mA)
def setTripAmps(amps) {
    if (amps == null) {
        log.warn "setTripAmps: no value provided"
        return
    }
    Integer ampsInt = amps.toInteger()
    if (ampsInt < 1 || ampsInt > 64) {
        log.warn "Amperage must be between 1 and 64 (given: ${ampsInt})"
        return
    }
    Integer milliamps = ampsInt * 1000
    logDebug "Setting over-current threshold to ${ampsInt}A (${milliamps}mA)"
    
    // Build and send the writeAttribute command
    List<String> cmds = zigbee.writeAttribute(
        CLUSTER_OVER_CURRENT,
        ATTR_THRESHOLD_MA,
        DATA_TYPE_UINT32,
        milliamps
    )
    sendZigbeeCommands(cmds)
    
    // Optionally read back after a short delay to confirm
    runIn(2, "getTripAmps")
}

// Command to read the currently set threshold
def getTripAmps() {
    logDebug "Reading over-current threshold"
    List<String> cmds = zigbee.readAttribute(
        CLUSTER_OVER_CURRENT,
        ATTR_THRESHOLD_MA
    )
    sendZigbeeCommands(cmds)
}

// Parse incoming Zigbee reports (handles read attribute response)
def parse(String description) {
    if (logEnable) log.debug "parse: ${description}"
    
    Map map = zigbee.parseDescriptionAsMap(description)
    if (!map) return []
    
    // Check if this is a read attribute response from our cluster/attribute
    if (map.clusterId == CLUSTER_OVER_CURRENT && map.attrId == ATTR_THRESHOLD_MA) {
        if (map.value) {
            Integer milliamps = map.value as Integer
            Integer amps = milliamps / 1000
            log.info "Current over-current threshold = ${amps}A (${milliamps}mA)"
            // Optionally send an event (not required, but nice)
            sendEvent(name: "tripAmps", value: amps, unit: "A")
        } else {
            log.warn "Failed to parse threshold value from response"
        }
    }
    return []
}

private logDebug(msg) {
    if (logEnable) log.debug msg
}

Ok, I selected your code, then I went to the driver code, and it will not let me paste the code in the text area. I can enter manually one letter at a time or it says I can import from url. How do I do this.

Another question. What AI are are you referencing?

Thanks

You should simply be able to copy and paste the code into the code editor. Try an incognito/private window in your browser and see what happens.

Ok, I figured that out now. I was trying to press and hold in the code box and the options said download, share and something else.

But, if you single tap the code box, then paste comes up.

When I tried to save the code, it gave me a few errors.

Modifier 'private' not allowed here. @ line 24, column 1.
Modifier 'static' not allowed here. @ line 24, column 1.
Modifier 'private' not allowed here. @ line 25, column 1.
Modifier 'static' not allowed here. @ line 25, column 1.
Modifier 'private' not allowed here. @ line 26, column 1.
Modifier 'static' not allowed here. @ line 26, column 1.

I think the AI is broken if it gives code with errors. Just my opinion there. Lol.

No one has told me where to find this AI so I can try it myself.

Thanks

You can use any commercially available LLM with a free tier, or pay for one.

ChatGPT, Claude, Copilot, Grok. All have free and paid tiers. For example.

I’ve been using Claude recently. Not specifically for groovy coding, but I’d use it if I had a need.

1 Like

Thanks @marktheknife . I had a feeling it was not something I missed in the hubitat ecosphere.

Well, I have a feeling @chrisbvt used Groc to make that driver because I tried it there and mine came up with the same error messages.

One off topic question. If you are running multiple hubs, on each zigbee radio should they be the same channel or a different channel?

Coming in late here, and I may have missed the plot, but is a Zigbee breaker a spouse with a crowbar?

3 Likes

It depends. If they can "see" each other, than yes. If they are in separate buildings (like my situation) then it doesn't really matter.

Ok, 1st, thanks John, I needed that. Truly needed that laugh.

Just to clarify, I purchased some din rail mount zigbee circuit breakers for my powerhouse. (Solar with dual backup)

2nd, Slate, I imagine they can see each other. My powerhouse which I wanted separate, is 50' or so from the house. They are both using the same mesh routers and I know the mesh routers can see each other so I imagine the zigbee devices can too, I just didn't know if they could use the same zigbee network channel.

The powerhouse is more like a close island. Lol. It was just easier for me to have them as separate hubs.

Any other input is greatly appreciated.

As far as the zigbee breaker driver, I did get positive results from Gemini. Groc didn't work, but at least it was consistent. Lol. My results matched Chris's results with the same errors.

With Gemini it worked. Now I am going to see if it can do a full driver or I might hit up kkossev to put the two drivers together.

I was able to change the driver to the custom one Gemini made, and save it, then I clicked configure or initialize, which ever one it was. Then I set the max amp level on one breaker to 20a @ 120vac max, and the other one to 50a @ 220vac max. Then I changed the driver back to tuya Zigbee metering plug for the rest.

I might try to get it to make one that does it all but I will probably tank that one. Hehehe

By the way, the zigbee breakers are original set to 63a for 120vac or 220vac breakers.

Thanks everyone!