That is correct.
That sounds like a great idea. How would I go about creating my own XML guide data?
That is correct.
That sounds like a great idea. How would I go about creating my own XML guide data?
I don't have the experience creating XMLTV files but if I wanted to try, I would ask for help from an AI, such as chatGPT.
Here is an example created by chatGPT:
<?xml version="1.0" encoding="UTF-8"?>
<tv>
<channel id="channel1">
<display-name>Channel 1</display-name>
</channel>
<channel id="channel2">
<display-name>Channel 2</display-name>
</channel>
<programme start="20240917180000 +0000" stop="20240917190000 +0000" channel="channel1">
<title>News</title>
<desc>Evening news program</desc>
</programme>
<programme start="20240917190000 +0000" stop="20240917200000 +0000" channel="channel2">
<title>Movie</title>
<desc>Action movie</desc>
</programme>
</tv>
I'm guessing you probably need the channel IDs in there so that Channels DVR can match them with the channels that it knows about.
What @mjitkop posted above looks reasonable as a starting point, and although you could use a regular editor or spreadsheet to manage it, something along these lines would probably be easiest:
Also, for the complete format that definitely works in Channels, open one XMLTV file used in one custom channel source, if you have one.
@bnhf @mjitkop thank y’all! I just asked ChatGPT to and it created it. I didn’t realize AI was this useful to understanding how all of this works.
I'm having trouble installing SLM via olivetin. My configuration is I have Channels running on a Synology NAS. Channels is installed from Package Manager (not in a docker container). I have Tailscale installed on the NAS with MagicDNS running a "cjynas" maps to the IP of the NAS (192.189.0.11).
If I shell into the NAS, here is where my Channels installed:
If I run Olivetin and attempt an install of SLM, I fill out the form like this:
When it runs it gets an error that it cannot resolve the host "cjynas". Here is standard error output:
exit status 1
++ basename /config/slm.sh
+ extension=slm.sh
+ extension=slm
+ cp /config/slm.env /tmp
+ envFile=/tmp/slm.env
+ envVars=("TAG=$1" "SLM_PORT=$2" "TIMEZONE=$3" "CHANNELS_FOLDER=$4")
+ printf '%s\n' TAG=latest SLM_PORT=5000 TIMEZONE=US/Pacific CHANNELS_FOLDER=/volume1/ChannelsDVR
+ sed -i /=#/d /tmp/slm.env
+ /config/portainerstack.sh slm
+ stackName=slm
+ portainerHost=cjynas
+ curl -s -o /dev/null http://cjynas:9000
+ portainerURL='https://cjynas:9443/api/stacks?type=2&method=string&endpointId=2'
+ portainerToken=ptr_mCoUK4hpSQnjOh42V0qeZsrfdOX0hmPEV0HkVoQ/LnY=
+ cp /config/slm.yaml /tmp
+ stackFile=/tmp/slm.yaml
+ envFile=/tmp/slm.env
++ grep DVR_SHARE= /tmp/slm.env
++ grep -v /
++ awk -F= '{print $2}'
+ dockerVolume=
++ grep VOL_EXTERNAL= /tmp/slm.env
++ grep -v '#'
++ awk -F= '{print $2}'
+ volumeExternal=
++ grep VOL_NAME= /tmp/slm.env
++ grep -v '#'
++ awk -F= '{print $2}'
+ volumeName=
++ grep NETWORK_MODE= /tmp/slm.env
++ grep -v '#'
++ awk -F= '{print $2}'
+ networkMode=
++ grep DEVICES= /tmp/slm.env
++ grep -v '#'
++ awk -F= '{print $2}'
+ transcoderDevice=
++ grep CDVR_CONTAINER= /tmp/slm.env
++ grep -v '#'
++ awk -F= '{print $2}'
+ stackNumber=
+ [[ -n '' ]]
+ [[ -n '' ]]
+ [[ -n '' ]]
+ [[ -n '' ]]
++ sed 's/\\/\\\\/g' /tmp/slm.yaml
++ sed 's/"/\\"/g'
++ awk '{printf "%s\\n", $0}'
+ stackContent='version: '\''3.9'\''\nservices:\n # 2024.09.12\n # GitHub home for this project with setup instructions: https://github.com/babsonnexus/stream-link-manager-for-channels\n # Docker container home for this project: https://ghcr.io/babsonnexus/stream-link-manager-for-channels\n slm:\n image: ghcr.io/babsonnexus/stream-link-manager-for-channels:${TAG:-latest}\n container_name: slm\n ports:\n - ${SLM_PORT:-5000}:5000\n environment:\n - TZ=${TIMEZONE:-UTC}\n volumes:\n - slm_files:/app/program_files\n - ${CHANNELS_FOLDER}:/app/channels_folder\n restart: unless-stopped\nvolumes:\n slm_files:\n\n# Default Environment variables can be found below under stderr -- copy and paste into Portainer-Stacks Environment variables section in Advanced mode\n'
+ stackEnvVars='['
+ IFS==
+ read -r key value
+ stackEnvVars='[{"name": "TAG", "value": "latest"},'
+ IFS==
+ read -r key value
+ stackEnvVars='[{"name": "TAG", "value": "latest"},{"name": "SLM_PORT", "value": "5000"},'
+ IFS==
+ read -r key value
+ stackEnvVars='[{"name": "TAG", "value": "latest"},{"name": "SLM_PORT", "value": "5000"},{"name": "TIMEZONE", "value": "US/Pacific"},'
+ IFS==
+ read -r key value
+ stackEnvVars='[{"name": "TAG", "value": "latest"},{"name": "SLM_PORT", "value": "5000"},{"name": "TIMEZONE", "value": "US/Pacific"},{"name": "CHANNELS_FOLDER", "value": "/volume1/ChannelsDVR"},'
+ IFS==
+ read -r key value
+ stackEnvVars='[{"name": "TAG", "value": "latest"},{"name": "SLM_PORT", "value": "5000"},{"name": "TIMEZONE", "value": "US/Pacific"},{"name": "CHANNELS_FOLDER", "value": "/volume1/ChannelsDVR"}]'
++ cat
+ stackJSON='{
"Name": "slm",
"SwarmID": "",
"StackFileContent": "version: '\''3.9'\''\nservices:\n # 2024.09.12\n # GitHub home for this project with setup instructions: https://github.com/babsonnexus/stream-link-manager-for-channels\n # Docker container home for this project: https://ghcr.io/babsonnexus/stream-link-manager-for-channels\n slm:\n image: ghcr.io/babsonnexus/stream-link-manager-for-channels:${TAG:-latest}\n container_name: slm\n ports:\n - ${SLM_PORT:-5000}:5000\n environment:\n - TZ=${TIMEZONE:-UTC}\n volumes:\n - slm_files:/app/program_files\n - ${CHANNELS_FOLDER}:/app/channels_folder\n restart: unless-stopped\nvolumes:\n slm_files:\n\n# Default Environment variables can be found below under stderr -- copy and paste into Portainer-Stacks Environment variables section in Advanced mode\n",
"Env": [{"name": "TAG", "value": "latest"},{"name": "SLM_PORT", "value": "5000"},{"name": "TIMEZONE", "value": "US/Pacific"},{"name": "CHANNELS_FOLDER", "value": "/volume1/ChannelsDVR"}]
}'
+ echo 'JSON response from https://cjynas:9443/api/stacks?type=2&method=string&endpointId=2:'
++ curl -k -X POST -H 'Content-Type: application/json' -H 'X-API-Key: ptr_mCoUK4hpSQnjOh42V0qeZsrfdOX0hmPEV0HkVoQ/LnY=' -d '{
"Name": "slm",
"SwarmID": "",
"StackFileContent": "version: '\''3.9'\''\nservices:\n # 2024.09.12\n # GitHub home for this project with setup instructions: https://github.com/babsonnexus/stream-link-manager-for-channels\n # Docker container home for this project: https://ghcr.io/babsonnexus/stream-link-manager-for-channels\n slm:\n image: ghcr.io/babsonnexus/stream-link-manager-for-channels:${TAG:-latest}\n container_name: slm\n ports:\n - ${SLM_PORT:-5000}:5000\n environment:\n - TZ=${TIMEZONE:-UTC}\n volumes:\n - slm_files:/app/program_files\n - ${CHANNELS_FOLDER}:/app/channels_folder\n restart: unless-stopped\nvolumes:\n slm_files:\n\n# Default Environment variables can be found below under stderr -- copy and paste into Portainer-Stacks Environment variables section in Advanced mode\n",
"Env": [{"name": "TAG", "value": "latest"},{"name": "SLM_PORT", "value": "5000"},{"name": "TIMEZONE", "value": "US/Pacific"},{"name": "CHANNELS_FOLDER", "value": "/volume1/ChannelsDVR"}]
}' 'https://cjynas:9443/api/stacks?type=2&method=string&endpointId=2'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: cjynas
+ portainerResponse=
+ [[ -z '' ]]
+ exit 1
+ [[ 1 == 1 ]]
+ exit 1
Any ideas what to check?
I believe what you're seeing is unrelated to slm, so we should probably move this discussion. Could you run the OliveTin Post-Install Healthcheck, and post the results in the OliveTin thread?
Thanks. Here it is.
Checking your OliveTin installation...
(extended_check=false)
----------------------------------------
Checking that your selected Channels DVR server (192.168.0.11:8089) is reachable by URL:
HTTP Status: 200 indicates success...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 1276 100 1276 0 0 1246k 0 --:--:-- --:--:-- --:--:-- 1246k
HTTP Status: 200
Effective URL: http://192.168.0.11:8089/
----------------------------------------
Checking that your selected Channels DVR server's data files (/mnt/192.168.0.11-8089) are accessible:
Folders with the names Database, Images, Imports, Logs, Movies, Streaming and TV should be visible...
total 20
drwxrwxrwx 1 root root 22 May 29 06:00 #recycle
drwx------ 1 242120 root 170 Sep 20 16:50 .
drwxr-xr-x 1 root root 78 Sep 19 14:54 ..
-rwxrwx--- 1 1026 users 18436 Jul 24 06:25 .DS_Store
drwxrwxrwx 1 root root 334 Apr 24 10:09 @eaDir
drwxrwx--- 1 1026 users 1350 Sep 19 19:51 Database
drwxrwx--- 1 1026 users 230598 Sep 20 18:30 Images
drwxrwx--- 1 1026 users 58 Mar 18 2022 Imports
drwxrwx--- 1 1026 users 62 Feb 1 2021 Logs
drwxrwx--- 1 1026 users 25932 Sep 20 16:50 Movies
drwxrwx--- 1 1026 users 10162 Sep 20 18:30 Streaming
drwxrwx--- 1 1026 users 8232 Sep 20 16:50 TV
drwxrwx--- 1 1026 users 50 Jan 16 2023 strmlnkTemplates
drwxrwx--- 1 1026 users 0 Jan 21 2024 temp
----------------------------------------
Checking that your selected Channels DVR server's log files (/mnt/192.168.0.11-8089_logs) are accessible:
Folders with the names data and latest should be visible...
total 4
drwxr-xr-x 1 242120 242120 200 Sep 16 19:50 .
drwxr-xr-x 1 root root 78 Sep 19 14:54 ..
drwxr-xr-x 1 242120 242120 154 Sep 4 19:28 2024.09.05.0212
drwxr-xr-x 1 242120 242120 134 Sep 10 15:31 2024.09.10.2115
drwxr-xr-x 1 242120 242120 154 Sep 11 15:32 2024.09.11.1846
drwxr-xr-x 1 242120 242120 154 Sep 12 10:02 2024.09.12.1557
drwxr-xr-x 1 242120 242120 154 Sep 13 09:32 2024.09.13.1554
drwxr-xr-x 1 242120 242120 154 Sep 16 19:50 2024.09.17.0218
drwxr-xr-x 1 242120 242120 4506 Sep 20 18:22 data
lrwxrwxrwx 1 242120 242120 15 Sep 16 19:50 latest -> 2024.09.17.0218
----------------------------------------
Here's a list of your current OliveTin-related settings:
HOSTNAME=olivetin
CHANNELS_DVR=192.168.0.11:8089
CHANNELS_DVR_ALTERNATES=
CHANNELS_CLIENTS=apple-tv
ALERT_SMTP_SERVER=smtp.gmail.com:587
ALERT_EMAIL_FROM=[Redacted]@gmail.com
ALERT_EMAIL_PASS=[Redacted]
ALERT_EMAIL_TO=[Redacted]@gmail.com
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
PORTAINER_TOKEN=[Redacted]
PORTAINER_HOST=cjynas
----------------------------------------
Here's the contents of /etc/resolv.conf from inside the container:
search tail[Redacted].ts.net
nameserver 127.0.0.11
options ndots:0
----------------------------------------
Here's the contents of /etc/hosts from inside the container:
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.31.0.3 olivetin
OK, a couple of ideas:
First in your OliveTin DOMAIN
env var, I'd try adding your local search domain (mine is localdomain
), in addition to your tailnet domain. These should be space separated, and in the order you'd like them searched. Something like this:
DOMAIN=localdomain tailxxxxx.ts.net
For this to be effective, cjynas
needs to resolve locally (cjynas.localdomain
), as well as via MagicDNS on your tailnet.
Second, if you don't want to mess with why local DNS resolution isn't working properly, you could simply use 192.168.0.11
as your PORTAINER_HOST value rather than the MagicDNS name.
If you're looking for a quick resolution, this is probably the way to go. Otherwise, as you know , I'll hang in there with you to get to the bottom of LAN DNS resolution issues, but that's probably not the easy, expedient path.
I got it working with changing PORTAINER_HOST to 192.168.0.11 instead of the magicDNS name of cjynas. But prior to this I tried the following which both failed to resolve cjynas:
So this this is the third thing I tried that works:
DOMAIN=localhost tailxxxxx.ts.net
PORTAINER_HOST=192.168.0.11
SLM is running with this config but if you would like to find out why cjynas was not resolving, I'm game to troubleshoot.
Edited: To note that I have not starting using SLM so I'm not sure if I have everything working properly. I'm still plugging through the SLM installation video but will try to finish viewing the install video tomorrow morning.
Is it possible to add an OLIVETIN alert to see if the ChannelsDVR service/app is running if not to send an alert ?
That's actually what the "Ping Channels DVR Server" Action does. It does a curl
of the Channels DVR URL, and then confirms success via healthchecks.io. If that confirmation is missed, then healthchecks.io will inform you by e-mail or other notifications platform (they support many).
I use it for both of my CDVR servers, one local and one remote. It's worked really well for me, by way of letting me know there's some sort of issue, often long before I would find out otherwise, through missed recordings and the like:
I tried with a fake IP did not get an alert .... my server is at 192.168.50.162 oops maybe I have to wait 30 m
Background script initiated, with 30 between runs for 192.168.50.163:8089
foreground.sh is exiting for pingcdvr with exit code 0
Tue Sep 24 07:41:43 PDT 2024
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:03 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:04 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:05 --:--:-- 0
curl: (28) Connection timed out after 5001 milliseconds
HTTP Status: 000
Effective URL: http://192.168.50.163:8089/
What does it show on the healthchecks.io website under "Last Ping" for the ping URL you set up? The frequency you set in the OliveTin Action should match the frequency you set on the healthchecks.io site (there's also a grace period in healthchecks.io, which I usually set to 5 minutes).
I have the default never changed that ?
[type or paste code here](https://hc-ping.com/your_custom_uuid)
That's just an example of the format, and is the equivalent of "none".
You need to go to the healthchecks.io website, and set up a free account. Then for each "ping" you want to monitor, you set up a "check" with a unique name. If healthchecks.io fails to hear from OliveTin in the prescribed time period it'll send you an e-mail or other notification.
The same process is used in several OliveTin Actions as a way to notify you if they're no longer running. One of the nice things about this approach is that you know something's amiss even if OliveTin itself, or the host it runs on, is down.
@bnhf is it currently possible to setup multiple email log alerts at the same time? I have multiple servers and they all show in the drop-down but it seems I can only choose one of them.
You can set up as many as you like using your defined servers (one set of alerts per server) -- but they are done one at a time. Each creates its own background process. To kill any, or all of them, reverse the process by selecting each server and entering 0 for the interval.
Due to a bug in the current version of the base OliveTin project, you'll want to refresh your browser tab between establishing (or killing) each log alert. Hopefully, next time I upgrade the underlying version of OliveTin, this will be addressed.
@bnhf Do I have to use Portainer, as I have an Unraid server and can use the Compose file in there. If so, how would the compose file and Env file look not using portainer? Right now I tried it and I'm getting a websocket error. Any ideas??
Yes. This project is supported only via Portainer. Project One-Click, in particular, uses the Portainer API for deployments.