Thanks for the quick reply! I updated this setting and the tile showed up right away!
Hey @JustinL , I recently installed your app and I'm loving it! I had been looking for a way to trigger some routines when my teams are playing or when they win, and this does exactly that!
I have noticed that I don't get notified on wins/losses until midnight. I figured that it was probably due to sportsdata.io not updating the win/loss record until the next day. However, tonight after a game, I decided to look at the logs, and I'm seeing the following:
This is happening in the "setStandings" function. You can correct me if I'm wrong, but I believe that it is due to state.teams getting cleared with the "Clear teams data between updates" option selected. Since the "setStandings" function relies on that state variable, it ends up crashing and never getting to the routine that checks if the win/loss record has changed.
For now, I have just added if (!state.teams) setTeams() to the setStandings function. I believe that this will correct the issue, but I'll need to wait for the next game to verify. The other option could be to not call "setStandings()" from the "updateRecord()" routine. If neither of these are the correct fix, or if you have other suggestions, I'd love to hear from you.
Thanks again for all your work with this. It's an excellent app!
Wonder why I haven't experienced this error, despite having some college teams with this option selection to clear team state. Either way, that appears to be the right solution, with just the tweak to avoid the rest of setStandings() since setTeams() makes the more efficient setStandings() unnecessary. I'll push an update out soon that makes that safeguard official. Thanks for pointing it out.
Thanks for the response, I look forward to the update!
I had one more suggestion that I wanted to get your thought on. After my team's game tonight (College Basketball) I noticed that sportsdata.io still hasn't updated the win/loss record of my team even two hours after the game ended. It got me wondering if there would be a faster way to get the win/loss for a game by using the box score. I've found, however, that the score from the /v3/cbb/scores/json/TeamSchedule/{season}/{team} endpoint isn't correct.
After digging around the sportsdata.io api documentation, I found that for free accounts, they scramble the final score so as to try to get you to purchase the paid version. As I looked through the scrambled scores from past games and compared to the actual scores, I've found that the scrambled scores are actually just scaled by a factor of approximately 3.6 as described below (at least this is how they were "scrambled" for the handful of games that I looked at):
scrambledScore = round(actualScore/3.6)
Since both the awayTeamScore and homeTeamScore are adjusted by the same scale factor, the winner can still usually be determined by comparing the scrambled scores. This approach likely won't work for close games, since the scrambled score could end up being the same for home/away team. However, for larger margin of victory games, I think this would work well and allow for pressing of button 3/4 sooner than just waiting for the win/loss record to be updated. What are your thoughts?
Below is how I've piecemealed this into your code in updateState(). This works for my use case, but I end up getting two button 3/4 presses (one for my update, and one when the win/loss gets updated), so there's likely a better approach for this.
def lastGameData = getGameData(lastGame)
if (state?.lastGame?.opponent?.school != lastGameData?.opponent?.school) {
logDebug("Checking box score to see if we can figure out the winner based on the scrambled score")
logDebug("${lastGameData.awayTeam.school} scored ${lastGame.AwayTeamScore}, ${lastGameData.homeTeam.school} scored ${lastGame.HomeTeamScore}")
if (lastGameData.opponent.school == lastGameData.awayTeam.school) { //opponent was the away team
if (lastGame.AwayTeamScore < lastGame.HomeTeamScore) pushDeviceButton(3)
else if (lastGame.AwayTeamScore > lastGame.HomeTeamScore) pushDeviceButton(4)
} else { //opponent was the home team
if (lastGame.AwayTeamScore > lastGame.HomeTeamScore) pushDeviceButton(3)
else if (lastGame.AwayTeamScore < lastGame.HomeTeamScore) pushDeviceButton(4)
}
}
The scrambling of the scores is indeed the reason why the app deduces win/losses from the record when the record is updated. I had not tried to reverse engineer the scrambling because their FAQs say "Our Free Trial has some values that are “scrambled,” or a value that is randomly adjusted up or down between 5% and 20% from the actual value. " I believe your approach to unscrambling would need to be tested quite a bit more to make sure that it's accurate and stable over time. I worry that they would randomly adjust the scaling factor from game to game or day to day or week to week. Could you monitor it for a while to see?
This has me looking though if there's some other source of live scores that the app could pull in. Most of the live score APIs appear to be geared towards sports betting, so the pricing doesn't make sense for a home automation enthusiast who isn't pulling in income from the data. I just found https://www.thesportsdb.com and it's intriguing. Looking into it. Might allow live scores for only $7 per month (or $70 / year), which is vastly cheaper than sportsdata.io.
I noticed the same in the FAQ, that the scrambling was random between 5% and 20%. I was a bit surprised to see that the actual scrambled value was actually 1/3.6X instead of 5-20%. Also, I was happy to see that (it appears) the same scrambling factor gets applied to both the away and home teams.
I just finished creating a script to log scores for the season from a handful of teams, with data collected once/day. I'll let it go for a few weeks/month to see if the scrambling factor appears to be constant, or if it varies and let you know the results. Even if it does vary, as long as the same factor is applied to both teams, it would still work for assessing winning team/losing team.
Ok will look forward to your report. Can you log for multiple leagues as well, to see if it varies across leagues?
Yeah, no problem. I've adjusted the script to look at CFB, CBB, NBA and NFL for a handful of teams in each league. I'll let you know what I find out.
Hey @JustinL, I've been logging the data for about a month now, and it has stayed consistent. I can't upload the *.csv files that I generated to the forum, so I've placed them in the following location in case you're interested in looking at them.
https://drive.google.com/drive/folders/1payF77Ij-R5hx8DZa5CCVYAS3tgKdkIL?usp=sharing
I collected data for NBA, NFL, CBB and CFB. Within each folder is a separate file for each of the teams that I was keeping an eye on (eg CBB/GTECH.csv).
The following shows an example of the data that's in these files. The data is as follows:
- Individual games are grouped in sets of three columns (Away Team/Home Team/ Winning Team)
- Row 4 shows the actual score of the game (note that this was manually entered, and I haven't entered the data for all teams)
- Row 5 shows the scale factor between the scrambled score and actual score
- The data was collected once/day. As can be seen, the scrambled score is consistent from week-to-week
- Note that for some close games, the scrambled score can end up being the same for the two teams, at which point the winner cannot be determined (see example MASLOW vs. GTECH). For this case, it would make sense to fallback on your other method of deducing the winner from record instead of from scrambled score.
A few important notes from the data:
- The scrambled scale factor is the same from day-to-day (at least with a month of data)
- The scrambled scale factor is the same for a given team from game-to-game
- The scrambled scale factor is the same for home team and away team
This last bullet is really what matters to us if we want to try to use the scrambled scores to deduce winners/losers.
Finally, in each of the league's folders there's a file named Records.csv. This contains the win-loss record for each of the tracked teams over time. For a given sample collection date, there are two rows: One contains the record as calculated from the game scores and one contains the record from the schedule. For the "Calculated from Games" row, the record is given as Wins-Losses-Undetermined, with undetermined games as described previously. As you look through the individual team's records, you'll notice that the records are consistent between both approaches, with the exception of the few games that are "undetermined".
Hopefully this is enough evidence for you to consider adding this capability to the gametime app. Let me know if any of this is unclear (sorry, this ended up being a long message). I'll continue to log the data to ensure that it stays consistent from month-to-month, but I'm very confident that it's behaving in a way that would allow for deducing winner/loser based on scrambled scores.
Yes, I think it is. Thanks! Under what conditions do you believe we should avoid making the call too soon from the scrambled data? Just when the scrambled scores are equal? Or also when they are within a certain amount of each other (how close?).
This has me also considering if we can be so bold as to unscramble the scores to provide in-game score data. It would require the app to know the scaling factor for each team. To figure that out, the app needs maybe just the score of the last game for each of the user’s teams. The rudimentary way to get that would be just to allow the user to enter the last score when adding a team in the app. A more sophisticated way would be to find some free non-live API with scores and get that data automatically, but I haven’t found any such API. All the APIs I have seen require authentication and not sure it would be a good user experience to have to sign up to multiple APIs. Thoughts on this given what you’ve seen with the scrambling?
EDIT: I have coded this enhancement up, including score descrambling based on an initial calibration during set up with the score of the last game. I will monitor its accuracy and release if it proves reliable. So far so good from initial testing. Of course, there will need to be qualifying language that the score can occasionally be off by a point, if the rounding from scrambling/descrambling hits just right. But I think that’s going to be rare enough that it won’t go noticed for our purposes.
I think it would just be when the scrambled scores are equal. If the scrambled scores differ at all, that would mean that the actual scores are different, and therefore the winner can be determined.
Due to the rounding that occurs, I don't think that this would be very reliable. However, like you mentioned, if you have the caveat that scores may be off by a few points up or down, I think you can leave that feature in there.
That's great that you were already able to code it up! Let me know if you'd like me to test it as well.
Sure, you can get the code from the "scores" branch on GitHub.
Win/Loss determination doesn't require any calibration. To see descrambled scores, though, you just have to go to the initial setup page for a team and enter the last completed game's score.
I've been using the code from your "scores" branch for the past week or so. It's been working great to get win/loss events much quicker for the handful of teams I've been monitoring (and the result has been correct every time so far).
I have noticed that for most of the teams, the app is triggering the win/loss event at 12:01 am with the "scheduledUpdate" job. Any idea what might be causing that?
Do you mean in addition to the win/loss event shortly after the game ends?
EDIT: I found the issue if so. Updated the code to hopefully fix.
Sorry, should have been more clear in my original comment. Yes, this was in addition to the win/loss event after the game ends. And not only that, but it was also triggering days after the game completed. For example see my notifications from last night.
Thanks for finding the fix. I'll update now to see if that resolves the issue.
I'll update now to see if that resolves the issue.
I've been so busy lately that I haven't hardly been able to evaluate this. How's it working for you? Think it's ready for release? I was just going to add an option so that you could turn on or off display of the scores. Right now I have a way to re-calibrate but no way to turn it off once it's been turned on.
Since the update that you made last week, it has been working great for me! I would say you're okay to release.
v1.6.0
- Determines win-loss from scores for faster game result notifications
- Add option to display game score on tile
This update requires you to click 'Done' again. Sorry for the inconvenience.
Note: the feature to display the game score on a tile is a best effort feature. While it is often correct, it is subject to inaccuracy due to the API limitations. Try it and see if it works. But don't rely on it for anything important like sports betting!
v1.6.2
- Add ability to show game result with color of score instead of text
- suppress game result notification on app initialization
I'm getting some odd behaviors in Dashboards On Firefox the schedule displays with a vertical scroll bar no matter how high I set the tile height. On Chrome, I see the same behavior with the tile attribute. Also on Chrome the broadcast name doesn't appear.
When I run the app on an Android Tablet everything appears as it should





