Skip to content

Instantly share code, notes, and snippets.

@Cheesebaron
Last active February 12, 2019 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cheesebaron/a302d267e8f20eabee6c1123c96e8899 to your computer and use it in GitHub Desktop.
Save Cheesebaron/a302d267e8f20eabee6c1123c96e8899 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Linq;
namespace dk.ostebaronen
{
public static class DevOpsStatus
{
private const string Pat = "your-azure-devops-pat";
private static HttpClient _httpClient;
[FunctionName("DevOpsStatus")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var lastBuild = await GetLatestBuild().ConfigureAwait(false);
if (lastBuild == null)
{
return new NotFoundObjectResult("No build found");
}
foreach(var build in lastBuild)
{
log.LogInformation($"{build.BuildNumber}: {build.Status} - {build.Result} - {build.Url}");
}
var anyFailed = lastBuild.Any(b => b.Status?.ToLowerInvariant() == "failed");
var anyRunning = lastBuild.Any(b => b.Result.ToLowerInvariant() == "inprogress");
var allFinished = lastBuild.All(b => b.Result.ToLowerInvariant() == "succeeded" && b.Status?.ToLowerInvariant() == "completed");
if (anyFailed)
return new OkObjectResult("failed");
if (anyRunning)
return new OkObjectResult("running");
if (allFinished)
return new OkObjectResult("finished");
return new OkObjectResult("unknown");
}
private static HttpClient EnsureHttpClient()
{
if (_httpClient == null)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Authorization
= new AuthenticationHeaderValue(
"Basic", Pat);
_httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Cheesebulb", "1.0"));
}
return _httpClient;
}
private static async Task<IEnumerable<Build>> GetLatestBuild(int top = 4)
{
var client = EnsureHttpClient();
var organization = "your-azure-devops-org";
var project = "your-project-id";
var url = $"https://dev.azure.com/{organization}/{project}/_apis/build/builds?$top={top}&api-version=5.0";
var response = await client.GetAsync(url).ConfigureAwait(false);
using (response)
{
if (response.IsSuccessStatusCode)
{
var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using (responseStream)
using (var streamReader = new StreamReader(responseStream))
using (var jsonReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
var results = serializer.Deserialize<Welcome>(jsonReader);
return results.Builds.Take(4);
}
}
}
return null;
}
}
public class Welcome
{
[JsonProperty("count")]
public long Count { get; set; }
[JsonProperty("value")]
public Build[] Builds { get; set; }
}
public class Build
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("buildNumber")]
public string BuildNumber { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("result")]
public string Result { get; set; }
[JsonProperty("queueTime")]
public DateTimeOffset QueueTime { get; set; }
[JsonProperty("startTime")]
public DateTimeOffset StartTime { get; set; }
[JsonProperty("finishTime")]
public DateTimeOffset FinishTime { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
}
}
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <NeoPixelBus.h>
const char* ssid = "your-wifi-ssid";
const char* password = "hunter42";
const unsigned long HTTP_TIMEOUT = 10000;
const char* host = "yourfunction.azurewebsites.net";
const char* request = "/api/YourFunctionName?code=code";
const int httpsPort = 443;
const uint8_t PixelCount = 9;
const uint8_t PixelPin = 0; // doesn't matter what you put here
NeoPixelBus<NeoGrbFeature, NeoEsp8266Dma800KbpsMethod> strip(PixelCount, PixelPin);
RgbColor off(0, 0, 0);
RgbColor red(255, 0, 0);
RgbColor green(0, 255, 0);
RgbColor blue(0, 0, 255);
RgbColor yellow(255, 255, 0);
RgbColor teal(0, 255, 255);
RgbColor purple(255, 0, 255);
RgbColor orange(255, 153, 0);
void setAllLedsColor(RgbColor color)
{
for(uint8_t i = 0; i < PixelCount; i++) {
strip.SetPixelColor(i, color);
}
strip.Show();
}
bool initializeWifi() {
if (WiFi.status() == WL_CONNECTED)
{
Serial.println("WiFi already connected");
return true;
}
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
for(uint8_t i = 0; i < 100; i++) {
if (WiFi.status() != WL_CONNECTED) {
// blink the leds while connecting to WiFi
setAllLedsColor(off);
delay(400);
setAllLedsColor(purple);
Serial.print(".");
delay(400);
}
}
if (WiFi.status() == WL_CONNECTED) {
setAllLedsColor(orange);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address ");
Serial.println(WiFi.localIP());
return true;
}
setAllLedsColor(off);
WiFi.disconnect();
return false;
}
void setup() {
Serial.begin(115200);
strip.Begin();
strip.Show();
setAllLedsColor(off);
initializeWifi();
}
WiFiClientSecure client;
bool connect() {
Serial.print("connecting to ");
Serial.println(host);
bool ok = client.connect(host, httpsPort);
Serial.println(ok ? "Connected Http" : "Connection Http Failed!");
return ok;
}
void disconnect() {
Serial.println("Disconnect Http");
client.stop();
}
void sendRequest() {
client.print("GET ");
client.print(request);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(host);
client.println("User-Agent: Cheesebulb/1.0");
client.println("Connection: close");
client.println();
}
void skipHeaders() {
while (client.connected()) {
String line = client.readStringUntil('\n');
if (line == "\r") {
Serial.println("headers received");
break;
}
}
}
String lastStatus;
void readResponseContent() {
String status = client.readStringUntil('\n');
Serial.println(status);
if (status == lastStatus) {
// no need to do anything
return;
}
if (status == "failed") {
setAllLedsColor(red);
}
else if (status == "running") {
setAllLedsColor(blue);
}
else if (status == "finished") {
setAllLedsColor(green);
}
else {
setAllLedsColor(yellow);
}
}
void getBuildStatus()
{
if (connect()) {
sendRequest();
skipHeaders();
readResponseContent();
}
disconnect();
}
uint8_t reconnects = 0;
void loop() {
if (initializeWifi()) {
getBuildStatus();
reconnects = 0;
delay(60000);
}
else {
lastStatus = "derp";
reconnects = reconnects + 1;
if (reconnects == 120) { // 10 minutes
ESP.reset();
}
// delay a bit and retry wifi
delay(5000);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment