Tag Archives: #VDM30in30

Lessons learned from #vDM30in30

Phew!  I’m not sorry to say that #vDM30in30 is over with!  Not to say it wasn’t a lot of fun, but honestly, it’s a lot of work – especially when juggling family, travel, the day job and all!  One might think that simply blasting out 30 pieces of content in 30 days would be relatively easy – but it’s not!  That said, I learned a lot about my writing process and styles during this challenge, and as my final, and, unfortunately only 28th post of the month I’d like to share those with you…

The challenge of topics

It’s not easy coming up with topics to write about, especially when writing so often.  I was lucky enough to have had a handful of ideas already sitting in my draft folders – and #vDM30in30 finally gave me the opportunity to write about them.  That said, I know I had thought of more throughout the month and simply forgot to write them down.  So whatever your means of tracking your ideas are (drafts, post-its, bullet journals) write them down!  I found that if I didn’t commit it to something I would forget it.  Needless to say I have a dozen or so topics just sitting in my drafts now – which leads me to the next challenge…

The challenge of time

Surely this is probably the biggest hurdle of all – finding the time to articulate yourself and get a blog post written.  I find that this varies for me – for some topics I’ll simply start writing and have a complete post hashed out in an hour or so.  Others I find myself having to go do research, read other blogs, whitepapers, trying to fully understand what I’m writing about 🙂  Those are the ones that sometimes take days – 10 minutes here and there, revisiting the same ol’ things.  For me I’m best to dedicate all the time I need to write the post in one sitting – otherwise I have  a hard time reading my own writing once I revisit the post.  That said, time is tricky thing to find – we have families, commitments, other things we need to take care of – what I did was always critique myself with what I was doing.  If I was watching a habs game I would try and at least do something “blog productive” while doing so.  Those endless hours on an airplane – perfect for editing and getting things ready!  My advice here, just use your time wisely and don’t sacrifice the things you love the most just to write a blog post – the kids will eventually go to sleep – do it then 🙂

The challenge of writing

Perhaps this is the oddest hurdle to overcome.  Sometimes the words just come, other times I struggle trying to explain myself.  There were times where, even though I knew I would have a hard time coming back to complete a post I simply had to walk away.  If you are burnt out, nothing will make sense.  Take breaks, either small or large – we are all different just find what works for you.  For me, that was walking…

So I’m happy to say that even though I was two shy of the infamous thirty – I did learn some things about my writing process and styles.  With that said, here’s a look at what I accomplished throughout the month of November on mwpreston.net.

Tech Field Day 12 Stuff

My favorite Veeamy things…

Other vendor stuff

My Friday Shorts

Randoms

So there you have it!  Thanks all for following along and reading and I hope to participate next year as well.  All that said, don’t expect a post per day to continue here – I need some sleep!

Another go around at #vDM30in30

Ah November!  Where I’m from that means much cooler temperatures, hours of wood-stacking, a flurry of blaze orange covered people hiding in the woods, and another shot at completing the #vDM30in30.

#vDM30in30 calendar

For those that are not in the know the #vDM30in30 is a personal challenge that you bring upon yourself.  A challenge in which bloggers attempt to publish 30 posts within the 30 days that November contains.  This is only the second year that the folks over at Virtual Design Master (thus the VDM portion) have officially put forth the challenge.  I for one attempted this last year and I think I only got a measly 8 posts out – so did I fail?  Absolutely not – it’s just for fun and unlike their actual Virtual Design Master challenges this one is simply personal and not judged.  If you want to learn more about the VDM’s vision for the challenge I’d suggest taking a look at @DiscoPosse’s blog here.

Is there value in cranking out blog posts?

I’m sure a few concerns will come to mind if you look at doing something like this.  Concern about creating valid content, concern about whether your readership will even care, and concern about simply just generating noise in the community.  These are the fears I had when I first started bouncing the idea of #vDM30in30 around my mind.  As I explored the idea more though I came to the conclusion that although this is a public blog and I do a lot of public work on it, it’s still my blog – and honestly, I can do whatever I want with it.  That’s when I took the idea of #vDM30in30 and really focused in on the personal challenge aspects of it.

