Added basic support for positioners to control steerable satellite dishes

This commit is contained in:
Klaus Schmidinger 2013-08-21 11:02:52 +02:00
parent 5b76eec1af
commit cd10b439d0
59 changed files with 1883 additions and 116 deletions

View File

@ -2696,6 +2696,7 @@ Ales Jurik <ajurik@quick.cz>
for reporting broken SI data on Czech/Slovak channels after changing the default
character set to ISO-8859-9
for adding MPEG 1 handling to remux.c
for a patch that was used as a base for implementing support for positioners
Magnus Andersson <svankan@bahnhof.se>
for translating OSD texts to the Swedish language
@ -3155,3 +3156,6 @@ Jochen Dolze <vdr@dolze.de>
Dominique Dumont <domi.dumont@free.fr>
for reporting a crash in the LCARS skin's main menu in case there is no current channel
Seppo Ingalsuo <seppo.ingalsuo@iki.fi>
for a patch that was used as a base for implementing support for positioners

28
HISTORY
View File

@ -7144,7 +7144,7 @@ Video Disk Recorder Revision History
Christian Richter).
- Added DeleteEvent() to the EPG handler interface, so that an EPG handler can trigger
deleting of an event (thanks to Christian Kaiser).
- Speeded up opening menus on systems with many (several thousands) of recordings, by
- Speeded up opening menus on systems with many (several thousands of) recordings, by
caching the information whether a recording is stored on the video directory file
system within the cRecording data (based on a patch from Torsten Lang).
@ -7813,7 +7813,7 @@ Video Disk Recorder Revision History
- Fixed a crash in the LCARS skin's main menu in case there is no current channel
(reported by Dominique Dumont).
2013-05-19: Version 2.1.1
2013-08-21: Version 2.1.1
- Fixed initializing cDevice::keepTracks.
- Fixed an endless loop in cTextWrapper::Set() in case the given Width is smaller than
@ -7844,3 +7844,27 @@ Video Disk Recorder Revision History
by Stefan Braun).
- Fixed a crash in the LCARS skin's main menu in case there is no current channel
(reported by Dominique Dumont).
- Added basic support for positioners to control steerable satellite dishes (based on
a patch from Seppo Ingalsuo and Ales Jurik).
+ Supports GotoN (aka "DiSEqC 1.2") and GotoX (aka "USALS").
+ The new DiSEqC command code 'P' can be used to instruct a positioner to move the
dish to the required satellite position. When a 'P' code is processed, further
execution of the remaining DiSEqC sequence (if any) is postponed until the positioner
has reached the new satellite position.
+ The new special source value of "S360E" can be used in diseqc.conf to indicate that
an entry using a positioner can move the dish to any requested position within its
range. Think of it as "full circle".
+ The devices a particular cDiseqc or cScr applies to are now stored directly in each
cDiseqc or cScr, respectively.
+ A plugin can implement a custom positioner control (see PLUGINS.html, section "Positioners").
+ The new function cSkinDisplayChannel::SetPositioner() can be implemented by skins to
show the user a progress display when the dish is being moved. The default implementation
calls SetMessage() with a string indicating the new position the dish is being moved to.
The LCARS skin shows a progress bar indicating the movement of the dish.
+ The new parameters "Site latitude", "Site longitude", "Positioner speed", and
"Positioner swing" in the "Setup/LNB" menu can be used to configure the necessary
values for a steerable dish.
+ The cDvbTuner now has a new status tsPositioning, in which it waits until a steerable
dish has reached its target position. Parsing SI data is paused until the target
position has been reached.
- The LCARS skin now shows the source value of the current channel in its channel display.

22
MANUAL
View File

@ -776,6 +776,28 @@ Version 2.0
are connected to the same sat cable must be set to the same
number here.
Use dish positioner = no
By default, the 'P' command code in DiSEqC command sequences
is ignored. Set this parameter to 'yes' if you are using a
satellite dish positioner.
Site latitude (degrees) = 0
Site longitude (degrees) = 0
Set these to the latitude and longitude of your dish's
location if you use a satellite dish positioner. Use the
"Green" key to switch between north/south and east/west,
respectively.
Max. positioner swing (degrees) = 65
Defines the maximum angle by which the positioner can move
the dish away from due south (or north) in either direction.
The valid range is 0...90.
Positioner speed (degrees/s) = 1.5
Defines the speed at which the positioner moves the dish.
The valid range is 0.1...180. This value is used to calculate
how long it takes the positioner to reach the target position.
CAM:
n CAM Name Shows the CAM slots that are present in this system, where

View File

@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
# $Id: Makefile 2.54 2013/03/11 15:01:01 kls Exp $
# $Id: Makefile 3.1 2013/05/23 10:10:00 kls Exp $
.DELETE_ON_ERROR:
@ -68,7 +68,7 @@ SILIB = $(LSIDIR)/libsi.a
OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\
dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o\
lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o positioner.o\
receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\
skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\
timers.o tools.o transfer.o vdr.o videodir.o

View File

