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}}.
10 * To attach and detach to particular property register new callback object using {{#crossLink "Bootstrap/carIndicator:addListener"}}{{/crossLink}} method, e.g.:
12 * var listenerId = bootstrap.carIndicator.addListener({
13 * onSteeringWheelAngleChanged: function(newValue){
14 * // Process new value
16 * onWheelBrakeChanged : function(newValue){
17 * // Process new value
21 * // Unregister listener
22 * bootstrap.carIndicator.removeListener(listenerId);
24 * Currently following signals are recognized:
26 * * SteeringWheelAngle
27 * * SteeringWheelAngle
42 * * TargetTemperatureRight
43 * * TargetTemperatureLeft
55 * * ExteriorTemperature
57 * * InteriorTemperature
67 * * ExteriorBrightness
69 * * DirectionIndicationINST
70 * * DirectionIndicationMS
76 * * HeatedSeatFRModeRequest
77 * * HeatedSeatFRRequest
78 * * HeatedSeatFLModeRequest
79 * * HeatedSeatFLRequest
86 var CarIndicator = function() {
88 console.info("Starting up service CarIndicator");
91 function parseInteger(value) {
93 return parseInt(value, 10);
96 function parseTirePressure(value) {
98 var floatValue = parseFloat(value).toFixed(2);
99 if (floatValue > 180 && floatValue < 220) {
106 * Array of registered listeners
108 * @property _listeners
111 CarIndicator.prototype._listeners = {};
114 * Array of registered listener IDs.
116 * @property _listenerIDs
119 CarIndicator.prototype._listenerIDs = [];
122 * Signal mapping table.
123 * Each entry should form an object
124 * @property _mappingTable
128 CarIndicator.prototype._mappingTable = {
132 ZONE_Middle = 000010;
136 ZONE_Center = 100000;
138 /* this is for steeringWheel game controler */
139 "SteeringWheelAngle" : {
140 propertyName : "SteeringWheelAngle",
141 callBackPropertyName : "SteeringWheelAngle",
142 subscribeName : "SteeringWheelAngle",
143 conversionFunction : function(value) {
145 value = parseInt(value, 10);
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) {
160 propertyName : "Engaged",
161 callBackPropertyName : "WheelBrake",
162 subscribeName : "WheelBrake",
165 /* end steeringWheel game controler*/
166 "TirePressureLeftFront" : {
167 propertyName : "leftFront",
168 callBackPropertyName : "tirePressureLeftFront",
169 subscribeName : "TirePressure",
170 conversionFunction : parseTirePressure,
173 "TirePressureRightFront" : {
174 propertyName : "rightFront",
175 callBackPropertyName : "tirePressureRightFront",
176 subscribeName : "TirePressure",
177 conversionFunction : parseTirePressure,
180 "TirePressureLeftRear" : {
181 propertyName : "leftRear",
182 callBackPropertyName : "tirePressureLeftRear",
183 subscribeName : "TirePressure",
184 conversionFunction : parseTirePressure,
187 "TirePressureRightRear" : {
188 propertyName : "rightRear",
189 callBackPropertyName : "tirePressureRightRear",
190 subscribeName : "TirePressure",
191 conversionFunction : parseTirePressure,
195 propertyName : "ChildLockStatus",
196 callBackPropertyName : "childLock",
197 subscribeName : "DoorStatus",
201 propertyName : "Defrost",
202 callBackPropertyName : "frontDefrost",
203 subscribeName : "WindowStatus",
207 propertyName : "Defrost",
208 callBackPropertyName : "rearDefrost",
209 subscribeName : "WindowStatus",
213 propertyName : "FanSpeed",
214 callBackPropertyName : "fanSpeed",
215 subscribeName : "HVAC",
216 conversionFunction : parseInteger,
219 "TargetTemperatureRight" : {
220 propertyName : "TargetTemperature",
221 callBackPropertyName : "targetTemperatureRight",
222 subscribeName : "HVAC",
223 conversionFunction : parseInteger,
226 "TargetTemperatureLeft" : {
227 propertyName : "TargetTemperature",
228 callBackPropertyName : "targetTemperatureLeft",
229 subscribeName : "HVAC",
230 conversionFunction : parseInteger,
234 propertyName : "Hazard",
235 callBackPropertyName : "hazard",
236 subscribeName : "LightStatus",
240 propertyName : "Head",
241 callBackPropertyName : "frontLights",
242 subscribeName : "LightStatus",
245 "SeatHeaterRight" : {
246 propertyName : "SeatHeater",
247 callBackPropertyName : "seatHeaterRight",
248 subscribeName : "HVAC",
252 propertyName : "SeatHeater",
253 callBackPropertyName : "seatHeaterLeft",
254 subscribeName : "HVAC",
258 propertyName : "Parking",
259 callBackPropertyName : "rearLights",
260 subscribeName : "LightStatus",
263 "AirConditioning" : {
264 propertyName : "AirConditioning",
265 callBackPropertyName : "fan",
266 subscribeName : "HVAC",
269 "AirRecirculation" : {
270 propertyName : "AirRecirculation",
271 callBackPropertyName : "airRecirculation",
272 subscribeName : "HVAC",
275 "AirflowDirection" : {
276 propertyName : "AirflowDirection",
277 callBackPropertyName : "airflowDirection",
278 subscribeName : "HVAC",
279 conversionFunction : parseInteger,
283 propertyName : "BatteryStatus",
284 callBackPropertyName : "batteryStatus",
285 conversionFunction : parseInteger,
288 "FullBatteryRange" : {
289 propertyName : "FullBatteryRange",
290 callBackPropertyName : "fullBatteryRange",
291 conversionFunction : parseInteger,
295 propertyName : "Exterior",
296 callBackPropertyName : "outsideTemp",
297 subscribeName : "ExteriorTemperature",
298 conversionFunction : parseInteger,
302 propertyName : "Interior",
303 callBackPropertyName : "insideTemp",
304 subscribeName : "InteriorTemperature",
305 conversionFunction : parseInteger,
309 propertyName : "FrontWheelRadius",
310 callBackPropertyName : "wheelAngle",
311 subscribeName : "WheelInformation",
312 conversionFunction : parseInteger,
316 propertyName : "Weather",
317 callBackPropertyName : "weather",
318 conversionFunction : parseInteger,
322 propertyName : "AvgKW",
323 callBackPropertyName : "avgKW",
324 subscribeName : "AvgKW",
325 conversionFunction : function(newValue) {
327 return parseFloat(newValue).toFixed(2);
332 propertyName : "VehicleSpeed",
333 callBackPropertyName : "speed",
334 conversionFunction : parseInteger,
338 propertyName : "Odometer",
339 callBackPropertyName : "odoMeter",
340 conversionFunction : parseInteger,
343 "TransmissionShiftPosition" : {
344 propertyName : "ShiftPosition",
345 callBackPropertyName : "gear",
346 conversionFunction : function(value) {
367 subscribeName : "Transmission",
371 propertyName : "Randomize",
372 callBackPropertyName : "randomize",
373 subscribeName : "Randomize",
376 "ExteriorBrightness" : {
377 propertyName : "ExteriorBrightness",
378 callBackPropertyName : "exteriorBrightness",
382 propertyName : "NightMode",
383 callBackPropertyName : "nightMode",
386 "DirectionIndicationINST" : {
387 propertyName : "DirectionIndicationINST",
388 callBackPropertyName : "DirectionIndicationINST",
389 subscribeName : "DirectionIndicationINST",
392 "DirectionIndicationMS" : {
393 propertyName : "DirectionIndicationMS",
394 callBackPropertyName : "DirectionIndicationMS",
395 subscribeName : "DirectionIndicationMS",
399 propertyName : "ACCommand",
400 callBackPropertyName : "ACCommand",
401 subscribeName : "ACCommand",
405 propertyName : "RecircReq",
406 callBackPropertyName : "RecircReq",
407 subscribeName : "RecircReq",
410 "FrontTSetRightCmd" : {
411 propertyName : "FrontTSetRightCmd",
412 callBackPropertyName : "FrontTSetRightCmd",
413 subscribeName : "FrontTSetRightCmd",
416 "FrontTSetLeftCmd" : {
417 propertyName : "FrontTSetLeftCmd",
418 callBackPropertyName : "FrontTSetLeftCmd",
419 subscribeName : "FrontTSetLeftCmd",
422 "FrontBlwrSpeedCmd" : {
423 propertyName : "FrontBlwrSpeedCmd",
424 callBackPropertyName : "FrontBlwrSpeedCmd",
425 subscribeName : "FrontBlwrSpeedCmd",
428 "HeatedSeatFRModeRequest" : {
429 propertyName : "HeatedSeatFRModeRequest",
430 callBackPropertyName : "HeatedSeatFRModeRequest",
431 subscribeName : "HeatedSeatFRModeRequest",
434 "HeatedSeatFRRequest" : {
435 propertyName : "HeatedSeatFRRequest",
436 callBackPropertyName : "HeatedSeatFRRequest",
437 subscribeName : "HeatedSeatFRRequest",
440 "HeatedSeatFLModeRequest" : {
441 propertyName : "HeatedSeatFLModeRequest",
442 callBackPropertyName : "HeatedSeatFLModeRequest",
443 subscribeName : "HeatedSeatFLModeRequest",
446 "HeatedSeatFLRequest" : {
447 propertyName : "HeatedSeatFLRequest",
448 callBackPropertyName : "HeatedSeatFLRequest",
449 subscribeName : "HeatedSeatFLRequest",
453 propertyName : "FLHSDistrCmd",
454 callBackPropertyName : "FLHSDistrCmd",
455 subscribeName : "FLHSDistrCmd",
459 propertyName : "FRHSDistrCmd",
460 callBackPropertyName : "FRHSDistrCmd",
461 subscribeName : "FRHSDistrCmd",
467 * This method adds listener object for car events. Object should define function callbacks taking signal names from mapping table, e.g.:
470 * onBatteryChange: function(newValue, oldValue) {}
472 * Methods are called back with new and last known values.
473 * @method addListener
474 * @param callback {Object} object with callback functions.
475 * @return {Integer} WatchID for later removal of listener.
477 CarIndicator.prototype.addListener = function(aCallbackObject) {
479 var id = Math.floor(Math.random() * 1000000);
481 this._listeners[id] = aCallbackObject;
482 this._listenerIDs.push(id);
484 var subscribeCallback = function(data) {
485 self.onDataUpdate(data, self);
487 for ( var i in aCallbackObject) {
488 if (aCallbackObject.hasOwnProperty(i)) {
489 var prop = i.replace("on", "").replace("Changed", "");
491 for ( var signal in this._mappingTable) {
492 if (this._mappingTable.hasOwnProperty(signal)) {
493 var mapping = this._mappingTable[signal];
494 var zone = parseInt(mapping.zone, 2);
495 var subscribeName = signal;
497 if (mapping.subscribeName !== undefined) {
498 subscribeName = mapping.subscribeName;
501 if (mapping.callBackPropertyName.toLowerCase() === prop.toLowerCase() && !mapping.subscribeCount) {
502 mapping.subscribeCount = typeof (mapping.subscribeCount) === 'undefined' ? 0 : mapping.subscribeCount++;
504 if (typeof (tizen) !== 'undefined') {
505 if (!(subscribeName.toString().trim().toLowerCase() === "nightmode" && id === this._listenerIDs[0])) {
506 var setUpData = tizen.vehicle.get(subscribeName, zone);
507 self.onDataUpdate(setUpData, self, id);
510 tizen.vehicle.subscribe(subscribeName, subscribeCallback, zone);
512 console.warn("Tizen API is not available, cannot subscribe to signal", signal);
523 * This method is call as callback if data oon tizen.vehicle was change onDataUpdate
524 * @method onDataUpdate
525 * @param data {object} object whit new data.
526 * @param self {object} this carIndicator Object.
527 * @param lisenersID {int} id of listener.
529 CarIndicator.prototype.onDataUpdate = function(data, self, lisenersID) {
531 if (data !== undefined) {
532 var zone = data.zone.toString(2);
535 for ( var property in data) {
536 if (data.hasOwnProperty(property)) {
538 if (property !== "time" && property !== "zone" && property.search("Sequence") === -1) {
539 for ( var element in self._mappingTable) {
540 if (self._mappingTable.hasOwnProperty(element)) {
541 if (self._mappingTable[element].propertyName.toLowerCase() === property.toLowerCase()) {
542 /* jshint bitwise: false */
543 if (!(zone ^ self._mappingTable[element].zone)) {
544 /* jshint bitwise: true */
545 mapping = self._mappingTable[element];
552 if (typeof (mapping) !== 'undefined') {
553 var value = data[property];
554 value = mapping.conversionFunction ? mapping.conversionFunction(value) : value;
556 var oldValue = self.status[mapping.callBackPropertyName];
557 if (oldValue !== value || property.toUpperCase() === "nightMode".toUpperCase()) {
558 console.info("AMB property '" + property + "' has changed to new value:" + value);
559 self.status[mapping.callBackPropertyName] = value;
561 var callbackName = "on" + mapping.callBackPropertyName[0].toUpperCase() + mapping.callBackPropertyName.substring(1) + "Changed";
564 if (lisenersID !== undefined) {
565 listener = self._listeners[lisenersID];
567 if (typeof (listener[callbackName]) === 'function') {
569 listener[callbackName](value, oldValue);
571 console.error("Error occured during executing listener", ex);
575 for ( var i in self._listeners) {
576 if (self._listeners.hasOwnProperty(i)) {
577 listener = self._listeners[i];
579 if (typeof (listener[callbackName]) === 'function') {
581 listener[callbackName](value, oldValue);
583 console.error("Error occured during executing listener", ex);
592 console.warn("Mapping for property '" + property + "' is not defined");
601 * This method removes previosly added listener object. Use WatchID returned from addListener method.
602 * @method removeListener
603 * @param aId {Integer} WatchID.
605 CarIndicator.prototype.removeListener = function(aId) {
607 var listener = this._listeners[aId];
609 for ( var i in listener) {
610 if (listener.hasOwnProperty(i)) {
611 var prop = i.replace("on", "").replace("Changed", "");
613 for ( var signal in this._mappingTable) {
614 if (this._mappingTable.hasOwnProperty(signal)) {
615 var mapping = this._mappingTable[signal];
617 if (mapping.subscribeCount === 0) { // Last signal, unscubscribe
618 tizen.vehicle.unsubscribe(signal);
619 mapping.subscribeCount = undefined;
620 } else if (typeof (mapping.subscribeCount) !== 'undefined') {
621 mapping.subscribeCount--;
628 this._listeners[aId] = undefined;
637 CarIndicator.prototype.status = {
639 targetTemperatureRight : 0,
640 targetTemperatureLeft : 0,
642 frontDefrost : false,
645 frontRightwhell : "",
654 airRecirculation : false,
655 airflowDirection : 0,
657 fullBatteryRange : 350,
668 exteriorBrightness : 1000
672 * This method return status object in callback
674 * @param callback {function} callback function.
676 CarIndicator.prototype.getStatus = function(callback) {
678 callback(this.status);
682 * this method set status for property in tizen.vehicle and status object
684 * @param indicator {string} indicator name.
685 * @param status {??} ??.
686 * @param text_status {string} new status .
687 * @param callback {function} callback function.
689 CarIndicator.prototype.setStatus = function(indicator, newValue, callback, zone) {
691 var mappingElement, mappingProperty;
692 for ( var element in this._mappingTable) {
693 if (this._mappingTable.hasOwnProperty(element)) {
694 mappingProperty = undefined;
695 if (this._mappingTable[element].callBackPropertyName.toLowerCase() === indicator.toLowerCase()) {
696 mappingElement = this._mappingTable[element];
697 mappingProperty = this._mappingTable[element].propertyName;
703 // this.status[indicator] = status === "true";
704 if (mappingProperty !== undefined) {
705 var objectName = mappingElement.subscribeName;
706 var propertyZone = parseInt(mappingElement.zone, 2);
707 var propertyValue = {};
708 propertyValue[mappingProperty] = newValue;
709 propertyValue.zone = propertyZone;
711 tizen.vehicle.set(objectName, propertyValue, function(msg) {
712 console.error("Set error: " + msg);