├── README.md ├── examples ├── A-example-helloWorld.html ├── B-example-subscribeOrientation.html ├── C-example-all-sensors.html ├── D-example-p5-1.html ├── E-example-p5-2.html ├── F-example-hardware.html ├── README.md └── stylesheet.css └── lib ├── tramontana.js ├── tramontana_min.js └── utils.js /README.md: -------------------------------------------------------------------------------- 1 | Tramontana web library 2 | ===================================== 3 | 4 | 5 | Introduction 6 | ------------ 7 | 8 | A prototyping kit for iOS. 9 |
10 | 11 |
12 | Tramonatana is a platform intended as a tool for designers and creatives to use iPhones and iPads as sensors or actuators and create quick prototypes of interactive apps, spaces and objects. 13 | 14 | With this web library you can control from a desktop sketch your phone and you can use it as a sensor or actuator with little effort. You can download the app for iOS, Android, macOS following the links listed on [www.tramontana.xyz](https://tramontana.xyz/downloads). 15 | 16 | Getting started 17 | ------------ 18 | 19 | HTML 20 | 21 | ~~~~ 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | ~~~~ 42 | 43 | 44 | You can find the IP Address to give as argument in the landing view on your Tramontana App:
45 | 46 | 47 | 48 | Device as actuator 49 | ------------ 50 | Your device can act as an actuator with:
51 | - vibration;
52 | - screen color and brightness;
53 | - flash light;
54 | - displaying a picture or playing audio and video;
55 | 56 | To trigger your device you can invoke any of the following methods: 57 | 58 | ```Javascript 59 | setFlashLight(intensity); 60 | pulseFlashLight(numberOfPulses, duration , intensity); 61 | 62 | makeVibrate(); 63 | setColor(r,g,b,a);//where a is not alpha but screen intensity 64 | transitionColors(color1, color2, duration); 65 | showImage(url); 66 | ``` 67 | 68 | Device as sensor 69 | ------------ 70 | It's possible to access the device sensors like:
71 | - orientation;
72 | - magnetometer;
73 | - accelerometer;
74 | - distance sensor;
75 | - audio jack;
76 | - changes in power source;
77 | - touch events;
78 | 79 | The logic with which you can access all the above uses an observer pattern logic. You need to __subscribe__ to sensors and provide a callback function. For example: 80 | 81 | ```Javascript 82 | subscribeOrientation(function(ipAddress,orientation){ 83 | /*...code...*/ 84 | }); 85 | ``` 86 | 87 | The callback function is optional for all the subscribe methods and alternatively you can register to jQuery events: 88 | 89 | ```Javascript 90 | $(document).on("orientationChanged",function(ip,e){ 91 | console.log("triggered",e); 92 | }) 93 | ``` 94 | 95 | These are all the methods you can subscribe to: 96 | 97 | ```Javascript 98 | subscribeOrientation(callback); 99 | subscribeMagnetometer(callback); 100 | 101 | /*where frequency determine the frequency in Hz of accelerometer data broadcasting from the device. The lower the frequency the more sporadic the updates. */ 102 | subscribeAttitude(frequency,callback); 103 | subscrubeDistance(callback); 104 | subscribeAudioJack(callback); 105 | subscribePowerSource(callback); 106 | subscribeTouch(callback); 107 | ``` 108 | 109 | Playing media remotely 110 | ------------ 111 | It's possible to play video, audio and display an image remotely. The supported formats are: 112 |
_images_ 113 | JPEG, PNG 114 |
_video_ H.264 MP4 (more info [here](http://www.apple.com/uk/iphone/compare/)) 115 |
_audio_ AAC, MP3 116 | 117 | ```Javascript 118 | playVideo(url,callback);//the callback is called when the video ends 119 | playVideo(url); 120 | playAudio(url); 121 | setBrightness(brightness); 122 | ``` 123 | 124 | Using the camera 125 | ------------ 126 | Tramontana allows you to use the camera remotely and optionally upload the picture to Dropbox. To use the Dropbox feature the only thing you need to do is connecting your dropbox account from the App's landing page.

127 | The method to take a picture can have 2 optional parameters, the first one for the camera number
__0 = back camera__ (default)
__1 = front camera__ 128 | 129 | 130 | The second allows you to display the standard iOS camera view. __true = interface__
__false = background shooting__ (default) 131 | 132 | 133 | ```Javascript 134 | takePicture() 135 | takePicture(camera) 136 | takePicture(camera,ui) 137 | 138 | ``` 139 | 140 | 141 | 142 | 143 | Dependencies 144 | ------------ 145 | [jQuery](https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js) 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /examples/A-example-helloWorld.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

To get started download the Tramontana App on your iOS device from here.

21 |

22 | 1. Insert the IP Address of your device and press start. 23 |

24 |

25 | 2. Press change color to change the color of the screen of your device. 26 |

27 | 28 |
29 |
30 |
31 |
32 |
33 |

34 | 35 | 36 |
37 | 38 | 39 | 40 | 42 |

43 | 44 | 45 | -------------------------------------------------------------------------------- /examples/B-example-subscribeOrientation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |
20 |

To get started download the Tramontana App on your iOS device from here.

21 |
22 |

23 | 1. Insert the IP Address. 24 |

25 |

26 | 2. Press the button to open the connection and listen to orientation changes. 27 |

28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 |
41 | 42 | 43 |
Orientation:unknown
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /examples/C-example-all-sensors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 21 | 30 | 31 | 32 | 33 |
34 |

To get started download the tramontana App on your iOS device from here.

35 |
36 |

37 | 1. Insert the IP Address and press start.

38 | 39 | 40 | 41 |
45 |

46 |

47 | 2. After you have initialized tramontana you can subscribe or unsubscribe to the following sensors: 48 |

49 | 50 | 51 | 52 | 55 |
56 |

Orientation

57 |

Note: check that your phone is not orientation locked.

58 | 61 | 62 | 63 |
Orientation:unknown
64 |
65 | 66 | 69 |
70 |

Distance

71 | 72 | 82 | 83 | 84 |
85 |
86 | 89 |
90 |

Audio Jack

91 | 92 | 98 | 99 | 100 |
Audio Jack:unknown
101 |
102 | 105 |
106 |

Attitude

107 | 108 | 114 | 115 | 116 |
Attitude
117 | yaw:unknown
118 | pitch:unknown
119 | roll:unknown
120 |
121 | 124 |
125 |

Power Source

126 | 127 | 131 | 132 | 133 |
Power Source:unknown
134 | 135 |
136 | 139 |
140 |

Magnetometer

141 |

Note: it works if you bring a magnet close to your device.

142 | 146 | 147 | 148 |
Power Source:unknown
149 | 150 |
151 | 152 | 153 | -------------------------------------------------------------------------------- /examples/D-example-p5-1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 77 | 78 | 79 | 80 | 81 | 82 |
To get started download the Tramontana App on your iOS device from here.
83 |
84 |
85 | Insert the IP address of your device and press start to begin. 86 |

87 | Turn your phone to see the pyramid rotate. 88 | 89 |
90 | 91 |
92 | 93 | 94 | 95 |
96 | 97 | 98 |
99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /examples/E-example-p5-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 49 | 50 | 51 | 52 | 53 | 54 |

To get started download the Tramontana App on your iOS device from here.

55 |
56 |
57 |
58 | Insert the IP address of your device and press start to begin. 59 |

60 | Use the distance sensor on top of your device to affect the sketch. 61 | 62 |
63 |

64 | 65 | 66 | 67 | 68 |
85 | 86 | 87 |
88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /examples/F-example-hardware.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

To get started download the Tramontana App on your iOS device from here.

21 |
22 |
23 | Insert the IP address of your tramontana board and press start to begin. 24 |

25 | Press change color to change color of the onboard LED. 26 |


27 | 28 |
29 |
30 | 31 | 32 |
33 | 34 | 35 | 36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | ##Examples are live at: 2 | 3 | ####[Hello World!](https://pierdr.github.io/tramontana/examples/A-example-helloWorld.html) 4 | 5 | ####[Sensor - Device Orientation](https://pierdr.github.io/tramontana/examples/B-example-subscribeOrientation.html) 6 | 7 | ####[All sensors](https://pierdr.github.io/tramontana/examples/C-example-all-sensors.html) 8 | 9 | ####[tramontana and p5js](https://pierdr.github.io/tramontana/examples/D-example-p5-1.html) 10 | 11 | ####[tramontana and p5js #2](https://pierdr.github.io/tramontana/examples/E-example-p5-2.html) 12 | 13 | ####[Hardware - tramontana board](https://pierdr.github.io/tramontana/examples/F-example-hardware.html) 14 | -------------------------------------------------------------------------------- /examples/stylesheet.css: -------------------------------------------------------------------------------- 1 | 2 | @font-face { 3 | font-family: 'reg'; 4 | src:url('http://files.cargocollective.com/757295/81780024-f1ae-4135-a0ae-d0bab2c19986.ttf') format('truetype'); 5 | font-weight: normal; 6 | font-style: normal; 7 | } 8 | body, html { 9 | 10 | font-family: reg, sans-serif; 11 | background-color: black; 12 | color: #efefef; 13 | } 14 | input{ 15 | background-color: black; 16 | color: #efefef; 17 | } 18 | button{ 19 | margin: 10px; 20 | } 21 | a{ 22 | color: #efefef; 23 | } 24 | input { 25 | outline: none; 26 | border: none; 27 | } -------------------------------------------------------------------------------- /lib/tramontana.js: -------------------------------------------------------------------------------- 1 | /******** 2 | Developed by Pierluigi Dalla Rosa and Enrico Gueli 3 | v0.1.5 4 | *******/ 5 | window.tramontanaMaster = {}; 6 | window.tramontanaMaster.state = "INIT"; 7 | window.tramontanaMaster.changedStateInCycle = 0; 8 | 9 | tramontanaMaster.changeState = function (newstate) { 10 | if (newstate != tramontana.state) { 11 | tramontanaMaster.state = newstate; 12 | tramontanaMaster.changedStateInCycle = 1; 13 | jQuery.event.trigger('stateChanged', {}); 14 | 15 | } 16 | } 17 | window.onbeforeunload = function () { 18 | 19 | for (var a in tramontanaMaster) { 20 | //tramontanaMaster[a].socket.close(16,"page closing"); 21 | } 22 | } 23 | window.tramontana = function () { 24 | var object = new Object(); 25 | object.socket = new Object(); 26 | object.status = "INIT"; 27 | object.subscribed = { distance: 0, orientation: 0, attitude: 0, magnetometer: 0, touch: 0, audiojack: 0, powersource: 0, rxembedded: 0, btnsembedded: 0, ldrembedded: 0 }; 28 | object.callbacks = { videoended: 0, socketopen: 0, distance: 0, orientation: 0, attitude: 0, magnetometer: 0, touch: 0, audiojack: 0, powersource: 0, rxembedded: 0, btnsembedded: 0, ldrembedded: 0 }; 29 | object.subscribeFunctions = { distance: 0, orientation: 0, attitude: 0, magnetometer: 0, touch: 0, audiojack: 0, powersource: 0, rxembedded: 0, btnsembedded: 0, ldrembedded: 0 }; 30 | object.setupSocket = object.start = function (socketAddress, b) { 31 | 32 | if (socketAddress == "") { 33 | socketAddress = "192.168.1.:9092"; 34 | return; 35 | } 36 | if (socketAddress.indexOf(":") == -1) { 37 | socketAddress = socketAddress + ":9092"; 38 | } 39 | if (BrowserDetect.browser == "Firefox") { 40 | console.error("Websocket not supported. Please use Safari or Chrome."); 41 | } else { 42 | object.socket = new ReconnectingWebSocket(get_appropriate_ws_url(socketAddress)); 43 | } 44 | 45 | //registerCALLBACK 46 | if (b != undefined) { 47 | object.callbacks.socketopen = b; 48 | } 49 | // open 50 | try { 51 | object.socket.onopen = function () { 52 | 53 | 54 | object.status = "OPEN"; 55 | jQuery.event.trigger('socketOpened', []); 56 | object.retrial = 0; 57 | 58 | for (var id in object.subscribed) { 59 | if (object.subscribed[id]) { 60 | object.subscribeFunctions[id](); 61 | } 62 | } 63 | if (object.callbacks.socketopen != 0) { 64 | object.callbacks.socketopen(); 65 | } 66 | try { 67 | socketOpened(); 68 | } 69 | catch (e) { 70 | 71 | } 72 | } 73 | 74 | // received message 75 | object.socket.onmessage = function got_packet(msg) { 76 | 77 | try { 78 | messageObject = JSON.parse(msg.data); 79 | } 80 | catch (e) { 81 | 82 | console.warn("error loading JSON", msg, e); 83 | } 84 | var ipAddress = object.socket.url.replace(object.socket.url.slice(-5), ''); 85 | ipAddress = ipAddress.slice(5); 86 | if (messageObject["m"] == "x" || messageObject["m"] == "xm" || messageObject["m"] == "xt") { 87 | jQuery.event.trigger('ping', { "address": ipAddress, "type": messageObject["m"] }); 88 | return; 89 | } 90 | console.info("::: ----> received:\"" + messageObject["m"] + "\"", messageObject); 91 | 92 | if (messageObject["m"] == "touched") { 93 | if (messageObject["value"] == 0 || messageObject["value"] == "0") { 94 | object.touched = false; 95 | } 96 | if (object.callbacks.touched != 0) { 97 | object.callbacks.touched(ipAddress, { "x": messageObject["x"], "y": messageObject["y"] }); 98 | } 99 | else { 100 | object.touched = true; 101 | jQuery.event.trigger('touched', { "address": ipAddress, "x": messageObject["x"], "y": messageObject["y"] }); 102 | } 103 | try { 104 | touched(ipAddress, messageObject["x"], messageObject["y"]); 105 | } 106 | catch (e) { 107 | 108 | } 109 | return; 110 | } 111 | else if (messageObject["m"] == "drag") { 112 | if (object.callbacks.drag != 0) { 113 | object.callbacks.drag(ipAddress, { "x": messageObject["x"], "y": messageObject["y"] }); 114 | } 115 | else { 116 | jQuery.event.trigger('drag', { "address": ipAddress, "x": messageObject["x"], "y": messageObject["y"] }); 117 | } 118 | try { 119 | drag(ipAddress, messageObject["x"], messageObject["y"]); 120 | } 121 | catch (e) { 122 | 123 | } 124 | return; 125 | } 126 | else if (messageObject["m"] == "a") { 127 | jQuery.event.trigger('a', { "address": ipAddress, "r": messageObject["r"], "y": messageObject["y"], "p": messageObject["p"] }); 128 | if (object.callbacks.attitude != 0) { 129 | object.callbacks.attitude(ipAddress, { "r": messageObject["r"], "y": messageObject["y"], "p": messageObject["p"] }); 130 | } 131 | try { 132 | attitude(ipAddress, messageObject["r"], messageObject["y"], messageObject["p"]); 133 | } 134 | catch (e) { 135 | 136 | } 137 | } 138 | else if (messageObject["m"] == "oom") { 139 | jQuery.event.trigger('oom', { "address": ipAddress }); 140 | } 141 | else if (messageObject["m"] == "rx") { 142 | jQuery.event.trigger('receivedRx', { "address": ipAddress, "v": messageObject["v"] }); 143 | if (object.callbacks.rxembedded != 0) { 144 | object.callbacks.rxembedded(ipAddress, messageObject["v"]); 145 | } 146 | } 147 | else if (messageObject["m"] == "orientationChanged") { 148 | object.orientation = messageObject["value"]; 149 | if (object.callbacks.orientation != 0) { 150 | object.callbacks.orientation(ipAddress, object.orientation); 151 | } 152 | try { 153 | orientationChanged(ipAddress, object.orientation); 154 | } 155 | catch (e) { 156 | 157 | } 158 | jQuery.event.trigger('orientationChanged', { "address": ipAddress, "value": messageObject["value"] }); 159 | } 160 | else if (messageObject["m"] == "magnetometerUpdate") { 161 | object.magnetometer = messageObject["t"]; 162 | object.magnetometerIntensity = messageObject["i"]; 163 | if (object.callbacks.magnetometer != 0) { 164 | object.callbacks.magnetometer(ipAddress, object.magnetometer, object.magnetometerIntensity); 165 | } 166 | try { 167 | magnetometerEvent(ipAddress, object.magnetometer, object.magnetometerIntensity); 168 | } 169 | catch (e) { 170 | 171 | } 172 | jQuery.event.trigger('magnetometerEvent', { "address": ipAddress, "i": messageObject["i"], "t": messageObject["t"] }); 173 | } 174 | else if (messageObject["m"] == "distanceChanged") { 175 | object.proximity = messageObject["proximity"]; 176 | if (object.callbacks.distance != 0) { 177 | object.callbacks.distance(ipAddress, object.proximity); 178 | } 179 | 180 | try { 181 | distanceChanged(ipAddress, object.proximity); 182 | 183 | } 184 | catch (e) { 185 | 186 | } 187 | jQuery.event.trigger('distanceChanged', { "address": ipAddress, "p": messageObject["proximity"] }); 188 | } 189 | else if (messageObject["m"] == "audioJackChanged") { 190 | object.audiojack = messageObject["in"]; 191 | 192 | if (object.callbacks.audiojack != 0) { 193 | object.callbacks.audiojack(ipAddress, object.audiojack); 194 | } 195 | try { 196 | audioJackChanged(ipAddress, object.audiojack); 197 | 198 | } 199 | catch (e) { 200 | 201 | } 202 | jQuery.event.trigger('audioJackChanged', { "address": ipAddress, "in": messageObject["in"] }); 203 | } 204 | else if (messageObject["m"] == "powerSourceChanged") { 205 | object.powersource = messageObject["source"]; 206 | 207 | if (object.callbacks.powersource != 0) { 208 | object.callbacks.powersource(ipAddress, object.powersource); 209 | } 210 | 211 | try { 212 | 213 | powerSourceChanged(ipAddress, object.powersource); 214 | 215 | } 216 | catch (e) { 217 | 218 | } 219 | jQuery.event.trigger('powerSourceChanged', { "address": ipAddress, "in": messageObject["source"] }); 220 | } else if (messageObject["m"] == "batteryGet") { 221 | object.batteryLevel = messageObject["value"]; 222 | 223 | try { 224 | gotBatteryLevel(messageObject["value"]); 225 | } 226 | catch (e) { 227 | 228 | } 229 | jQuery.event.trigger('gotBatteryLevel', { "address": ipAddress, "batteryLevel": messageObject["value"] }); 230 | 231 | } else if (messageObject["m"] == "videoEnded") { 232 | if (object.callbacks.videoended != 0) { 233 | object.callbacks.videoended(ipAddress); 234 | } 235 | try { 236 | videoEnded(); 237 | } 238 | catch (e) { 239 | 240 | } 241 | jQuery.event.trigger('videoEnded', { "address": ipAddress }); 242 | } else if (messageObject["m"] == "btn") { 243 | if (object.callbacks.btnsembedded != 0) { 244 | object.callbacks.btnsembedded(ipAddress, messageObject[n], messageObject[v]); 245 | } 246 | try { 247 | 248 | } 249 | catch (e) { 250 | 251 | } 252 | jQuery.event.trigger('btnEvent', { "address": ipAddress }); 253 | } 254 | else if (messageObject["m"] == "ldr") { 255 | if (object.callbacks.ldrembedded != 0) { 256 | object.callbacks.ldrembedded(ipAddress, messageObject["v"]); 257 | } 258 | try { 259 | ldrEmbeddedReceived(ipAddress, messageObject["v"]); 260 | } 261 | catch (e) { 262 | 263 | } 264 | jQuery.event.trigger('ldrUpdate', { "address": ipAddress, "v": messageObject["v"] }); 265 | } 266 | else if (messageObject["m"] == "error") { 267 | console.warn(messageObject["type"]); 268 | } 269 | else if (messageObject["m"] == "test") { 270 | console.log(Date.now()); 271 | } 272 | } 273 | 274 | object.socket.onclose = function () { 275 | object.status = "CLOSED"; 276 | console.warn("connection: %s", object.status, object.socket); 277 | 278 | } 279 | object.socket.onerror = function () { 280 | object.status = "ERROR"; 281 | } 282 | 283 | } catch (exception) { 284 | alert('

Error' + exception); 285 | object.status = "ERROR"; 286 | } 287 | } 288 | 289 | 290 | object.setServoEmbedded = function (servoIndex, value) { 291 | if (arguments.length == 2) { 292 | this.sendMessage("{\"m\":\"srv\",\"n\":" + servoIndex + ",\"v\":" + value + "}"); 293 | } 294 | } 295 | object.setRelayEmbeddedOff = function (relayIndex) { 296 | this.sendMessage("{\"m\":\"rel\",\"n\":" + relayIndex + ",\"v\":0}"); 297 | } 298 | object.setRelayEmbeddedOn = function (relayIndex) { 299 | this.sendMessage("{\"m\":\"rel\",\"n\":" + relayIndex + ",\"v\":1}"); 300 | } 301 | object.setRelayEmbedded = function (num, val) { 302 | if (arguments.length == 2) { 303 | 304 | this.sendMessage("{\"m\":\"rel\",\"n\":" + num + ",\"v\":" + Math.round(val) + "}"); 305 | } 306 | } 307 | object.sendSerialMessageEmbedded = function (val) { 308 | if (arguments.length == 1) { 309 | 310 | this.sendMessage("{\"m\":\"tx\",\"v\":\"" + val + "\"}"); 311 | } 312 | } 313 | object.setColorEmbedded = function (num, red, green, blue) { 314 | 315 | this.sendMessage("{\"m\":\"col\",\"n\":\"" + num + "\",\"r\":\"" + Math.floor(red) + "\",\"g\":\"" + Math.floor(green) + "\",\"b\":\"" + Math.floor(blue) + "\"}"); 316 | 317 | } 318 | object.blinkColorEmbedded = function (num, red, green, blue) { 319 | if (arguments.length == 4) { 320 | 321 | this.sendMessage("{\"m\":\"blk\",\"n\":\"" + num + "\",\"r\":\"" + Math.floor(red) + "\",\"g\":\"" + Math.floor(green) + "\",\"b\":\"" + Math.floor(blue) + "\"}"); 322 | } 323 | } 324 | object.setAllColorEmbedded = function (red, green, blue) { 325 | if (arguments.length == 3) { 326 | 327 | this.sendMessage("{\"m\":\"all\",\"r\":\"" + Math.floor(red) + "\",\"g\":\"" + Math.floor(green) + "\",\"b\":\"" + Math.floor(blue) + "\"}"); 328 | } 329 | } 330 | object.setColor = function (red, green, blue, intensity) { 331 | 332 | if (arguments.length == 3 || arguments.length == 4) { 333 | if (red > 1.0 || green > 1.0 || blue > 1.0) { 334 | red = red / 255; 335 | green = green / 255; 336 | blue = blue / 255; 337 | intensity = intensity / 255; 338 | } 339 | this.sendMessage("{\"m\":\"setColor\",\"r\":\"" + red + "\",\"g\":\"" + green + "\",\"b\":\"" + blue + "\",\"a\":\"" + intensity + "\"}"); 340 | } 341 | 342 | if (arguments.length == 1) { 343 | if (arguments[0].hasOwnProperty(r)) { 344 | var color = red; 345 | if (color.r > 1.0 || color.g > 1.0 || color.b > 1.0) { 346 | color.r = color.r / 255; 347 | color.g = color.g / 255; 348 | color.b = color.b / 255; 349 | color.a = color.a / 255; 350 | } 351 | this.sendMessage("{\"m\":\"setColor\",\"r\":\"" + color.r + "\",\"g\":\"" + color.g + "\",\"b\":\"" + color.b + "\",\"a\":\"" + color.a + "\"}"); 352 | } 353 | } 354 | } 355 | object.setFlashLight = function (onvalue) { 356 | 357 | onvalue = clamp(onvalue, 0, onvalue); 358 | this.sendMessage("{\"m\":\"setLED\",\"value\":\"1\",\"in\":\"" + onvalue + "\"}"); 359 | 360 | 361 | } 362 | object.pulseFlashLight = function (numberOfPulses, duration, intensity) { 363 | if (arguments.length == 3) { 364 | this.sendMessage("{\"m\":\"pulseLED\",\"t\":\"" + numberOfPulses + "\",\"d\":\"" + duration + "\",\"i\":\"" + intensity + "\"}"); 365 | } 366 | else { 367 | console.warn('pulseLED requires 3 inputs: numberOfPulses,duration,intensity'); 368 | } 369 | } 370 | object.showImage = function (url) { 371 | if (typeof url == 'string') { 372 | this.sendMessage("{\"m\":\"showImage\",\"url\":\"" + url + "\"}"); 373 | } 374 | else { 375 | console.warn('showImage requires a string input'); 376 | } 377 | } 378 | object.playVideo = function (url, callback) { 379 | if (callback != undefined) { 380 | object.callbacks.videoended = callback; 381 | } 382 | else { 383 | object.callbacks.videoended = 0; 384 | } 385 | if (typeof url == 'string') { 386 | this.sendMessage("{\"m\":\"playVideo\",\"url\":\"" + url + "\"}"); 387 | } 388 | else { 389 | console.warn('playVideo requires a string input'); 390 | } 391 | } 392 | object.loopVideo = function (url, callback) { 393 | if (callback != undefined) { 394 | object.callbacks.videoended = callback; 395 | } 396 | else { 397 | object.callbacks.videoended = 0; 398 | } 399 | if (typeof url == 'string') { 400 | this.sendMessage("{\"m\":\"loopVideo\",\"url\":\"" + url + "\"}"); 401 | } 402 | else { 403 | console.warn('loopVideo requires a string input'); 404 | } 405 | } 406 | object.playAudio = function (url) { 407 | if (typeof url == 'string') { 408 | this.sendMessage("{\"m\":\"playAudio\",\"url\":\"" + url + "\"}"); 409 | } 410 | else { 411 | console.warn('playAudio requires a string input'); 412 | } 413 | } 414 | object.setBrightness = function (brightness) { 415 | if (isNumber(brightness)) { 416 | this.sendMessage("{\"m\":\"setBrightness\",\"b\":\"" + brightness + "\"}"); 417 | } 418 | else { 419 | console.warn('setBrighness requires one numerical parameter'); 420 | } 421 | } 422 | object.takePicture = function (camera, ui) { 423 | if (arguments.length > 0 && isNumber(camera)) { 424 | var message = "{\"m\":\"takePicture\",\"c\":\"" + camera + "\""; 425 | 426 | if (arguments.length > 1) { 427 | if (ui == "ui") { 428 | message += ",\"i\":\"ui\""; 429 | } 430 | } 431 | message += "}"; 432 | this.sendMessage(message); 433 | } 434 | else { 435 | this.sendMessage("{\"m\":\"takePicture\"}"); 436 | } 437 | } 438 | object.transitionColors = function (color1, color2, duration) { 439 | if (arguments.length == 3) { 440 | if (!isNumber(duration)) { 441 | duration = 5.0; 442 | console.warn("transitionColors: duration is not a number"); 443 | } 444 | this.sendMessage("{\"m\":\"transitionColors\",\"r1\":\"" + color1.r + "\",\"g1\":\"" + color1.b + "\",\"b1\":\"" + color1.g + "\",\"a1\":\"" + color1.a + "\",\"r2\":\"" + color2.r + "\",\"g2\":\"" + color2.g + "\",\"b2\":\"" + color2.b + "\",\"a2\":\"" + color2.a + "\",\"duration\":\"" + duration + "\"}"); 445 | } 446 | else { 447 | console.warn('transitionColors requires 3 parameters: color1,color2,duration'); 448 | } 449 | } 450 | object.getBatteryLevel = function () { 451 | 452 | var message = "{\"m\":\"getBattery\"}"; 453 | object.sendMessage(message); 454 | } 455 | object.subscribeFunctions.distance = object.subscribeDistance = function (callback) { 456 | object.subscribed.distance = 1; 457 | object.sendMessage("{\"m\":\"registerDistance\"}"); 458 | if (callback != undefined) { 459 | object.callbacks.distance = callback; 460 | } 461 | else { 462 | object.callbacks.distance = 0; 463 | } 464 | } 465 | object.releaseDistance = function () { 466 | object.subscribed.distance = 0; 467 | object.sendMessage("{\"m\":\"releaseDistance\"}"); 468 | } 469 | object.subscribeFunctions.touch = object.subscribeTouch = function (callback) { 470 | object.subscribed.touch = 1; 471 | 472 | object.sendMessage("{\"m\":\"registerTouch\"}"); 473 | if (callback != undefined) { 474 | object.callbacks.touched = callback; 475 | } 476 | else { 477 | object.callbacks.touched = 0; 478 | } 479 | } 480 | object.releaseTouch = function () { 481 | object.subscribed.touch = 0; 482 | object.sendMessage("{\"m\":\"releaseTouch\"}"); 483 | } 484 | object.subscribeFunctions.touchDrag = object.subscribeTouchDrag = function (callback) { 485 | object.subscribed.touchDrag = 1; 486 | 487 | object.sendMessage("{\"m\":\"registerTouchDrag\"}"); 488 | if (callback != undefined) { 489 | object.callbacks.drag = callback; 490 | object.callbacks.touched = callback; 491 | } 492 | else { 493 | object.callbacks.drag = 0; 494 | object.callbacks.touched = 0; 495 | } 496 | } 497 | object.releaseTouchDrag = function () { 498 | object.subscribed.touchDrag = 0; 499 | object.sendMessage("{\"m\":\"releaseTouchDrag\"}"); 500 | } 501 | 502 | object.subscribeFunctions.attitude = object.subscribeAttitude = function (frequency, callback) { 503 | object.subscribed.attitude = 1; 504 | object.sendMessage("{\"m\":\"registerAttitude\",\"f\":\"" + frequency + "\"}"); 505 | if (callback != undefined) { 506 | object.callbacks.attitude = callback; 507 | } 508 | else { 509 | object.callbacks.attitude = 0; 510 | } 511 | } 512 | object.releaseAttitude = function (frequency) { 513 | object.subscribed.attitude = 0; 514 | object.sendMessage("{\"m\":\"releaseAttitude\"}"); 515 | } 516 | object.subscribeFunctions.audiojack = object.subscribeAudioJack = function (callback) { 517 | object.subscribed.audiojack = 1; 518 | object.sendMessage("{\"m\":\"registerAudioJack\"}"); 519 | if (callback != undefined) { 520 | object.callbacks.audiojack = callback; 521 | } 522 | else { 523 | object.callbacks.audiojack = 0; 524 | } 525 | } 526 | object.releaseAudioJack = function () { 527 | object.subscribed.audiojack = 0; 528 | object.sendMessage("{\"m\":\"releaseAudioJack\"}"); 529 | } 530 | object.subscribeFunctions.powersource = object.subscribePowerSource = function (callback) { 531 | object.subscribed.powersource = 1; 532 | object.sendMessage("{\"m\":\"registerPowerSource\"}"); 533 | if (callback != undefined) { 534 | object.callbacks.powersource = callback; 535 | } 536 | else { 537 | object.callbacks.powersource = 0; 538 | } 539 | } 540 | object.releasePowerSource = function () { 541 | object.subscribed.powersource = 0; 542 | object.sendMessage("{\"m\":\"releasePowerSource\"}"); 543 | } 544 | object.subscribeFunctions.magnetometer = object.subscribeMagnetometer = function (callback) { 545 | object.subscribed.magnetometer = 1; 546 | object.sendMessage("{\"m\":\"registerMagnetometer\"}"); 547 | if (callback != undefined) { 548 | object.callbacks.magnetometer = callback; 549 | } 550 | else { 551 | object.callbacks.magnetometer = 0; 552 | } 553 | } 554 | object.releaseMagnetometer = function () { 555 | object.subscribed.magnetometer = 0; 556 | object.sendMessage("{\"m\":\"releaseMagnetometer\"}"); 557 | } 558 | object.subscribeFunctions.orientation = object.subscribeOrientation = function (callback) { 559 | object.subscribed.orientation = 1; 560 | var message = "{\"m\":\"registerOrientation\"}"; 561 | object.sendMessage(message); 562 | if (callback != undefined) { 563 | object.callbacks.orientation = callback; 564 | } 565 | else { 566 | object.callbacks.orientation = 0; 567 | } 568 | } 569 | object.releaseOrientation = function () { 570 | 571 | var message = "{\"m\":\"releaseOrientation\"}"; 572 | object.subscribed.orientation = 0; 573 | object.sendMessage(message); 574 | } 575 | object.subscribeFunctions.rxembedded = object.subscribeRxEmbedded = function (callback) { 576 | var message = "{\"m\":\"srx\"}"; 577 | object.subscribed.rxembedded = 1; 578 | object.sendMessage(message); 579 | if (callback != undefined) { 580 | object.callbacks.rxembedded = callback; 581 | } 582 | else { 583 | object.callbacks.rxembedded = 0; 584 | } 585 | } 586 | object.releaseRxEmbedded = function () { 587 | object.subscribed.rxembedded = 0; 588 | object.sendMessage("{\"m\":\"drx\"}"); 589 | } 590 | object.subscribeFunctions.ldrembedded = object.subscribeLDREmbedded = function (frequency, callback) { 591 | var message = "{\"m\":\"sldr\",\"f\":\"" + frequency + "\"}"; 592 | object.subscribed.ldrembedded = 1; 593 | object.sendMessage(message); 594 | if (callback != undefined) { 595 | object.callbacks.ldrembedded = callback; 596 | } 597 | else { 598 | object.callbacks.ldrembedded = 0; 599 | } 600 | } 601 | object.releaseLDREmbedded = function () { 602 | object.subscribed.ldrembedded = 0; 603 | object.sendMessage("{\"m\":\"dldr\"}"); 604 | } 605 | object.subscribeFunctions.btnsembedded = object.subscribeButtonsEventEmbedded = function (callback) { 606 | var message = "{\"m\":\"sbtn\"}"; 607 | object.subscribed.btnsembedded = 1; 608 | object.sendMessage(message); 609 | if (callback != undefined) { 610 | object.callbacks.btnsembedded = callback; 611 | } 612 | else { 613 | object.callbacks.btnsembedded = 0; 614 | } 615 | } 616 | object.releaseButtonsEventEmbedded = function () { 617 | object.subscribed.btnsembedded = 0; 618 | object.sendMessage("{\"m\":\"dbtn\"}"); 619 | } 620 | object.makeVibrate = function (duration) { 621 | var message; 622 | if (duration != "" && duration != undefined && duration != '') { 623 | message = "{\"m\":\"makeVibrate\",\"duration\":\"" + duration + "\"}"; 624 | } 625 | else { 626 | message = "{\"m\":\"makeVibrate\"}"; 627 | } 628 | object.sendMessage(message); 629 | } 630 | object.sendMessage = function (message) { 631 | try { 632 | object.socket.send(message); 633 | object.retrial = 0; 634 | } 635 | catch (e) { 636 | if (object.retrial < 3) { 637 | object.socket.refresh(); 638 | object.retrial++; 639 | setTimeout(function () { 640 | object.sendMessage(message); 641 | } 642 | , 100); 643 | } 644 | else { 645 | console.warn("communication error: " + e); 646 | } 647 | } 648 | } 649 | return object; 650 | }; 651 | -------------------------------------------------------------------------------- /lib/tramontana_min.js: -------------------------------------------------------------------------------- 1 | /******** 2 | Developed by Pierluigi Dalla Rosa and Enrico Gueli 3 | v0.1.5 4 | *******/ 5 | function isNumber(e){return!isNaN(parseFloat(e))}function get_appropriate_ws_url(e){var t,s=document.URL;"https"==s.substring(0,5)?(t="wss://",s=s.substr(8)):(t="ws://","http"==s.substring(0,4)&&(s=s.substr(7))),s=s.split("/");var n="";return n=""==e?s[0]:e,t+n}function clamp(e,t,s){return es?(e=s,e):e}window.tramontanaMaster={},window.tramontanaMaster.state="INIT",window.tramontanaMaster.changedStateInCycle=0,tramontanaMaster.changeState=function(e){e!=tramontana.state&&(tramontanaMaster.state=e,tramontanaMaster.changedStateInCycle=1,jQuery.event.trigger("stateChanged",{}))},window.onbeforeunload=function(){for(var e in tramontanaMaster);},window.tramontana=function(){var e=new Object;return e.socket=new Object,e.status="INIT",e.subscribed={distance:0,orientation:0,attitude:0,magnetometer:0,touch:0,audiojack:0,powersource:0,rxembedded:0,btnsembedded:0,ldrembedded:0},e.callbacks={videoended:0,socketopen:0,distance:0,orientation:0,attitude:0,magnetometer:0,touch:0,audiojack:0,powersource:0,rxembedded:0,btnsembedded:0,ldrembedded:0},e.subscribeFunctions={distance:0,orientation:0,attitude:0,magnetometer:0,touch:0,audiojack:0,powersource:0,rxembedded:0,btnsembedded:0,ldrembedded:0},e.setupSocket=e.start=function(t,s){if(""!=t){-1==t.indexOf(":")&&(t+=":9092"),"Firefox"==BrowserDetect.browser?console.error("Websocket not supported. Please use Safari or Chrome."):e.socket=new ReconnectingWebSocket(get_appropriate_ws_url(t)),null!=s&&(e.callbacks.socketopen=s);try{e.socket.onopen=function(){for(var t in e.status="OPEN",jQuery.event.trigger("socketOpened",[]),e.retrial=0,e.subscribed)e.subscribed[t]&&e.subscribeFunctions[t]();0!=e.callbacks.socketopen&&e.callbacks.socketopen();try{socketOpened()}catch(e){}},e.socket.onmessage=function(t){try{messageObject=JSON.parse(t.data)}catch(e){console.warn("error loading JSON",t,e)}var s=e.socket.url.replace(e.socket.url.slice(-5),"");if(s=s.slice(5),"x"!=messageObject.m&&"xm"!=messageObject.m&&"xt"!=messageObject.m)if(console.info('::: ----> received:"'+messageObject.m+'"',messageObject),"touched"!=messageObject.m)if("drag"!=messageObject.m)if("a"==messageObject.m){jQuery.event.trigger("a",{address:s,r:messageObject.r,y:messageObject.y,p:messageObject.p}),0!=e.callbacks.attitude&&e.callbacks.attitude(s,{r:messageObject.r,y:messageObject.y,p:messageObject.p});try{attitude(s,messageObject.r,messageObject.y,messageObject.p)}catch(e){}}else if("oom"==messageObject.m)jQuery.event.trigger("oom",{address:s});else if("rx"==messageObject.m)jQuery.event.trigger("receivedRx",{address:s,v:messageObject.v}),0!=e.callbacks.rxembedded&&e.callbacks.rxembedded(s,messageObject.v);else if("orientationChanged"==messageObject.m){e.orientation=messageObject.value,0!=e.callbacks.orientation&&e.callbacks.orientation(s,e.orientation);try{orientationChanged(s,e.orientation)}catch(e){}jQuery.event.trigger("orientationChanged",{address:s,value:messageObject.value})}else if("magnetometerUpdate"==messageObject.m){e.magnetometer=messageObject.t,e.magnetometerIntensity=messageObject.i,0!=e.callbacks.magnetometer&&e.callbacks.magnetometer(s,e.magnetometer,e.magnetometerIntensity);try{magnetometerEvent(s,e.magnetometer,e.magnetometerIntensity)}catch(e){}jQuery.event.trigger("magnetometerEvent",{address:s,i:messageObject.i,t:messageObject.t})}else if("distanceChanged"==messageObject.m){e.proximity=messageObject.proximity,0!=e.callbacks.distance&&e.callbacks.distance(s,e.proximity);try{distanceChanged(s,e.proximity)}catch(e){}jQuery.event.trigger("distanceChanged",{address:s,p:messageObject.proximity})}else if("audioJackChanged"==messageObject.m){e.audiojack=messageObject.in,0!=e.callbacks.audiojack&&e.callbacks.audiojack(s,e.audiojack);try{audioJackChanged(s,e.audiojack)}catch(e){}jQuery.event.trigger("audioJackChanged",{address:s,in:messageObject.in})}else if("powerSourceChanged"==messageObject.m){e.powersource=messageObject.source,0!=e.callbacks.powersource&&e.callbacks.powersource(s,e.powersource);try{powerSourceChanged(s,e.powersource)}catch(e){}jQuery.event.trigger("powerSourceChanged",{address:s,in:messageObject.source})}else if("batteryGet"==messageObject.m){e.batteryLevel=messageObject.value;try{gotBatteryLevel(messageObject.value)}catch(e){}jQuery.event.trigger("gotBatteryLevel",{address:s,batteryLevel:messageObject.value})}else if("videoEnded"==messageObject.m){0!=e.callbacks.videoended&&e.callbacks.videoended(s);try{videoEnded()}catch(e){}jQuery.event.trigger("videoEnded",{address:s})}else if("btn"==messageObject.m)0!=e.callbacks.btnsembedded&&e.callbacks.btnsembedded(s,messageObject[n],messageObject[v]),jQuery.event.trigger("btnEvent",{address:s});else if("ldr"==messageObject.m){0!=e.callbacks.ldrembedded&&e.callbacks.ldrembedded(s,messageObject.v);try{ldrEmbeddedReceived(s,messageObject.v)}catch(e){}jQuery.event.trigger("ldrUpdate",{address:s,v:messageObject.v})}else"error"==messageObject.m?console.warn(messageObject.type):"test"==messageObject.m&&console.log(Date.now());else{0!=e.callbacks.drag?e.callbacks.drag(s,{x:messageObject.x,y:messageObject.y}):jQuery.event.trigger("drag",{address:s,x:messageObject.x,y:messageObject.y});try{drag(s,messageObject.x,messageObject.y)}catch(e){}}else{0!=messageObject.value&&"0"!=messageObject.value||(e.touched=!1),0!=e.callbacks.touched?e.callbacks.touched(s,{x:messageObject.x,y:messageObject.y}):(e.touched=!0,jQuery.event.trigger("touched",{address:s,x:messageObject.x,y:messageObject.y}));try{touched(s,messageObject.x,messageObject.y)}catch(e){}}else jQuery.event.trigger("ping",{address:s,type:messageObject.m})},e.socket.onclose=function(){e.status="CLOSED",console.warn("connection: %s",e.status,e.socket)},e.socket.onerror=function(){e.status="ERROR"}}catch(t){alert("

Error"+t),e.status="ERROR"}}else t="192.168.1.:9092"},e.setServoEmbedded=function(e,t){2==arguments.length&&this.sendMessage('{"m":"srv","n":'+e+',"v":'+t+"}")},e.setRelayEmbeddedOff=function(e){this.sendMessage('{"m":"rel","n":'+e+',"v":0}')},e.setRelayEmbeddedOn=function(e){this.sendMessage('{"m":"rel","n":'+e+',"v":1}')},e.setRelayEmbedded=function(e,t){2==arguments.length&&this.sendMessage('{"m":"rel","n":'+e+',"v":'+Math.round(t)+"}")},e.sendSerialMessageEmbedded=function(e){1==arguments.length&&this.sendMessage('{"m":"tx","v":"'+e+'"}')},e.setColorEmbedded=function(e,t,s,n){this.sendMessage('{"m":"col","n":"'+e+'","r":"'+Math.floor(t)+'","g":"'+Math.floor(s)+'","b":"'+Math.floor(n)+'"}')},e.blinkColorEmbedded=function(e,t,s,n){4==arguments.length&&this.sendMessage('{"m":"blk","n":"'+e+'","r":"'+Math.floor(t)+'","g":"'+Math.floor(s)+'","b":"'+Math.floor(n)+'"}')},e.setAllColorEmbedded=function(e,t,s){3==arguments.length&&this.sendMessage('{"m":"all","r":"'+Math.floor(e)+'","g":"'+Math.floor(t)+'","b":"'+Math.floor(s)+'"}')},e.setColor=function(e,t,s,n){if(3!=arguments.length&&4!=arguments.length||((e>1||t>1||s>1)&&(e/=255,t/=255,s/=255,n/=255),this.sendMessage('{"m":"setColor","r":"'+e+'","g":"'+t+'","b":"'+s+'","a":"'+n+'"}')),1==arguments.length&&arguments[0].hasOwnProperty(r)){var a=e;(a.r>1||a.g>1||a.b>1)&&(a.r=a.r/255,a.g=a.g/255,a.b=a.b/255,a.a=a.a/255),this.sendMessage('{"m":"setColor","r":"'+a.r+'","g":"'+a.g+'","b":"'+a.b+'","a":"'+a.a+'"}')}},e.setFlashLight=function(e){e=clamp(e,0,e),this.sendMessage('{"m":"setLED","value":"1","in":"'+e+'"}')},e.pulseFlashLight=function(e,t,s){3==arguments.length?this.sendMessage('{"m":"pulseLED","t":"'+e+'","d":"'+t+'","i":"'+s+'"}'):console.warn("pulseLED requires 3 inputs: numberOfPulses,duration,intensity")},e.showImage=function(e){"string"==typeof e?this.sendMessage('{"m":"showImage","url":"'+e+'"}'):console.warn("showImage requires a string input")},e.playVideo=function(t,s){e.callbacks.videoended=null!=s?s:0,"string"==typeof t?this.sendMessage('{"m":"playVideo","url":"'+t+'"}'):console.warn("playVideo requires a string input")},e.loopVideo=function(t,s){e.callbacks.videoended=null!=s?s:0,"string"==typeof t?this.sendMessage('{"m":"loopVideo","url":"'+t+'"}'):console.warn("loopVideo requires a string input")},e.playAudio=function(e){"string"==typeof e?this.sendMessage('{"m":"playAudio","url":"'+e+'"}'):console.warn("playAudio requires a string input")},e.setBrightness=function(e){isNumber(e)?this.sendMessage('{"m":"setBrightness","b":"'+e+'"}'):console.warn("setBrighness requires one numerical parameter")},e.takePicture=function(e,t){if(arguments.length>0&&isNumber(e)){var s='{"m":"takePicture","c":"'+e+'"';arguments.length>1&&"ui"==t&&(s+=',"i":"ui"'),s+="}",this.sendMessage(s)}else this.sendMessage('{"m":"takePicture"}')},e.transitionColors=function(e,t,s){3==arguments.length?(isNumber(s)||(s=5,console.warn("transitionColors: duration is not a number")),this.sendMessage('{"m":"transitionColors","r1":"'+e.r+'","g1":"'+e.b+'","b1":"'+e.g+'","a1":"'+e.a+'","r2":"'+t.r+'","g2":"'+t.g+'","b2":"'+t.b+'","a2":"'+t.a+'","duration":"'+s+'"}')):console.warn("transitionColors requires 3 parameters: color1,color2,duration")},e.getBatteryLevel=function(){var t='{"m":"getBattery"}';e.sendMessage(t)},e.subscribeFunctions.distance=e.subscribeDistance=function(t){e.subscribed.distance=1,e.sendMessage('{"m":"registerDistance"}'),e.callbacks.distance=null!=t?t:0},e.releaseDistance=function(){e.subscribed.distance=0,e.sendMessage('{"m":"releaseDistance"}')},e.subscribeFunctions.touch=e.subscribeTouch=function(t){e.subscribed.touch=1,e.sendMessage('{"m":"registerTouch"}'),e.callbacks.touched=null!=t?t:0},e.releaseTouch=function(){e.subscribed.touch=0,e.sendMessage('{"m":"releaseTouch"}')},e.subscribeFunctions.touchDrag=e.subscribeTouchDrag=function(t){e.subscribed.touchDrag=1,e.sendMessage('{"m":"registerTouchDrag"}'),null!=t?(e.callbacks.drag=t,e.callbacks.touched=t):(e.callbacks.drag=0,e.callbacks.touched=0)},e.releaseTouchDrag=function(){e.subscribed.touchDrag=0,e.sendMessage('{"m":"releaseTouchDrag"}')},e.subscribeFunctions.attitude=e.subscribeAttitude=function(t,s){e.subscribed.attitude=1,e.sendMessage('{"m":"registerAttitude","f":"'+t+'"}'),e.callbacks.attitude=null!=s?s:0},e.releaseAttitude=function(t){e.subscribed.attitude=0,e.sendMessage('{"m":"releaseAttitude"}')},e.subscribeFunctions.audiojack=e.subscribeAudioJack=function(t){e.subscribed.audiojack=1,e.sendMessage('{"m":"registerAudioJack"}'),e.callbacks.audiojack=null!=t?t:0},e.releaseAudioJack=function(){e.subscribed.audiojack=0,e.sendMessage('{"m":"releaseAudioJack"}')},e.subscribeFunctions.powersource=e.subscribePowerSource=function(t){e.subscribed.powersource=1,e.sendMessage('{"m":"registerPowerSource"}'),e.callbacks.powersource=null!=t?t:0},e.releasePowerSource=function(){e.subscribed.powersource=0,e.sendMessage('{"m":"releasePowerSource"}')},e.subscribeFunctions.magnetometer=e.subscribeMagnetometer=function(t){e.subscribed.magnetometer=1,e.sendMessage('{"m":"registerMagnetometer"}'),e.callbacks.magnetometer=null!=t?t:0},e.releaseMagnetometer=function(){e.subscribed.magnetometer=0,e.sendMessage('{"m":"releaseMagnetometer"}')},e.subscribeFunctions.orientation=e.subscribeOrientation=function(t){e.subscribed.orientation=1;var s='{"m":"registerOrientation"}';e.sendMessage(s),e.callbacks.orientation=null!=t?t:0},e.releaseOrientation=function(){var t='{"m":"releaseOrientation"}';e.subscribed.orientation=0,e.sendMessage(t)},e.subscribeFunctions.rxembedded=e.subscribeRxEmbedded=function(t){var s='{"m":"srx"}';e.subscribed.rxembedded=1,e.sendMessage(s),e.callbacks.rxembedded=null!=t?t:0},e.releaseRxEmbedded=function(){e.subscribed.rxembedded=0,e.sendMessage('{"m":"drx"}')},e.subscribeFunctions.ldrembedded=e.subscribeLDREmbedded=function(t,s){var n='{"m":"sldr","f":"'+t+'"}';e.subscribed.ldrembedded=1,e.sendMessage(n),e.callbacks.ldrembedded=null!=s?s:0},e.releaseLDREmbedded=function(){e.subscribed.ldrembedded=0,e.sendMessage('{"m":"dldr"}')},e.subscribeFunctions.btnsembedded=e.subscribeButtonsEventEmbedded=function(t){var s='{"m":"sbtn"}';e.subscribed.btnsembedded=1,e.sendMessage(s),e.callbacks.btnsembedded=null!=t?t:0},e.releaseButtonsEventEmbedded=function(){e.subscribed.btnsembedded=0,e.sendMessage('{"m":"dbtn"}')},e.makeVibrate=function(t){var s;s=""!=t&&null!=t&&""!=t?'{"m":"makeVibrate","duration":"'+t+'"}':'{"m":"makeVibrate"}',e.sendMessage(s)},e.sendMessage=function(t){try{e.socket.send(t),e.retrial=0}catch(s){e.retrial<3?(e.socket.refresh(),e.retrial++,setTimeout(function(){e.sendMessage(t)},100)):console.warn("communication error: "+s)}},e};var BrowserDetect={init:function(){this.browser=this.searchString(this.dataBrowser)||"An unknown browser",this.version=this.searchVersion(navigator.userAgent)||this.searchVersion(navigator.appVersion)||"an unknown version",this.OS=this.searchString(this.dataOS)||"an unknown OS"},searchString:function(e){for(var t=0;tc.maxReconnectInterval?c.maxReconnectInterval:a)}},i.onmessage=function(t){(c.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",c.url,t.data);var s=r("message");s.data=t.data,g.dispatchEvent(s)},i.onerror=function(t){(c.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","onerror",c.url,t),g.dispatchEvent(r("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(t){if(i)return(c.debug||e.debugAll)&&console.debug("ReconnectingWebSocket","send",c.url,t),i.send(t);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(e,t){void 0===e&&(e=1e3),d=!0,i&&i.close(e,t)},this.refresh=function(){i&&i.close()}}return e.prototype.onopen=function(){},e.prototype.onclose=function(){},e.prototype.onconnecting=function(){},e.prototype.onmessage=function(){},e.prototype.onerror=function(){},e.debugAll=!1,e.CONNECTING=WebSocket.CONNECTING,e.OPEN=WebSocket.OPEN,e.CLOSING=WebSocket.CLOSING,e.CLOSED=WebSocket.CLOSED,e}); -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | /******** 2 | Developed by Pierluigi Dalla Rosa 3 | v0.1.3 4 | 07-09-19 5 | *******/ 6 | 7 | /* BrowserDetect came from http://www.quirksmode.org/js/detect.html */ 8 | 9 | var BrowserDetect = { 10 | init: function () { 11 | this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; 12 | this.version = this.searchVersion(navigator.userAgent) 13 | || this.searchVersion(navigator.appVersion) 14 | || "an unknown version"; 15 | this.OS = this.searchString(this.dataOS) || "an unknown OS"; 16 | }, 17 | searchString: function (data) { 18 | for (var i=0;imaxVal) 174 | { 175 | value = maxVal; 176 | return value; 177 | } 178 | return value; 179 | } 180 | !function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a}); --------------------------------------------------------------------------------