Get state from web page

Hi friends

Im trying to create an interface between OH and my robot vacuum,

succesfully i created some .sh script to run and stop my robot from Openhab.

Everytime i send a command to my robot in the openab webpage it execute correctly the command and reply me with its status.

example.

From terminal i do: sh robot_clean.sh it reply me this:

{"version":1,"reqId":"1","result":"ok","error":"ui_alert_invalid","data": {},"state":1,"action":0,"cleaning": {"category":2,"mode":1,"modifier":2,"spotWidth":0,"spotHeight":0},"details": {"isCharging":false,"isDocked":false,"isScheduleEnabled":true,"dockHasBeenSeen":false,"charge":98},"availableCommands": {"start":true,"stop":false,"pause":false,"resume":false,"goToBase":false},"availableServices": {"houseCleaning":"basic-1","spotCleaning":"basic-1","manualCleaning":"basic-1","easyConnect":"basic-1","schedule":"basic-1"},"meta": {"modelName":"BotVacConnected","firmware":"2.0.0"}}

As you can see in the code there are all the status info.
Also i can recall these status info via another sh script.

in the item i created a string for every value:

String BotVacError "Latest Info [MAP(botvac_error.map):% s]"
 String BotVacModel "model [% s]"
 String BotVacFirmware "firmware version [% s]"
 Number BotVacBattery "BotVac battery status (%) [% s]"
 String BotVacSchedule "schedule [MAP(botvac_schedule.map):% s]"
 String BotVacDock "dock state [MAP(botvac_dock.map):% s]"
 String BotVacControl "control"
 String BotVacState "status [MAP(botvac_state.map):% s]" 

In the SITEMAP i created a frame for this

Frame label="Neato Vacuum" {

          Text item=BotVacState icon="botvac"
          Text item=BotVacModel icon="botvac"
          Text item=BotVacFirmware icon="botvac"
          Text item=BotVacBattery valuecolor=[>70="green",>50="orange",<30="red"] icon="botvac"
          Text item=BotVacError  icon="botvac"
          Text item=BotVacSchedule  icon="botvac"
          Text item=BotVacDock  icon="botvac"

}


                                Frame label="Robot Console" {
                                        Switch item=BotVacControl mappings=[clean="Clean", home="Go home"] icon="botvac"
                                }

I create also the relative mappings. But i have no idea how OH can retrieve the information from these messages and how it can select only the right value from all the message e.g… only the part

"isDocked"=false

any advice?

OK update…

I modified the script to send the state to my text items…

rule "BotVacHome"
 when
         Item BotVacControl received command home
 then
         executeCommandLine ( "/Openhab/configurations/scripts/examples/botvac_home.sh")
         val  result = sendHttpGetRequest("http://localhost:9292/get_robot_state")
         BotVacState.postUpdate(result)

 end

now the items seems receive the entire web page…

2016-09-25 23:44:49.471 [INFO ] [g.openhab.io.net.exec.ExecUtil] - executed commandLine '/Openhab/configurations/scripts/examples/botvac_home.sh'
2016-09-25 23:44:49.496 [WARN ] [o.u.i.items.ItemUIRegistryImpl] - Exception while formatting value '{"version":1,"reqId":"1","result":"ok","error":"ui_alert_invalid","data": {},"state":1,"action":0,"cleaning": {"category":2,"mode":1,"modifier":1,"spotWidth":0,"spotHeight":0},"details": {"isCharging":false,"isDocked":true,"isScheduleEnabled":true,"dockHasBeenSeen":false,"charge":99},"availableCommands": {"start":true,"stop":false,"pause":false,"resume":false,"goToBase":false},"availableServices": {"houseCleaning":"basic-1","spotCleaning":"basic-1","manualCleaning":"basic-1","easyConnect":"basic-1","schedule":"basic-1"},"meta": {"modelName":"BotVacConnected","firmware":"2.0.0"}}' of item BotVacState with format 'MAP(botvac_state.map):% s': java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags =  
2016-09-25 23:44:50.231 [INFO ] [runtime.busevents             ] - BotVacState state updated to {"version":1,"reqId":"1","result":"ok","error":"ui_alert_invalid","data": {},"state":1,"action":0,"cleaning": {"category":2,"mode":1,"modifier":1,"spotWidth":0,"spotHeight":0},"details": {"isCharging":false,"isDocked":true,"isScheduleEnabled":true,"dockHasBeenSeen":false,"charge":99},"availableCommands": {"start":true,"stop":false,"pause":false,"resume":false,"goToBase":false},"availableServices": {"houseCleaning":"basic-1","spotCleaning":"basic-1","manualCleaning":"basic-1","easyConnect":"basic-1","schedule":"basic-1"},"meta": {"modelName":"BotVacConnected","firmware":"2.0.0"}}

how can i extract only one part of it?

The text appears to be JSON. So use the JSONPATH Transform to extract specific values.

For example, in your Rule you can:

