Python script to be notified of channel lineup changes

Not sure how you're using SMS but I found I while back that SMS messages can be "emailed". Maybe it will help you.

#
# Common email addresses for texting.
#

# AT&T: [email protected] (SMS), [email protected] (MMS)
# Boost Mobile: [email protected] (SMS), [email protected] (MMS)
# C-Spire: [email protected]
# Consumer Cellular: [email protected]
# Cricket: [email protected] (SMS), [email protected] (MMS)
# Google Fi (Project Fi): [email protected] (SMS & MMS)
# H2O Wireless: [email protected] (SMS), [email protected] (MMS)
# Metro by T-Mobile: [email protected] (SMS & MMS)
# Mint Mobile: [email protected] (SMS)
# Page Plus: [email protected] (SMS), [email protected] (MMS)
# Red Pocket: Red Pocket uses AT&T or T-Mobile (for GSM SIMs) & Verizon for CDMA. See info. for those carriers.
# Republic Wireless: [email protected] (SMS)
# Simple Mobile: [email protected] (SMS)
# Sprint: [email protected] (SMS), [email protected] (MMS)
# T-Mobile: [email protected] (SMS & MMS)
# Ting: [email protected] (SMS for CDMA), [email protected] (SMS for GSM)
# Tracfone: [email protected] (MMS)
# Ultra Mobile: [email protected]
# U.S. Cellular: [email protected] (SMS), [email protected] (MMS)
# U.S. Mobile: [email protected] (SMS), [email protected] (MMS)
# Verizon: [email protected] (SMS), [email protected] (MMS)
# Virgin Mobile: [email protected] (SMS), [email protected] (MMS)
# Visible: [email protected] (SMS), [email protected] (MMS)
# Xfinity Mobile: [email protected] (SMS), [email protected] (MMS)

With this new version, your sources should be reflected accurately. Basically, whatever shows up in ip:port/devices. Even if there are duplicate channels at different numbers. I have not tested with an HDHR since I don't have one so it will be interesting to see what your experience is.

Thank you. Indeed, I use the email method to send a message to a cell phone as you mentioned.

The problem is somewhere in my Python code.
Do you have a piece of code in Python that does this, by chance? :slightly_smiling_face:

The Olivetin function called Create Channels List in CSV Format does this.

I was using it as part a bash script that called ssmtp.

echo -e $MESSAGE | sudo ssmtp -vvv $CONTACT

$CONTACT is the phone number I am sending to.

1 Like

Thanks, was aware of that :smile:

Which reminds me that I will have to tweak that script too. I will wait and see what feedback I get after I release this notification script first.

Good news: I got text notifications to work. :grinning:

I'm happy to release version 2.0.0 to GitHub with the following changes:
[IMPROVED] Save channel lineups to files
[IMPROVED] Add error handling for situations where the DVR isn't found
[FIXED] Need to handle the case when a source is added while the script is NOT running
[FIXED] Don't ignore duplicate channels
[NEW] Option '-l', '--log': Log channel changes to a file

@bnhf if you want to integrate it in OliveTin. :slight_smile:

I need to update the documentation now.

This can be done now with the '-l' option. The changes will be written to cdvr_channel_lineup_changes.txt.

Added in version 2.0.0. If it happens now, you will see something like this:

No response from the server at http://192.0.0.1:8089
If the URL is correct, the server is offline.

If an email address and/or a text number are provided, notifications will also be sent.

An email will look like this:
image

And a text message:

You will see this channel modification now.
Examples:

! 1006 : Swerve Sports -> Comedy Dynamics
! 1007 : Film Detective -> Docurama
! 1008 : The Archive -> Swerve Sports

It should work now. I just tested:

Pluto TV: 370 channels (=)

------ Lineup changes ------
- 10436 : Newsmax
+ 10068 : Newsmax2
------ Channel changes ------
- Newsmax (10436)
+ Newsmax2 (10068)
1 Like

If you wonder why I report lineup change and channel changes when they appear to be the same in a lot of cases, here are two perfect example with Pluto TV and STIRR today:

Pluto TV: 370 channels (-2)
------ Lineup changes ------
+ 10358 : KIRO Seattle
+ 10424 : CBS News Bay Area
- 10426 : CBS News Texas
- 10427 : WSB Atlanta
- 10428 : WSOC Charlotte
- 10429 : WFTV Orlando
------ Channel changes ------
+ KIRO Seattle (10358)
- WFTV Orlando (10429)
- WSB Atlanta (10427)
- WSOC Charlotte (10428)

You can see that CBS News Bay Area on channel number 10424 is not reported in the channel changes as a new channel. The reason being that it is a duplicate in the lineup, it already exists on channel number 10345:


Literally just now as I was typing this, I just had the idea to report duplicate channels in channel changes.

And even though CBS News Texas was removed on channel 10426, it was a duplicate channel and still exists in the lineup:

And now the example with STIRR: they added 2 channels and, in the process, also renumbered others:

STIRR: 31 channels (+2)
------ Lineup changes ------
! 1012 : NASATV (was: Horse Shopping Channel)
! 1013 : Horse Shopping Channel (was: So...Real)
! 1014 : So...Real (was: Electric Now)
! 1015 : Electric Now (was: Midnight Pulp)
! 1016 : Midnight Pulp (was: RetroCrush)
! 1017 : RetroCrush (was: LiveXLive)
! 1018 : LiveXLive (was: Revry)
! 1019 : Revry (was: Dove)
! 1020 : Dove (was: The Country Network)
! 1021 : The Country Network (was: Popstar! TV)
! 1022 : Popstar! TV (was: SOAR)
! 1023 : Ambiance (was: QVC)
! 1024 : SOAR (was: HSN)
! 1025 : QVC (was: ONTV4U)
! 1026 : HSN (was: Shop LC)
! 1027 : ONTV4U (was: The T)
! 1028 : Shop LC (was: PursuitUp)
+ 1029 : The T
+ 1030 : PursuitUp
------ Channel changes ------
+ Ambiance (1023)
+ NASATV (1012)

Just pushed version 2.2.0 to GitHub after quietly pushing version 2.1.0:

  • 2.1.0 :
    [CHANGED] Show lineup changes in order of channel numbers.
    [CHANGED] Show channel changes in order of channel names.

  • 2.2.0 :
    [IMPROVED] Added "Channels DVR lineup changes:" as first line in SMS message
    [NEW] Show duplicated channels in each modified source

1 Like

@mjitkop I'm planning to update OliveTin-for-Channels soon, which will include the latest version of this fabulous script! :slight_smile:

I was able to plug it in to my existing framework without issue so far, but I do have a question. On initial run, I received this output to the OliveTin log, along with a matching e-mail. However, I have not been able to locate the referenced files:

Using Channels DVR server at: http://media-server6:8089.
Checking for channel lineup changes every 30 minutes.

An email will be sent to [email protected] when changes are detected.

Last check    : 2024-02-05 16:27:22
Server version: 2024.01.08.1431

Channels DVR version: 2024.01.08.1431

New source with 160 channels: DIRECTV
See file DIRECTV.txt for the full lineup.

New source with 96 channels: CDVR - Minneapolis
See file CDVR - Minneapolis.txt for the full lineup.

New source with 20 channels: Fire TV - DTV
See file Fire TV - DTV.txt for the full lineup.

New source with 31 channels: Fire TV - Live TV
See file Fire TV - Live TV.txt for the full lineup.

New source with 370 channels: Pluto TV
See file Pluto TV.txt for the full lineup.

New source with 329 channels: Samsung TV Plus
See file Samsung TV Plus.txt for the full lineup.

New source with 44 channels: FrndlyTV
See file FrndlyTV.txt for the full lineup.

New source with 5 channels: FrndlyTV-noEPG
See file FrndlyTV-noEPG.txt for the full lineup.

New source with 31 channels: Stirr
See file Stirr.txt for the full lineup.

New source with 2 channels: Chrome Capture
See file Chrome Capture.txt for the full lineup.

New source with 7 channels: Virtual Channels
See file Virtual Channels.txt for the full lineup.

New source with 1 channels: VLC-Bridge - PBS
See file VLC-Bridge - PBS.txt for the full lineup.

