Huehuehue

For this week’s assignment, we had to make a web dashboard for controlling a Philips Hue bulb. I was pretty stretched for time this week so I decided to keep things simple and learn the basics. Going through the tutorial was pretty self-explanatory and the code on github was pretty logical. However, I tripped up with the call-backs and it was quite confusing for me to understand. Thankfully, I read through Timothy and Atharva’s blog and their call-backs made sense to me. I created a basic UI where the Hue can be controlled by changing it’s Hue, Saturation and Brightness values through sliders and also gave the users the option to turn it on and off. I was also changing the background of the webpage to match the color of the Hue bulb.

Screenshot 2019-02-12 04.26.39.png


I was looking at changing the color of the text to a complementary color based on the currently selected value but did not find any easy way to convert HSB values to its complementary colors. Also, I had thought of an ambient mode where the digits of HH:MM:SS are converted into a RGB hex value which is then transmitted to the hue. Again, I tripped up because I could not find a reliable way to do this. Passing RGB to HSL did not match the colors. So my top questions for this week would be:

1) How do you calculate the complementary HSB value of a color through code?

2) How do you convert a rgb color to a HSB color?

Currently listening: A whiter shade of pale - Procol Harum

/* 
References used: 
https://www.thatworkedyesterday.com/blog/2019/2/12/connected-devices-web-interface-for-hue

https://github.com/tigoe/hue-control/blob/master/client-example/public/single-lamp.js

*/

//IP address of Philips Hue
let IPHub = '128.122.151.172';
let userName = 'g12MalhwYs2DUmfQhW-GYJEzwYsV3mYxiKJLXuxb'; // My user name as per the hue developer API
let url;

//Font
let gotham;

//Variables for display of controls and labels
let checkBox;
let hueSlide;
let hueText;
let satSlide;
let satText;
let brightSlide;
let brightText;

//Variables for controlling the philips bulb and its color
let lightNum = 1;
let hueVal = 32767;
let satVal = 127;
let brightVal = 127;

//Loading fonts
function preload() {
  gotham = loadFont('assets/Gotham Book.otf');
}

function setup() {

  //Create canvas
  canvas = createCanvas(windowWidth, windowHeight);
  canvas.background(hueVal, satVal, brightVal);

  //Declare Hue URL
  url = "http://" + IPHub + "/api" + userName;

  //Position ON/OFF checkbox
  checkBox = createCheckbox(' IS ON/OFF', false);
  checkBox.position(canvas.width / 2 - 90, 200);
  checkBox.class('lightSwitch');
  checkBox.mouseClicked(toggleLight);

  //Position Sliders for color control
  hueSlide = createSlider(0, 65535, 32767, 100);
  hueSlide.position(canvas.width / 2 - 225, 400);
  hueSlide.style('rotate', 90);

  satSlide = createSlider(0, 254, 127, 1);
  satSlide.position(canvas.width / 2 - 100, 400);
  satSlide.style('rotate', 90);

  brightSlide = createSlider(1, 255, 127, 1);
  brightSlide.position(canvas.width / 2 + 25, 400);
  brightSlide.style('rotate', 90);

  //Position button for 'Ambient Mode'
  button = createButton('Ambient mode');
  button.position(canvas.width / 2 - 85, 600);
  button.mousePressed(changeBG);

}

function draw() {

  colorMode(HSB);

  if (hueSlide.value() != hueVal || satSlide.value() != satVal || brightSlide.value() != brightVal) {

    //Change color
    changeLightColour();

    //Capture slider value
    hueVal = hueSlide.value();
    satVal = satSlide.value();
    brightVal = brightSlide.value();

    //Change background
    colorMode(HSB, 65535, 254, 255);
    background(65535 - hueVal, 254 - satVal, 255 - brightVal);

    //Display text
    textFont(gotham);
    textSize(width / 15);
    textAlign(CENTER, CENTER);
    text('Huehuehue', width / 2, 100);

    hueText = textSize(width / 60);
    hueText.text('Hue', canvas.width / 2 - 160, 500);

    satText = textSize(width / 60);
    satText.text('Sat', canvas.width / 2 - 35, 500);

    brightText = textSize(width / 60);
    brightText.text('Brightness', canvas.width / 2 + 100, 500);

  }
}

function toggleLight() {

  let path = url + '/lights'
  httpDo(path, 'GET', toggleGetResponse);

}

function toggleGetResponse(getData) {

  let lights = JSON.parse(getData);
  lightState = lights["1"].state.on

  let body = {
    'on': !lightState
  };
  let path = url + '/lights/' + lightNum + '/state/'
  httpDo(path, 'PUT', body, togglePutData);

}

