# x10interface.cpp

Go to the documentation of this file.

    00001 /*
    00002  * SmartHome server: Plug-in x10
    00003  *
    00004  * Copyright (C) 2010 Daniel Pisi <dan.pisi@gmail.com>
    00005  *
    00006  * This program is free software; you can redistribute it and/or modify it
    00007  * under the terms of version 2 of the GNU General Public License
    00008  * as published by the Free Software Foundation.
    00009  *
    00010  */
    00011
    00018 #include "x10interface.h"
    00019 #include <QWeakPointer>
    00020 // -----------------------------------------------------------------------------
    00021
    00027 X10Interface::X10Interface(QString device, QObject *parent) : QObject(parent)
    00028 {
    00029     mX10Port = new QextSerialPort(device, QextSerialPort::EventDriven);
    00030     mX10Port->setBaudRate(BAUD4800);
    00031     mX10Port->setFlowControl(FLOW_OFF);
    00032     mX10Port->setDataBits(DATA_8);
    00033     mX10Port->setStopBits(STOP_1);
    00034     mX10Port->setParity(PAR_NONE);
    00035
    00036     if (mX10Port->open(QIODevice::ReadWrite) == true)
    00037     {
    00038         connect(mX10Port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    00039     }
    00040     else
    00041         qWarning(QString("X10 device failed to open: %1").arg(mX10Port->errorString()).toLatin1());
    00042
    00043     mTimer = new QTimer(this);
    00044     mTimer->setSingleShot(true);
    00045     mTimer->setInterval(20000);
    00046
    00047     connect(mTimer, SIGNAL(timeout()), this, SLOT(onTimeout()));
    00048
    00049     mX10Port->write("X10Ready ");
    00050     mState = stReady;
    00051 }
    00052 // -----------------------------------------------------------------------------
    00053
    00057 void X10Interface::sendNextPacket()
    00058 {
    00059     if (mPacketQueue.isEmpty())
    00060     {
    00061         mTimer->stop();
    00062         mState = stReady;
    00063         emit transmissionDone();
    00064     }
    00065     else
    00066     {
    00067         QByteArray arr = mPacketQueue.head()->frameData();
    00068         qDebug(QString("Sending packet %1 %2").arg(QString::number(arr[0], 16), QString::number(arr[1], 16)).toAscii());
    00069         mTimer->start();
    00070         mX10Port->write(mPacketQueue.head()->frameData());
    00071         mState = stCmdSent;
    00072     }
    00073 }
    00074 // -----------------------------------------------------------------------------
    00075
    00079 void X10Interface::sendTime()
    00080 {
    00081     char data[7];
    00082     QDateTime dateTime = QDateTime::currentDateTime();
    00083
    00084     data[0]  =  0x9B;
    00085     data[1]  =  dateTime.time().second();
    00086     data[2]  =  dateTime.time().minute();
    00087     data[3]  =  dateTime.time().hour() % 12;
    00088     data[4]  =  dateTime.date().dayOfYear() & 0xFF;
    00089     data[5]  = (dateTime.date().dayOfYear() & 0x100) >> 8;
    00090     data[5] |=  0x80 >> (dateTime.date().dayOfWeek() % 7);
    00091     data[6]  =  0x00;
    00092
    00093     mX10Port->write(data, 7);
    00094     qDebug("Time sent");
    00095 }
    00096 // -----------------------------------------------------------------------------
    00097
    00103 bool X10Interface::enqueueAddressing(QString devices)
    00104 {
    00105     QRegExp rxn("([A-P])(1[0-5]|[0-9])((?:\\s*,\\s*)(1[0-5]|[0-9]))*");
    00106     if (!rxn.exactMatch(devices))
    00107         return false;
    00108
    00109     QStringList deviceList = devices.split(QRegExp("[^0-9]+"), QString::SkipEmptyParts);
    00110
    00111     X10PacketPtr packet;
    00112     foreach (QString device, deviceList)
    00113     {
    00114         packet = X10PacketPtr(new X10Packet);
    00115         packet->setHousecode(devices[0].toAscii());
    00116         packet->setDevicecode(device.toInt());
    00117         mPacketQueue.enqueue(packet);
    00118     }
    00119     return true;
    00120 }
    00121 // -----------------------------------------------------------------------------
    00122
    00129 bool X10Interface::onOffDevices(QString devices, bool on)
    00130 {
    00131     if ((mState != stReady) || (!enqueueAddressing(devices)))
    00132         return false;
    00133
    00134     X10PacketPtr packet;
    00135
    00136     packet = X10PacketPtr(new X10Packet);
    00137     packet->setHousecode(devices[0].toAscii());
    00138     packet->setFunction(on ? X10Packet::fcOn : X10Packet::fcOff);
    00139     mPacketQueue.enqueue(packet);
    00140
    00141     sendNextPacket();
    00142
    00143     qDebug("on/off");
    00144     return true;
    00145 }
    00146 // -----------------------------------------------------------------------------
    00147
    00154 bool X10Interface::dimLights(QString devices, int dim)
    00155 {
    00156     if ((mState != stReady) || (!enqueueAddressing(devices)))
    00157         return false;
    00158
    00159     X10Packet::X10Function fce;
    00160
    00161     fce = (dim >= 0) ? X10Packet::fcBright : X10Packet::fcDim;
    00162     dim = qMin(qAbs(dim), 22);
    00163
    00164     X10PacketPtr packet;
    00165     packet = X10PacketPtr(new X10Packet);
    00166     packet->setHousecode(devices[0].toAscii());
    00167     packet->setFunction(fce);
    00168     packet->setDimAmount(dim);
    00169     mPacketQueue.enqueue(packet);
    00170
    00171     sendNextPacket();
    00172     qDebug("dimming");
    00173     return true;
    00174 }
    00175 // -----------------------------------------------------------------------------
    00176
    00183 bool X10Interface::onOffAllLights(char house, bool on)
    00184 {
    00185     if (mState != stReady)
    00186         return false;
    00187
    00188     X10PacketPtr packet;
    00189
    00190     packet = X10PacketPtr(new X10Packet);
    00191     packet->setHousecode(house);
    00192     packet->setFunction(on ? X10Packet::fcAllLightsOn : X10Packet::fcAllLightsOff);
    00193     mPacketQueue.enqueue(packet);
    00194
    00195     sendNextPacket();
    00196     return true;
    00197 }
    00198 // -----------------------------------------------------------------------------
    00199
    00203 void X10Interface::onReadyRead()
    00204 {
    00205     char b;
    00206
    00207     if (mX10Port->bytesAvailable())
    00208     {
    00209         mX10Port->read(&b, 1);
    00210
    00211         switch (mState)
    00212         {
    00213         case stCmdSent:
    00214             if ((quint8)b == mPacketQueue.head()->checksum())
    00215             {
    00216                 qDebug("Checksum OK");
    00217                 mX10Port->putChar(0x00);
    00218                 mPacketQueue.dequeue();
    00219                 mState = stChecksumOk;
    00220             }
    00221             else
    00222                 sendNextPacket();
    00223             break;
    00224
    00225         case stChecksumOk:
    00226             sendNextPacket();
    00227             break;
    00228
    00229         case stReady:
    00230             if ((quint8)b == 0xA5)
    00231                 sendTime();
    00232             break;
    00233         }
    00234     }
    00235     else
    00236         qWarning("Nothing was available");
    00237 }
    00238 // -----------------------------------------------------------------------------
    00239
    00243 void X10Interface::onTimeout()
    00244 {
    00245     mTimer->stop();
    00246
    00247     mPacketQueue.clear();
    00248     mState = stReady;
    00249
    00250     emit transmissionFailed("timeout");
    00251 }
    00252 // -----------------------------------------------------------------------------

All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends