How to begin creating a Roomba wifi remote plugin?

[quote=“LightsOn, post:40, topic:174190”]Hi Chuck,

Just offering further support! keep at it :slight_smile:

I am just about to purchase a board and reside in the UK so very very excited to see how you get on. I think I will use it in Vera in lost of ways but most like to ensure a clean is only activated when the home alarm is not on and for it to take place ASAP after last clean time missed etc. Lots of possibilities outside of just scheduled clean etc.

Really excited with you and all on this project - just wish i could add more help on the coding side ???[/quote]

Thanks for the words of encouragement! I love this forum because so many great people are willing to help me learn how to write code! It will be very rewarding once I conquer Project Roomba (version 1)!

Chuck,

I would suggest a few structural changes to hopefully make you journey a bit easier. Execuse me but it is the middle of the night here and I am doing this on an iPhone which believe me isn’t easy as I only ever see a small part of the screen.

In the example below for the implementation file I have changed the SID; however, it is not really that critical.

Make your declaration first and that will shorten the requirement of declare them all through out and lessen the chance of error. It also enable you to mange dynamic variable changes better such as your example of the change of the IP Address.

Define your functions rather then having them contained within your actions. It will make it simpler to read and add functions later.

What missing is functions for validation and error handling I.E checking IP exists or is not null and if it is how does it mange this. There are a number of apps which do this (DSC, Sonos, AV stuff) that would assist. Also when a function is called to assist you may want to to write to the log file using luup.log

I also suggest that even though the API may provide a lot of data, you won’t require child devices to display this and could be handled with JSON file. However, if you are going to drive it and intend to add a large number of controls (left, right etc but do not see this would be the case) it may be easier to divide the physical controls and status reporting later.

<?xml version="1.0"?>
<implementation>
  <functions>
  
  	local ipAddress
	local ROOMBA_SID = "urn:irobot-com:serviceId:Roomba1"
	local deviceid = lul_device  

	function clean ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=CLEAN")
	end	
	
	function spot ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=SPOT")
	end
	
	function dock ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=DOCK")
	end
	
	
  function init(x) end -- well, not really but roughly
  	 
 -- check IP address at start up

  </functions>
  <startup>init</startup>
  <actionList>
    <action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Clean</name>
		<run>
			Clean ()
		</run>
	</action>
	<action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Spot</name>
		<run>
			Spot ()
		</run>
	</action>
	<action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Dock</name>
		<run>
			Dock ()
		</run>
	</action>

    </action>
  </actionList>
</implementation>

Wow! Thanks Brientim! I’ll work on this again later.

Chuck what is the initial intent of the JSON file?
Is it only to have the three buttons for the time being?

There are some real good plugin out that provide a very sound basis for what your are doing and there are some very helpful ladies and gents in the forum who will endeavour to help.
Always remember, it is your app that you developing initially.

I also just noticed Infoviewer app has hyperlinked to reference that may be of assistance.

For Infoviewer see: http://forum.micasaverde.com/index.php/topic,13477.msg100381/topicseen.html#msg100381

The other point I forgot to mention/ask was about spot? Being that you need to drive/get the ROOMBA to a “spot” first before the action would be required, it is really a desired function that would be set into action via your Vera? To my logic it would not be due to the nature of why it is required and used.

I agree… only need clean and dock functions to start. I would like to know when Roomba gets “hung up” but that comes later. Basic functions to start!

Most excellent thread on the development of a plugin. Very interesting even though I prefer the Neato to the Roomba. I’m learning alot…keep posting the progress and status!

I just want to chime in with my appreciation. Everything I know about programming could be fit on the back of a postage stamp so any efforts made by plugin developers is highly appreciated by me. Stick with it! Ride this process out and at the end you may be making plugins that make Vera the top dog.
I love My Roomba’s and look forward to integrating them with Vera!

Good luck! …Chuck

[quote=“S-F, post:48, topic:174190”]I just want to chime in with my appreciation. Everything I know about programming could be fit on the back of a postage stamp so any efforts made by plugin developers is highly appreciated by me. Stick with it! Ride this process out and at the end you may be making plugins that make Vera the top dog.
I love My Roomba’s and look forward to integrating them with Vera!

Good luck! …Chuck[/quote]

Thanks guys! I am learning a lot and there great people on here to help us programming newbies learn. I appreciate how I am not just “given the answer” but snippets to help me understand what I need to do and learn as I go.

