Hubitat for AUS/NZ Chat

Yeah I was going to say you could buy the Xbee S2C to save on $$$ here is some more on Aliexpress too. In relation to boards just these which I mentioned previously. Then plug straight into USB ports by replacing a few of your GPO's around the house with these.

Interesting, the other way might be to buy the Sonoff Basic ZBR3 that would make them a bloody cheap option too with the added bonus of just wiring into your existing lamp looms. Note, I haven't done this so I am making an assumption they act as zigbee routers. I do have one at home but haven't played with it.

Hang on all the boards have mini usb connectors so will need another adapter. WAF isn't an issue but I can't :stuck_out_tongue_closed_eyes:

1 Like

haha, just design a slick looking 3d printed case that looks neat then :stuck_out_tongue: . Hell someone has probably already designed one somewhere that you could just use. If your looking for something a little more stealth then that Basic R3Z would be pretty slick (if it works the way I assume it would).

Love to go cheap but these are non approved right and I'm also trying to avoid the expense of electricians turning up which is why all my stuff is either low power or bulbs.:grinning:

1 Like

Yeah I personally prefer low voltage as well which is why i like the Xbee's more although you'll just need to either make a 3d printed case and neaten it up a bit or just find USB ports behind your existing devices in the house. I actually installed 11 of those GPO's I mentioned above so I have ports everywhere and most are covered behind furniture, devices etc so if I had gone that route a short usb cable plugged into a tiny box with it running would have worked for me.

FYI all, @markus has done some great work here on Tasmota drivers and merged firmware to support them in HE, so if your into flashing Tuya or running Sonoff devices check it out.

2 Likes

Thats cool, The xbee adapters have ftdi pins so easy to wire up for power and ground.

I might break open one of the tradfri repeaters to see whether I can hook up an rpa connector for a bit of extra gain.

Also I noticed you can buy ikea usb wall plugs that the repeaters come with so entirely possible to build repeaters that look like tradfris but have xbees inside lol.

2 Likes

Now your thinking! Good luck and post your results as I am sure other's will be interested in that too.

Using Sonoff Basic ZBR3's get my vote.
I've also got one of the Zigbee On/Off controllers, that are on fleabay, which routes my Iris and Sengled devices.

1 Like

what are people using for house energy consumption viewing ?
any aus spec zwave/zigbee/wifi ones that work with HE ?

This should be good news for you guys as this will/should drive the Z-Wave prices down and make it more affordable.

1 Like

Here's my take on a siren using the Shelly 1 and sgrayban's alarm driver (not wired up yet). Uses standard 115 db siren, 2.5mm power socket and 12V plug pack from either Altronics or Jaycar. If anyone is interested in the case I can put it up on Thingiverse.

4 Likes

Looks good mate. I have a spare Shelly 1 too unless @stevebott123 buys it :stuck_out_tongue: . Anyways definitely post up the 3d printed case as I may consider it for indoors in the future.

EDIT: It would be worth documenting this in detail too as I did with mine. Shelly 1 12v Outdoor Siren Strobe Alarm โ€“ Smarter Home Club

Fyi all, if anyone is looking to install LED strips and want a super clean job check out these. It looks really nice and clean, unless I pointed it out to someone they wouldn't even notice. Good quality too.

1 Like

STL file here Piezo Siren Case with Shelly 1 by rockets - Thingiverse. Enjoy!

3 Likes

That's nice !! Here is the Alarm driver.

The driver needs to be updated for changes on how the new httpPost works but as long as you don't use a username/password in the app or webserver for it then you be will ok.

/**
 *
 *  Shelly Alarm Driver
 *
 *  Copyright ยฉ 2019 Scott Grayban
 *
 * Please Note: This app is NOT released under any open-source license.
 * Please be sure to read the license agreement before installing this code.
 *
 * This software package is created and licensed by Scott Grayban.
 *
 * This software, along with associated elements, including but not limited to online and/or electronic documentation are
 * protected by international laws and treaties governing intellectual property rights.
 *
 * This software has been licensed to you. All rights are reserved. You may use and/or modify the software.
 * You may not sublicense or distribute this software or any modifications to third parties in any way.
 *
 * You may not distribute any part of this software without the author's express permission
 *
 * By downloading, installing, and/or executing this software you hereby agree to the terms and conditions set forth
 * in the Software license agreement.
 * This agreement can be found on-line at: https://sgrayban.github.io/Hubitat-Public/software_License_Agreement.txt
 * 
 * Hubitat is the Trademark and intellectual Property of Hubitat Inc.
 * Shelly is the Trademark and Intellectual Property of Allterco Robotics Ltd
 * Scott Grayban has no formal or informal affiliations or relationships with Hubitat or Allterco Robotics Ltd.
 *
 * 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 Agreement
 * for the specific language governing permissions and limitations under the License.
 *
 *-------------------------------------------------------------------------------------------------------------------
 *
 * See all the Shelly Products at https://shelly.cloud/
 *
 * Shelly Alarm works off a Shelly 1 or Shelly 1PM
 * It is based on the project by Jason Churchward --> http://blog.smarterhome.club/2019/09/07/shelly1strobealarm/
 *
 *  Changes:
 *  1.0.1 - Added code that will allow you to upgrade the device firmware and will auto-refresh in 30 seconds.
 *  1.0.0 - Initial port of Shelly Alarm
 *
 */