The first concern, creating valid content.  It’s inevitable that I won’t be able to crank out 30 technical posts about technical things in 30 days. It’s hard enough to do this in a year!   What I will do is write about things I’m passionate about though – so don’t be surprised if you see some “out of place” articles pop up.   The fact is it doesn’t matter whether I’m writing about connecting to an API, a newly released product, or Stompin’ Tom Connors – the end goal of this challenge for me is simply writing.  With each and every post I would hope I learn something – whether that be technical, or something that simply helps me become a better writer.  The end goal for me is to simply get the creative juices flowing and “put pen to paper”.

The second concern, similar to the first, is whether my readership will care.  Again I’ll reiterate the end goal of improving my writing skills.  I may write about the Montreal Canadiens – I’m an absolute fanatic – are you?  Maybe, maybe not – doesn’t really matter.  If you want to read it you will – if you don’t, you won’t.  It’s as simple as that!

And thirdly, noise generation.  Honestly, there is so much noise on my Twitter/Facebook right now that it’s hard enough to sift through it.  At then end of this I came to the conclusion that my little tweets aren’t as influential as what I may think they are.  I’m not a billion dollar company that has to keep on eye on my every public move – I’m just me, and the things I say and do only last a brief moment in the world of social media 🙂

Honestly I have a crazy November coming up with a VMUG, a VMware vForum, a Veeam User Group and a Tech Field Day.  Now all of this is triggers a “content-generating” event anyways so I guess you could say that #vDM30in30 couldn’t come at a more fitting time for me.  That said I can’t drag these out into 30 posts so I hope you all understand that you may see some “off topic” posts in the next 30 days.  Take them with a grain of salt and know my end goal here is to simply improve and have fun.  Feel free to play along – simply hashtag your posts with #vDM30in30, or don’t – doesn’t matter.  And don’t worry too much about actually hitting 30 – remember last year – I had 8!  This isn’t supposed to stress you out!  That said – this counts as #1 🙂

Friday Shorts – #vDM30in30, AWS, Reading, Writing, AWS and more…

Would it kill you not to be so funny all the time? That’s all I’m askin’. This woman thinks I’m very funny and now you’re gonna be funny, so what am I gonna be? I’m gonna be a short bald guy with glasses who suddenly doesn’t seem so funny. – George Costanza

VMworld is over – vSphere 6.5 is near

VMware LogoWith VMworld EMEA sweeping up the remains of the solutions exchange the dawn of vSphere 6.5 is here!  And with that comes a multitude – and I mean a crap load of multitudes of blogs talking about all of their favourite features of the release to come!  With that said I can’t possible link to all of them that I have read – but what I will link to is to the linkmaster himself Eric Siebert!  He’s got a great roundup post here of all of the features within vSphere 6.5.  Now this post doesn’t have links, just quickly lists the features – but if you want to go deeper on a certain feature be sure to check out his ‘vSphere 6.5 Link-O-Rama’ page as well!

Renting vSphere on AWS

vmware_awsVMware and AWS announced a partnership – one which would allow vSphere to run on the Amazon cloud!  What this means for customers is that they will get the familiarity of vSphere and all it has to offer, but on a cloud-like scale, running on bare-metal within Amazon’s datacenters.  What’s in it for VMware – well, they get that global cloud they have been looking for, without having to actually build the datacenters behind it!  And Amazon – well, who knows where they will take it but I can’t see them complaining too much about being able to pitch certain services and products to those who chose to run VMware on AWS!  Anyways, Frank Denneman has a great article here taking a deeper look into everything – as well, a little bit of a preview on how the new service enables one pretty cool new feature – Elastic DRS.

Alastair teaches us to read!

