Локальная TV-программа через CCcam/OScam: настройка EPG

Каналы открываются, картинка есть, но вместо программы передач — пустота или чужой регион. Это классическая ситуация после настройки CCcam/OScam: local tv guide не работает, хотя всё остальное в порядке. Причина банальная — дескремблирование и EPG технически не связаны вообще. Разберём по шагам как это починить.

Что такое локальный EPG и почему он не работает из коробки

EPG (Electronic Program Guide) — это расписание передач, которое ресивер отображает в InfoBar и планировщике записей. Данные для него могут приходить двумя принципиально разными способами, и путаница между ними — корень большинства проблем.

Разница между DVB EPG (из потока) и XMLTV EPG (внешний источник)

DVB EIT (Event Information Table) передаётся прямо в транспондере на PID 0x12. Ресивер читает эти таблицы параллельно с декодированием видео — никакого дополнительного ПО не нужно. Это работает на открытых и незашифрованных пакетах или когда провайдер передаёт EIT незашифрованным даже в scrambled-потоке.

XMLTV — это XML-файл с расписанием, который тянется с внешнего сервера по HTTP и парсится плагином на ресивере. Формат стандартизирован, файлы могут весить от нескольких мегабайт до десятков мегабайт для большого пакета каналов. Плагин EPGImport на Enigma2 работает именно с этим форматом.

Почему CCcam/OScam не передают EPG — только дескремблируют поток

CCcam и OScam работают на уровне условного доступа: они принимают ECM-запросы от ресивера, запрашивают Control Word у карты или сервера, и возвращают его обратно. Всё. Они понятия не имеют что за видео дескремблируется — HD-канал, SD или EIT-таблица с EPG.

Проблема в том, что некоторые провайдеры шифруют EIT-таблицы тем же CAID, что и видео. CCcam дескремблирует видео нормально, но EPG-таблицы в транспондере остаются зашифрованными и ресивер их не парсит. Итог: каналы идут, EPG пуст.

Когда провайдер вырезает EPG из транспондера

Это отдельный сценарий — провайдер просто не передаёт EIT в потоке. Такое делается намеренно: либо чтобы заставить использовать собственное приложение с EPG, либо просто экономия полосы транспондера. В этом случае ни CCcam, ни OScam, ни какие-либо другие плагины EIT из потока не достанут — его там нет физически.

Часовые пояса и сдвиг расписания на несколько часов

DVB EIT передаёт время в UTC. Ресивер конвертирует его в локальное время согласно настройкам часового пояса. Если ресивер выставлен в UTC, а канал московский (+0300) — всё расписание будет сдвинуто на три часа. Проверяй: Menu → Setup → Expert Setup → Time settings → Timezone.

Источники XMLTV для локальной TV-программы

Local tv guide через XMLTV — это рабочий способ получить нормальное расписание даже когда провайдер не отдаёт EIT. Но не любой XMLTV-фид подойдёт, и выбирать его нужно осознанно.

Бесплатные открытые XMLTV-фиды (общие критерии выбора)

На что смотреть при выборе фида: частота обновления (нормальный фид обновляется раз в 6-12 часов, не раз в неделю), глубина расписания (минимум 3-7 дней вперёд, лучше 14), наличие описаний передач и категорий, поддержка иконок каналов через тег icon src=.

Для русскоязычных каналов особенно важна кодировка. Фид должен быть строго UTF-8 — если в XML-декларации написано encoding="windows-1251", готовься к кракозябрам на ресивере. Ещё момент: проверяй что в фиде есть именно твои каналы, а не только федеральный пакет без региональных вставок.

Формат файла: tag channel, programme, start/stop, timezone

Валидный XMLTV выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tv SYSTEM "xmltv.dtd">
<tv generator-info-name="my-grabber">
  <channel id="perviy.ru">
    <display-name lang="ru">Первый канал</display-name>
    <icon src="https://example.com/icons/perviy.png"/>
  </channel>
  <programme start="20260523180000 +0300" stop="20260523190000 +0300" channel="perviy.ru">
    <title lang="ru">Вечерние новости</title>
    <desc lang="ru">Главные события дня</desc>
    <category lang="ru">Новости</category>
  </programme>
