Ultenic / proscenic python to groovy

ive just got a Ultenic vacuum and am looking to integrate it, found this code below could anyone help translate it to groovy. Im no programmer but if someone could help get me 80% their i could work out the bugs.

I'm OK with most it's just sending the http post command

anyone help with this error. im trying to send an initial command to the vacuum, but cant seem to form the request

this is what im trying to mirror from capturing the mobile app

this is the code im using

def sendcommand(code){
    Map reqParams = [
        uri: "http://mobile.proscenic.com.de:443/user/getEquips/"+VuserId+" HTTP/1.1",
        headers:[ token: Vtoken,
            lan: 'en',
            t: 'u',
            'Content-Type': "application/json;charset=UTF-8",
            'Content-Length': '20',
            Host: 'mobile.proscenic.com.de',
            Connection: 'Keep-Alive',
            'Accept-Encoding': 'gzip',
            'User-Agent': 'okhttp/3.12.3'],
        
        body:[
            size: '10',
            page: '0']
        ]
    log.debug "param Map ${reqParams}"
    try{
        httpPost(reqParams) { resp ->
            log.debug "response ${resp}"
        }
    }
    catch (e){
        log.debug "error ${e}"
    }
}

Any ideas?

You might need to URI encode the VuserId variable, but first I'd remove the HTTP/1.1 bit from the end the string.

Incidentally your email is still visible in various screenshots.

IMO you'd probably do better grabbing a copy of POSTMAN ( https://www.postman.com/ ) or use something like Curl or WGET to first test what you're trying to mirror from the mobile App.

That way you can verify that what you're trying to achieve will actually work before getting into the Groovy and Hubitat side!

tried postman, getting a 200 but its not responding to any configeration of commands ive tried rferancing this hass-proscenic-790T-vacuum/vacuum_proscenic.py at master · deblockt/hass-proscenic-790T-vacuum · GitHub

Does that other python library actually work when you try it? It looks like some kind of lower level socket interface that you could try to replicate on Hubitat.

The captures from your mobile app don't resemble at all what that python library has implemented, so it will be good to figure out which path you're trying to go down.

I assume it works, but yes the capture looks different I assumed it was because I was using a different app.

I guess I'll have to some fresh captures and see if any of the keys have changed

I think it is likely that you'll have issues if you try to mix the content from your mobile app captures and the commands in the hass-proscenic-790T-vacuum code.

Let's assume that the hass code works and that the Hubitat raw socket interface provides similar functionality to exchange byte arrays as the python code does.

I can get a successful connection on the IP and port for the remote server. But I can't get a reply to my login or ping commands, presumably because the deviceId, userId, and token are bogus.

Grab this code and edit the code to put the correct values in device, token, and user. Create a virtual device of this type. Then open a Logs window in a separate tab and hit openSocket, login, and ping (in that order) on the device page. Do you get a response?

Summary
/*

*/

metadata
{
    definition(name: "raw socket testing", namespace: "tomw", author: "tomw", importUrl: "")
    {
        command "openSocket"
        command "closeSocket"
        
        command "login"
        command "ping"

        attribute "commStatus", "string"
    }
}

preferences
{
    section
    {
        input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true
    }
}

def logDebug(msg) 
{
    if (logEnable)
    {
        log.debug(msg)
    }
}

def socketStatus(String message)
{
    logDebug("socketStatus: ${message}")
}

def openSocket()
{
    try
    {
        sendEvent(name: "commStatus", value: "unknown")
        
        interfaces.rawSocket.connect("47.91.67.181", 20008, byteInterface: true)
        
        sendEvent(name: "commStatus", value: "good")
    }
    catch (Exception e)
    {
        logDebug("error: ${e.message}")
        sendEvent(name: "commStatus", value: "error")
    }
}

def closeSocket()
{
    try
    {
        interfaces.rawSocket.close()
        
        sendEvent(name: "commStatus", value: "unknown")
    }
    catch (Exception e)
    {
        // swallow errors
    }
}

def login()
{
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
    
    byte[] header = [0xfb, 0, 0, 0, 0x10, 0, 0xc8, 0, 0, 0, 0x29, 0x27, 0x2a, 0x27, 0, 0, 0, 0, 0, 0]
    outputStream.write(header)
    
    def bodyPayload = 
        [
            cmd: 0,
            control: [targetId: ""],
            seq: 0,
            value:
            [
                appKey: "67ce4fabe562405d9492cad9097e09bf",
                deviceId: "ENTER DEVICE ID",
                deviceType: "3",
                token: "ENTER TOKEN",
                userId: "ENTER USER ID"
            ]
        ]
                
    byte[] body = groovy.json.JsonOutput.toJson(bodyPayload)?.getBytes()
    outputStream.write(body)
    
    _writeByteStreamToSocket(outputStream.toByteArray())
}

def ping()
{
    byte[] body = [0x14, 0, 0, 0, 0, 0x01, 0xc8, 0, 0, 0, 0x01, 0, 0x22, 0x27, 0, 0, 0, 0, 0, 0]
    _writeByteStreamToSocket(body)
}

def _writeByteStreamToSocket(byte[] bytes)
{
    logDebug("${new String(bytes, "UTF-8")}")
    interfaces.rawSocket.sendMessage(hubitat.helper.HexUtils.byteArrayToHexString(bytes))  
}

def parse(String message)
{
    logDebug("parse: ${message}")
}
1 Like

thanks for this
clicking openSocket gave 'good'
clicking log in gave

clicking ping gave

login in - open socket - ping results