Although this post is a couple months old I’m just getting around to sharing it now!  I wanted to be sure as I’m always interested in how everyone in this community stays current with so much going on all the time!  The amount of content getting created for and by the tech community is huge, and keeping track of it all is certainly becoming a skill!  I read a lot, a lot of blogs so any way of figuring out ways to streamline my content consumption always sparks my interest!  Alastair has already taken us through is process of creating content, but with this post he takes us through his process of consuming content!  This is a great post with excellent tips on how to stay current!

More than simply writing a file

There’s a guest blog post on Michael White’s blog written by Michael Cade outlining the various backup methods used within Veeam Backup & Replication and how each one of them affects the capacity and performance on your backup repositories.   If you are using VBR and you haven’t had an in-depth look at these backup methods I would suggest starting with this post – it does a great job at outlining just how each backup method works, what is actually contained within each VBR backup file type.  It’s not just simply copying data here 🙂

#VDM30in30 30 posts, 30 days!

Think you have what it takes to pump out 30 posts in 30 days – I can say that I certainly thought I did at one point in time, but quickly realized after just a few days that I most certainly did not!  But hey, kudos for trying right – and even though I have a lot going on this November I will most likely try again!  Don’t have a clue what I’m talking about – well, the folks from the Virtual Design Master competition are once again challenging the blogging community to crank out 30 posts in 30 days throughout the month of November!  Have a look at Eric Wright’s blog for a great description of what this is like!  Now I know some people may think that the quality of posts may not be there, or that the content won’t be relevant, but honestly, my blogging isn’t about perfecting every single thing I do (I’m sure that’s apparent).  It’s about sharing things I do, problems I run into, opinions I have – sometimes it may be relevant, sometimes it won’t – sometimes you may agree, sometimes you won’t – sometimes you may just not even understand why a post ends up on this blog!   To me writing is about passion, and whether that passion be virtualization, technology, canadian folk music, maple syrup, hunting, whatever, it doesn’t matter!   The point here is that when I write, I think –  and when I think I learn – and nobody can argue that learning is invaluable!  So heads up, you might see some odd posts here come this November!

Friday Shorts – JSON, Veeam, Embedded Host Client and more…

I think you’re really beautiful and I feel really warm when I’m around you and my tongue swells up. – Buddy the Elf

JSON will be the death of me

I don’t do a lot of JSON parsing but when I do I tend to get just a little frustrated.  Honestly I almost always try and retrieve API responses as XML if the option is there, but sometimes it isn’t and sorting through JSON is the only alternative!  I’m a newbie to this stuff and still am learning quite a deal about interacting with APIs using various methods – one of the many reason I follow Scott Lowe’s blog regularly.  In a post this week he introduced us to a lightweight command line tool called jq, which looks like it could most definitely help me with my JSON woes – next time I find myself staring down at a page full of squigglies (not sure of the official term for  {}) I’ll give it a go… Thanks Scott!

Embedded Host Client is awesome x 5

I haven’t had a lot of time to spend with the Embedded Host Client fling – a replacement that will allow us to do away with the giant c# installable that we have all grown to love for individual host management.  I did get to use the EHC early on, and it was not the greatest experience – but as time went on and it was released via VMware Flings it is now a lot better, in fact people are loving it!  Here’s a great article outlining 5 reasons why the Embedded Host Client is awesome!

VVOLs 4 DBs!

VVOLs is still a little unknown when it comes to adoption – I haven’t seen a lot of blogs or information out there about widespread adoption!  I do know that there is general excitement out there and definitely benefits to be had by utilizing them, however they are still a little “ripe” in IT years!  That said there’s an interesting series on the VMware blogs going on right now outlining the benefits they can provide to databases – you can check out Part 1 and Part 2 if you like…

The Expert Guide to VMware Disaster Recovery and Data Protection

Shameless plug for myself on this one – A few months ago I began work on a guide for Veeam centering around how to provide Data Protection within a VMware environment – and the result is finally live!  Note – you are going to hit a reg-wall when trying to view this – it’s the nature of the world we live in, but if you do end up checking it out I’d love to know what you think – good or bad, but mostly good!