import groovy.json.*
import groovy.transform.Field

metadata {
	definition (
		name: "Shelly Alarm",
		namespace: "sgrayban",
		author: "Scott Grayban"
		)
	{
        capability "Actuator"
        capability "Sensor"
        capability "Refresh"
        capability "Switch"
        capability "Polling"
        capability "Alarm"
        
        attribute "switch", "string"
        attribute "FW_Update_Needed", "string"
        attribute "LastRefresh", "string"
        attribute "internal_tempC", "string"
        attribute "MAC", "string"
        attribute "Primary_IP", "string"
        attribute "Primary_SSID", "string"
        attribute "Cloud", "string"
        attribute "Cloud_Connected", "string"
        attribute "alarm", "string"
        attribute "status", "string"
        attribute "WiFiSignal", "string"
        attribute "Secondary_IP", "string"
        attribute "Secondary_SSID", "string"
        attribute "DeviceType", "string"
        
        command "RebootDevice"
        command "UpdateDeviceFW" // ota?update=1
	}


	preferences {
	def refreshRate = [:]
		refreshRate << ["1 min" : "Refresh every minute"]
		refreshRate << ["5 min" : "Refresh every 5 minutes"]
		refreshRate << ["15 min" : "Refresh every 15 minutes"]
		refreshRate << ["30 min" : "Refresh every 30 minutes"]
	input("ip", "string", title:"IP", description:"Shelly IP Address", defaultValue:"" , required: false, displayDuringSetup: true)
	input name: "username", type: "text", title: "Username:", description: "(blank if none)", required: false
	input name: "password", type: "password", title: "Password:", description: "(blank if none)", required: false
    input ("refresh_Rate", "enum", title: "Device Refresh Rate", options: refreshRate, defaultValue: "30 min")
	input "locale", "enum", title: "Choose refresh date format", required: true, defaultValue: true, options: [US:"US MM/DD/YYYY",UK:"UK DD/MM/YYYY"]
	input name: "debugOutput", type: "bool", title: "Enable debug logging?", defaultValue: true
	input name: "debugParse", type: "bool", title: "Enable JSON parse logging?", defaultValue: false
	input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true
	input name: "Shellyinfo", type: "text", title: "<center><font color=blue>Info Box</font><br>Shelly API docs are located</center>", 
        description: "<center><br><a href='http://shelly-api-docs.shelly.cloud/' title='shelly-api-docs.shelly.cloud' target='_blank'>[here]</a></center>", 
        required: false
	input name: "Donate", type: "text", title: "<center><font color=blue>Donate</font><br>If you like my drivers please donate</center>", 
        description: "<center><a href='https://paypal.me/sgrayban'>[here]</a></center>", required: false
	}
}

def initialize() {
	log.info "initialize"
}

def installed() {
    log.debug "Installed"
}

def uninstalled() {
    log.debug "Uninstalled"
    unschedule()
}

def setVersion(){
	state.Version = "1.0.1"
	state.InternalName = "ShellyAlarm"
}

def updated() {
    if (txtEnable) log.info "Preferences updated..."
    log.warn "Debug logging is: ${debugOutput == true}"
    unschedule()
    dbCleanUp()
    
    switch(refresh_Rate) {
		case "1 min" :
			runEvery1Minute(autorefresh)
			break
		case "5 min" :
			runEvery5Minutes(autorefresh)
			break
		case "15 min" :
			runEvery15Minutes(autorefresh)
			break
		default:
			runEvery30Minutes(autorefresh)
	}
	if (txtEnable) log.info ("Auto Refresh set for every ${refresh_Rate} minute(s).")

    if (debugOutput) runIn(1800,logsOff)
    state.LastRefresh = new Date().format("YYYY/MM/dd \n HH:mm:ss", location.timeZone)
    
    version()
    getSettings()
    refresh()
}

