00001 #include <unistd.h>
00002 #include <fcntl.h>
00003 #include <stdio.h>
00004 #include <unistd.h>
00005 #include <termios.h>
00006 #include <sys/ioctl.h>
00007
00008 #include "X10Recv.h"
00009 #include "SerialOp.h"
00010
00011 namespace rwil {
00012 using namespace SerialOp;
00013 std::string X10Recv::GetRealHouse(char house) const
00014 {
00015 switch(house)
00016 {
00017 case 'F' : return "A";
00018 case 'N' : return "B";
00019 case 'B' : return "C";
00020 case 'J' : return "D";
00021 case 'A' : return "E";
00022 case 'I' : return "F";
00023 case 'E' : return "G";
00024 case 'M' : return "H";
00025 case 'G' : return "I";
00026 case 'O' : return "J";
00027 case 'C' : return "K";
00028 case 'K' : return "L";
00029 case '@' : return "M";
00030 case 'H' : return "N";
00031 case 'D' : return "O";
00032 case 'L' : return "P";
00033 }
00034 return "";
00035 assert(0);
00036 }
00037
00038 std::string X10Recv::GetRealNumber(char unitnumber) const
00039 {
00040 switch(unitnumber)
00041 {
00042 case 'L' : return "1";
00043 case '\\' : return "2";
00044 case 'D' : return "3";
00045 case 'T' : return "4";
00046 case 'B' : return "5";
00047 case 'R' : return "6";
00048 case 'J' : return "7";
00049 case 'Z' : return "8";
00050 case 'N' : return "9";
00051 case '^' : return "10";
00052 case 'F' : return "11";
00053 case 'V' : return "12";
00054 case '@' : return "13";
00055 case 'P' : return "14";
00056 case 'H' : return "15";
00057 case 'X' : return "16";
00058 }
00059 return "";
00060 assert(0);
00061 }
00062
00063 std::string X10Recv::GetMessageType(char type) const
00064 {
00065 switch(type)
00066 {
00067 case 'A' : return "all-units-off";
00068 case 'C' : return "all-lights-on";
00069 case 'E' : return "on";
00070 case 'G' : return "off";
00071 case 'I' : return "dim";
00072 case 'K' : return "bright";
00073 case 'M' : return "all-lights-off";
00074 case 'O' : return "extended-code";
00075 case 'Q' : return "hail-request";
00076 case 'W' : return "pre-set-dim-high";
00077 case 'U' : return "pre-set-dim-low";
00078 case 'Y' : return "extended-data";
00079 case '[' : return "status-on";
00080 case ']' : return "status-off";
00081 case '_' : return "status-request";
00082 }
00083 return "";
00084 assert(0);
00085 }
00086
00087 bool X10Recv::Tick()
00088 {
00089 std::string messagetype;
00090 std::string unitnumber;
00091 std::string house;
00092 char buf[5];
00093
00094 int waiting;
00095 if(fd==0)
00096 {
00097 open_port();
00098 configure_port();
00099 }
00100
00101 while(true)
00102 {
00103 int n;
00104 ioctl(fd, FIONREAD, &waiting);
00105 if(waiting < 5) return false;
00106
00107 n = read(fd, buf, 1);
00108 if(n < 0) return false;
00109 if(n == 1)
00110 {
00111 if((buf[0] == 0x58) || (buf[0] == 0x78))
00112 break;
00113 }
00114 }
00115
00116
00117 int n;
00118 int totalread = 0;
00119 while(totalread < 4)
00120 {
00121 n = read(fd, buf + 1 + totalread, 4-totalread);
00122 if(n < 0) return false;
00123 totalread += n;
00124 }
00125 house = GetRealHouse(buf[1]);
00126 unitnumber = GetRealNumber(buf[2]);
00127 messagetype = GetMessageType(buf[2]);
00128
00129
00130 if(!((buf[4] == 0x0d) || (buf[4] == 0x0a))) return false;
00131 if(house.length() == 0) return false;
00132 if((unitnumber.length() == 0) && (messagetype.length() == 0)) return false;
00133 if(unitnumber.length())
00134 {
00135 activenums[house] = unitnumber;
00136 return true;
00137 }
00138 if(activenums[house].length() == 0) return true;
00139
00140 Message msg(GetName(), messagetype);
00141 msg.SetParam("house", house);
00142 msg.SetParam("number", activenums[house]);
00143 m_output.Add(msg);
00144
00145
00146 }
00147
00148 }
00149