APIs

Show:
  1. /**
  2. This module manages active list of remote stations (screens) retrieved from the server
  3. Poll for stations status every n seconds, as well as remote manage each station individually.
  4. @class StationsListView
  5. @constructor
  6. @param {String} i_container element that CompCampaignNavigator inserts itself into
  7. @return {Object} instantiated StationsListView
  8. **/
  9. define(['jquery', 'backbone', 'StationsCollection', 'LiveInput'], function ($, Backbone, StationsCollection, LiveInput) {
  10.  
  11. BB.SERVICES.STATIONS_LIST_VIEW = 'StationsListView';
  12.  
  13. var StationsListView = Backbone.View.extend({
  14.  
  15. /**
  16. Constructor
  17. @method initialize
  18. **/
  19. initialize: function () {
  20. var self = this;
  21.  
  22. BB.comBroker.setService(BB.SERVICES['STATIONS_LIST_VIEW'], self);
  23. self.m_snapshotInProgress = undefined;
  24. self.m_imageReloadCount = 0;
  25. self.m_imagePath = '';
  26. self.m_selected_station_id = undefined;
  27. self.m_property = BB.comBroker.getService(BB.SERVICES['PROPERTIES_VIEW']);
  28. self.m_property.initPanel(Elements.STATION_PROPERTIES);
  29. self.m_stationCollection = new StationsCollection();
  30.  
  31. self.listenTo(self.m_stationCollection, 'add', function (i_model) {
  32. $(Elements.STATION_ALERT).hide();
  33. self._onAddStation(i_model);
  34. self._listenStationSelected();
  35. });
  36.  
  37. self.listenTo(self.m_stationCollection, 'change', function (i_model) {
  38. self._onUpdateStation(i_model);
  39. });
  40.  
  41. BB.comBroker.listen(BB.EVENTS.STATION_NAME_CHANGED, function (e) {
  42. var stationID = e.edata.stationID;
  43. var stationName = e.edata.stationName;
  44. var a = $(Elements.STATION_LIST_VIEW).find('[data-station_id="' + stationID + '"]');
  45. $(Elements.STATION_LIST_VIEW).find('[data-station_id="' + stationID + '"]').find(Elements.CLASS_LIVE_RENAME).text(stationName);
  46. });
  47.  
  48. self._wireUI();
  49. self._initStationRename();
  50. self._wireSnapshot();
  51. self._populateStationCampaignDropDown(-1);
  52. self._listenEnableServerMode();
  53. self._listenIpChange();
  54. self._listenPortChange();
  55. },
  56.  
  57. /**
  58. Listen to changes in IP selection to assign to station local server
  59. @method _listenIpChange
  60. **/
  61. _listenIpChange: function () {
  62. var self = this;
  63. var input = self.m_liveSationIpInput = new LiveInput({
  64. el: Elements.STATION_SERVER_IP,
  65. dataLocalize: 'stationServerIp',
  66. placeHolder: 'Station IP',
  67. value: ''
  68. }).on('LIVE_INPUT_CHANGED', function (e) {
  69. var stationRecord = BB.Pepper.getStationRecord(self.m_selected_station_id);
  70. stationRecord.lan_server_ip = e.value;
  71. BB.Pepper.setStationRecord(self.m_selected_station_id, stationRecord);
  72. }
  73. ).on('LIVE_INPUT_VALID_ERROR', function (e) {
  74. }
  75. );
  76. input.rules({
  77. 1: [input.getValidator().noEmpty, $(Elements.MSG_LIVEINPUT_NOT_BLANK).text()],
  78. 2: [input.getValidator().isIP, $(Elements.MSG_LIVEINPUT_NO_IP).text()]
  79. });
  80. },
  81.  
  82. /**
  83. Listen to changes in port selection to assign to station local server
  84. @method _listenPortChange
  85. **/
  86. _listenPortChange: function () {
  87. var self = this;
  88. var input = self.m_liveSationPortInput = new LiveInput({
  89. el: Elements.STATION_SERVER_PORT,
  90. dataLocalize: 'stationServerPort',
  91. placeHolder: 'Station Port',
  92. value: '1024'
  93. }).on('LIVE_INPUT_CHANGED', function (e) {
  94. var stationRecord = BB.Pepper.getStationRecord(self.m_selected_station_id);
  95. stationRecord.lan_server_port = e.value;
  96. BB.Pepper.setStationRecord(self.m_selected_station_id, stationRecord);
  97. }
  98. ).on('LIVE_INPUT_VALID_ERROR', function (e) {
  99. }
  100. );
  101. input.rules({
  102. 1: [
  103. input.getValidator().isNumberInRange, $(Elements.MSG_LIVEINPUT_NOT_PORT).text(), {
  104. min: 1024,
  105. max: 65535
  106. }]
  107. });
  108. },
  109.  
  110. /**
  111. Listen to enable server mode
  112. @method _listenEnableServerMode
  113. @param {Number} i_playerData
  114. @return {Number} Unique clientId.
  115. **/
  116. _listenEnableServerMode: function () {
  117. var self = this;
  118. $(Elements.STATION_SERVER_MODE).on('change', function (e) {
  119. var stationRecord = BB.Pepper.getStationRecord(self.m_selected_station_id);
  120. var mode = $(Elements.STATION_SERVER_MODE).prop('checked');
  121. if (mode) {
  122. $(Elements.STATION_SERVER_PROPS).show();
  123. stationRecord.lan_server_enabled = 'True';
  124. } else {
  125. stationRecord.lan_server_enabled = 'False';
  126. $(Elements.STATION_SERVER_PROPS).hide();
  127. }
  128. BB.Pepper.setStationRecord(self.m_selected_station_id, stationRecord);
  129. });
  130. },
  131.  
  132. /**
  133. Render is called when the StackView is in view which tightly coupled with StationView instance
  134. so we can update the station list status when this View is visible
  135. @method render
  136. **/
  137. render: function () {
  138. var self = this;
  139. self.m_stationCollection.resumeGetRemoteStations();
  140. self.getTotalActiveStation();
  141. //log('in view');
  142. },
  143.  
  144. /**
  145. Unrender method used to notify this View that is it no longer visible so we can stop
  146. updating remote station status to increase app perfromance
  147. @method unrender
  148. **/
  149. unrender: function () {
  150. var self = this;
  151. self.m_stationCollection.pauseGetRemoteStations();
  152. log('out of view');
  153. },
  154.  
  155. /**
  156. Init station rename component
  157. @method _initStationRename
  158. **/
  159. _initStationRename: function () {
  160. var self = this;
  161. self.m_liveRenameInput = new LiveInput({
  162. el: Elements.STATION_RENAME,
  163. dataLocalize: 'stationRename',
  164. placeHolder: 'Station rename',
  165. value: ''
  166. }).on('LIVE_INPUT_CHANGED', function (e) {
  167. var stationLI = $(Elements.STATION_LIST_VIEW).find('[data-station_id="' + self.m_selected_station_id + '"]');
  168. $(stationLI).find(Elements.CLASS_LIVE_RENAME).text(e.value);
  169. pepper.setStationName(self.m_selected_station_id, e.value);
  170. self._getStationModel(self.m_selected_station_id).set('stationName', e.value);
  171. });
  172. },
  173.  
  174. /**
  175. Listen to station selection, populate the properties panel
  176. @method _listenStationSelected
  177. **/
  178. _listenStationSelected: function () {
  179. var self = this;
  180. $(Elements.CLASS_STATION_LIST_ITEMS).off('click');
  181. $(Elements.CLASS_STATION_LIST_ITEMS).on('click', function (e) {
  182. var elem = $(e.target).closest('li');
  183. var stationID = $(elem).attr('data-station_id');
  184. if (stationID !== self.m_selected_station_id)
  185. self._stopSnapshot();
  186. self.m_selected_station_id = stationID;
  187. var stationModel = self._getStationModel(self.m_selected_station_id);
  188. self.m_liveRenameInput.setValue(stationModel.get('stationName'), false, false);
  189. $(Elements.CLASS_STATION_LIST_ITEMS).removeClass('activated').find('a').removeClass('whiteFont');
  190. $(elem).addClass('activated').find('a').addClass('whiteFont');
  191. self.m_property.viewPanel(Elements.STATION_PROPERTIES);
  192. self._updatePropStats(stationModel);
  193. self._updatePropButtonState(stationModel);
  194. self._selectCampaignDropDownForStation(self.m_selected_station_id);
  195. return false;
  196. });
  197. },
  198.  
  199. /**
  200. Update properties > button state on station selection
  201. @method _updatePropButtonState
  202. @param {Object} i_model
  203. **/
  204. _updatePropButtonState: function (i_model) {
  205. var self = this;
  206. if (!_.isUndefined(self.m_snapshotInProgress))
  207. return;
  208. var disabled = ''
  209. if (i_model.get('connection') == '0') {
  210. disabled = 'disabled';
  211. }
  212. $(Elements.STATION_CONTROL + ' button').prop('disabled', disabled);
  213. },
  214.  
  215. /**
  216. Update the properties UI station stats from Backbone collection > model
  217. @method _updateProperties
  218. @param {Object} i_model
  219. **/
  220. _updatePropStats: function (i_model) {
  221. var self = this;
  222. //$(Elements.STATION_NAME).text(pepper.getStationNameSync(self.m_selected_station_id));
  223. $(Elements.STATION_WATCHDOG).text(i_model.get('watchDogConnection'));
  224. $(Elements.STATION_TOTAL_MEMORY).text(i_model.get('totalMemory'));
  225. $(Elements.STATION_PEAK_MEMORY).text(i_model.get('peakMemory'));
  226. $(Elements.STATION_LAST_UPDATE).text(i_model.get('lastUpdate'));
  227. $(Elements.STATION_RUNNING_TIME).text(i_model.get('runningTime'));
  228. $(Elements.STATION_AIR_VERSION).text(i_model.get('airVersion'));
  229. $(Elements.STATION_APP_VERSION).text(i_model.get('appVersion'));
  230. $(Elements.STATION_OS).text(i_model.get('stationOS'));
  231. $(Elements.STATION_ID).text(i_model.get('stationID'));
  232.  
  233. var stationRecord = BB.Pepper.getStationRecord(i_model.get('stationID'));
  234.  
  235. if (stationRecord.lan_server_enabled == 'True') {
  236. $(Elements.STATION_SERVER_MODE).prop('checked', true);
  237. $(Elements.STATION_SERVER_PROPS).show();
  238. } else {
  239. $(Elements.STATION_SERVER_MODE).prop('checked', false);
  240. $(Elements.STATION_SERVER_PROPS).hide();
  241. }
  242. self.m_liveSationIpInput.setValue(i_model.get('localAddress'));
  243. self.m_liveSationPortInput.setValue(stationRecord.lan_server_port);
  244. },
  245.  
  246. /**
  247. Reconfigure the location (offset) of the screen snapshot UI depending on current property with
  248. @method _reconfigSnapLocation
  249.  
  250. _reconfigSnapLocation: function () {
  251. var offset = BB.comBroker.getService(BB.SERVICES['PROPERTIES_VIEW']).getPropWidth();
  252. if (offset < 240)
  253. offset = 240;
  254. var box = (offset / 2) - 120;
  255. $(Elements.SNAP_SHOT_SVG).css({
  256. left: box + 'px'
  257. });
  258. $(Elements.SNAP_SHOT_IMAGE).css({
  259. left: box + 15 + 'px'
  260. });
  261. $(Elements.SNAP_SHOT_SPINNER).css({
  262. left: (offset / 2) - 20 + 'px'
  263. });
  264. },
  265. **/
  266.  
  267. /**
  268. Update existing station in list with data from remote mediaSERVER
  269. If a station is selected in the list, make sure we also update its open property values
  270. @method _onUpdateStation
  271. @param {Object} i_stationModel
  272. **/
  273. _onUpdateStation: function (i_stationModel) {
  274. var self = this;
  275. if (i_stationModel.get('connectionStatusChanged')) {
  276. var stationLI = $(Elements.STATION_LIST_VIEW).find('[data-station_id="' + i_stationModel.get('stationID') + '"]');
  277. $(stationLI).find('circle').attr('fill', i_stationModel.get('stationColor'));
  278. }
  279. if (i_stationModel.get('stationID') == self.m_selected_station_id) {
  280. if (!stationLI)
  281. var stationLI = $(Elements.STATION_LIST_VIEW).find('[data-station_id="' + i_stationModel.get('stationID') + '"]');
  282. stationLI.trigger('click');
  283. // log('update data on ' + self.m_selected_station_id);
  284. }
  285. },
  286.  
  287. /**
  288. When data is available from the remote server, update the list with current data.
  289. @method _onAddStation
  290. @param {Event} e remote server data call back from Ajax call
  291. @return none
  292. **/
  293. _onAddStation: function (i_stationModel) {
  294. var self = this;
  295. var snippet = '<li class="' + BB.lib.unclass(Elements.CLASS_STATION_LIST_ITEMS) + ' list-group-item" data-station_id="' + i_stationModel.get('stationID') + '">' +
  296. '<a href="#">' +
  297. '<span id="stationIcon' + i_stationModel.get('id') + '">' +
  298. '<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg"><g><circle stroke="black" id="svg_1" fill="' + i_stationModel.get('stationColor') + '" stroke-width="2" r="16" cy="20" cx="20"/></g></svg>' +
  299. '</span>' +
  300. '<span class="' + BB.lib.unclass(Elements.CLASS_LIVE_RENAME) + '" style="font-size: 1.5em; position: relative; top: -23px">' + i_stationModel.get('stationName') + '</span>' +
  301. '</a>' +
  302. '</li>';
  303. $(Elements.STATION_LIST_VIEW).append(snippet)
  304. },
  305.  
  306. /**
  307. Bind all event listeners on the UI for remote stations commands including commands
  308. @method _wireUI
  309. @return none
  310. **/
  311. _wireUI: function () {
  312. var self = this;
  313.  
  314. $(Elements.STATION_PLAY_COMMAND + ' , ' + Elements.STATION_STOP_COMMAND).on('click', function (e) {
  315. var command = BB.lib.unhash(Elements.STATION_PLAY_COMMAND) == e.currentTarget.id ? 'start' : 'stop';
  316. pepper.sendCommand(command, self.m_selected_station_id, function () {
  317. // log('cmd done'+command);
  318. });
  319. return false;
  320. });
  321.  
  322. $(Elements.STATION_REFRESH).on('click', function (e) {
  323. $(Elements.STATION_LIST_VIEW).fadeOut('fast', function () {
  324. self.m_stationCollection.getRemoteStations();
  325. $(this).fadeIn('fast');
  326. });
  327. });
  328.  
  329. $(Elements.STATION_RELOAD_COMMAND).on('click', function (e) {
  330. // pepper.sendCommand('rebootStation', self.m_selected_station_id, function () {});
  331. pepper.sendCommand('rebootPlayer', self.m_selected_station_id, function () {
  332. });
  333. return false;
  334. });
  335.  
  336. $(Elements.STATION_SELECTION_CAMPAIGN).on('change', function (e) {
  337. self._onChangedCampaign(e);
  338. return false;
  339. });
  340.  
  341. $(Elements.STATION_REMOVE).on('click', function () {
  342. self._removeStation(self);
  343. });
  344.  
  345. $(Elements.STATION_EVENT_SEND_COMMAND).on('click', function () {
  346. var eventValue = $(Elements.STATION_SEND_EVENT_VALUE).val();
  347. pepper.sendEvent(eventValue, self.m_selected_station_id, function () {
  348. });
  349. });
  350. },
  351.  
  352. /**
  353. Translate a station id to Backbone.Model
  354. @method _getStationModel
  355. @param {Number} i_station_id
  356. **/
  357. _getStationModel: function (i_station_id) {
  358. var self = this;
  359. return self.m_stationCollection.findWhere({'stationID': i_station_id});
  360. },
  361.  
  362. /**
  363. Send a remote value (i.e.: remote event / remote touch) to a selected station.
  364. If events are enabled at the campaign level, the _sendStationEvent method enables users to fire events on a selected
  365. Station and thus change campaign attributes.
  366. @method _sendStationEvent
  367. @param {String} i_eventName
  368. @param {String} i_eventValue
  369. @return none
  370. _sendStationEvent: function (i_eventName, i_eventValue) {
  371. var self = this;
  372. model.sendStationEvent(model.getDataByID(self.m_selected_resource_id)['id'], i_eventName, i_eventValue);
  373. $(Elements.EVENT_SEND_BUTTON).button('disable');
  374. },
  375. **/
  376. _removeStation: function (i_context) {
  377. var self = i_context;
  378. if (_.isUndefined(self.m_selected_station_id)) {
  379. bootbox.dialog({
  380. message: $(Elements.MSG_BOOTBOX_NO_STATION_SELECTED).text(),
  381. buttons: {
  382. danger: {
  383. label: $(Elements.MSG_BOOTBOX_OK).text(),
  384. className: "btn-danger",
  385. callback: function () {
  386. }
  387. }
  388. }
  389. });
  390. return false;
  391. }
  392. bootbox.confirm($(Elements.MSG_BOOTBOX_STEPS).text(), function (result) {
  393. if (result == true) {
  394. var navigationView = BB.comBroker.getService(BB.SERVICES.NAVIGATION_VIEW);
  395. // pepper.sendCommand('rebootStation', self.m_selected_station_id, function () {});
  396. pepper.sendCommand('rebootPlayer', self.m_selected_station_id, function () {
  397. });
  398. pepper.removeStation(self.m_selected_station_id);
  399. navigationView.save(function () {
  400. });
  401. pepper.sync(function () {
  402. self._removeStationFromLI(self.m_selected_station_id);
  403. navigationView.resetPropertiesView();
  404. });
  405.  
  406. }
  407. });
  408. },
  409.  
  410. /**
  411. Remove a selected station from UI LI
  412. @method _removeStationFromLI
  413. @param {Number} i_stationID
  414. **/
  415. _removeStationFromLI: function (i_stationID) {
  416. var self = this;
  417. $(Elements.STATION_LIST_VIEW).find('[data-station_id="' + i_stationID + '"]').remove();
  418. },
  419.  
  420. /**
  421. Wire the Snapshot UI button and handle related opeations before and after executing a station snapshot
  422. @method _wireSnapshot
  423. **/
  424. _wireSnapshot: function () {
  425. var self = this;
  426. $(Elements.STATION_SNAPSHOT_COMMAND).on('click', function (e) {
  427. self.m_imagePath = '';
  428. self.m_imageReloadCount = 0;
  429. self._listenSnapshotComplete();
  430.  
  431. /* Can't use short path due to IE error, gotta go long route via _sendSnapshotCommand
  432. self.m_imagePath = pepper.sendSnapshot(Date.now(), '0.2', self.m_selected_station_id, function (e) {});
  433. log(self.m_imagePath);
  434. */
  435.  
  436. self._sendSnapshotCommand(self.m_selected_station_id);
  437. $(Elements.SNAP_SHOT_IMAGE).attr('src', self.m_imagePath);
  438. $(Elements.SNAP_SHOT_IMAGE).hide();
  439. $(Elements.SNAP_SHOT_SPINNER).fadeIn('slow');
  440. $(Elements.STATION_CONTROL + ' button').prop('disabled', 'disabled');
  441.  
  442. self.m_snapshotInProgress = setInterval(function () {
  443. self.m_imageReloadCount++;
  444. // log('snapshot JS... ' + self.m_imagePath);
  445. $(Elements.SNAP_SHOT_IMAGE).attr('src', self.m_imagePath);
  446.  
  447. // snapshot timed out so reset
  448. if (self.m_imageReloadCount > 6) {
  449. self._stopSnapshot();
  450. $(Elements.SNAP_SHOT_IMAGE).attr('src', self.m_imagePath);
  451. var stationModel = self._getStationModel(self.m_selected_station_id);
  452. self._updatePropButtonState(stationModel);
  453. }
  454. }, 1000);
  455. return false;
  456. });
  457. },
  458.  
  459. /**
  460. Send a remote snapshot command for station id and wait for a call back.
  461. @method _sendSnapshotCommand
  462. @param {Number} i_station
  463. @return none
  464. **/
  465. _sendSnapshotCommand: function (i_station) {
  466. var self = this;
  467. var d = new Date().getTime();
  468. var path = pepper.sendSnapshot(d, 0.2, i_station, function (e) {
  469. });
  470. setTimeout(function () {
  471. self.m_imagePath = path;
  472. }, 3000);
  473.  
  474. /*
  475. var data = {
  476. '@functionName': 'f_captureScreen',
  477. '@stationID': i_station,
  478. '@quality': 1,
  479. '@time': Date.now()
  480. };
  481. self.ajaxJsonGetter.getData(data, onSnapshotReply);
  482. function onSnapshotReply(e) {
  483. if (e.responce['status'] == 'pass') {
  484. log('getting image from ' + e.responce['path']);
  485. self.m_imagePath = e.responce['path'];
  486. }
  487. }
  488. // self.m_imagePath = 'https://pluto.signage.me/Snapshots/business355181/station12/1397689062944.jpg';
  489. // return;
  490. */
  491.  
  492. },
  493.  
  494. /**
  495. Stop any ongoing snapshots that are pending and reset all related snapshot UI and values
  496. @method _stopSnapshot
  497. **/
  498. _stopSnapshot: function () {
  499. var self = this;
  500. if (self.m_snapshotInProgress)
  501. clearTimeout(self.m_snapshotInProgress);
  502. self.m_snapshotInProgress = undefined;
  503. $(Elements.SNAP_SHOT_SPINNER).hide();
  504. $(Elements.SNAP_SHOT_IMAGE).attr('src', '');
  505. $(Elements.SNAP_SHOT_IMAGE).hide();
  506. $(Elements.SNAP_SHOT_IMAGE).unbind('load');
  507. },
  508.  
  509. /**
  510. Listen when a new remote snapshot is available on the server for a selected station, so we can display it in the properties panel
  511. We use the Image.load event to be notified when the Image element has succesfully recived a working image path
  512. @method _listenSnapshotComplete
  513. @return none
  514. **/
  515. _listenSnapshotComplete: function () {
  516. var self = this;
  517. // snapshot success
  518. $(Elements.SNAP_SHOT_IMAGE).one('load', function (e) {
  519. $(Elements.SNAP_SHOT_SPINNER).hide();
  520. $(Elements.SNAP_SHOT_IMAGE).attr('src', self.m_imagePath);
  521. $(Elements.SNAP_SHOT_IMAGE).fadeIn('slow');
  522. clearTimeout(self.m_snapshotInProgress);
  523. self.m_snapshotInProgress = undefined;
  524. var stationModel = self._getStationModel(self.m_selected_station_id);
  525. self._updatePropButtonState(stationModel);
  526. });
  527. },
  528.  
  529. /**
  530. Select the campaign that is bound to i_stationID and select it in the dropdown UI
  531. @method _selectCampaignDropDownForStation
  532. @param {Number} i_stationID
  533. **/
  534. _selectCampaignDropDownForStation: function (i_stationID) {
  535. var self = this;
  536. var campaignID = pepper.getStationCampaignID(i_stationID);
  537. self._populateStationCampaignDropDown(campaignID);
  538. },
  539.  
  540. /**
  541. Populate the selection drop down UI with all available campaigns for station selection
  542. @method _populateStationCampaignDropDown
  543. @param {Number} i_campaignID
  544. **/
  545. _populateStationCampaignDropDown: function (i_campaignID) {
  546. var self = this;
  547. $(Elements.STATION_SELECTION_CAMPAIGN).empty();
  548. if (i_campaignID == undefined || i_campaignID == -1)
  549. $(Elements.STATION_SELECTION_CAMPAIGN).append('<option selected data-campaign_id="-1">Select campaign</option>');
  550. var campaignIDs = pepper.getCampaignIDs();
  551. for (var i = 0; i < campaignIDs.length; i++) {
  552. var campaignID = campaignIDs[i];
  553. var recCampaign = pepper.getCampaignRecord(campaignID);
  554. var selected = campaignID == i_campaignID ? 'selected' : '';
  555. var snippet = '<option ' + selected + ' data-campaign_id="' + campaignID + '">' + recCampaign['campaign_name'] + '</option>';
  556. $(Elements.STATION_SELECTION_CAMPAIGN).append(snippet);
  557. }
  558. },
  559.  
  560. /**
  561. On change campaign action apply changes to local msdb
  562. @method _onChangedCampaign
  563. **/
  564. _onChangedCampaign: function (e) {
  565. var self = this;
  566. var campaign_id = $(Elements.STATION_SELECTION_CAMPAIGN + ' option:selected').attr('data-campaign_id');
  567. if (campaign_id == -1)
  568. return;
  569. pepper.setStationCampaignID(self.m_selected_station_id, campaign_id);
  570. },
  571.  
  572. /**
  573. Get current total active, non red stations
  574. @method getTotalActiveStation
  575. @param {Number} i_playerData
  576. @return {Number} total active / non red stations
  577. **/
  578. getTotalActiveStation: function () {
  579. var self = this;
  580. var connected = self.m_stationCollection.filter(function (stationsModel) {
  581. return stationsModel.get('connection') != '0'
  582. });
  583. return connected.length;
  584. }
  585. });
  586.  
  587. return StationsListView;
  588. });
  589.