Updated Modello Common libraries
[profile/ivi/sdk/web-ide-resources.git] / web-ui-fw / 0.0.2 / 0.0.2_Common / original / js / services / carIndicator.js
1 /**
2  * @module Services
3  */
4
5 /**
6  * Class provides AMB related functionality utilizing `tizen.vehicle` API for signals used in HTML applications. This component is usually initialized by {{#crossLink "Bootstrap"}}{{/crossLink}} class
7  * and can be later accessed using {{#crossLink "Bootstrap/carIndicator:property"}}{{/crossLink}} property. Signals recognized by this class needs to be registered in property
8  * {{#crossLink "CarIndicator/_mappingTable:property"}}{{/crossLink}}.
9  *
10  * To attach and detach to particular property register new callback object using {{#crossLink "Bootstrap/carIndicator:addListener"}}{{/crossLink}} method, e.g.:
11  *
12  *     var listenerId = bootstrap.carIndicator.addListener({
13  *        onSteeringWheelAngleChanged: function(newValue){
14  *           // Process new value
15  *        },
16  *        onWheelBrakeChanged : function(newValue){
17  *           // Process new value
18  *        }
19  *     });
20  *
21  *     // Unregister listener
22  *     bootstrap.carIndicator.removeListener(listenerId);
23  *
24  * Currently following signals are recognized:
25  *
26  * * SteeringWheelAngle
27  *   * SteeringWheelAngle
28  * * WheelBrake
29  *   * Engaged
30  * * TirePressure
31  *   * leftFront
32  *   * rightFront
33  *   * leftRear
34  *   * rightRear
35  * * DoorStatus
36  *   * ChildLockStatus
37  * * WindowStatus
38  *   * FrontDefrost
39  *   * RearDefrost
40  * * HVAC
41  *   * FanSpeed
42  *   * TargetTemperatureRight
43  *   * TargetTemperatureLeft
44  *   * SeatHeaterRight
45  *   * SeatHeaterLeft
46  *   * AirConditioning
47  *   * AirRecirculation
48  *   * AirflowDirection
49  * * LightStatus
50  *   * Hazard
51  *   * Head
52  *   * Parking
53  * * BatteryStatus
54  * * FullBatteryRange
55  * * ExteriorTemperature
56  *   * Exterior
57  * * InteriorTemperature
58  *   * Interior
59  * * WheelInformation
60  *   * FrontWheelRadius
61  * * AvgKW
62  *   * AvgKW
63  * * VehicleSpeed
64  * * Odometer
65  * * Transmission
66  *   * ShiftPosition
67  * * ExteriorBrightness
68  * * NightMode
69  * * DirectionIndicationINST
70  * * DirectionIndicationMS
71  * * ACCommand
72  * * RecircReq
73  * * FrontTSetRightCmd
74  * * FrontTSetLeftCmd
75  * * FrontBlwrSpeedCmd
76  * * HeatedSeatFRModeRequest
77  * * HeatedSeatFRRequest
78  * * HeatedSeatFLModeRequest
79  * * HeatedSeatFLRequest
80  * * FLHSDistrCmd
81  * * FRHSDistrCmd
82  *
83  * @class CarIndicator
84  * @constructor
85  */
86 var CarIndicator = function() {
87         "use strict";
88         console.info("Starting up service CarIndicator");
89 };
90
91 function parseInteger(value) {
92         "use strict";
93         return parseInt(value, 10);
94 }
95
96 function parseTirePressure(value) {
97         "use strict";
98         var floatValue = parseFloat(value).toFixed(2);
99         if (floatValue > 180 && floatValue < 220) {
100                 floatValue = "OK";
101         }
102         return floatValue;
103 }
104
105 /**
106  * Array of registered listeners
107  * @type Object
108  * @property _listeners
109  * @private
110  */
111 CarIndicator.prototype._listeners = {};
112
113 /**
114  * Array of registered listener IDs.
115  * @type Array
116  * @property _listenerIDs
117  * @private
118  */
119 CarIndicator.prototype._listenerIDs = [];
120
121 /**
122  * Signal mapping table.
123  * Each entry should form an object
124  * @property _mappingTable
125  * @private
126  * @type Object
127  */
128 CarIndicator.prototype._mappingTable = {
129         /*
130         ZONE_None   = 000000;
131         ZONE_Front  = 000001;
132         ZONE_Middle = 000010;
133         ZONE_Right  = 000100;
134         ZONE_Left   = 001000;
135         ZONE_Rear   = 010000;
136         ZONE_Center = 100000;
137         */
138         /* this is for steeringWheel game controler */
139         "SteeringWheelAngle" : {
140                 propertyName : "SteeringWheelAngle",
141                 callBackPropertyName : "SteeringWheelAngle",
142                 subscribeName : "steeringWheel",
143                 conversionFunction : function(value) {
144                         "use strict";
145                         value = parseInt(value, 10);
146                         var returnValue = 0;
147                         if (value <= 180 && value > 0) {
148                                 returnValue = (1 * (value / 6)) - 30;
149                         } else if (value <= 360 && value > 180) {
150                                 returnValue = ((value - 179) / 6);
151                         } else if (value === 0) {
152                                 returnValue = -30;
153                         }
154                         return returnValue;
155                 }
156         },
157         "WheelBrake" : {
158                 propertyName : "Engaged",
159                 callBackPropertyName : "WheelBrake",
160                 subscribeName : "brakeOperation"
161         },
162         /* end steeringWheel game controler*/
163         "TirePressureLeftFront" : {
164                 propertyName : "leftFront",
165                 callBackPropertyName : "tirePressureLeftFront",
166                 subscribeName : "tire",
167                 conversionFunction : parseTirePressure,
168                 zone : new Zone(["Front","Left"])
169         },
170         "TirePressureRightFront" : {
171                 propertyName : "rightFront",
172                 callBackPropertyName : "tirePressureRightFront",
173                 subscribeName : "tire",
174                 conversionFunction : parseTirePressure,
175                 zone : new Zone(["Front","Right"])
176         },
177         "TirePressureLeftRear" : {
178                 propertyName : "leftRear",
179                 callBackPropertyName : "tirePressureLeftRear",
180                 subscribeName : "tire",
181                 conversionFunction : parseTirePressure,
182                 zone : new Zone(["Rear","Left"])
183         },
184         "TirePressureRightRear" : {
185                 propertyName : "rightRear",
186                 callBackPropertyName : "tirePressureRightRear",
187                 subscribeName : "tire",
188                 conversionFunction : parseTirePressure,
189                 zone : new Zone(["Rear","Right"])
190         },
191         "ChildLock" : {
192                 propertyName : "ChildLockStatus",
193                 callBackPropertyName : "childLock",
194                 subscribeName : "childSafetyLock"
195         },
196         "FrontDefrost" : {
197                 propertyName : "Defrost",
198                 callBackPropertyName : "frontDefrost",
199                 subscribeName : "defrost"
200         },
201         "RearDefrost" : {
202                 propertyName : "Defrost",
203                 callBackPropertyName : "rearDefrost",
204                 subscribeName : "defrost"
205         },
206         "FanSpeed" : {
207                 propertyName : "FanSpeed",
208                 callBackPropertyName : "fanSpeed",
209                 subscribeName : "climateControl",
210                 conversionFunction : parseInteger
211         },
212         "TargetTemperatureRight" : {
213                 propertyName : "TargetTemperature",
214                 callBackPropertyName : "targetTemperatureRight",
215                 subscribeName : "climateControl",
216                 conversionFunction : parseInteger,
217                 zone : new Zone(["Right"])
218         },
219         "TargetTemperatureLeft" : {
220                 propertyName : "TargetTemperature",
221                 callBackPropertyName : "targetTemperatureLeft",
222                 subscribeName : "climateControl",
223                 conversionFunction : parseInteger,
224                 zone : new Zone(["Left"])
225         },
226         "Hazard" : {
227                 propertyName : "Hazard",
228                 callBackPropertyName : "hazard",
229                 subscribeName : "lightStatus"
230         },
231         "Head" : {
232                 propertyName : "Head",
233                 callBackPropertyName : "frontLights",
234                 subscribeName : "lightStatus"
235         },
236         "SeatHeaterRight" : {
237                 propertyName : "SeatHeater",
238                 callBackPropertyName : "seatHeaterRight",
239                 subscribeName : "climateControl",
240                 zone : new Zone(["Right"])
241         },
242         "SeatHeaterLeft" : {
243                 propertyName : "SeatHeater",
244                 callBackPropertyName : "seatHeaterLeft",
245                 subscribeName : "climateControl",
246                 zone : new Zone(["Left"])
247         },
248         "Parking" : {
249                 propertyName : "Parking",
250                 callBackPropertyName : "rearLights",
251                 subscribeName : "lightStatus",
252         },
253         "AirConditioning" : {
254                 propertyName : "AirConditioning",
255                 callBackPropertyName : "fan",
256                 subscribeName : "climateControl"
257         },
258         "AirRecirculation" : {
259                 propertyName : "AirRecirculation",
260                 callBackPropertyName : "airRecirculation",
261                 subscribeName : "climateControl"
262         },
263         "AirflowDirection" : {
264                 propertyName : "AirflowDirection",
265                 callBackPropertyName : "airflowDirection",
266                 subscribeName : "climateControl",
267                 conversionFunction : parseInteger
268         },
269         "BatteryStatus" : {
270                 propertyName : "BatteryStatus",
271                 callBackPropertyName : "batteryStatus",
272                 subscribeName : "batteryStatus",
273                 conversionFunction : parseInteger
274         },
275         "FullBatteryRange" : {
276                 propertyName : "FullBatteryRange",
277                 callBackPropertyName : "fullBatteryRange",
278                 conversionFunction : parseInteger
279         },
280         "Exterior" : {
281                 propertyName : "Exterior",
282                 callBackPropertyName : "outsideTemp",
283                 subscribeName : "temperature",
284                 conversionFunction : parseInteger
285         },
286         "Interior" : {
287                 propertyName : "Interior",
288                 callBackPropertyName : "insideTemp",
289                 subscribeName : "temperature",
290                 conversionFunction : parseInteger
291         },
292         "WheelAngle" : {
293                 propertyName : "FrontWheelRadius",
294                 callBackPropertyName : "wheelAngle",
295                 //subscribeName : "wheelConfiguration",
296                 conversionFunction : parseInteger
297         },
298         "Weather" : {
299                 propertyName : "Weather",
300                 callBackPropertyName : "weather",
301                 conversionFunction : parseInteger
302         },
303         "AvgKW" : {
304                 propertyName : "AvgKW",
305                 callBackPropertyName : "avgKW",
306                 //subscribeName : "AvgKW",
307                 conversionFunction : function(newValue) {
308                         "use strict";
309                         return parseFloat(newValue).toFixed(2);
310                 }
311         },
312         "VehicleSpeed" : {
313                 propertyName : "VehicleSpeed",
314                 callBackPropertyName : "speed",
315                 subscribeName : "vehicleSpeed",
316                 conversionFunction : parseInteger
317         },
318         "Odometer" : {
319                 propertyName : "Odometer",
320                 callBackPropertyName : "odoMeter",
321                 subscribeName : "odometer",
322                 conversionFunction : parseInteger
323         },
324         "TransmissionShiftPosition" : {
325                 propertyName : "ShiftPosition",
326                 callBackPropertyName : "gear",
327                 conversionFunction : function(value) {
328                         "use strict";
329                         switch (value) {
330                         case 0:
331                                 value = "N";
332                                 break;
333                         case 64:
334                                 value = "C";
335                                 break;
336                         case 96:
337                                 value = "D";
338                                 break;
339                         case 128:
340                                 value = "R";
341                                 break;
342                         case 255:
343                                 value = "P";
344                                 break;
345                         }
346                         return value;
347                 },
348                 subscribeName : "transmission"
349         },
350         "Randomize" : {
351                 propertyName : "Randomize",
352                 callBackPropertyName : "randomize",
353                 subscribeName : "Randomize"
354         },
355         "ExteriorBrightness" : {
356                 propertyName : "ExteriorBrightness",
357                 callBackPropertyName : "exteriorBrightness"
358         },
359         "NightMode" : {
360                 propertyName : "NightMode",
361                 callBackPropertyName : "nightMode",
362                 subscribeName : "nightMode"
363         },
364         "DirectionIndicationINST" : {
365                 propertyName : "DirectionIndicationINST",
366                 callBackPropertyName : "DirectionIndicationINST",
367                 //subscribeName : "DirectionIndicationINST"
368         },
369         "DirectionIndicationMS" : {
370                 propertyName : "DirectionIndicationMS",
371                 callBackPropertyName : "DirectionIndicationMS",
372                 //subscribeName : "DirectionIndicationMS"
373         },
374         "ACCommand" : {
375                 propertyName : "ACCommand",
376                 callBackPropertyName : "ACCommand",
377                 //subscribeName : "ACCommand"
378         },
379         "RecircReq" : {
380                 propertyName : "RecircReq",
381                 callBackPropertyName : "RecircReq",
382                 //subscribeName : "RecircReq"
383         },
384         "FrontTSetRightCmd" : {
385                 propertyName : "FrontTSetRightCmd",
386                 callBackPropertyName : "FrontTSetRightCmd",
387                 //subscribeName : "FrontTSetRightCmd"
388         },
389         "FrontTSetLeftCmd" : {
390                 propertyName : "FrontTSetLeftCmd",
391                 callBackPropertyName : "FrontTSetLeftCmd",
392                 //subscribeName : "FrontTSetLeftCmd"
393         },
394         "FrontBlwrSpeedCmd" : {
395                 propertyName : "FrontBlwrSpeedCmd",
396                 callBackPropertyName : "FrontBlwrSpeedCmd",
397                 //subscribeName : "FrontBlwrSpeedCmd"
398         },
399         "HeatedSeatFRModeRequest" : {
400                 propertyName : "HeatedSeatFRModeRequest",
401                 callBackPropertyName : "HeatedSeatFRModeRequest",
402                 //subscribeName : "HeatedSeatFRModeRequest"
403         },
404         "HeatedSeatFRRequest" : {
405                 propertyName : "HeatedSeatFRRequest",
406                 callBackPropertyName : "HeatedSeatFRRequest",
407                 //subscribeName : "HeatedSeatFRRequest"
408         },
409         "HeatedSeatFLModeRequest" : {
410                 propertyName : "HeatedSeatFLModeRequest",
411                 callBackPropertyName : "HeatedSeatFLModeRequest",
412                 //subscribeName : "HeatedSeatFLModeRequest"
413         },
414         "HeatedSeatFLRequest" : {
415                 propertyName : "HeatedSeatFLRequest",
416                 callBackPropertyName : "HeatedSeatFLRequest",
417                 //subscribeName : "HeatedSeatFLRequest"
418         },
419         "FLHSDistrCmd" : {
420                 propertyName : "FLHSDistrCmd",
421                 callBackPropertyName : "FLHSDistrCmd",
422                 //subscribeName : "FLHSDistrCmd"
423         },
424         "FRHSDistrCmd" : {
425                 propertyName : "FRHSDistrCmd",
426                 callBackPropertyName : "FRHSDistrCmd",
427                 //subscribeName : "FRHSDistrCmd"
428         }
429 };
430
431 /**
432  * This method adds listener object for car events. Object should define function callbacks taking signal names from mapping table, e.g.:
433  * @example
434  *     {
435  *        onBatteryChange: function(newValue, oldValue) {}
436  *     }
437  * Methods are called back with new and last known values.
438  * @method addListener
439  * @param callback {Object} object with callback functions.
440  * @return {Integer} WatchID for later removal of listener.
441  */
442 CarIndicator.prototype.addListener = function(aCallbackObject) {
443         "use strict";
444         var id = Math.floor(Math.random() * 1000000);
445         var self = this;
446         this._listeners[id] = aCallbackObject;
447         this._listenerIDs.push(id);
448
449         var subscribeCallback = function(data) {
450                 self.onDataUpdate(data, self);
451         };
452         for ( var i in aCallbackObject) {
453                 if (aCallbackObject.hasOwnProperty(i)) {
454                         var prop = i.replace("on", "").replace("Changed", "");
455
456                         for ( var signal in this._mappingTable) {
457                                 if (this._mappingTable.hasOwnProperty(signal)) {
458                                         var mapping = this._mappingTable[signal];
459                                         var zone = mapping.zone;
460                                         var subscribeName = signal;
461
462                                         if (mapping.subscribeName !== undefined) {
463                                                 subscribeName = mapping.subscribeName;
464                                         }
465
466                                         if (mapping.callBackPropertyName.toLowerCase() === prop.toLowerCase() && !mapping.subscribeCount) {
467                                                 mapping.subscribeCount = typeof (mapping.subscribeCount) === 'undefined' ? 0 : mapping.subscribeCount++;
468
469                                                 if (typeof (tizen) !== 'undefined' && tizen.vehicle !== undefined && tizen.vehicle[subscribeName] !== undefined) {
470                                                         if (!(subscribeName.toString().trim().toLowerCase() === "nightmode" && id === this._listenerIDs[0])) {
471                                                                 if (tizen.vehicle[subscribeName]){
472                                                                         var setUpData = tizen.vehicle[subscribeName].get(zone);
473                                                                         if (setUpData !== undefined)
474                                                                                 self.onDataUpdate(setUpData, self, id);
475                                                                 }
476                                                         }
477                                                         if (typeof (tizen.vehicle[subscribeName].subscribe) !== undefined)
478                                                         {
479                                                                 console.log("Modello: Subscribing to AMB signal - " + subscribeName);
480                                                                 tizen.vehicle[subscribeName].subscribe(subscribeCallback, zone);
481                                                         }
482                                                 } else {
483                                                         if (tizen.vehicle[subscribeName] === undefined)
484                                                                 console.warn(subscribeName + " is not available to subscribe to");
485                                                         else
486                                                                 console.warn("Tizen API is not available, cannot subscribe to signal", signal);
487                                                 }
488                                         }
489                                 }
490                         }
491                 }
492         }
493
494         return id;
495 };
496 /**
497  * This method is call as callback if data oon tizen.vehicle was change onDataUpdate
498  * @method onDataUpdate
499  * @param data {object} object whit new data.
500  * @param self {object} this carIndicator Object.
501  * @param lisenersID {int} id of listener.
502  */
503 CarIndicator.prototype.onDataUpdate = function(data, self, lisenersID) {
504         "use strict";
505         if (data !== undefined) {
506                 if (data.zone !== undefined)
507                         var zone = data.zone.toString(2);
508                 else
509                         var zone = "0";
510                 var mapping;
511
512                 for ( var property in data) {
513                         if (data.hasOwnProperty(property)) {
514                                 mapping = undefined;
515                                 if (property !== "time" && property !== "zone" && property.search("Sequence") === -1) {
516                                         for ( var element in self._mappingTable) {
517                                                 if (self._mappingTable.hasOwnProperty(element)) {
518                                                         if (self._mappingTable[element].propertyName.toLowerCase() === property.toLowerCase()) {
519                                                                 /* jshint bitwise: false */
520                                                                 if (!(zone ^ self._mappingTable[element].zone)) {
521                                                                         /* jshint bitwise: true */
522                                                                         mapping = self._mappingTable[element];
523                                                                         break;
524                                                                 }
525                                                         }
526                                                 }
527                                         }
528
529                                         if (typeof (mapping) !== 'undefined') {
530                                                 var value = data[property];
531                                                 value = mapping.conversionFunction ? mapping.conversionFunction(value) : value;
532
533                                                 var oldValue = self.status[mapping.callBackPropertyName];
534                                                 if (oldValue !== value || property.toUpperCase() === "nightMode".toUpperCase()) {
535                                                         console.info("AMB property '" + property + "' has changed to new value:" + value);
536                                                         self.status[mapping.callBackPropertyName] = value;
537
538                                                         var callbackName = "on" + mapping.callBackPropertyName[0].toUpperCase() + mapping.callBackPropertyName.substring(1) + "Changed";
539                                                         var listener;
540
541                                                         if (lisenersID !== undefined) {
542                                                                 listener = self._listeners[lisenersID];
543
544                                                                 if (typeof (listener[callbackName]) === 'function') {
545                                                                         try {
546                                                                                 listener[callbackName](value, oldValue);
547                                                                         } catch (ex) {
548                                                                                 console.error("Error occured during executing listener", ex);
549                                                                         }
550                                                                 }
551                                                         } else {
552                                                                 for ( var i in self._listeners) {
553                                                                         if (self._listeners.hasOwnProperty(i)) {
554                                                                                 listener = self._listeners[i];
555
556                                                                                 if (typeof (listener[callbackName]) === 'function') {
557                                                                                         try {
558                                                                                                 listener[callbackName](value, oldValue);
559                                                                                         } catch (ex) {
560                                                                                                 console.error("Error occured during executing listener", ex);
561                                                                                         }
562                                                                                 }
563                                                                         }
564                                                                 }
565                                                         }
566                                                 }
567
568                                         } else {
569                                                 console.warn("Mapping for property '" + property + "' is not defined");
570                                         }
571                                 }
572                         }
573                 }
574         }
575 };
576
577 /**
578  * This method removes previosly added listener object. Use WatchID returned from addListener method.
579  * @method removeListener
580  * @param aId {Integer} WatchID.
581  */
582 CarIndicator.prototype.removeListener = function(aId) {
583         "use strict";
584         var listener = this._listeners[aId];
585
586         for ( var i in listener) {
587                 if (listener.hasOwnProperty(i)) {
588                         var prop = i.replace("on", "").replace("Changed", "");
589
590                         for ( var signal in this._mappingTable) {
591                                 if (this._mappingTable.hasOwnProperty(signal)) {
592                                         var mapping = this._mappingTable[signal];
593
594                                         if (mapping.subscribeCount === 0) { // Last signal, unscubscribe
595                                                 tizen.vehicle.unsubscribe(signal);
596                                                 mapping.subscribeCount = undefined;
597                                         } else if (typeof (mapping.subscribeCount) !== 'undefined') {
598                                                 mapping.subscribeCount--;
599                                         }
600                                 }
601                         }
602                 }
603         }
604
605         this._listeners[aId] = undefined;
606 };
607
608 /**
609  * status object
610  * @property status
611  * @type Object
612  * @private
613  */
614 CarIndicator.prototype.status = {
615         fanSpeed : 0,
616         targetTemperatureRight : 0,
617         targetTemperatureLeft : 0,
618         hazard : false,
619         frontDefrost : false,
620         rearDefrost : false,
621         frontLeftwhell : "",
622         frontRightwhell : "",
623         rearLeftwhell : "",
624         rearRightwhell : "",
625         childLock : false,
626         frontLights : false,
627         rearLights : false,
628         fan : false,
629         seatHeaterRight : 0,
630         seatHeaterLeft : 0,
631         airRecirculation : false,
632         airflowDirection : 0,
633         batteryStatus : 58,
634         fullBatteryRange : 350,
635         outsideTemp : 74.2,
636         insideTemp : 68.2,
637         wheelAngle : 0,
638         weather : 1,
639         avgKW : 0.28,
640         speed : 65,
641         odoMeter : 75126,
642         gear : "D",
643         nightMode : false,
644         randomize : false,
645         exteriorBrightness : 1000
646 };
647
648 /**
649  * This method return status object in callback
650  * @method getStatus
651  * @param callback {function} callback function.
652  */
653 CarIndicator.prototype.getStatus = function(callback) {
654         "use strict";
655         callback(this.status);
656 };
657
658 /**
659  * this method set status for property in tizen.vehicle and status object
660  * @method setStatus
661  * @param indicator {string} indicator name.
662  * @param status {??} ??.
663  * @param text_status {string} new status .
664  * @param callback {function} callback function.
665  */
666 CarIndicator.prototype.setStatus = function(indicator, newValue, callback, zone) {
667         "use strict";
668         var mappingElement, mappingProperty;
669         for ( var element in this._mappingTable) {
670                 if (this._mappingTable.hasOwnProperty(element)) {
671                         mappingProperty = undefined;
672                         if (this._mappingTable[element].callBackPropertyName.toLowerCase() === indicator.toLowerCase()) {
673                                 mappingElement = this._mappingTable[element];
674                                 mappingProperty = this._mappingTable[element].propertyName;
675                                 break;
676                         }
677                 }
678         }
679
680         // this.status[indicator] = status === "true";
681         if (mappingProperty !== undefined) {
682                 var objectName = mappingElement.subscribeName;
683                 var propertyZone = parseInt(mappingElement.zone, 2);
684                 var propertyValue = {};
685                 propertyValue[mappingProperty] = newValue;
686                 propertyValue.zone = propertyZone;
687
688                 tizen.vehicle.set(objectName, propertyValue, function(msg) {
689                         console.error("Set error: " + msg);
690                 });
691         }
692         if (!!callback) {
693                 callback();
694         }
695 };