Driver for Gas Sensor

@mike.maxwell :
I believe that a zigbee/zwave sensor to detect and report on natural gas leakage is an important safety device that many (if not most) Smart Home installations want.

I recently purchased the Heiman (Zigbee) Gas Detector.

Is there any chance that you could add this device to the list of devices that HE supports?
If necessary, I could ship my unit to you for you to play around with.
I think that it would be a worthwhile addition to the Hubitat "stable".
(In other words, "please?")

2 Likes

I agree, however I have quite a backlog currently, I expect things will look better in about a month.

3 Likes

No problem. A month will be perfectly fine. If I can be of some assistance, please let me know.

This doesn't mean in a month that a driver will be available, it means in a month I might have time to consider this device.

We will take whatever we can get!

FYI this zigbee gas sensor is on sale for Amazon Prime Day! $39.19
https://www.amazon.com/gp/product/B07QCSGX53/

@cuboy29 posted a ported driver in this thread that may work. I plan to test on my outdoor gas grill when I receive mine:
https://community.hubitat.com/t/4-types-of-gas-detector-zigbee/17087/50

@mike.maxwell Let me know if you need one of these Gas Detectors (https://www.amazon.com/gp/product/B07QCSGX53/) to help with developing and testing. I would be happy to loan you one (as soon as it arrives).

Ping me in a couple of weeks, hopefully I'll be caught up by then...

OK. Thanks. It's not supposed to be delivered until next week. It does sound like a useful device type.

I just got my gas detector. Anything I can do to help out? I got this one.

I just brought this gas detector from Amazon that @razorwing shows in the post above and borrow a device driver and it shows up as Heiman Gas sensor. I haven't tested it but the green light is on and steady. It seems to be working.

What device driver did you use?

I have one going. Seems to be working for me so far. Haven't test with actual gas yet. I am sure the driver could use some work.

Updated 7/21: Changed smoke status from "cleared" to "clear".

/**
 *  Heiman Natural Gas Sensor
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 */


import hubitat.zigbee.clusters.iaszone.ZoneStatus
 
metadata {
	definition (name: "Heiman Gas Detector", namespace: "hubitat", author: "cuboy29") {
		
        capability "Configuration"
        capability "SmokeDetector"
        capability "Sensor"
        capability "Refresh"
              
        attribute "smoke", "string"
        
		fingerprint profileID: "0104", deviceID: "12", inClusters: "0000,0003,0500,0009", outClusters: "0003,0019"      
    }
}
 
def parse(String description) {
    
	//log.debug "description: $description"
    def descMap = [:]
    
	if (description?.startsWith('zone status')) {
			descMap = parseIasMessage(description)
    }else if (description?.startsWith('enroll request')) {
		    List cmds = zigbee.enrollResponse()
		    descMap = cmds?.collect { new hubitat.device.HubAction(it) }
	}else if (description?.startsWith('catchall')) {
            descMap = parseCatchAllMessage(description)
    }else if (description?.startsWith('read attr'))  {  
            descMap = zigbee.parseDescriptionAsMap(description)
       
            if ((descMap?.cluster == "0500" && descMap.attrInt == 0x0001) && (descMap.value == '002B')){  //Zone Type
                log.debug "Zone Type is Carbon Monoxide (CO) Sensor"
			}else if ((descMap?.cluster == "0500" && descMap.attrInt == 0x0000) && (descMap.value == '01')){  //Zone State
                log.debug "Zone State is enrolled"
			}else if ((descMap?.cluster == "0500" && descMap.attrInt == 0x0002) && ((descMap.value == '0030') || (descMap.value == '0020'))){  //Zone Status
                log.debug "${device.displayName} is cleared"
            }else if (descMap?.cluster == "0000" && descMap.attrInt == 0x0004){  //Manufacture
                sendEvent(name: "manufacture", value: descMap.value)
            }else if (descMap?.cluster == "0000" && descMap.attrInt == 0x0005){  //Model 
                sendEvent(name: "model", value: descMap.value)
            }
	}

	//def result = descMap ? createEvent(descMap) : [:]	
	return descMap   
}    


private Map translateZoneStatus(ZoneStatus zs) {
	// Some sensor models that use this DTH use alarm1 and some use alarm2 to signify motion       
	return getGasResult(zs.isAlarm1Set() || zs.isAlarm2Set())
}

private Map getGasResult(value) {

    def descriptionText = value ? "${device.displayName} has detected GAS!" : "${device.displayName} is clear!"
    log.debug descriptionText
	return [
			name			: 'smoke',
			value			: value ? 'detected' : 'clear',
            isStateChange: true,
			descriptionText : descriptionText
	]
}

private parseCatchAllMessage(String description) {
    
    Map resultMap = [:]
    def descMap = zigbee.parse(description)  
    //log.debug descMap.inspect()
    return resultMap
}

private Map parseIasMessage(String description) {
    
    ZoneStatus zs = zigbee.parseZoneStatus(description)    
    translateZoneStatus(zs)    
}

def refresh() {
    
	log.debug "Refreshing..."
	def refreshCmds = []
    
    refreshCmds +=
	zigbee.readAttribute(0x0500, 1) +	// IAS ZoneType
    zigbee.readAttribute(0x0500, 0) +	// IAS ZoneState
    zigbee.readAttribute(0x0500, 2) +	// IAS ZoneStatus
    zigbee.readAttribute(0x0000, 7) +	// power source
    //zigbee.readAttribute(0x0009, 7) +	// not sure what this cluster do yet
    zigbee.readAttribute(0x0000, 4) +	// manufacture
    zigbee.readAttribute(0x0000, 5) +	// model indentification
        zigbee.enrollResponse()
    
	return refreshCmds
}

def configure() {
    
    log.debug "Configuring..."
    
    def cmds = [
            //bindings
            "zdo bind 0x${device.deviceNetworkId} 1 1 0x0500 {${device.zigbeeId}} {}", "delay 200",
        ] +  zigbee.enrollResponse(1200) + refresh()
    
    return cmds
}
3 Likes

Now I using the one @cuboy29 just listed as it seems to be better.

All I am getting is the model and Manuf. in the Current States. After pressing test button I get Smoke: Cleared

EDIT: Anyone seen this?

OR This:

I wonder if this is the one that works with this driver:

One critical piece of information about this device, if someone could help me.

How often does this device "check in"?
The reason why I find that to be important is that I can test pro grammatically when the device has "checked in". If it misses too many check in's, it probably has dropped from the mesh. Correct?

I am getting this weird stuff in the logs. It repeats these.

dev:2072019-07-19 09:32:30.724 am debugRefreshing...

dev:2072019-07-19 09:32:02.922 am debugNatural Gas Detector is cleared

dev:2072019-07-19 09:32:00.910 am debugZone State is enrolled

dev:2072019-07-19 09:32:00.742 am debugNatural Gas Detector is cleared

dev:2072019-07-19 09:31:58.916 am debugZone Type is Carbon Monoxide (CO) Sensor

dev:2072019-07-19 09:31:58.836 am debugRefreshing...

dev:2072019-07-19 09:31:58.738 am debugZone State is enrolled

dev:2072019-07-19 09:31:56.737 am debugZone Type is Carbon Monoxide (CO) Sensor

dev:2072019-07-19 09:31:54.012 am debugRefreshing...

dev:2072019-07-19 09:31:53.968 am debugConfiguring...

dev:2072019-07-17 04:31:19.494 pm debugNatural Gas Detector, parse description: catchall: 0000 8032 00 00 0040 00 8855 00 00 0000 00 00 00000A0109000003000000000300000000030000000003000000000300000000030000000003000000000300000000030000

dev:2072019-07-17 03:31:52.739 pm debugNatural Gas Detector, parse description: catchall: 0000 0006 00 00 0040 00 8855 00 00 0000 00 00 01FDFF040101190000

it seems to check in every 30 minutes.

image

I'm getting the 30 minutes check in also but not the other that @razorwing is getting? @razorwing did you go into device and click the configure and refresh button ?

Several times, and pressed the test button. There is a reset on the side, I might try that.

EDIT: I did a reset on it and discover and it said it found a previous device, which is correct. I did a configure and refresh again and got the same result. Smoke: Cleared