asynchhttpPost - Global Variable use or better solution?

I am relatively new to the Hubitat development scene and I am trying to make my code look more professional and efficient so please forgive what is probably a really simple question.

I am writing a device driver that sends an asynchttpPost to control a cloud connected device. The body of the request needs to change depending on the request so with help from @thebearmay & @tomw I manged to get the request working using the following code

> Map output = [attrs: [heat_power: 1]]
String body = new groovy.json.JsonOutput().toJson(output)
def params = [
    uri: "Path to server",
    headers: [
        'User-token' : "Hidden",
        'Application-Id' : "98754e684ec045528b073876c34c7348"
    ],
    contentType: 'application/json',
    requestContentType: 'application/json',
    body: body
]
asynchttpPost ("handlerHeatOn", params)
}

Now I could just copy the above code into each of the relevant commands which work just fine but makes my code look very clunky.

Instead I was thinking I should be able to define the params into a global variable and modify the body depending on the required command but not sure if its possible to specify global variables in a device driver.

Thanks for your patience

I feel like you are good hands with mentors like @tomw and @thebearmay.... Not like I am absolving responsibility or anything... :wink:

But yes, I expect you should be able to do something to achieve what you are describing.... At the very least methods that pass their own values to a common method.... Hopefully those with more brainpower than me atm can chime in...

Easiest thing to do, assuming that all commands have the same pattern is to pass the command and value to a method that contains your code above, and then change the hardcoded map to one with the variables.

void callServer(String cmd, String val) {
    Map output = [attrs: [cmd: val]]
    String body = new groovy.json.JsonOutput().toJson(output)
    
    def params2 =
        [
            uri: "https:pathtoserver",
            headers:
            [
                'User-token': "Hidden",
                'Application-Id': "Hidden"
            ],
            contentType: 'application/json',
            requestContentType: 'application/json',
            body: body
        ]
...
3 Likes

I would write a method that takes as parameters the things that may change (for me, that tends to be a body and maybe just a part of the uri that may differ between requests). Then return a properly formatted Map of the Params.

This is helpful for encapsulating any additional details that are required, for example if you need to checksum or include anything else with the request before sending.

EDIT: I was going to post an example, but @thebearmay beat me to it. :wink:

3 Likes

What did I tell you.... :slight_smile:

1 Like

Wow @thebearmay & @tomw do you guys ever sleep?.......

I did actually do something similar but nowhere near as elegant using a switch case on a ID parameter that I created so a little pat on the back for me. However as you can probably see I switched from httpPost (original post) to asychttPost (In this post) as I was hoping I could use the call back to update the command button status therefore having some confidence that the request had been dealt with.

Using your solution I cant see a way to keep visibility of the "command ID" to trigger the relevant command update when the call back triggers.

Sorry for the stupid questions but I have always been somewhat of a pragmatic programmer (IE just get it working which with your help I have) but trying to make my output looks somewhat more professional.

1 Like

Very impressed

I am not totally sure I understand, but I think you want a way to pass data from the async caller to the callback (asynchttpPost to the callback method).

You could use the data parameter on asynchttpPost as shown here: Async HTTP calls

2 Likes

You need to pass it as an additional parameter, and then access it using the data map:

    asynchttpPost("getResp", requestParams, [cmd:"$vName/$vValue/$vType"])     
}

void getResp(resp, data) {
    try {
        if(debugEnabled) log.debug "$resp.properties - ${data['cmd']} - ${resp.getStatus()}"
...
2 Likes

@thebearmay @tomw Thanks that's cracked it.

Didn't realise that the asynchttPost function allowed passing of an additional parameter even though I had been looking at the documentation.

But its clearly documented so thanks for your patience.

I am going to mark post 3 as the solution to my question because that actually answered my original question. Your last post answered my follow up. Thanks once again

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.