function togglePutData(putData) {

  var response = JSON.stringify(putData);
  if (response.includes("success")) {
    lightState = !lightState
  }
}

function changeLightColour() {
  var path = url + '/lights/' + lightNum + '/state';
  var body = {
    'bri': 255 - brightSlide.value(),
    'sat': 254 - satSlide.value(),
    'hue': 65535 - hueSlide.value()
  };
  var path = url + '/lights/' + lightNum + '/state/'
  httpDo(path, 'PUT', body, changeColourResponse);
}

function changeColourResponse() {
  console.log('Colors changed!');
}

function changeBG() {
  let hr = hour();
  let mn = minute();
  let sc = second();

}

Disobedient electronics

The theme for our second assignment was to create an object that exemplifies the ethos of disobedient electronics. I teamed up with Winnie Yoe and in our first discussion, we decided to make a few learning objectives for ourselves. Our initial list was: 1) Learn how to use ESP32 2) Learn how to fetch and display real time data 3) Use data to work with a mundane regular object that we see day to day.

Initially, we looked at the NYC open data sets and we found some interesting data around maternal health, mental health and the drug crisis. We were interested to use the data set for the opioid crisis but we realised that none of the datasets we had was not real-time and had no granularity beyond a district zone. Working with such large data-sets was proving to be challenging and we gave up on the approach.

During the discussion, we started talking about how mundane objects are basically fronts for corporations inside our homes in the name of ‘Smartness‘. That struck a chord and we refined the idea into a simple ‘smart‘bulb that is free to use but it won’t light up if the latest stock market price of the company was lower than the previous day. Going through stock market prices api, we found one which was easy to use but only gave daily stock prices. We wanted one which was hourly but in the interest of time, we went ahead with the one we found to build the proof of concept. We used the ESP32 HUZZAH to control the light bulb.

The final interaction was as follows: The bulb lights up if it detects the presence of the user and then checks for the stock price of the company (*cough* Facebook *cough*) and if the price of the company was lower, it starts blinking annoyingly. The user then has to mash the ‘like‘ button which leaves gratuitous comments on social media (not prototyped) and the bulb is ready for use again. You can watch the interaction in the video below.

I was quite happy about getting the APIs to work with the chip. I realise that there are conceptual gaps in our prototype but a lot of it was pared down in the interest of time. I believe that there is enough depth in the concept to take it further and I would like to see if I can do the same project in a more refined manner later.

A piece of velvet

I grew up in a small city in India. It was hot, dry and utterly boring in a way that only small cities in 80’s India can be. I was born premature which made me pretty sick through my early years and having no brothers and sisters, I was pretty much in my own head. And a bursting imagination often needs outlets and for me, in came in the form of playing with wooden toys. My family did not have a lot of money, so LEGOs, action figures and toys were out. But as a child, who cared? A few blocks of wood, plastic and boxes and you got a castle going! And in 80’s India, no one around me had any expensive, manufactured toys. So, it wasn’t as if I felt the need to have something that wasn’t being given to me. I was pretty happy in my own head until I saw an advertisement for a GI Joe.

 

GI Joes were probably the first thing I ever wanted. I was entranced and I remember throwing tantrums for having them. My parents couldn’t really afford them so they would try to keep me away but being a male child in India comes with doting grandparents and uncles who would try and cater to my whims. My frustrated parents couldn’t really say anything and in a few years, I had a collection of about 50 of them.

 

But this is not the story of the GI Joes.

 

One summer, while spending the summer vacation at my maternal grandmothers place, I came upon a box which had a small piece of velvet, 2 tiny pillows and a small piece of wood. The velvet was bedraggled with aluminum milk bottle caps stuck on it, the pillows were made out of cloth and the piece of wood, was well, a piece of wood. When I asked my grandmother about it, she told me about how that was a bed for my mother’s doll. My family is one that was torn apart from the partition of India and both my grandfathers had to leave everything they knew behind to start from scratch. So, we never had a lot of money and buying a doll was impossible. But that didn’t stop my grandmother and mother. They made dolls from whatever material they could find, built a bed, a blanket and pillows. My mom grew up playing with a stuffed piece of cloth and treasured it long after she had outgrown them. On that summer afternoon, it all came rushing to me about how entitled was I to ask for an expensive piece of plastic which was way above our means but my parents still tried to do the best they could. I felt the insides of my stomach churn and I had no way to understand what I was feeling as a child but that feeling created a sense of gratitude for them trying to do the best for me in whatever way they could. The little piece of velvet became a part of my GI Joe collection. After a long, hard day of fighting, they all were put to sleep under my mom’s velvet blanket. After all, warriors need to sleep. I often wonder what they dreamt of? What would people who fought all day dream of? Do they dream of peaceful times or more war? And under the glittering, shiny blanket, would they be happy? I did not know but it was fun to imagine that.

 