executeCommandLine ( "/Openhab/configurations/scripts/examples/botvac_home.sh")
val  result = sendHttpGetRequest("http://localhost:9292/get_robot_state")
val version = transform("JSONPATH", "$.version", result).replace('\"', '')
...
val isCharging = transform("JSONPATH", $.details.isCharging", result)

There are other ways too but this is probably the easiest. NOTE: JSONPATH returns the value just as it appears, so if it is a String value it comes with the double quotes. the .replace strips the double quotes out of the String.

Thank you now it perfectly work.
This is wath i ve done for someone want include his NEATO BOTVAC in openhab. if can be useful i can create a little tutorial

ITEMS:


 String BotVacError "Errors [MAP(botvac_error.map):%s]"
 Number BotVacBattery "Battery (%) [%s]"
 String BotVacSchedule "Mode [MAP(botvac_schedule.map):%s]"
 String BotVacDock "Position [MAP(botvac_dock.map):%s]"
 String BotVacControl "control"
 String BotVacState "status [MAP(botvac_state.map):%s]" 
 String BaseHasSeen "Dock[MAP(BaseHasSeen.map):%s]" 

RULES

  rule "BotVacHome" 
 when
         Item BotVacControl received command home
 then
    executeCommandLine ( "/Openhab/configurations/scripts/examples/botvac_home.sh")
    
    //*When you push home button Robot send you its new state (you can do this for every action)
val resulto = sendHttpGetRequest("http://localhost:9292/get_robot_state")
val isScheduleEnabled = transform("JSONPATH", "$details.isScheduleEnabled",resulto).replace('\"', '')
val isdocked = transform("JSONPATH", "$details.isDocked",resulto).replace('\"', '')
val batterystat = transform("JSONPATH", "$details.charge",resulto).replace('\"', '')
val BaseHasBeenSeen = transform("JSONPATH", "$details.dockHasBeenSeen",resulto).replace('\"', '')
val Error = transform("JSONPATH", "$error",resulto).replace('\"', '') 
val state = transform("JSONPATH", "$state",resulto).replace('\"', '')
BaseHasSeen.postUpdate(BaseHasBeenSeen)
BotVacDock.postUpdate(isdocked)
BotVacState.postUpdate(state)
BotVacError.postUpdate(Error)
BotVacBattery.postUpdate(batterystat)
BotVacSchedule.postUpdate(isScheduleEnabled)
end


SITEMAP

Frame label="Stato BotVac" {

          Text item=BotVacState icon="botvac" 
          Text item=BotVacBattery valuecolor=[>70="green",>50="orange",<30="red"] icon="botvac"
          Text item=BotVacError  icon="botvac" valuecolor=[Funzionamento Regolare="green"]
          Text item=BotVacSchedule icon="botvac"
          Text item=BotVacDock  icon="botvac"
          Text item=BaseHasSeen 

}


                                Frame label="Controllo BotVac" {
                                        Switch item=BotVacControl mappings=[clean="Clean", home="Dock"] icon="botvac"
                                }

Now the only thing i miss is create a timer on system startup… i tried like this but probably i’m wrong with the syntax.

rule "BotvacStartup"
    
when  System started

then
timer = createTimer(now.plusSeconds(10)) 
[|val resulto = sendHttpGetRequest("http://localhost:9292/get_robot_state")
val isScheduleEnabled = transform("JSONPATH", "$details.isScheduleEnabled",resulto).replace('\"', '')
val isdocked = transform("JSONPATH", "$details.isDocked",resulto).replace('\"', '')
val batterystat = transform("JSONPATH", "$details.charge",resulto).replace('\"', '')
val BaseHasBeenSeen = transform("JSONPATH", "$details.dockHasBeenSeen",resulto).replace('\"', '')
val Error = transform("JSONPATH", "$error",resulto).replace('\"', '') 
val state = transform("JSONPATH", "$state",resulto).replace('\"', '')
BaseHasSeen.postUpdate(BaseHasBeenSeen)
BotVacDock.postUpdate(isdocked)
BotVacState.postUpdate(state)
BotVacError.postUpdate(Error)
BotVacBattery.postUpdate(batterystat)
BotVacSchedule.postUpdate(isScheduleEnabled)]
end

wich library i have to import in addons?

1 Like

If on OH 1 you need to import org.openhab.model.script.actions.* I think. In OH 2 you don’t need to import anything.

Yes… I ve already imported these library but i dont have it in addons library… And i dont found it on my folder with all addons Are they included in the core?

Hello @technotools, by all means, please write a tutorial!
I own a Neato Signature myself (sadly too old for this integration) and it would be amazing to integrate it. Maybe I’ll upgrade after your instructions are out :wink:

Timer is part of the core of OH. No need to install anything special to use it.

Yeah… Its strange. I have an error message from openhab designer. But i read there is a bug.

Is the code correct?

The OH 1.x Designer has a bug right now where it no longer recognizes now. If Designer is complaining about the now.plusSeconds(10) the it is just a Designer problem, not a real problem. Running it and see if it works.

yes seems to work. Thank you for now.

Soon (when my integration will be complete) i’ll write a little HowTo.

FYI: This helped me a lot in getting the botvac and openhab to talk: http://www.roboter-forum.com/showthread.php?16117-Botvac-Connected-Integration-in-openHAB