Light is the foundation of our virtual and physical world, the very beginning of materiality. It gives birth to all the objects, visually and physically. It lights up the space, brings out all the characteristics of the physical world around us. Also it’s an objective reminiscent of time. In my projects, I would take the light as an instrument to explore the tension and cohesion between virtual reality and physicality.
In this document I create built a webpage in which people can use their body elements/movements or by pressing a key on the computer keyboard to trigger a light effect in ITP floor. The light effect can be a single light doing waving or blinking effect, or all the light together doing a spatial hue wave. The input to control these lights can be body movement signals translated by machine learning platform, or time API to make the lights synchronized to the outside skylight hue, also there are several compiled light effect there. In the future, I hope this remote control project could become an intrument to stretch the connection between specific people and space. Another dimension of this project is to make a light system which is more intuitive to play with also help people to make creative light performance more easily, which means a platform can endure some randomness of the its operator. Here is the how it looks like.
Here is my code. Somethings don’t work in this embedded version. The fundamental structure comes from Hue Control by Tom Igoe. The hardware and network system are also built by him.
I went through several technical difficulties which I think it’s helpful to mention and compare notes with other beginners like me:
Compile several JavaScript files into one html file.
Because I want to use keyboard to control the remote light system, create a main JavaScript file to do all the controls. The main input web event is to listen if a specific key is pressed. Also I want to visualize what is happening there in the remote light system. So I want to get the live status of the lights. Then I encountered the problem about light API which I will mention later. Finally I decided to use another sketch to visualize the changes just by doing synchronous visualizations with the PUT command when a specific key is pressed.
Then I began to make this visualization sketch. The first problem is how to refer to more than one sketch in one html file. Because I want an easy loop function so I used p5.js library. Then it brings me the problem that it would make errors if I have somethings in draw function in these two sketches. I found that if one have setup and draw the other only has setup then it won’t cause the problem. But I have to use draw function in both sketches.
Finally, I learnt what I should do is to use instance mode for one sketch, and what this mode do is to make this sketch looks like a function or a class or something can be the child of the first sketch. Here is the instance mode example in p5.js, which I think it’s very helpful to look into.
Even by doing this, I found that the two sketches are still competing with each other when they all listen to the keyPress event. Only one of them can win and run the event triggered by this key. I don't know if it has something to do with I tried to reach light API at the same time but I would say the one who always lose it the p5 sketch other than the rather plain javascript sketch.
When several scripts, web elements come together, how to organize them?
In this process I always make mistakes and mess up my webpage, so I will talk through all the terrible things I have made and how I solve them.
Canvas: if you actually use draw function to draw some graphics on it, where would this canvas be in your webpage? You can position it by giving names to all elements and set their relative position in your scripts. The function can help you to do that is:
var parentElt = select(‘.theclassyouwantittobeparent’) or var parentElt = select(‘.theidyouwantittobeparent’)
Then say myCanvas.parent(parentElt) can put your canvas in its parent element, which is always a div you create in your html file. Then you can further position relatively by using the parentElt.width and parentElt.height.
You can also do that to your buttons, sliders and other elements. For example, you can create a call back function for one button by select('#buttonName').mousePressed(callback function);
Or you can get an element the change its properties in scripts to make it interactive. For example, you can change the color of a web element with the brightness of the light by document.getElementById(“circle").style.backgroundColor= color-value mapped from brightness value.
About light API
This project use the Phillips Hue Light API, and after get to know it step by step I still have several questions in my mind.
The first one is after I load the webpage, can I still get light API for several times? I assume the answer should be yes. But if I tried to do GET twice it would come lots of errors. I also tried to make GET request as a callback function in setLight, which is a function doing PUT updated light status into the system. I guess there might be two reasons for the error: one is I do GET too frequently, the other is I make GET request as a callback after I do PUT request and the interval between these two is too short.
Since I don't know how to use GET to get live light status, I tried to read it from the returns of PUT request. It looks like {“success”:{/light/16/status/bri:160}} or {“error”:{/light/16/error description}}. At the beginning I don't know how can I read the things inside the curly braces after “success”:. Then I found that it’s still a JSON object and I can get the by select theReturnValue.success, and I was a little surprised at “success” is also a tag in this JSON object. What I got is /light/16/status/bri:160. Then I fail to take the things I want out of from many layers of slashes. Maybe after I know more about JavaScripts I can translate that to string and deconstruct it.
This afternoon, I have office hour with Tom and sort of solve this problem. I am sorry for didn’t get all about it, but I’d like to show what I have got here. That’s how to deconstruct the return value of PUT request. Here is the code he ran in the broswer console page to get the things in this JSON object. It used split and substring function in JavaScript to get the value I’m waiting for. It’s really amazing.
var foo = {"success":{"/lights/2/state/on":true}};
foo
{success: {…}}success: {/lights/2/state/on: true}__proto__: Object
foo.success
{/lights/2/state/on: true}
foo.success./lights/2/state/on
Uncaught SyntaxError: Unexpected token '/'
foo.success."/lights/2/state/on"
Uncaught SyntaxError: Unexpected string
var fie = "{/lights/2/state/on}"
fieBits = fie.split('/');
(5) ["{", "lights", "2", "state", "on}"]
fie.substring(1, fie.length-1);
"/lights/2/state/on"
fie.substring(1, fie.length-1).split('/');
(5) ["", "lights", "2", "state", "on"]
fie.substring(2, fie.length-1).split('/');
(4) ["lights", "2", "state", "on"]
Another work I’d like to share with you is a beautiful light fixture I made. Check it out!
Another sketchy demo I want to show is that on phone screen people could do AR to his own light environment. For example if it’s a cloudy day, people can bring the sunlight into their reality through this AR tool. It might be very subtle change in their environment but add another vitual but realistic layer to that. Here in this demo I do in a very simple way by adding a brightness matte, but what ideally I’d like to bring in is a live natural sunlight which can interact with our real environment by reflections and refractions.