896aac94b6900b5004825f9a404a4f60d50821d8
[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' && 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                                                         //subscribe isn't supported yet, will re-enable once it is
478                                                         //tizen.vehicle[subscribeName].subscribe(subscribeCallback, zone);
479                                                 } else {
480                                                         console.warn("Tizen API is not available, cannot subscribe to signal", signal);
481                                                 }
482                                         }
483                                 }
484                         }
485                 }
486         }
487
488         return id;
489 };
490 /**
491  * This method is call as callback if data oon tizen.vehicle was change onDataUpdate
492  * @method onDataUpdate
493  * @param data {object} object whit new data.
494  * @param self {object} this carIndicator Object.
495  * @param lisenersID {int} id of listener.
496  */
497 CarIndicator.prototype.onDataUpdate = function(data, self, lisenersID) {
498         "use strict";
499         if (data !== undefined) {
500                 if (data.zone !== undefined)
501                         var zone = data.zone.toString(2);
502                 else
503                         var zone = "0";
504                 var mapping;
505
506                 for ( var property in data) {
507                         if (data.hasOwnProperty(property)) {
508                                 mapping = undefined;
509                                 if (property !== "time" && property !== "zone" && property.search("Sequence") === -1) {
510                                         for ( var element in self._mappingTable) {
511                                                 if (self._mappingTable.hasOwnProperty(element)) {
512                                                         if (self._mappingTable[element].propertyName.toLowerCase() === property.toLowerCase()) {
513                                                                 /* jshint bitwise: false */
514                                                                 if (!(zone ^ self._mappingTable[element].zone)) {
515                                                                         /* jshint bitwise: true */
516                                                                         mapping = self._mappingTable[element];
517                                                                         break;
518                                                                 }
519                                                         }
520                                                 }
521                                         }
522
523                                         if (typeof (mapping) !== 'undefined') {
524                                                 var value = data[property];
525                                                 value = mapping.conversionFunction ? mapping.conversionFunction(value) : value;
526
527                                                 var oldValue = self.status[mapping.callBackPropertyName];
528                                                 if (oldValue !== value || property.toUpperCase() === "nightMode".toUpperCase()) {
529                                                         console.info("AMB property '" + property + "' has changed to new value:" + value);
530                                                         self.status[mapping.callBackPropertyName] = value;
531
532                                                         var callbackName = "on" + mapping.callBackPropertyName[0].toUpperCase() + mapping.callBackPropertyName.substring(1) + "Changed";
533                                                         var listener;
534
535                                                         if (lisenersID !== undefined) {
536                                                                 listener = self._listeners[lisenersID];
537
538                                                                 if (typeof (listener[callbackName]) === 'function') {
539                                                                         try {
540                                                                                 listener[callbackName](value, oldValue);
541                                                                         } catch (ex) {
542                                                                                 console.error("Error occured during executing listener", ex);
543                                                                         }
544                                                                 }
545                                                         } else {
546                                                                 for ( var i in self._listeners) {
547                                                                         if (self._listeners.hasOwnProperty(i)) {
548                                                                                 listener = self._listeners[i];
549
550                                                                                 if (typeof (listener[callbackName]) === 'function') {
551                                                                                         try {
552                                                                                                 listener[callbackName](value, oldValue);
553                                                                                         } catch (ex) {
554                                                                                                 console.error("Error occured during executing listener", ex);
555                                                                                         }
556                                                                                 }
557                                                                         }
558                                                                 }
559                                                         }
560                                                 }
561
562                                         } else {
563                                                 console.warn("Mapping for property '" + property + "' is not defined");
564                                         }
565                                 }
566                         }
567                 }
568         }
569 };
570
571 /**
572  * This method removes previosly added listener object. Use WatchID returned from addListener method.
573  * @method removeListener
574  * @param aId {Integer} WatchID.
575  */
576 CarIndicator.prototype.removeListener = function(aId) {
577         "use strict";
578         var listener = this._listeners[aId];
579
580         for ( var i in listener) {
581                 if (listener.hasOwnProperty(i)) {
582                         var prop = i.replace("on", "").replace("Changed", "");
583
584                         for ( var signal in this._mappingTable) {
585                                 if (this._mappingTable.hasOwnProperty(signal)) {
586                                         var mapping = this._mappingTable[signal];
587
588                                         if (mapping.subscribeCount === 0) { // Last signal, unscubscribe
589                                                 tizen.vehicle.unsubscribe(signal);
590                                                 mapping.subscribeCount = undefined;
591                                         } else if (typeof (mapping.subscribeCount) !== 'undefined') {
592                                                 mapping.subscribeCount--;
593                                         }
594                                 }
595                         }
596                 }
597         }
598
599         this._listeners[aId] = undefined;
600 };
601
602 /**
603  * status object
604  * @property status
605  * @type Object
606  * @private
607  */
608 CarIndicator.prototype.status = {
609         fanSpeed : 0,
610         targetTemperatureRight : 0,
611         targetTemperatureLeft : 0,
612         hazard : false,
613         frontDefrost : false,
614         rearDefrost : false,
615         frontLeftwhell : "",
616         frontRightwhell : "",
617         rearLeftwhell : "",
618         rearRightwhell : "",
619         childLock : false,
620         frontLights : false,
621         rearLights : false,
622         fan : false,
623         seatHeaterRight : 0,
624         seatHeaterLeft : 0,
625         airRecirculation : false,
626         airflowDirection : 0,
627         batteryStatus : 58,
628         fullBatteryRange : 350,
629         outsideTemp : 74.2,
630         insideTemp : 68.2,
631         wheelAngle : 0,
632         weather : 1,
633         avgKW : 0.28,
634         speed : 65,
635         odoMeter : 75126,
636         gear : "D",
637         nightMode : false,
638         randomize : false,
639         exteriorBrightness : 1000
640 };
641
642 /**
643  * This method return status object in callback
644  * @method getStatus
645  * @param callback {function} callback function.
646  */
647 CarIndicator.prototype.getStatus = function(callback) {
648         "use strict";
649         callback(this.status);
650 };
651
652 /**
653  * this method set status for property in tizen.vehicle and status object
654  * @method setStatus
655  * @param indicator {string} indicator name.
656  * @param status {??} ??.
657  * @param text_status {string} new status .
658  * @param callback {function} callback function.
659  */
660 CarIndicator.prototype.setStatus = function(indicator, newValue, callback, zone) {
661         "use strict";
662         var mappingElement, mappingProperty;
663         for ( var element in this._mappingTable) {
664                 if (this._mappingTable.hasOwnProperty(element)) {
665                         mappingProperty = undefined;
666                         if (this._mappingTable[element].callBackPropertyName.toLowerCase() === indicator.toLowerCase()) {
667                                 mappingElement = this._mappingTable[element];
668                                 mappingProperty = this._mappingTable[element].propertyName;
669                                 break;
670                         }
671                 }
672         }
673
674         // this.status[indicator] = status === "true";
675         if (mappingProperty !== undefined) {
676                 var objectName = mappingElement.subscribeName;
677                 var propertyZone = parseInt(mappingElement.zone, 2);
678                 var propertyValue = {};
679                 propertyValue[mappingProperty] = newValue;
680                 propertyValue.zone = propertyZone;
681
682                 tizen.vehicle.set(objectName, propertyValue, function(msg) {
683                         console.error("Set error: " + msg);
684                 });
685         }
686         if (!!callback) {
687                 callback();
688         }
689 };