private dbCleanUp() {
	state.remove("version")
	state.remove("Version")
	state.remove("ShellyfwUpdate")
	state.remove("power")
	state.remove("overpower")
	state.remove("dcpower")
	state.remove("max_power")
	state.remove("internal_tempC")
}

// We dont use this anymore 
// but it's still called so
// keep it until I fix the
// http POST calls.
def parse(description) {
    return
}

def refresh(){
    getSettings()
    logDebug "Shelly Status called"
    def params = [uri: "http://${username}:${password}@${ip}/status"]

try {
    httpGet(params) {
        resp -> resp.headers.each {
        logJSON "Response: ${it.name} : ${it.value}"
    }
        obs = resp.data
        if(logSet == false){  
       
        logJSON "params: ${params}"
        logJSON "response contentType: ${resp.contentType}"
	    logJSON "response data: ${resp.data}"
        }

        if (obs.temperature != null) sendEvent(name: "internal_tempC", value: obs.temperature)
        if (obs.overtemperature != null) sendEvent(name: "DeviceOverTemp", value: obs.overtemperature)
        
        ison = obs.relays.ison[0]
        
        if (ison == true) {
            sendEvent(name: "switch", value: "on")
            sendEvent(name: "status", value: "on")
            sendEvent(name: "alarm", value: "on")
        } else {
            sendEvent(name: "switch", value: "off")
            sendEvent(name: "status", value: "off")
            sendEvent(name: "alarm", value: "off")
        }
        
        if (obs.wifi_sta != null) {
        state.rssi = obs.wifi_sta.rssi
        state.ssid = obs.wifi_sta.ssid
        state.ip = obs.wifi_sta.ip
        sendEvent(name: "Primary_SSID", value: state.ssid)
        sendEvent(name: "Primary_IP", value: state.ip)
        }
        
        state.mac = obs.mac
        sendEvent(name: "MAC", value: state.mac)

/*
-30 dBm	Excellent | -67 dBm	Good | -70 dBm	Poor | -80 dBm	Weak | -90 dBm	Dead
*/
        signal = state.rssi
        if (signal <= 0 && signal >= -70) {
            sendEvent(name:  "WiFiSignal", value: "<font color='green'>Excellent</font>", isStateChange: true);
        } else
        if (signal < -70 && signal >= -80) {
            sendEvent(name:  "WiFiSignal", value: "<font color='green'>Good</font>", isStateChange: true);
        } else
        if (signal < -80 && signal >= -90) {
            sendEvent(name: "WiFiSignal", value: "<font color='yellow'>Poor</font>", isStateChange: true);
        } else 
        if (signal < -90 && signal >= -100) {
            sendEvent(name: "WiFiSignal", value: "<font color='red'>Weak</font>", isStateChange: true);
        }

 // Device FW Updates
        state.has_update = obs.has_update
        if (state.has_update == true) {
            if (txtEnable) log.info "sendEvent NEW SHELLY FIRMWARE"
            sendEvent(name: "FW_Update_Needed", value: "<font color='red'>FIRMWARE Update Required</font>")
        }
        
        if (state.has_update == false) {
            if (txtEnable) log.info "sendEvent Device FW is current"
            sendEvent(name: "FW_Update_Needed", value: "<font color='green'>Device FW is current</font>")
        }

// Cloud
        state.cloud = obs.cloud.enabled
        if (state.cloud == true) {
            sendEvent(name: "Cloud", value: "<font color='green'>Enabled</font>")
        } else {
            sendEvent(name: "Cloud", value: "<font color='red'>Disabled</font>")
        }
        
        state.cloudConnected = obs.cloud.connected
        if (state.cloudConnected == true) {
            sendEvent(name: "Cloud_Connected", value: "<font color='green'>Enabled</font>")
        } else {
            sendEvent(name: "Cloud_Connected", value: "<font color='red'>Not Connected</font>")
        }
        
} // End try
       } catch (e) {
           log.error "something went wrong: $e"
       }
} // End Refresh Status