I get the purpose of the S_ , D_ and I_ .xml files (mostly) but the .json file seems to be a great mystery.

I am loving this forum because of its members’ You guys all are great. Thanks for the support!!!

Chuck

Okay, more trimming. I have reduced the functions to Clean and Dock for now. If I can get these two working, then I can think about adding more features… For now this would be a major step forward. Do I dare load these files below and test?

Programming Gurus… thoughts?!? Oh, and about the json file… What the heck is the deal with it? I still don’t know how anyone writes and edits the darn thing! :-[ .

Roomba_S

<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <actionList>
    <action>
      <name>Clean</name>
      <argumentList></argumentList>
    </action>
    
    <action>
      <name>Dock</name>
      <argumentList></argumentList>
    </action>
  </actionList>
</scpd>[/code]

Roomba_D
[code]<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <device>
    <deviceType>urn:schemas-micasaverde-com:device:receiver:1</deviceType>
    <staticJson>D_Roomba1.json</staticJson> 
    <friendlyName>Roomba</friendlyName>
    <manufacturer>iRobot</manufacturer>
    <manufacturerURL>http://www.iRobot.com</manufacturerURL>
    <modelDescription>Roomba</modelDescription>
    <modelName>700 Series</modelName>
    <modelNumber>790</modelNumber>
    <UDN>uuid:</UDN>
    <protocol>raw</protocol>
    <handleChildren>0</handleChildren>

    <implementationList>
        <implementationFile>I_Roomba1.xml</implementationFile>
    </implementationList>

    <serviceList>
      <service>
        <serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:SwitchPower1</serviceId>
        <SCPDURL>S_SwitchPower1.xml</SCPDURL>
      </service>
    </serviceList>
  </device>
</root>

Roomba_I

<?xml version="1.0"?>
<implementation>
  <functions>
  
  	local ipAddress
	local ROOMBA_SID = "urn:irobot-com:serviceId:Roomba1"
	local deviceid = lul_device  

	function clean ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=CLEAN")
	end	
	
	function dock ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=DOCK")
	end
	
	
  function init(x) end -- well, not really but roughly
  	 
 -- check IP address at start up

  </functions>
  <startup>init</startup>
  <actionList>
    <action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Clean</name>
		<run>
			Clean ()
		</run>
	</action>
	<action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Dock</name>
		<run>
			Dock ()
		</run>
	</action>

    </action>
  </actionList>
</implementation>

Look carefully at the differences between your I_Roomba1.xml and this:

<?xml version="1.0"?>
<implementation>
  <functions>
  
  	local ipAddress
	local ROOMBA_SID = "urn:irobot-com:serviceId:Roomba1"
	local deviceid = lul_device  

	function clean ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=CLEAN")
	end	
	
	function dock ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=DOCK")
	end
	
	
  function init(lul_device)
     -- check IP address at start up
    ipAddress = "192.168.1.10" -- or whatever it is, and this will go in a device variable later
  end

  </functions>
  <startup>init</startup>
  <actionList>
    <action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Clean</name>
		<run>
			clean ()
		</run>
	</action>
	<action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Dock</name>
		<run>
			dock ()
		</run>
	</action>

    </action>
  </actionList>
</implementation>

Study all the examples you can, and check the wiki – http://wiki.mios.com/index.php/Luup_plugins:_Static_JSON_file.

Keep going, Chuck!

watou

Also, your D_Roomba1.xml says it’s implementing SwitchPower, but it should actually be implementing your service type (S_Roomba1.xml) to match the implementation (I_Roomba1.xml).

[quote=“watou, post:51, topic:174190”]Look carefully at the differences between your I_Roomba1.xml and this:

<?xml version="1.0"?>
<implementation>
  <functions>
  
  	local ipAddress
	local ROOMBA_SID = "urn:irobot-com:serviceId:Roomba1"
	local deviceid = lul_device  

	function clean ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=CLEAN")
	end	
	
	function dock ()
		luup.inet.wget("http://" .. ipAddress .. "/roomba.cgi?button=DOCK")
	end
	
	
  function init(lul_device)
     -- check IP address at start up
    ipAddress = "192.168.1.10" -- or whatever it is, and this will go in a device variable later
  end

  </functions>
  <startup>init</startup>
  <actionList>
    <action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Clean</name>
		<run>
			clean ()
		</run>
	</action>
	<action>
		<serviceId>urn:irobot-com:serviceId:Roomba1</serviceId>
		<name>Dock</name>
		<run>
			dock ()
		</run>
	</action>

    </action>
  </actionList>
</implementation>

Study all the examples you can, and check the wiki – http://wiki.mios.com/index.php/Luup_plugins:_Static_JSON_file.

Keep going, Chuck!

watou[/quote]

I was actually wondering how to define the IP correctly. I assume that once the plugin is installed on a Vera the IP can be changed in the “Advanced” tab?

I’ll do json research… but it may have to wait until after “V-Day”. Thanks for the help.

This is where I get a bit confused. The relationship between the files is critical and I don’t quite fully grasp it yet! D_Roomba1.xml is supposed to tie in “urn:irobot-com:serviceId:Roomba1” from I_Roomba1.xml?!?

Chuck

[quote=“chuck1026, post:53, topic:174190”]I was actually wondering how to define the IP correctly. I assume that once the plugin is installed on a Vera the IP can be changed in the “Advanced” tab?

This is where I get a bit confused. The relationship between the files is critical and I don’t quite fully grasp it yet! D_Roomba1.xml is supposed to tie in “urn:irobot-com:serviceId:Roomba1” from I_Roomba1.xml?!?[/quote]

In a nutshell, this is how the files are related to one another: The S_ file defines a service, the D_ file defines a device that supports one or more services, and the I_ file implements one or more services in Lua code. If you were making a device that implemented services that have already been defined, you would not need to create any new S_ files. But since there aren’t any Roomba UPnP service definitions out there (yet), you get to create it.

At some point, you will have to declare a variable in your S_Roomba1.xml service, possibly called IpAddress, and then you can set that variable on the Advanced tab and read it in the code in the I_Roomba1.xml file to substitute into your URLs.

I really recommend digging into the available documentation and looking at examples. Before starting the Nest plugin, I bought the book “Programming in Lua,” written by its principle creator, Roberto Ierusalimschy. It’s a great learning tool and it helped me figure out good coding practices.

In the meantime, have a nice holiday!

watou

[quote=“watou, post:54, topic:174190”]I really recommend digging into the available documentation and looking at examples. Before starting the Nest plugin, I bought the book “Programming in Lua,” written by its principle creator, Roberto Ierusalimschy. It’s a great learning tool and it helped me figure out good coding practices.

In the meantime, have a nice holiday!

watou[/quote]

Okay… I agree I need to read up and that book sounds like it could be very helpful! I see a link to the 1st edition is available at Programming in Lua … or should I buy the latest edition?

I recommend the second edition, the one I got. It exactly matches Lua 5.1, which is what you are interested in. Lua is a very nice, simple language, and the book presents it very clearly.

watou

[quote=“watou, post:56, topic:174190”]I recommend the second edition, the one I got. It exactly matches Lua 5.1, which is what you are interested in. Lua is a very nice, simple language, and the book presents it very clearly.

watou[/quote]

I just ordered that book and look forward to studying and learning more too! I went to the Wiki link on Json files and kind of wonder, like in the case of the ultra cool Nest plugin icons, what can you use as a server and how do you link to them? I think I eventually need to peek at the Nest code to understand. Otherwise I think I am bound to “canned” icons (not as much fun or clever).

Chuck

Chuck,

A little bit more for you. Keep at it.
There is an example of the icons and the first line of the JSON file of linking to the icon which goes in /www/cmh/skins/default/icons.

[quote=“Brientim, post:58, topic:174190”]Chuck,

A little bit more for you. Keep at it.
There is an example of the icons and the first line of the JSON file of linking to the icon which goes in /www/cmh/skins/default/icons.[/quote]

That is a great looking icon for Roomba ;D !!!

Thanks!

Hi Chuck,

Great work - still motoring on I see :slight_smile:

My board just arrived today - any chance of a PM to me stating a ‘brain dump’ of what you did to get the basics up and running? e.g basic good practice for instalation and set up on my network so I can conrtrol through my network by sending http commands or similar. In return once i have mine set up i shall add a “how to” somewher that you could use in a link to the pluck in your building.

P.S for future thought (much more in the future) a signal to say the Rommba got stuck would be ace if possible? as then (for me at least) i can check where it was hiding once i recive an email notification or similar - thus making sure Rooma is retruned to base when I get in as I have ofter found it hiding somwhere and its not untill several days have gone by that I ntoice it did not get back to base and has thus not be cleaning as required.