Dumping SharePoint Integrated SSRS reports to pdf using c#

Anytime I’m working on any sort of coding project Google is really my savior – there is absolutely no way I can know how all of the different libraries and functions available inside of all the .net components, nor do I really care to.  Sometimes I’ll get lucky and find exactly what I’m looking for but in reality it’s a fury of Google searches opened up in multiple tabs that end up getting pieced together into what I call “Production Code”.    Anytime I have to piece together solutions from various sites I try and post the finished product here – mainly so I don’t have to go and find it all again the next time I do it but also I’m sure it helps the odd stranger during his Google-Fu – so with that said, and with #vDM30in30 looming over me here’s a solution to help with connecting to a SharePoint integrated reporting services instance, passing parameters to a report, and exporting the report to pdf through code-behind.

I chose to do this as a c# Windows Forms app but you could technically try and reproduce the code with some slight changes if you were to use asp.  Either way we only need two controls on the form to make it work; a ReportViewer and a Button – go ahead and drag those onto the form.

form

So for the setup of the ReportViewer control there are only a few properties we need to setup in order to get our connection to the SharePoint SSRS instance which are listed below

  • ProcessingMode – Set this to Remote.  This simply states that the report we will be running is located remotely
  • Then under ServerReport we need to specify a couple of options
    • ReportServerUrl – This is the URL to the SSRS Report Server.  Usually, in SharePoint integrated mode it will be the same as your site URL, with ‘_vti_bin/reportserver/’ tagged on the end.  IE, https://mysharepoint.url/sitename/_vti_bin/reportserver/
    • ReportPath – This is the path to the report you would like to process, relative to your ReportServerUrl.  So if you browse to your Report Server and keep track of the directories you click on to get to the desired rdl – this is what goes into this property – IE Reports/MyReports/ReportName.rdl

And some code…

First up we are going to be accessing a few methods and objects outside of the normal c# includes.  In order to gain access to these you will need to import the following references into your project and declare them at the top of your cs file – Use nuget it’s much easier 🙂

using Microsoft.Reporting.WinForms.Internal.Soap.ReportingServices2005.Execution;
using Microsoft.Reporting.WinForms;
using System.Web.Services.Protocols;
using System.IO;

And the code for the main click event on our button….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
private void Button1_Click(object sender, EventArgs e)
{
  string FilePath = "C:\\Desired\\Path\\";
 
  // define and add parameteres
  Microsoft.Reporting.WinForms.ReportParameter[] reportParameterCollection = new Microsoft.Reporting.WinForms.ReportParameter[3];
  reportParameterCollection[0] = new Microsoft.Reporting.WinForms.ReportParameter();
  reportParameterCollection[0].Name = "Parameter1";
  reportParameterCollection[0].Values.Add("Param1Value");
  reportParameterCollection[1] = new Microsoft.Reporting.WinForms.ReportParameter();
  reportParameterCollection[1].Name = "Parameter2";
  reportParameterCollection[1].Values.Add("Param2Value");
  reportParameterCollection[2] = new Microsoft.Reporting.WinForms.ReportParameter();
  reportParameterCollection[2].Name = "Parameter3";
  reportParameterCollection[2].Values.Add("Param3Value");
  reportViewer1.ServerReport.SetParameters(reportParameterCollection);
 
  //render report
  string[] streamids;
  string mimeType, encoding, extension;
  string deviceInf = "8.5in11in";
  Microsoft.Reporting.WinForms.Warning[] warnings;
  byte[] bytes = reportViewer1.ServerReport.Render("PDF", deviceInf, out mimeType, out encoding, out extension, out streamids, out warnings);
 
  //write file and refresh reportviewer control
  string completefilename = FilePath +  "Report.pdf";
  FileStream fs = new FileStream(completefilename, FileMode.Create, FileAccess.Write);
  fs.Write(bytes, 0, bytes.Length);
  fs.Close();
  reportViewer1.RefreshReport();
}

