Guest User

Untitled

a guest
Nov 1st, 2020
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const mqtt = require('mqtt');
  2. const request = require('request-promise');
  3. const _ = require('underscore');
  4. const express = require('express');
  5. const bodyParser = require('body-parser');
  6. const server = express();
  7. const varClientId = makeId(30);
  8.  
  9. const sessionUrl = 'https://web-api-prod-obo.horizon.tv/oesp/v3/NL/nld/web/session';
  10. const jwtUrl = 'https://web-api-prod-obo.horizon.tv/oesp/v3/NL/nld/web/tokens/jwt';
  11. const channelsUrl = 'https://web-api-prod-obo.horizon.tv/oesp/v3/NL/nld/web/channels';
  12. const mqttUrl = 'wss://obomsg.prod.nl.horizon.tv:443/mqtt';
  13.  
  14. let mqttClient = {};
  15.  
  16. // Set Ziggo username and password
  17. const ziggoUsername = "Your username";
  18. const ziggoPassword = "Your password";
  19.  
  20. let mqttUsername;
  21. let mqttPassword;
  22. let setopboxId;
  23. let setopboxState;
  24. let stbDevicesCount = 0;
  25. let stations = [];
  26. let uiStatus;
  27. let currentChannel;
  28. let currentChannelId;
  29.  
  30. const sessionRequestOptions = {
  31.     method: 'POST',
  32.     uri: sessionUrl,
  33.     body: {
  34.         username: ziggoUsername,
  35.         password: ziggoPassword
  36.     },
  37.     json: true
  38. };
  39.  
  40. const getChannels = request({
  41.     url: channelsUrl,
  42.     json: true
  43. }, function (error, response, body) {
  44.     if (!error && response.statusCode === 200) {
  45.         channels = body.channels;
  46.         channels.forEach(function (c) {
  47.             c.stationSchedules.forEach(function (s) {
  48.                 stations.push(s.station);
  49.             });
  50.         });
  51.     }
  52. });
  53.  
  54. const getSession = async () => {
  55.     await request(sessionRequestOptions)
  56.         .then(json => {
  57.             sessionJson = json;
  58.         })
  59.         .catch(function (err) {
  60.             console.log('getSession: ', err.message);
  61.             return false;
  62.         });
  63.        
  64.         return sessionJson;
  65. };
  66.  
  67. const getJwtToken = async (oespToken, householdId) => {
  68.     const jwtRequestOptions = {
  69.         method: 'GET',
  70.         uri: jwtUrl,
  71.         headers: {
  72.             'X-OESP-Token': oespToken,
  73.             'X-OESP-Username': ziggoUsername
  74.         },
  75.         json: true
  76.     };
  77.    
  78.     await request(jwtRequestOptions)
  79.         .then(json => {
  80.             jwtJson = json;
  81.         })
  82.         .catch(function (err) {
  83.             console.log('getJwtToken: ', err.message);
  84.             return false;
  85.         });
  86.        
  87.         return jwtJson;
  88. };
  89.  
  90. const startMqttClient = async () => {
  91.     mqttClient = mqtt.connect(mqttUrl, {
  92.         connectTimeout: 10*1000, //10 seconds
  93.         clientId: varClientId,
  94.         username: mqttUsername,
  95.         password: mqttPassword
  96.     });
  97.    
  98.     mqttClient.on('connect', function () {
  99.         mqttClient.publish(mqttUsername + '/' + varClientId + '/status', '{"source":"' + varClientId + '","state":"ONLINE_RUNNING","deviceType":"HGO"}');
  100.        
  101.         mqttClient.subscribe(mqttUsername, function (err) {
  102.             if(err){
  103.                 console.log(err);
  104.                 return false;
  105.             }
  106.         });
  107.        
  108.         mqttClient.subscribe(mqttUsername + '/+/status', function (err) {
  109.             if(err){
  110.                 console.log(err);
  111.                 return false;
  112.             }
  113.         });
  114.        
  115.         mqttClient.on('message', function (topic, payload) {
  116.             let payloadValue = JSON.parse(payload);
  117.            
  118.             if(payloadValue.deviceType){
  119.                 if(payloadValue.deviceType == 'STB'){
  120.                     stbDevicesCount++;
  121.                     setopboxId = payloadValue.source;
  122.                     setopboxState = payloadValue.state;
  123.  
  124.                     if(stbDevicesCount == 1){
  125.                         getUiStatus();
  126.                     }
  127.                    
  128.                     mqttClient.subscribe(mqttUsername + '/' + varClientId, function (err) {
  129.                         if(err){
  130.                             console.log(err);
  131.                             return false;
  132.                         }
  133.                     });
  134.                    
  135.                     mqttClient.subscribe(mqttUsername + '/' + setopboxId, function (err) {
  136.                         if(err){
  137.                             console.log(err);
  138.                             return false;
  139.                         }
  140.                     });
  141.                    
  142.                     mqttClient.subscribe(mqttUsername + '/'+ setopboxId +'/status', function (err) {
  143.                         if(err){
  144.                             console.log(err);
  145.                             return false;
  146.                         }
  147.                     });
  148.                 }
  149.             }
  150.            
  151.             if(payloadValue.status){
  152.                 if(payloadValue.status.playerState){
  153.                     let filtered = _.where(stations, {serviceId: payloadValue.status.playerState.source.channelId});
  154.                     uiStatus = payloadValue;
  155.                     currentChannelId = uiStatus.status.playerState.source.channelId;
  156.                     currentChannel = filtered[0].title;
  157.                     console.log('Current channel:', filtered[0].title);
  158.                 }
  159.             }
  160.         });
  161.        
  162.         mqttClient.on('error', function(err) {
  163.             console.log(err);
  164.             mqttClient.end();
  165.             return false;
  166.         });
  167.  
  168.         mqttClient.on('close', function () {
  169.             console.log('Connection closed');
  170.             mqttClient.end();
  171.             return false;
  172.         });
  173.     });
  174. };
  175.  
  176. function switchChannel(channel) {
  177.     console.log('Switch to', channel);
  178.     mqttClient.publish(mqttUsername + '/' + setopboxId, '{"id":"' + makeId(8) + '","type":"CPE.pushToTV","source":{"clientId":"' + varClientId + '","friendlyDeviceName":"NodeJs"},"status":{"sourceType":"linear","source":{"channelId":"' + channel + '"},"relativePosition":0,"speed":1}}')
  179. };
  180.  
  181. function powerKey() {
  182.     console.log('Power on/off');
  183.     mqttClient.publish(mqttUsername + '/' + setopboxId, '{"id":"' + makeId(8) + '","type":"CPE.KeyEvent","source":"' + varClientId + '","status":{"w3cKey":"Power","eventType":"keyDownUp"}}')
  184. };
  185.  
  186. function escapeKey() {
  187.     console.log('Send escape-key');
  188.     mqttClient.publish(mqttUsername + '/' + setopboxId, '{"id":"' + makeId(8) + '","type":"CPE.KeyEvent","source":"' + varClientId + '","status":{"w3cKey":"Escape","eventType":"keyDownUp"}}')
  189. };
  190.  
  191. function pauseKey() {
  192.     console.log('Send pause-key');
  193.     mqttClient.publish(mqttUsername + '/' + setopboxId, '{"id":"' + makeId(8) + '","type":"CPE.KeyEvent","source":"' + varClientId + '","status":{"w3cKey":"MediaPause","eventType":"keyDownUp"}}')
  194. };
  195.  
  196. function getUiStatus() {
  197.     console.log('Get UI status');
  198.     mqttClient.publish(mqttUsername + '/' + setopboxId, '{"id":"' + makeId(8) + '","type":"CPE.getUiStatus","source":"' + varClientId + '"}')
  199. };
  200.  
  201. function makeId(length) {
  202.     let result  = '';
  203.     let characters  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  204.     let charactersLength = characters.length;
  205.     for ( let i = 0; i < length; i++ ) {
  206.         result += characters.charAt(Math.floor(Math.random() * charactersLength));
  207.     }
  208.     return result;
  209. };
  210.  
  211. getSession()
  212.     .then(async sessionJson => {
  213.         const jwtTokenJson = await getJwtToken(sessionJson.oespToken, sessionJson.customer.householdId);
  214.  
  215.         mqttUsername = sessionJson.customer.householdId;
  216.         mqttPassword = jwtTokenJson.token; 
  217.  
  218.         startMqttClient();
  219.        
  220.         server.use(bodyParser.json());
  221.         server.use(bodyParser.urlencoded({
  222.             extended: true
  223.         }));
  224.  
  225.         server.listen(8080, () => {
  226.             console.log("Server running on port 8080");
  227.         });
  228.        
  229.         server.get("/", (req, res, next) => {
  230.             res.sendFile(__dirname + '/index.html');
  231.         });
  232.  
  233.         server.post("/api", (req, res, next) => {
  234.             switch(req.body.action){
  235.                 case 'pushChannel':
  236.                     switchChannel(req.body.channel);
  237.                     break;
  238.                 case 'powerKey':
  239.                     powerKey();
  240.                     break;
  241.                 case 'escapeKey':
  242.                     escapeKey();
  243.                     break;
  244.                 case 'pauseKey':
  245.                     pauseKey();
  246.                     break; 
  247.                 case 'getUiStatus':
  248.                     getUiStatus();
  249.                     break;                                         
  250.                 default:
  251.                     res.json({"Status": "Error"});
  252.                     break;
  253.             }
  254.             res.json({"Status": "Ok"});
  255.         });
  256.  
  257.         server.get("/api/status", (req, res, next) => {
  258.             if(setopboxState){
  259.                 res.json({"Status": "Ok", "setopboxState": setopboxState, "currentChannel": currentChannel, "currentChannelId": currentChannelId, "rawUiStatus": {uiStatus}});
  260.             }else{
  261.                 res.json({"Status": "Error"});
  262.             }
  263.         });
  264.        
  265.         server.get("/api/stations", (req, res, next) => {
  266.             res.json(stations);
  267.             console.log('Get stations');
  268.         });
  269.        
  270.     });
Add Comment
Please, Sign In to add comment