Skip to content

Commit

Permalink
update GDO blaQ and White driver; adds some informational attributes …
Browse files Browse the repository at this point in the history
…and syncs contactSensor with garage door state for Homekit integration
  • Loading branch information
heythisisnate committed May 8, 2024
1 parent 287e9ac commit 8ccdfa3
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 34 deletions.
108 changes: 92 additions & 16 deletions drivers/konnected-gdov2-q.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ metadata {
capability 'Sensor'
capability 'Refresh'
capability 'Initialize'
capability 'Signal Strength'
capability 'Door Control'
capability 'Garage Door Control'
capability 'SignalStrength'
capability 'DoorControl'
capability 'GarageDoorControl'
capability 'ContactSensor'
capability 'Switch'
capability 'Lock'
capability 'MotionSensor'
Expand All @@ -51,6 +52,10 @@ metadata {
attribute 'uptime', 'number'
attribute 'openings', 'number'
attribute 'position', 'number'
attribute 'openingDuration', 'number'
attribute 'closingDuration', 'number'
attribute 'esphomeVersion', 'string'
attribute 'securityPlusProtocol', 'string'

command 'setPosition', [
[ name: 'Position*', type: 'NUMBER', description: 'Numerical position 0 (fully closed) to 100 (fully open)' ]
Expand All @@ -59,6 +64,7 @@ metadata {
command 'learnOff'
command 'restart'
command 'stop'
command 'preCloseWarning'
}

preferences {
Expand Down Expand Up @@ -149,71 +155,98 @@ private void doParseDevice(Map message) {

private void doParseEntity(Map message) {
if (message.platform == 'cover') {
if (message.name == "Garage Door") {
if (message.objectId == "garage_door") {
state.doorKey = message.key as Long
}
return
}
if (message.platform == 'binary') {
if (message.name == "Motion") {
if (message.objectId == "motion") {
state.motionKey = message.key as Long
getMotionDevice(message.key)
}
if (message.name == "Obstruction") {
if (message.objectId == "obstruction") {
state.obstructionKey = message.key as Long
getObstructionDevice(message.key)
}
if (message.name == "Button") {
if (message.objectId == "button") {
state.buttonKey = message.key as Long
getButtonDevice(message.key)
}
if (message.name == "Motor") {
if (message.objectId == "motor") {
state.motorKey = message.key as Long
}
return
}

if (message.platform == 'light') {
if (message.name == "Garage Light") {
if (message.objectId == "garage_light") {
state.lightKey = message.key as Long
getLightDevice(message.key)
}
return
}

if (message.platform == 'switch') {
if (message.name == "Learn") {
if (message.objectId == "learn") {
state.learnKey = message.key as Long
getLearnDevice(message.key)
}
return
}

if (message.platform == 'lock') {
if (message.name == "Lock") {
if (message.objectId == "lock") {
state.lockKey = message.key as Long
getLockDevice(message.key)
}
return
}

if (message.platform == 'sensor') {
if (message.name == "Garage Openings") {
if (message.objectId == "garage_openings") {
state.openingsKey = message.key as Long
}
if (message.deviceClass == 'signal_strength' && message.unitOfMeasurement == 'dBm') {
state.signalStrengthKey = message.key
}
if (message.name == "Uptime") {
if (message.objectId == "uptime") {
state.uptimeKey = message.key as Long
}
return
}

if (message.platform == 'number') {
if (message.objectId == 'opening_duration') {
state.openingDurationKey = message.key
}
if (message.objectId == 'closing_duration') {
state.closingDurationKey = message.key
}
return
}

if (message.platform == 'select') {
if (message.objectId == 'security__protocol') {
state.securityPlusProtocolKey = message.key
}
return
}

if (message.platform == 'text') {
if (message.objectId == 'esphome_version') {
state.esphomeVersionKey = message.key
}
return
}

if (message.platform == 'button') {
if (message.name == "Restart") {
if (message.objectId == "restart") {
state.restartKey = message.key
}
if (message.objectId == "pre-close_warning") {
state.preCloseWarningKey = message.key
}
return
}
}
Expand All @@ -226,10 +259,11 @@ private void doParseState(Map message) {
return
}
String value
String contact
switch (message.currentOperation) {
case COVER_OPERATION_IDLE:
value = message.position > 0 ? 'open' : 'closed'
contact = value
contact = value
break
case COVER_OPERATION_IS_OPENING:
value = 'opening'
Expand All @@ -239,6 +273,7 @@ private void doParseState(Map message) {
break
}
sendDeviceEvent("door", value, type, "Door")
sendDeviceEvent("contact", contact, type, "Contact")
int position = Math.round(message.position * 100) as int
sendDeviceEvent("position", position, type, "Position")
return
Expand Down Expand Up @@ -276,7 +311,7 @@ private void doParseState(Map message) {

if (state.lockKey as Long == message.key) {
String value = message.state == 1 ? "locked" : "unlocked"
sendDeviceEvent("lock", value, type, "Remotes lock", getLockDevice(message.key))
sendDeviceEvent("lock", value, type, "Lock", getLockDevice(message.key))
return
}

Expand All @@ -292,6 +327,33 @@ private void doParseState(Map message) {
return
}

if (state.esphomeVersionKey as Long == message.key) {
sendDeviceEvent("esphomeVersion", message.state, type, "ESPHome Version")
return
}

if (state.securityPlusProtocolKey as Long == message.key) {
sendDeviceEvent("securityPlusProtocol", message.state, type, "Security+ Protocol")
return
}

if (state.openingDurationKey as Long == message.key) {
sendDeviceEvent("openingDuration", message.state, type, "Opening duration")
return
}

if (state.openingDurationKey as Long == message.key) {
int value = message.state as int
sendDeviceEvent("openingDuration", value, type, "Opening duration")
return
}

if (state.closingDurationKey as Long == message.key) {
int value = message.state as int
sendDeviceEvent("closingDuration", value, type, "Closing duration")
return
}

if (state.buttonKey as Long == message.key && message.hasState) {
if (message.state) {
sendDeviceEvent("pushed", 1, type, "Button", getButtonDevice(message.key), null, true)
Expand Down Expand Up @@ -405,6 +467,20 @@ public void setPosition(BigDecimal pos) {
}
}

public void playSound() {
if (state.playSoundKey) {
if (logTextEnable) { log.info "${device} play sound" }
espHomeButtonCommand(key: state.playSoundKey as Long)
}
}

public void preCloseWarning() {
if (state.preCloseWarningKey) {
if (logTextEnable) { log.info "${device} pre-close warning" }
espHomeButtonCommand(key: state.preCloseWarningKey as Long)
}
}

// TODO: Toggle
// public void toggle() {
// if (state.doorKey) {
Expand Down
66 changes: 52 additions & 14 deletions drivers/konnected-gdov2-s.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ metadata {
attribute 'calibratedDistance', 'number'

command 'calibrate'
command 'preCloseWarning'
command 'restart'
}

preferences {
Expand Down Expand Up @@ -142,13 +144,30 @@ public void calibrate() {
espHomeCallService('calibrate_open_garage')
}

public void preCloseWarning() {
if (state.preCloseWarning) {
if (logTextEnable) { log.info "${device} pre-close warning" }
espHomeButtonCommand(key: state.preCloseWarning as Long)
}
}

public void restart() {
if (state.restart) {
log.info "${device} restart"
espHomeButtonCommand(key: state.restart as Long)
}
}


// the parse method is invoked by the API library when messages are received
public void parse(Map message) {
if (logEnable) { log.debug "ESPHome received: ${message}" }

switch (message.type) {
case 'device':
// Device information
if (!device.label && message.macAddress) {
device.label = "GDO White " + message.macAddress.replaceAll(':','').toLowerCase().substring(6)
}
break

case 'entity':
Expand Down Expand Up @@ -182,16 +201,29 @@ public void parse(Map message) {
state['switch'] = message.key
return
}

if (message.platform == 'button') {
if (message.objectId == "restart") {
state['restart'] = message.key
}
if (message.objectId == "pre-close_warning") {
state['preCloseWarning'] = message.key
}
return
}

break

case 'state':
String type = message.isDigital ? 'digital' : 'physical'
// Check if the entity key matches the message entity key received to update device state
if (state.cover as Long == message.key) {
String value
String contact
switch (message.currentOperation) {
case COVER_OPERATION_IDLE:
value = message.position > 0 ? 'open' : 'closed'
contact = value
break
case COVER_OPERATION_IS_OPENING:
value = 'opening'
Expand All @@ -203,6 +235,7 @@ public void parse(Map message) {
if (device.currentValue('door') != value) {
descriptionText = "${device} door is ${value}"
sendEvent(name: 'door', value: value, type: type, descriptionText: descriptionText)
sendEvent(name: 'contact', value: contact, type: type, descriptionText: descriptionText)
if (logTextEnable) { log.info descriptionText }
}
return
Expand All @@ -219,19 +252,24 @@ public void parse(Map message) {
return
}

if (state.wiredSensor as Long == message.key && message.hasState) {
String value = message.state ? 'open' : 'closed'
if (device.currentValue('contact') != value) {
descriptionText = "Contact is ${value}"
sendEvent([
name: 'contact',
value: value, type: type,
descriptionText: descriptionText
])
if (logTextEnable) { log.info descriptionText }
}
return
}
// REMOVED because 'contact' track the state of the Garage Door
// no longer tracking the wired contact as a separate entity
//
// TODO: optionally add as a child entity
//
// if (state.wiredSensor as Long == message.key && message.hasState) {
// String value = message.state ? 'open' : 'closed'
// if (device.currentValue('contact') != value) {
// descriptionText = "Contact is ${value}"
// sendEvent([
// name: 'contact',
// value: value, type: type,
// descriptionText: descriptionText
// ])
// if (logTextEnable) { log.info descriptionText }
// }
// return
// }

if (state.sensorDistance as Long == message.key && message.hasState) {
BigDecimal value = message.state.setScale(2, BigDecimal.ROUND_HALF_UP)
Expand Down
4 changes: 2 additions & 2 deletions package-gdov2q.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"packageName": "Garge Door Opener blaQ (GDOv2-Q)",
"author": "Konnected Inc.",
"version": "1.1",
"version": "1.2",
"minimumHEVersion": "0.0",
"dateReleased": "2024-05-06",
"bundles": [
Expand All @@ -20,7 +20,7 @@
"namespace": "konnected",
"location": "https://raw.githubusercontent.com/konnected-io/konnected-hubitat/master/drivers/konnected-gdov2-q.groovy",
"required": true,
"version": "1.1"
"version": "1.2"
}
]
}
4 changes: 2 additions & 2 deletions package-gdov2s.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"packageName": "Garage Door Opener GDOv2-S",
"author": "Konnected Inc.",
"version": "1.0",
"version": "1.1",
"minimumHEVersion": "0.0",
"dateReleased": "2024-03-03",
"bundles": [
Expand All @@ -20,7 +20,7 @@
"namespace": "konnected",
"location": "https://raw.githubusercontent.com/konnected-io/konnected-hubitat/master/drivers/konnected-gdov2-s.groovy",
"required": true,
"version": "1.0"
"version": "1.1"
}
]
}

0 comments on commit 8ccdfa3

Please sign in to comment.