How Can I Put Computer to sleep and Wake Computer with SmartThings

Hi, this thread got bumped so it caught my attention for the first time.

Basically, I’m using WOL to turn it on and a custom windows service to shutdown. The WOL is actually done with the help of my router. I couldn t figure out how to send the magic packet from the smartthings hub, so instead smartthings makes a request from the internet to my desktop through the port forwarding on the router. The router will send if a request is made to it and the desktop doesnt respond to the routers ping. This works on ASUS Merlin, but I think it might work on any router running some variant of dd-wrt.

after replacing MAC with your desktop mac address, and TARGET with your desktop’s IP address, add the script to your jffs directory and call it from your routers start up script

#!/bin/sh

INTERVAL=5
NUMP=1
OLD=""
TARGET=192.168.0.128 
IFACE=br0
MAC=FF:FF:FF:FF:FF:FF
WOL=/usr/bin/ether-wake
LOGFILE="/var/log/ether-wake.log"

while sleep $INTERVAL;do
NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ {print }' | tail -1`
SRC=`echo $NEW | awk -F'[=| ]' '{print $8}'`
DPORT=`echo $NEW | awk -F'[=| ]' '{print $27}'`
PROTO=`echo $NEW | awk -F'[=| ]' '{print $23}'`

if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
if ! ping -qc $NUMP $TARGET >/dev/null; then
# echo "NOWAKE $TARGET was accessed by $SRC, port $DPORT, protocol $PROTO and is already alive at" `date`>> $LOGFILE
# else
echo "WAKE $TARGET requested by $SRC, port $DPORT, protocol $PROTO at" `date`>> $LOGFILE
$WOL -i $IFACE $MAC
sleep 5
fi
OLD=$NEW
fi
done

If you need help with the windows service that accepts the shutdown request I can give you my C#/dotnet code. And lastly, the device type that Im using for smartthings is as follows. Go easy on me since I threw it together just for my purposes and might have some hard coded paths. Also it was a learning exercise for me with groovy

/**
 *  Desktop
 *
 *  Copyright 2015 Herbert Carroll
 *
 */
 preferences {
    input("confIpAddr", "string", title:"IP Address of the desktop",
        defaultValue: "192.168.0.195", required:true, displayDuringSetup: true)
    input("dnsName", "string", title:"Public DNS name or IP",
        defaultValue: "192.168.0.195", required:true, displayDuringSetup: true)
    input("confTcpPort", "number", title:"TCP Port the shutdown service is running on",
        defaultValue:"9080", required:true, displayDuringSetup:true)
}
 
metadata {
	definition (name: "Desktop", namespace: "herbcarroll", author: "Herbert Carroll") {
		capability "Polling"
        capability "Refresh"
		capability "Switch"
	}

	simulator {
		// TODO: define status and reply messages here
	}

	tiles {
		
       standardTile("mainTile", "device.switch") {
	        
            state "off", label: 'Off', action:"polling.poll", icon: "st.Electronics.electronics18", backgroundColor: "#ffffff"
			state "on", label: 'On', action:"polling.poll", icon: "st.Electronics.electronics18", backgroundColor: "#ffa81e"

		}
            
        standardTile("switchOn", "device.switch", inactiveLabel: false, decoration: "flat") {
	        
            state "off", label: '', action: "switch.on", icon: "st.sonos.play-btn", backgroundColor: "#ffffff"
			state "on", label: '', action: "switch.on", icon: "st.sonos.play-btn", backgroundColor: "#79b821"

		}
        
        standardTile("switchOff", "device.switch", inactiveLabel: false, decoration: "flat") {
	        
            state "off", label: '', action: "switch.off", icon: "st.sonos.stop-btn", backgroundColor: "#ffffff"
			state "on", label: '', action: "switch.off", icon: "st.sonos.stop-btn", backgroundColor: "#79b821"

		}
        
		standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
			state "default", action:"polling.poll", icon:"st.secondary.refresh"
		}
		

        main ("mainTile");
        details(["switchOn", "switchOff", "mainTile", "refresh"]);
	}
	
}


// parse events into attributes
def parse(String description) {
	log.debug "Parsing '${description}'"
	
    def map = [:]
    def retResult = []
    def descMap = parseDescriptionAsMap(description)

    def body = new String(descMap["body"].decodeBase64());
    log.debug body;
    
    if  ( body.startsWith("ping"))
    	sendEvent(name: "switch", value: "on");
}

def parseDescriptionAsMap(description) {
	description.split(",").inject([:]) { map, param ->
		def nameAndValue = param.split(":")
		map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
	}
}

def on() {
	log.debug "Executing 'on'"
	
    sendEvent(name: "switch", value: "on")
    
    sendWOL();
}

def off() {
	log.debug "Executing 'off'"
	
    sendEvent(name: "switch", value: "off");
   
    return apiGet("/smartshutdown");
}

def poll() {
	log.debug "Executing 'poll'"
	sendEvent(name: "switch", value: "off");
    
    return apiGet("/ping");
    
}

def sendWOL(evt)
{
	log.debug "wake via router!";

	def params = [
    	uri: "http://${dnsName}:${confTcpPort}/ping"
	]

	try {
    	httpGet(params) { resp ->
        	
            log.debug("looks like the box is already up!");
        	log.debug( "response : ${resp}");
    	}
        return;
        
	} 
    catch (e){
    	log.debug("sent a WOL!");
    	log.debug("Its expected something went wrong: $e");
	}
}

private apiGet(String path) {
    TRACE("apiGet(${path})")
    
    setNetworkId(confIpAddr, confTcpPort);
    

    def headers = [
        HOST:       "${confIpAddr}:${confTcpPort}",
        Accept:     "*/*"
    ]

    def httpRequest = [
        method:     'GET',
        path:       path,
        headers:    headers
    ]

    return new physicalgraph.device.HubAction(httpRequest)
}

private def TRACE(message) {
    log.debug message
}

private String setNetworkId(ipaddr, port) { 
    TRACE("setNetworkId(${ipaddr}, ${port})")

    def hexIp = ipaddr.tokenize('.').collect {
        String.format('%02X', it.toInteger())
    }.join()

    def hexPort = String.format('%04X', port.toInteger())
    device.deviceNetworkId = "${hexIp}:${hexPort}"
    log.debug "device.deviceNetworkId = ${device.deviceNetworkId}"
}

The best part of this is I am able to have my HTPC automatically turn on amongst other things as I open the door to my media room

1 Like