</tv>

Критичные атрибуты: start и stop в формате YYYYMMDDHHmmss TIMEZONE. Timezone должна быть явной: +0300, +0000, но не просто Z или пустой. Отсутствие timezone — источник половины проблем со сдвигом расписания.

Как проверить корректность XMLTV через xmllint

Перед тем как заливать файл на ресивер — проверяй на компьютере:

xmllint --noout epg.xml
# Если есть ошибки — выдаст строку и описание

# Считаем количество программ:
grep -c '<programme ' epg.xml

# Проверяем кодировку:
file -i epg.xml
# Должно быть: application/xml; charset=utf-8

Если grep -c programme выдаёт 0 или несколько штук при большом файле — XML сломан, парсер ресивера молча проигнорирует всё содержимое.

Кодировка UTF-8 и проблемы с кириллицей в названиях передач

Если получил файл в windows-1251 — конвертируй перед использованием:

iconv -f cp1251 -t utf-8 epg_win.xml -o epg_utf8.xml

После конвертации обязательно проверить что XML-декларация тоже поменяна: <?xml version="1.0" encoding="UTF-8"?>. Иначе парсер будет ругаться на несоответствие.

Настройка EPGImport на Enigma2 (OpenATV, OpenPLi)

EPGImport — стандартный плагин для Enigma2, работает на OpenATV, OpenPLi, OpenVision и большинстве других прошивок. На DreamOS (Dreambox) устанавливается через ipk-пакет, не через opkg, и пути к конфигам совпадают: /etc/epgimport/.

Установка плагина: opkg install enigma2-plugin-extensions-epgimport

# Через SSH на ресивер:
opkg update
opkg install enigma2-plugin-extensions-epgimport

# На DreamOS через ipk:
dpkg -i enigma2-plugin-extensions-epgimport_*.ipk

После установки плагин появляется в меню: Plugins → EPGImport. При первом запуске создаёт каталог /etc/epgimport/ если его нет.

Структура каталогов: /etc/epgimport/ и формат .channels.xml и .sources.xml

/etc/epgimport/
├── sources.xml          # или custom.sources.xml
├── myepg.channels.xml   # маппинг channel id → ServiceRef
└── sources/             # поддиректория для дополнительных источников

Важно: EPGImport читает все файлы *.sources.xml и *.channels.xml из /etc/epgimport/ автоматически. Не надо трогать системные файлы плагина — создавай свои с префиксом custom. или любым другим именем.

Создание собственного источника: source description, url, channels href

Файл /etc/epgimport/custom.sources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<sources>
  <sourcecat sourcecatname="Мои каналы">
    <source type="gen_xmltv" nocheck="1">
      <description>Российские каналы EPG</description>
      <url>http://192.168.1.100/epg/russia.xml</url>
      <channels>/etc/epgimport/russia.channels.xml</channels>
    </source>
  </sourcecat>
</sources>

