# Jogos de Futebol com transmissão televisiva v2

**URL:** <https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837>\
**Category:** Partilha de Projectos\
**Created:** [21 Maio , 2024 14:49 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837 "2024-05-21T14:49:25Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [21 Maio , 2024 14:49 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/1 "2024-05-21T14:49:26Z")

</div>

Boas malta, o anterior parser que tinha feito para obter os jogos de futebol com transmissão na TV deixou de funcionar e fiz outro apartir de outro site fonte.

Partilho o flow que fiz para obter um conjunto de dados como o card que fiz de forma a facilitar a leitura dos jogos entre os diferentes dias/competições.

O card tem vários buttons para selecionar o dia assim como o tipo de vista, para tal é necessário seguir as instruções na parte de configuração do card.

Devem instalar as seguintes bibliotecas no node red:  
**node-red-contrib-cron-plus**  
**node-red-contrib-iconv**

Flow a importar para o Node Red:  
(devem configurar os nodes necessários de forma a executarem o flow e criar o sensor no Home Assistant)

```auto
[{"id":"30ee198fc9087217","type":"tab","label":"Futebol","disabled":false,"info":"","env":[]},{"id":"e01a42f439c105e8","type":"inject","z":"30ee198fc9087217","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":160,"wires":[["ac7e9165fbb8182e"]]},{"id":"ac7e9165fbb8182e","type":"http request","z":"30ee198fc9087217","name":"","method":"GET","ret":"bin","paytoqs":"ignore","url":"https://www.zerozero.pt/zapping","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":290,"y":160,"wires":[["e9e914a8d34f99f7"]]},{"id":"e9e914a8d34f99f7","type":"converter","z":"30ee198fc9087217","name":"","from":"ISO-8859-1","x":460,"y":160,"wires":[["2162710daca98e23"]]},{"id":"bb49728e0dd5d749","type":"debug","z":"30ee198fc9087217","name":"debug 12","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1160,"y":160,"wires":[]},{"id":"2162710daca98e23","type":"html","z":"30ee198fc9087217","name":"tbody","property":"payload","outproperty":"payload","tag":"#page_main > div:nth-child(2) > table > tbody","ret":"html","as":"single","x":610,"y":160,"wires":[["01ecd02c959eaef3"]]},{"id":"01ecd02c959eaef3","type":"function","z":"30ee198fc9087217","name":"Get table rows","func":"let allRows = [];\nlet html = msg.payload[0];\nlet htmlToParse = html;\n\nwhile(htmlToParse.indexOf(\"<tr>\") > -1 && htmlToParse.indexOf(\"</tr>\") > -1) {\n let currentRow = htmlToParse.substring(4, htmlToParse.indexOf(\"</tr>\"));\n\n allRows.push( {\n 'row': currentRow,\n });\n htmlToParse = htmlToParse.substring(htmlToParse.indexOf(\"</tr>\")+5, htmlToParse.length);\n} \n\n\nreturn [{\n 'payload': \n {\n 'allRows': allRows\n }\n}, null];","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":160,"wires":[["a52ede8c0bbbfc24"]]},{"id":"a52ede8c0bbbfc24","type":"function","z":"30ee198fc9087217","name":"Get all games","func":"let allRows = msg.payload.allRows;\nlet games = [];\n\nlet remainingRow = null;\nlet urlBase = \"https://www.zerozero.pt\";\n\nvar date = new Date();\nvar dateStr =\n date.getFullYear()+ \"-\" +\n (\"00\" + (date.getMonth() + 1)).slice(-2) + \"-\" +\n (\"00\" + date.getDate()).slice(-2) + \" \" +\n (\"00\" + date.getHours()).slice(-2) + \":\" +\n (\"00\" + date.getMinutes()).slice(-2) + \":\" +\n (\"00\" + date.getSeconds()).slice(-2);\n\n\n\n\nfor (var i = 0; i < allRows.length; i++) {\n\n let row = allRows[i].row;\n let game = {\n 'date' : '',\n 'time' : '',\n 'transmissionType' : '',\n 'country' : '',\n 'countryIcon' : '',\n 'division' : '',\n 'homeTeamName' : '',\n 'homeTeamIcon' : '',\n 'awayTeamName' : '',\n 'awayTeamIcon' : '',\n 'channel' : '',\n 'channelIcon' : '',\n 'channelLink' : '',\n 'competitionName' : ''\n };\n\n if (game.date == '') {\n let gameTime = row.substring(row.indexOf(\";data=\") + 6, row.indexOf(\";data=\") + 25);\n game.date =gameTime.split(\" \")[0];\n game.time = gameTime.split(\" \")[1].substring(0, gameTime.split(\" \")[1].length - 3);\n row = row.substring(row.indexOf(\";data=\") + 25, row.length);\n\n remainingRow = row;\n }\n if (game.countryIcon == '') {\n game.countryIcon = urlBase + row.substring(row.indexOf(\"img src=\") + 9, row.indexOf(\"alt=\") - 25);\n game.country = row.substring(row.indexOf(\"alt=\") + 5, row.indexOf(\"title\") - 2);\n\n row = row.substring(row.indexOf(\"title\"), row.length);\n remainingRow = row;\n }\n\n if(game.division == '') {\n game.division = row.substring(0, row.indexOf(\"</a>\")).substring(row.substring(0, row.indexOf(\"</a>\")).lastIndexOf(\">\")+1,row.substring(0, row.indexOf(\"</a>\")).length);\n // game.division = game.division.substring(0, game.division.lastIndexOf(\" \"));\n row = row.substring(row.indexOf(\"</a>\"), row.length);\n remainingRow = row;\n }\n\n if(game.homeTeamName == '') {\n game.homeTeamName = hexHtmlToString(row.substring(row.indexOf(\"alt=\") + 5, row.indexOf(\"title\") - 2));\n game.homeTeamIcon = urlBase + row.substring(row.indexOf(\"src=\") + 5, row.indexOf(\"border=\") - 2);\n\n row = row.substring(row.indexOf(\"border=\")+10, row.length);\n remainingRow = row;\n\n game.awayTeamIcon = urlBase+ row.substring(row.indexOf(\"src=\") + 5, row.indexOf(\"border=\") - 2);\n row = row.substring(row.indexOf(\"vs\"), row.length);\n remainingRow = row;\n }\n\n if(game.awayTeamName == '') {\n game.awayTeamName = hexHtmlToString(row.substring( row.substring(0, row.indexOf(\"<span\")).lastIndexOf(\">\")+1, row.indexOf(\"<span\")));\n \n row = row.substring(row.indexOf('<span'), row.length);\n remainingRow = row;\n }\n\n if(game.channel == '') {\n if(row.indexOf(\"href=\") < row.indexOf(\"<img\")) {\n game.channelLink = row.substring(row.indexOf(\"href=\") + 6, row.indexOf(\"<img\") - 2);\n }\n \n game.channelIcon = getChannelLink(game);\n // urlBase+ row.substring(row.indexOf(\"src=\") + 5, row.indexOf(\"width=\")-2);\n game.channel = row.substring(row.indexOf(\"alt=\") + 5, row.indexOf(\"title\") - 2);\n game.competitionName = row.substring(row.substring(0, row.lastIndexOf(\"</a>\") - 2).lastIndexOf(\">\")+1, row.lastIndexOf(\"</a>\"));\n game.competitionName = game.competitionName.substring(0, game.competitionName.lastIndexOf(\" \"));\n \n if( game.channel == \"Canal11\"){\n game.channel = \"Canal 11\";\n game.channelIcon = \"https://www.canal11.pt/images/customer/logo.png\";\n } else if(game.channel.includes(\"11Sports\")) {\n game.channel = game.channel.replace(\"11Sports\", \"Eleven Sports\");\n \n } else if (game.channel == \"SporTtv+\") {\n game.channel = \"Sport TV +\";\n game.channelIcon = \"https://www.sporttv.pt/logos/sporttv-mais-rebrand.svg\";\n \n\n } else if (game.channel == \"SportTv1\") {\n game.channel = \"Sport TV1\";\n game.channelIcon = \"https://www.sporttv.pt/logos/sporttv-1-rebrand.svg\";\n \n\n } else if (game.channel == \"SportTv2\") {\n game.channel = \"Sport TV 2\";\n game.channelIcon = \"https://www.sporttv.pt/logos/sporttv-2-rebrand.svg\";\n \n\n } else if (game.channel == \"SportTv3\") {\n game.channel = \"Sport TV 3\";\n game.channelIcon = \"https://www.sporttv.pt/logos/sporttv-3-rebrand.svg\";\n \n\n } else if (game.channel == \"SportTv4\") {\n game.channel = \"Sport TV 4\";\n game.channelIcon = \"https://www.sporttv.pt/logos/sporttv-4-rebrand.svg\";\n \n\n } else if (game.channel == \"SportTv5\") {\n game.channel = \"Sport TV 5\";\n game.channelIcon = \"https://www.sporttv.pt/logos/sporttv-5-rebrand.svg\";\n\n } else if (game.channel == \"SportTv6\") {\n game.channel = \"Sport TV 6\";\n game.channelIcon = \"https://www.sporttv.pt/logos/sporttv-6-rebrand.svg\";\n } else if (game.channel == \"BTv\") {\n game.channel = \"Benfica TV\";\n game.channelIcon = \"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d2/Logo_Benfica_TV.png/800px-Logo_Benfica_TV.png\";\n }\n \n if (game.channel === \"Eleven Sports 1\") {\n game.channelIcon = \"https://www.meo.pt/PublishingImages/canais/dazn-eleven-1-meo-logo.webp\";\n }\n if (game.channel === \"Eleven Sports 2\") {\n game.channelIcon = \"https://www.meo.pt/PublishingImages/canais/dazn-eleven-2-meo-logo.webp\";\n }\n if (game.channel === \"Eleven Sports 3\") {\n game.channelIcon = \"https://www.meo.pt/PublishingImages/canais/dazn-eleven-3-meo-logo.webp\";\n }\n if (game.channel == \"Eleven Sports 4\") {\n game.channelIcon = \"https://www.meo.pt/PublishingImages/canais/dazn-eleven-4-meo-logo.webp\";\n }\n if (game.channel == \"Eleven Sports 5\") {\n game.channelIcon = \"https://www.meo.pt/PublishingImages/canais/dazn-eleven-5-meo-logo.webp\";\n }\n if (game.channel == \"Eleven Sports 6\") {\n game.channelIcon = \"https://www.meo.pt/PublishingImages/canais/dazn-eleven-6-meo-logo.webp\";\n }\n\n if (game.channel == \"RTP1\") {\n game.channel = \"RTP 1\";\n game.channelIcon = \"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/RTP1_-_Logo_2016.svg/2560px-RTP1_-_Logo_2016.svg.png\";\n }\n\n if (game.channel == \"RTP Play\") {\n game.channelIcon = \"https://static.wikia.nocookie.net/logopedia/images/4/47/RTP_Play.svg/revision/latest?cb=20211109150238\";\n }\n\n if (game.channel == \"SIC\") {\n game.channelIcon = \"https://upload.wikimedia.org/wikipedia/pt/5/51/Logo_SIC_2018.png\";\n }\n\n if (game.channel == \"TVI\") {\n game.channelIcon = \"https://upload.wikimedia.org/wikipedia/en/6/63/TVI_logo_2017.png\";\n }\n\n if(game.channel == \"AFL TV\") {\n game.channelIcon = \"https://afl.pt/wp-content/uploads/2023/10/AFL-TV__.png\";\n }\n\n \n\n \n\n \n }\n games.push(game);\n}\n\nfunction getChannelLink(game) {\n let channelLink = \"\";\n\n if(game.channel == \"Eleven Sports 4\") {\n channelLink = \"canais/dazn-eleven-4-meo-logo.webp\";\n }\n \n return channelLink;\n}\n\nfunction hexHtmlToString(str) {\n if (str.includes(\"&#xE7;\")) {\n str = str.replace(\"&#xE7;\", \"ç\");\n }\n\n if (str.includes(\"&#xE1;\")) {\n str = str.replace(\"&#xE1;\", \"á\");\n }\n\n if (str.includes(\"&#xE3;\")) {\n str = str.replace(\"&#xE3;\", \"ã\");\n }\n\n if (str.includes(\"&#xE9;\")) {\n str = str.replace(\"&#xE9;\", \"é\");\n }\n\n\n if (str.includes(\"&#xF3;\")) {\n str = str.replace(\"&#xF3;\", \"ó\");\n }\n\n \n \n return str;\n}\n\nfunction getTodayGames(gamesByDate) {\n let today = new Date().toISOString().split('T')[0];\n let todayGames = [];\n for(var i=0; i<gamesByDate.length; i++) {\n if(gamesByDate[i].date == today) {\n todayGames = gamesByDate[i];\n break;\n }\n }\n return todayGames;\n}\n\nfunction getTomorrowGames(gamesByDate) {\n var tomorrowDate = new Date();\n tomorrowDate.setDate(tomorrowDate.getDate() + 1);\n tomorrowDate = tomorrowDate.toISOString().split('T')[0];\n\n let tomorrowGames = [];\n for(var i=0; i<gamesByDate.length; i++) {\n if(gamesByDate[i].date == tomorrowDate) {\n tomorrowGames = gamesByDate[i];\n break;\n }\n }\n return tomorrowGames;\n}\n\nfunction getNextThreeDaysGames(gamesByDate) {\n let nextThreeDays = [];\n let today = new Date().toISOString().split('T')[0];\n nextThreeDays.push(today);\n\n var tomorrowDate = new Date();\n tomorrowDate.setDate(tomorrowDate.getDate() + 1);\n tomorrowDate = tomorrowDate.toISOString().split('T')[0];\n nextThreeDays.push(tomorrowDate);\n\n var nextTomorrowDate = new Date();\n nextTomorrowDate.setDate(nextTomorrowDate.getDate() + 2);\n nextTomorrowDate = nextTomorrowDate.toISOString().split('T')[0];\n nextThreeDays.push(nextTomorrowDate);\n\n let nextThreeDaysGames = [];\n for(var i=0; i<gamesByDate.length; i++) {\n if(nextThreeDays.includes(gamesByDate[i].date)) {\n nextThreeDaysGames.push(gamesByDate[i]);\n }\n }\n return nextThreeDaysGames;\n}\n\n\n\n\nfunction getGamesByDate(allGames) {\n let gamesByDate = [];\n for(var i=0; i<allGames.length; i++) {\n if(gamesByDate.length ==0) {\n gamesByDate.push({\n 'date' : allGames[i].date,\n 'games' : [allGames[i]],\n 'competitions' : [{\n 'name' : allGames[i].competitionName,\n 'icon': allGames[i].countryIcon,\n 'games' : [allGames[i]]\n }\n ]\n });\n } else {\n let foundedDate = false;\n let foundedCompetition = false;\n for (var t = 0; t < gamesByDate.length; t++) {\n if (gamesByDate[t].date == allGames[i].date) {\n foundedDate = true;\n gamesByDate[t].games.push(allGames[i]);\n for(var x=0; x<gamesByDate[t].competitions.length; x++) {\n if(gamesByDate[t].competitions[x].name ==allGames[i].competitionName ) {\n gamesByDate[t].competitions[x].games.push(allGames[i]);\n foundedCompetition = true;\n }\n }\n if(!foundedCompetition) {\n gamesByDate[t].competitions.push({\n 'name' : allGames[i].competitionName,\n 'icon' : allGames[i].countryIcon,\n 'games' : [allGames[i]]\n });\n }\n }\n }\n if(!foundedDate) {\n gamesByDate.push({\n 'date' : allGames[i].date,\n 'games' : [allGames[i]],\n 'competitions' : [{\n 'name' : allGames[i].competitionName,\n 'icon' : allGames[i].countryIcon,\n 'games' : [allGames[i]]\n }\n ]\n });\n }\n }\n }\n return gamesByDate;\n}\n\nlet gamesByDate = getGamesByDate(games);\nlet todayGames = getTodayGames(gamesByDate);\nlet tomorrowGames = getTomorrowGames(gamesByDate);\nlet nextThreeDaysGames = getNextThreeDaysGames(gamesByDate);\n\nreturn [{\n 'payload': {\n 'updatedOn' : dateStr,\n 'allGames': games,\n 'gamesByDate' : gamesByDate,\n 'todayGames' : todayGames,\n 'tomorrowGames' : tomorrowGames,\n 'nextThreeDaysGames' : nextThreeDaysGames\n }\n}, null];","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":980,"y":160,"wires":[["bb49728e0dd5d749","956c0583d750ed41"]]},{"id":"956c0583d750ed41","type":"ha-sensor","z":"30ee198fc9087217","name":"TV FootbalGames","entityConfig":"c5c174550c444990","version":0,"state":"payload.updatedOn","stateType":"msg","attributes":[{"property":"todayGames","value":"payload.todayGames","valueType":"msg"},{"property":"tomorrowGames","value":"payload.tomorrowGames","valueType":"msg"},{"property":"updatedOn","value":"payload.updatedOn","valueType":"msg"},{"property":"nextThreeDaysGames","value":"payload.nextThreeDaysGames","valueType":"msg"},{"property":"gamesByDate","value":"payload.gamesByDate","valueType":"msg"}],"inputOverride":"allow","outputProperties":[],"x":1190,"y":260,"wires":[[]]},{"id":"70ab84cc965c1022","type":"cronplus","z":"30ee198fc9087217","name":"Every hour","outputField":"payload","timeZone":"","storeName":"","commandResponseMsgOutput":"output1","defaultLocation":"","defaultLocationType":"default","outputs":1,"options":[{"name":"schedule1","topic":"topic1","payloadType":"default","payload":"","expressionType":"cron","expression":"0 0 * * * *","location":"","offset":"0","solarType":"all","solarEvents":"sunrise,sunset"}],"x":150,"y":60,"wires":[["ac7e9165fbb8182e"]]},{"id":"c5c174550c444990","type":"ha-entity-config","server":"b9ae8401.4dfb28","deviceConfig":"","name":"TV Footbal Games","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"TV Footbal Games"},{"property":"icon","value":"mdi:soccer"},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false},{"id":"b9ae8401.4dfb28","type":"server","name":"Home Assistant","addon":true}]

```

NOVO FLOW:

```auto
[{"id":"c9d018a87d4f1e27","type":"tab","label":"Flow 2","disabled":false,"info":"","env":[]},{"id":"fc201300f9f5e5b2","type":"converter","z":"c9d018a87d4f1e27","name":"","from":"ISO-8859-1","x":520,"y":140,"wires":[["89da9c4f1530c80c"]]},{"id":"89da9c4f1530c80c","type":"html","z":"c9d018a87d4f1e27","name":"tbody","property":"payload","outproperty":"payload","tag":"#page > div.fake_container > div.zz-wrapper.mb-2 > div > div > div.zz-tpl-main > div:nth-child(2) > table > tbody","ret":"html","as":"single","chr":"","x":690,"y":140,"wires":[["7ac8caa3c9fcb76c"]]},{"id":"14415ab5755f057e","type":"http request","z":"c9d018a87d4f1e27","name":"","method":"GET","ret":"bin","paytoqs":"ignore","url":"https://www.zerozero.pt/zapping","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":350,"y":140,"wires":[["fc201300f9f5e5b2"]]},{"id":"7ac8caa3c9fcb76c","type":"function","z":"c9d018a87d4f1e27","name":"Get table rows","func":"let allRows = [];\nlet allGames = [];\nlet html = msg.payload[0];\nlet htmlToParse = html;\nlet baseUrl = \"https://www.zerozero.pt\";\n\nvar date = new Date();\nvar dateStr =\n date.getFullYear()+ \"-\" +\n (\"00\" + (date.getMonth() + 1)).slice(-2) + \"-\" +\n (\"00\" + date.getDate()).slice(-2) + \" \" +\n (\"00\" + date.getHours()).slice(-2) + \":\" +\n (\"00\" + date.getMinutes()).slice(-2) + \":\" +\n (\"00\" + date.getSeconds()).slice(-2);\n\nconst rows = html.split(/<tr[^>]*>/gi).slice(1); \n\nrows.forEach(row => {\n // Extract date and time from the link containing \"data=\"\n const dateTimeMatch = row.match(/data=([\\d-]+)\\s([\\d:]+)/);\n const date = dateTimeMatch ? dateTimeMatch[1] : '';\n const time = dateTimeMatch ? dateTimeMatch[2] : '';\n\n // Competition icon and short name\n let competitionIcon = '';\n let competitionShortName = '';\n let competitionFullName = '';\n\n const compBlock = row.match(/<div class=\"micrologo_and_text\">([\\s\\S]*?)<\\/div><\\/div><\\/td>/);\n if (compBlock) {\n const compImgMatch = compBlock[1].match(/<img[^>]+src=\"([^\"]+)\"[^>]*title=\"([^\"]+)\"[^>]*>/);\n if (compImgMatch) {\n competitionIcon = compImgMatch[1].startsWith('http') ? compImgMatch[1] : baseUrl + compImgMatch[1];\n competitionFullName = compImgMatch[2].trim();\n }\n const shortNameMatch = compBlock[1].match(/<div class=\"text\"><a[^>]*>([^<]+)<\\/a>/);\n competitionShortName = shortNameMatch ? shortNameMatch[1].trim() : '';\n }\n\n \n // Teams\n const homeTeam = row.match(/<td class=\"home\"><a[^>]*>(.*?)<span/)?.[1]?.trim() || '';\n const homeIcon = row.match(/<td><a[^>]*><img[^>]+src=\"([^\"]+?)\"/)?.[1] || '';\n const awayTeam = row.match(/<td class=\"away\"><a[^>]*>(.*?)<span/)?.[1]?.trim() || '';\n\n const imgMatches = [...row.matchAll(/<img[^>]+src=\"([^\"]+?)\"[^>]*>/g)];\n const awayIcon = imgMatches[2]?.[1] || ''; // third image is usually away team\n\n // TV channel icon and name (look for <img> before last column)\n const tvChannelMatch = [...row.matchAll(/<img[^>]+src=\"([^\"]+)\"[^>]+title=\"([^\"]+)\"[^>]*>/g)]\n .find(m => m[1].includes('/logos/tv/')); // find TV logo specifically\n\n const tvChannelIcon = tvChannelMatch ? (tvChannelMatch[1].startsWith('http') ? tvChannelMatch[1] : baseUrl + tvChannelMatch[1]) : '';\n const tvChannelName = tvChannelMatch ? tvChannelMatch[2] : '';\n\n // Push extracted data as a game object\n allGames.push({ \n 'date': date,\n 'time': time.slice(0, 5),\n 'transmissionType': '',\n 'country': competitionFullName,\n 'countryIcon': competitionIcon,\n 'division': competitionShortName,\n 'homeTeamName': homeTeam,\n 'homeTeamIcon': baseUrl + homeIcon,\n 'awayTeamName': awayTeam,\n 'awayTeamIcon': baseUrl + awayIcon,\n 'channel': tvChannelName,\n 'channelIcon': tvChannelIcon,\n 'channelLink': '',\n 'competitionName': competitionFullName\n });\n});\n\nfunction getTodayGames(gamesByDate) {\n let today = new Date().toISOString().split('T')[0];\n let todayGames = [];\n for(var i=0; i<gamesByDate.length; i++) {\n if(gamesByDate[i].date == today) {\n todayGames = gamesByDate[i];\n break;\n }\n }\n return todayGames;\n}\n\nfunction getTomorrowGames(gamesByDate) {\n var tomorrowDate = new Date();\n tomorrowDate.setDate(tomorrowDate.getDate() + 1);\n tomorrowDate = tomorrowDate.toISOString().split('T')[0];\n\n let tomorrowGames = [];\n for(var i=0; i<gamesByDate.length; i++) {\n if(gamesByDate[i].date == tomorrowDate) {\n tomorrowGames = gamesByDate[i];\n break;\n }\n }\n return tomorrowGames;\n}\n\nfunction getNextThreeDaysGames(gamesByDate) {\n let nextThreeDays = [];\n let today = new Date().toISOString().split('T')[0];\n nextThreeDays.push(today);\n\n var tomorrowDate = new Date();\n tomorrowDate.setDate(tomorrowDate.getDate() + 1);\n tomorrowDate = tomorrowDate.toISOString().split('T')[0];\n nextThreeDays.push(tomorrowDate);\n\n var nextTomorrowDate = new Date();\n nextTomorrowDate.setDate(nextTomorrowDate.getDate() + 2);\n nextTomorrowDate = nextTomorrowDate.toISOString().split('T')[0];\n nextThreeDays.push(nextTomorrowDate);\n\n let nextThreeDaysGames = [];\n for(var i=0; i<gamesByDate.length; i++) {\n if(nextThreeDays.includes(gamesByDate[i].date)) {\n nextThreeDaysGames.push(gamesByDate[i]);\n }\n }\n return nextThreeDaysGames;\n}\n\n\n\n\nfunction getGamesByDate(allGames) {\n let gamesByDate = [];\n for(var i=0; i<allGames.length; i++) {\n if(gamesByDate.length ==0) {\n gamesByDate.push({\n 'date' : allGames[i].date,\n 'games' : [allGames[i]],\n 'competitions' : [{\n 'name' : allGames[i].competitionName,\n 'icon': allGames[i].countryIcon,\n 'games' : [allGames[i]]\n }\n ]\n });\n } else {\n let foundedDate = false;\n let foundedCompetition = false;\n for (var t = 0; t < gamesByDate.length; t++) {\n if (gamesByDate[t].date == allGames[i].date) {\n foundedDate = true;\n gamesByDate[t].games.push(allGames[i]);\n for(var x=0; x<gamesByDate[t].competitions.length; x++) {\n if(gamesByDate[t].competitions[x].name ==allGames[i].competitionName ) {\n gamesByDate[t].competitions[x].games.push(allGames[i]);\n foundedCompetition = true;\n }\n }\n if(!foundedCompetition) {\n gamesByDate[t].competitions.push({\n 'name' : allGames[i].competitionName,\n 'icon' : allGames[i].countryIcon,\n 'games' : [allGames[i]]\n });\n }\n }\n }\n if(!foundedDate) {\n gamesByDate.push({\n 'date' : allGames[i].date,\n 'games' : [allGames[i]],\n 'competitions' : [{\n 'name' : allGames[i].competitionName,\n 'icon' : allGames[i].countryIcon,\n 'games' : [allGames[i]]\n }\n ]\n });\n }\n }\n }\n return gamesByDate;\n}\n\n\n\nlet gamesByDate = getGamesByDate(allGames);\nlet todayGames = getTodayGames(gamesByDate);\nlet tomorrowGames = getTomorrowGames(gamesByDate);\nlet nextThreeDaysGames = getNextThreeDaysGames(gamesByDate);\n\nreturn [{\n 'payload': {\n 'updatedOn' : dateStr,\n 'allGames': allGames,\n 'gamesByDate' : gamesByDate,\n 'todayGames' : todayGames,\n 'tomorrowGames' : tomorrowGames,\n 'nextThreeDaysGames' : nextThreeDaysGames\n }\n}, null];","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":260,"wires":[["c6ec6249e3406c61","cb091b3bc6898cab"]]},{"id":"384451d939c2f977","type":"inject","z":"c9d018a87d4f1e27","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":140,"wires":[["14415ab5755f057e"]]},{"id":"e81c3f1f3c47c2ad","type":"cronplus","z":"c9d018a87d4f1e27","name":"Every hour","outputField":"payload","timeZone":"","storeName":"","commandResponseMsgOutput":"output1","defaultLocation":"","defaultLocationType":"default","outputs":1,"options":[{"name":"schedule1","topic":"topic1","payloadType":"default","payload":"","expressionType":"cron","expression":"0 0 * * * *","location":"","offset":"0","solarType":"all","solarEvents":"sunrise,sunset"}],"x":150,"y":80,"wires":[["14415ab5755f057e"]]},{"id":"c6ec6249e3406c61","type":"ha-sensor","z":"c9d018a87d4f1e27","name":"TV FootballGames","entityConfig":"c5c174550c444990","version":0,"state":"payload.updatedOn","stateType":"msg","attributes":[{"property":"todayGames","value":"payload.todayGames","valueType":"msg"},{"property":"tomorrowGames","value":"payload.tomorrowGames","valueType":"msg"},{"property":"updatedOn","value":"payload.updatedOn","valueType":"msg"},{"property":"nextThreeDaysGames","value":"payload.nextThreeDaysGames","valueType":"msg"},{"property":"gamesByDate","value":"payload.gamesByDate","valueType":"msg"}],"inputOverride":"allow","outputProperties":[],"x":630,"y":320,"wires":[[]]},{"id":"cb091b3bc6898cab","type":"debug","z":"c9d018a87d4f1e27","name":"debug 26","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":220,"wires":[]},{"id":"c5c174550c444990","type":"ha-entity-config","server":"b9ae8401.4dfb28","deviceConfig":"","name":"TV Football Games","version":"6","entityType":"sensor","haConfig":[{"property":"name","value":"TV Football Games"},{"property":"icon","value":"mdi:soccer"},{"property":"entity_picture","value":""},{"property":"entity_category","value":""},{"property":"device_class","value":""},{"property":"unit_of_measurement","value":""},{"property":"state_class","value":""}],"resend":false,"debugEnabled":false},{"id":"b9ae8401.4dfb28","type":"server","name":"Home Assistant","addon":true}]

```

 ![image](https://forum.cpha.pt/uploads/default/original/3X/9/f/9f471b21bb2b88332f256aad5423e6caafebf06c.png)

Devem testar a execução do flow para garantir que o sensor é criado com sucesso. O sensor criado tem o nome sensor.tv\_footbal\_games. Para validar, podem aceder ao Developer Tools e consultar o estado do sensor anterior para garantir que os dados foram carregados com sucesso.

Devem criar o seguinte **template** no ficheiro **configuration.yaml**

```auto
template:
  - sensor:
      - name: "Football TV Selected View Type"
        state: >
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            today_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'list') %}
            today_list
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            tomorrow_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'list') %}
            tomorrow_list
            {% endif %}
            {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            nextdays_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'list') %}
            nextdays_list  
          {% endif %}

```

 ![image](https://forum.cpha.pt/uploads/default/original/3X/2/0/2061a8463b274733071f149ce5d6efef89bbf63c.png)

A nivel do card, é necessário adicionarem os seguintes cards custom:  
[https://github.com/ofekashery/vertical-stack-in-card](https://github.com/ofekashery/vertical-stack-in-card)  
[https://github.com/custom-cards/button-card](https://github.com/custom-cards/button-card)  
[https://github.com/PiotrMachowski/Home-Assistant-Lovelace-HTML-Jinja2-Template-card](https://github.com/PiotrMachowski/Home-Assistant-Lovelace-HTML-Jinja2-Template-card)  
[https://github.com/ownbee/bootstrap-grid-card](https://github.com/ownbee/bootstrap-grid-card)

Para o card, criei 2 inputs helpers (aceder às Settings, integrations, helpers e criar com os nomes iguais) que permite guardar a selecção do dia e tipo de vista.  
Criar dois helpers com os ids:

_ **input\_text.football\_tv\_view\_type** _ e _ **input\_text.football\_tv\_range\_days** _

Código do Card:

```auto
type: custom:vertical-stack-in-card
cards:
  - type: custom:bootstrap-grid-card
    cards:
      - type: row
        cards:
          - type: custom:button-card
            class: col-xs-3 col-md-1 col-2 col-lg-1
            icon: mdi:calendar-today
            size: 60%
            styles:
              card:
                - height: 30px
            tap_action:
              action: call-service
              service: input_text.set_value
              target:
                entity_id: input_text.football_tv_range_days
              data:
                value: today
          - type: custom:button-card
            class: col-xs-3 col-md-2 col-2 col-lg-1
            icon: mdi:calendar-arrow-right
            size: 60%
            styles:
              card:
                - height: 30px
            tap_action:
              action: call-service
              service: input_text.set_value
              target:
                entity_id: input_text.football_tv_range_days
              data:
                value: tomorrow
          - type: custom:button-card
            class: col-xs-3 col-md-2 col-2 col-lg-1
            icon: mdi:calendar-end
            size: 60%
            styles:
              card:
                - height: 30px
            tap_action:
              action: call-service
              service: input_text.set_value
              target:
                entity_id: input_text.football_tv_range_days
              data:
                value: nextdays
          - type: custom:button-card
            color_type: blank-card
            class: col-xs-3 col-md-5 col-2 col-lg-7
          - type: custom:button-card
            class: col-xs-10 col-md-1 col-2 col-lg-1
            icon: mdi:format-list-bulleted
            size: 60%
            styles:
              card:
                - height: 30px
            tap_action:
              action: call-service
              service: input_text.set_value
              target:
                entity_id: input_text.football_tv_view_type
              data:
                value: list
          - type: custom:button-card
            class: col-xs-10 col-md-1 col-2 col-lg-1
            size: 60%
            styles:
              card:
                - height: 30px
            tap_action:
              action: call-service
              service: input_text.set_value
              target:
                entity_id: input_text.football_tv_view_type
              data:
                value: grid
            icon: mdi:order-bool-ascending
  - type: vertical-stack
    cards:
      - type: conditional
        conditions:
          - entity: sensor.football_tv_selected_view_type
            state: today_list
        card:
          type: custom:html-template-card
          ignore_line_breaks: true
          content: |
            <h2> Futebol na TV: <u>
              {{states.sensor.tv_footbal_games.attributes.todaygames.date }}</u>
              </h2>
               <table style="width: 100%; border: 1px solid; border-radius: 10px;">
              <tbody>
               {% for game in states.sensor.tv_footbal_games.attributes.todaygames.games -%}

               <tr>
               <td colspan="4" style=" text-align:center;"><img style=margin-top:10px;margin-right:10px;width:20px;border-radius:50px;height:20px" src={{game.countryIcon}} /><b>{{game.competitionName}} </b></td>

                <tr>
                
                  <td style="font-size:10px;text-align:center; width:10%">{{game.time}}</td>
                  <td> <div style="margin-left:10px;border-left:1px solid;height:30px"></div></td>
                  <td >
                      <div style="margin-top:10px; margin-bottom:5px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.homeTeamIcon}} /><label style="margin-left:10px">{{game.homeTeamName}} </label> </div>
                      <div style="margin-bottom:10px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.awayTeamIcon}} /><label style="margin-left:10px">{{game.awayTeamName}} </label> </div>
                  
                  </td>
                  <td style="width:20%; text-align:center">
                    <div ><img
              style="max-height:30px; max-width:70px; height:auto;width:auto;"
              src={{game.channelIcon}} /><div>
                    <div style="font-size:8px;">{{game.channel}}</div>
                  </td>
              </tr>

              {%- endfor %} <tbody> </table>
      - type: conditional
        conditions:
          - entity: sensor.football_tv_selected_view_type
            state: today_grid
        card:
          type: custom:html-template-card
          title: null
          ignore_line_breaks: true
          content: >
            <h2> Futebol na TV: <u>
            {{states.sensor.tv_footbal_games.attributes.todaygames.date }}</u>
            </h2>

             {% for competition in states.sensor.tv_footbal_games.attributes.todaygames.competitions -%}
               <table style="margin-top:15px; width: 100%; border: 1px solid; border-radius: 10px;">
            <tbody>
             <tr>
             <td colspan="4" style=" text-align:center;"><img style=margin-top:10px;margin-right:10px;width:20px;border-radius:50px;height:20px" src={{competition.icon}} /><b>{{competition.name}} </b></td>
                
              </tr>
              {% for game in competition.games -%}
              <tr>
                
                  <td style="font-size:10px;text-align:center; width:10%">{{game.time}}</td>
                  <td> <div style="margin-left:10px;border-left:1px solid;height:30px"></div></td>
                  <td >
                      <div style="margin-top:10px; margin-bottom:5px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.homeTeamIcon}} /><label style="margin-left:10px">{{game.homeTeamName}} </label> </div>
                      <div style="margin-bottom:10px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.awayTeamIcon}} /><label style="margin-left:10px">{{game.awayTeamName}} </label> </div>
                  
                  </td>
                  <td style="width:20%;text-align:center">
                    <div ><img
              style="max-height:30px; max-width:70px; height:auto;width:auto;"
              src={{game.channelIcon}} /><div>
                    <div style="font-size:8px;">{{game.channel}}</div>
                  </td>
              </tr>
              {%- endfor %}  
            <tbody> </table> {%- endfor %}  
      - type: conditional
        conditions:
          - entity: sensor.football_tv_selected_view_type
            state: tomorrow_list
        card:
          type: custom:html-template-card
          ignore_line_breaks: true
          content: |
            <h2> Futebol na TV: <u>
              {{states.sensor.tv_footbal_games.attributes.tomorrowgames.date }}</u>
              </h2>
               <table style="width: 100%; border: 1px solid; border-radius: 10px;">
              <tbody>
               {% for game in states.sensor.tv_footbal_games.attributes.tomorrowgames.games -%}

               <tr>
               <td colspan="4" style=" text-align:center;"><img style=margin-top:10px;margin-right:10px;width:20px;border-radius:50px;height:20px" src={{game.countryIcon}} /><b>{{game.competitionName}} </b></td>

                <tr>
                
                  <td style="font-size:10px;text-align:center; width:10%">{{game.time}}</td>
                  <td> <div style="margin-left:10px;border-left:1px solid;height:30px"></div></td>
                  <td >
                      <div style="margin-top:10px; margin-bottom:5px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.homeTeamIcon}} /><label style="margin-left:10px">{{game.homeTeamName}} </label> </div>
                      <div style="margin-bottom:10px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.awayTeamIcon}} /><label style="margin-left:10px">{{game.awayTeamName}} </label> </div>
                  
                  </td>
                  <td style="width:20%;text-align:center">
                    <div ><img
              style="max-height:30px; max-width:70px; height:auto;width:auto;"
              src={{game.channelIcon}} /><div>
                    <div style="font-size:8px;">{{game.channel}}</div>
                  </td>
              </tr>

              {%- endfor %} <tbody> </table>
      - type: conditional
        conditions:
          - entity: sensor.football_tv_selected_view_type
            state: tomorrow_grid
        card:
          type: custom:html-template-card
          ignore_line_breaks: true
          content: >
            <h2> Futebol na TV: <u>
            {{states.sensor.tv_footbal_games.attributes.tomorrowgames.date
            }}</u> </h2>

             {% for competition in states.sensor.tv_footbal_games.attributes.tomorrowgames.competitions -%}
               <table style="margin-top:15px; width: 100%; border: 1px solid; border-radius: 10px;">
            <tbody>
             <tr>
             <td colspan="4" style=" text-align:center;"><b>{{competition.name}} </b></td>
                
              </tr>
              {% for game in competition.games -%}
              <tr>
                
                  <td style="font-size:10px;text-align:center; width:10%">{{game.time}}</td>
                  <td> <div style="margin-left:10px;border-left:1px solid;height:30px"></div></td>
                  <td >
                      <div style="margin-top:10px; margin-bottom:5px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.homeTeamIcon}} /><label style="margin-left:10px">{{game.homeTeamName}} </label> </div>
                      <div style="margin-bottom:10px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.awayTeamIcon}} /><label style="margin-left:10px">{{game.awayTeamName}} </label> </div>
                  
                  </td>
                  <td style="width:20%;text-align:center">
                    <div ><img
              style="max-height:30px; max-width:70px; height:auto;width:auto;"
              src={{game.channelIcon}} /><div>
                    <div style="font-size:8px;">{{game.channel}}</div>
                  </td>
              </tr>
              {%- endfor %}  
            <tbody> </table> {%- endfor %}  
      - type: conditional
        conditions:
          - entity: sensor.football_tv_selected_view_type
            state: nextdays_list
        card:
          type: custom:html-template-card
          ignore_line_breaks: true
          content: >
            {% for gameDate in
            states.sensor.tv_footbal_games.attributes.gamesbydate -%}
                <h2>{{gameDate.date}}</h2>
                   <table style="width: 100%; border: 1px solid; border-radius: 10px;">
             <tbody>
                  {% for game in gameDate.games -%}
                  

              <tr>
              <td colspan="4" style=" text-align:center;"><img style=margin-top:10px;margin-right:10px;width:20px;border-radius:50px;height:20px" src={{game.countryIcon}} /><b>{{game.competitionName}} </b></td>

               <tr>
               
                 <td style="font-size:10px;text-align:center; width:10%">{{game.time}}</td>
                 <td> <div style="margin-left:10px;border-left:1px solid;height:30px"></div></td>
                 <td >
                     <div style="margin-top:10px; margin-bottom:5px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.homeTeamIcon}} /><label style="margin-left:10px">{{game.homeTeamName}} </label> </div>
                     <div style="margin-bottom:10px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.awayTeamIcon}} /><label style="margin-left:10px">{{game.awayTeamName}} </label> </div>
                 
                 </td>
                 <td style="width:20%;text-align:center">
                   <div ><img
             style="max-height:30px; max-width:70px; height:auto;width:auto;"
             src={{game.channelIcon}} /><div>
                   <div style="font-size:8px;">{{game.channel}}</div>
                 </td>
             </tr>
                   {%- endfor %} 
                    <tbody> </table>
              {%- endfor %} 
      - type: conditional
        conditions:
          - entity: sensor.football_tv_selected_view_type
            state: nextdays_grid
        card:
          type: custom:html-template-card
          ignore_line_breaks: true
          content: |
            {% for gameDate in
             states.sensor.tv_footbal_games.attributes.gamesbydate -%}
                 <h2>{{gameDate.date}}</h2>
                   
                   {% for competition in gameDate.competitions -%}
                    <table style="margin-top:15px; width: 100%; border: 1px solid; border-radius: 10px;">
                    <tbody>
              <tr>
              <td colspan="4" style=" text-align:center;"><b>{{competition.name}} </b></td>
                 
               </tr>
                      {% for game in competition.games -%}
               <tr>
                 
                   <td style="font-size:10px;text-align:center; width:10%">{{game.time}}</td>
                   <td> <div style="margin-left:10px;border-left:1px solid;height:30px"></div></td>
                   <td >
                       <div style="margin-top:10px; margin-bottom:5px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.homeTeamIcon}} /><label style="margin-left:10px">{{game.homeTeamName}} </label> </div>
                       <div style="margin-bottom:10px"><img style="vertical-align:middle;width:20px;height:20px" src={{game.awayTeamIcon}} /><label style="margin-left:10px">{{game.awayTeamName}} </label> </div>
                   
                   </td>
                   <td style="width:20%;text-align:center">
                     <div ><img
               style="max-height:30px; max-width:70px; height:auto;width:auto;"
               src={{game.channelIcon}} /><div>
                     <div style="font-size:8px;">{{game.channel}}</div>
                   </td>
               </tr>
               {%- endfor %}
                    </table>
                     {%- endfor %} 
               {%- endfor %} 

```

Além disto é preciso criar o seguinte sensor no ficheiro configuration.yaml para guardar a seleção referente ao tipo de vista/dia.

```auto
template:
  - sensor:
      - name: "Football TV Selected View Type"
        state: >
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            today_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'list') %}
            today_list
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            tomorrow_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'list') %}
            tomorrow_list
            {% endif %}
            {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            nextdays_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'list') %}
            nextdays_list  
          {% endif %}

```

 ![image](https://forum.cpha.pt/uploads/default/original/3X/9/e/9ee16ba7aafac3e50a403c057577d3713323464e.jpeg)

 ![image](https://forum.cpha.pt/uploads/default/original/3X/b/7/b72fb6ce5a9808747c31b820570f46d48437e51f.jpeg)

 ![image](https://forum.cpha.pt/uploads/default/original/3X/a/4/a421cf36a473dc3c2d3ec3ba200f21f9adec7844.jpeg)  
 ![image](https://forum.cpha.pt/uploads/default/original/3X/9/a/9a55803bbacbd7542901e74912411d02ef217e13.jpeg)

---

<div class="post-metadata">

**Author:** ![loading27](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/l/858c86/32.png) [@loading27](https://forum.cpha.pt/u/loading27)\
**Post date:** [23 Maio , 2024 07:23 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/2 "2024-05-23T07:23:13Z")

</div>

Logo já experimento mas parece brutal. Obrigado pela partilha 💪

---

<div class="post-metadata">

**Author:** ![NOG003](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/n/bc79bd/32.png) [@NOG003](https://forum.cpha.pt/u/NOG003)\
**Post date:** [27 Maio , 2024 21:00 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/3 "2024-05-27T21:00:37Z")

</div>

> [@vpnobrega](#):
>

Boas.

Já tentei instalar mas não aparece nada.  
Apesar de faltar de mencionar um addon do HACS (bootstrap-grid-card), não aparece nada.  
Instalei as bibliotecas do NR e não me cria nenhum sensor.football\_tv\_selected\_view\_type.

Fico assim.

 ![image](https://forum.cpha.pt/uploads/default/original/3X/e/b/eb9986ba5b322078b9f62471106a9db2e9c300fc.png)

Pode dar-me uma ajuda por favor?  
Obrigado desde já

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [27 Maio , 2024 21:22 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/4 "2024-05-27T21:22:32Z")

</div>

Boas.

Antes de mais obrigado pelo feedback.  
Deves validar se o flow do Node Red foi executado e se no último node mostra alguma data.

Atualizei o post inicial com a informação complementar para validar se o sensor ficou bem criado.

---

<div class="post-metadata">

**Author:** ![NOG003](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/n/bc79bd/32.png) [@NOG003](https://forum.cpha.pt/u/NOG003)\
**Post date:** [27 Maio , 2024 21:28 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/5 "2024-05-27T21:28:32Z")

</div>

Sim o flow foi executado conforme mostra a imagem.

 ![image](https://forum.cpha.pt/uploads/default/original/3X/d/7/d79bc7cf62483646a0b3d80e13c9abd9c2684426.png)

Mas o sensor não é criado…

 ![image](https://forum.cpha.pt/uploads/default/original/3X/c/a/ca582b5f8bc8c1d6ba207c98aa18bbdb20c6c5dc.png)

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [27 Maio , 2024 21:45 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/6 "2024-05-27T21:45:39Z")

</div>

Edita o ultimo node para ver os detalhes.

Tenho assim:

 ![image](https://forum.cpha.pt/uploads/default/original/3X/e/1/e10d776d62da4a2a717e274fa1384e6de8328690.png)

O nome do sensor deverá ser o sensor que ele cria no flow.

---

<div class="post-metadata">

**Author:** ![NOG003](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/n/bc79bd/32.png) [@NOG003](https://forum.cpha.pt/u/NOG003)\
**Post date:** [27 Maio , 2024 21:57 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/7 "2024-05-27T21:57:53Z")

</div>

> [@vpnobrega](#):
>

Refere-se a isto?

 ![image](https://forum.cpha.pt/uploads/default/original/3X/c/b/cb3d9c1221ae90358078ad33f19adc8c7d0d8af3.png)

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [27 Maio , 2024 22:09 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/8 "2024-05-27T22:09:08Z")

</div>

sim mas está ok.

Faz assim

1. Aceder às Settings
2. Devices & services
3. Selecionar a integração Node Red Companion
4. Aceder às entidades  
 ![image](https://forum.cpha.pt/uploads/default/original/3X/6/a/6a744161f3c1c423d1581d1670c27eea8a7dfa40.png)
5. Consultar o sensor criado (sensor.tv\_footbal\_games) senão tiver este nome, consultar os outros sensores para ver se o Node Red aplicou outro nome.  
 ![image](https://forum.cpha.pt/uploads/default/optimized/3X/f/8/f80794282aab346295389b509170600f64716561_2_640x19.png)

 ![image](https://forum.cpha.pt/uploads/default/original/3X/f/2/f2b98586196df5af33386f9dcfe141a218afa1ad.png)

---

<div class="post-metadata">

**Author:** ![NOG003](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/n/bc79bd/32.png) [@NOG003](https://forum.cpha.pt/u/NOG003)\
**Post date:** [27 Maio , 2024 22:13 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/9 "2024-05-27T22:13:06Z")

</div>

Afinal os macacos estão aqui com outro nome…

 ![image](https://forum.cpha.pt/uploads/default/original/3X/d/6/d67cc6ec1cb46f8ce8afe170d9362ec4bea22097.png)

porque andava à procura deste nome… não sei se isso faz diferença!!!

 ![image](https://forum.cpha.pt/uploads/default/original/3X/2/e/2e203404c6ab090371a1298ca87b548bb9b7dfee.png)

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [27 Maio , 2024 22:52 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/10 "2024-05-27T22:52:41Z")

</div>

Txiii esqueci-me de outro sensor que é criado no configuration.yaml

Adiciona isto, dá restart e testa.

```auto
template:
  - sensor:
      - name: "Football TV Selected View Type"
        state: >
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            today_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'list') %}
            today_list
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            tomorrow_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'list') %}
            tomorrow_list
            {% endif %}
            {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            nextdays_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'list') %}
            nextdays_list  
          {% endif %}

```

---

<div class="post-metadata">

**Author:** ![NOG003](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/n/bc79bd/32.png) [@NOG003](https://forum.cpha.pt/u/NOG003)\
**Post date:** [27 Maio , 2024 23:01 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/11 "2024-05-27T23:01:48Z")

</div>

Já está a dar.  
Muito obrigado

 ![image](https://forum.cpha.pt/uploads/default/original/3X/2/5/255c1db4b0b3c0734c6dbfe3747d8131bc6f6244.png)

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [27 Maio , 2024 23:14 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/12 "2024-05-27T23:14:00Z")

</div>

Obrigado pelo feedback. Desta forma partilhei os dados no post inicial para que outros users consigam ler e colocar isto a bombar

---

<div class="post-metadata">

**Author:** ![karma](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/k/bcef8e/32.png) [@karma](https://forum.cpha.pt/u/karma)\
**Post date:** [1 Junho , 2024 16:11 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/13 "2024-06-01T16:11:18Z")

</div>

Boas.

Tentei instalar também mas a mim os unicos sensores que tenho são estes :

 ![image](https://forum.cpha.pt/uploads/default/original/3X/d/d/dd29bbb8f573f7d1df3fbf59c681d105c4fb016a.png)

No NodeRed não tenho erro nenhum, e no card quando carrego num dos botões não faz nada:

 ![image](https://forum.cpha.pt/uploads/default/original/3X/9/8/986c124dc62d41f844f3a84bb84f01e8e327ee7e.png)  
 ![image](https://forum.cpha.pt/uploads/default/original/3X/f/6/f6cedd6249def98ad0753b2499b440e7dd9f89f6.png)

Sou eu que tenho de criar estas entidades?

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [1 Junho , 2024 16:52 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/14 "2024-06-01T16:52:59Z")

</div>

@karma falta esta parte no configuration. Tenho de colocar no post inicial

Adiciona isto, dá restart e testa.

```auto
template:
  - sensor:
      - name: "Football TV Selected View Type"
        state: >
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            today_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'today') and
          is_state('input_text.football_tv_view_type', 'list') %}
            today_list
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            tomorrow_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'tomorrow') and
          is_state('input_text.football_tv_view_type', 'list') %}
            tomorrow_list
            {% endif %}
            {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'grid') %}
            nextdays_grid
            {% endif %}
          {% if is_state('input_text.football_tv_range_days', 'nextdays') and
          is_state('input_text.football_tv_view_type', 'list') %}
            nextdays_list  
          {% endif %}

```

---

<div class="post-metadata">

**Author:** ![karma](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/k/bcef8e/32.png) [@karma](https://forum.cpha.pt/u/karma)\
**Post date:** [1 Junho , 2024 17:29 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/15 "2024-06-01T17:29:21Z")

</div>

Sim, esse eu já criei (como mostro na foto em cima), já me aparece esse sensor. Ele não está propriamente no configuration, mas está dentro dos pakages que é a mesma coisa. Eu já o tenho criado, mas nao apresenta valor nenhum, é mesmo assim?

Os “input\_text.\*\*\*”, temos que os criar?

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [4 Junho , 2024 21:47 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/16 "2024-06-04T21:47:12Z")

</div>

Sim os input texto é preciso criar. Sempre para guardar o tipo de vista.

---

<div class="post-metadata">

**Author:** ![karma](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/k/bcef8e/32.png) [@karma](https://forum.cpha.pt/u/karma)\
**Post date:** [5 Junho , 2024 20:36 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/17 "2024-06-05T20:36:59Z")

</div>

Partilha essa configuração sff. E adiciona em cima na partilha de projetos. Como é informação que falta para conseguirmos ter o card a funcionar 👍

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [5 Junho , 2024 21:44 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/18 "2024-06-05T21:44:43Z")

</div>

Já atualizei com os passos que deves seguir para ir á parte dos helpers e criar dois com os nomes indicados.

---

<div class="post-metadata">

**Author:** ![karma](https://forum.cpha.pt/letter_avatar_proxy/v4/letter/k/bcef8e/32.png) [@karma](https://forum.cpha.pt/u/karma)\
**Post date:** [7 Junho , 2024 20:55 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/19 "2024-06-07T20:55:01Z")

</div>

Amigo, não adicionas te essa configuração.

---

<div class="post-metadata">

**Author:** ![vpnobrega](https://forum.cpha.pt/user_avatar/forum.cpha.pt/vpnobrega/32/5112_2.png) [@vpnobrega](https://forum.cpha.pt/u/vpnobrega)\
**Post date:** [7 Junho , 2024 23:59 UTC](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837/20 "2024-06-07T23:59:26Z")

</div>

Para o card, criei 2 inputs helpers (aceder às Settings, integrations, helpers e criar com os nomes iguais) que permite guardar a selecção do dia e tipo de vista.  
Criar dois helpers com os ids:

_input\_text.football\_tv\_view\_type_ e _ **input\_text.football\_tv\_range\_days** _

Está nesta parte. Tem de ser criado manualmente.

[Próxima página](https://forum.cpha.pt/t/jogos-de-futebol-com-transmissao-televisiva-v2/13837.md?page=2)
