Build Status Monitor

Finally got my Raspberry Pi zero from Pimoroni. Was super happy it only took 2 days to be delivered :)
The question of course to follow was: what the hell to do with the thing, I really want to spare it from becoming another media player... so build status monitor it would be :)

The idea is to hook it up to a build service like hudson, jenkins go-cd etc... by connecting to a rest api when the build breaks this should trigger a light to flash, just enough to irritate us developers into fixing stuff pronto:)

So... to turn the light on hit the URL http://192.168.43.6:8083/alertBuildUnstable (obviously change the ip to reflect your pi's IP. To turn off hit the URL http://192.168.43.6:8083/alertBuildStable, easy peasy.

below is the code for the GOlang service, I used a library from https://github.com/stianeikeland/go-rpio works pretty well :)




the circuit is simple - the gpio 10 from the pi connects to the dc side of a solid state relay to turn on a 220v led (downlight) on the AC side. there's also a wifi adapter connected to the pi to make coms a little simpler

here's some images with the light on and then the light off



The Basic plan ... 



: here's the go code, also made use of some channel magic


       
package main

import(

  "fmt"
 "log"
 "net/http"
 "encoding/json"
 "github.com/stianeikeland/go-rpio"
        "os"
        "time"
)

var buildStable bool = true
var alerting bool = false
var (
        // Use mcu pin 10, corresponds to physical pin 19 on the pi
        pin = rpio.Pin(10)
)

func main() {

  buildch := make(chan bool)
 
 // Open and map memory to access gpio, check for errors
        if err := rpio.Open(); err != nil {
                fmt.Println(err)
                os.Exit(1)
        }

        // Unmap gpio memory when done
        defer rpio.Close()

        // Set pin to output mode
        pin.Output()

   //lets just send a signal to show that the service is up
        pin.High()
        time.Sleep(time.Second / 2)
        pin.Low()
        time.Sleep(time.Second / 2)
        pin.High()
        time.Sleep(time.Second / 2)
        pin.Low()

  
 http.HandleFunc("/alertBuildUnstable", func(w http.ResponseWriter, r *http.Request) {
 
  handleBuildError(w, buildch)
 }) 

  http.HandleFunc("/alertBuildStable", func(w http.ResponseWriter, r *http.Request) {
 
  handleBuildStable(w, buildch)
 }) 


  
 log.Fatal(http.ListenAndServe(":8083", nil))
}

func handleBuildError(w http.ResponseWriter, buildch chan bool) {

  mapResponse, _ := json.Marshal("unstable")

  fmt.Fprintf(w, "%q", string(mapResponse))
 
 time.Sleep(time.Second)

  buildStable = false
 if alerting == false {
  alerting = true
  go toggleBuildAlert(buildch)
 }

}

func toggleBuildAlert(buildch chan bool){  
 var buildStable bool = false
 for buildStable  == false { 
  pin.Toggle()
                time.Sleep(time.Second)
  // use select for non blocking operation
      select {
      case buildStable =
   fmt.Println("build stable? : ", buildStable)
      default:
   fmt.Println("build unstable!")
      }
 }
}

func handleBuildStable(w http.ResponseWriter, buildch chan bool) {

  mapResponse, _ := json.Marshal("stable")
 time.Sleep(time.Second) 
 fmt.Fprintf(w, "%q", string(mapResponse))
 if buildStable == false {
  buildch
  pin.Low()
  buildStable = true
  alerting = false
 }
}
       
 
Share on Google Plus

About J@$E

Developer of stuffs ...
    Blogger Comment

0 comments:

Post a Comment