So lets break this down into manageable chunks of code…

Line 3 simply defines the path to the folder where we would like to export the report

Lines 5 through 15 define and set three parameters for our report.  Obviously if your has more/less you can adjust accordingly.  Line 16 simply calls the setParameters function of our ReportViewer component and passes our newly generated parameters.

Lines 18 through 22 define and set a few variables that we need setup in order to render our report but the real magic happens on line 23 where we call the render function of our ReportViewer and store the PDF result in an array of bytes.

Lines 26 through 29 take our bytes array and utilize a FileStream object in order to write the information to a pdf file.

I’ve included a refresh command on Line 30 even though it isn’t needed for just rendering one report.  I wanted to place this in here just in case someone may be copying the code to achieve the same thing I was trying to achieve.  Basically I had all of this code within a loop – I was looping through various strings and running my target report multiple times, each time with different parameters – in order to do this you need to call the RefreshReport() method at the end of every run in order to allow the object to completely initialize.  I even went as far as to set the visibility of the ReportViewer object false as I simply just wanted to click a button and be left with a folder full of pdfs.  So, not needed for 1 run, but if you place the code into a loop its needed.

So in essence this is the code I’ve used.  It certainly is a time saver – we used to have someone manually changing parameters and dumping these reports to PDF which as you can imagine can take quite a long time if you need to do it a few hundred times – now, it’s simply an application that they run…

Happy coding.

Ravello on my wrist – Pebble in the cloud

You can probably get the gist as to what this post might be about by the title but it does leave a little to the imagination.  For those who hate waiting for the point go ahead an watch this small video…

Before I get right into what I’ve done let me first provide a little background information as to why I’ve done this aside from just looking for “something geeky to do”.

Ravello-Systems-LogoFirst up I’ve pretty much let everyone know how much I heart Ravello Systems .  Not to go too deep but as I build up labs and environments for this blog and for other interests I really like to break things.  Why?  That’s how I learn best, breaking things, fixing them, then writing them down.  The problem is I seem to always be rebuilding or fixing before I can move onto my next project.  Ravello solves that issue for me – with Ravello I’m able to keep multiple blueprints of completely configured vSphere labs (different versions, different hardware configs) in the cloud.  When I’m feeling geeky I can simply deploy one of these as an application to either Google or Amazon and away I go.  If I break it to the point of no return it’s no biggie, I can simply redeploy!  Point and case it’s a time-saver for me!

Secondly I love to write code – it’s an odd passion of mine but it’s something I actually went to school for and never 100% pursued.  Meaning I love to write code….casually!  I couldn’t imagine dedicating my whole career to it, but having the knowledge of how to do it casually sure has helped me with almost every position I’ve held.

pebbleThirdly a little while I ago I purchased a Pebble watch.  I’m still not sure why I wanted a smartwatch but I knew if I had one I’d want it to be somewhat “open” and Pebble met those needs.  Using a service called CloudPebble and by turning on the development mode on the iPhone app I’m able to deploy custom applications to my Pebble – so that was a big seller when I was looking at watches – oh, and the fact that it’s only like $100 helps as well…

So on to the problem – I mentioned I love Ravello and have multiple applications setup within the service.  The applications are great, however it takes a good amount of time after powering one on before you are able to start using it.  Those vSphere services need time to initialize and boot.  My usual routine involves me logging into Ravello and powering on what I might need for the night before I leave work.  That way the initialization can happen during my commute, supper with my family, and bedtime routines and is ready to go when I am.  There are times though when I get half way home and realize I forgot to power on my labs, or I’m not near a computer and can’t be bothered to use the small iPhone screen.

There’s an app for that!

PowerOnRavelloFor these reasons I decided to try and figure out the Ravello APIs and the Pebble SDK and see if it was possible to create a small application to simply login into Ravello, select an existing application, and power it on!  It sounds simple enough but took a lot of trial and error – I had no clue what I was doing but in the end I was left with the solution below – and it works so I guess you could call it a success.

