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 : "steeringWheel",
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) {
158 propertyName : "Engaged",
159 callBackPropertyName : "WheelBrake",
160 subscribeName : "brakeOperation"
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"])
170 "TirePressureRightFront" : {
171 propertyName : "rightFront",
172 callBackPropertyName : "tirePressureRightFront",
173 subscribeName : "tire",
174 conversionFunction : parseTirePressure,
175 zone : new Zone(["Front","Right"])
177 "TirePressureLeftRear" : {
178 propertyName : "leftRear",
179 callBackPropertyName : "tirePressureLeftRear",
180 subscribeName : "tire",
181 conversionFunction : parseTirePressure,
182 zone : new Zone(["Rear","Left"])
184 "TirePressureRightRear" : {
185 propertyName : "rightRear",
186 callBackPropertyName : "tirePressureRightRear",
187 subscribeName : "tire",
188 conversionFunction : parseTirePressure,
189 zone : new Zone(["Rear","Right"])
192 propertyName : "ChildLockStatus",
193 callBackPropertyName : "childLock",
194 subscribeName : "childSafetyLock"
197 propertyName : "Defrost",
198 callBackPropertyName : "frontDefrost",
199 subscribeName : "defrost"
202 propertyName : "Defrost",
203 callBackPropertyName : "rearDefrost",
204 subscribeName : "defrost"
207 propertyName : "FanSpeed",
208 callBackPropertyName : "fanSpeed",
209 subscribeName : "climateControl",
210 conversionFunction : parseInteger
212 "TargetTemperatureRight" : {
213 propertyName : "TargetTemperature",
214 callBackPropertyName : "targetTemperatureRight",
215 subscribeName : "climateControl",
216 conversionFunction : parseInteger,
217 zone : new Zone(["Right"])
219 "TargetTemperatureLeft" : {
220 propertyName : "TargetTemperature",
221 callBackPropertyName : "targetTemperatureLeft",
222 subscribeName : "climateControl",
223 conversionFunction : parseInteger,
224 zone : new Zone(["Left"])
227 propertyName : "Hazard",
228 callBackPropertyName : "hazard",
229 subscribeName : "lightStatus"
232 propertyName : "Head",
233 callBackPropertyName : "frontLights",
234 subscribeName : "lightStatus"
236 "SeatHeaterRight" : {
237 propertyName : "SeatHeater",
238 callBackPropertyName : "seatHeaterRight",
239 subscribeName : "climateControl",
240 zone : new Zone(["Right"])
243 propertyName : "SeatHeater",
244 callBackPropertyName : "seatHeaterLeft",
245 subscribeName : "climateControl",
246 zone : new Zone(["Left"])
249 propertyName : "Parking",
250 callBackPropertyName : "rearLights",
251 subscribeName : "lightStatus",
253 "AirConditioning" : {
254 propertyName : "AirConditioning",
255 callBackPropertyName : "fan",
256 subscribeName : "climateControl"
258 "AirRecirculation" : {
259 propertyName : "AirRecirculation",
260 callBackPropertyName : "airRecirculation",
261 subscribeName : "climateControl"
263 "AirflowDirection" : {
264 propertyName : "AirflowDirection",
265 callBackPropertyName : "airflowDirection",
266 subscribeName : "climateControl",
267 conversionFunction : parseInteger
270 propertyName : "BatteryStatus",
271 callBackPropertyName : "batteryStatus",
272 subscribeName : "batteryStatus",
273 conversionFunction : parseInteger
275 "FullBatteryRange" : {
276 propertyName : "FullBatteryRange",
277 callBackPropertyName : "fullBatteryRange",
278 conversionFunction : parseInteger
281 propertyName : "Exterior",
282 callBackPropertyName : "outsideTemp",
283 subscribeName : "temperature",
284 conversionFunction : parseInteger
287 propertyName : "Interior",
288 callBackPropertyName : "insideTemp",
289 subscribeName : "temperature",
290 conversionFunction : parseInteger
293 propertyName : "FrontWheelRadius",
294 callBackPropertyName : "wheelAngle",
295 //subscribeName : "wheelConfiguration",
296 conversionFunction : parseInteger
299 propertyName : "Weather",
300 callBackPropertyName : "weather",
301 conversionFunction : parseInteger
304 propertyName : "AvgKW",
305 callBackPropertyName : "avgKW",
306 //subscribeName : "AvgKW",
307 conversionFunction : function(newValue) {
309 return parseFloat(newValue).toFixed(2);
313 propertyName : "VehicleSpeed",
314 callBackPropertyName : "speed",
315 subscribeName : "vehicleSpeed",
316 conversionFunction : parseInteger
319 propertyName : "Odometer",
320 callBackPropertyName : "odoMeter",
321 subscribeName : "odometer",
322 conversionFunction : parseInteger
324 "TransmissionShiftPosition" : {
325 propertyName : "ShiftPosition",
326 callBackPropertyName : "gear",
327 conversionFunction : function(value) {
348 subscribeName : "transmission"
351 propertyName : "Randomize",
352 callBackPropertyName : "randomize",
353 subscribeName : "Randomize"
355 "ExteriorBrightness" : {
356 propertyName : "ExteriorBrightness",
357 callBackPropertyName : "exteriorBrightness"
360 propertyName : "NightMode",
361 callBackPropertyName : "nightMode",
362 subscribeName : "nightMode"
364 "DirectionIndicationINST" : {
365 propertyName : "DirectionIndicationINST",
366 callBackPropertyName : "DirectionIndicationINST",
367 //subscribeName : "DirectionIndicationINST"
369 "DirectionIndicationMS" : {
370 propertyName : "DirectionIndicationMS",
371 callBackPropertyName : "DirectionIndicationMS",
372 //subscribeName : "DirectionIndicationMS"
375 propertyName : "ACCommand",
376 callBackPropertyName : "ACCommand",
377 //subscribeName : "ACCommand"
380 propertyName : "RecircReq",
381 callBackPropertyName : "RecircReq",
382 //subscribeName : "RecircReq"
384 "FrontTSetRightCmd" : {
385 propertyName : "FrontTSetRightCmd",
386 callBackPropertyName : "FrontTSetRightCmd",
387 //subscribeName : "FrontTSetRightCmd"
389 "FrontTSetLeftCmd" : {
390 propertyName : "FrontTSetLeftCmd",
391 callBackPropertyName : "FrontTSetLeftCmd",
392 //subscribeName : "FrontTSetLeftCmd"
394 "FrontBlwrSpeedCmd" : {
395 propertyName : "FrontBlwrSpeedCmd",
396 callBackPropertyName : "FrontBlwrSpeedCmd",
397 //subscribeName : "FrontBlwrSpeedCmd"
399 "HeatedSeatFRModeRequest" : {
400 propertyName : "HeatedSeatFRModeRequest",
401 callBackPropertyName : "HeatedSeatFRModeRequest",
402 //subscribeName : "HeatedSeatFRModeRequest"
404 "HeatedSeatFRRequest" : {
405 propertyName : "HeatedSeatFRRequest",
406 callBackPropertyName : "HeatedSeatFRRequest",
407 //subscribeName : "HeatedSeatFRRequest"
409 "HeatedSeatFLModeRequest" : {
410 propertyName : "HeatedSeatFLModeRequest",
411 callBackPropertyName : "HeatedSeatFLModeRequest",
412 //subscribeName : "HeatedSeatFLModeRequest"
414 "HeatedSeatFLRequest" : {
415 propertyName : "HeatedSeatFLRequest",
416 callBackPropertyName : "HeatedSeatFLRequest",
417 //subscribeName : "HeatedSeatFLRequest"
420 propertyName : "FLHSDistrCmd",
421 callBackPropertyName : "FLHSDistrCmd",
422 //subscribeName : "FLHSDistrCmd"
425 propertyName : "FRHSDistrCmd",
426 callBackPropertyName : "FRHSDistrCmd",
427 //subscribeName : "FRHSDistrCmd"
432 * This method adds listener object for car events. Object should define function callbacks taking signal names from mapping table, e.g.:
435 * onBatteryChange: function(newValue, oldValue) {}
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.
442 CarIndicator.prototype.addListener = function(aCallbackObject) {
444 var id = Math.floor(Math.random() * 1000000);
446 this._listeners[id] = aCallbackObject;
447 this._listenerIDs.push(id);
449 var subscribeCallback = function(data) {
450 self.onDataUpdate(data, self);
452 for ( var i in aCallbackObject) {
453 if (aCallbackObject.hasOwnProperty(i)) {
454 var prop = i.replace("on", "").replace("Changed", "");
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;
462 if (mapping.subscribeName !== undefined) {
463 subscribeName = mapping.subscribeName;
466 if (mapping.callBackPropertyName.toLowerCase() === prop.toLowerCase() && !mapping.subscribeCount) {
467 mapping.subscribeCount = typeof (mapping.subscribeCount) === 'undefined' ? 0 : mapping.subscribeCount++;
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);
477 if (typeof (tizen.vehicle[subscribeName].subscribe) !== undefined)
479 console.log("Modello: Subscribing to AMB signal - " + subscribeName);
480 tizen.vehicle[subscribeName].subscribe(subscribeCallback, zone);
483 if (tizen.vehicle[subscribeName] === undefined)
484 console.warn(subscribeName + " is not available to subscribe to");
486 console.warn("Tizen API is not available, cannot subscribe to signal", signal);
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.
503 CarIndicator.prototype.onDataUpdate = function(data, self, lisenersID) {
505 if (data !== undefined) {
506 if (data.zone !== undefined)
507 var zone = data.zone.toString(2);
512 for ( var property in data) {
513 if (data.hasOwnProperty(property)) {
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];
529 if (typeof (mapping) !== 'undefined') {
530 var value = data[property];
531 value = mapping.conversionFunction ? mapping.conversionFunction(value) : value;
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;
538 var callbackName = "on" + mapping.callBackPropertyName[0].toUpperCase() + mapping.callBackPropertyName.substring(1) + "Changed";
541 if (lisenersID !== undefined) {
542 listener = self._listeners[lisenersID];
544 if (typeof (listener[callbackName]) === 'function') {
546 listener[callbackName](value, oldValue);
548 console.error("Error occured during executing listener", ex);
552 for ( var i in self._listeners) {
553 if (self._listeners.hasOwnProperty(i)) {
554 listener = self._listeners[i];
556 if (typeof (listener[callbackName]) === 'function') {
558 listener[callbackName](value, oldValue);
560 console.error("Error occured during executing listener", ex);
569 console.warn("Mapping for property '" + property + "' is not defined");
578 * This method removes previosly added listener object. Use WatchID returned from addListener method.
579 * @method removeListener
580 * @param aId {Integer} WatchID.
582 CarIndicator.prototype.removeListener = function(aId) {
584 var listener = this._listeners[aId];
586 for ( var i in listener) {
587 if (listener.hasOwnProperty(i)) {
588 var prop = i.replace("on", "").replace("Changed", "");
590 for ( var signal in this._mappingTable) {
591 if (this._mappingTable.hasOwnProperty(signal)) {
592 var mapping = this._mappingTable[signal];
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--;
605 this._listeners[aId] = undefined;
614 CarIndicator.prototype.status = {
616 targetTemperatureRight : 0,
617 targetTemperatureLeft : 0,
619 frontDefrost : false,
622 frontRightwhell : "",
631 airRecirculation : false,
632 airflowDirection : 0,
634 fullBatteryRange : 350,
645 exteriorBrightness : 1000
649 * This method return status object in callback
651 * @param callback {function} callback function.
653 CarIndicator.prototype.getStatus = function(callback) {
655 callback(this.status);
659 * this method set status for property in tizen.vehicle and status object
661 * @param indicator {string} indicator name.
662 * @param status {??} ??.
663 * @param text_status {string} new status .
664 * @param callback {function} callback function.
666 CarIndicator.prototype.setStatus = function(indicator, newValue, callback, zone) {
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;
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;
688 tizen.vehicle.set(objectName, propertyValue, function(msg) {
689 console.error("Set error: " + msg);