GI Joes unleashed my imagination. Simulation video games and construction kits later shaped my intellect, thinking and unleashed my ability to make. But my mother’s piece of velvet taught my gratitude, kindness and softness. And for that, I am grateful. Growing up as a man in India, you have a lot of hard edges as a patriarchal, masculine society shapes you to be. But a piece of cloth can round you and round you out like stones in a river. Who could have guessed?

Week 1: Just another basic server.

For this week’s assignment, we were asked to create a simple http server using node.js and express. Both these terms were completely new to me and I decided to keep my ambitions in check and build something that works instead of the glorious failures of ICM and P.Comp in the semester past.

For starters, I familiarized myself with node and express with Dan Shiffman’s videos. (Link)

The ‘Programming A to Z’ website also has some great explanations on working with node.js and express (Link)

For my assignment, a combination of hanging out with small bots in ‘Hacking smart toys for AI learning‘ and listening to Leonard Nimoy narrating Ray Bradbury’s ‘There will come soft rains‘, I decided to make a web server to control a bot in the following ways:

  • Make the robot move ahead. (/forward)

  • Make the robot move behind. (/back)

  • Make the robot turn left or right. (/turn/[:left or :right])

  • Make the robot dance. (/happydance)

The code was pretty uneventful except the part of constantly having to turn the server on and off. Another part which tripped me over was that home I was encountering an error when I was trying “My network IP“ :8080 instead of localhost:8080. It works like a charm inside ITP though. Maybe, it was happening because I was on a hotspot but I had no idea to rectify it. I would like to know more about how to identify and rectify such network issues.

/* References used4-line server example from Tom Igoe's class:

https://github.com/tigoe/NodeExamples/blob/master/FourLineServer/server.jsDan Shiffman's videos from coding train:

https://www.youtube.com/watch?v=P-Upi9TMrBk&list=PLRqwX-V7Uu6Yyn-fBtGHfN0_xCtBwUkBp*/

//Include express

let express = require('express');

//Create a server

let server = express();

//Serve static files from public

server.use('/', express.static('pages'));

//GET parameters

server.get('/turn/:direction', turnBabyTurn);

server.get('/forward', moveForward);

server.get('/back', moveBack);

server.get('/happydance', happyDance);

//Start the server

server.listen(8080);

//Functions to send response to GET requests

//robot turn

function turnBabyTurn(request, response) {    

let newTurnState = request.params.direction;    

if (newTurnState == 'left') {        

response.send('The robot makes a sharp turn to the ' + newTurnState);} 

else if (newTurnState == 'right') {        

response.send('The robot makes a sharp turn to the ' + newTurnState);} 

else {       

 response.send('Something went terribly wrong. Bots are stupid like that. try left or right?');}    

response.end();}//Move back

function moveBack(request, response) {    

response.send('The bot retreats back not knowing what’s lies behind it.');    

response.end();}

//Move forward

function moveForward(request, response) {   

response.send('The bot whirrs forward towards an indeterminate future.');    

response.end();}

//Dance

function happyDance(request, response) {    

response.send('The bot spins on its own axis silent and alone.');    

response.end();}


Currently listening: Keep Talking-Pink Floyd

Apology as a Service (AAAS)

For our first assignment for critical objects, I teamed up Winnie Yoe to work on a critical object. The shop was shut for the week and we started talking about how we should write an apology for not doing the assignment. This led us to a further discussion of how apologies are manufactured and it’s as if they are a formula.

We went down the rabbit-hole of digging up apologies from Kevin Spacey to facebook to Uber and many others and we came up with the formula as follows:

[Inspirational title] → [Demonstrate passion] → [Play the Victim] → [Feign innocence of events] → [Cautiously appreciate the victims] → [Ask for time]→ [Recognise role of company without any direct acceptance of wrong-doing]→ [Promise indeterminate actions in the future]→ [Promise that it won’t happen again]→ [salutations]→ [Actual signature].

While analysing the responses, we are realised that the formula also caters to institutional anxieties and are about protecting the organisation rather than the aggrieved ones. We came up with the idea of a service for CEOs in the future which is a voice driven interface for generating apologies. We name it Bernays after Edward Bernays, the father of modern PR quite extensively documented in The century of the self.

The hypothetical device sits on the desk of the CEO and talks to him/her about the current issue and uses advanced AI to understand the situation. It asks the CEO for ‘uncomputable‘ information which helps it create a more nuanced approach to a situation and generates an apology and a strategy for handling the situation.

You can scroll through the UI below. A sister post on the project can be found here.