|
From: <j-...@us...> - 2012-08-12 16:41:55
|
Revision: 942
http://openautomation.svn.sourceforge.net/openautomation/?rev=942&view=rev
Author: j-n-k
Date: 2012-08-12 16:41:47 +0000 (Sun, 12 Aug 2012)
Log Message:
-----------
knxdmxd: update for source, binary tbd
Modified Paths:
--------------
tools/knxdmxd/Makefile.am
tools/knxdmxd/src/cue.cc
tools/knxdmxd/src/cue.h
tools/knxdmxd/src/dmxsender.cc
tools/knxdmxd/src/dmxsender.h
tools/knxdmxd/src/fixture.cc
tools/knxdmxd/src/fixture.h
tools/knxdmxd/src/knxdmxd.cc
tools/knxdmxd/src/knxdmxd.h
tools/knxdmxd/src/trigger.cc
tools/knxdmxd/src/trigger.h
Modified: tools/knxdmxd/Makefile.am
===================================================================
--- tools/knxdmxd/Makefile.am 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/Makefile.am 2012-08-12 16:41:47 UTC (rev 942)
@@ -1,11 +1,2 @@
-# what flags you want to pass to the C compiler & linker
-#CPPFLAGS = --pedantic -Wall -std=c99 -O2
-#LDFLAGS =
-
-knxdmxd_CXXFLAGS = $(OLA_CFLAGS) $(AM_CXXFLAGS)
-knxdmxd_LDADD = $(OLA_LIBS)
-
-# this lists the binaries to produce, the (non-PHONY, binary) targets in
-# the previous manual Makefile
-bin_PROGRAMS = knxdmxd
-knxdmxd_SOURCES = knxdmxd.cc log.cc fixture.cc cue.cc dmxsender.cc trigger.cc
+AUTOMAKE_OPTIONS = foreign
+SUBDIRS = src
\ No newline at end of file
Modified: tools/knxdmxd/src/cue.cc
===================================================================
--- tools/knxdmxd/src/cue.cc 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/cue.cc 2012-08-12 16:41:47 UTC (rev 942)
@@ -13,8 +13,6 @@
Cue::Cue(const std::string name, const bool isLink) {
_name=name;
- lock_.locker = name; // default is cue-name
- lock_.prio = 0;
fadeIn_ = 0.0;
fadeOut_ = 0.0;
waittime_ = -1; // never step automatically
@@ -30,7 +28,7 @@
void Cue::AddChannel(const cue_channel_t& channel) {
_channel_data.push_back(channel);
- std::clog << "Cue " << _name << ": added channel definition " << channel.fixture->GetName() << "/" << channel.name << "@" << channel.value << std::endl;
+ std::clog << "Cue " << _name << ": added channel definition " << channel.dmx << "@" << channel.value << std::endl;
}
void Cue::SetFading(const float fadeIn, const float fadeOut) {
@@ -48,13 +46,7 @@
std::clog << "Called cue " << _name << " (delaying)" << std::endl;
} else {
for(std::list<cue_channel_t>::iterator it = _channel_data.begin(); it != _channel_data.end(); ++it) {
- if (!it->fixture->Lock(lock_)) { // Test if we can lock
- std::clog << _name << ": locking failed " << it->fixture->GetName() << std::endl;
- continue; // no, we can't
- }
- int deltaVal = it->fixture->GetCurrentValue(it->name) - it->value;
- float ft = (deltaVal>0) ? ((deltaVal+1)/(fadeOut_*1.e3/(DMX_INTERVAL+1))) : ((-deltaVal+1)/(fadeIn_*1.e3/(DMX_INTERVAL+1)));
- it->fixture->Update(it->name, it->value, ft);
+ DMX::SetDMXChannel(it->dmx , it->value, fadeIn_, fadeOut_ );
}
delay_on_ = false;
std::clog << "Called cue " << _name << std::endl;
@@ -64,9 +56,6 @@
Cuelist::Cuelist(const std::string name) {
_name=name;
-
- lock_.locker = name; // default is cuelist-name
- lock_.prio = 0;
current_cue_=-1;
was_direct_ = false;
@@ -111,33 +100,37 @@
case -2: // next on running cuelist
was_direct_ = true;
break;
-
}
if (max_cue_>(current_cue_+1)) {
- if (current_cue_>=0)
- cue_data_.at(current_cue_).Release();
- current_cue_++;
- knxdmxd::Cue cue = cue_data_.at(current_cue_);
- if (cue.isLink()) {
- current_cue_ = cue_names_.find(cue.GetName())->second;
- }
+ try {
+ if (current_cue_>=0)
+ cue_data_.at(current_cue_).Release();
+
+ current_cue_++;
+ knxdmxd::Cue cue = cue_data_.at(current_cue_);
+ if (cue.isLink()) {
+ current_cue_ = cue_names_.find(cue.GetName())->second;
+ }
- cue_data_.at(current_cue_).Go();
+ cue_data_.at(current_cue_).Go();
- float waittime;
- int nextCuenum = current_cue_+1;
- if (max_cue_>nextCuenum) { // last cue stops automatically
- knxdmxd::Cue nextCue = cue_data_.at(nextCuenum);
- if (nextCue.isLink()) {
- nextCuenum = cue_names_.find(nextCue.GetName())->second;
- nextCue = cue_data_.at(nextCuenum);
+ float waittime;
+ int nextCuenum = current_cue_+1;
+ if (max_cue_>nextCuenum) { // last cue stops automatically
+ knxdmxd::Cue nextCue = cue_data_.at(nextCuenum);
+ if (nextCue.isLink()) {
+ nextCuenum = cue_names_.find(nextCue.GetName())->second;
+ nextCue = cue_data_.at(nextCuenum);
+ }
+ waittime = nextCue.GetWaitTime();
+ if ((waittime>=0) && (!cue_halted_)) {
+ DMX::GetOLAClient().GetSelectServer()->RegisterSingleTimeout(
+ (int) waittime*1000, ola::NewSingleCallback(this, &Cuelist::NextCue, -1));
+ }
}
- waittime = nextCue.GetWaitTime();
- if ((waittime>=0) && (!cue_halted_)) {
- DMX::GetOLAClient().GetSelectServer()->RegisterSingleTimeout(
- (int) waittime*1000, ola::NewSingleCallback(this, &Cuelist::NextCue, -1));
- }
+ } catch (char *str) {
+ std::clog << kLogErr << "Exception " << str << " in calling cue, current_cue_ = " << current_cue_ << std::endl;
}
}
}
Modified: tools/knxdmxd/src/cue.h
===================================================================
--- tools/knxdmxd/src/cue.h 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/cue.h 2012-08-12 16:41:47 UTC (rev 942)
@@ -19,8 +19,7 @@
namespace knxdmxd {
typedef struct {
- pFixture fixture;
- std::string name;
+ dmx_addr_t dmx;
int value;
} cue_channel_t;
@@ -29,7 +28,7 @@
float fadeIn_, fadeOut_;
float waittime_, delay_;
bool is_link_, delay_on_;
- fixture_lock_t lock_;
+ // fixture_lock_t lock_;
public:
Cue() {};
@@ -39,13 +38,13 @@
void SetFading(const float fadeIn, const float fadeOut);
void SetWaittime(const float waittime) { waittime_ = waittime; };
void SetDelay(const float delay) { delay_ = delay; };
- void SetLock(const fixture_lock_t lock) { lock_ = lock; };
+ // void SetLock(const fixture_lock_t lock) { lock_ = lock; };
void Go();
void Release() {
- for(std::list<cue_channel_t>::iterator it = _channel_data.begin(); it != _channel_data.end(); ++it) {
+ /*for(std::list<cue_channel_t>::iterator it = _channel_data.begin(); it != _channel_data.end(); ++it) {
it->fixture->Release(lock_);
- }
+ }*/
};
const std::string GetName() { return _name; };
@@ -59,7 +58,7 @@
int current_cue_, max_cue_;
bool cue_halted_, was_direct_;
bool release_on_halt_;
- fixture_lock_t lock_;
+ // fixture_lock_t lock_;
std::vector<knxdmxd::Cue> cue_data_;
std::map<std::string, int> cue_names_;
Modified: tools/knxdmxd/src/dmxsender.cc
===================================================================
--- tools/knxdmxd/src/dmxsender.cc 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/dmxsender.cc 2012-08-12 16:41:47 UTC (rev 942)
@@ -11,9 +11,20 @@
namespace knxdmxd {
+ dmx_addr_t DMX::Address(const std::string addr) {
+ char universe;
+ int channel;
+ sscanf( (char*)addr.c_str(), "%d.%d", &universe, &channel);
+ return (channel==-1) ? (universe+512) : ((universe << 9) + channel);
+ }
+
+ // initalize static variables of DMX class
+ ola::OlaCallbackClientWrapper DMX::m_client;
+ std::map<char, knxdmxd::pUniverse> DMX::output;
+
bool DMXSender::Init() {
if (!m_client.Setup()) {
- std::clog << kLogWarning << "OLA: client Setup failed " << std::endl;
+ std::clog << kLogWarning << "DMXSender: OLA client setup failed " << std::endl;
return false;
}
return true;
@@ -21,19 +32,41 @@
int DMXSender::Start() {
SendDMX();
- fixture_list_.StartRefresh();
m_client.GetSelectServer()->Run();
sender_running_ = true;
return 0;
}
+ void Universe::Crossfade() {
+ ola::thread::MutexLocker locker(&data_mutex);
+ int i;
+ int max=512;
+ unsigned long currenttime = Timer::Get();
+
+ for(i=511; i>=0; max=i, i--) // find last value
+ if(new_[i]||old_[i])
+ break;
+
+ for(i=0; i<max; i++) {
+ if ((new_[i] || old_[i]) && (new_[i] != old_[i])) { /* avoid calculating with only 0 or finished */
+ if (currenttime>fadeend_[i]) {
+ current_[i] = old_[i] = new_[i];
+ } else {
+ float p = (float)(currenttime-fadestart_[i])/(fadeend_[i]-fadestart_[i]);
+ float q = 1.0f - p;
+ current_[i]=(unsigned char)(old_[i]*q + new_[i]*p);
+ }
+ }
+ }
+ }
+
void DMXSender::SendDMX() {
- for(std::map<int, ola::DmxBuffer>::const_iterator i = output.begin(); i != output.end(); ++i) {
+ for(std::map<char, pUniverse>::const_iterator i = output.begin(); i != output.end(); ++i) {
int universe = i->first;
- //std::clog << "C1/2 " << (int) i->second.Get(0) << " " << (int) i->second.Get(1) << " " << (int) i->second.Get(2) << std::endl;
- if (!m_client.GetClient()->SendDmx(universe, i->second)) { // send all universes
+ i->second->Crossfade();
+ if (!m_client.GetClient()->SendDmx(universe, i->second->GetBuffer())) { // send all universes
m_client.GetSelectServer()->Terminate();
- std::clog << kLogWarning << "OLA: failed to send universe "<< universe << std::endl;
+ std::clog << kLogWarning << "DMXSender: OLA failed to send universe "<< universe << std::endl;
sender_running_ = false;
return;
}
Modified: tools/knxdmxd/src/dmxsender.h
===================================================================
--- tools/knxdmxd/src/dmxsender.h 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/dmxsender.h 2012-08-12 16:41:47 UTC (rev 942)
@@ -4,7 +4,7 @@
* (c) by JNK 2012
*
*
-*/
+ */
#ifndef DMXSENDER_H
#define DMXSENDER_H
@@ -15,33 +15,91 @@
#include <ola/OlaCallbackClient.h>
#include <ola/OlaClientWrapper.h>
#include <map>
-#include <fixture.h>
namespace knxdmxd {
- class DMXSender : private DMX {
- FixtureList fixture_list_;
+ class Universe {
+ protected:
+ unsigned char current_[512], new_[512], old_[512];
+ unsigned long fadestart_[512], fadeend_[512];
+ ola::DmxBuffer buffer_;
+ ola::thread::Mutex data_mutex;
+ public:
+ Universe() {
+ ola::thread::MutexLocker locker(&data_mutex);
+ for (int i=0; i<512; i++) {
+ current_[i] = new_[i] = old_[i] = 0;
+ }
+ buffer_.Blackout();
+ };
+ void Set(const unsigned channel, const unsigned char value, const float fade_in=1.e-4, const float fade_out=1.e-4) {
+ ola::thread::MutexLocker locker(&data_mutex);
+ new_[channel] = value;
+ old_[channel] = current_[channel];
+ float fadeTime = (new_[channel]>current_[channel]) ? fade_in : fade_out;
+ fadestart_[channel] = Timer::Get();
+ fadeend_[channel] = fadestart_[channel] + (unsigned long) (fadeTime*1000.0);
+ }
+ unsigned char Get(const unsigned channel) {
+ return current_[channel];
+ }
+ ola::DmxBuffer &GetBuffer() {
+ ola::thread::MutexLocker locker(&data_mutex);
+ buffer_.Set(current_, 512);
+ return buffer_;
+ }
+ void Crossfade();
+ };
+
+ typedef Universe* pUniverse;
+
+ class DMX {
+ protected:
+ static std::map<char, pUniverse> output;
+ static ola::OlaCallbackClientWrapper m_client;
+
+ public:
+ DMX() {};
+ static void SetDMXChannel(const dmx_addr_t channel, const unsigned char value, const float fade_in=1.e-4, const float fade_out=1.e-4) {
+ int dmxuniverse = (int) (channel / 512), dmxchannel = channel % 512;
+ output[dmxuniverse]->Set(dmxchannel, value, fade_in, fade_out);
+ };
+ char GetDMXChannel(int channel);
+
+ static dmx_addr_t Address(const std::string s);
+ static ola::OlaCallbackClientWrapper& GetOLAClient() { return m_client; };
+
+ };
+
+ class DMXSender: private DMX {
bool sender_running_;
-
+
public:
- DMXSender() { sender_running_ = false; };
+ DMXSender() {
+ sender_running_ = false;
+ }
+
~DMXSender();
bool Init();
int Start();
void SendDMX();
-
+
void Terminate();
- bool Running() { return sender_running_; };
-
- void AddFixture(pFixture fixture) { fixture_list_.Add(fixture); };
- pFixture GetFixture(const std::string& name) { return fixture_list_.Get(name); };
+ bool Running() {
+ return sender_running_;
+ };
-// void Process(const Trigger& trigger) { fixture_list_.Process(trigger); };
+ void AddUniverse(char universe) {
+ if (!output.count(universe)) { // only create if not already existing;
+ pUniverse new_universe = new Universe();
+ output.insert(std::pair<char, pUniverse> (universe, new_universe));
+ std::clog << "DMXSender created universe " << (int) universe << std::endl;
+ }
+ };
};
-
}
#endif
Modified: tools/knxdmxd/src/fixture.cc
===================================================================
--- tools/knxdmxd/src/fixture.cc 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/fixture.cc 2012-08-12 16:41:47 UTC (rev 942)
@@ -10,7 +10,7 @@
namespace knxdmxd {
- Fixture::Fixture(const std::string name) {
+ /* Fixture::Fixture(const std::string name) {
name_ = name;
fadeTimeKNX_ = 0;
std::clog << "Creating Fixture " << name_ << std::endl;
@@ -70,20 +70,20 @@
bool Fixture::RegisterRefresh() {
m_client.GetSelectServer()->RegisterSingleTimeout(
- DMX_INTERVAL, ola::NewSingleCallback(this, &Fixture::Refresh));
+ DMX_INTERVAL, ola::NewSingleCallback(this, &Fixture::Refresh));
return true;
}
-
+
int Fixture::GetCurrentValue(const std::string& channel) {
return (int) channel_data_[channel_names_[channel]].floatValue;
}
-
+
void Fixture::Process(const Trigger& trigger) {
std::clog << "fprocess" << std::endl;
for (std::vector<knxdmxd::fixture_channel_t>::iterator it=channel_data_.begin(); it!=channel_data_.end(); ++it) {
if (it->KNX == trigger.GetKNX()) {
it->value = trigger.GetValue();
- it->fadeStep = _fadeStep;
+ it->fadeStep = _fadeStep;
refresh_ = true;
std::clog << "Updated " << it->DMX << " to " << it->value << "rate: " << it->fadeStep << std::endl;
}
@@ -91,35 +91,7 @@
if (fadeTimeKNX_ == trigger.GetKNX()) {
SetFadeTime(trigger.GetValue());
}
- }
-
- void DMX::SetDMXChannel(int channel, int value) {
- int dmxuniverse = (int) (channel / 512), dmxchannel = channel % 512;
- output[dmxuniverse].SetChannel(dmxchannel, value);
- }
-
- int DMX::GetDMXChannel(int channel) {
- int dmxuniverse = (int) (channel / 512), dmxchannel = channel % 512;
- return output[dmxuniverse].Get(dmxchannel);
- }
-
- int DMX::Address(const std::string addr) {
- int universe, channel;
- sscanf( (char*)addr.c_str(), "%d.%d", &universe, &channel);
- if (channel==-1) { // default universe is 1
- channel = universe;
- universe = 1;
- }
- return (universe << 9) + channel;
- }
+ } */
- void FixtureList::StartRefresh() {
- for(std::map<std::string, knxdmxd::pFixture>::iterator it=fixture_list_.begin(); it!=fixture_list_.end(); ++it) {
- it->second->RegisterRefresh();
- }
- }
- // initalize static variables of DMX class
- ola::OlaCallbackClientWrapper DMX::m_client;
- std::map<int, ola::DmxBuffer> DMX::output;
-
+
}
Modified: tools/knxdmxd/src/fixture.h
===================================================================
--- tools/knxdmxd/src/fixture.h 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/fixture.h 2012-08-12 16:41:47 UTC (rev 942)
@@ -13,101 +13,47 @@
#include <knxdmxd.h>
#include <trigger.h>
#include <ola/OlaClientWrapper.h>
+#include <ola/thread/Mutex.h>
+#include <dmxsender.h>
+
namespace knxdmxd {
- class DMX {
- protected:
- static std::map<int, ola::DmxBuffer> output;
- static ola::OlaCallbackClientWrapper m_client;
-
- public:
- DMX() {};
- void SetDMXChannel(int channel, int value);
- int GetDMXChannel(int channel);
-
- static int Address(const std::string s);
- static ola::OlaCallbackClientWrapper& GetOLAClient() { return m_client; };
-
- };
-
- typedef struct {
- int KNX, DMX, value;
- float fadeStep, floatValue;
- } fixture_channel_t;
-
- typedef struct {
- std::string locker;
- int prio;
- } fixture_lock_t;
-
- class Fixture : private DMX, public TriggerHandler {
+ class Dimmer : public TriggerHandler {
std::string name_;
- std::vector<fixture_channel_t> channel_data_;
- std::map<std::string, unsigned> channel_names_;
-
- float _fadeTime; // is set by knx or config
- float _fadeStep; // calculated from _fadeTime
- int fadeTimeKNX_;
- fixture_lock_t lock_;
-
- bool refresh_;
-
+ dmx_addr_t dmx_;
+ float fade_time_;
+ eibaddr_t ga_, ga_fading_;
public:
- Fixture() {};
- Fixture(const std::string name);
-
- void AddChannel(const std::string& name, const std::string& DMX, const std::string& KNX);
- void SetFadeTime(const float t);
- void PatchFadeTime(const int KNX) { fadeTimeKNX_ = KNX; };
- void Update(const std::string& channel, const int val, const float fadeStep);
- void Process(const Trigger& trigger);
-
- void Wait();
- void Refresh();
- bool RegisterRefresh();
-
- int GetCurrentValue(const std::string& channel);
- std::string& GetName() { return name_; };
-
- // locking
- bool Lock(const fixture_lock_t& lock) {
- if ((lock_.locker == lock.locker) || (lock_.locker == "") || (lock_.prio<=lock.prio)) {
- std::clog << "Locking " << lock.locker << " @ " << lock.prio << std::endl;
- lock_ = lock;
- return true;
- } else {
- std::clog << "Refused " << lock.locker << " @ " << lock.prio << std::endl;
- return false;
+ Dimmer() {};
+ Dimmer(const std::string name, eibaddr_t ga, dmx_addr_t dmx) {
+ name_ = name;
+ dmx_ = dmx;
+ ga_ = ga;
+ fade_time_ = 1.e-4;
+ std::clog << "Created dimmer '" << name << "' for "
+ << dmx << std::endl;
+ }
+ void SetFadeTime(float fade_time) {
+ fade_time_ = fade_time;
+ }
+ void SetFadeKNX(eibaddr_t ga) {
+ ga_fading_ = ga;
+ }
+ void Process(const Trigger& trigger) {
+ eibaddr_t ga = trigger.GetKNX();
+ std::clog << "Checking trigger" << trigger << " / " << ga_ << std::endl;
+ if (ga == ga_) {
+ DMX::SetDMXChannel(dmx_, trigger.GetValue(), fade_time_, fade_time_ );
+ std::clog << "Dimmer/Process: Updating value" << std::endl;
}
- };
- bool Release(const fixture_lock_t& lock) {
- if (lock_.locker == lock.locker) {
- lock_.locker = "";
- lock_.prio=0;
- return true;
- } else {
- return false;
+ if (ga == ga_fading_) {
+ std::clog << "Dimmer/Process: Updating fading" << std::endl;
}
- };
- fixture_lock_t GetLock() { return lock_; };
-
+ }
};
- typedef Fixture* pFixture;
- class FixtureList {
- std::map<std::string, knxdmxd::pFixture> fixture_list_;
-
- public:
- FixtureList() {};
-
- void Add(pFixture fixture) { fixture_list_.insert(std::pair<std::string, knxdmxd::pFixture> (fixture->GetName(), fixture)); };
- void StartRefresh();
-// void Process(const Trigger& trigger);
-
- pFixture Get(const std::string& name) { return fixture_list_[name]; };
- };
}
Modified: tools/knxdmxd/src/knxdmxd.cc
===================================================================
--- tools/knxdmxd/src/knxdmxd.cc 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/knxdmxd.cc 2012-08-12 16:41:47 UTC (rev 942)
@@ -71,9 +71,20 @@
std::string pidfilename = "/var/run/knxdmxd.pid";
knxdmxd::TriggerList triggerList;
knxdmxd::DMXSender sender;
+std::map<std::string, knxdmxd::dmx_addr_t> channel_names;
+std::map<knxdmxd::dmx_addr_t, eibaddr_t> statusmap;
+
namespace knxdmxd {
+ std::queue<Trigger> KNXHandler::fromKNX;
+ ola::thread::Mutex KNXHandler::mutex_fromKNX;
+ std::queue<eib_message_t> KNXHandler::toKNX;
+ ola::thread::Mutex KNXHandler::mutex_toKNX;
+
+ std::set<eibaddr_t> KNXHandler::listenGA;
+ std::map<eibaddr_t, long> KNXHandler::messagetracker;
+
eibaddr_t KNXHandler::Address(const std::string addr) {
int a, b, c;
char *s = (char *) addr.c_str();
@@ -111,6 +122,16 @@
}
while (1) {
+ triggerList.Process();
+ knxdmxd::eib_message_t message;
+ if (!KNXHandler::toKNX.empty()) { // there is something to send
+ {
+ ola::thread::MutexLocker locker(&KNXHandler::mutex_toKNX);
+ message = KNXHandler::toKNX.front();
+ KNXHandler::toKNX.pop();
+ }
+ std::clog << "KNXOut : " << message.ga << std::endl;
+ }
len = EIBGetGroup_Src(con, sizeof(buf), buf, &src, &dest);
if (len == -1) {
std::clog << kLogWarning << "eibd: Read failed" << std::endl;
@@ -138,8 +159,13 @@
case 0x80:
if (buf[1] & 0xC0) {
val = (len == 2) ? buf[1] & 0x3F : buf[2];
- knxdmxd::Trigger trigger(knxdmxd::kTriggerAll, dest, val);
- triggerList.Process(trigger);
+ if (KNXHandler::listenGA.count(dest)) { // keep queue clean from unwanted messages
+ std::clog << "EIBD: " << dest << " " << (int) val << std::endl;
+ knxdmxd::Trigger trigger(knxdmxd::kTriggerAll, dest, val);
+ ola::thread::MutexLocker locker(&KNXHandler::mutex_fromKNX);
+ KNXHandler::fromKNX.push(trigger);
+ }
+
}
break;
}
@@ -218,9 +244,10 @@
return NULL;
}
- int knx = knxdmxd::KNXHandler::Address(json_object_get_string(trigger_knx));
- int val = (trigger_value) ? json_object_get_int(trigger_value) : -1;
+ eibaddr_t knx = knxdmxd::KNXHandler::Address(json_object_get_string(trigger_knx));
+ int val = (trigger_value) ? json_object_get_int(trigger_value) : 256;
+ knxdmxd::KNXHandler::listenGA.insert(knx);
return new knxdmxd::Trigger(type, knx, val);
}
@@ -241,7 +268,7 @@
knxdmxd::Cue *new_cue = new knxdmxd::Cue(c_name);
// get channels
- struct json_object *channels = json_object_object_get(cue, "channels");
+ struct json_object *channels = json_object_object_get(cue, "data");
if (!channels) {
std::clog << kLogInfo << "Skipping cue '" << c_name
<< "' (no channels defined)" << std::endl;
@@ -253,19 +280,26 @@
// get channel
struct json_object *channel = json_object_array_get_idx(channels, j);
- struct json_object *fixt = json_object_object_get(channel, "fixture");
struct json_object *chan = json_object_object_get(channel, "channel");
struct json_object *value = json_object_object_get(channel, "value");
- if ((!fixt) || (!chan) || (!value)) {
+ if ((!chan) || (!value)) {
std::clog << kLogInfo << "Skipping errorneous channel def " << j
<< " in cue '" << c_name << "'" << std::endl;
continue;
}
+ std::string chan_str = json_object_get_string(chan);
+ if (!channel_names.count(chan_str)) {
+ std::clog << kLogInfo << "Skipping errorneous channel def " << j
+ << " in cue '" << c_name << "'" << std::endl;
+ continue;
+ }
+ knxdmxd::dmx_addr_t dmx = channel_names.find(chan_str)->second;
+
knxdmxd::cue_channel_t channeldata;
- channeldata.fixture = sender.GetFixture(json_object_get_string(fixt));
- channeldata.name = json_object_get_string(chan);
+
+ channeldata.dmx = dmx;
channeldata.value = json_object_get_int(value);
// add
@@ -333,82 +367,107 @@
config = json_object_from_file((char *) conf_file.c_str());
/*
- * fixtures
+ * channel definitions
*/
+ struct json_object *in_data = json_object_object_get(config, "channels");
+ int in_length = json_object_array_length(in_data);
+ std::clog << "Trying to import " << in_length << " channel(s)" << std::endl;
- struct json_object *fixtures = json_object_object_get(config, "fixtures");
- int fixturenum = json_object_array_length(fixtures);
- std::clog << "Trying to import " << fixturenum << " fixture(s)" << std::endl;
+ for (int i = 0; i < in_length; i++) { // read all
+ struct json_object *element = json_object_array_get_idx(in_data, i);
+ struct json_object *name = json_object_object_get(element, "name");
+ std::string name_str =
+ (name) ? json_object_get_string(name) : "_f_" + t_to_string(i);
+ struct json_object *dmx = json_object_object_get(element, "dmx");
+ if (!dmx) {
+ std::clog << kLogInfo << "Skipping channel '" << name_str
+ << " (missing dmx)" << std::endl;
+ continue;
+ }
+ knxdmxd::dmx_addr_t dmx_addr(knxdmxd::DMX::Address(json_object_get_string(dmx)));
+ sender.AddUniverse((char) (dmx_addr / 512));
+ channel_names.insert(std::pair<std::string, knxdmxd::dmx_addr_t> (name_str, dmx_addr));
- for (int i = 0; i < fixturenum; i++) { // read all
+ std::clog << "Named DMX " << dmx_addr << " as " << name_str;
+ struct json_object *ga = json_object_object_get(element, "statusga");
+ if (!ga) {
+ std::clog << std::endl;
+ continue;
+ }
+
+ std::string ga_str = json_object_get_string(ga);
+ statusmap.insert(std::pair<knxdmxd::dmx_addr_t, eibaddr_t> (dmx_addr, knxdmxd::KNXHandler::Address(ga_str)));
+ std::clog << " (GA: " << ga_str << ")" << std::endl;
+
+ }
+
+ /*
+ * dimmers
+ */
+
+ in_data = json_object_object_get(config, "dimmers");
+ in_length = json_object_array_length(in_data);
+ std::clog << "Trying to import " << in_length << " dimmer(s)" << std::endl;
+
+ for (int i = 0; i < in_length; i++) { // read all
// get fixture
- struct json_object *fixture = json_object_array_get_idx(fixtures, i);
+ struct json_object *element = json_object_array_get_idx(in_data, i);
// get name & create
- struct json_object *name = json_object_object_get(fixture, "name");
- std::string fname =
- (name) ? json_object_get_string(name) : "_f_" + t_to_string(i);
- knxdmxd::Fixture* f = new knxdmxd::Fixture(fname);
+ struct json_object *name = json_object_object_get(element, "name");
+ std::string name_str =
+ (name) ? json_object_get_string(name) : "_d_" + t_to_string(i);
- // get channels & patch them
- struct json_object *channels = json_object_object_get(fixture, "channels");
- if (!channels) {
- std::clog << kLogInfo << "Skipping fixture '" << fname
+ // get channel
+ struct json_object *channel = json_object_object_get(element, "channel");
+ if (!channel) {
+ std::clog << kLogInfo << "Skipping dimmer '" << name_str
<< "' (no channels defined)" << std::endl;
continue;
}
+ std::string channel_str = json_object_get_string(channel);
+ if (!channel_names.count(channel_str)) {
+ std::clog << kLogInfo << "Skipping dimmer '" << name_str
+ << "' (invalid channel name)" << std::endl;
+ continue;
+ }
+ knxdmxd::dmx_addr_t dmx = channel_names.find(channel_str)->second;
- for (int j = 0; j < json_object_array_length(channels); j++) { // read all
- // get channel
- struct json_object *channel = json_object_array_get_idx(channels, j);
+ struct json_object *ga = json_object_object_get(element, "ga");
+ if (!ga) {
+ std::clog << kLogInfo << "Skipping dimmer '" << name_str
+ << "' (no group address defined)" << std::endl;
+ continue;
+ }
- // channel name, default is _c_<num>
- struct json_object *name = json_object_object_get(channel, "name");
- std::string cname =
- (name) ? json_object_get_string(name) : "_c_" + t_to_string(j);
+ eibaddr_t ga_ = knxdmxd::KNXHandler::Address(json_object_get_string(ga));
- // dmx is required
- struct json_object *dmx = json_object_object_get(channel, "dmx");
- if (!dmx) {
- std::clog << kLogInfo << "Skipping channel '" << cname
- << "' in fixture '" << fname << "' (missing dmx)" << std::endl;
- continue;
- }
- std::string cdmx(json_object_get_string(dmx));
+ knxdmxd::Dimmer* d = new knxdmxd::Dimmer(name_str, ga_, dmx);
- // knx is optional
- struct json_object *knx = json_object_object_get(channel, "knx"); // knx is optional
- if (knx) { // if we have knx, add to triggerlist
- f->AddChannel(cname, cdmx, json_object_get_string(knx));
- knxdmxd::Trigger* trigger = new knxdmxd::Trigger(
- knxdmxd::kTriggerProcess,
- knxdmxd::KNXHandler::Address(json_object_get_string(knx)), -1);
- triggerList.Add(*trigger, f);
- } else {
- f->AddChannel(cname, cdmx, "");
- }
- }
+ knxdmxd::KNXHandler::listenGA.insert(ga_);
+ knxdmxd::Trigger* trigger = new knxdmxd::Trigger(
+ knxdmxd::kTriggerProcess,
+ ga_, 256);
+ triggerList.Add(*trigger, d);
// get fading
- struct json_object *fading = json_object_object_get(fixture, "fading");
- float ftime =
- (fading) ?
- json_object_get_double(json_object_object_get(fading, "time")) : 0;
- f->SetFadeTime(ftime);
+ struct json_object *fading = json_object_object_get(element, "fading");
+ if (fading) {
+ d->SetFadeTime(json_object_get_double(fading));
+ }
- sender.AddFixture(f);
}
/*
* scenes
*/
- struct json_object *scenes = json_object_object_get(config, "scenes");
- int scenenum = json_object_array_length(scenes);
- std::clog << "Trying to import " << scenenum << " scene(s)" << std::endl;
+ in_data = json_object_object_get(config, "scenes");
+ in_length = json_object_array_length(in_data);
+ std::clog << "Trying to import " << in_length << " scene(s)" << std::endl;
- for (int i = 0; i < scenenum; i++) { // read all
- struct json_object *scene = json_object_array_get_idx(scenes, i);
+ for (int i = 0; i < in_length; i++) { // read all
+ struct json_object *scene = json_object_array_get_idx(in_data, i);
// get name & create
struct json_object *name = json_object_object_get(scene, "name");
@@ -444,8 +503,8 @@
knxdmxd::Cue* cue = json_get_cue(json_object_array_get_idx(cues, i), i,
knxdmxd::kCue);
- knxdmxd::fixture_lock_t lock = { cname, prio };
- cue->SetLock(lock);
+ /*knxdmxd::fixture_lock_t lock = { cname, prio };
+ cue->SetLock(lock);*/
c->AddCue(*cue);
}
@@ -512,6 +571,7 @@
return 1;
default:
abort();
+ break;
}
//FIXME: clean shutdown in sub-thread with signals?
Modified: tools/knxdmxd/src/knxdmxd.h
===================================================================
--- tools/knxdmxd/src/knxdmxd.h 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/knxdmxd.h 2012-08-12 16:41:47 UTC (rev 942)
@@ -13,20 +13,45 @@
#include <map>
#include <string>
#include <log.h>
-
+#include <queue>
+#include <set>
#include <eibclient.h>
#include <ola/DmxBuffer.h>
#include <ola/thread/Thread.h>
+#include <sys/time.h>
#define DMX_INTERVAL 50 // in ms
+
namespace knxdmxd {
const int kFixture = 1;
const int kScene = 2;
const int kCue = 4;
const int kCuelist = 8;
+ typedef long dmx_addr_t;
+
+ typedef struct {
+ eibaddr_t ga;
+ long value;
+ } eib_message_t;
+
class DMXSender;
+ class Trigger;
+ class Timer {
+ private:
+ unsigned long start_time_;
+ public:
+ Timer() {
+ start_time_ = Get();
+ }
+ static unsigned long Get() {
+ struct timeval tv ;
+ gettimeofday(&tv, NULL) ;
+ return (unsigned long)tv.tv_sec*1000UL+ (unsigned long)tv.tv_usec/1000;
+ }
+ };
+
class KNXHandler: public ola::thread::Thread {
public:
KNXHandler() :
@@ -35,7 +60,15 @@
}
~KNXHandler() {
}
+ static std::queue<Trigger> fromKNX;
+ static ola::thread::Mutex mutex_fromKNX;
+ static std::queue<eib_message_t> toKNX;
+ static ola::thread::Mutex mutex_toKNX;
+ static std::set<eibaddr_t> listenGA;
+ static std::map<eibaddr_t, long> messagetracker;
+
+
static eibaddr_t Address(const std::string addr);
void knxhandler();
@@ -43,8 +76,8 @@
eibd_url_ = EIBD_URL;
}
const std::string& GetEIBDURL() {
- return eibd_url_;
- }
+ return eibd_url_;
+ }
void *Run() {
ola::thread::MutexLocker locker(&m_mutex);
knxhandler();
@@ -54,6 +87,7 @@
private:
ola::thread::Mutex m_mutex;
std::string eibd_url_;
+ std::map<eibaddr_t, unsigned long> lastmsg;
};
class OLAThread: public ola::thread::Thread {
Modified: tools/knxdmxd/src/trigger.cc
===================================================================
--- tools/knxdmxd/src/trigger.cc 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/trigger.cc 2012-08-12 16:41:47 UTC (rev 942)
@@ -7,10 +7,11 @@
*/
#include "trigger.h"
+#include "ola/thread/Thread.h"
namespace knxdmxd {
- Trigger::Trigger(const int type, int knx, const int val) {
+ Trigger::Trigger(const int type = kTriggerAll, const eibaddr_t knx=0, const unsigned val=0) {
_type= type;
_knx = knx;
_val = val;
@@ -19,7 +20,7 @@
bool Trigger::operator==(const Trigger &other) const {
return ((_knx == other._knx) // same knx
&& ((_type == other._type) || (other._type == kTriggerAll) || (_type==kTriggerAll)) // same trigger type
- && ((_val == other._val) || (other._val ==-1) || (_val==-1))); // same value
+ && ((_val == other._val) || (other._val==256) || (_val==256))); // same value
}
Trigger& Trigger::operator= (Trigger const& other) {
@@ -37,7 +38,16 @@
std::clog << "Added Trigger " << trigger << " for handler " << (*handler) << std::endl;
}
- void TriggerList::Process(const Trigger& trigger) {
+ void TriggerList::Process() {
+ if (KNXHandler::fromKNX.empty())
+ return;
+ Trigger trigger;
+ {
+ ola::thread::MutexLocker locker(&KNXHandler::mutex_fromKNX);
+ trigger = KNXHandler::fromKNX.front();
+ KNXHandler::fromKNX.pop();
+ }
+
for (unsigned i=0; i<_triggers.size(); i++) {
knxdmxd::Trigger tr = _triggers[i];
if (tr==trigger) {
@@ -54,7 +64,8 @@
case kTriggerProcess:
_handlers[i]->Process(trigger);
break;
- default: ;
+ default:
+ break;
}
}
}
Modified: tools/knxdmxd/src/trigger.h
===================================================================
--- tools/knxdmxd/src/trigger.h 2012-08-12 16:33:10 UTC (rev 941)
+++ tools/knxdmxd/src/trigger.h 2012-08-12 16:41:47 UTC (rev 942)
@@ -24,17 +24,17 @@
const int kTriggerProcess = 256;
class Trigger {
- int _knx;
- int _val;
+ eibaddr_t _knx;
+ unsigned _val;
int _type;
public:
- Trigger(const int type, const int knx, const int val);
+ Trigger(const int type, const eibaddr_t knx, const unsigned val);
bool operator == (const Trigger &other) const;
Trigger& operator = (const Trigger &other);
- const int GetKNX() const { return _knx; };
- const int GetValue() const { return _val; };
+ const eibaddr_t GetKNX() const { return _knx; };
+ const unsigned GetValue() const { return _val; };
const int GetType() const { return _type; };
friend std::ostream& operator<<(std::ostream &stream, const Trigger& t);
@@ -50,7 +50,8 @@
virtual void Direct(const int val) {};
virtual void Release() {};
virtual void Process(const Trigger& trigger) {};
-
+ virtual ~TriggerHandler() {};
+
friend std::ostream& operator<<(std::ostream &stream, const TriggerHandler& handler);
};
@@ -63,7 +64,7 @@
TriggerList() { };
void Add(Trigger& trigger, pTriggerHandler handler);
- void Process(const Trigger& trigger);
+ void Process();
};
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|