Where do i go now?

Hi,

Over the last few years i’ve added various smartapps into the Groovy IDE. And a few device handlers for some odd little things i have. All of them are self-written and they all do rather specific things (reading sensors and issuing commands over https to a server of mine at home, which then makes other changes to non-smartthings devices, as one example).

The logic in them is all pretty simple, and they have worked fine for a long time.

I’ve gone to edit one of them today, just to adjust a scheduled task within it, only to find that ‘edit’ is no longer there. Having done some reading i’ve found a lot about Groovy basically ending and the IDE is now locked/dead?

I can’t for the life of me work out what i need to move “to” in order to continue with these features.

I have no knowlege about anything in the Smartthings ecosystem outside of the smartapps that i have built. There are mentions of so many different tools, sites, APIs etc. but i can’t even see where to start.

Can someone help? It kinda feels like the rug has been pulled from under me right now… :cry:

Thanks in advance!

It’s definitely frustrating for a lot of people. Why don’t you start with the following thread, and see if it feels like any of those might be an option for you. If not, we can talk about what might be needed to write new smartapps for the new architecture, but that’s gonna be a lot more work than if one of the other options will Meet your needs. And we’ll probably need to just look at one smartapp at a time to see what’s doable.

Replace Groovy with Automations—what’s your plan?

1 Like

Hi! Thanks for reaching out!

I’ve been having a look just now and (in the 5 years since i started my SmartThings journey) it does look like a number of my apps can now probably be achieved with Routines. It looks like that has come a long way, as when i started you couldn’t even make simple decisions based on a temperature sensor going above or below a threshold. This appears to be there and i suspect i can re-work several of my apps to use this instead.

The big thing i’m going to struggle with is the data collection and http push to my server, which then graphs the data and (where required) makes changes to other items directly connected to the server within the house as a result.

I’m going to post it below with the more personal/irrelevant bits removed.

