2017-08-12 Fred Gleason <fredg@paravelsystems.com>

* Implemented a driver for WheatNet SLIO devices.
This commit is contained in:
Fred Gleason 2017-08-12 16:50:49 -04:00
parent 98e9c89dec
commit 6a174ae612
8 changed files with 489 additions and 7 deletions

View File

@ -15929,3 +15929,5 @@
'rlm_filewrite' RLM from 256 to 8192 characters. 'rlm_filewrite' RLM from 256 to 8192 characters.
2017-08-07 Fred Gleason <fredg@paravelsystems.com> 2017-08-07 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.16.0int06_rfa02. * Incremented the package version to 2.16.0int06_rfa02.
2017-08-12 Fred Gleason <fredg@paravelsystems.com>
* Implemented a driver for WheatNet SLIO devices.

View File

@ -37,6 +37,7 @@ Sine Systems ACU-1 (Prophet version)
Software Authority Protocol Software Authority Protocol
StarGuide III Satellite Receiver StarGuide III Satellite Receiver
Wegener Unity4000 DVB Satellite Receiver Wegener Unity4000 DVB Satellite Receiver
WheatNet Blade SLIO
See the sections below for notes on each specific model. See the sections below for notes on each specific model.
@ -851,4 +852,18 @@ output at a time. Commanding a stream to an output will cause that
stream to be silently deselected from a previously selected output. stream to be silently deselected from a previously selected output.
----------------------------------------------------------------------------
WHEATNET BLADE SLIO
Driver Name: WheatNet SLIO
Supported RML Commands:
GPO Set ('GO')
GENERAL NOTES:
Control is done by means of a TCP/IP connection to port 55776 on a blade.
The only required configuration parameters are IP Address and IP Port.
The number of pins is auto-detected at driver startup.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------

View File

