mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-09 13:21:53 +00:00
Merge pull request #547 from workingmonk/remove_samsung
[DVCSMP-1480] removing old samsung integration
This commit is contained in:
@@ -1,235 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2015 SmartThings
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Samsung TV
|
|
||||||
*
|
|
||||||
* Author: SmartThings (juano23@gmail.com)
|
|
||||||
* Date: 2015-01-08
|
|
||||||
*/
|
|
||||||
|
|
||||||
metadata {
|
|
||||||
definition (name: "Samsung Smart TV", namespace: "smartthings", author: "SmartThings") {
|
|
||||||
capability "switch"
|
|
||||||
|
|
||||||
command "mute"
|
|
||||||
command "source"
|
|
||||||
command "menu"
|
|
||||||
command "tools"
|
|
||||||
command "HDMI"
|
|
||||||
command "Sleep"
|
|
||||||
command "Up"
|
|
||||||
command "Down"
|
|
||||||
command "Left"
|
|
||||||
command "Right"
|
|
||||||
command "chup"
|
|
||||||
command "chdown"
|
|
||||||
command "prech"
|
|
||||||
command "volup"
|
|
||||||
command "voldown"
|
|
||||||
command "Enter"
|
|
||||||
command "Return"
|
|
||||||
command "Exit"
|
|
||||||
command "Info"
|
|
||||||
command "Size"
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
|
|
||||||
state "default", label:'TV', action:"switch.off", icon:"st.Electronics.electronics15", backgroundColor:"#ffffff"
|
|
||||||
}
|
|
||||||
standardTile("power", "device.switch", width: 1, height: 1, canChangeIcon: false) {
|
|
||||||
state "default", label:'', action:"switch.off", decoration: "flat", icon:"st.thermostat.heating-cooling-off", backgroundColor:"#ffffff"
|
|
||||||
}
|
|
||||||
standardTile("mute", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Mute', action:"mute", icon:"st.custom.sonos.muted", backgroundColor:"#ffffff"
|
|
||||||
}
|
|
||||||
standardTile("source", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Source', action:"source", icon:"st.Electronics.electronics15"
|
|
||||||
}
|
|
||||||
standardTile("tools", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Tools', action:"tools", icon:"st.secondary.tools"
|
|
||||||
}
|
|
||||||
standardTile("menu", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Menu', action:"menu", icon:"st.vents.vent"
|
|
||||||
}
|
|
||||||
standardTile("HDMI", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Source', action:"HDMI", icon:"st.Electronics.electronics15"
|
|
||||||
}
|
|
||||||
standardTile("Sleep", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Sleep', action:"Sleep", icon:"st.Bedroom.bedroom10"
|
|
||||||
}
|
|
||||||
standardTile("Up", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Up', action:"Up", icon:"st.thermostat.thermostat-up"
|
|
||||||
}
|
|
||||||
standardTile("Down", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Down', action:"Down", icon:"st.thermostat.thermostat-down"
|
|
||||||
}
|
|
||||||
standardTile("Left", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Left', action:"Left", icon:"st.thermostat.thermostat-left"
|
|
||||||
}
|
|
||||||
standardTile("Right", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Right', action:"Right", icon:"st.thermostat.thermostat-right"
|
|
||||||
}
|
|
||||||
standardTile("chup", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'CH Up', action:"chup", icon:"st.thermostat.thermostat-up"
|
|
||||||
}
|
|
||||||
standardTile("chdown", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'CH Down', action:"chdown", icon:"st.thermostat.thermostat-down"
|
|
||||||
}
|
|
||||||
standardTile("prech", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Pre CH', action:"prech", icon:"st.secondary.refresh-icon"
|
|
||||||
}
|
|
||||||
standardTile("volup", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Vol Up', action:"volup", icon:"st.thermostat.thermostat-up"
|
|
||||||
}
|
|
||||||
standardTile("voldown", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Vol Down', action:"voldown", icon:"st.thermostat.thermostat-down"
|
|
||||||
}
|
|
||||||
standardTile("Enter", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Enter', action:"Enter", icon:"st.illuminance.illuminance.dark"
|
|
||||||
}
|
|
||||||
standardTile("Return", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Return', action:"Return", icon:"st.secondary.refresh-icon"
|
|
||||||
}
|
|
||||||
standardTile("Exit", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Exit', action:"Exit", icon:"st.locks.lock.unlocked"
|
|
||||||
}
|
|
||||||
standardTile("Info", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Info', action:"Info", icon:"st.motion.acceleration.active"
|
|
||||||
}
|
|
||||||
standardTile("Size", "device.switch", decoration: "flat", canChangeIcon: false) {
|
|
||||||
state "default", label:'Picture Size', action:"Size", icon:"st.contact.contact.open"
|
|
||||||
}
|
|
||||||
main "switch"
|
|
||||||
details (["power","HDMI","Sleep","chup","prech","volup","chdown","mute","voldown", "menu", "Up", "tools", "Left", "Enter", "Right", "Return", "Down", "Exit", "Info","Size"])
|
|
||||||
}
|
|
||||||
|
|
||||||
def parse(String description) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
log.debug "Turning TV OFF"
|
|
||||||
parent.tvAction("POWEROFF",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Power Off", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def mute() {
|
|
||||||
log.trace "MUTE pressed"
|
|
||||||
parent.tvAction("MUTE",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Mute", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def source() {
|
|
||||||
log.debug "SOURCE pressed"
|
|
||||||
parent.tvAction("SOURCE",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Source", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def menu() {
|
|
||||||
log.debug "MENU pressed"
|
|
||||||
parent.tvAction("MENU",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def tools() {
|
|
||||||
log.debug "TOOLS pressed"
|
|
||||||
parent.tvAction("TOOLS",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Tools", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def HDMI() {
|
|
||||||
log.debug "HDMI pressed"
|
|
||||||
parent.tvAction("HDMI",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command sent", value: "Source", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Sleep() {
|
|
||||||
log.debug "SLEEP pressed"
|
|
||||||
parent.tvAction("SLEEP",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Sleep", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Up() {
|
|
||||||
log.debug "UP pressed"
|
|
||||||
parent.tvAction("UP",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Down() {
|
|
||||||
log.debug "DOWN pressed"
|
|
||||||
parent.tvAction("DOWN",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Left() {
|
|
||||||
log.debug "LEFT pressed"
|
|
||||||
parent.tvAction("LEFT",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Right() {
|
|
||||||
log.debug "RIGHT pressed"
|
|
||||||
parent.tvAction("RIGHT",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def chup() {
|
|
||||||
log.debug "CHUP pressed"
|
|
||||||
parent.tvAction("CHUP",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Channel Up", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def chdown() {
|
|
||||||
log.debug "CHDOWN pressed"
|
|
||||||
parent.tvAction("CHDOWN",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Channel Down", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def prech() {
|
|
||||||
log.debug "PRECH pressed"
|
|
||||||
parent.tvAction("PRECH",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Prev Channel", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Exit() {
|
|
||||||
log.debug "EXIT pressed"
|
|
||||||
parent.tvAction("EXIT",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def volup() {
|
|
||||||
log.debug "VOLUP pressed"
|
|
||||||
parent.tvAction("VOLUP",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Volume Up", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def voldown() {
|
|
||||||
log.debug "VOLDOWN pressed"
|
|
||||||
parent.tvAction("VOLDOWN",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Volume Down", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Enter() {
|
|
||||||
log.debug "ENTER pressed"
|
|
||||||
parent.tvAction("ENTER",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Return() {
|
|
||||||
log.debug "RETURN pressed"
|
|
||||||
parent.tvAction("RETURN",device.deviceNetworkId)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Info() {
|
|
||||||
log.debug "INFO pressed"
|
|
||||||
parent.tvAction("INFO",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Info", displayed: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
def Size() {
|
|
||||||
log.debug "PICTURE_SIZE pressed"
|
|
||||||
parent.tvAction("PICTURE_SIZE",device.deviceNetworkId)
|
|
||||||
sendEvent(name:"Command", value: "Picture Size", displayed: true)
|
|
||||||
}
|
|
||||||
@@ -1,401 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2015 SmartThings
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Samsung TV Service Manager
|
|
||||||
*
|
|
||||||
* Author: SmartThings (Juan Risso)
|
|
||||||
*/
|
|
||||||
|
|
||||||
definition(
|
|
||||||
name: "Samsung TV (Connect)",
|
|
||||||
namespace: "smartthings",
|
|
||||||
author: "SmartThings",
|
|
||||||
description: "Allows you to control your Samsung TV from the SmartThings app. Perform basic functions like power Off, source, volume, channels and other remote control functions.",
|
|
||||||
category: "SmartThings Labs",
|
|
||||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Samsung/samsung-remote%402x.png",
|
|
||||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Samsung/samsung-remote%403x.png",
|
|
||||||
singleInstance: true
|
|
||||||
)
|
|
||||||
|
|
||||||
preferences {
|
|
||||||
page(name:"samsungDiscovery", title:"Samsung TV Setup", content:"samsungDiscovery", refreshTimeout:5)
|
|
||||||
}
|
|
||||||
|
|
||||||
def getDeviceType() {
|
|
||||||
return "urn:samsung.com:device:RemoteControlReceiver:1"
|
|
||||||
}
|
|
||||||
|
|
||||||
//PAGES
|
|
||||||
def samsungDiscovery()
|
|
||||||
{
|
|
||||||
if(canInstallLabs())
|
|
||||||
{
|
|
||||||
int samsungRefreshCount = !state.samsungRefreshCount ? 0 : state.samsungRefreshCount as int
|
|
||||||
state.samsungRefreshCount = samsungRefreshCount + 1
|
|
||||||
def refreshInterval = 3
|
|
||||||
|
|
||||||
def options = samsungesDiscovered() ?: []
|
|
||||||
|
|
||||||
def numFound = options.size() ?: 0
|
|
||||||
|
|
||||||
if(!state.subscribe) {
|
|
||||||
log.trace "subscribe to location"
|
|
||||||
subscribe(location, null, locationHandler, [filterEvents:false])
|
|
||||||
state.subscribe = true
|
|
||||||
}
|
|
||||||
|
|
||||||
//samsung discovery request every 5 //25 seconds
|
|
||||||
if((samsungRefreshCount % 5) == 0) {
|
|
||||||
log.trace "Discovering..."
|
|
||||||
discoversamsunges()
|
|
||||||
}
|
|
||||||
|
|
||||||
//setup.xml request every 3 seconds except on discoveries
|
|
||||||
if(((samsungRefreshCount % 1) == 0) && ((samsungRefreshCount % 8) != 0)) {
|
|
||||||
log.trace "Verifing..."
|
|
||||||
verifysamsungPlayer()
|
|
||||||
}
|
|
||||||
|
|
||||||
return dynamicPage(name:"samsungDiscovery", title:"Discovery Started!", nextPage:"", refreshInterval:refreshInterval, install:true, uninstall: true) {
|
|
||||||
section("Please wait while we discover your Samsung TV. Discovery can take five minutes or more, so sit back and relax! Select your device below once discovered.") {
|
|
||||||
input "selectedsamsung", "enum", required:false, title:"Select Samsung TV (${numFound} found)", multiple:true, options:options
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
def upgradeNeeded = """To use SmartThings Labs, your Hub should be completely up to date.
|
|
||||||
|
|
||||||
To update your Hub, access Location Settings in the Main Menu (tap the gear next to your location name), select your Hub, and choose "Update Hub"."""
|
|
||||||
|
|
||||||
return dynamicPage(name:"samsungDiscovery", title:"Upgrade needed!", nextPage:"", install:true, uninstall: true) {
|
|
||||||
section("Upgrade") {
|
|
||||||
paragraph "$upgradeNeeded"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def installed() {
|
|
||||||
log.trace "Installed with settings: ${settings}"
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def updated() {
|
|
||||||
log.trace "Updated with settings: ${settings}"
|
|
||||||
unschedule()
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def uninstalled() {
|
|
||||||
def devices = getChildDevices()
|
|
||||||
log.trace "deleting ${devices.size()} samsung"
|
|
||||||
devices.each {
|
|
||||||
deleteChildDevice(it.deviceNetworkId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def initialize() {
|
|
||||||
// remove location subscription afterwards
|
|
||||||
if (selectedsamsung) {
|
|
||||||
addsamsung()
|
|
||||||
}
|
|
||||||
//Check every 5 minutes for IP change
|
|
||||||
runEvery5Minutes("discoversamsunges")
|
|
||||||
}
|
|
||||||
|
|
||||||
//CHILD DEVICE METHODS
|
|
||||||
def addsamsung() {
|
|
||||||
def players = getVerifiedsamsungPlayer()
|
|
||||||
log.trace "Adding childs"
|
|
||||||
selectedsamsung.each { dni ->
|
|
||||||
def d = getChildDevice(dni)
|
|
||||||
if(!d) {
|
|
||||||
def newPlayer = players.find { (it.value.ip + ":" + it.value.port) == dni }
|
|
||||||
log.trace "newPlayer = $newPlayer"
|
|
||||||
log.trace "dni = $dni"
|
|
||||||
d = addChildDevice("smartthings", "Samsung Smart TV", dni, newPlayer?.value.hub, [label:"${newPlayer?.value.name}"])
|
|
||||||
log.trace "created ${d.displayName} with id $dni"
|
|
||||||
|
|
||||||
d.setModel(newPlayer?.value.model)
|
|
||||||
log.trace "setModel to ${newPlayer?.value.model}"
|
|
||||||
} else {
|
|
||||||
log.trace "found ${d.displayName} with id $dni already exists"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private tvAction(key,deviceNetworkId) {
|
|
||||||
log.debug "Executing ${tvCommand}"
|
|
||||||
|
|
||||||
def tvs = getVerifiedsamsungPlayer()
|
|
||||||
def thetv = tvs.find { (it.value.ip + ":" + it.value.port) == deviceNetworkId }
|
|
||||||
|
|
||||||
// Standard Connection Data
|
|
||||||
def appString = "iphone..iapp.samsung"
|
|
||||||
def appStringLength = appString.getBytes().size()
|
|
||||||
|
|
||||||
def tvAppString = "iphone.UN60ES8000.iapp.samsung"
|
|
||||||
def tvAppStringLength = tvAppString.getBytes().size()
|
|
||||||
|
|
||||||
def remoteName = "SmartThings".encodeAsBase64().toString()
|
|
||||||
def remoteNameLength = remoteName.getBytes().size()
|
|
||||||
|
|
||||||
// Device Connection Data
|
|
||||||
def ipAddress = convertHexToIP(thetv?.value.ip).encodeAsBase64().toString()
|
|
||||||
def ipAddressHex = deviceNetworkId.substring(0,8)
|
|
||||||
def ipAddressLength = ipAddress.getBytes().size()
|
|
||||||
|
|
||||||
def macAddress = thetv?.value.mac.encodeAsBase64().toString()
|
|
||||||
def macAddressLength = macAddress.getBytes().size()
|
|
||||||
|
|
||||||
// The Authentication Message
|
|
||||||
def authenticationMessage = "${(char)0x64}${(char)0x00}${(char)ipAddressLength}${(char)0x00}${ipAddress}${(char)macAddressLength}${(char)0x00}${macAddress}${(char)remoteNameLength}${(char)0x00}${remoteName}"
|
|
||||||
def authenticationMessageLength = authenticationMessage.getBytes().size()
|
|
||||||
|
|
||||||
def authenticationPacket = "${(char)0x00}${(char)appStringLength}${(char)0x00}${appString}${(char)authenticationMessageLength}${(char)0x00}${authenticationMessage}"
|
|
||||||
|
|
||||||
// If our initial run, just send the authentication packet so the prompt appears on screen
|
|
||||||
if (key == "AUTHENTICATE") {
|
|
||||||
sendHubCommand(new physicalgraph.device.HubAction(authenticationPacket, physicalgraph.device.Protocol.LAN, "${ipAddressHex}:D6D8"))
|
|
||||||
} else {
|
|
||||||
// Build the command we will send to the Samsung TV
|
|
||||||
def command = "KEY_${key}".encodeAsBase64().toString()
|
|
||||||
def commandLength = command.getBytes().size()
|
|
||||||
|
|
||||||
def actionMessage = "${(char)0x00}${(char)0x00}${(char)0x00}${(char)commandLength}${(char)0x00}${command}"
|
|
||||||
def actionMessageLength = actionMessage.getBytes().size()
|
|
||||||
|
|
||||||
def actionPacket = "${(char)0x00}${(char)tvAppStringLength}${(char)0x00}${tvAppString}${(char)actionMessageLength}${(char)0x00}${actionMessage}"
|
|
||||||
|
|
||||||
// Send both the authentication and action at the same time
|
|
||||||
sendHubCommand(new physicalgraph.device.HubAction(authenticationPacket + actionPacket, physicalgraph.device.Protocol.LAN, "${ipAddressHex}:D6D8"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private discoversamsunges()
|
|
||||||
{
|
|
||||||
sendHubCommand(new physicalgraph.device.HubAction("lan discovery ${getDeviceType()}", physicalgraph.device.Protocol.LAN))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private verifysamsungPlayer() {
|
|
||||||
def devices = getsamsungPlayer().findAll { it?.value?.verified != true }
|
|
||||||
|
|
||||||
if(devices) {
|
|
||||||
log.warn "UNVERIFIED PLAYERS!: $devices"
|
|
||||||
}
|
|
||||||
|
|
||||||
devices.each {
|
|
||||||
verifysamsung((it?.value?.ip + ":" + it?.value?.port), it?.value?.ssdpPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private verifysamsung(String deviceNetworkId, String devicessdpPath) {
|
|
||||||
log.trace "dni: $deviceNetworkId, ssdpPath: $devicessdpPath"
|
|
||||||
String ip = getHostAddress(deviceNetworkId)
|
|
||||||
log.trace "ip:" + ip
|
|
||||||
sendHubCommand(new physicalgraph.device.HubAction("""GET ${devicessdpPath} HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))
|
|
||||||
}
|
|
||||||
|
|
||||||
Map samsungesDiscovered() {
|
|
||||||
def vsamsunges = getVerifiedsamsungPlayer()
|
|
||||||
def map = [:]
|
|
||||||
vsamsunges.each {
|
|
||||||
def value = "${it.value.name}"
|
|
||||||
def key = it.value.ip + ":" + it.value.port
|
|
||||||
map["${key}"] = value
|
|
||||||
}
|
|
||||||
log.trace "Devices discovered $map"
|
|
||||||
map
|
|
||||||
}
|
|
||||||
|
|
||||||
def getsamsungPlayer()
|
|
||||||
{
|
|
||||||
state.samsunges = state.samsunges ?: [:]
|
|
||||||
}
|
|
||||||
|
|
||||||
def getVerifiedsamsungPlayer()
|
|
||||||
{
|
|
||||||
getsamsungPlayer().findAll{ it?.value?.verified == true }
|
|
||||||
}
|
|
||||||
|
|
||||||
def locationHandler(evt) {
|
|
||||||
def description = evt.description
|
|
||||||
def hub = evt?.hubId
|
|
||||||
def parsedEvent = parseEventMessage(description)
|
|
||||||
parsedEvent << ["hub":hub]
|
|
||||||
log.trace "${parsedEvent}"
|
|
||||||
log.trace "${getDeviceType()} - ${parsedEvent.ssdpTerm}"
|
|
||||||
if (parsedEvent?.ssdpTerm?.contains(getDeviceType()))
|
|
||||||
{ //SSDP DISCOVERY EVENTS
|
|
||||||
|
|
||||||
log.trace "TV found"
|
|
||||||
def samsunges = getsamsungPlayer()
|
|
||||||
|
|
||||||
if (!(samsunges."${parsedEvent.ssdpUSN.toString()}"))
|
|
||||||
{ //samsung does not exist
|
|
||||||
log.trace "Adding Device to state..."
|
|
||||||
samsunges << ["${parsedEvent.ssdpUSN.toString()}":parsedEvent]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // update the values
|
|
||||||
|
|
||||||
log.trace "Device was already found in state..."
|
|
||||||
|
|
||||||
def d = samsunges."${parsedEvent.ssdpUSN.toString()}"
|
|
||||||
boolean deviceChangedValues = false
|
|
||||||
|
|
||||||
if(d.ip != parsedEvent.ip || d.port != parsedEvent.port) {
|
|
||||||
d.ip = parsedEvent.ip
|
|
||||||
d.port = parsedEvent.port
|
|
||||||
deviceChangedValues = true
|
|
||||||
log.trace "Device's port or ip changed..."
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deviceChangedValues) {
|
|
||||||
def children = getChildDevices()
|
|
||||||
children.each {
|
|
||||||
if (it.getDeviceDataByName("mac") == parsedEvent.mac) {
|
|
||||||
log.trace "updating dni for device ${it} with mac ${parsedEvent.mac}"
|
|
||||||
it.setDeviceNetworkId((parsedEvent.ip + ":" + parsedEvent.port)) //could error if device with same dni already exists
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (parsedEvent.headers && parsedEvent.body)
|
|
||||||
{ // samsung RESPONSES
|
|
||||||
def deviceHeaders = parseLanMessage(description, false)
|
|
||||||
def type = deviceHeaders.headers."content-type"
|
|
||||||
def body
|
|
||||||
log.trace "REPONSE TYPE: $type"
|
|
||||||
if (type?.contains("xml"))
|
|
||||||
{ // description.xml response (application/xml)
|
|
||||||
body = new XmlSlurper().parseText(deviceHeaders.body)
|
|
||||||
log.debug body.device.deviceType.text()
|
|
||||||
if (body?.device?.deviceType?.text().contains(getDeviceType()))
|
|
||||||
{
|
|
||||||
def samsunges = getsamsungPlayer()
|
|
||||||
def player = samsunges.find {it?.key?.contains(body?.device?.UDN?.text())}
|
|
||||||
if (player)
|
|
||||||
{
|
|
||||||
player.value << [name:body?.device?.friendlyName?.text(),model:body?.device?.modelName?.text(), serialNumber:body?.device?.serialNum?.text(), verified: true]
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log.error "The xml file returned a device that didn't exist"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(type?.contains("json"))
|
|
||||||
{ //(application/json)
|
|
||||||
body = new groovy.json.JsonSlurper().parseText(bodyString)
|
|
||||||
log.trace "GOT JSON $body"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.trace "TV not found..."
|
|
||||||
//log.trace description
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def parseEventMessage(String description) {
|
|
||||||
def event = [:]
|
|
||||||
def parts = description.split(',')
|
|
||||||
parts.each { part ->
|
|
||||||
part = part.trim()
|
|
||||||
if (part.startsWith('devicetype:')) {
|
|
||||||
part -= "devicetype:"
|
|
||||||
event.devicetype = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('mac:')) {
|
|
||||||
part -= "mac:"
|
|
||||||
event.mac = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('networkAddress:')) {
|
|
||||||
part -= "networkAddress:"
|
|
||||||
event.ip = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('deviceAddress:')) {
|
|
||||||
part -= "deviceAddress:"
|
|
||||||
event.port = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('ssdpPath:')) {
|
|
||||||
part -= "ssdpPath:"
|
|
||||||
event.ssdpPath = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('ssdpUSN:')) {
|
|
||||||
part -= "ssdpUSN:"
|
|
||||||
event.ssdpUSN = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('ssdpTerm:')) {
|
|
||||||
part -= "ssdpTerm:"
|
|
||||||
event.ssdpTerm = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('headers')) {
|
|
||||||
part -= "headers:"
|
|
||||||
event.headers = part.trim()
|
|
||||||
}
|
|
||||||
else if (part.startsWith('body')) {
|
|
||||||
part -= "body:"
|
|
||||||
event.body = part.trim()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event
|
|
||||||
}
|
|
||||||
|
|
||||||
def parse(childDevice, description) {
|
|
||||||
def parsedEvent = parseEventMessage(description)
|
|
||||||
|
|
||||||
if (parsedEvent.headers && parsedEvent.body) {
|
|
||||||
def headerString = new String(parsedEvent.headers.decodeBase64())
|
|
||||||
def bodyString = new String(parsedEvent.body.decodeBase64())
|
|
||||||
log.trace "parse() - ${bodyString}"
|
|
||||||
|
|
||||||
def body = new groovy.json.JsonSlurper().parseText(bodyString)
|
|
||||||
} else {
|
|
||||||
log.trace "parse - got something other than headers,body..."
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer convertHexToInt(hex) {
|
|
||||||
Integer.parseInt(hex,16)
|
|
||||||
}
|
|
||||||
|
|
||||||
private String convertHexToIP(hex) {
|
|
||||||
[convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
|
|
||||||
}
|
|
||||||
|
|
||||||
private getHostAddress(d) {
|
|
||||||
def parts = d.split(":")
|
|
||||||
def ip = convertHexToIP(parts[0])
|
|
||||||
def port = convertHexToInt(parts[1])
|
|
||||||
return ip + ":" + port
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean canInstallLabs()
|
|
||||||
{
|
|
||||||
return hasAllHubsOver("000.011.00603")
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean hasAllHubsOver(String desiredFirmware)
|
|
||||||
{
|
|
||||||
return realHubFirmwareVersions.every { fw -> fw >= desiredFirmware }
|
|
||||||
}
|
|
||||||
|
|
||||||
private List getRealHubFirmwareVersions()
|
|
||||||
{
|
|
||||||
return location.hubs*.firmwareVersionString.findAll { it }
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user