definition(
    name: "Push AC Unit Info To Cacti",
    namespace: "snip",
    author: "snip",
    description: "Pushes values from Air Conditioning devices to Cacti over HTTP.",
    category: "snip",
    iconUrl: "snip"
    iconX2Url: "snip"
    iconX3Url: "snip"

preferences {
    section("Select an Air Conditioning Unit") {
        input "acunit", "capability.airConditionerMode", title: "Unit", required: true
    }
    section("Cacti Target DS") {
    	input "roomName", "text", title: "Room Name", required: true
    }
    section("Cacti Password") {
        input "password", "password", title: "Variable password", required: true
    }
}

def installed() {
    log.debug "Installed with settings: ${settings}"
    initialize()
}

def updated() {
    log.debug "Updated with settings: ${settings}"
    unsubscribe()
    unschedule()
    initialize()
}

def initialize() {
    subscribe(acunit, "temperature", temperatureChangedHandler)
    subscribe(acunit, "humidity", humidityChangedHandler)
    subscribe(acunit, "switch", powerChangedHandler)
    subscribe(acunit, "airConditionerMode", modeChangedHandler)
    subscribe(acunit, "coolingSetpoint", setpointChangedHandler)
    subscribe(acunit, "fanMode", fanModeChangedHandler)
    subscribe(acunit, "acOptionalMode", optionalModeChangedHandler)
    subscribe(acunit, "airFlowDirection", airflowChangedHandler)
    
    schedule("0 /15 * * * ?", updateAllValues)
    updateAllValues()
}

def debugHandler(evt) {
    // get the event name, e.g., "switch"
    log.debug "This event name is ${evt.name}"

    // get the value of this event, e.g., "on" or "off"
    log.debug "The value of this event is ${evt.value}"

    // get the Date this event happened at
    log.debug "This event happened at ${evt.date}"

    // did the value of this event change from its previous state?
    log.debug "The value of this event is different from its previous value: ${evt.isStateChange()}"
}

def updateAllValues() {
    temperatureChangedHandler()
    humidityChangedHandler()
    setpointChangedHandler()
    modeChangedHandler()
    airflowChangedHandler()
    fanModeChangedHandler()
    optionalModeChangedHandler()
    powerChangedHandler()
}

def updateDS(var, pwd, val) {
    //log.debug "DS-POST: ${var} : ${pwd} : ${val}"
    def params = [
        uri: "https://a-web-server-url",
        path: "/a-php-page.php",
        query: [
            "variable": var,
            "ttl": "86400",
            "password": pwd,
            "value": val
        ]
    ]
    
    try {
        httpGet(params) { resp ->   
            log.debug "response data: ${resp.data}"
        }
    } catch (e) {
        log.error "I did a bad: $e"
    }
}

def temperatureChangedHandler(evt) {
	updateDS("${roomName}T", password, acunit.currentTemperature)
}

def humidityChangedHandler(evt) {
	updateDS("${roomName}H", password, acunit.currentHumidity)
}

def setpointChangedHandler(evt) {
    updateDS("${roomName}SP", password, acunit.currentCoolingSetpoint)
}

def modeChangedHandler(evt) {
	def result = ""
	switch ("${acunit.currentAirConditionerMode}") {
         case "auto": result = "0"; break;
         case "cool": result = "1"; break;
         case "dry": result = "2"; break;
         case "coolClean": result = "3"; break;
         case "dryClean": result = "4"; break;
         case "fanOnly": result = "5"; break;
         case "heat": result = "6"; break;
         case "heatClean": result = "7"; break;
         case "notSupported": result = "8"; break;
         default: result = "9";
	}
    updateDS("${roomName}M", password, result)
}

def airflowChangedHandler(evt) {
	def result = ""
	switch ("${acunit.currentAirFlowDirection}") {
         case "all": result = "0"; break;
         case "fixed": result = "1"; break;
         case "vertial": result = "2"; break;
         case "horizontal": result = "3"; break;
         default: result = "9";
      }
    updateDS("${roomName}AF", password, result)
}

def fanModeChangedHandler(evt) {
	def result = ""
	switch ("${acunit.currentFanMode}") {
         case "auto": result = "0"; break;
         case "low": result = "1"; break;
         case "medium": result = "2"; break;
         case "high": result = "3"; break;
         case "turbo": result = "4"; break;
         default: result = "9";
      }
    updateDS("${roomName}FM", password, result)
}

def optionalModeChangedHandler(evt) { 
	def result = ""
	switch ("${acunit.currentAcOptionalMode}") {
         case "off": result = "0"; break;
         case "twoStep": result = "1"; break;
         case "quiet": result = "2"; break;
         case "speed": result = "3"; break;
         case "windFree": result = "4"; break;
         case "energySaving": result = "5"; break;
         default: result = "9";
      }
    updateDS("${roomName}OPT", password, result)
}

def powerChangedHandler(evt) {
	def result = ""
	switch ("${acunit.switchState.value}") {
         case "off": result = "0"; break;
         case "on": result = "1"; break;
         default: result = "9";
      }
    updateDS("${roomName}PWR", password, result)
}

This has worked for years now, and a chunk of it i’m sure i found from some Samsung page when i first made it - although please don’t judge my code too harshly!!

So looking through the list, i reckon most of what i need to do falls in to two groups with just one exception:

  1. Get info from a device and push it to a URL (i.e. the above).
  2. Look for a change in temperature and turn something on/off (now a routine).

The exception: Is a ZXT-120 IR transmitter which uses a custom device handler to control one very old A/C unit. I do not use this a lot, and i’m not adverse to changing the IR transmitter for another one. My priority is really getting the above code ‘migrated’ to something new so it does not suddenly stop working as it sounds like it soon will do.

Thanks for any help you can offer!!

1 Like

Thanks to some amazingly clever work by some community members, there are now edge drivers which can do webhooks to a device on your local LAN. (I mean, seriously, it’s amazing work.) so why don’t you take a look at the quick browse lists in the community-created wiki for the “edge services” list and see if there’s something you can use there for your webhooks.

https://thingsthataresmart.wiki/index.php?title=Quick_Browse_Lists_for_Edge_Drivers

1 Like

I don’t remember seeing anything for that particular IR device yet. (Remotec ZXT-120 IR transmitter)

A lot of people are using either bond or the SwitchBot mini hub as IR blasters now. Both have manufacturer – provided smartthings integrations. And I would expect to see Black Friday deals on both in the next week.

Tagging @rboy

1 Like

Oh thanks, right, this one here looks like it could do what’s required:

https://community.smartthings.com/t/st-edge-web-requestor-a-driver-to-issue-local-post-and-get-http-requests/232911

But - i’ve got a proper newbie question - because i’m clearly missing the absolute basic part of this.

Where is the whole ‘Edge’ concept/interface/thing managed? What’s the starting page/login/platform to get to the equivalent code interface so i can write something that gets the current setpoint of an AC unit (for example) and then passes this as the variable to the example Edge Web driver linked above?

I think the issue is i’m coming to this party so late, everything i find has literally hundreds of pages of replies to it and i just can’t see where this all starts yet.

In order, i need to:

  1. Have something ‘trigger’ when the temperature on the AC unit changes (event handler equivalent).
  2. Pass this new temperature value to the edge web requestor so that it does the HTTP GET.

It’s probably so basic i’m embarrassed to ask, but it was just a few lines of code in Groovy and I’ve literally only ever logged into the Groovy IDE to do this stuff…

Cheers!

There isn’t an equivalent to what you used to have because smartthings used to offer the free groovy cloud where you could run your code, and now they aren’t going to offer that service anymore.

So you have four choices:

  1. figure out how to do the logic you want in the regular routines and then use a pre-configured webhook in the edge driver you’ve been looking at. It allows you to preconfigure up to 50 different URLs. So you just decide which one to trigger based on the conditions. That’s similar to turning on a switch. So you use the routine to define what the trigger conditions will be and turn on the switch. Then the edge driver will post the predefined webhook.

  2. if you can’t define the conditions you want in regular routines, take a look at sharptools. It has a powerful rules engine with an easy to use interface, and it might do everything you need. It’s cloud-based, but so is your previous custom code. This is my own recommendation for most people, at least as a starting candidate. It’s easy to use, it’s quite powerful, and it just saves a lot of work.

They’ve got a black Friday deal right now for $18 for the first year, which seems worth trying, and will give you time to explore other alternatives.

  1. if you don’t want to use a third-party product and you’re OK with a fairly steep learning curve, you might be able to do it with the official rules API. The “ get started” process for that is pretty complicated. You will have to have a PC, there’s no webpage interface in the official features. You write your code on the PC and then upload it to the “rules API” in the cloud using the CLI (command line interface). To be honest, I don’t know much more about it than that, but there’s a whole section in the forum where you can ask.
  1. or you can write your own code in any language you want, host it yourself either on a local server, or through a hosting service, and connect to smartthings through the “REST API.”

And yes, I agree, it’s confounding that smartthings has not provided transition guidelines for groovy smartapp authors, but they haven’t. Which just leaves us in the community to help each other as best we can. There are staff members who will answer very specific questions if you run into something, but no “dummies guide” with the A-Z steps that I’ve seen.

2 Likes

BTW, have you had a chance to read the following yet:

FAQ: I have no idea what Edge is. Is that a new developer tool? (2022)

1 Like

Hi @JDRoberts - thanks so much for all this, i’ve had a good look and i believe i can see how to make 100% of my code within the SharpTools platform you suggest. I’m going to make a list (and check it twice :santa: ) and see if i can work through them all before the Samsung Grinch takes all my old apps away from me…

So, thank you once more, i honestly could have just thrown in the towel without this sort of guidance from you!

All the best!

2 Likes

The API Browser from @TAustin makes using the Rules API a tad less onerous. You can define your rules using a JSON file and can upload (and manage) it from the web browser interface.