// Get shelly device type
def getSettings(){
 logDebug "Get Shelly Settings"
    def paramsSettings = [uri: "http://${username}:${password}@${ip}/settings"]

try {
    httpGet(paramsSettings) {
        respSettings -> respSettings.headers.each {
        logJSON "ResponseSettings: ${it.name} : ${it.value}"
    }
        obsSettings = respSettings.data

        logJSON "params: ${paramsSettings}"
        logJSON "response contentType: ${respSettings.contentType}"
	    logJSON "response data: ${respSettings.data}"

        state.DeviceType = obsSettings.device.type
        if (state.DeviceType == "SHSW-1") sendEvent(name: "DeviceType", value: "Shelly 1")
        if (state.DeviceType == "SHSW-PM") sendEvent(name: "DeviceType", value: "Shelly 1PM")
        if (state.DeviceType == "SHSW-21") sendEvent(name: "DeviceType", value: "Shelly 2")
        if (state.DeviceType == "SHSW-25") sendEvent(name: "DeviceType", value: "Shelly 2.5")
        if (state.DeviceType == "SHSW-44") sendEvent(name: "DeviceType", value: "Shelly 4Pro")
        if (state.DeviceType == "SHEM") sendEvent(name: "DeviceType", value: "Shelly EM")
        if (state.DeviceType == "SHPLG-1") sendEvent(name: "DeviceType", value: "Shelly Plug")
        if (state.DeviceType == "SHPLG-S") sendEvent(name: "DeviceType", value: "Shelly PlugS")

        updateDataValue("model", state.DeviceType)
        updateDataValue("ShellyHostname", state.ShellyHostname)
        updateDataValue("ShellyIP", obsSettings.wifi_sta.ip)
        updateDataValue("ShellySSID", obsSettings.wifi_sta.ssid)
        updateDataValue("manufacturer", "Allterco Robotics")
        updateDataValue("MAC", state.mac)

        if (obsSettings.wifi_sta1 != null) {
        state.rssi = obsSettings.wifi_sta1.rssi
        state.Secondary_ssid = obsSettings.wifi_sta1.ssid
        state.Secondary_IP = obsSettings.wifi_sta1.ip
        if (obsSettings.wifi_sta1.enabled == true) sendEvent(name: "Secondary_SSID", value: state.Secondary_ssid)
        if (state.Secondary_IP != null) sendEvent(name: "Secondary_IP", value: state.Secondary_IP)
        sendEvent(name: "WiFiSignal", value: state.rssi)
        }

        state.ShellyHostname = obsSettings.device.hostname
        
} // End try
       } catch (e) {
           log.error "something went wrong: $e"
       }
} // End Refresh Status

//Alarm on
def on() {
    logDebug "Executing switch.on"
    sendSwitchCommand "turn=on"
}

def strobe() {
    logDebug "Executing strobe"
    on()
}

def both() {
    logDebug "Executing strobe"
    on()
}

def siren() {
    logDebug "Executing strobe"
    on()
}

//Alarm off
def off() {
    logDebug "Executing switch.off"
    sendSwitchCommand "turn=off"
}

def ping() {
	logDebug "ping"
	poll()
}

def logsOff(){
	log.warn "debug logging auto disabled..."
	device.updateSetting("debugOutput",[value:"false",type:"bool"])
}

