Steam Driver

I'm not sure how many gamers are on here, but I created a Steam driver. It calls the public steam API to "let you know what game you're playing" and turn a switch on and off if you are playing a game. I'm not sure how many people would use this, but this will help me control my office light when I'm gaming and not moving for a long period of time... The GitHub repo is here.

UPDATE: There were some issues with the first version, but I've updated it now... Seems to be working great!

For anyone who wants to mess with this code, I highly recommend not doing any less than 5 seconds. I had a lot of issues with this when it was 1 second... Not sure why.

metadata {
    definition (name: "Steam API Driver", namespace: "AJax2012", author: "Adam Gardner") {
        capability "Switch";
        capability "Sensor";
        command "ForcePoll";
        command "poll";

        attribute "userName", "string";
        attribute "avatar", "string";
        attribute "status", "string";
        attribute "currentGame", "string";
 		attribute "DriverAuthor", "string";
    }

    preferences() {
        section("Query Inputs"){
            input "apiKey", "text", required: true, title: "API Key";
            input "steamId", "text", required: true, title: "steamID64 (https://steamidfinder.com/lookup)";
            input "autoPoll", "bool", required: false, title: "Enable Auto Poll";
            input "pollInterval", "enum", title: "Auto Poll Interval:", required: false, options: ["1 Second","5 Seconds", "10 Seconds", "15 Seconds", "30 Seconds", "1 Minute", "3 Minutes"];
        }
    }
}

def installed() {
    initialize();
}

def updated() {
    initialize();
}

def initialize() {
    unschedule();
    if (autoPoll){
        Schedule();
    }
}

def poll() {
    ForcePoll();
}

def ForcePoll()
{
    log.debug "Steam Forcepoll called";
    def params = [uri: "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${apiKey}&steamids=${steamId}"];

    try {
        httpGet(params) { resp ->

            // resp.headers.each {
            //     log.debug "Response: ${it.name} : ${it.value}"
            // }

            // log.debug "params: ${params}"
            // log.debug "response contentType: ${resp.contentType}"
            // log.debug "response data: ${resp.data}"

            def data = resp.data.response.players[0]

            sendEvent(name: "userName", value: data.personaname, isStateChange: true);
            sendEvent(name: "avatar", value: data.avatar, isStateChange: true);

            if (data.gameextrainfo){
                sendEvent(name: "currentGame", value: data.gameextrainfo, isStateChange: true);
                sendEvent(name: "status", value: "in game", unit: rainUnit, isStateChange: true);
                sendEvent(name: "switch", value: "on");
            }
            else {
                sendEvent(name: "currentGame", value: "n/a", isStateChange: true);
                sendEvent(name: "status", value: "offline", unit: rainUnit, isStateChange: true);
                sendEvent(name: "switch", value: "off")
            }
        }
    } catch (e) {
        log.debug e
    }
}

def Schedule() {
    def array = pollInterval.split();
    def numb = array[0];
    def unit = array[1];

    if (unit.contains("Second")) {
        schedule("0/${numb} * * ? * * *", poll);
    } else {
        schedule("${numb} * * ? * * *", poll);
    }
}

def Report(){
    def obvTime = observationTime.value
    log.info "$obvTime"  
}

def setVersion(){
    state.InternalName = "Steam API Driver"
    sendEvent(name: "DriverAuthor", value: "Adam Gardner", isStateChange: true)
}
2 Likes

I can see a rule that runs when door opened, play TTS message "Can't talk. In game. Bring food". Nice!

1 Like

Maybe try asynchronous http calls?:man_shrugging:

1 Like

I might give that a try at some point. I personally don't really need it more than once every minute for my purposes, so... Not sure if I'll get around to it, but we'll see. This is only my second second attempt at creating a driver, so there might be a good use for it in the future!

I am actually having some trouble with the autopolling feature and if I make any changes to the driver, if anyone wants to give me a hand with that... It doesn't recognize when I change the amount of time for auto polling and it doesn't seem to recognize when I've changed the driver at all unless I reboot entirely. Anyone know how I can fix that?

I took a quick look. You might want to add an updated() method where scheduling is initiated. At the beginning of it should include an unschedule command. That way changes are properly updated. The best thing would be to find a driver that does polling and use it as template. There's a link to one of my drivers below with a basic example.

Also you need to ensure you click Save after changing driver preferences.

1 Like

I'd advise on using asynchronous calls where possible. There have been quite a few cases where apps and drivers were causing hub lockups and making this change helped considerably. Just a word of advice...it MAY not be necessary.

1 Like

I'll definitely look into it. I'm not generally very good with async yet... I'm a jr dev and I generally use C#, so groovy is still a bit confusing for me. I took a quick glance at the documentation and I'm still a bit confused, but I'll definitely give it a try later today. Thanks for the tip :slightly_smiling_face:

1 Like

If I get some time this weekend, I may give the driver a spin and send you some feedback. I just haven't thought of a practical use for it yet.

1 Like

Looks like your other suggestions worked! I even got 1 second working. I'm gonna update the code in the first post. Thanks for the help!