19#include "libmythbase/mythconfig.h"
45static constexpr uint8_t TIMEOUT_RETRIES { 10 };
46static constexpr std::chrono::milliseconds TIMEOUT_WAIT { 250ms };
49static constexpr uint8_t DISEQC_FRM { 0xe0 };
50static constexpr uint8_t DISEQC_FRM_REPEAT {1 << 0};
93static constexpr double EPS { 1E-4 };
95#define LOC QString("DiSEqCDevTree: ")
101 for (
const auto &item : table)
102 if (
type == item.value)
110 for (
const auto &item : table)
111 if (
type == item.name)
113 return table[0].value;
140 "SELECT diseqcid, value "
141 "FROM diseqc_config "
142 "WHERE cardinputid = :INPUTID");
144 query.
bindValue(
":INPUTID", card_input_id);
170 "DELETE from diseqc_config "
171 "WHERE cardinputid = :INPUTID");
172 query.
bindValue(
":INPUTID", card_input_id);
182 "INSERT INTO diseqc_config "
183 " ( cardinputid, diseqcid, value) "
184 "VALUES (:INPUTID, :DEVID, :VALUE) ");
188 query.
bindValue(
":INPUTID", card_input_id);
208 uint_to_dbl_t::const_iterator it =
m_config.find(devid);
271 cardid_to_diseqc_tree_t::iterator it =
m_trees.find(cardid);
320 "WHERE hostname = :HOSTNAME AND "
321 " videodevice = :VIDEODEVICE "
332 else if (query.
next())
334 cardid = query.
value(0).toUInt();
360 "SELECT diseqcid, cardtype, inputname "
362 "WHERE cardid = :CARDID");
369 else if (!query.
next())
374 if (query.
value(0).toBool())
377 *
this, query.
value(0).toUInt());
379 else if ((query.
value(1).toString().toUpper() ==
"DVB") &&
380 ((query.
value(2).toString().toUpper() ==
"DVB-S" ) ||
381 (query.
value(2).toString().toUpper() ==
"DVB-S2") ))
383 LOG(VB_GENERAL, LOG_WARNING,
LOC +
384 QString(
"No device tree for cardid %1").arg(cardid));
402 "WHERE cardid = :CARDID");
409 else if (query.
next())
411 if (query.
value(0).toUInt() > 0)
434 "DELETE FROM diseqc_tree "
435 "WHERE diseqcid = :DEVID");
437 "DELETE FROM diseqc_config "
438 "WHERE diseqcid = :DEVID");
460 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to save DiSEqC tree.");
466 "UPDATE capturecard "
467 "SET diseqcid = :DEVID "
468 "WHERE (hostname = :HOSTNAME AND "
469 " videodevice = :VIDEODEVICE) "
470 " OR cardid = :CARDID");
473 query0.
bindValue(
":VIDEODEVICE", device);
486 bool success =
false;
489 for (
uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
492 on ? SEC_TONE_ON : SEC_TONE_OFF) == 0)
495 std::this_thread::sleep_for(TIMEOUT_WAIT);
500 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FE_SET_TONE failed" +
ENO);
516 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No root device tree node!");
557 for (
uint count = 0; node;)
561 if (rotor && (++count > index))
644static bool send_diseqc(
int fd,
const dvb_diseqc_master_cmd cmd)
646 bool success =
false;
648 for (
uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
650 if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd) == 0)
653 std::this_thread::sleep_for(TIMEOUT_WAIT);
658 LOG(VB_GENERAL, LOG_ERR,
LOC +
659 "send_diseqc FE_DISEQC_SEND_MASTER_CMD failed" +
ENO);
675 [[maybe_unused]]
uint cmd,
676 [[maybe_unused]]
uint repeats,
682 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad DiSEqC command");
692 bool resend_cmd =
false;
695 dvb_diseqc_master_cmd mcmd = {};
696 mcmd.msg[0] = DISEQC_FRM;
699 mcmd.msg_len = data.size() + 3;
702 std::copy(data.cbegin(), data.cend(), mcmd.msg + 3);
706 for (
uint byte = 0;
byte < mcmd.msg_len;
byte++)
707 cmdstr += QString(
"%1 ").arg(mcmd.msg[
byte], 2, 16);
709 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Sending DiSEqC Command: " + cmdstr);
713 repeats = repeats - 10;
718 for (
uint i = 0; i <= repeats; i++)
720 if (!send_diseqc(
GetFD(), mcmd))
722 LOG(VB_GENERAL, LOG_ERR,
LOC +
"DiSEqC command failed" +
ENO);
727 mcmd.msg[0] |= DISEQC_FRM_REPEAT;
751 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Power-cycling DiSEqC Bus");
767 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Resetting DiSEqC Bus");
770 LOG(VB_GENERAL, LOG_ERR,
LOC +
"DiSEqC reset failed" +
ENO);
779 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Skipping reset: already done for this SCR bus");
811 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Changing LNB voltage to " +
812 QString(
"%1V").arg(volts));
814 bool success =
false;
817 for (
uint retry = 0; !success && retry < TIMEOUT_RETRIES; retry++)
822 std::this_thread::sleep_for(TIMEOUT_WAIT);
828 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FE_SET_VOLTAGE failed" +
ENO);
863 {
"switch", kTypeSwitch },
864 {
"rotor", kTypeRotor },
867 { QString(), kTypeLNB },
886 for (
uint ch = 0; !dev && ch < num_children; ch++)
906 "SELECT type, description "
908 "WHERE diseqcid = :DEVID");
918 LOG(VB_GENERAL, LOG_ERR,
LOC +
"CreateById failed to find dtv dev " +
919 QString(
"%1").arg(devid));
925 QString desc = query.
value(1).toString();
1054 {
"legacy_sw21", kTypeLegacySW21 },
1055 {
"legacy_sw42", kTypeLegacySW42 },
1056 {
"legacy_sw64", kTypeLegacySW64 },
1057 {
"tone", kTypeTone },
1058 {
"diseqc", kTypeDiSEqCCommitted },
1059 {
"diseqc_uncom", kTypeDiSEqCUncommitted },
1060 {
"voltage", kTypeVoltage },
1061 {
"mini_diseqc", kTypeMiniDiSEqC },
1062 { QString(), kTypeTone },
1085 bool success =
true;
1117 LOG(VB_GENERAL, LOG_ERR,
LOC +
1118 QString(
"Unknown switch type (%1)").arg((
uint)
m_type));
1125 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Waiting for switch");
1134 success =
m_children[pos]->Execute(settings, tuning);
1210 voltage = child->
GetVoltage(settings, tuning);
1226 "SELECT subtype, address, switch_ports, cmd_repeat "
1228 "WHERE diseqcid = :DEVID");
1249 "SELECT diseqcid, ordinal "
1251 "WHERE parentid = :DEVID");
1259 while (query.
next())
1261 uint child_dev_id = query.
value(0).toUInt();
1264 if (child && !
SetChild(ordinal, child))
1266 LOG(VB_GENERAL, LOG_ERR,
LOC +
1267 QString(
"Switch port out of range (%1 > %2)")
1285 "UPDATE diseqc_tree "
1286 "SET parentid = :PARENT, "
1287 " ordinal = :ORDINAL, "
1288 " type = 'switch', "
1289 " description = :DESC, "
1290 " subtype = :TYPE, "
1291 " address = :ADDRESS, "
1292 " switch_ports = :PORTS, "
1293 " cmd_repeat = :REPEAT "
1294 "WHERE diseqcid = :DEVID");
1300 "INSERT INTO diseqc_tree"
1301 " ( parentid, ordinal, type, "
1302 " description, address, subtype, "
1303 " switch_ports, cmd_repeat ) "
1305 " (:PARENT, :ORDINAL, 'switch', "
1306 " :DESC, :ADDRESS, :TYPE, "
1307 " :PORTS, :REPEAT )");
1331 bool success =
true;
1335 success &= child->Store();
1345 if (old_num > num_ports)
1347 for (
uint ch = num_ports; ch < old_num; ch++)
1354 else if (old_num < num_ports)
1357 for (
uint ch = old_num; ch < num_ports; ch++)
1366 [[maybe_unused]]
uint pos)
1368#if CONFIG_DVB && defined(FE_DISHNETWORK_SEND_LEGACY_CMD)
1369 static const cmd_vec_t kSw21Cmds { 0x34, 0x65, };
1370 static const cmd_vec_t kSw42Cmds { 0x46, 0x17, };
1371 static const cmd_vec_t kSw64VCmds { 0x39, 0x4b, 0x0d, };
1372 static const cmd_vec_t kSw64HCmds { 0x1a, 0x5c, 0x2e, };
1375 unsigned char horizcmd = 0x00;
1378 bool horizontal =
false;
1405 LOG(VB_CHANNEL, LOG_INFO,
LOC +
1406 QString(
"Changing to Legacy switch port %1/%2")
1407 .arg(pos + 1).arg(cmds.size()));
1410 if (ioctl(
m_tree.
GetFD(), FE_DISHNETWORK_SEND_LEGACY_CMD,
1411 cmds[pos] | horizcmd) == -1)
1413 LOG(VB_GENERAL, LOG_ERR,
LOC +
1414 "FE_DISHNETWORK_SEND_LEGACY_CMD failed" +
ENO);
1423 LOG(VB_GENERAL, LOG_ERR,
LOC +
"You must compile with a newer "
1424 "version of the linux headers for DishNet Legacy switch support.");
1431static bool set_tone(
int fd, fe_sec_tone_mode tone)
1433 bool success =
false;
1435 for (
uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
1437 if (ioctl(fd, FE_SET_TONE, tone) == 0)
1440 std::this_thread::sleep_for(TIMEOUT_WAIT);
1445 LOG(VB_GENERAL, LOG_ERR,
LOC +
"set_tone failed" +
ENO);
1453static bool set_voltage(
int fd, fe_sec_voltage volt)
1455 bool success =
false;
1457 for (
uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
1459 if (0 == ioctl(fd, FE_SET_VOLTAGE, volt))
1462 std::this_thread::sleep_for(TIMEOUT_WAIT);
1467 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FE_SET_VOLTAGE failed" +
ENO);
1475static bool mini_diseqc(
int fd, fe_sec_mini_cmd cmd)
1477 bool success =
false;
1479 for (
uint retry = 0; !success && (retry < TIMEOUT_RETRIES); retry++)
1481 if (ioctl(fd, FE_DISEQC_SEND_BURST, cmd) == 0)
1484 std::this_thread::sleep_for(TIMEOUT_WAIT);
1489 LOG(VB_GENERAL, LOG_ERR,
LOC +
1490 "mini_diseqc FE_DISEQC_SEND_BURST failed" +
ENO);
1501 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Changing to Tone switch port " +
1502 QString(
"%1/2").arg(pos + 1));
1505 if (set_tone(
m_tree.
GetFD(), (0 == pos) ? SEC_TONE_OFF : SEC_TONE_ON))
1509 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Setting Tone Switch failed." +
ENO);
1517 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Changing to Voltage Switch port " +
1518 QString(
"%1/2").arg(pos + 1));
1528 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Setting Voltage Switch failed." +
ENO);
1537 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Changing to MiniDiSEqC Switch port " +
1538 QString(
"%1/2").arg(pos + 1));
1541 if (mini_diseqc(
m_tree.
GetFD(), (0 == pos) ? SEC_MINI_A : SEC_MINI_B))
1545 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Setting Mini DiSEqC Switch failed." +
ENO);
1561 bool high_band =
false;
1562 bool horizontal =
false;
1578 bool horizontal =
false;
1599 auto pos =
static_cast<uint8_t
>(pos32);
1601 bool high_band =
false;
1602 bool horizontal =
false;
1614 LOG(VB_GENERAL, LOG_ERR,
LOC +
1615 QString(
"Invalid number of ports for DiSEqC 1.x Switch (%1)")
1626 data[0] = ((pos << 2) | (horizontal ? 2 : 0) | (high_band ? 1 : 0));
1630 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Changing to DiSEqC switch port " +
1631 QString(
"%1/%2").arg(pos + 1).arg(
m_numPorts));
1648 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Port %1 ").arg(pos + 1) +
1649 QString(
"is not in range [0..%1)").arg(
m_numPorts));
1656 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Port %1 ").arg(pos + 1) +
1657 "has no connected devices configured.");
1669 struct timeval curtime {};
1670 gettimeofday(&curtime,
nullptr);
1671 return (
double)curtime.tv_sec + (((double)curtime.tv_usec) / 1000000);
1680 {
"diseqc_1_2", kTypeDiSEqC_1_2 },
1681 {
"diseqc_1_3", kTypeDiSEqC_1_3 },
1682 {
nullptr, kTypeDiSEqC_1_3 }
1693 bool success =
true;
1708 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown rotor type " +
1787 LOG(VB_CHANNEL, LOG_INFO,
LOC +
1788 "Overriding voltage to 18V for faster rotor movement");
1803 "SELECT subtype, rotor_positions, "
1804 " rotor_hi_speed, rotor_lo_speed, "
1807 "WHERE diseqcid = :DEVID");
1823 QString positions = query.
value(1).toString();
1824 QStringList pos = positions.split(
":", Qt::SkipEmptyParts);
1825 for (
const auto & kv : std::as_const(pos))
1827 const QStringList eq = kv.split(
"=", Qt::SkipEmptyParts);
1829 m_posmap[eq[0].toFloat()] = eq[1].toUInt();
1843 "WHERE parentid = :DEVID");
1853 uint child_dev_id = query.
value(0).toUInt();
1862 QString posmap =
"";
1869 dbl_to_uint_t::const_iterator it =
m_posmap.begin();
1871 pos.push_back(QString(
"%1=%2").arg(it.key()).arg(*it));
1873 posmap = pos.join(
":");
1882 "UPDATE diseqc_tree "
1883 "SET parentid = :PARENT, "
1884 " ordinal = :ORDINAL, "
1886 " description = :DESC, "
1887 " subtype = :TYPE, "
1888 " rotor_hi_speed = :HISPEED, "
1889 " rotor_lo_speed = :LOSPEED, "
1890 " rotor_positions = :POSMAP, "
1891 " cmd_repeat = :REPEAT "
1892 "WHERE diseqcid = :DEVID");
1898 "INSERT INTO diseqc_tree "
1899 " ( parentid, ordinal, type, "
1900 " description, subtype, rotor_hi_speed, "
1901 " rotor_lo_speed, rotor_positions, cmd_repeat ) "
1903 " (:PARENT, :ORDINAL, 'rotor', "
1904 " :DESC, :TYPE, :HISPEED, "
1905 " :LOSPEED, :POSMAP, :REPEAT )");
1950 double duration = change / speed;
1954 double completed = time_since_move / duration;
1979 dbl_to_uint_t::const_iterator it;
1981 inv_posmap[*it] = it.key();
1990 uint_to_dbl_t::const_iterator it;
1991 for (it = inv_posmap.begin(); it != inv_posmap.end(); ++it)
2000 dbl_to_uint_t::const_iterator it =
2002 cmd_vec_t index {
static_cast<uint8_t
>(angle) };
2009 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Rotor - " +
2010 QString(
"Goto Stored Position %1").arg(index[0]));
2023 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"USALS Rotor - " +
2024 QString(
"Goto %1 (Azimuth %2)").arg(angle).arg(azimuth));
2026 uint az16 = (
uint) (abs(azimuth) * 16.0);
2028 static_cast<uint8_t
>(((azimuth > 0.0) ? 0xE0 : 0xD0) | ((az16 >> 8) & 0x0f)),
2029 static_cast<uint8_t
>(az16 & 0xff) };
2048 return TO_DEC * atan( tan(Us - Ue) / sin(P) );
2089 {
"A", kTypeScrPosA },
2090 {
"B", kTypeScrPosB },
2091 { QString(), kTypeScrPosA },
2111 LOG(VB_GENERAL, LOG_ERR,
LOC +
"SCR: No LNB for this configuration!");
2126 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"SCR: Userband ID=%1 is out of range (0-7)!")
2133 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"SCR: T=%1 is out of range!").arg(
t));
2137 LOG(VB_GENERAL, LOG_INFO, QString(
"SCR: Tuning to %1kHz, %2, %3 using UB=%4, FREQ=%5MHz, POS=%6%7")
2139 .arg(high_band ?
"HiBand" :
"LoBand",
2140 horizontal ?
"H" :
"V")
2143 .arg((scr_position) ?
"B" :
"A",
2145 QString(
", PIN=%1").arg(
m_scrPin) : QString(
"")));
2150 static_cast<uint8_t
>(
t & 0x00FF) };
2153 data[0] |= (1 << 2);
2156 data[0] |= (1 << 3);
2159 data[0] |= (1 << 4);
2172 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"SCR: Userband ID=%1 is out of range (0-7)!")
2177 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"SCR: Power off UB=%1%7")
2180 ? QString(
", PIN=%1").arg(
m_scrPin)
2194 [[maybe_unused]]
uint repeats,
2221 return (((
t + 350) * 4) * 1000) - frequency;
2229 "SELECT scr_userband, scr_frequency, "
2230 " scr_pin, cmd_repeat "
2232 "WHERE diseqcid = :DEVID");
2258 "WHERE parentid = :DEVID");
2268 uint child_dev_id = query.
value(0).toUInt();
2283 "UPDATE diseqc_tree "
2284 "SET parentid = :PARENT, "
2285 " ordinal = :ORDINAL, "
2287 " description = :DESC, "
2288 " scr_userband = :USERBAND, "
2289 " scr_frequency = :FREQUENCY, "
2291 " cmd_repeat = :REPEAT "
2292 "WHERE diseqcid = :DEVID");
2298 "INSERT INTO diseqc_tree"
2299 " ( parentid, ordinal, type, "
2300 " description, scr_userband, scr_frequency, "
2301 " scr_pin, cmd_repeat) "
2303 " (:PARENT, :ORDINAL, 'scr', "
2304 " :DESC, :USERBAND, :FREQUENCY,"
2305 " :PIN, :REPEAT) ");
2363 {
"fixed", kTypeFixed },
2364 {
"voltage", kTypeVoltageControl },
2365 {
"voltage_tone", kTypeVoltageAndToneControl },
2366 {
"bandstacked", kTypeBandstacked },
2367 { QString(), kTypeVoltageAndToneControl },
2398 "SELECT subtype, lnb_lof_switch, "
2399 " lnb_lof_hi, lnb_lof_lo, "
2400 " lnb_pol_inv, cmd_repeat "
2402 "WHERE diseqcid = :DEVID");
2432 "UPDATE diseqc_tree "
2433 "SET parentid = :PARENT, "
2434 " ordinal = :ORDINAL, "
2436 " description = :DESC, "
2437 " subtype = :TYPE, "
2438 " lnb_lof_switch = :LOFSW, "
2439 " lnb_lof_lo = :LOFLO, "
2440 " lnb_lof_hi = :LOFHI, "
2441 " lnb_pol_inv = :POLINV, "
2442 " cmd_repeat = :REPEAT "
2443 "WHERE diseqcid = :DEVID");
2449 "INSERT INTO diseqc_tree"
2450 " ( parentid, ordinal, type, "
2451 " description, subtype, lnb_lof_switch, "
2452 " lnb_lof_lo, lnb_lof_hi, lnb_pol_inv, "
2455 " (:PARENT, :ORDINAL, 'lnb', "
2456 " :DESC, :TYPE, :LOFSW, "
2457 " :LOFLO, :LOFHI, :POLINV, "
2531 return (lof > abs_freq) ? (lof - abs_freq) : (abs_freq - lof);
Represents a node in a DVB-S device network.
uint GetDeviceID(void) const
std::vector< TypeTable > TypeTableVec
virtual void Reset(void)
Resets to the last known settings for this device.
bool IsRealDeviceID(void) const
virtual bool Store(void) const =0
Stores this device to the database.
virtual uint GetChildCount(void) const
Retrieves the proper number of children for this node.
virtual DiSEqCDevDevice * GetSelectedChild(const DiSEqCDevSettings &) const
Retrieves the selected child for this configuration, if any.
virtual DiSEqCDevDevice * GetChild(uint)
Retrieves the nth child of this node.
static DiSEqCDevDevice * CreateById(DiSEqCDevTree &tree, uint devid)
virtual bool Execute(const DiSEqCDevSettings &, const DTVMultiplex &)=0
Applies DiSEqC settings to this node and any children.
QString GetDescription(void) const
void SetDescription(const QString &desc)
void SetParent(DiSEqCDevDevice *parent)
virtual uint GetVoltage(const DiSEqCDevSettings &, const DTVMultiplex &) const =0
Retrives the desired voltage for this config.
void SetOrdinal(uint ordinal)
static QString TableToString(uint type, const TypeTableVec &table)
void SetDeviceID(uint devid) const
virtual ~DiSEqCDevDevice()
static DiSEqCDevDevice * CreateByType(DiSEqCDevTree &tree, dvbdev_t type, uint dev_id=0)
DiSEqCDevDevice * FindDevice(uint dev_id)
Returns a device by ID.
virtual bool Load(void)=0
Loads this device from the database.
void SetDeviceType(dvbdev_t type)
static const TypeTableVec kDvbdevLookup
static uint TableFromString(const QString &type, const TypeTableVec &table)
DiSEqCDevDevice * m_parent
dvbdev_t GetDeviceType(void) const
virtual bool IsCommandNeeded(const DiSEqCDevSettings &, const DTVMultiplex &) const
Determines if this device or any child will be sending a command for the given configuration chain.
static dvbdev_t DevTypeFromString(const QString &type)
static dvbdev_lnb_t LNBTypeFromString(const QString &type)
bool IsHighBand(const DTVMultiplex &tuning) const
Determine if the high frequency band is active (for switchable LNBs).
bool IsPolarityInverted(void) const
uint32_t GetIntermediateFrequency(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const
Calculate proper intermediate frequency for the given settings and tuning parameters.
bool Store(void) const override
Stores this device to the database.
@ kTypeVoltageAndToneControl
static QString LNBTypeToString(dvbdev_lnb_t type)
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) override
Applies DiSEqC settings to this node and any children.
bool Load(void) override
Loads this device from the database.
static const TypeTableVec kLNBTypeTable
bool m_polInv
If a signal is circularly polarized the polarity will flip on each reflection, so antenna systems wit...
bool IsHorizontal(const DTVMultiplex &tuning) const
Determine if horizontal polarity is active (for switchable LNBs).
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
void StartRotorPositionTracking(double azimuth)
bool ExecuteUSALS(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, double angle)
static dvbdev_rotor_t RotorTypeFromString(const QString &type)
uint_to_dbl_t GetPosMap(void) const
double GetProgress(void) const
Returns an indication of rotor progress.
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
bool SetChild(uint ordinal, DiSEqCDevDevice *device) override
Changes the nth child of this node.
bool ExecuteRotor(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, double angle)
~DiSEqCDevRotor() override
bool IsMoving(const DiSEqCDevSettings &settings) const
static const TypeTableVec kRotorTypeTable
static double CalculateAzimuth(double angle)
bool Store(void) const override
Stores this device to the database.
bool IsCommandNeeded(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Determines if this device or any child will be sending a command for the given configuration chain.
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) override
Applies DiSEqC settings to this node and any children.
void SetPosMap(const uint_to_dbl_t &posmap)
void RotationComplete(void) const
bool IsPositionKnown(void) const
Returns true if there is reasonable confidence in the value returned by GetProgress().
DiSEqCDevDevice * m_child
static QString RotorTypeToString(dvbdev_rotor_t type)
bool Load(void) override
Loads this device from the database.
double GetApproxAzimuth(void) const
void Reset(void) override
Resets to the last known settings for this device.
DiSEqCDevDevice * GetSelectedChild(const DiSEqCDevSettings &setting) const override
Retrieves the selected child for this configuration, if any.
bool SendCommand(uint cmd, uint repeats, cmd_vec_t &data) const
uint32_t GetIntermediateFrequency(uint32_t frequency) const
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
bool PowerOff(void) const
DiSEqCDevDevice * m_child
void Reset(void) override
Resets to the last known settings for this device.
bool Store(void) const override
Stores this device to the database.
bool SetChild(uint ordinal, DiSEqCDevDevice *device) override
Changes the nth child of this node.
bool Load(void) override
Loads this device from the database.
static const TypeTableVec kSCRPositionTable
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) override
Applies DiSEqC settings to this node and any children.
DVB-S device settings class.
double GetValue(uint devid) const
Retrieves a value from this configuration chain by device id.
void SetValue(uint devid, double value)
Sets a value for this configuration chain by device id.
bool Store(uint card_input_id) const
Stores configuration chain to DB for specified card input id.
bool Load(uint card_input_id)
Loads configuration chain from DB for specified card input id.
uint m_inputId
current input id
Switch class, including tone, legacy and DiSEqC switches.
static QString SwitchTypeToString(dvbdev_switch_t type)
DiSEqCDevDevice * GetChild(uint ordinal) override
Retrieves the nth child of this node.
DiSEqCDevSwitch(DiSEqCDevTree &tree, uint devid)
DiSEqCDevDevice * GetSelectedChild(const DiSEqCDevSettings &settings) const override
Retrieves the selected child for this configuration, if any.
bool SetChild(uint ordinal, DiSEqCDevDevice *device) override
Changes the nth child of this node.
bool ShouldSwitch(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const
bool IsCommandNeeded(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Determines if this device or any child will be sending a command for the given configuration chain.
bool Execute(const DiSEqCDevSettings &, const DTVMultiplex &) override
Applies DiSEqC settings to this node and any children.
int GetPosition(const DiSEqCDevSettings &settings) const
static const TypeTableVec kSwitchTypeTable
uint GetChildCount(void) const override
Retrieves the proper number of children for this node.
bool ExecuteTone(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
bool ExecuteLegacy(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
void SetNumPorts(uint num_ports)
bool Store(void) const override
Stores this device to the database.
static dvbdev_switch_t SwitchTypeFromString(const QString &type)
~DiSEqCDevSwitch() override
bool Load(void) override
Loads this device from the database.
bool ExecuteMiniDiSEqC(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
void Reset(void) override
Resets to the last known settings for this device.
bool ExecuteDiseqc(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
bool ExecuteVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning, uint pos)
uint GetVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const override
Retrives the desired voltage for this config.
uint GetVoltage(void) const
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning)
Applies settings to the entire tree.
bool Load(const QString &device)
Loads the device tree from the database.
void AddDeferredDelete(uint dev_id)
void SetRoot(DiSEqCDevDevice *root)
Changes the root node of the tree.
DiSEqCDevDevice * FindDevice(uint dev_id)
Returns a device by ID.
uint CreateFakeDiSEqCID(void)
void Reset(void)
Reset state of nodes in tree, forcing updates on the next Execute command.
static const uint kFirstFakeDiSEqCID
bool Store(uint cardid, const QString &device="")
Stores the device tree to the database.
bool ResetDiseqc(bool hard_reset, bool is_SCR)
Resets the DiSEqC bus.
DiSEqCDevSCR * FindSCR(const DiSEqCDevSettings &settings)
Returns the SCR device object selected by the configuration chain.
DiSEqCDevLNB * FindLNB(const DiSEqCDevSettings &settings)
Returns the LNB device object selected by the configuration chain.
DiSEqCDevRotor * FindRotor(const DiSEqCDevSettings &settings, uint index=0)
Returns the nth rotor device object in the tree.
bool SendCommand(uint adr, uint cmd, uint repeats, cmd_vec_t &data) const
static bool Exists(int cardid)
Check if a Diseqc device tree exists.
bool SetVoltage(uint voltage)
bool SetTone(bool on) const
bool ApplyVoltage(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning)
std::vector< uint > m_delete
bool IsInNeedOfConf(void) const
void Open(int fd_frontend, bool is_SCR)
Retrieve device tree.
Static-scoped locked tree list class.
DiSEqCDevTree * FindTree(uint cardid)
Retrieve device tree.
void InvalidateTrees(void)
Invalidate cached trees.
cardid_to_diseqc_tree_t m_trees
static DiSEqCDevTree * FindTree(uint cardid)
Retrieve device tree.
static void InvalidateTrees(void)
Invalidate cached trees.
static DiSEqCDevTrees s_trees
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
QVariant lastInsertId()
Return the id of the last inserted row.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetHostName(void)
QString GetSetting(const QString &key, const QString &defaultval="")
static void DBError(const QString &where, const MSqlQuery &query)
static constexpr std::chrono::milliseconds DISEQC_POWER_ON_WAIT
static constexpr std::chrono::milliseconds DISEQC_SHORT_WAIT
static constexpr double EPS
bool diseqc_bus_already_reset
static constexpr uint8_t SEC_VOLTAGE_18
static constexpr uint8_t SEC_VOLTAGE_OFF
static constexpr uint8_t SEC_VOLTAGE_13
static constexpr double TO_DEC
static double GetCurTimeFloating(void)
static constexpr std::chrono::milliseconds DISEQC_LONG_WAIT
static constexpr std::chrono::milliseconds DISEQC_POWER_OFF_WAIT
static constexpr double TO_RADS
std::vector< uint8_t > cmd_vec_t
QMap< uint, double > uint_to_dbl_t
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define ENO
This can be appended to the LOG args with "+".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MBASE_PUBLIC long long copy(QFile &dst, QFile &src, uint block_size=0)
Copies src file to dst file.