Prerequisites

There’s a few pieces that need to fall into place before any of this will work.  First up you wiill need a CloudPebble account.  CloudPebble is a development environment that allows us to write applications for use on the Pebble watch in either JavaScript or C.  You can use an existing Pebble account to log into CloudPebble or simply setup a new account – either way you need one and it’s free!

devmodeSecondly you will need to enable developer connections within the Pebble app on your phone.  This is easlily done by selecting ‘Developer’ within the main menu and sliding the switcher over.  Honestly, it’s a phone app I’m sure you can figure it out.

Thirdly lets go ahead and setup a project within CloudPebble You can do this by simply importing mine, or manually by giving your new project a name and select PebbleJS as your Project Type.  Once created you should be at a screen similar to that shown below…

cloudpebble

As you can see we have one source file (app.js).  This is the only source file we will need for this project.  If you imported my project you are done for now, but if you created a new project manually this file will be full of a bunch of example code on how to perform various functions and respond to different events within the Pebble interface – we won’t need any of this so go ahead and delete all the code within the file, but not the file itself.  We will replace it with all of this syntax –  explained in the next section.

The code

If you simply just want all the code to go through on your own go head and get that here.  For the rest of us I’ll try and explain the different blocks of code below…

1
2
3
4
5
// import required libraries
var UI = require('ui');
var ajax = require('ajax');
var Vector2 = require('vector2');
var Vibe = require('ui/vibe');

Lines 1 through 5 simply deal with importing the libraries we will be working with – UI will give us access to the Pebble UI, Ajax is what we will use for the Ravello API calls, Vector2 for use with positioning on items on the watch, and Vibe is simply so we can access the vibration features of the watch.

7
8
9
// setup authentication information
var encodedLogin = "mybiglongencodedstring";
var expirationTimeInSeconds = 600; // timeout for app

Lines 8 and 9 set up a couple of variables for the application.  First up, encodedLogin represents a base64 encoded string of the username and password you use to login to Ravello, with a “:” between them.  You can grab this by heading to https://www.base64encode.org/ and grabbing the encoded string using UTF-8 as the output – just don’t forget to place the : between (ie. I encoded “mwpreston@myemail.com:supersecretpassword”).  Copy the result and place assign it to the encodedLogin variable on Line 8

Line 9 deals with our expiration time – When we power on an application within Ravello we need to specify an auto power off parameter which states how long we want before the application powers itself down.  You don’t want to use up all those valuable CPU hours right?  The variable defined on line 9 is matched to that, however in seconds so get your calculator out and come up with a number.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// main window
var splashWindow = new UI.Window();
var text = new UI.Text({
position: new Vector2(0,0),
size: new Vector2(144,168),
text: 'Logging into Ravello Sytems, please wait...',
color:'black',
textOverflow:'wrap',
textAlign:'center',
backgroundColor:'white' 
});
 
// Add to splashWindow and show
splashWindow.add(text);
splashWindow.show();

Lines 11 through 25 simply define the first splash window we will see in the application.  Kind of a message to show the user as we are making the API calls and gathering the application lists.  You can start to see some of the Pebble object functions and parameters here…

As we move into ajax calls starting on Line 28 we can start to see the URLs and API calls to Ravello and how they are formatted when using PebbleJS.  From here each API call that is sent to Ravello is nested within the previous – this was the only way I could get this to work.   You can go ahead and read the docs on the ajax function here – I still don’t really completely understand the values being returned but hey, it works!