def autorefresh() {
	if (locale == "UK") {
	logDebug "Get last UK Date DD/MM/YYYY"
	state.LastRefresh = new Date().format("d/MM/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	} 
	if (locale == "US") {
	logDebug "Get last US Date MM/DD/YYYY"
	state.LastRefresh = new Date().format("MM/d/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	}
	if (txtEnable) log.info "Executing 'auto refresh'" //RK

    refresh()
}

private logJSON(msg) {
	if (settings?.debugParse || settings?.debugParse == null) {
	log.info "$msg"
	}
}

private logDebug(msg) {
	if (settings?.debugOutput || settings?.debugOutput == null) {
	log.debug "$msg"
	}
}

// handle commands
//RK Updated to include last refreshed
def poll() {
	if (locale == "UK") {
	logDebug "Get last UK Date DD/MM/YYYY"
	state.LastRefresh = new Date().format("d/MM/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	} 
	if (locale == "US") {
	logDebug "Get last US Date MM/DD/YYYY"
	state.LastRefresh = new Date().format("MM/d/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	}
	if (txtEnable) log.info "Executing 'poll'" //RK
	refresh()
}

def sendSwitchCommand(action) {
    if (txtEnable) log.info "Calling /relay/ with $action"
    if (username != null) {
        host = "${username}:${password}@${ip}"
    } else {
        host = "${ip}"
    }
    sendHubCommand(new hubitat.device.HubAction (
      method: "POST",
      path: "/relay/0",
      body: action,
      headers: [HOST: host, "Content-Type": "application/x-www-form-urlencoded"]
    ))
    runIn(1, refresh)
}


def RebootDevice() {
    if (txtEnable) log.info "Rebooting Device"
    if (username != null) {
        host = "${username}:${password}@${ip}"
    } else {
        host = "${ip}"
    }
    sendHubCommand(new hubitat.device.HubAction(
      method: "POST",
      path: "/reboot",
      body: action,
      headers: [HOST: host, "Content-Type": "application/x-www-form-urlencoded"]
    ))
    runIn(10,refresh)
}

def UpdateDeviceFW() {
    if (txtEnable) log.info "Updating Device FW"
    if (username != null) {
        host = "${username}:${password}@${ip}"
    } else {
        host = "${ip}"
    }
	sendEvent(name: "FW_Update_Needed", value: "Please Wait..Updating FW.")
    sendHubCommand(new hubitat.device.HubAction(
      method: "POST",
      path: "/ota?update=1",
      body: action,
      headers: [
        HOST: host,
        "Content-Type": "application/x-www-form-urlencoded"
      ]
    ))
    runIn(30,refresh)
}

def version(){
	updatecheck()
	schedule("0 0 18 1/1 * ? *", updatecheck) // Cron schedule
//	schedule("0 0/1 * 1/1 * ? *", updatecheck) // Test Cron schedule
}

def updatecheck(){
	setVersion()
	 def paramsUD = [uri: "http://sgrayban.borgnet.online:8081/scotts-projects/version.json"]
	  try {
			httpGet(paramsUD) { respUD ->
				  if (debugParse) log.warn " Version Checking - Response Data: ${respUD.data}"   // Troubleshooting Debug Code - Uncommenting this line should show the JSON response from your webserver
				  def copyrightRead = (respUD.data.copyright)
				  state.Copyright = copyrightRead
				  def newVerRaw = (respUD.data.versions.Driver.(state.InternalName))
				  def newVer = (respUD.data.versions.Driver.(state.InternalName).replace(".", ""))
				  def currentVer = state.Version.replace(".", "")
				  state.UpdateInfo = (respUD.data.versions.UpdateInfo.Driver.(state.InternalName))
				  state.author = (respUD.data.author)
                  state.icon = "<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAC9FBMVEUdFwIoGQM4JgE5NABELwBJMwBOMwBEOwBKOQJNOAJSNgBNQABXOwBKQgBUPQBRPwBPRABVQgBZQQBcRABZRgBiQgBTSgBXSQBoRABiSABfSgBgSwBeTgBXUgBbUABqSgBuSQBoTQBbVgFfVAFmUQFuTQNjUwFqUwB4TABuUgBnVgBkWABhWgB0UgB4UQBtWwFzWAFmXwFqXQF9VgB4WgCDVQBvYQB+WgBzYAB3XgBsZAB8XgCEWgGJWQJzZQB4ZAGLWwCIXQBxaQJ2aAR4aQB1bAB9aQCBZwCFZQCNYgCRYACLZQB9bgCUYwONZwKCbQGKaQJ7cQGHbAKQaQCWaQCDcwCIcQCBdgCNcQCRbwCeagGHdgCibQCKeQKOdwOHewKOfACWeACadgCicwCmcQCTewCMfwCgdgCTgQCXfwCgewKRhAGtdgCdfgKzdgCkfgChgQCtewCZhgCdhACpfgCSigCYigCxfwC1fQCeigCnhgCxhADBfACdjgKthgS7ggCojQCljwCikgC6hgDCggCflQCwjgCilwDJgwS7jAOolwG5kAC1kgSylQDPiADFjwCsnACzmwDQjQDFlADNkQKyoAC+mgDDmAK7nQLGmgC+nwDSlQCxpQXXkwDckgDEnwC2qADSmgC7qADglQLBpwDRnwDGpQDNogDkmADZnwDdnQC/rAK+sADHrADMqgDErwDlnwDUqADtnQHGtwDTsQH1oADbrQPkqQDMtgPkrgDxqADMvADQugD2pwDatgDisgDetQDqsADwrQDZuwD/qADSwQDWvwD8rAD1sQD6sADwtgD/rwDgwQDnvwDuvAD7tgD/tAD3uQDgxwD2vQHlxgD+uQLZzQDrxQD/uwDgzQTd0AD/vwDvyADsywDpzgD6xgD+xADl0QD/xgD0zADxzwD6ywD+ygDp1QDv0wDn2AD/zAD40AP/zAb20wD/0ADz1wDv2gD90wD/1gD13gD53AD+2gD34QD/3QL05AP+4AD/4gD85QC9W0cbAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4wwICSkZc7wKxgAAAdpJREFUGBmdwV1rUmEAwPH/d+pLdLO77rvpoogMYuRi1S7mxdwummmRRgiicxS4DoozECeItuIMxGyzrIMKqQjZybLBuum8PL6c9aiw34/zHty9ykLFZkf/+7urVqPMU9Q/Y9tMqWFm0o+ZoqQhHlcSIc7Tkzj4D/xAIvFdxUHHYc3DcgxLtptlooODC4N/FZumMZJRkVhHaJYQVGQ8jOgIVUaSEST2dCypBMKfs+EREjqWPII26PdaSBQrmMIIX3qN+j4Tt25gy1QwHYDHgyH4/vA1E296wyo2DdNDvxeJl7VW//Q6ll+YFC8yu+V6+ye2Lob0VgCpd7UPW9gKwNM4swQQQgUgB6wwn+qDfBjDNebKAQXm2wBCObhXZYHHoABqFCHodyPz/IqCIZvBluo1PnqQCaxiKCGc9tu1F0i4Y5hK2J6cDXqNAP97ROwyhmwEW+n0m8LExn0Ml1xAENOnCjK7b8uHCAlMN3Uk1sq1elvBlsfSRGK/3uoNfNhOsCR1RlyMHQ2GKkIOW7OCsMLEHUa+MqJnEAKYlpj2rMqYpiKsw8oSDhpTKt0IlmWvG6cuToXCSSJuuB1kWqTDTOkdxirHzLGTy0V9m75XpZK+zQLRwg9tb5sL+QdvDc0dp1ZEdQAAAABJRU5ErkJggg=='>"
				  if(newVer == "NLS"){
					   state.DriverStatus = "<b>** This driver is no longer supported by $state.author  **</b>"       
					   log.warn "** This driver is no longer supported by $state.author **"      
				  }           
				  else if(newVer == "BETA"){
					   state.Status = "<b>** THIS IS BETA CODE  **</b>"       
					   log.warn "** BETA CODE **"      
				  }           
				  else if(currentVer < newVer){
					   state.DriverStatus = "<b>New Version Available (Version: $newVerRaw)</b>"
					   log.warn "** There is a newer version of this driver available  (Version: $newVerRaw) **"
					   log.warn "** $state.UpdateInfo **"
				 } 
				 else if(currentVer > newVer){
					   state.DriverStatus = "<b>You are using a Test version of this Driver (Version: $newVerRaw)</b>"
				 }
				 else{ 
					 state.DriverStatus = "Current"
					 log.info "You are using the current version of this driver"
				 }
			} // httpGet
	  } // try

	  catch (e) {
		   log.error "Something went wrong: CHECK THE JSON FILE AND IT'S URI -  $e"
	  }

	  if(state.DriverStatus == "Current"){
		   state.UpdateInfo = "Up to date"
		   sendEvent(name: "DriverUpdate", value: state.UpdateInfo)
		   sendEvent(name: "DriverStatus", value: state.DriverStatus)
	  }
	  else {
		   sendEvent(name: "DriverUpdate", value: state.UpdateInfo)
		   sendEvent(name: "DriverStatus", value: state.DriverStatus)
	  }

	  sendEvent(name: "DriverAuthor", value: "sgrayban")
	  sendEvent(name: "DriverVersion", value: state.Version)
}
5 Likes

It's been awhile since I posted my code openly. Don't expect it again :slight_smile:

1 Like

What water valve did you use and where did you get it from?

If you follow this article here you will have links to everything you need plus a build guide. If your in the Brisbane area though I have spare one here I can sell to you to speed up the shipping if you want it sooner. Unfortunately I don't have a spare 2 channel relay though but again if you want/need it sooner then these guys are super quick to post stuff out.

1 Like

Thanks for that. Unfortunately this is way to involved compared to what I am willing to contemplate at the moment. While I am an electrical engineer, I was hoping for an off the shelf product :slight_smile: Just as you, I have just built a house, well itโ€™s actually still being built around us, so I still have 1001 other things that need to be done.
You havenโ€™t happened to see any other off the shelf products for closing a water valve?

1 Like