@ -68,7 +68,8 @@ bool __mx_primary_controls[RDMatrix::LastType][RDMatrix::LastControl]=
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT ADMS 44.22 {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT ADMS 44.22
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT SS 4.1 MLR {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0}, // BT SS 4.1 MLR
{0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, // Modbus {0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, // Modbus
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0} // Kernel GPIO {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, // Kernel GPIO
{0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0} // WheatNet SLIO
}; };
bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]= bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]=
{ {
@ -113,7 +114,8 @@ bool __mx_backup_controls[RDMatrix::LastType][RDMatrix::LastControl]=
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT ADMS 44.22 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT ADMS 44.22
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT SS 4.1 MLR {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // BT SS 4.1 MLR
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Modbus {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Modbus
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // Kernel GPIO {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Kernel GPIO
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // WheatNet SLIO
}; };
int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]= int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]=
@ -159,7 +161,8 @@ int __mx_default_values[RDMatrix::LastType][RDMatrix::LastControl]=
{0,0,0,0,0,0,0,0,0,0,0,8,2,16,13,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT ADMS 44.22 {0,0,0,0,0,0,0,0,0,0,0,8,2,16,13,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT ADMS 44.22
{0,0,0,0,0,0,0,0,0,0,0,4,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT SS 4.1 MLR {0,0,0,0,0,0,0,0,0,0,0,4,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // BT SS 4.1 MLR
{1,0,0,502,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Modbus {1,0,0,502,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Modbus
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // Kernel GPIO {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, // Kernel GPIO
{1,0,0,55776,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0} // WheatNet SLIO
}; };
RDMatrix::RDMatrix(const QString &station,int matrix) RDMatrix::RDMatrix(const QString &station,int matrix)
@ -731,6 +734,10 @@ QString RDMatrix::typeString(RDMatrix::Type type)
return QString("Kernel GPIO"); return QString("Kernel GPIO");
break; break;
case RDMatrix::WheatnetSlio:
return QString("WheatNet SLIO");
break;
default: default:
return QString("Unknown Type"); return QString("Unknown Type");
break; break;

View File

@ -38,7 +38,7 @@ class RDMatrix
BtSrc16=24,Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28, BtSrc16=24,Harlond=25,Acu1p=26,LiveWireMcastGpio=27,Am16=28,
LiveWireLwrpGpio=29,BtSentinel4Web=30,BtGpi16=31,ModemLines=32, LiveWireLwrpGpio=29,BtSentinel4Web=30,BtGpi16=31,ModemLines=32,
SoftwareAuthority=33,Sas16000=34,RossNkScp=35,BtAdms4422=36, SoftwareAuthority=33,Sas16000=34,RossNkScp=35,BtAdms4422=36,
BtSs41Mlr=37,Modbus=38,KernelGpio=39,LastType=40}; BtSs41Mlr=37,Modbus=38,KernelGpio=39,WheatnetSlio=40,LastType=41};
enum Endpoint {Input=0,Output=1}; enum Endpoint {Input=0,Output=1};
enum Mode {Stereo=0,Left=1,Right=2}; enum Mode {Stereo=0,Left=1,Right=2};
enum VguestAttribute {VguestEngine=0,VguestDevice=1,VguestSurface=2, enum VguestAttribute {VguestEngine=0,VguestDevice=1,VguestSurface=2,

View File

@ -76,7 +76,8 @@ dist_ripcd_SOURCES = acu1p.cpp acu1p.h\
switcher.cpp switcher.h\ switcher.cpp switcher.h\
unity4000.cpp unity4000.h\ unity4000.cpp unity4000.h\
unity_feed.cpp unity_feed.h\ unity_feed.cpp unity_feed.h\
vguest.cpp vguest.h vguest.cpp vguest.h\
wheatnet_slio.cpp wheatnet_slio.h
nodist_ripcd_SOURCES = moc_am16.cpp\ nodist_ripcd_SOURCES = moc_am16.cpp\
moc_acu1p.cpp\ moc_acu1p.cpp\
@ -118,7 +119,8 @@ nodist_ripcd_SOURCES = moc_am16.cpp\
moc_swauthority.cpp\ moc_swauthority.cpp\
moc_switcher.cpp\ moc_switcher.cpp\
moc_unity4000.cpp\ moc_unity4000.cpp\
moc_vguest.cpp moc_vguest.cpp\
moc_wheatnet_slio.cpp
ripcd_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ ripcd_LDADD = @LIB_RDLIBS@ @LIBVORBIS@

View File

@ -2,7 +2,7 @@
// //
// Load Switcher drivers for ripcd(8) // Load Switcher drivers for ripcd(8)
// //
// (C) Copyright 2002-2016 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2017 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as // it under the terms of the GNU General Public License version 2 as
@ -61,6 +61,7 @@
#include <swauthority.h> #include <swauthority.h>
#include <unity4000.h> #include <unity4000.h>
#include <vguest.h> #include <vguest.h>
#include <wheatnet_slio.h>
bool MainObject::LoadSwitchDriver(int matrix_num) bool MainObject::LoadSwitchDriver(int matrix_num)
{ {
@ -219,6 +220,10 @@ bool MainObject::LoadSwitchDriver(int matrix_num)
ripcd_switcher[matrix_num]=new Unity4000(matrix,this); ripcd_switcher[matrix_num]=new Unity4000(matrix,this);
break; break;
case RDMatrix::WheatnetSlio:
ripcd_switcher[matrix_num]=new WheatnetSlio(matrix,this);
break;
default: default:
ripcd_switcher[matrix_num]=NULL; ripcd_switcher[matrix_num]=NULL;
delete matrix; delete matrix;

370
ripcd/wheatnet_slio.cpp Normal file
View File

@ -0,0 +1,370 @@
// wheatnet_slio.cpp
//
// A Rivendell switcher driver for Modbus TCP
//
// (C) Copyright 2017 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <syslog.h>
#include <rddb.h>
#include <rdescape_string.h>
#include "wheatnet_slio.h"
WheatnetSlio::WheatnetSlio(RDMatrix *matrix,QObject *parent)
: Switcher(matrix,parent)
{
slio_watchdog_active=false;
slio_gpios=0;
slio_ip_address=matrix->ipAddress(RDMatrix::Primary);
slio_ip_port=matrix->ipPort(RDMatrix::Primary);
slio_socket=new QSocket(this);
connect(slio_socket,SIGNAL(connected()),this,SLOT(connectedData()));
connect(slio_socket,SIGNAL(readyRead()),this,SLOT(readyReadData()));
connect(slio_socket,SIGNAL(error(int)),this,SLOT(errorData(int)));
slio_socket->connectToHost(slio_ip_address.toString(),slio_ip_port);
slio_poll_timer=new QTimer(this);
connect(slio_poll_timer,SIGNAL(timeout()),this,SLOT(pollInputs()));
slio_reset_mapper=new QSignalMapper(this);
connect(slio_reset_mapper,SIGNAL(mapped(int)),
this,SLOT(resetStateData(int)));
for(int i=0;i<slio_gpios;i++) {
slio_reset_timers.push_back(new QTimer(this));
connect(slio_reset_timers.back(),SIGNAL(timeout()),
slio_reset_mapper,SLOT(map()));
slio_reset_mapper->setMapping(slio_reset_timers.back(),i);
slio_reset_states.push_back(false);
}
slio_watchdog_timer=new QTimer(this);
connect(slio_watchdog_timer,SIGNAL(timeout()),this,SLOT(watchdogData()));
}
WheatnetSlio::~WheatnetSlio()
{
delete slio_watchdog_timer;
delete slio_poll_timer;
for(unsigned i=0;i<slio_reset_timers.size();i++) {
delete slio_reset_timers[i];
}
delete slio_reset_mapper;
delete slio_socket;
}
RDMatrix::Type WheatnetSlio::type()
{
return RDMatrix::WheatnetSlio;
}
unsigned WheatnetSlio::gpiQuantity()
{
return slio_gpios;
}
unsigned WheatnetSlio::gpoQuantity()
{
return slio_gpios;
}
bool WheatnetSlio::primaryTtyActive()
{
return false;
}
bool WheatnetSlio::secondaryTtyActive()
{
return false;
}
void WheatnetSlio::processCommand(RDMacro *cmd)
{
switch(cmd->command()) {
case RDMacro::GO:
if((cmd->argQuantity()!=5)||
((cmd->arg(1).toString().lower()!="i")&&
(cmd->arg(1).toString().lower()!="o"))||
(cmd->arg(2).toInt()<1)||(cmd->arg(3).toInt()>slio_gpios)||
(cmd->arg(2).toInt()>slio_gpios)||
((cmd->arg(3).toInt()!=1)&&(cmd->arg(3).toInt()!=0)&&
(cmd->arg(1).toString().lower()!="i"))||
((cmd->arg(3).toInt()!=1)&&(cmd->arg(3).toInt()!=0)&&
(cmd->arg(3).toInt()!=-1)&&(cmd->arg(1).toString().lower()=="i"))||
(cmd->arg(4).toInt()<0)) {
cmd->acknowledge(false);
emit rmlEcho(cmd);
return;
}
if(cmd->arg(3).toInt()==0) { // Turn OFF
if(cmd->arg(4).toInt()==0) {
if(cmd->arg(1).toString().lower()=="o") {
SendCommand(QString().sprintf("<SLIO:%d|LVL:0>",cmd->arg(2).toInt()));
emit gpoChanged(matrixNumber(),cmd->arg(2).toInt()-1,false);
}
}
else {
if(cmd->echoRequested()) {
cmd->acknowledge(false);
emit rmlEcho(cmd);
}
return;
}
}
else {
if(cmd->arg(4).toInt()==0) { // Turn ON
if(cmd->arg(1).toString().lower()=="o") {
SendCommand(QString().sprintf("<SLIO:%d|LVL:1>",cmd->arg(2).toInt()));
emit gpoChanged(matrixNumber(),cmd->arg(2).toInt()-1,true);
}
}
else { // Pulse
if(cmd->arg(1).toString().lower()=="o") {
SendCommand(QString().sprintf("<SLIO:%d|LVL:%d>",
cmd->arg(2).toInt(),
cmd->arg(3).toInt()!=0));
slio_reset_states[cmd->arg(2).toInt()-1]=cmd->arg(3).toInt()==0;
slio_reset_timers[cmd->arg(2).toInt()-1]->
start(cmd->arg(4).toInt(),true);
emit gpoChanged(matrixNumber(),cmd->arg(2).toInt()-1,
cmd->arg(3).toInt()!=0);
}
}
}
if(cmd->echoRequested()) {
cmd->acknowledge(true);
emit rmlEcho(cmd);
}
break;
default:
break;
}
}
void WheatnetSlio::connectedData()
{
syslog(LOG_INFO,
"connection to WheatNet SLIO device at %s:%u established",
(const char *)slio_ip_address.toString(),0xffff&slio_ip_port);
slio_watchdog_active=false;
SendCommand("<SYS?SLIO>");
}
void WheatnetSlio::readyReadData()
{
char data[1501];
int n=0;
while((n=slio_socket->readBlock(data,1500))>0) {
data[n]=0;
for(int i=0;i<n;i++) {
switch(0xff&data[i]) {
case 13:
break;
case 10:
ProcessCommand(slio_accum);
slio_accum="";
break;
default:
slio_accum+=data[i];
break;
}
}
}
}
void WheatnetSlio::errorData(int err)
{
watchdogData();
}
void WheatnetSlio::pollInputs()
{
for(int i=0;i<slio_gpios;i++) {
SendCommand(QString().sprintf("<SLIO:%d?LVL>",i+1));
}
}
void WheatnetSlio::resetStateData(int line)
{
SendCommand(QString().sprintf("<SLIO:%d|LVL:%d>",line+1,
(int)slio_reset_states[line]));
emit gpoChanged(matrixNumber(),line,slio_reset_states[line]);
}
void WheatnetSlio::watchdogData()
{
if(!slio_watchdog_active) {
syslog(LOG_WARNING,
"connection to Wheatnet SLIO device at %s:%u lost, attempting reconnect",
(const char *)slio_ip_address.toString(),0xffff&slio_ip_port);
slio_watchdog_active=true;
}
slio_socket->close();
slio_socket->connectToHost(slio_ip_address.toString(),slio_ip_port);
}
void WheatnetSlio::CheckLineEntry(int line)
{
QString sql;
RDSqlQuery *q;
sql=QString("select ID from GPIS where ")+
"(STATION_NAME=\""+RDEscapeString(stationName())+"\")&&"+
QString().sprintf("(MATRIX=%d)&&",matrixNumber())+
QString().sprintf("(NUMBER=%d)",line);
q=new RDSqlQuery(sql);
if(!q->first()) {
delete q;
sql=QString("insert into GPIS set ")+
"STATION_NAME=\""+RDEscapeString(stationName())+"\","+
QString().sprintf("MATRIX=%d,",matrixNumber())+
QString().sprintf("NUMBER=%d",line);
q=new RDSqlQuery(sql);
}
delete q;
sql=QString("select ID from GPOS where ")+
"(STATION_NAME=\""+RDEscapeString(stationName())+"\")&&"+
QString().sprintf("(MATRIX=%d)&&",matrixNumber())+
QString().sprintf("(NUMBER=%d)",line);
q=new RDSqlQuery(sql);
if(!q->first()) {
delete q;
sql=QString("insert into GPOS set ")+
"STATION_NAME=\""+RDEscapeString(stationName())+"\","+
QString().sprintf("MATRIX=%d,",matrixNumber())+
QString().sprintf("NUMBER=%d",line);
q=new RDSqlQuery(sql);
}
delete q;
}
void WheatnetSlio::ProcessSys(const QString &cmd)
{
// printf("SYS: %s\n",(const char *)cmd);
QString sql;
RDSqlQuery *q;
bool ok=false;
QStringList f0=f0.split(":",cmd);
if((f0[0]=="SLIO")&&(f0.size()==2)) {
int slio=f0[1].toUInt(&ok);
if(ok) {
slio_gpios=slio;
for(unsigned i=0;i<slio_reset_timers.size();i++) {
delete slio_reset_timers[i];
}
slio_reset_timers.clear();
slio_reset_states.clear();
slio_gpi_states.clear();
for(int i=0;i<slio_gpios;i++) {
slio_reset_timers.push_back(new QTimer(this));
connect(slio_reset_timers.back(),SIGNAL(timeout()),
slio_reset_mapper,SLOT(map()));
slio_reset_mapper->setMapping(slio_reset_timers.back(),i);
slio_reset_states.push_back(false);
slio_gpi_states.push_back(false);
CheckLineEntry(i+1);
}
sql=QString("update MATRICES set ")+
QString().sprintf("GPIS=%d,GPOS=%d where ",slio_gpios,slio_gpios)+
"(STATION_NAME=\""+RDEscapeString(stationName())+"\")&&"+
QString().sprintf("(MATRIX=%d)",matrixNumber());
q=new RDSqlQuery(sql);
delete q;
pollInputs();
}
}
}
void WheatnetSlio::ProcessSlio(int chan,QString &cmd)
{
// printf("ProcessSlip(%d,%s)\n",chan,(const char *)cmd);
QStringList f0=f0.split(":",cmd);
if((f0[0]=="LVL")&&(f0.size()==2)) {
if(chan<=(int)slio_gpi_states.size()) {
bool state=f0[1]=="1";
if(state!=slio_gpi_states[chan-1]) {
printf("change chan: %d state: %d\n",chan,state);
slio_gpi_states[chan-1]=state;
emit gpiChanged(matrixNumber(),chan-1,state);
}
}
else {
syslog(LOG_WARNING,
"WheatNet device at %s:%d sent invalid SLIO LVL update [%s]",
(const char *)slio_ip_address.toString(),
slio_ip_port,(const char *)cmd);
}
if(chan==slio_gpios) {
slio_poll_timer->start(50,true);
slio_watchdog_timer->stop();
slio_watchdog_timer->start(1000,true);
}
}
}
void WheatnetSlio::ProcessCommand(const QString &cmd)
{
// printf("ProcessCommand(%s)\n",(const char *)cmd);
bool ok=false;
if((cmd.left(1)=="<")&&(cmd.right(1)==">")) {
QStringList f0=f0.split("|",cmd.mid(1,cmd.length()-2));
if(f0.size()==2) {
QStringList f1=f1.split(":",f0[0]);
if(f1[0]=="SYS") {
ProcessSys(f0[1]);
}
if((f1[0]=="SLIO")&&(f1.size()==2)) {
int chan=f1[1].toUInt(&ok);
if(ok) {
ProcessSlio(chan,f0[1]);
}
}
}
}
}
void WheatnetSlio::SendCommand(const QString &cmd)
{
slio_socket->writeBlock(cmd+"\r\n",cmd.length()+2);
}

81
ripcd/wheatnet_slio.h Normal file
View File

@ -0,0 +1,81 @@
// wheatnet_slio.h
//
// A Rivendell switcher driver for Wheatnet SLIO devices
//
// (C) Copyright 2017 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#ifndef WHEATNET_SLIO_H
#define WHEATNET_SLIO_H
#include <vector>
#include <qsignalmapper.h>
#include <qsocket.h>
#include <qtimer.h>
#include <rd.h>
#include <rdmatrix.h>
#include <rdmacro.h>
#include <switcher.h>
#define WHEATNET_SLIO_POLL_INTERVAL 100
#define WHEATNET_SLIO_WATCHDOG_INTERVAL 1000
class WheatnetSlio : public Switcher
{
Q_OBJECT
public:
WheatnetSlio(RDMatrix *matrix,QObject *parent=0);
~WheatnetSlio();
RDMatrix::Type type();
unsigned gpiQuantity();
unsigned gpoQuantity();
bool primaryTtyActive();
bool secondaryTtyActive();
void processCommand(RDMacro *cmd);
private slots:
void connectedData();
void readyReadData();
void errorData(int err);
void pollInputs();
void resetStateData(int line);
void watchdogData();
private:
void CheckLineEntry(int line);
void ProcessSys(const QString &cmd);
void ProcessSlio(int chan,QString &cmd);
void ProcessCommand(const QString &cmd);
void SendCommand(const QString &cmd);
QSocket *slio_socket;
QTimer *slio_poll_timer;
QTimer *slio_watchdog_timer;
bool slio_watchdog_active;
QHostAddress slio_ip_address;
uint16_t slio_ip_port;
int slio_gpios;
QString slio_accum;
std::vector<bool> slio_gpi_states;
QSignalMapper *slio_reset_mapper;
std::vector<QTimer *> slio_reset_timers;
std::vector<bool> slio_reset_states;
};
#endif // WHEATNET_SLIO_H