Anyways, back to the task at hand – As shown below lines 28-30 makes are login request, passing basic authorization and our encodedLogin variable within the header.  After parsing the response on Line 34 we display yet another splash screen (Lines 35-44) with a success.

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//login to Ravello
ajax({ url: 'https://cloud.ravellosystems.com/api/v1/login',method: 'post',
headers: {Authorization: "Basic " + encodedlogin,
Accept: "application/json"}
},
function(data,status,obj) {
// success into Ravello
var contents = JSON.parse(data);
var text2 = new UI.Text({
position: new Vector2(0,0),
size: new Vector2(144,168),
text: 'Hello ' + contents.name + ', you are now logged in! - Fetching applications, please wait...',
color:'black',
textOverflow:'wrap',
textAlign:'center',
backgroundColor:'white' 
});
splashWindow.add(text2);

Another API call, this one to gather our application lists takes place on lines 46 and 47.  From there lines 51 through 74 build a menu to display the application listing, hide our previous screen, and display our newly formed menu.

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
ajax({ url: 'https://cloud.ravellosystems.com/api/v1/applications',method: 'get',
headers: {Accept: "application/json"}
},
function(data,status,obj) 
{
// success application list
var apps = JSON.parse(data); 
var count = Object.keys(apps).length;
var menuItems = [];
var appname;
var appid;
for(var i = 0; i < count; i++) {
appname = apps[i].name;
appid = apps[i].id;
menuItems.push({
title:appname,
subtitle:appid
});
}
// Construct Application menu to show to user
var resultsMenu = new UI.Menu({
sections: [{
title: 'My Applications',
items: menuItems
}]
}); 
// Show the Menu, hide the splash
resultsMenu.show();
splashWindow.hide();

At this point we are waiting on user interaction – the user needs to select the application they want powered on.  Line 76 defines that exact event listener, triggered once the user hits the select button.

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Add an action for SELECT
resultsMenu.on('select', function(e) {
console.log('Item number ' + e.itemIndex + ' was pressed!');
// this is where magic happens and we translate which item was pressed into turning on applications
var detailCard = new UI.Card
(
{title: "Starting Lab", subtitle: e.item.title }
);
detailCard.show();
detailCard.body('Setting lab power off time to ' + expirationTimeInSeconds.toString() + ' seconds...');
var ExpURL = 'https://cloud.ravellosystems.com/api/v1/applications/'+e.item.subtitle+'/setExpiration';
console.log(ExpURL);
// set expiration time for selected application
var expbody = { "expirationFromNowSeconds": + expirationTimeInSeconds };
ajax
(
{
url: ExpURL,type: "json",method: "post",headers: { Accept: "application/json" }, data: expbody
},
function(data,status,obj)
{
// success setting expiration time
detailCard.body('Setting lab power off time to ' + expirationTimeInSeconds.toString() + ' seconds...'+ 'DONE!\nPowering on lab...');
var StartURL = 'https://cloud.ravellosystems.com/api/v1/applications/'+e.item.subtitle+'/start';
ajax
(
{
url: StartURL,type: "json",method:"post",headers: {Accept: "application/json"}
},

Once an application is selected lines 78 through 84 display some status messages as to what is happening, and beginning on line 89 we start the API calls to power on the application.  First (Line 92) sets the expiration time for the selected application.  Then, line 102 sends the actual Power Up command to Ravello.

104
105
106
107
108
109
110
function(data,status,obj)
{
// success starting application
console.log("Success on start:" + status);
detailCard.body('Setting lab power off time to ' + expirationTimeInSeconds.toString() + ' seconds...'+ 'DONE!\nPowering on lab...' + 'DONE!\nLab Powered On' );
Vibe.vibrate('short');
},

Lines 108 and 109 simply display some success messages to the user and send a short vibrate command to the Pebble watch.

I’ve done my best to explain the code – it’s probably not the cleanest or best way to do all this but guess what?  I can power on a Ravello application from my watch so that’s all that matters…  Please feel free to steal all the code if you want it – or here is the complete CloudPebble project if you are in a hurry and just want to skip the copy/paste.  I’d love any feedback anyone may have on this.  For now this is where the project sits but I’d love to expand it further and integrate with more of the Ravello APIs available.  At the moment I’m happy with powering on my Ravello labs from my wrist!