Атрибут nocheck="1" отключает проверку доступности URL при старте — полезно если сервер не всегда онлайн. Можно указывать как локальный файл (file:///tmp/epg.xml), так и HTTP-URL.

Маппинг ServiceRef к channel id из XMLTV

Файл /etc/epgimport/russia.channels.xml:

<?xml version="1.0" encoding="UTF-8"?>
<channels>
  <channel id="perviy.ru">1:0:19:283D:3FB:1:C00000:0:0:0:</channel>
  <channel id="russia1.ru">1:0:19:3F84:3FB:1:C00000:0:0:0:</channel>
  <channel id="ntv.ru">1:0:19:3F85:3FB:1:C00000:0:0:0:</channel>
</channels>

Здесь id должен точно совпасть с id тега channel в XMLTV-файле. ServiceRef — строка из lamedb ресивера. Несовпадение этих двух значений — причина 90% случаев когда "импорт прошёл, но EPG пуст".

Автообновление по cron: /etc/cron.daily или через настройки плагина

Через плагин: EPGImport → Settings → Schedule import → Daily, время 04:00 (когда нагрузка минимальна).

Через cron — создать файл /etc/cron.daily/epgimport:

#!/bin/sh
/usr/lib/enigma2/python/Plugins/Extensions/EPGImport/epgimport.sh
chmod +x /etc/cron.daily/epgimport

Путь к базе EPG: /etc/enigma2/epg.dat и принудительная перезагрузка

Enigma2 хранит кешированный EPG в /etc/enigma2/epg.dat. После импорта данные сохраняются туда и переживают перезагрузку — если путь задан правильно. Параметр в /etc/enigma2/settings:

config.misc.epgcache_filename=/etc/enigma2/epg.dat

Принудительный сброс кеша через telnet на ресивер (порт 23):

telnet 192.168.1.x 23
# В консоли enigma2:
e2_clearepgcache

Настройка EPG для OScam через oscam.services и dvbapi

OScam EPG не отдаёт и не собирает — это не его задача. Но в правильной связке с Tvheadend OScam дескремблирует поток через DVBAPI, а Tvheadend самостоятельно тянет XMLTV и раздаёт EPG клиентам по HTSP. Получается что местная local tv guide раздаётся централизованно одним сервером.

Файл oscam.services: привязка caid/provid к именам сервисов

Файл /etc/oscam/oscam.services используется для ограничения доступа к сервисам, не для EPG. Но для диагностики полезно знать его формат:

[RussianChannels]
caid = 0500
provid = 032000
srvid = 283D,3F84,3F85,3F86

[SportPackage]
caid = 0500
provid = 041500
srvid = 1001,1002,1003

srvid — это SSID каналов в hex. Совпадает с частью ServiceRef: в строке 1:0:19:283D:3FB:1:C00000:0:0:0: значение 283D — это и есть srvid.

DVBAPI-протокол и сокет /tmp/camd.socket

OScam общается с Enigma2 или Tvheadend через DVBAPI-протокол. Настройка в /etc/oscam/oscam.dvbapi:

[dvbapi]
enabled = 1
user = dvbapi
au = 1
boxtype = dreambox
pmt_mode = 0
request_mode = 0
listen_port = 0
extended_cw_api = 0

Сокет создаётся автоматически: /tmp/camd.socket. Tvheadend подключается к нему для дескремблирования. Если сокет не появился — OScam не запущен или dvbapi не включён.

Как OScam логирует EPG-запросы при DEBUG=4

OScam не логирует EPG-запросы как таковые — он их не обрабатывает. Но при уровне DEBUG=4 в /etc/oscam/oscam.conf можно увидеть все ECM-запросы и понять какие srvid обращаются к серверу:

[global]
logfile = /tmp/oscam.log
debuglevel = 4
tail -f /tmp/oscam.log | grep "srvid\|ECM"

Связка OScam + Tvheadend для серверной раздачи EPG

Tvheadend при этой схеме делает всё: дескремблирует через OScam (DVBAPI), собирает EPG через XMLTV-grabber, и раздаёт HTSP-поток с EPG клиентам (Kodi, второй ресивер, мобильное приложение). Конфигурация grabber находится в:

/home/hts/.hts/tvheadend/epggrab/xmltv/

В web-интерфейсе Tvheadend (порт 9981): Configuration → Channel/EPG → EPG Grabber Modules → External XMLTV. Указываешь путь к скрипту-грабберу или URL. Tvheadend сам запускает grabber по расписанию и маппит channel id на каналы.

Маппинг каналов: связать XMLTV id с ServiceRef ресивера

Это самый больной момент. XMLTV знает каналы по своим id (perviy.ru, channel.1). Enigma2 знает их по ServiceRef. Если маппинг неправильный — EPG импортируется но нигде не отображается.

Где взять ServiceRef: lamedb на ресивере /etc/enigma2/lamedb

Файл /etc/enigma2/lamedb — это база каналов ресивера. Альтернативный способ — web-интерфейс на порту 80: открыть любой канал через браузер, ServiceRef будет в URL вида:

http://192.168.1.x/web/stream.m3u?ref=1:0:19:283D:3FB:1:C00000:0:0:0:

Из lamedb строка канала выглядит так:

s 283D:3FB:1:C00000:0:0:0:  ← hex: ssid:tsid:onid:namespace
p Первый канал

Собираем ServiceRef: 1:0:19:283D:3FB:1:C00000:0:0:0: где 19 = тип сервиса (SD video), 283D = ssid, 3FB = tsid, 1 = onid, C00000 = namespace.

Скрипт автоматического маппинга по имени канала

#!/usr/bin/env python3
import re, xml.etree.ElementTree as ET

def parse_lamedb(path='/etc/enigma2/lamedb'):
    channels = {}
    with open(path, encoding='utf-8', errors='ignore') as f:
        lines = f.readlines()
    i = 0
    while i < len(lines):
        if lines[i].startswith('s '):
            ref_parts = lines[i][2:].strip().split(':')
            if i+1 < len(lines) and lines[i+1].startswith('p '):
                name = lines[i+1][2:].strip().lower()
                ssid, tsid, onid, ns = ref_parts[0], ref_parts[1], ref_parts[2], ref_parts[3]
                sref = f"1:0:19:{ssid}:{tsid}:{onid}:{ns}:0:0:0:"
                channels[name] = sref
        i += 1
    return channels

def build_channels_xml(xmltv_path, lamedb_path, out_path):
    tree = ET.parse(xmltv_path)
    lame = parse_lamedb(lamedb_path)
    root = ET.Element('channels')
    for ch in tree.getroot().findall('channel'):
        cid = ch.get('id')
        names = [d.text.lower() for d in ch.findall('display-name') if d.text]
        for name in names:
            if name in lame:
                ET.SubElement(root, 'channel', id=cid).text = lame[name]
                break
    ET.ElementTree(root).write(out_path, encoding='UTF-8', xml_declaration=True)

build_channels_xml('/tmp/epg.xml', '/etc/enigma2/lamedb', '/etc/epgimport/auto.channels.xml')
print("Done")

Что делать если имена в XMLTV и lamedb различаются (Первый HD vs Первый канал HD)

Скрипт выше делает точное совпадение по строке. Если имена не совпадают — надо вести CSV с ручным маппингом:

# mapping.csv
xmltv_id,service_ref
perviy.ru,1:0:19:283D:3FB:1:C00000:0:0:0:
perviy-hd.ru,1:0:1:1234:5678:1:C00000:0:0:0:
russia1.ru,1:0:19:3F84:3FB:1:C00000:0:0:0:

Тогда скрипт сначала смотрит в CSV, и только если там нет — пытается найти по имени. Это надёжнее fuzzy-матчинга.

Хранение маппинга в rytec.channels.xml формате

Rytec — популярный источник XMLTV для европейских каналов. Их channels.xml формат совместим с EPGImport напрямую. Если используешь rytec-фид — скачивай готовый rytec.channels.xml и дополняй его своими каналами вручную.

Troubleshooting: EPG пустой, отстаёт или показывает не то

Диагностика EPG — это последовательное сужение проблемы. Сначала проверяем что файл валидный, потом что он правильно доехал, потом что маппинг совпадает.

EPG.dat не сохраняется после перезагрузки (config.misc.epgcache_filename)

Проверь значение параметра:

grep epgcache /etc/enigma2/settings

Должно быть: config.misc.epgcache_filename=/etc/enigma2/epg.dat. Если параметра нет или путь указывает на /tmp/ — EPG будет теряться при каждой перезагрузке, потому что /tmp/ на Enigma2 в RAM. Исправить через меню или прямо в файле settings.

Время в передачах сдвинуто на 2-3 часа — проблема с timezone в XMLTV

Два сценария. Первый: фид отдаёт UTC (+0000), ресивер в +0300 — передачи сдвинуты на 3 часа вперёд в расписании. Второй (хуже): фид отдаёт время без timezone вообще, и ресивер интерпретирует его как локальное. Решение одно — найти фид с явным timezone-атрибутом, или конвертировать через скрипт перед импортом.

Импорт прошёл но в InfoBar пусто — несовпадение ServiceRef

Это самый частый случай. Алгоритм проверки:

# 1. Смотрим что импортировалось в epg.dat (через enigma2 debug):
tail -f /tmp/epgimport.log

# 2. Проверяем ServiceRef конкретного канала через web:
# http://192.168.1.x/web/epgservice?sRef=1:0:19:283D:3FB:1:C00000:0:0:0:
# Если EPG есть — ServiceRef правильный, проблема в маппинге
# Если пусто — ServiceRef не совпадает с channels.xml

Кракозябры вместо кириллицы — XMLTV в windows-1251 вместо UTF-8

file -i /tmp/epg.xml
# Если charset=iso-8859-1 или charset=windows-1251:
iconv -f cp1251 -t utf-8 /tmp/epg.xml -o /tmp/epg_utf8.xml
# Потом заменить в XML-декларации encoding="windows-1251" на encoding="UTF-8"
sed -i 's/encoding="windows-1251"/encoding="UTF-8"/i' /tmp/epg_utf8.xml

EPG обновляется но через час пропадает — мало места в /etc/enigma2/

Проверяем:

df -h /etc/enigma2/
ls -lh /etc/enigma2/epg.dat

Полный EPG для 200+ каналов на 7 дней — это 15-50 МБ. Если раздел переполнен — enigma2 не может записать epg.dat и тихо теряет данные при следующей перезагрузке. Или переносить epg.dat на USB: config.misc.epgcache_filename=/media/usb/epg.dat.

Логи: tail -f /tmp/epgimport.log и /var/volatile/log/messages

tail -f /tmp/epgimport.log
# Смотрим строки вида:
# INFO: Fetching http://...
# ERROR: Channel not found: perviy.ru
# INFO: Imported 4521 events for 87 channels

tail -f /var/volatile/log/messages | grep -i epg

Строка "Channel not found" — прямой индикатор что channel id из XMLTV не совпадает ни с одним из channels.xml. Именно здесь смотреть при пустом EPG после "успешного" импорта.

Альтернативы: OpenTV EPG, MHW, EIT через сторонний транспондер

XMLTV — не единственный вариант. Существуют плагины которые собирают EPG прямо из спутникового потока, без внешних серверов.

OpenTV EPG: где встречается и как настроить сбор

OpenTV — проприетарный формат EPG, который исторически использовали британские (Sky), французские (Canal+) и ряд других платформ. Enigma2 поддерживает его через CrossEPG. Но в 2026 году большинство операторов которые раньше транслировали OpenTV EPG перешли на собственные форматы или убрали EPG из потока совсем. Проверить наличие OpenTV на конкретном транспондере можно только сканированием через CrossEPG с включённым логированием.

MHW2 EPG на спутниковых пакетах — плагин CrossEPG

CrossEPG — плагин для Enigma2 который умеет собирать EPG из потока в форматах OpenTV, MHW, MHW2, Sky и конвертировать в формат Enigma2. Устанавливается через opkg:

opkg install enigma2-plugin-extensions-crossepg

MHW2 встречается на ряде спутниковых пакетов — CrossEPG его подхватывает автоматически при сканировании. Глубина EPG при этом зависит от самого провайдера: обычно 2-5 дней, редко больше.

EIT с соседнего спутника как источник для своих каналов

Интересный хак: некоторые провайдеры транслируют незашифрованный EIT для своих каналов на другом транспондере или спутнике. Настраиваешь ресивер на сбор EIT с этого транспондера через CrossEPG или стандартный EIT-сборщик Enigma2 — и получаешь EPG для каналов с основного пакета. Работает не всегда и требует экспериментов с конкретными транспондерами.

Раздача EPG по сети на несколько ресиверов через Tvheadend HTSP

Это правильная архитектура для дома с несколькими ресиверами. Один хост (может быть Raspberry Pi или старый ноутбук) запускает Tvheadend, тянет XMLTV-фид, маппит каналы, хранит EPG. Остальные ресиверы и Kodi подключаются по HTSP (порт 9982) и получают EPG готовым — без собственных плагинов и фидов.

Это также снижает нагрузку: вместо 3 ресиверов которые каждые 6 часов качают 30 МБ XMLTV — один сервер качает один раз и раздаёт внутри сети. При этом local tv guide обновляется централизованно и всегда актуальна на всех устройствах.

Почему после установки CCcam/OScam пропала программа передач?

CCcam и OScam не управляют EPG — они только дескремблируют видеопоток. Если EPG раньше приходил из DVB-потока (EIT на PID 0x12), он и должен продолжать приходить. Если пропал — проверь настройки в /etc/enigma2/settings: параметр config.epg.eit должен быть true. Также убедись что в меню ресивера не отключён автоматический сбор EIT.

Можно ли получить EPG только через CCcam без XMLTV?

Нет. CCcam передаёт только Control Words для дескремблирования — это всё что он умеет делать. EPG приходит либо из самого транспондера (DVB EIT), либо тянется отдельно как XMLTV. Это разные технические уровни: CCcam работает на уровне условного доступа, EPG — на уровне сервисной информации DVB. Никакой связи между ними нет.

Какой формат XMLTV правильный и как его проверить?

Файл должен начинаться с XML-декларации <?xml version="1.0" encoding="UTF-8"?> и корневого тега <tv>. Каждый канал — тег channel id="...", каждая передача — тег programme с атрибутами start, stop, channel и явным timezone: start="20260523180000 +0300". Проверка: xmllint --noout file.xml. Кодировка строго UTF-8.

EPGImport показывает Import successful, но в EPG ничего нет — что делать?

В 90% случаев это несовпадение ServiceRef в channels.xml с реальными в lamedb. Проверь через web-интерфейс ресивера на порту 80: открой канал, ServiceRef будет виден в URL. Сравни с тем что написано в channels.xml. Также проверь что config.misc.epgcache_filename=/etc/enigma2/epg.dat — иначе EPG не переживает перезагрузку.

Как настроить автоматическое обновление EPG раз в сутки?

Через настройки EPGImport: Settings → Schedule import → Daily, время 04:00 (минимальная нагрузка ночью). Альтернатива — добавить скрипт в /etc/cron.daily/. После импорта EPG сохраняется в epg.dat при штатной работе enigma2, либо принудительно через GUI меню перезагрузки.

Время передач сдвинуто на несколько часов — как починить?

Проблема в timezone XMLTV-фида. В тегах programme должен быть явный offset: start="20260523180000 +0300". Если фид отдаёт UTC (+0000), а ресивер настроен на +0300 — расписание сдвинется. Решение: использовать фид с правильным TZ, либо настроить timezone ресивера под фид. Проверяй через Menu → Expert Setup → Time settings.

Tvheadend нужен или можно обойтись EPGImport?

Для одного ресивера EPGImport полностью достаточен. Tvheadend нужен если хочешь центральный EPG-сервер: один хост собирает XMLTV, раздаёт по HTSP второму ресиверу, Kodi, мобильным клиентам — и все получают актуальную local tv guide из одного источника. Это снижает трафик и упрощает поддержку маппинга каналов.

Practical checklist for smooth viewing

Even the best CCCam or OSCam line needs two or three simple preparations. Update your receiver firmware, reset the ECM cache once a week and keep 15–20% free space on the USB stick or internal flash so that the reader can store keys without delays.

When tuning a dish, aim for MER/BER reserve: a two‑degree offset or a loose F‑connector often causes the “freezing” that users blame on cardsharing. Keep a short patch cord to test alternative routers, and save two profiles in OSCam — one for TCP, one for UDP — so you can switch instantly if your ISP starts filtering a protocol.

Utgard.tv monitors each hub 24/7, but you can speed up diagnostics by keeping a short log of your receiver actions. Note the time when you changed the channel, which CAID was active and whether you used Wi‑Fi or Ethernet. This tiny “journal” helps engineers reproduce your environment in the lab and return with a solution in minutes instead of hours.

  • Keep two line slots enabled: if the first server hits a maintenance window, the second one instantly takes over without re-entering credentials.
  • Run a monthly speed and latency test. Stable 1–2 Mbps with ping <80 ms is enough for SD/HD, but if jitter exceeds 20 ms, switch the router to wired mode.
  • Save the Utgard.tv status page and Telegram bot @utgard_tv_bot to bookmarks — they publish maintenance notices before SEMrush or uptime monitors raise alerts.