@ -99,6 +99,7 @@ structures and allows it to hook itself into specific areas to perform special a
<li><a href="#Skins">Skins</a>
<li><a href="#Themes">Themes</a>
<li><a href="#Devices">Devices</a>
<li><modified><a href="#Positioners">Positioners</a></modified>
<li><a href="#Audio">Audio</a>
<li><a href="#Remote Control">Remote Control</a>
<li><a href="#Conditional Access">Conditional Access</a>
@ -2024,6 +2025,49 @@ new cMyDeviceHook;
and shall not delete this object. It will be automatically deleted when the program ends.
<div class="modified">
<hr><h2><a name="Positioners">Positioners</a></h2>
<div class="blurb">Now you see me - now you don't!</div><p>
If you are using a positioner (also known as "motor" or "rotor") to move your
satellite dish to receive various satellites, you will be using the 'P' command
in the <tt>diseqc.conf</tt> file. This command sends the necessary data to the
positioner to move the dish to the satellite's orbital position. By default VDR
uses its builtin DiSEqC positioner control. If your positioner requires a different
method of controlling (like maybe via a serial link), you can derive a class
from <tt>cPositioner</tt>, as in
<p><table><tr><td class="code"><pre>
#include &lt;vdr/positioner.h&gt;
class cMyPositioner : public cPositioner {
private:
void SendDiseqc(uint8_t *Codes, int NumCodes);
public:
cMyPositioner(void);
virtual void Drive(ePositionerDirection Direction);
virtual void Step(ePositionerDirection Direction, uint Steps = 1);
virtual void Halt(void);
virtual void SetLimit(ePositionerDirection Direction);
virtual void DisableLimits(void);
virtual void EnableLimits(void);
virtual void StorePosition(uint Number);
virtual void RecalcPositions(uint Number);
virtual void GotoPosition(uint Number, int Longitude);
virtual void GotoAngle(int Longitude);
};
</pre></td></tr></table><p>
See the implementation of <tt>cDiseqcPositioner</tt> in <tt>diseqc.c</tt> for details.
<p>
You should create your derived positioner object in the
<a href="#Getting started"><tt>Start()</tt></a> function of your plugin.
Note that the object has to be created on the heap (using <tt>new</tt>),
and you shall not delete it at any point (it will be deleted automatically
when the program ends).
</div modified>
<hr><h2><a name="Audio">Audio</a></h2>
<div class="blurb">"The stereo effect may only be experienced if stereo equipment is used!"</div><p>

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.c 2.38 2013/03/18 08:57:50 kls Exp $
* $Id: config.c 3.1 2013/05/23 12:41:06 kls Exp $
*/
#include "config.h"
@ -389,6 +389,12 @@ cSetup::cSetup(void)
LnbFrequLo = 9750;
LnbFrequHi = 10600;
DiSEqC = 0;
UsePositioner = 0;
SiteLat = 0;
SiteLon = 0;
PositionerSpeed = 15;
PositionerSwing = 65;
PositionerLastLon = 0;
SetSystemTime = 0;
TimeSource = 0;
TimeTransponder = 0;
@ -594,6 +600,12 @@ bool cSetup::Parse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value);
else if (!strcasecmp(Name, "DiSEqC")) DiSEqC = atoi(Value);
else if (!strcasecmp(Name, "UsePositioner")) UsePositioner = atoi(Value);
else if (!strcasecmp(Name, "SiteLat")) SiteLat = atoi(Value);
else if (!strcasecmp(Name, "SiteLon")) SiteLon = atoi(Value);
else if (!strcasecmp(Name, "PositionerSpeed")) PositionerSpeed = atoi(Value);
else if (!strcasecmp(Name, "PositionerSwing")) PositionerSwing = atoi(Value);
else if (!strcasecmp(Name, "PositionerLastLon")) PositionerLastLon = atoi(Value);
else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value);
else if (!strcasecmp(Name, "TimeSource")) TimeSource = cSource::FromString(Value);
else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value);
@ -703,6 +715,12 @@ bool cSetup::Save(void)
Store("LnbFrequLo", LnbFrequLo);
Store("LnbFrequHi", LnbFrequHi);
Store("DiSEqC", DiSEqC);
Store("UsePositioner", UsePositioner);
Store("SiteLat", SiteLat);
Store("SiteLon", SiteLon);
Store("PositionerSpeed", PositionerSpeed);
Store("PositionerSwing", PositionerSwing);
Store("PositionerLastLon", PositionerLastLon);
Store("SetSystemTime", SetSystemTime);
Store("TimeSource", cSource::ToString(TimeSource));
Store("TimeTransponder", TimeTransponder);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: config.h 3.1 2013/04/05 10:27:16 kls Exp $
* $Id: config.h 3.2 2013/05/23 12:40:19 kls Exp $
*/
#ifndef __CONFIG_H
@ -27,8 +27,8 @@
// The plugin API's version number:
#define APIVERSION "2.0.0"
#define APIVERSNUM 20000 // Version * 10000 + Major * 100 + Minor
#define APIVERSION "2.1.1"
#define APIVERSNUM 20101 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to
@ -266,6 +266,12 @@ public:
int LnbFrequLo;
int LnbFrequHi;
int DiSEqC;
int UsePositioner;
int SiteLat;
int SiteLon;
int PositionerSpeed;
int PositionerSwing;
int PositionerLastLon;
int SetSystemTime;
int TimeSource;
int TimeTransponder;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.c 3.1 2013/04/05 10:05:33 kls Exp $
* $Id: device.c 3.2 2013/06/01 11:34:11 kls Exp $
*/
#include "device.h"
@ -665,6 +665,11 @@ int cDevice::NumProvidedSystems(void) const
return 0;
}
const cPositioner *cDevice::Positioner(void) const
{
return NULL;
}
int cDevice::SignalStrength(void) const
{
return -1;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.h 2.47 2013/02/16 15:20:01 kls Exp $
* $Id: device.h 3.1 2013/06/01 11:35:23 kls Exp $
*/
#ifndef __DEVICE_H
@ -17,6 +17,7 @@
#include "filter.h"
#include "nit.h"
#include "pat.h"
#include "positioner.h"
#include "remux.h"
#include "ringbuffer.h"
#include "sdt.h"
@ -273,6 +274,11 @@ public:
///< actually provide channels must implement this function.
///< The result of this function is used when selecting a device, in order
///< to avoid devices that provide more than one system.
virtual const cPositioner *Positioner(void) const;
///< Returns a pointer to the positioner (if any) this device has used to
///< move the satellite dish to the requested position (only applies to DVB-S
///< devices). If no positioner is involved, or this is not a DVB-S device,
///< NULL will be returned.
virtual int SignalStrength(void) const;
///< Returns the "strength" of the currently received signal.
///< This is a value in the range 0 (no signal at all) through

200
diseqc.c
View File

@ -4,24 +4,37 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: diseqc.c 3.1 2013/05/02 09:30:33 kls Exp $
* $Id: diseqc.c 3.2 2013/08/21 09:26:11 kls Exp $
*/
#include "diseqc.h"
#include <ctype.h>
#include <linux/dvb/frontend.h>
#include <sys/ioctl.h>
#include "sources.h"
#include "thread.h"
static bool ParseDeviceNumbers(const char *s, int &Devices)
#define ALL_DEVICES (~0) // all bits set to '1'
#define MAX_DEVICES 32 // each bit in a 32-bit integer represents one device
static int CurrentDevices = 0;
static bool IsDeviceNumbers(const char *s)
{
if (*s && s[strlen(s) - 1] == ':') {
return *s && s[strlen(s) - 1] == ':';
}
static bool ParseDeviceNumbers(const char *s)
{
if (IsDeviceNumbers(s)) {
CurrentDevices = 0;
const char *p = s;
while (*p && *p != ':') {
char *t = NULL;
int d = strtol(p, &t, 10);
p = t;
if (0 < d && d < 31)
Devices |= (1 << d - 1);
if (0 < d && d <= MAX_DEVICES)
CurrentDevices |= (1 << d - 1);
else {
esyslog("ERROR: invalid device number %d in '%s'", d, s);
return false;
@ -31,6 +44,107 @@ static bool ParseDeviceNumbers(const char *s, int &Devices)
return true;
}
// --- cDiseqcPositioner -----------------------------------------------------
// See http://www.eutelsat.com/files/live/sites/eutelsatv2/files/contributed/satellites/pdf/Diseqc/associated%20docs/positioner_appli_notice.pdf
cDiseqcPositioner::cDiseqcPositioner(void)
{
SetCapabilities(pcCanDrive |
pcCanStep |
pcCanHalt |
pcCanSetLimits |
pcCanDisableLimits |
pcCanEnableLimits |
pcCanStorePosition |
pcCanRecalcPositions |
pcCanGotoPosition |
pcCanGotoAngle
);
}
void cDiseqcPositioner::SendDiseqc(uint8_t *Codes, int NumCodes)
{
struct dvb_diseqc_master_cmd cmd;
NumCodes = min(NumCodes, int(sizeof(cmd.msg) - 2));
cmd.msg_len = 0;
cmd.msg[cmd.msg_len++] = 0xE0;
cmd.msg[cmd.msg_len++] = 0x31;
for (int i = 0; i < NumCodes; i++)
cmd.msg[cmd.msg_len++] = Codes[i];
CHECK(ioctl(Frontend(), FE_DISEQC_SEND_MASTER_CMD, &cmd));
}
void cDiseqcPositioner::Drive(ePositionerDirection Direction)
{
uint8_t Code[] = { uint8_t(Direction == pdLeft ? 0x68 : 0x69), 0x00 };
SendDiseqc(Code, 2);
}
void cDiseqcPositioner::Step(ePositionerDirection Direction, uint Steps)
{
if (Steps == 0)
return;
uint8_t Code[] = { uint8_t(Direction == pdLeft ? 0x68 : 0x69), 0xFF };
Code[1] -= min(Steps, uint(0x7F)) - 1;
SendDiseqc(Code, 2);
}
void cDiseqcPositioner::Halt(void)
{
uint8_t Code[] = { 0x60 };
SendDiseqc(Code, 1);
}
void cDiseqcPositioner::SetLimit(ePositionerDirection Direction)
{
uint8_t Code[] = { uint8_t(Direction == pdLeft ? 0x66 : 0x67) };
SendDiseqc(Code, 1);
}
void cDiseqcPositioner::DisableLimits(void)
{
uint8_t Code[] = { 0x63 };
SendDiseqc(Code, 1);
}
void cDiseqcPositioner::EnableLimits(void)
{
uint8_t Code[] = { 0x6A, 0x00 };
SendDiseqc(Code, 2);
}
void cDiseqcPositioner::StorePosition(uint Number)
{
uint8_t Code[] = { 0x6A, uint8_t(Number) };
SendDiseqc(Code, 2);
}
void cDiseqcPositioner::RecalcPositions(uint Number)
{
uint8_t Code[] = { 0x6F, uint8_t(Number), 0x00, 0x00 };
SendDiseqc(Code, 4);
}
void cDiseqcPositioner::GotoPosition(uint Number, int Longitude)
{
uint8_t Code[] = { 0x6B, uint8_t(Number) };
SendDiseqc(Code, 2);
cPositioner::GotoPosition(Number, Longitude);
}
void cDiseqcPositioner::GotoAngle(int Longitude)
{
uint8_t Code[] = { 0x6E, 0x00, 0x00 };
int Angle = CalcHourAngle(Longitude);
int a = abs(Angle);
Code[1] = a / 10 / 16;
Code[2] = a / 10 % 16 * 16 + a % 10 * 16 / 10;
Code[1] |= (Angle < 0) ? 0xE0 : 0xD0;
SendDiseqc(Code, 3);
cPositioner::GotoAngle(Longitude);
}
// --- cScr ------------------------------------------------------------------
cScr::cScr(void)
@ -44,10 +158,9 @@ cScr::cScr(void)
bool cScr::Parse(const char *s)
{
if (!ParseDeviceNumbers(s, devices))
return false;
if (devices)
return true;
if (IsDeviceNumbers(s))
return ParseDeviceNumbers(s);
devices = CurrentDevices;
bool result = false;
int fields = sscanf(s, "%d %u %d", &channel, &userBand, &pin);
if (fields == 2 || fields == 3) {
@ -68,16 +181,17 @@ bool cScr::Parse(const char *s)
cScrs Scrs;
bool cScrs::Load(const char *FileName, bool AllowComments, bool MustExist)
{
CurrentDevices = ALL_DEVICES;
return cConfig<cScr>::Load(FileName, AllowComments, MustExist);
}
cScr *cScrs::GetUnused(int Device)
{
cMutexLock MutexLock(&mutex);
int Devices = 0;
for (cScr *p = First(); p; p = Next(p)) {
if (p->Devices()) {
Devices = p->Devices();
continue;
}
if (Devices && !(Devices & (1 << Device - 1)))
if (!IsBitSet(p->Devices(), Device - 1))
continue;
if (!p->Used()) {
p->SetUsed(true);
@ -96,6 +210,7 @@ cDiseqc::cDiseqc(void)
slof = 0;
polarization = 0;
lof = 0;
position = -1;
scrBank = -1;
commands = NULL;
parsing = false;
@ -108,10 +223,9 @@ cDiseqc::~cDiseqc()
bool cDiseqc::Parse(const char *s)
{
if (!ParseDeviceNumbers(s, devices))
return false;
if (devices)
return true;
if (IsDeviceNumbers(s))
return ParseDeviceNumbers(s);
devices = CurrentDevices;
bool result = false;
char *sourcebuf = NULL;
int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands);
@ -178,6 +292,28 @@ const char *cDiseqc::Wait(const char *s) const
return NULL;
}
const char *cDiseqc::GetPosition(const char *s) const
{
if (!*s || !isdigit(*s)) {
position = 0;
return s;
}
char *p = NULL;
errno = 0;
int n = strtol(s, &p, 10);
if (!errno && p != s && n >= 0 && n < 0xFF) {
if (parsing) {
if (position < 0)
position = n;
else
esyslog("ERROR: more than one position in '%s'", s - 1);
}
return p;
}
esyslog("ERROR: invalid satellite position in '%s'", s - 1);
return NULL;
}
const char *cDiseqc::GetScrBank(const char *s) const
{
char *p = NULL;
@ -250,8 +386,12 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
case 'V': return daVoltage18;
case 'A': return daMiniA;
case 'B': return daMiniB;
case 'W': *CurrentAction = Wait(*CurrentAction); break;
case 'S': *CurrentAction = GetScrBank(*CurrentAction); break;
case 'W': *CurrentAction = Wait(*CurrentAction); return daWait;
case 'P': *CurrentAction = GetPosition(*CurrentAction);
if (Setup.UsePositioner)
return position ? daPositionN : daPositionA;
break;
case 'S': *CurrentAction = GetScrBank(*CurrentAction); return daScr;
case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes);
if (*CurrentAction) {
if (Scr && Frequency) {
@ -261,7 +401,8 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
return daCodes;
}
break;
default: return daNone;
default: esyslog("ERROR: unknown diseqc code '%c'", *(*CurrentAction - 1));
return daNone;
}
}
return daNone;
@ -271,17 +412,18 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Code
cDiseqcs Diseqcs;
bool cDiseqcs::Load(const char *FileName, bool AllowComments, bool MustExist)
{
CurrentDevices = ALL_DEVICES;
return cConfig<cDiseqc>::Load(FileName, AllowComments, MustExist);
}
const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const
{
int Devices = 0;
for (const cDiseqc *p = First(); p; p = Next(p)) {
if (p->Devices()) {
Devices = p->Devices();
if (!IsBitSet(p->Devices(), Device - 1))
continue;
}
if (Devices && !(Devices & (1 << Device - 1)))
continue;
if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) {
if (cSource::Matches(p->Source(), Source) && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) {
if (p->IsScr() && Scr && !*Scr) {
*Scr = Scrs.GetUnused(Device);
if (*Scr)

View File

@ -5,6 +5,9 @@
# satellite slof polarization lof command...
#
# satellite: one of the 'S' codes defined in sources.conf
# the special value 'S360E' means that this entry uses a positioner
# (command 'P') that can move the dish to any requested satellite
# position withing its range
# slof: switch frequency of LNB; the first entry with
# an slof greater than the actual transponder
# frequency will be used
@ -18,7 +21,9 @@
# V voltage high (18V)
# A mini A
# B mini B
# Sn Satellite channel routing code sequence for bank n follows
# Pn use positioner to move dish to satellite position n (or to the
# satellite's orbital position, if no position number is given)
# Sn satellite channel routing code sequence for bank n follows
# Wnn wait nn milliseconds (nn may be any positive integer number)
# [xx ...] hex code sequence (max. 6)
#
@ -88,3 +93,10 @@ S13.0E 99999 H 10600 t V W15 [E0 10 38 F7] W15 B W15 T
# S13.0E 99999 V 10600 t V W10 S5 [E0 10 5A 00 00] W10 v
# S13.0E 11700 H 9750 t V W10 S6 [E0 10 5A 00 00] W10 v
# S13.0E 99999 H 10600 t V W10 S7 [E0 10 5A 00 00] W10 v
#
# Positioner for steerable dish:
#
# S360E 11700 V 9750 t V W20 P W20 t v
# S360E 99999 V 10600 t V W20 P W20 T v
# S360E 11700 H 9750 t V W20 P W20 t V
# S360E 99999 H 10600 t V W20 P W20 T V

View File

@ -4,15 +4,33 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: diseqc.h 2.5 2011/09/17 13:15:17 kls Exp $
* $Id: diseqc.h 3.1 2013/06/12 11:52:17 kls Exp $
*/
#ifndef __DISEQC_H
#define __DISEQC_H
#include "config.h"
#include "positioner.h"
#include "thread.h"
class cDiseqcPositioner : public cPositioner {
private:
void SendDiseqc(uint8_t *Codes, int NumCodes);
public:
cDiseqcPositioner(void);
virtual void Drive(ePositionerDirection Direction);
virtual void Step(ePositionerDirection Direction, uint Steps = 1);
virtual void Halt(void);
virtual void SetLimit(ePositionerDirection Direction);
virtual void DisableLimits(void);
virtual void EnableLimits(void);
virtual void StorePosition(uint Number);
virtual void RecalcPositions(uint Number);
virtual void GotoPosition(uint Number, int Longitude);
virtual void GotoAngle(int Longitude);
};
class cScr : public cListObject {
private:
int devices;
@ -35,6 +53,7 @@ class cScrs : public cConfig<cScr> {
private:
cMutex mutex;
public:
bool Load(const char *FileName, bool AllowComments = false, bool MustExist = false);
cScr *GetUnused(int Device);
};
@ -50,8 +69,11 @@ public:
daVoltage18,
daMiniA,
daMiniB,
daPositionN,
daPositionA,
daScr,
daCodes,
daWait,
};
enum { MaxDiseqcCodes = 6 };
private:
@ -60,12 +82,14 @@ private:
int slof;
char polarization;
int lof;
mutable int position;
mutable int scrBank;
char *commands;
bool parsing;
uint SetScrFrequency(uint SatFrequency, const cScr *Scr, uint8_t *Codes) const;
int SetScrPin(const cScr *Scr, uint8_t *Codes) const;
const char *Wait(const char *s) const;
const char *GetPosition(const char *s) const;
const char *GetScrBank(const char *s) const;
const char *GetCodes(const char *s, uchar *Codes = NULL, uint8_t *MaxCodes = NULL) const;
public:
@ -89,16 +113,31 @@ public:
///< Frequency must be the frequency the tuner will be tuned to, and will be
///< set to the proper SCR frequency upon return (if SCR is used).
int Devices(void) const { return devices; }
///< Returns an integer where each bit represents one of the system's devices.
///< If a bit is set, this DiSEqC sequence applies to the corresponding device.
int Source(void) const { return source; }
///< Returns the satellite source this DiSEqC sequence applies to.
int Slof(void) const { return slof; }
///< Returns the switch frequency of the LNB this DiSEqC sequence applies to.
char Polarization(void) const { return polarization; }
///< Returns the signal polarization this DiSEqC sequence applies to.
int Lof(void) const { return lof; }
bool IsScr() const { return scrBank >= 0; }
///< Returns the local oscillator frequency of the LNB this DiSEqC sequence applies to.
int Position(void) const { return position; }
///< Indicates which positioning mode to use in order to move the dish to a given
///< satellite position. -1 means "no positioning" (i.e. fixed dish); 0 means the
///< positioner can be moved to any arbitrary satellite position (within its
///< limits); and a positive number means "move the dish to the position stored
///< under the given number".
bool IsScr(void) const { return scrBank >= 0; }
///< Returns true if this DiSEqC sequence uses Satellite Channel Routing.
const char *Commands(void) const { return commands; }
///< Returns a pointer to the actual commands of this DiSEqC sequence.
};
class cDiseqcs : public cConfig<cDiseqc> {
public:
bool Load(const char *FileName, bool AllowComments = false, bool MustExist = false);
const cDiseqc *Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const;
///< Selects a DiSEqC entry suitable for the given Device and tuning parameters.
///< If this DiSEqC entry requires SCR and the given *Scr is NULL

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbdevice.c 3.1 2013/04/08 22:13:35 kls Exp $
* $Id: dvbdevice.c 3.2 2013/08/17 13:52:05 kls Exp $
*/
#include "dvbdevice.h"
@ -284,7 +284,7 @@ bool cDvbTransponderParameters::Parse(const char *s)
class cDvbTuner : public cThread {
private:
static cMutex bondMutex;
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
enum eTunerStatus { tsIdle, tsSet, tsPositioning, tsTuned, tsLocked };
int frontendType;
const cDvbDevice *device;
int fd_frontend;
@ -295,6 +295,9 @@ private:
time_t lastTimeoutReport;
cChannel channel;
const cDiseqc *lastDiseqc;
int diseqcOffset;
int lastSource;
cPositioner *positioner;
const cScr *scr;
bool lnbPowerTurnedOn;
eTunerStatus tunerStatus;
@ -309,6 +312,7 @@ private:
bool IsBondedMaster(void) const { return !bondedTuner || bondedMaster; }
void ClearEventQueue(void) const;
bool GetFrontendStatus(fe_status_t &Status) const;
cPositioner *GetPositioner(void);
void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency);
void ResetToneAndVoltage(void);
bool SetFrontend(void);
@ -325,6 +329,7 @@ public:
bool IsTunedTo(const cChannel *Channel) const;
void SetChannel(const cChannel *Channel);
bool Locked(int TimeoutMs = 0);
const cPositioner *Positioner(void) const { return positioner; }
int GetSignalStrength(void) const;
int GetSignalQuality(void) const;
};
@ -343,6 +348,9 @@ cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int
lockTimeout = 0;
lastTimeoutReport = 0;
lastDiseqc = NULL;
diseqcOffset = 0;
lastSource = 0;
positioner = NULL;
scr = NULL;
lnbPowerTurnedOn = false;
tunerStatus = tsIdle;
@ -482,6 +490,7 @@ void cDvbTuner::SetChannel(const cChannel *Channel)
cMutexLock MutexLock(&mutex);
if (!IsTunedTo(Channel))
tunerStatus = tsSet;
diseqcOffset = 0;
channel = *Channel;
lastTimeoutReport = 0;
newSet.Broadcast();
@ -662,6 +671,15 @@ static unsigned int FrequencyToHz(unsigned int f)
return f;
}
cPositioner *cDvbTuner::GetPositioner(void)
{
if (!positioner) {
positioner = cPositioner::GetPositioner();
positioner->SetFrontend(fd_frontend);
}
return positioner;
}
void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency)
{
if (!lnbPowerTurnedOn) {
@ -673,23 +691,47 @@ void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency)
Mutex.Lock();
struct dvb_diseqc_master_cmd cmd;
const char *CurrentAction = NULL;
for (;;) {
cPositioner *Positioner = NULL;
bool Break = false;
for (int i = 0; !Break; i++) {
cmd.msg_len = sizeof(cmd.msg);
cDiseqc::eDiseqcActions da = Diseqc->Execute(&CurrentAction, cmd.msg, &cmd.msg_len, scr, Frequency);
if (da == cDiseqc::daNone)
if (da == cDiseqc::daNone) {
diseqcOffset = 0;
break;
}
bool d = i >= diseqcOffset;
switch (da) {
case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
case cDiseqc::daCodes: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
case cDiseqc::daToneOff: if (d) CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
case cDiseqc::daToneOn: if (d) CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
case cDiseqc::daVoltage13: if (d) CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
case cDiseqc::daVoltage18: if (d) CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
case cDiseqc::daMiniA: if (d) CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
case cDiseqc::daMiniB: if (d) CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
case cDiseqc::daCodes: if (d) CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
case cDiseqc::daPositionN: if ((Positioner = GetPositioner()) != NULL) {
if (d) {
Positioner->GotoPosition(Diseqc->Position(), cSource::Position(channel.Source()));
Break = Positioner->IsMoving();
}
}
break;
case cDiseqc::daPositionA: if ((Positioner = GetPositioner()) != NULL) {
if (d) {
Positioner->GotoAngle(cSource::Position(channel.Source()));
Break = Positioner->IsMoving();
}
}
break;
case cDiseqc::daScr:
case cDiseqc::daWait: break;
default: esyslog("ERROR: unknown diseqc command %d", da);
}
if (Break)
diseqcOffset = i + 1;
}
if (scr)
positioner = Positioner;
if (scr && !Break)
ResetToneAndVoltage(); // makes sure we don't block the bus!
if (Diseqc->IsScr())
Mutex.Unlock();
@ -752,7 +794,7 @@ bool cDvbTuner::SetFrontend(void)
if (Setup.DiSEqC) {
if (const cDiseqc *diseqc = Diseqcs.Get(device->CardIndex() + 1, channel.Source(), frequency, dtp.Polarization(), &scr)) {
frequency -= diseqc->Lof();
if (diseqc != lastDiseqc || diseqc->IsScr()) {
if (diseqc != lastDiseqc || diseqc->IsScr() || diseqc->Position() >= 0 && channel.Source() != lastSource) {
if (IsBondedMaster()) {
ExecuteDiseqc(diseqc, &frequency);
if (frequency == 0)
@ -761,6 +803,7 @@ bool cDvbTuner::SetFrontend(void)
else
ResetToneAndVoltage();
lastDiseqc = diseqc;
lastSource = channel.Source();
}
}
else {
@ -877,15 +920,30 @@ void cDvbTuner::Action(void)
int WaitTime = 1000;
switch (tunerStatus) {
case tsIdle:
break;
break; // we want the TimedWait() below!
case tsSet:
tunerStatus = SetFrontend() ? tsTuned : tsIdle;
Timer.Set(tuneTimeout + (scr ? rand() % SCR_RANDOM_TIMEOUT : 0));
tunerStatus = SetFrontend() ? tsPositioning : tsIdle;
continue;
case tsPositioning:
if (positioner) {
if (positioner->IsMoving())
break; // we want the TimedWait() below!
else if (diseqcOffset) {
lastDiseqc = NULL;
tunerStatus = tsSet; // have it process the rest of the DiSEqC sequence
continue;
}
}
tunerStatus = tsTuned;
Timer.Set(tuneTimeout + (scr ? rand() % SCR_RANDOM_TIMEOUT : 0));
if (positioner)
continue;
// otherwise run directly into tsTuned...
case tsTuned:
if (Timer.TimedOut()) {
tunerStatus = tsSet;
lastDiseqc = NULL;
lastSource = 0;
if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these
isyslog("frontend %d/%d timed out while tuning to channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder());
lastTimeoutReport = time(NULL);
@ -893,10 +951,12 @@ void cDvbTuner::Action(void)
continue;
}
WaitTime = 100; // allows for a quick change from tsTuned to tsLocked
// run into tsLocked...
case tsLocked:
if (Status & FE_REINIT) {
tunerStatus = tsSet;
lastDiseqc = NULL;
lastSource = 0;
isyslog("frontend %d/%d was reinitialized", adapter, frontend);
lastTimeoutReport = 0;
continue;
@ -1357,7 +1417,7 @@ void cDvbDevice::UnBond(void)
bool cDvbDevice::BondingOk(const cChannel *Channel, bool ConsiderOccupied) const
{
cMutexLock MutexLock(&bondMutex);
if (bondedDevice)
if (bondedDevice || Positioner())
return dvbTuner && dvbTuner->BondingOk(Channel, ConsiderOccupied);
return true;
}
@ -1539,6 +1599,11 @@ int cDvbDevice::NumProvidedSystems(void) const
return numDeliverySystems + numModulations;
}
const cPositioner *cDvbDevice::Positioner(void) const
{
return dvbTuner ? dvbTuner->Positioner() : NULL;
}
int cDvbDevice::SignalStrength(void) const
{
return dvbTuner ? dvbTuner->GetSignalStrength() : -1;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbdevice.h 3.1 2013/04/08 22:13:35 kls Exp $
* $Id: dvbdevice.h 3.2 2013/06/01 11:36:18 kls Exp $
*/
#ifndef __DVBDEVICE_H
@ -233,6 +233,7 @@ public:
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = IDLEPRIORITY, bool *NeedsDetachReceivers = NULL) const;
virtual bool ProvidesEIT(void) const;
virtual int NumProvidedSystems(void) const;
virtual const cPositioner *Positioner(void) const;
virtual int SignalStrength(void) const;
virtual int SignalQuality(void) const;
virtual const cChannel *GetCurrentlyTunedTransponder(void) const;

30
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 3.2 2013/04/27 10:25:51 kls Exp $
* $Id: menu.c 3.3 2013/08/21 10:45:11 kls Exp $
*/
#include "menu.h"
@ -2971,6 +2971,14 @@ void cMenuSetupLNB::Setup(void)
}
}
Add(new cMenuEditBoolItem(tr("Setup.LNB$Use dish positioner"), &data.UsePositioner));
if (data.UsePositioner) {
Add(new cMenuEditIntxItem(tr("Setup.LNB$Site latitude (degrees)"), &data.SiteLat, -900, 900, 10, tr("South"), tr("North")));
Add(new cMenuEditIntxItem(tr("Setup.LNB$Site longitude (degrees)"), &data.SiteLon, -1800, 1800, 10, tr("West"), tr("East")));
Add(new cMenuEditIntxItem(tr("Setup.LNB$Max. positioner swing (degrees)"), &data.PositionerSwing, 0, 900, 10));
Add(new cMenuEditIntxItem(tr("Setup.LNB$Positioner speed (degrees/s)"), &data.PositionerSpeed, 1, 1800, 10));
}
SetCurrent(Get(current));
Display();
}
@ -2978,6 +2986,7 @@ void cMenuSetupLNB::Setup(void)
eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
{
int oldDiSEqC = data.DiSEqC;
int oldUsePositioner = data.UsePositioner;
bool DeviceBondingsChanged = false;
if (Key == kOk) {
cString NewDeviceBondings = satCableNumbers.ToString();
@ -2986,7 +2995,7 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
}
eOSState state = cMenuSetupBase::ProcessKey(Key);
if (Key != kNone && data.DiSEqC != oldDiSEqC)
if (Key != kNone && (data.DiSEqC != oldDiSEqC || data.UsePositioner != oldUsePositioner))
Setup();
else if (DeviceBondingsChanged)
cDvbDevice::BondDevices(data.DeviceBondings);
@ -3625,6 +3634,7 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched)
displayChannel = Skins.Current()->DisplayChannel(withInfo);
number = 0;
timeout = Switched || Setup.TimeoutRequChInfo;
positioner = NULL;
channel = Channels.GetByNumber(Number);
lastPresent = lastFollowing = NULL;
if (channel) {
@ -3646,6 +3656,7 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey)
lastTime.Set();
withInfo = Setup.ShowInfoOnChSwitch;
displayChannel = Skins.Current()->DisplayChannel(withInfo);
positioner = NULL;
channel = Channels.GetByNumber(cDevice::CurrentChannel());
ProcessKey(FirstKey);
}
@ -3853,7 +3864,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
return osEnd;
}
};
if (!timeout || lastTime.Elapsed() < (uint64_t)(Setup.ChannelInfoTime * 1000)) {
if (positioner || !timeout || lastTime.Elapsed() < (uint64_t)(Setup.ChannelInfoTime * 1000)) {
if (Key == kNone && !number && group < 0 && !NewChannel && channel && channel->Number() != cDevice::CurrentChannel()) {
// makes sure a channel switch through the SVDRP CHAN command is displayed
channel = Channels.GetByNumber(cDevice::CurrentChannel());
@ -3861,13 +3872,24 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
lastTime.Set();
}
DisplayInfo();
displayChannel->Flush();
if (NewChannel) {
SetTrackDescriptions(NewChannel->Number()); // to make them immediately visible in the channel display
Channels.SwitchTo(NewChannel->Number());
SetTrackDescriptions(NewChannel->Number()); // switching the channel has cleared them
channel = NewChannel;
}
const cPositioner *Positioner = cDevice::ActualDevice()->Positioner();
bool PositionerMoving = Positioner && Positioner->IsMoving();
SetNeedsFastResponse(PositionerMoving);
if (!PositionerMoving) {
if (positioner)
lastTime.Set(); // to keep the channel display up a few seconds after the target position has been reached
Positioner = NULL;
}
if (Positioner || positioner) // making sure we call SetPositioner(NULL) if there is a switch from "with" to "without" positioner
displayChannel->SetPositioner(Positioner);
positioner = Positioner;
displayChannel->Flush();
return osContinue;
}
return osEnd;

3
menu.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.h 2.13 2012/12/07 13:44:13 kls Exp $
* $Id: menu.h 3.1 2013/06/01 13:44:57 kls Exp $
*/
#ifndef __MENU_H
@ -120,6 +120,7 @@ private:
cTimeMs lastTime;
int number;
bool timeout;
const cPositioner *positioner;
cChannel *channel;
const cEvent *lastPresent;
const cEvent *lastFollowing;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menuitems.c 2.16 2013/02/15 14:20:29 kls Exp $
* $Id: menuitems.c 3.1 2013/05/24 10:26:01 kls Exp $
*/
#include "menuitems.h"
@ -51,14 +51,14 @@ void cMenuEditItem::SetHelp(const char *Red, const char *Green, const char *Yell
helpDisplayed = false;
}
bool cMenuEditItem::DisplayHelp(void)
bool cMenuEditItem::DisplayHelp(bool Current)
{
bool HasHelp = helpRed || helpGreen || helpYellow || helpBlue;
if (HasHelp && !helpDisplayed) {
if (HasHelp && !helpDisplayed && Current) {
cSkinDisplay::Current()->SetButtons(helpRed, helpGreen, helpYellow, helpBlue);
cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
helpDisplayed = true;
}
helpDisplayed = Current;
return HasHelp;
}
@ -223,6 +223,50 @@ eOSState cMenuEditNumItem::ProcessKey(eKeys Key)
return state;
}
// --- cMenuEditIntxItem -----------------------------------------------------
cMenuEditIntxItem::cMenuEditIntxItem(const char *Name, int *Value, int Min, int Max, int Factor, const char *NegString, const char *PosString)
:cMenuEditIntItem(Name, Value, Min, Max)
{
factor = ::max(Factor, 1);
negString = NegString;
posString = PosString;
Set();
}
void cMenuEditIntxItem::SetHelpKeys(void)
{
if (negString && posString)
SetHelp(NULL, (*value < 0) ? posString : negString);
}
void cMenuEditIntxItem::Set(void)
{
const char *s = (*value < 0) ? negString : posString;
int v = *value;
if (negString && posString)
v = abs(v);
SetValue(cString::sprintf(s ? "%.*f %s" : "%.*f", factor / 10, double(v) / factor, s));
SetHelpKeys();
}
eOSState cMenuEditIntxItem::ProcessKey(eKeys Key)
{
eOSState state = cMenuEditIntItem::ProcessKey(Key);
if (state == osUnknown) {
switch (Key) {
case kGreen: if (negString && posString) {
*value = -*value;
Set();
state = osContinue;
}
break;
default: ;
}
}
return state;
}
// --- cMenuEditPrcItem ------------------------------------------------------
cMenuEditPrcItem::cMenuEditPrcItem(const char *Name, double *Value, double Min, double Max, int Decimals)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menuitems.h 2.8 2012/03/13 11:19:11 kls Exp $
* $Id: menuitems.h 3.1 2013/05/24 10:19:55 kls Exp $
*/
#ifndef __MENUITEMS_H
@ -27,7 +27,7 @@ public:
cMenuEditItem(const char *Name);
~cMenuEditItem();
void SetValue(const char *Value);
bool DisplayHelp(void);
bool DisplayHelp(bool Current);
};
class cMenuEditIntItem : public cMenuEditItem {
@ -70,6 +70,17 @@ public:
virtual eOSState ProcessKey(eKeys Key);
};
class cMenuEditIntxItem : public cMenuEditIntItem {
private:
int factor;
const char *negString, *posString;
void SetHelpKeys(void);
virtual void Set(void);
public:
cMenuEditIntxItem(const char *Name, int *Value, int Min = INT_MIN, int Max = INT_MAX, int Factor = 1, const char *NegString = NULL, const char *PosString = NULL);
virtual eOSState ProcessKey(eKeys Key);
};
class cMenuEditPrcItem : public cMenuEditItem {
protected:
double *value;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osdbase.c 2.7 2012/12/07 09:50:47 kls Exp $
* $Id: osdbase.c 3.1 2013/05/24 10:19:31 kls Exp $
*/
#include "osdbase.h"
@ -286,7 +286,7 @@ void cOsdMenu::DisplayCurrent(bool Current)
if (!Current)
item->SetFresh(true); // leaving the current item resets 'fresh'
if (cMenuEditItem *MenuEditItem = dynamic_cast<cMenuEditItem *>(item)) {
if (!MenuEditItem->DisplayHelp())
if (!MenuEditItem->DisplayHelp(Current))
DisplayHelp();
else
helpDisplayed = false;

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-02-03 16:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2008-10-16 11:16-0400\n"
"Last-Translator: Osama Alrawab <alrawab@hotmail.com>\n"
"Language-Team: Arabic <ar@li.org>\n"
@ -997,6 +997,33 @@ msgstr "Device %d connected to sat cable"
msgid "Setup.LNB$own"
msgstr "own"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "اعادة تشغيل الكامة"
@ -1334,6 +1361,10 @@ msgstr "بث حى"
msgid "PLAY"
msgstr "عرض"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG شاشة "

View File

@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2008-03-02 19:02+0100\n"
"Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
"Language-Team: Catalan <vdr@linuxtv.org>\n"
@ -996,6 +996,33 @@ msgstr "Dispositiu %d connectat a cable sat
msgid "Setup.LNB$own"
msgstr "propi"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Reiniciar CAM"
@ -1333,6 +1360,10 @@ msgstr "EN DIRECTE"
msgid "PLAY"
msgstr "REPRODUIR"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "Quadres ST:TNG"

View File

@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2010-05-06 11:00+0200\n"
"Last-Translator: Aleš Juřík <ajurik@quick.cz>\n"
"Language-Team: Czech <vdr@linuxtv.org>\n"
@ -996,6 +996,33 @@ msgstr "Zařízení %d připojeno k sat. kabelu"
msgid "Setup.LNB$own"
msgstr "vlastní"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Reset CAMu"
@ -1333,6 +1360,10 @@ msgstr "ŽIVĚ"
msgid "PLAY"
msgstr "PŘEHRÁVÁNÍ"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG konzola"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
"Language-Team: Danish <vdr@linuxtv.org>\n"
@ -993,6 +993,33 @@ msgstr ""
msgid "Setup.LNB$own"
msgstr ""
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM nulstil"
@ -1330,6 +1357,10 @@ msgstr ""
msgid "PLAY"
msgstr ""
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG konsol"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2010-01-16 16:46+0100\n"
"Last-Translator: Klaus Schmidinger <vdr@tvdr.de>\n"
"Language-Team: German <vdr@linuxtv.org>\n"
@ -993,6 +993,33 @@ msgstr "Device %d angeschlossen an Sat-Kabel"
msgid "Setup.LNB$own"
msgstr "eigenes"
msgid "Setup.LNB$Use dish positioner"
msgstr "Antennen-Positionierer benutzen"
msgid "Setup.LNB$Site latitude (degrees)"
msgstr "Standort Längengrad"
msgid "South"
msgstr "Süd"
msgid "North"
msgstr "Nord"
msgid "Setup.LNB$Site longitude (degrees)"
msgstr "Standort Breitengrad"
msgid "West"
msgstr "West"
msgid "East"
msgstr "Ost"
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr "Max. Positionier-Winkel (Grad)"
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr "Max. Positionier-Geschwindigkeit (Grad/s)"
msgid "CAM reset"
msgstr "CAM zurückgesetzt"
@ -1330,6 +1357,10 @@ msgstr "LIVE"
msgid "PLAY"
msgstr "WIEDERGABE"
#, c-format
msgid "Moving dish to %.1f..."
msgstr "Antenne wird auf %.1f gedreht..."
msgid "ST:TNG Panels"
msgstr "ST:TNG-Konsolen"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
"Language-Team: Greek <vdr@linuxtv.org>\n"
@ -993,6 +993,33 @@ msgstr ""
msgid "Setup.LNB$own"
msgstr ""
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr ""
@ -1330,6 +1357,10 @@ msgstr ""
msgid "PLAY"
msgstr ""
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ÌïñöÝò ST:TNG"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2008-03-02 19:02+0100\n"
"Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
"Language-Team: Spanish <vdr@linuxtv.org>\n"
@ -994,6 +994,33 @@ msgstr "Dispositivo %d conectado a cable sat
msgid "Setup.LNB$own"
msgstr "propio"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Reset CAM"
@ -1331,6 +1358,10 @@ msgstr "EN DIRECTO"
msgid "PLAY"
msgstr "REPRODUCIR"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "Paneles ST:TNG"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
"Language-Team: Estonian <vdr@linuxtv.org>\n"
@ -993,6 +993,33 @@ msgstr "DVB seade %d ühendatud SAT-kaabliga"
msgid "Setup.LNB$own"
msgstr "oma"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM taaskäivitamine"
@ -1330,6 +1357,10 @@ msgstr "LIVE"
msgid "PLAY"
msgstr "ESITUS"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG Panels"

View File

@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2007-08-15 15:52+0200\n"
"Last-Translator: Matti Lehtimäki <matti.lehtimaki@gmail.com>\n"
"Language-Team: Finnish <vdr@linuxtv.org>\n"
@ -997,6 +997,33 @@ msgstr "DVB-sovitin %d kytketty SAT-kaapeliin"
msgid "Setup.LNB$own"
msgstr "oma"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM nollaus"
@ -1334,6 +1361,10 @@ msgstr "LIVE"
msgid "PLAY"
msgstr "TOISTO"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG konsoli"

View File

@ -17,7 +17,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-02-24 12:56+0100\n"
"Last-Translator: Dominique Plu <dplu@free.fr>\n"
"Language-Team: French <vdr@linuxtv.org>\n"
@ -1003,6 +1003,33 @@ msgstr "Le périphérique %d est connecté au câble satellite"
msgid "Setup.LNB$own"
msgstr "Propriétaire"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM réinitialisé"
@ -1340,6 +1367,10 @@ msgstr "DIRECT"
msgid "PLAY"
msgstr "LECTURE"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "Consoles ST:TNG"

View File

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2008-03-17 19:00+0100\n"
"Last-Translator: Adrian Caval <anrxc@sysphere.org>\n"
"Language-Team: Croatian <vdr@linuxtv.org>\n"
@ -995,6 +995,33 @@ msgstr ""
msgid "Setup.LNB$own"
msgstr ""
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Ponovno pokreni CAM"
@ -1332,6 +1359,10 @@ msgstr ""
msgid "PLAY"
msgstr ""
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG Panele"

View File

@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-03-01 19:22+0200\n"
"Last-Translator: István Füley <ifuley@tigercomp.ro>\n"
"Language-Team: Hungarian <vdr@linuxtv.org>\n"
@ -997,6 +997,33 @@ msgstr "Fejkábel a %d. tunerhez"
msgid "Setup.LNB$own"
msgstr "saját"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM újraindítás"
@ -1334,6 +1361,10 @@ msgstr "ÉLŐ"
msgid "PLAY"
msgstr "LEJÁTSZÁS"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG Konzol"

View File

@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-02-11 23:46+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: Italian <vdr@linuxtv.org>\n"
@ -1000,6 +1000,33 @@ msgstr "Periferica %d connessa al cavo sat"
msgid "Setup.LNB$own"
msgstr "propria"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Reimposta la CAM"
@ -1337,6 +1364,10 @@ msgstr "DAL VIVO"
msgid "PLAY"
msgstr "RIPRODUCI"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "Consolle ST:TNG"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2010-10-30 11:55+0200\n"
"Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
"Language-Team: Lithuanian <vdr@linuxtv.org>\n"
@ -993,6 +993,33 @@ msgstr "Įrenginys %d prijungtas prie sat kabelio"
msgid "Setup.LNB$own"
msgstr "savas"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Dekodavimo modulis (CAM) perkrautas"
@ -1330,6 +1357,10 @@ msgstr "GYVAI"
msgid "PLAY"
msgstr "GROTI"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG Skydeliai"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2012-11-19 15:18+0100\n"
"Last-Translator: Dimitar Petrovski <dimeptr@gmail.com>\n"
"Language-Team: Macedonian <en@li.org>\n"
@ -994,6 +994,33 @@ msgstr "Уред %d поврзан со сателитски кабел"
msgid "Setup.LNB$own"
msgstr "свој"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Рестартирај CAM"
@ -1331,6 +1358,10 @@ msgstr "ЖИВО"
msgid "PLAY"
msgstr "ПУШТИ"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG Панели"

View File

@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2008-02-26 17:20+0100\n"
"Last-Translator: Cedric Dewijs <cedric.dewijs@telfort.nl>\n"
"Language-Team: Dutch <vdr@linuxtv.org>\n"
@ -998,6 +998,33 @@ msgstr "Apparaat %d verbionden met sat. kabel"
msgid "Setup.LNB$own"
msgstr "eigen"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM herstarten"
@ -1335,6 +1362,10 @@ msgstr "LIVE"
msgid "PLAY"
msgstr "AFSPELEN"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG Consoles"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2007-08-12 14:17+0200\n"
"Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
"Language-Team: Norwegian Nynorsk <vdr@linuxtv.org>\n"
@ -994,6 +994,33 @@ msgstr ""
msgid "Setup.LNB$own"
msgstr ""
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr ""
@ -1331,6 +1358,10 @@ msgstr ""
msgid "PLAY"
msgstr ""
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr ""

View File

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2008-03-09 12:59+0100\n"
"Last-Translator: Marek Nazarko <mnazarko@gmail.com>\n"
"Language-Team: Polish <vdr@linuxtv.org>\n"
@ -995,6 +995,33 @@ msgstr "Urz
msgid "Setup.LNB$own"
msgstr "W³asny"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM zresetowany"
@ -1332,6 +1359,10 @@ msgstr "NA
msgid "PLAY"
msgstr "ODTWARZA"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "Panel ST:TNG"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2010-03-28 22:49+0100\n"
"Last-Translator: Cris Silva <hudokkow@gmail.com>\n"
"Language-Team: Portuguese <vdr@linuxtv.org>\n"
@ -994,6 +994,33 @@ msgstr ""
msgid "Setup.LNB$own"
msgstr ""
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Reiniciar CAM"
@ -1331,6 +1358,10 @@ msgstr ""
msgid "PLAY"
msgstr ""
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "Consola ST:TNG"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-02-09 23:01+0100\n"
"Last-Translator: Lucian Muresan <lucianm@users.sorceforge.net>\n"
"Language-Team: Romanian <vdr@linuxtv.org>\n"
@ -995,6 +995,33 @@ msgstr "Receptorul %d conectat la cablul de satelit"
msgid "Setup.LNB$own"
msgstr "propriu"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Resetare CAM"
@ -1332,6 +1359,10 @@ msgstr "LIVE"
msgid "PLAY"
msgstr "REDARE"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "Cons. ST:TNG"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-03-10 17:13+0100\n"
"Last-Translator: Oleg Roitburd <oroitburd@gmail.com>\n"
"Language-Team: Russian <vdr@linuxtv.org>\n"
@ -994,6 +994,33 @@ msgstr "
msgid "Setup.LNB$own"
msgstr "áÒÞÙ"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM ßÕàÕÓàãÖÕÝ"
@ -1331,6 +1358,10 @@ msgstr "LIVE"
msgid "PLAY"
msgstr "²ÞáßàÞØ×ÒÕÔÕÝØÕ"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG ßÐÝÕÛØ"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-02-03 16:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-03-04 21:24+0100\n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: Slovak <vdr@linuxtv.org>\n"
@ -993,6 +993,33 @@ msgstr "Zariadenie %d je pripojen
msgid "Setup.LNB$own"
msgstr "vlastný"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Resetnutie CAMu"
@ -1330,6 +1357,10 @@ msgstr "NA
msgid "PLAY"
msgstr "PREHRÁVA SA"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG panely"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-03-04 12:46+0100\n"
"Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
"Language-Team: Slovenian <vdr@linuxtv.org>\n"
@ -994,6 +994,33 @@ msgstr "Naprava %d priklju
msgid "Setup.LNB$own"
msgstr "lastni"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Reset CAM-a"
@ -1331,6 +1358,10 @@ msgstr "V
msgid "PLAY"
msgstr "PREDVAJAJ"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG Konsola"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-03-16 15:05+0100\n"
"Last-Translator: Zoran Turalija <zoran.turalija@gmail.com>\n"
"Language-Team: Serbian <vdr@linuxtv.org>\n"
@ -994,6 +994,33 @@ msgstr "Ure
msgid "Setup.LNB$own"
msgstr "sopstven"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Ponovno pokreni CAM"
@ -1331,6 +1358,10 @@ msgstr "U
msgid "PLAY"
msgstr "REPRODUKCIJA"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG paneli"

View File

@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-02-18 17:04+0100\n"
"Last-Translator: Richard Lithvall <r-vdr@boomer.se>\n"
"Language-Team: Swedish <vdr@linuxtv.org>\n"
@ -997,6 +997,33 @@ msgstr "Enhet %d ansluten till satellitkabel"
msgid "Setup.LNB$own"
msgstr "ägare"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM omstart"
@ -1334,6 +1361,10 @@ msgstr "LIVE"
msgid "PLAY"
msgstr "SPELA"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2008-02-28 00:33+0100\n"
"Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n"
"Language-Team: Turkish <vdr@linuxtv.org>\n"
@ -993,6 +993,33 @@ msgstr ""
msgid "Setup.LNB$own"
msgstr ""
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM sýfýrlandý"
@ -1330,6 +1357,10 @@ msgstr ""
msgid "PLAY"
msgstr ""
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG paneli"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-03-04 14:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-02-09 16:00+0100\n"
"Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n"
"Language-Team: Ukrainian <vdr@linuxtv.org>\n"
@ -994,6 +994,33 @@ msgstr "Пристрій %d під’єднано до сателітарног
msgid "Setup.LNB$own"
msgstr "власне"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "Перезавантаження CAM"
@ -1331,6 +1358,10 @@ msgstr "ЕФІР"
msgid "PLAY"
msgstr "ПРОГРАВАННЯ"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG панелі"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: VDR 2.0.0\n"
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
"POT-Creation-Date: 2013-02-03 16:46+0100\n"
"POT-Creation-Date: 2013-06-10 12:16+0200\n"
"PO-Revision-Date: 2013-03-04 14:52+0800\n"
"Last-Translator: NFVDR <nfvdr@live.com>\n"
"Language-Team: Chinese (simplified) <nfvdr@live.com>\n"
@ -995,6 +995,33 @@ msgstr "设备%d卫星连接线"
msgid "Setup.LNB$own"
msgstr "所有"
msgid "Setup.LNB$Use dish positioner"
msgstr ""
msgid "Setup.LNB$Site latitude (degrees)"
msgstr ""
msgid "South"
msgstr ""
msgid "North"
msgstr ""
msgid "Setup.LNB$Site longitude (degrees)"
msgstr ""
msgid "West"
msgstr ""
msgid "East"
msgstr ""
msgid "Setup.LNB$Max. positioner swing (degrees)"
msgstr ""
msgid "Setup.LNB$Positioner speed (degrees/s)"
msgstr ""
msgid "CAM reset"
msgstr "CAM重置"
@ -1332,6 +1359,10 @@ msgstr "现场"
msgid "PLAY"
msgstr "播放"
#, c-format
msgid "Moving dish to %.1f..."
msgstr ""
msgid "ST:TNG Panels"
msgstr "ST:TNG 面板"

140
positioner.c Normal file
View File

@ -0,0 +1,140 @@
/*
* positioner.c: Steerable dish positioning
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* For an explanation (in German) of the theory behind the calculations see
* http://www.vdr-portal.de/board17-developer/board97-vdr-core/p1154305-grundlagen-und-winkelberechnungen-f%C3%BCr-h-h-diseqc-motor-antennenanlagen
*
* $Id: positioner.c 3.1 2013/08/21 11:02:52 kls Exp $
*/
#include "positioner.h"
#include <math.h>
#include "config.h"
#define SAT_EARTH_RATIO 0.1513 // the Earth's radius, divided by the distance from the Earth's center to the satellite
#define SAT_VISIBILITY_LAT 810 // the absolute latitude beyond which no satellite can be seen (degrees * 10)
#define RAD(x) ((x) * M_PI / 1800)
#define DEG(x) ((x) * 1800 / M_PI)
cPositioner *cPositioner::positioner = NULL;
cPositioner::cPositioner(void)
{
capabilities = pcCanNothing;
frontend = -1;
targetLongitude = lastLongitude = Setup.PositionerLastLon;
targetHourAngle = lastHourAngle = CalcHourAngle(lastLongitude);
swingTime = 0;
delete positioner;
positioner = this;
}
cPositioner::~cPositioner()
{
positioner = NULL;
}
int cPositioner::NormalizeAngle(int Angle)
{
while (Angle < -1800)
Angle += 3600;
while (Angle > 1800)
Angle -= 3600;
return Angle;
}
int cPositioner::CalcHourAngle(int Longitude)
{
double Delta = RAD(Longitude - Setup.SiteLon);
double Lat = RAD(Setup.SiteLat);
int Sign = Setup.SiteLat >= 0 ? -1 : 1; // angles to the right are positive, angles to the left are negative
return Sign * round(DEG(atan2(sin(Delta), cos(Delta) - cos(Lat) * SAT_EARTH_RATIO)));
}
int cPositioner::CalcLongitude(int HourAngle)
{
double Lat = RAD(Setup.SiteLat);
double Lon = RAD(Setup.SiteLon);
double Alpha = RAD(HourAngle);
double Delta = Alpha - asin(sin(M_PI - Alpha) * cos(Lat) * SAT_EARTH_RATIO);
int Sign = Setup.SiteLat >= 0 ? 1 : -1;
return NormalizeAngle(round(DEG(Lon - Sign * Delta)));
}
int cPositioner::HorizonLongitude(ePositionerDirection Direction)
{
double Delta;
if (abs(Setup.SiteLat) < SAT_VISIBILITY_LAT)
Delta = acos(SAT_EARTH_RATIO / cos(RAD(Setup.SiteLat)));
else
Delta = RAD(145);
if ((Setup.SiteLat >= 0) != (Direction == pdLeft))
Delta = -Delta;
return NormalizeAngle(round(DEG(RAD(Setup.SiteLon) + Delta)));
}
int cPositioner::HardLimitLongitude(ePositionerDirection Direction) const
{
return CalcLongitude(Direction == pdLeft ? -Setup.PositionerSwing : Setup.PositionerSwing);
}
void cPositioner::StartMovementTimer(int Longitude)
{
if (Setup.PositionerSpeed <= 0)
return;
cMutexLock MutexLock(&mutex);
lastLongitude = CurrentLongitude(); // in case the dish was already in motion
targetLongitude = Longitude;
lastHourAngle = CalcHourAngle(lastLongitude);
targetHourAngle = CalcHourAngle(targetLongitude);
swingTime = abs(targetHourAngle - lastHourAngle) * 1000 / Setup.PositionerSpeed; // time (ms) it takes to move the dish from lastHourAngle to targetHourAngle
movementStart.Set();
Setup.PositionerLastLon = targetLongitude;
}
void cPositioner::GotoPosition(uint Number, int Longitude)
{
if (Longitude != targetLongitude)
dsyslog("moving positioner to position %d, longitude %d", Number, Longitude);
StartMovementTimer(Longitude);
}
void cPositioner::GotoAngle(int Longitude)
{
if (Longitude != targetLongitude)
dsyslog("moving positioner to longitude %d", Longitude);
StartMovementTimer(Longitude);
}
int cPositioner::CurrentLongitude(void) const
{
cMutexLock MutexLock(&mutex);
if (targetLongitude != lastLongitude) {
int Elapsed = movementStart.Elapsed(); // it's important to make this 'int', otherwise the expression below yields funny results
if (swingTime <= Elapsed)
lastLongitude = targetLongitude;
else
return CalcLongitude(lastHourAngle + (targetHourAngle - lastHourAngle) * Elapsed / swingTime);
}
return lastLongitude;
}
bool cPositioner::IsMoving(void) const
{
cMutexLock MutexLock(&mutex);
return CurrentLongitude() != targetLongitude;
}
cPositioner *cPositioner::GetPositioner(void)
{
return positioner;
}
void cPositioner::DestroyPositioner(void)
{
delete positioner;
}

171
positioner.h Normal file
View File

@ -0,0 +1,171 @@
/*
* positioner.h: Steerable dish positioning
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: positioner.h 3.1 2013/06/10 14:27:14 kls Exp $
*/
#ifndef __POSITIONER_H
#define __POSITIONER_H
#include "thread.h"
#include "tools.h"
/// A steerable satellite dish generally points to the south on the northern hemisphere,
/// and to the north on the southern hemisphere (unless you're located directly on the
/// equator, in which case the general direction is "up"). Therefore, moving the dish
/// "east" or "west" means something different on either hemisphere. From the local dish
/// motor's point of view, it makes more sense to speak of turning the dish "left" or
/// "right", which is independent of the actual hemisphere the dish is located in.
/// In the cPositioner class context, when a dish on the northern hemisphere moves "east",
/// it is considered to be moving "left". Imagine standing behind the dish and looking
/// towards the satellites, and clearly "east" is "left". On the southern hemisphere
/// the same move to the "left" would go to the "west". So on the hardware level it is
/// clear what "left" and "right" means. The user interface may present different labels
/// to the viewer, depending on the hemisphere the dish is on.
/// All angles in this context are given in "degrees * 10", which allows for an angular
/// resolution of 0.1 degrees.
class cPositioner {
private:
mutable cMutex mutex;
static cPositioner *positioner;
int capabilities;
int frontend; // file descriptor of the DVB frontend
mutable int lastLongitude; // the longitude the dish has last been moved to
int targetLongitude; // the longitude the dish is supposed to be moved to
mutable int lastHourAngle; // the hour angle the positioner has last been moved to
int targetHourAngle; // the hour angle the positioner is supposed to be moved to
int swingTime;
cTimeMs movementStart;
protected:
cPositioner(void);
virtual ~cPositioner();
void SetCapabilities(int Capabilities) { capabilities = Capabilities; }
///< A derived class shall call this function in its constructor to set the
///< capability flags it supports.
int Frontend(void) const { return frontend; }
///< Returns the file descriptor of the DVB frontend the positioner is
///< connected to. If the positioner is not connected to any DVB device,
///< -1 will be returned.
static int CalcHourAngle(int Longitude);
///< Takes the longitude and latitude of the dish location from the system
///< setup and the given Longitude to calculate the "hour angle" to which to move
///< the dish to in order to point to the satellite at orbital position Longitude.
///< An hour angle of zero means the dish shall point directly towards the
///< celestial equator (which is south on the northern hemisphere, and north on
///< the southern hemisphere). Negative values mean that the dish needs to be
///< moved to the left (as seen from behind the dish), while positive values
///< require a movement to the right.
static int CalcLongitude(int HourAngle);
///< Returns the longitude of the satellite position the dish points at when the
///< positioner is moved to the given HourAngle.
void StartMovementTimer(int Longitude);
///< Starts a timer that estimates how long it will take to move the dish from
///< the current position to the one given by Longitude. The default implementation
///< of CurrentLongitude() uses this timer.
public:
enum ePositionerCapabilities {
pcCanNothing = 0x0000,
pcCanDrive = 0x0001,
pcCanStep = 0x0002,
pcCanHalt = 0x0004,
pcCanSetLimits = 0x0008,
pcCanDisableLimits = 0x0010,
pcCanEnableLimits = 0x0020,
pcCanStorePosition = 0x0040,
pcCanRecalcPositions = 0x0080,
pcCanGotoPosition = 0x0100,
pcCanGotoAngle = 0x0200,
};
enum ePositionerDirection { pdLeft, pdRight };
static int NormalizeAngle(int Angle);
///< Normalizes the given Angle into the range -1800...1800.
int Capabilities(void) const { return capabilities; }
///< Returns a flag word defining all the things this positioner is
///< capable of.
void SetFrontend(int Frontend) { frontend = Frontend; }
///< This function is called whenever the positioner is connected to
///< a DVB frontend.
static int HorizonLongitude(ePositionerDirection Direction);
///< Returns the longitude of the satellite position that is just at the
///< horizon when looking in the given Direction. Note that this function
///< only delivers reasonable values for site latitudes between +/-81 degrees.
///< Beyond these limits (i.e. near the north or south pole) a constant value
///< of +/-14.5 degrees (integer value 145) will be returned.
int HardLimitLongitude(ePositionerDirection Direction) const;
///< Returns the longitude of the positioner's hard limit in the given
///< Direction. Note that the value returned here may be larger (or smaller,
///< depending on the Direction) than that returned by HorizonLongitude(),
///< which would mean that it lies below that horizon.
int LastLongitude(void) const { return lastLongitude; }
///< Returns the longitude the dish has last been moved to.
int TargetLongitude(void) const { return targetLongitude; }
///< Returns the longitude the dish is supposed to be moved to. Once the target
///< longitude has been reached, this is the same as the value returned by
///< CurrentLongitude().
virtual cString Error(void) const { return NULL; }
///< Returns a short, single line string indicating an error condition (if
///< the positioner is able to report any errors).
///< NULL means there is no error.
virtual void Drive(ePositionerDirection Direction) {}
///< Continuously move the dish to the given Direction until Halt() is
///< called or it hits the soft or hard limit.
virtual void Step(ePositionerDirection Direction, uint Steps = 1) {}
///< Move the dish the given number of Steps in the given Direction.
///< The maximum number of steps a particular positioner can do in a single
///< call may be limited.
///< A "step" is the smallest possible movement the positioner can make, which
///< is typically 0.1 degrees.
virtual void Halt(void) {}
///< Stop any ongoing motion of the dish.
virtual void SetLimit(ePositionerDirection Direction) {}
///< Set the soft limit of the dish movement in the given Direction to the
///< current position.
virtual void DisableLimits(void) {}
///< Disables the soft limits for the dish movement.
virtual void EnableLimits(void) {}
///< Enables the soft limits for the dish movement.
virtual void StorePosition(uint Number) {}
///< Store the current position as a satellite position with the given Number.
///< Number can be in the range 1...255. However, a particular positioner
///< may only have a limited number of satellite positions it can store.
virtual void RecalcPositions(uint Number) {}
///< Take the difference betwen the current actual position of the dish and
///< the position stored with teh given Number, and apply the difference to
///< all stored positions.
virtual void GotoPosition(uint Number, int Longitude);
///< Move the dish to the satellite position stored under the given Number.
///< Number must be one of the values previously used with StorePosition().
///< The special value 0 shall move the dish to a "reference position",
///< which usually is due south (or north, if you're on the southern hemisphere).
///< Longitude will be used to calculate how long it takes to move the dish
///< from its current position to the given Longitude.
///< A derived class must call the base class function to have the target
///< longitude stored.
virtual void GotoAngle(int Longitude);
///< Move the dish to the given angular position. Longitude can be in the range
///< -1800...+1800. A positive sign indicates a position east of Greenwich,
///< while western positions have a negative sign. The absolute value is in
///< "degrees * 10", which allows for a resolution of 1/10 of a degree.
///< A derived class must call the base class function to have the target
///< longitude stored.
virtual int CurrentLongitude(void) const;
///< Returns the longitude the dish currently points to. If the dish is in motion,
///< this may be an estimate based on the angular speed of the positioner.
///< The default implementation takes the last and target longitude as well as
///< the rotation speed of the positioner to calculate the estimated current
///< longitude the dish points to.
virtual bool IsMoving(void) const;
///< Returns true if the dish is currently moving as a result of a call to
///< GotoPosition() or GotoAngle().
static cPositioner *GetPositioner(void);
///< Returns a previously created positioner. If no plugin has created
///< a positioner, there will always be the default DiSEqC positioner.
static void DestroyPositioner(void);
///< Destroys a previously created positioner.
};
#endif //__POSITIONER_H

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: skinlcars.c 3.2 2013/05/19 12:04:09 kls Exp $
* $Id: skinlcars.c 3.3 2013/08/18 13:45:36 kls Exp $
*/
// "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
@ -27,6 +27,7 @@
#include "font.h"
#include "menu.h"
#include "osd.h"
#include "positioner.h"
#include "themes.h"
#include "videodir.h"
@ -299,6 +300,44 @@ static void DrawDeviceSignal(cOsd *Osd, const cDevice *Device, int x0, int y0, i
}
}
static void DrawDevicePosition(cOsd *Osd, const cPositioner *Positioner, int x0, int y0, int x1, int y1, int &LastCurrent)
{
int HorizonLeft = Positioner->HorizonLongitude(cPositioner::pdLeft);
int HorizonRight = Positioner->HorizonLongitude(cPositioner::pdRight);
int HardLimitLeft = cPositioner::NormalizeAngle(HorizonLeft - Positioner->HardLimitLongitude(cPositioner::pdLeft));
int HardLimitRight = cPositioner::NormalizeAngle(Positioner->HardLimitLongitude(cPositioner::pdRight) - HorizonRight);
int HorizonDelta = cPositioner::NormalizeAngle(HorizonLeft - HorizonRight);
int Current = cPositioner::NormalizeAngle(HorizonLeft - Positioner->CurrentLongitude());
int Target = cPositioner::NormalizeAngle(HorizonLeft - Positioner->TargetLongitude());
int d = (y1 - y0) / 2;
int w = x1 - x0 - 2 * d;
int l = max(x0 + d, x0 + d + w * HardLimitLeft / HorizonDelta);
int r = min(x1 - d, x1 - d - w * HardLimitRight / HorizonDelta) - 1;
int c = constrain(x0 + d + w * Current / HorizonDelta, l, r);
int t = constrain(x0 + d + w * Target / HorizonDelta, l, r);
if (c == LastCurrent)
return;
if (c > t)
swap(c, t);
tColor ColorRange, ColorMove;
if (TwoColors) {
ColorRange = Theme.Color(clrChannelFrameBg);
ColorMove = Theme.Color(clrBackground);
}
else {
ColorRange = Theme.Color(clrChannelFrameBg);
ColorMove = Theme.Color(clrDeviceBg);
}
Osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, Theme.Color(clrBackground));
Osd->DrawEllipse(l - d, y0, l, y1 - 1, ColorRange, 7);
Osd->DrawRectangle(l, y0, r, y1 - 1, ColorRange);
Osd->DrawEllipse(r, y0, r + d, y1 - 1, ColorRange, 5);
Osd->DrawEllipse(c - d, y0, c, y1 - 1, ColorMove, 7);
Osd->DrawRectangle(c, y0, t, y1 - 1, ColorMove);
Osd->DrawEllipse(t, y0, t + d, y1 - 1, ColorMove, 5);
LastCurrent = c;
}
// --- cSkinLCARSDisplayChannel ----------------------------------------------
class cSkinLCARSDisplayChannel : public cSkinDisplayChannel {
@ -317,6 +356,7 @@ private:
bool initial;
cString lastDate;
int lastSeen;
int lastCurrentPosition;
int lastDeviceNumber;
cString lastDeviceType;
cCamSlot *lastCamSlot;
@ -336,6 +376,7 @@ public:
virtual void SetChannel(const cChannel *Channel, int Number);
virtual void SetEvents(const cEvent *Present, const cEvent *Following);
virtual void SetMessage(eMessageType Type, const char *Text);
virtual void SetPositioner(const cPositioner *Positioner);
virtual void Flush(void);
};
@ -352,6 +393,7 @@ cSkinLCARSDisplayChannel::cSkinLCARSDisplayChannel(bool WithInfo)
initial = true;
present = NULL;
lastSeen = -1;
lastCurrentPosition = -1;
lastDeviceNumber = -1;
lastCamSlot = NULL;
lastSignalStrength = -1;
@ -458,6 +500,8 @@ void cSkinLCARSDisplayChannel::DrawTrack(void)
void cSkinLCARSDisplayChannel::DrawSeen(int Current, int Total)
{
if (lastCurrentPosition >= 0)
return; // to not interfere with SetPositioner()
int Seen = (Total > 0) ? min(xc07 - xc06, int((xc07 - xc06) * double(Current) / Total)) : 0;
if (initial || Seen != lastSeen) {
int y0 = yc11 - ShowSeenExtent;
@ -532,8 +576,13 @@ void cSkinLCARSDisplayChannel::SetChannel(const cChannel *Channel, int Number)
osd->DrawText(xc00, yc00, ChNumber, Theme.Color(clrChannelFrameFg), frameColor, tallFont, xc02 - xc00, yc02 - yc00, taTop | taRight | taBorder);
osd->DrawText(xc03, yc00, ChName, Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xi - xc03 - lineHeight, 0, taTop | taLeft);
lastSignalDisplay = 0;
if (withInfo)
if (withInfo) {
if (Channel) {
int x = xc00 + (yc10 - yc09); // compensate for the arc
osd->DrawText(x, yc07, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), frameColor, cFont::GetFont(fontOsd), xc02 - x, yc10 - yc07, taTop | taRight | taBorder);
}
DrawDevice();
}
}
void cSkinLCARSDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
@ -587,6 +636,20 @@ void cSkinLCARSDisplayChannel::SetMessage(eMessageType Type, const char *Text)
}
}
void cSkinLCARSDisplayChannel::SetPositioner(const cPositioner *Positioner)
{
if (Positioner) {
int y0 = yc11 - ShowSeenExtent;
int y1 = yc11 + lineHeight / 2 - Gap / 2;
DrawDevicePosition(osd, Positioner, xc06, y0, xc07, y1, lastCurrentPosition);
}
else {
lastCurrentPosition = -1;
initial = true; // to have DrawSeen() refresh the progress bar
}
return;
}
void cSkinLCARSDisplayChannel::Flush(void)
{
if (withInfo) {
@ -1345,6 +1408,8 @@ void cSkinLCARSDisplayMenu::DrawLive(const cChannel *Channel)
if (initial || Channel != lastChannel) {
osd->DrawText(xa00, yt00, itoa(Channel->Number()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), tallFont, xa02 - xa00, yt02 - yt00, taTop | taRight | taBorder);
osd->DrawText(xa03, yt00, Channel->Name(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
int x = xa00 + (yc03 - yc02); // compensate for the arc
osd->DrawText(x, yc00, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), cFont::GetFont(fontOsd), xa02 - x, yc03 - yc00, taTop | taRight | taBorder);
lastChannel = Channel;
DrawSeen(0, 0);
}

18
skins.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: skins.c 2.10 2012/06/02 11:44:14 kls Exp $
* $Id: skins.c 3.1 2013/08/18 12:07:22 kls Exp $
*/
#include "skins.h"
@ -63,6 +63,22 @@ cSkinDisplay::~cSkinDisplay()
current = NULL;
}
// --- cSkinDisplayChannel ---------------------------------------------------
cSkinDisplayChannel::cSkinDisplayChannel(void)
{
positioner = NULL;
}
void cSkinDisplayChannel::SetPositioner(const cPositioner *Positioner)
{
if (positioner && Positioner != positioner)
SetMessage(mtInfo, NULL);
positioner = Positioner;
if (positioner)
SetMessage(mtInfo, cString::sprintf(tr("Moving dish to %.1f..."), double(positioner->TargetLongitude()) / 10));
}
// --- cSkinDisplayMenu ------------------------------------------------------
cSkinDisplayMenu::cSkinDisplayMenu(void)

17
skins.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: skins.h 2.9 2012/12/21 11:09:13 kls Exp $
* $Id: skins.h 3.1 2013/08/21 10:29:10 kls Exp $
*/
#ifndef __SKINS_H
@ -14,6 +14,7 @@
#include "epg.h"
#include "keys.h"
#include "osd.h"
#include "positioner.h"
#include "recording.h"
#include "themes.h"
#include "thread.h"
@ -52,7 +53,10 @@ class cSkinDisplayChannel : public cSkinDisplay {
///< This class is used to display the current channel, together with
///< the present and following EPG event. How and to what extent this
///< is done is totally up to the derived class.
private:
const cPositioner *positioner;
public:
cSkinDisplayChannel(void);
virtual void SetChannel(const cChannel *Channel, int Number) = 0;
///< Sets the current channel to Channel. If Number is not 0, the
///< user is in the process of entering a channel number, which must
@ -65,6 +69,17 @@ public:
///< to determine, e.g., the colors for displaying the Text.
///< If Text is NULL, any previously displayed message must be removed, and
///< any previous contents overwritten by the message must be restored.
virtual void SetPositioner(const cPositioner *Positioner);
///< Sets the Positioner used to move the satellite dish. The skin may use the
///< data provided by Positioner to implement some form of progress display,
///< since moving the dish may take a while. This function will only be called
///< if the device receiving the current live channel actually uses a positioner,
///< and it will be called with NULL once the dish has reached its target
///< position (or the user switches to a channel that doesn't require positioning
///< the dish). While the dish is moving, SetPositioner() is called repeatedly,
///< so the skin has a chance to update the progress display.
///< The default implementation calls SetMessage() with a text that indicates
///< that the dish is being moved to a new position.
/*TODO
SetButtons
Red = Video options

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: sources.c 3.3 2013/05/23 09:41:54 kls Exp $
* $Id: sources.c 3.4 2013/05/23 10:20:28 kls Exp $
*/
#include "sources.h"
@ -37,6 +37,13 @@ bool cSource::Parse(const char *s)
return code != stNone && description && *description;
}
bool cSource::Matches(int Code1, int Code2)
{
if (Code1 == (stSat | st_Any))
return IsSat(Code2);
return Code1 == Code2;
}
int cSource::Position(int Code)
{
int n = (Code & st_Pos);

View File

@ -179,6 +179,8 @@ S135W AMC 10
S137W AMC 7
S139W AMC 8
S360E Any satellite
# Cable
C DVB-C

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: sources.h 3.1 2013/04/11 10:23:16 kls Exp $
* $Id: sources.h 3.2 2013/08/21 10:27:32 kls Exp $
*/
#ifndef __SOURCES_H
@ -22,6 +22,7 @@ public:
stTerr = ('T' << 24),
st_Mask = 0xFF000000,
st_Pos = 0x0000FFFF,
st_Any = 0x00000E10, // 3600 - special value indicating "any position"
};
private:
int code;
@ -33,12 +34,19 @@ public:
int Code(void) const { return code; }
int Position(void) { return Position(code); }
///< Returns the orbital position of the satellite in case this is a DVB-S
///< source (zero otherwise). The returned value is in the range -1800...+1800.
///< source (zero otherwise). The returned value is in the range -1800...+1800,
///< except for the special value 3600, which indicates "any position". This is
///< used with positioners that can move the dish to any requested satellite
///< within their range.
///< A positive sign indicates a position east of Greenwich, while western
///< positions have a negative sign. The absolute value is in "degrees * 10",
///< which allows for a resolution of 1/10 of a degree.
const char *Description(void) const { return description; }
bool Parse(const char *s);
static bool Matches(int Code1, int Code2);
///< Returns true if Code2 matches Code1. This is simply a check whether the
///< two codes are equal, except for the special case that Code1 is stSat|st_Any,
///< in which case it matches any Code2 that is stSat.
static int Position(int Code);
static char ToChar(int Code) { return (Code & st_Mask) >> 24; }
static cString ToString(int Code);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.c 2.29 2012/12/07 09:00:00 kls Exp $
* $Id: tools.c 3.1 2013/05/23 10:10:00 kls Exp $
*/
#include "tools.h"
@ -691,12 +691,12 @@ void cTimeMs::Set(int Ms)
begin = Now() + Ms;
}
bool cTimeMs::TimedOut(void)
bool cTimeMs::TimedOut(void) const
{
return Now() >= begin;
}
uint64_t cTimeMs::Elapsed(void)
uint64_t cTimeMs::Elapsed(void) const
{
return Now() - begin;
}

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.h 2.24 2013/02/17 13:18:06 kls Exp $
* $Id: tools.h 3.1 2013/08/21 08:49:48 kls Exp $
*/
#ifndef __TOOLS_H
@ -64,6 +64,8 @@ void syslog_with_tid(int priority, const char *format, ...) __attribute__ ((form
#define BCDCHARTOINT(x) (10 * ((x & 0xF0) >> 4) + (x & 0xF))
int BCD2INT(int x);
#define IsBitSet(v, b) ((v) & (1 << (b))) // checks if the bit at index b is set in v, where the least significant bit has index 0
// Unfortunately there are no platform independent macros for unaligned
// access, so we do it this way:
@ -330,8 +332,8 @@ public:
///< time.
static uint64_t Now(void);
void Set(int Ms = 0);
bool TimedOut(void);
uint64_t Elapsed(void);
bool TimedOut(void) const;
uint64_t Elapsed(void) const;
};
class cReadLine {

3
vdr.5
View File

@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
.\" $Id: vdr.5 2.36 2013/03/29 10:25:56 kls Exp $
.\" $Id: vdr.5 3.1 2013/08/11 13:50:42 kls Exp $
.\"
.TH vdr 5 "31 Mar 2013" "2.0" "Video Disk Recorder Files"
.SH NAME
@ -483,6 +483,7 @@ l l.
\fBV\fR@voltage high (18V)
\fBA\fR@mini A
\fBB\fR@mini B
\fBPn\fR@use positioner to move dish to satellite position n (or to the satellite's orbital position, if no position number is given)
\fBSn\fR@Satellite channel routing code sequence for bank n follows
\fBWnn\fR@wait nn milliseconds (nn may be any positive integer number)
\fB[xx ...]\fR@hex code sequence (max. 6)

8
vdr.c
View File

@ -22,7 +22,7 @@
*
* The project's page is at http://www.tvdr.de
*
* $Id: vdr.c 2.57 2013/03/15 10:44:54 kls Exp $
* $Id: vdr.c 3.1 2013/06/10 14:28:43 kls Exp $
*/
#include <getopt.h>
@ -800,6 +800,11 @@ int main(int argc, char *argv[])
if (AudioCommand)
new cExternalAudio(AudioCommand);
// Positioner:
if (!cPositioner::GetPositioner()) // no plugin has created a positioner
new cDiseqcPositioner;
// Channel:
if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT))
@ -1400,6 +1405,7 @@ Exit:
Setup.Save();
}
cDevice::Shutdown();
cPositioner::DestroyPositioner();
EpgHandlers.Clear();
PluginManager.Shutdown(true);
cSchedules::Cleanup(true);