Sending email to [email protected]...
Background Channel Lineup Change Notifications process running for media-server6:8089

Are those files only generated if the -l option is used? And, if -l is used, is there still output to the console?

1 Like

Glad that you will be updating with my latest script. :slightly_smiling_face:

No. They are always created. They are necessary since they are used as references.

They are (should be!) located in the same directory from where the script is called.

This is a good point, though. I realize now that I should display the full paths.

Watch for another version coming soon. :wink:

Yes.

Actually, the text that you pasted is what is shown on the console.
Well, for me, the text is shown in the terminal window when I run it on my Windows PC.

I must admit that I still have not installed OliveTin.
Sorry. :blush:
I went as far as installing Portainer but this is all new to me. Now I need to figure out how to use the docker compose files.
I have some work to do to educate myself. :grimacing:

That would work, however doing a "find" just now, they are located in "~", which in the case of a container running as root, is /root. It would be much better if they could be placed in ".", as that would place them in the directory that is mapped to the host.

One twist though, I've set this up to support multiple DVRs, just in case someone has different lineups in each. So, ideally if you could support a sub-directory flag, that would fit with my current structure (i.e. ./subdirectory). If not, I'd imagine I can figure something out.

I'd be happy to walk you through the process, either in a thread here that others might benefit from, or we could do it over on Discord -- for best speed of the back-and-forth.

That shouldn't be too hard. :slightly_smiling_face:

Not sure what you mean by "flag".

If I understand correctly, will it work if I save the files in ./ip_port?
Example: ./192_168_18_120_8089

Or what names should the sub-directories have?

I might take your offer but first let me see what I can do with all the information that you posted in the thread.
You put a lot of work into it so it's only fair that I put a minimum effort into it.
Other people have been able to do it so I should be able to. I just need to have a clear head and focus on the task. :wink:

Actually, there's no need to pass a new argument given you already have the values of -i and -p to work with. If you write the data files to host-port_data, that would fit perfectly with the scheme I'm already using. So examples would be ./192.168.18.120-8089_data or ./media-server6-8089_data -- how's that work for you?

1 Like

Sure, no problem.

I just need to make sure I capture the current directory.
I do my development on Windows but it should work the same with '.' hopefully.

I will let you know when I have something you can try. :slightly_smiling_face:

@bnhf I've started to make the code changes. I should be done before the weekend.

Here it is, @bnhf, the new and improved version 3.0.0:

[IMPROVED] Save reference files and the log file into a subdirectory that is named using the IP address and the port number of the server (better support for multiple servers)

[IMPROVED] When displaying duplicated channels, show the channel numbers without square brackets and without quotes (just the numbers)

[IMPROVED] Some cosmetic changes to increase readability in the detailed message

[NEW] Added the server URL as the first line of the detailed message (useful information when monitoring multiple servers)

[NEW] Added the source URL (used in the source settings) below the source name in the detailed message

[NEW] Added the starting channel number of the modified source when displaying the "Lineup changes" header

[NEW] Added the DVR URL on the second line of the SMS message (useful information when monitoring multiple servers)

I hope I got the directory structure right now so that it works in OliveTin. :crossed_fingers:
If not, there is something else I can try.

Thanks! I should be able to test this tomorrow, and if all seems good, I'll push an update to OliveTin.

2 Likes

Looks promising, but I did need to make one change to the code (and related comment) at lines 331 and 335:

def create_data_subdirectory(ip_address, port_number):
    '''
    Create a directory with the path as:
    current directory + "_<ip_address>-<port_number>_data" at the end
    '''
    global Data_Subdirectory_Path

    end_of_path = f'{ip_address}-{port_number}_data'
    data_subdirectory_path = os.path.join(os.getcwd(), end_of_path)

    if not os.path.exists(data_subdirectory_path):
        os.mkdir(data_subdirectory_path)
        
    Data_Subdirectory_Path = data_subdirectory_path

"_" changed to "-" between {ip_address} and {port_number}

On first run the data files ended up under /root again, but this time I cleverly :slight_smile: changed the directory to /config before running the script. Don't know why I didn't think of that before. It's good to have the data files in a subdirectory though.

1 Like