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 : "deadReckoning",
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 : "WheelBrake"
162 /* end steeringWheel game controler*/
163 "TirePressureLeftFront" : {
164 propertyName : "leftFront",
165 callBackPropertyName : "tirePressureLeftFront",
166 subscribeName : "Tire",
167 conversionFunction : parseTirePressure,
168 zone : ["Front","Left"]
170 "TirePressureRightFront" : {
171 propertyName : "rightFront",
172 callBackPropertyName : "tirePressureRightFront",
173 subscribeName : "Tire",
174 conversionFunction : parseTirePressure,
175 zone : ["Front","Right"]
177 "TirePressureLeftRear" : {
178 propertyName : "leftRear",
179 callBackPropertyName : "tirePressureLeftRear",
180 subscribeName : "Tire",
181 conversionFunction : parseTirePressure,
182 zone : ["Rear","Left"]
184 "TirePressureRightRear" : {
185 propertyName : "rightRear",
186 callBackPropertyName : "tirePressureRightRear",
187 subscribeName : "Tire",
188 conversionFunction : parseTirePressure,
189 zone : ["Rear","Right"]
192 propertyName : "ChildLockStatus",
193 callBackPropertyName : "childLock",
194 subscribeName : "childSafetyLock"
197 propertyName : "Defrost",
198 callBackPropertyName : "frontDefrost",
199 subscribeName : "defrostWindshield"
202 propertyName : "Defrost",
203 callBackPropertyName : "rearDefrost",
204 subscribeName : "defrostRearWindow"
207 propertyName : "FanSpeed",
208 callBackPropertyName : "fanSpeed",
209 subscribeName : "fanSpeedLevel",
210 conversionFunction : parseInteger
212 "TargetTemperatureRight" : {
213 propertyName : "TargetTemperature",
214 callBackPropertyName : "targetTemperatureRight",
215 subscribeName : "targetTemperature",
216 conversionFunction : parseInteger,
219 "TargetTemperatureLeft" : {
220 propertyName : "TargetTemperature",
221 callBackPropertyName : "targetTemperatureLeft",
222 subscribeName : "targetTemperature",
223 conversionFunction : parseInteger,
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",
243 propertyName : "SeatHeater",
244 callBackPropertyName : "seatHeaterLeft",
245 subscribeName : "climateControl",
249 propertyName : "Parking",
250 callBackPropertyName : "rearLights",
251 subscribeName : "parkingLights",
254 "AirConditioning" : {
255 propertyName : "AirConditioning",
256 callBackPropertyName : "fan",
257 subscribeName : "climateControl"
259 "AirRecirculation" : {
260 propertyName : "AirRecirculation",
261 callBackPropertyName : "airRecirculation",
262 subscribeName : "climateControl"
264 "AirflowDirection" : {
265 propertyName : "AirflowDirection",
266 callBackPropertyName : "airflowDirection",
267 subscribeName : "climateControl",
268 conversionFunction : parseInteger
271 propertyName : "BatteryStatus",
272 callBackPropertyName : "batteryStatus",
273 subscribeName : "batteryStatus",
274 conversionFunction : parseInteger
276 "FullBatteryRange" : {
277 propertyName : "FullBatteryRange",
278 callBackPropertyName : "fullBatteryRange",
279 conversionFunction : parseInteger
282 propertyName : "Exterior",
283 callBackPropertyName : "outsideTemp",
284 subscribeName : "temperature",
285 conversionFunction : parseInteger
288 propertyName : "Interior",
289 callBackPropertyName : "insideTemp",
290 subscribeName : "temperature",
291 conversionFunction : parseInteger
294 propertyName : "FrontWheelRadius",
295 callBackPropertyName : "wheelAngle",
296 subscribeName : "wheelConfiguration",
297 conversionFunction : parseInteger
300 propertyName : "Weather",
301 callBackPropertyName : "weather",
302 conversionFunction : parseInteger
305 propertyName : "AvgKW",
306 callBackPropertyName : "avgKW",
307 subscribeName : "AvgKW",
308 conversionFunction : function(newValue) {
310 return parseFloat(newValue).toFixed(2);
314 propertyName : "VehicleSpeed",
315 callBackPropertyName : "speed",
316 subscribeName : "vehicleSpeed",
317 conversionFunction : parseInteger
320 propertyName : "Odometer",
321 callBackPropertyName : "odoMeter",
322 subscribeName : "odometer",
323 conversionFunction : parseInteger
325 "TransmissionShiftPosition" : {
326 propertyName : "ShiftPosition",
327 callBackPropertyName : "gear",
328 conversionFunction : function(value) {
349 subscribeName : "transmission"
352 propertyName : "Randomize",
353 callBackPropertyName : "randomize",
354 subscribeName : "Randomize"
356 "ExteriorBrightness" : {
357 propertyName : "ExteriorBrightness",
358 callBackPropertyName : "exteriorBrightness"
361 propertyName : "NightMode",
362 callBackPropertyName : "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') {
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);
474 tizen.vehicle[subscribeName].subscribe(subscribeCallback, zone);
476 console.warn("Tizen API is not available, cannot subscribe to signal", signal);
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.
493 CarIndicator.prototype.onDataUpdate = function(data, self, lisenersID) {
495 if (data !== undefined) {
496 var zone = data.zone.toString(2);
499 for ( var property in data) {
500 if (data.hasOwnProperty(property)) {
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];
516 if (typeof (mapping) !== 'undefined') {
517 var value = data[property];
518 value = mapping.conversionFunction ? mapping.conversionFunction(value) : value;
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;
525 var callbackName = "on" + mapping.callBackPropertyName[0].toUpperCase() + mapping.callBackPropertyName.substring(1) + "Changed";
528 if (lisenersID !== undefined) {
529 listener = self._listeners[lisenersID];
531 if (typeof (listener[callbackName]) === 'function') {
533 listener[callbackName](value, oldValue);
535 console.error("Error occured during executing listener", ex);
539 for ( var i in self._listeners) {
540 if (self._listeners.hasOwnProperty(i)) {
541 listener = self._listeners[i];
543 if (typeof (listener[callbackName]) === 'function') {
545 listener[callbackName](value, oldValue);
547 console.error("Error occured during executing listener", ex);
556 console.warn("Mapping for property '" + property + "' is not defined");
565 * This method removes previosly added listener object. Use WatchID returned from addListener method.
566 * @method removeListener
567 * @param aId {Integer} WatchID.
569 CarIndicator.prototype.removeListener = function(aId) {
571 var listener = this._listeners[aId];
573 for ( var i in listener) {
574 if (listener.hasOwnProperty(i)) {
575 var prop = i.replace("on", "").replace("Changed", "");
577 for ( var signal in this._mappingTable) {
578 if (this._mappingTable.hasOwnProperty(signal)) {
579 var mapping = this._mappingTable[signal];
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--;
592 this._listeners[aId] = undefined;
601 CarIndicator.prototype.status = {
603 targetTemperatureRight : 0,
604 targetTemperatureLeft : 0,
606 frontDefrost : false,
609 frontRightwhell : "",
618 airRecirculation : false,
619 airflowDirection : 0,
621 fullBatteryRange : 350,
632 exteriorBrightness : 1000
636 * This method return status object in callback
638 * @param callback {function} callback function.
640 CarIndicator.prototype.getStatus = function(callback) {
642 callback(this.status);
646 * this method set status for property in tizen.vehicle and status object
648 * @param indicator {string} indicator name.
649 * @param status {??} ??.
650 * @param text_status {string} new status .
651 * @param callback {function} callback function.
653 CarIndicator.prototype.setStatus = function(indicator, newValue, callback, zone) {
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;
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;
675 tizen.vehicle.set(objectName, propertyValue, function(msg) {
676 console.error("Set error: " + msg);