0aa50ab5b87ccc3036c21d841a96067a9f5a22b3
[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 : "deadReckoning",
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 : "WheelBrake"
161         },
162         /* end steeringWheel game controler*/
163         "TirePressureLeftFront" : {
164                 propertyName : "leftFront",
165                 callBackPropertyName : "tirePressureLeftFront",
166                 subscribeName : "Tire",
167                 conversionFunction : parseTirePressure,
168                 zone : ["Front","Left"]
169         },
170         "TirePressureRightFront" : {
171                 propertyName : "rightFront",
172                 callBackPropertyName : "tirePressureRightFront",
173                 subscribeName : "Tire",
174                 conversionFunction : parseTirePressure,
175                 zone : ["Front","Right"]
176         },
177         "TirePressureLeftRear" : {
178                 propertyName : "leftRear",
179                 callBackPropertyName : "tirePressureLeftRear",
180                 subscribeName : "Tire",
181                 conversionFunction : parseTirePressure,
182                 zone : ["Rear","Left"]
183         },
184         "TirePressureRightRear" : {
185                 propertyName : "rightRear",
186                 callBackPropertyName : "tirePressureRightRear",
187                 subscribeName : "Tire",
188                 conversionFunction : parseTirePressure,
189                 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 : "defrostWindshield"
200         },
201         "RearDefrost" : {
202                 propertyName : "Defrost",
203                 callBackPropertyName : "rearDefrost",
204                 subscribeName : "defrostRearWindow"
205         },
206         "FanSpeed" : {
207                 propertyName : "FanSpeed",
208                 callBackPropertyName : "fanSpeed",
209                 subscribeName : "fanSpeedLevel",
210                 conversionFunction : parseInteger
211         },
212         "TargetTemperatureRight" : {
213                 propertyName : "TargetTemperature",
214                 callBackPropertyName : "targetTemperatureRight",
215                 subscribeName : "targetTemperature",
216                 conversionFunction : parseInteger,
217                 zone : ["Right"]
218         },
219         "TargetTemperatureLeft" : {
220                 propertyName : "TargetTemperature",
221                 callBackPropertyName : "targetTemperatureLeft",
222                 subscribeName : "targetTemperature",
223                 conversionFunction : parseInteger,
224                 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 : ["Right"]
241         },
242         "SeatHeaterLeft" : {
243                 propertyName : "SeatHeater",
244                 callBackPropertyName : "seatHeaterLeft",
245                 subscribeName : "climateControl",
246                 zone : ["Left"]
247         },
248         "Parking" : {
249                 propertyName : "Parking",
250                 callBackPropertyName : "rearLights",
251                 subscribeName : "parkingLights",
252                 zone : "None"
253         },
254         "AirConditioning" : {
255                 propertyName : "AirConditioning",
256                 callBackPropertyName : "fan",
257                 subscribeName : "climateControl"
258         },
259         "AirRecirculation" : {
260                 propertyName : "AirRecirculation",
261                 callBackPropertyName : "airRecirculation",
262                 subscribeName : "climateControl"
263         },
264         "AirflowDirection" : {
265                 propertyName : "AirflowDirection",
266                 callBackPropertyName : "airflowDirection",
267                 subscribeName : "climateControl",
268                 conversionFunction : parseInteger
269         },
270         "BatteryStatus" : {
271                 propertyName : "BatteryStatus",
272                 callBackPropertyName : "batteryStatus",
273                 subscribeName : "batteryStatus",
274                 conversionFunction : parseInteger
275         },
276         "FullBatteryRange" : {
277                 propertyName : "FullBatteryRange",
278                 callBackPropertyName : "fullBatteryRange",
279                 conversionFunction : parseInteger
280         },
281         "Exterior" : {
282                 propertyName : "Exterior",
283                 callBackPropertyName : "outsideTemp",
284                 subscribeName : "temperature",
285                 conversionFunction : parseInteger
286         },
287         "Interior" : {
288                 propertyName : "Interior",
289                 callBackPropertyName : "insideTemp",
290                 subscribeName : "temperature",
291                 conversionFunction : parseInteger
292         },
293         "WheelAngle" : {
294                 propertyName : "FrontWheelRadius",
295                 callBackPropertyName : "wheelAngle",
296                 subscribeName : "wheelConfiguration",
297                 conversionFunction : parseInteger
298         },
299         "Weather" : {
300                 propertyName : "Weather",
301                 callBackPropertyName : "weather",
302                 conversionFunction : parseInteger
303         },
304         "AvgKW" : {
305                 propertyName : "AvgKW",
306                 callBackPropertyName : "avgKW",
307                 subscribeName : "AvgKW",
308                 conversionFunction : function(newValue) {
309                         "use strict";
310                         return parseFloat(newValue).toFixed(2);
311                 }
312         },
313         "VehicleSpeed" : {
314                 propertyName : "VehicleSpeed",
315                 callBackPropertyName : "speed",
316                 subscribeName : "vehicleSpeed",
317                 conversionFunction : parseInteger
318         },
319         "Odometer" : {
320                 propertyName : "Odometer",
321                 callBackPropertyName : "odoMeter",
322                 subscribeName : "odometer",
323                 conversionFunction : parseInteger
324         },
325         "TransmissionShiftPosition" : {
326                 propertyName : "ShiftPosition",
327                 callBackPropertyName : "gear",
328                 conversionFunction : function(value) {
329                         "use strict";
330                         switch (value) {
331                         case 0:
332                                 value = "N";
333                                 break;
334                         case 64:
335                                 value = "C";
336                                 break;
337                         case 96:
338                                 value = "D";
339                                 break;
340                         case 128:
341                                 value = "R";
342                                 break;
343                         case 255:
344                                 value = "P";
345                                 break;
346                         }
347                         return value;
348                 },
349                 subscribeName : "transmission"
350         },
351         "Randomize" : {
352                 propertyName : "Randomize",
353                 callBackPropertyName : "randomize",
354                 subscribeName : "Randomize"
355         },
356         "ExteriorBrightness" : {
357                 propertyName : "ExteriorBrightness",
358                 callBackPropertyName : "exteriorBrightness"
359         },
360         "NightMode" : {
361                 propertyName : "NightMode",
362                 callBackPropertyName : "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') {
470                                                         if (!(subscribeName.toString().trim().toLowerCase() === "nightmode" && id === this._listenerIDs[0])) {
471                                                                 var setUpData = tizen.vehicle[subscribeName].get(zone);
472                                                                 self.onDataUpdate(setUpData, self, id);
473                                                         }
474                                                         tizen.vehicle[subscribeName].subscribe(subscribeCallback, zone);
475                                                 } else {
476                                                         console.warn("Tizen API is not available, cannot subscribe to signal", signal);
477                                                 }
478                                         }
479                                 }
480                         }
481                 }
482         }
483
484         return id;
485 };
486 /**
487  * This method is call as callback if data oon tizen.vehicle was change onDataUpdate
488  * @method onDataUpdate
489  * @param data {object} object whit new data.
490  * @param self {object} this carIndicator Object.
491  * @param lisenersID {int} id of listener.
492  */
493 CarIndicator.prototype.onDataUpdate = function(data, self, lisenersID) {
494         "use strict";
495         if (data !== undefined) {
496                 var zone = data.zone.toString(2);
497                 var mapping;
498
499                 for ( var property in data) {
500                         if (data.hasOwnProperty(property)) {
501                                 mapping = undefined;
502                                 if (property !== "time" && property !== "zone" && property.search("Sequence") === -1) {
503                                         for ( var element in self._mappingTable) {
504                                                 if (self._mappingTable.hasOwnProperty(element)) {
505                                                         if (self._mappingTable[element].propertyName.toLowerCase() === property.toLowerCase()) {
506                                                                 /* jshint bitwise: false */
507                                                                 if (!(zone ^ self._mappingTable[element].zone)) {
508                                                                         /* jshint bitwise: true */
509                                                                         mapping = self._mappingTable[element];
510                                                                         break;
511                                                                 }
512                                                         }
513                                                 }
514                                         }
515
516                                         if (typeof (mapping) !== 'undefined') {
517                                                 var value = data[property];
518                                                 value = mapping.conversionFunction ? mapping.conversionFunction(value) : value;
519
520                                                 var oldValue = self.status[mapping.callBackPropertyName];
521                                                 if (oldValue !== value || property.toUpperCase() === "nightMode".toUpperCase()) {
522                                                         console.info("AMB property '" + property + "' has changed to new value:" + value);
523                                                         self.status[mapping.callBackPropertyName] = value;
524
525                                                         var callbackName = "on" + mapping.callBackPropertyName[0].toUpperCase() + mapping.callBackPropertyName.substring(1) + "Changed";
526                                                         var listener;
527
528                                                         if (lisenersID !== undefined) {
529                                                                 listener = self._listeners[lisenersID];
530
531                                                                 if (typeof (listener[callbackName]) === 'function') {
532                                                                         try {
533                                                                                 listener[callbackName](value, oldValue);
534                                                                         } catch (ex) {
535                                                                                 console.error("Error occured during executing listener", ex);
536                                                                         }
537                                                                 }
538                                                         } else {
539                                                                 for ( var i in self._listeners) {
540                                                                         if (self._listeners.hasOwnProperty(i)) {
541                                                                                 listener = self._listeners[i];
542
543                                                                                 if (typeof (listener[callbackName]) === 'function') {
544                                                                                         try {
545                                                                                                 listener[callbackName](value, oldValue);
546                                                                                         } catch (ex) {
547                                                                                                 console.error("Error occured during executing listener", ex);
548                                                                                         }
549                                                                                 }
550                                                                         }
551                                                                 }
552                                                         }
553                                                 }
554
555                                         } else {
556                                                 console.warn("Mapping for property '" + property + "' is not defined");
557                                         }
558                                 }
559                         }
560                 }
561         }
562 };
563
564 /**
565  * This method removes previosly added listener object. Use WatchID returned from addListener method.
566  * @method removeListener
567  * @param aId {Integer} WatchID.
568  */
569 CarIndicator.prototype.removeListener = function(aId) {
570         "use strict";
571         var listener = this._listeners[aId];
572
573         for ( var i in listener) {
574                 if (listener.hasOwnProperty(i)) {
575                         var prop = i.replace("on", "").replace("Changed", "");
576
577                         for ( var signal in this._mappingTable) {
578                                 if (this._mappingTable.hasOwnProperty(signal)) {
579                                         var mapping = this._mappingTable[signal];
580
581                                         if (mapping.subscribeCount === 0) { // Last signal, unscubscribe
582                                                 tizen.vehicle.unsubscribe(signal);
583                                                 mapping.subscribeCount = undefined;
584                                         } else if (typeof (mapping.subscribeCount) !== 'undefined') {
585                                                 mapping.subscribeCount--;
586                                         }
587                                 }
588                         }
589                 }
590         }
591
592         this._listeners[aId] = undefined;
593 };
594
595 /**
596  * status object
597  * @property status
598  * @type Object
599  * @private
600  */
601 CarIndicator.prototype.status = {
602         fanSpeed : 0,
603         targetTemperatureRight : 0,
604         targetTemperatureLeft : 0,
605         hazard : false,
606         frontDefrost : false,
607         rearDefrost : false,
608         frontLeftwhell : "",
609         frontRightwhell : "",
610         rearLeftwhell : "",
611         rearRightwhell : "",
612         childLock : false,
613         frontLights : false,
614         rearLights : false,
615         fan : false,
616         seatHeaterRight : 0,
617         seatHeaterLeft : 0,
618         airRecirculation : false,
619         airflowDirection : 0,
620         batteryStatus : 58,
621         fullBatteryRange : 350,
622         outsideTemp : 74.2,
623         insideTemp : 68.2,
624         wheelAngle : 0,
625         weather : 1,
626         avgKW : 0.28,
627         speed : 65,
628         odoMeter : 75126,
629         gear : "D",
630         nightMode : false,
631         randomize : false,
632         exteriorBrightness : 1000
633 };
634
635 /**
636  * This method return status object in callback
637  * @method getStatus
638  * @param callback {function} callback function.
639  */
640 CarIndicator.prototype.getStatus = function(callback) {
641         "use strict";
642         callback(this.status);
643 };
644
645 /**
646  * this method set status for property in tizen.vehicle and status object
647  * @method setStatus
648  * @param indicator {string} indicator name.
649  * @param status {??} ??.
650  * @param text_status {string} new status .
651  * @param callback {function} callback function.
652  */
653 CarIndicator.prototype.setStatus = function(indicator, newValue, callback, zone) {
654         "use strict";
655         var mappingElement, mappingProperty;
656         for ( var element in this._mappingTable) {
657                 if (this._mappingTable.hasOwnProperty(element)) {
658                         mappingProperty = undefined;
659                         if (this._mappingTable[element].callBackPropertyName.toLowerCase() === indicator.toLowerCase()) {
660                                 mappingElement = this._mappingTable[element];
661                                 mappingProperty = this._mappingTable[element].propertyName;
662                                 break;
663                         }
664                 }
665         }
666
667         // this.status[indicator] = status === "true";
668         if (mappingProperty !== undefined) {
669                 var objectName = mappingElement.subscribeName;
670                 var propertyZone = parseInt(mappingElement.zone, 2);
671                 var propertyValue = {};
672                 propertyValue[mappingProperty] = newValue;
673                 propertyValue.zone = propertyZone;
674
675                 tizen.vehicle.set(objectName, propertyValue, function(msg) {
676                         console.error("Set error: " + msg);
677                 });
678         }
679         if (!!callback) {
680                 callback();
681         }
682 };