Skip to content

Commit

Permalink
Use ssdpUSN as device DNI to correctly handle the same device present…
Browse files Browse the repository at this point in the history
…ing multiple network interfaces.
  • Loading branch information
billsq committed Mar 30, 2020
1 parent 9a773f6 commit 4814874
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 34 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

devicetypes/billsq/.DS_Store
49 changes: 37 additions & 12 deletions devicetypes/billsq/denon-av-receiver.src/denon-av-receiver.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata {
capability "Refresh"
capability "Sensor"
capability "Music Player"
capability "Switch Level"
//capability "Switch Level"

attribute "phono", "string"
attribute "cd", "string"
Expand Down Expand Up @@ -270,8 +270,8 @@ private String convertHexToIP(hex) {
}

private String getHostAddress() {
def ip = convertHexToIP(getDataValue("ip"))
def port = convertHexToInt(getDataValue("port"))
def ip = convertHexToIP(getDataValue("networkAddress"))
def port = convertHexToInt(getDataValue("deviceAddress"))
def host = "${ip}:${port}"

//log.debug "Using SOAP host: ${host} for device: ${device.label}"
Expand All @@ -280,7 +280,7 @@ private String getHostAddress() {
}

private String getApiAddress() {
def ip = convertHexToIP(getDataValue("ip"))
def ip = convertHexToIP(getDataValue("networkAddress"))
def host = "${ip}:${getDataValue("apiPort")}"

//log.debug "Using API host: ${host} for device: ${device.label}"
Expand Down Expand Up @@ -320,14 +320,39 @@ def initialize() {
refresh()
}

def sync(ip, port) {
def existingIp = getDataValue("ip")
def existingPort = getDataValue("port")
if (ip && ip != existingIp) {
updateDataValue("ip", ip)
def sync(ssdp_data) {
log.debug "Sync with data ${ssdp_data}"
def updated = false

if (ssdp_data) {
def fields = [
"AVTransportControlPath",
"AVTransportEventPath",
"RenderingControlControlPath",
"RenderingControlEventPath",
"apiPort",
"networkAddress",
"mac",
"deviceAddress"
]

fields.each {
if (ssdp_data[it]) {
if (ssdp_data[it] != getDataValue(it)) {
updateDataValue(it, ssdp_data[it])
log.debug "Update ${it} with new value: ${ssdp_data[it]}"
updated = true
} else {
log.debug "${it} value doesn't change: ${getDataValue(it)}"
}
} else {
log.error "No new value exists for field: ${it}!"
}
}
}
if (port && port != existingPort) {
updateDataValue("port", port)

if (updated) {
refresh()
}
}

Expand Down Expand Up @@ -939,7 +964,7 @@ void pollCallback(physicalgraph.device.HubResponse hubResponse) {
if (volume) {
log.trace "Got GetAllZoneVolume zone1=${volume}"

sendEvent(name: "level", value: volume)
sendEvent(name: "level", value: Math.round(volume.toFloat()))
} else {
log.error "Malformed GetAllZoneVolume response!"
}
Expand Down
44 changes: 22 additions & 22 deletions smartapps/billsq/denon-avr-connect.src/denon-avr-connect.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ def deviceDiscovery() {
def devices = getVerifiedDevices()
devices.each {
def value = "${it.value.name} [Model: ${it.value.model}]"
def key = it.value.mac
def key = it.value.ssdpUSN
options["${key}"] = value
}

ssdpSubscribe()
ssdpDiscover()
verifyDevices()

return dynamicPage(name: "deviceDiscovery", title: "Discovering your Denon AV receivers...", nextPage: "", refreshInterval: 5, install: true, uninstall: true) {
section {
Expand Down Expand Up @@ -73,20 +72,20 @@ Map verifiedDevices() {
def map = [:]
devices.each {
def value = "${it.value.name} [Model: ${it.value.model}]"
def key = it.value.mac
def key = it.value.ssdpUSN
map["${key}"] = value
}
map
}

void verifyDevices() {
def devices = getDevices().findAll { it?.value?.verified != true }
def devices = getDevices()
devices.each {
int port = convertHexToInt(it.value.deviceAddress)
String ip = convertHexToIP(it.value.networkAddress)
String host = "${ip}:${port}"

log.debug("verifyDevices host=${host} path=${it.value.ssdpPath}")
log.debug("verifyDevices host=${host} path=${it.value.ssdpPath} device=${it.value}")

sendHubCommand(new physicalgraph.device.HubAction([
path: it.value.ssdpPath,
Expand Down Expand Up @@ -114,22 +113,20 @@ def addDevices() {
def devices = getDevices()

selectedDevices.each { dni ->
def selectedDevice = devices.find { it.value.mac == dni }
def selectedDevice = devices.find { it.value.ssdpUSN == dni }
def d
if (selectedDevice) {
d = getChildDevices()?.find {
it.deviceNetworkId == selectedDevice.value.mac
}
d = getChildDevice(dni)
}

if (!d) {
log.debug "Creating Denon AV receiver with dni: ${selectedDevice.value.mac}"
addChildDevice("billsq", "Denon AV Receiver", selectedDevice.value.mac, selectedDevice?.value.hub, [
log.debug "Creating Denon AV receiver with dni: ${selectedDevice.value.ssdpUSN}"
addChildDevice("billsq", "Denon AV Receiver", selectedDevice.value.ssdpUSN, selectedDevice.value.hub, [
"label": selectedDevice.value.name,
"data": [
"mac": selectedDevice.value.mac,
"ip": selectedDevice.value.networkAddress,
"port": selectedDevice.value.deviceAddress,
"networkAddress": selectedDevice.value.networkAddress,
"deviceAddress": selectedDevice.value.deviceAddress,
"apiPort": selectedDevice.value.apiPort,
"RenderingControlControlPath": selectedDevice.value.RenderingControlControlPath,
"RenderingControlEventPath": selectedDevice.value.RenderingControlEventPath,
Expand All @@ -154,17 +151,12 @@ def ssdpHandler(evt) {
String ssdpUSN = parsedEvent.ssdpUSN.toString()
if (devices."${ssdpUSN}") {
def d = devices."${ssdpUSN}"
if (d.networkAddress != parsedEvent.networkAddress || d.deviceAddress != parsedEvent.deviceAddress) {
d.networkAddress = parsedEvent.networkAddress
d.deviceAddress = parsedEvent.deviceAddress
def child = getChildDevice(parsedEvent.mac)
if (child) {
child.sync(parsedEvent.networkAddress, parsedEvent.deviceAddress)
}
}
d << parsedEvent
} else {
devices << ["${ssdpUSN}": parsedEvent]
}

verifyDevices()
}

void deviceDescriptionHandler(physicalgraph.device.HubResponse hubResponse) {
Expand Down Expand Up @@ -223,6 +215,14 @@ void deviceDescriptionHandler(physicalgraph.device.HubResponse hubResponse) {

if (verified == 2) {
device.value << [verified: true]

def child = getChildDevice(device.value.ssdpUSN)
if (child) {
log.debug "Found existing child, sync..."
child.sync(device.value)
}
} else {
device.value << [verified: false]
}

log.debug "deviceDescriptionHandler device.value=${device.value}"
Expand All @@ -235,4 +235,4 @@ private Integer convertHexToInt(hex) {

private String convertHexToIP(hex) {
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
}
}

0 comments on commit 4814874

Please sign in to comment.