Sunday, June 13, 2010

TeamCity (continuous integration) integration with lava lamps

I wanted to hook up some lavalamps to our CI server.

Shopping list:
2 lava lamps (one red and one green, Teknikmagasinet in Sweden, 199:- sek a piece)
1 usb controlled power outlet (Silver Shield Power Manager bought at Kjell och Company in Sweden, 449:- sek)

The usb controlled poweroutlet comes with a command line program. I wrote this groovy script to poll the rss feed for our projects on the TeamCity server. The script has an added power save feature that allows you to configure it to turn off the lamps at weekends, it also allows you to only run the lamps between certain times of the day, say 08:00-19:00.

Have fun!


File: CILampControl.groovy
----------------------------
/**
 * User: Jonas Ekstrand
 * Date: 2010-maj-27
 * Time: 14:43:22
 */
def config = new ConfigSlurper().parse(new File('lampcontrol.config').toURL())

def LampController lampControl = new LampController(config.executable,
        config.deviceName, config.greenSocketName, config.redSocketName)
def TeamCityBuildFeed teamCityFeed = new TeamCityBuildFeed(config.feedUrl);

enum STATE {
  BUILD_SUCCESSFUL, BUILD_FAILED, LIGHTS_OFF
}
STATE lastState
//noinspection GroovyInfiniteLoopStatement
while (true) {
  // Get state, first check if lights should be on or off
  STATE state = getState(teamCityFeed, config.operateHours, config.operateWeekends)
  // Operate lights
  //noinspection GroovyVariableNotAssigned
  if (state != lastState)
    updateLamps(state, lampControl)
  // Update last state
  lastState = state
  // Print state
  println """${Calendar.getInstance().getTime()} $state
    Operate weekends:$config.operateWeekends Operate hours:$config.operateHours"""
  // Sleep
  Thread.sleep config.secondsBetweenChecks * 1000
}

private def updateLamps(STATE state, LampController lampControl) {
  switch (state) {
    case STATE.LIGHTS_OFF: lampControl.lightsOff(); return;
    case STATE.BUILD_SUCCESSFUL: lampControl.greenOnRedOff(); return;
    case STATE.BUILD_FAILED: lampControl.redOnGreenOff(); return;
  }
}

private STATE getState(TeamCityBuildFeed teamCityCI1, String operateHours, boolean operateWeekends) {
  //Should not operate during weekends and it is weekend OR is out of operation hours
  if ((!operateWeekends && !isWeekday()) || !isOperationHours(operateHours))
    return STATE.LIGHTS_OFF
  //Is build ok or not
  return teamCityCI1.getBuildStatus() ? STATE.BUILD_SUCCESSFUL : STATE.BUILD_FAILED
}

boolean isWeekday() {
  int day = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
  return (day != Calendar.SUNDAY && day != Calendar.SATURDAY)
}

private boolean isOperationHours(String operateHours) {
  int hourNow = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
  def startAndStop = operateHours.split("-")
  int fromHour = startAndStop[0].toInteger()
  int toHour = startAndStop[1].toInteger()
  return hourNow >= fromHour && hourNow < toHour
}

class LampController {
  private String greenOnCmd, greenOffCmd, redOnCmd, redOffCmd

  public LampController(String executable, String deviceName,
                        String greenSocketName, String redSocketName) {
    greenOnCmd = "$executable -on -$deviceName -$greenSocketName"
    greenOffCmd = "$executable  -off -$deviceName -$greenSocketName"
    redOnCmd = "$executable  -on -$deviceName -$redSocketName"
    redOffCmd = "$executable  -off -$deviceName -$redSocketName"
  }

  def redOnGreenOff() {
    runCmd greenOffCmd
    runCmd redOnCmd
  }

  def greenOnRedOff() {
    runCmd greenOnCmd
    runCmd redOffCmd
  }

  def lightsOff() {
    runCmd redOffCmd
    runCmd greenOffCmd
  }

  private runCmd(String cmd) {
    Process process = cmd.execute()
    process.waitFor()
    process.destroy()
  }
}

class TeamCityBuildFeed {
  private String feedUrl;

  def TeamCityBuildFeed(feedUrl) {
    this.feedUrl = feedUrl;
  }

  def boolean getBuildStatus() {
    try {
      def feed = new XmlParser().parse(feedUrl)
      return feed.entry[0].'dc:creator'.text().equals("Successful Build")
    } catch (Exception e) {
      println "Could not get status from CI server $e"
      return false;
    }
  }
}
File: lampcontrol.config
----------------------------
/** How often (seconds) to check the for build state **/ secondsBetweenChecks=10 /** The url to the build server's rss feed for this project**/ feedUrl="http://SERVER_NAME/guestAuth/feed.html?projectId=PROJECT_ID&itemsType=builds&buildStatus=successful&buildStatus=failed&userKey=guest" /** If lights should be on during weekends **/ operateWeekends=false /** Between what hours should the lights be on. This settings assumes 24H clock. Use 0-24 for use round the clock **/ operateHours="8-19" /** Silver Shield Power Manager **/ executable="C:\\Program\\Gembird\\Power Manager\\pm.exe" deviceName="lava" greenSocketName="green" redSocketName="red"

2 comments:

Anonymous said...

Therefore, we must claim a reasonable price, because we realize that is both time consuming and expensive to launch a website. Therefore, most companies can not pay too much money for SEO services with this crazy economy. Keeping small businesses in mind, we have seen SEO services requires a relatively small investment, so that you can take pleasure in top search engine placement. We follow ethical and biological basis for all marketing activities and SEO, and the only objective is to get you results.The team of experts from our affordable SEO firm will enable your site to generate highly targeted keywords, so that people who are looking for topics that relate to your content can be found on the first click. We help make your site seem more important to search engines than any other by optimizing certain pages and off page elements on your site. And all this help is untaken at a great rate.You want the whole world of online search to find you, right? Our affordable SEO services will give your website the web page drop necessary for you to find for those looking for what you do and where they do it. Our expert SEO website offers affordable seo services. We know that your company is certified and it is important for you to find a partner that provides expert honest, ethical results.
Read this link for more information on San Diego SEO:http://www.desiuniverse.com/story.php?id=30668

Internet marketing investment through search engine marketing at a low cost is a capable endavor. It requires communication and commitment from both companies to san diego seo and site owner. If the San Diego san diego seo Company will not return calls or e-mail, and meet clear investment objectives, you should reconsider who is on your team. Most of all the right San Diego san diego seo Company can make you succeed! Other companies offer affordable search engine ranking, but not the best investment. Thewecoast.com is way better about such things.We offer the best Affordable san diego seo services and more accessible services, so that customers and potential customers find your site to Google, Yahoo or MSN without difficulty. san diego seo Solutions offered a very reasonable cost, the company reserves the right to hook you up.Our approach is to focus on organic san diego seo services, and the implementation of successful keywords. If you already have a design, we can work around it, and allows our expertise to ensure that the most key content is available to search engines to find access. Formatting of page content that is informative and combined with san diego seo.We are a company of san diego seo at affordable prices and we are eager to help small businesses struggling to get quality search engine exposure. Therefore, we must maintain a reasonable price, because we realize that is both time consuming and expensive to launch a website.

Anonymous said...

I would like to exchange links with your site www.blogger.com
Is this possible?