public InsteonStandardMessage(DeviceAddress sourceAddress, DeviceAddress targetAddress, byte command1, byte command2, byte flagByte)
 {
     _sourceAddress = sourceAddress;
     _targetAddress = targetAddress;
     _command1 = command1;
     _command2 = command2;
     _flag = (MessageFlag)(flagByte & ((byte)0xE0));
     _flagByte = flagByte;
 }
Example #2
0
        public LinkRecord(byte recordControl, byte group, DeviceAddress address, byte localData1, byte localData2, byte localData3)
        {
            Group = group;
            _recordControl = recordControl;
            Address = address;

            _localData[0] = localData1;
            _localData[1] = localData2;
            _localData[2] = localData3;

            ParseRecordControl();
            ParseLocalData();
        }
        public ThermostatDevice(string name, DeviceAddress address, Mode mode, int setPoint)
            : base(name, address)
        {
            if (mode == Mode.Cooling)
            {
                CoolSetPoint = setPoint;
                HeatSetPoint = -1;
            }
            else if (mode == Mode.Heating)
            {
                HeatSetPoint = setPoint;
                CoolSetPoint = -1;
            }
            CurrentMode = mode;

            AmbientTemperature = -1;
        }
        private void ProcessRelatedDeviceEvents(byte command1, byte command2, DeviceAddress fromAddress, DeviceAddress toAddress)
        {
            Device sourceDevice = FindDeviceForAddress(fromAddress.ToString());
            Device targetDevice = FindDeviceForAddress(toAddress.ToString());

            // if the target is not an existing device (group target)
            // look at address entries for devices that are RESPONDERS to the
            // address of the command, matching the group in the address..
            if (null == targetDevice || targetDevice is PLMDevice)
            {
                foreach (string i in _allDevices.Keys)
                {
                    DeviceALDB devALDB = _aldbLibrary.Devices.FirstOrDefault(d => d.DeviceAddress == _allDevices[i].Address.ToString());
                    if (null == devALDB)
                        continue;

                    foreach (ALDBRecord record in devALDB.ALDBRecords)
                    {
                        // record not active
                        if ((record.Flags & 0x80) == 0)
                            continue;

                        if ((record.Flags & 0x40) == 0 && // responder
                            record.AddressToString() == fromAddress.ToString())
                        {
                         //   log.DebugFormat("Device: {0}, TargetAddress:{1}, Command2: {2}", _allDevices[i].Name, toAddress.ToString(), command2.ToString("X"));

                            // its possible a kpl button sends a direct message to the PLM and the group # is in cmd2
                            if (record.Group == toAddress.Byte3 || ((null != targetDevice) && ((targetDevice is PLMDevice) && record.Group == command2)))
                            {
                                log.Info(string.Format("Event detected matched ALDB record for device {0}, group {1}.  Local Data: {2} {3} {4}", _allDevices[i].Name, record.Group, record.LocalData1.ToString("X"), record.LocalData2.ToString("X"), record.LocalData3.ToString("X")));

                                if (_allDevices[i] is IMultiButtonDevice)
                                {
                                    IMultiButtonDevice kplDevice = _allDevices[i] as IMultiButtonDevice;
                                    // update KPL button for the action.. mainly concerned with bits --XXXX--
                                    byte flipMask = 0xFF;
                                    switch (record.LocalData3)
                                    {
                                        case 3:
                                            flipMask = 0x04;
                                            break;
                                        case 4:
                                            flipMask = 0x08;
                                            break;
                                        case 5:
                                            flipMask = 0x10;
                                            break;
                                        case 6:
                                            flipMask = 0x20;
                                            break;
                                        default:
                                            break;
                                    }

                                    if (command1 == Constants.STD_COMMAND_ON || command1 == Constants.STD_COMMAND_FAST_ON)
                                    {
                                        kplDevice.KPLButtonMask |= flipMask;
                                    }
                                    else if (command1 == Constants.STD_COMMAND_OFF || command1 == Constants.STD_COMMAND_FAST_OFF)
                                    {
                                        kplDevice.KPLButtonMask &= (byte)(0xFF ^ flipMask);
                                    }
                                    log.InfoFormat("Updated Button Mask to {0} for device {1}", kplDevice.KPLButtonMask.ToString("X"), _allDevices[i].Name);
                                }

                                if ((command1 == Constants.STD_COMMAND_FAST_ON || command1 == Constants.STD_COMMAND_ON) && _allDevices[i].DefaultOffMinutes.HasValue)
                                    _allDevices[i].SetTimer(new DeviceTimerCallBack(DeviceTimerCallBack));

                            }
                        }
                    }
                }
            }
        }
        private void ProcessExtendedGetResponse(byte[] message)
        {
            try
            {
                byte deviceAddress1 = message[2];
                byte deviceAddress2 = message[3];
                byte deviceAddress3 = message[4];

                DeviceAddress deviceAddress = new DeviceAddress(deviceAddress1, deviceAddress2, deviceAddress3);

                Device device = _allDevices[deviceAddress.ToString()];
                if (device is IMultiButtonDevice)
                {

                    IMultiButtonDevice multiButtonDevice= device as IMultiButtonDevice;

                    // for now just get the button mask...
                    multiButtonDevice.KPLButtonMask = message[21];

                    if (_gettingExtendedStatus)
                        _extendedGetWaitHandle.Set();
                }
                else if (device is ThermostatDevice){
                    ThermostatDevice thermostatDevice = device as ThermostatDevice;
                    // message[11] is data 1
                    // message[13] and 11 would be local temp high and low
                    // message[15] = data5 = humidity
                    // message[16] = data6 = tempoffset
                    // message[17] = data7 = humidity offset
                    byte systemMode = message[18];
                    byte fanMode = message[19];

                    if (fanMode == 0x00)
                    {
                        thermostatDevice.Fan = ThermostatDevice.FanMode.Auto;
                    }
                    else thermostatDevice.Fan = ThermostatDevice.FanMode.AlwaysOn;

                    if (systemMode == 0x00)
                        thermostatDevice.CurrentMode = ThermostatDevice.Mode.Off;
                    else if (systemMode == 0x01)
                        thermostatDevice.CurrentMode = ThermostatDevice.Mode.Auto;
                    else if (systemMode == 0x02)
                        thermostatDevice.CurrentMode = ThermostatDevice.Mode.Heating;
                    else if (systemMode == 0x03)
                        thermostatDevice.CurrentMode = ThermostatDevice.Mode.Cooling;
                    else
                        thermostatDevice.CurrentMode = ThermostatDevice.Mode.Program;

                    if (_gettingThermostatExtended)
                        _extendedGetWaitHandle.Set();

                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("Error processing Extended Get Response");
            }
        }
Example #6
0
 public FanDevice(string deviceName, DeviceAddress deviceAddress)
     : base(deviceName, deviceAddress)
 {
 }
        private InsteonExtendedMessage CommandBytesToExtendedMessage(byte[] command)
        {
            DeviceAddress sourceAddress = new DeviceAddress(command[2], command[3], command[4]);
            DeviceAddress targetAddress = new DeviceAddress(command[5], command[6], command[7]);
            byte messageFlag = command[8];
            byte[] extendedData = new byte[14];
            Array.Copy(command, 11, extendedData, 0, 14);
            InsteonExtendedMessage message = new InsteonExtendedMessage(sourceAddress, targetAddress, command[9], command[10], extendedData, messageFlag);

            message.CommandDescription = ExtCommandToString(command[9]);
            Device sourceDevice = _allDevices.Values.FirstOrDefault(d => d.Address == sourceAddress);
            if (null != sourceDevice)
                message.SourceName = sourceDevice.Name;
            else
                message.SourceName = sourceAddress.StringAddress;

            Device targetDevice = _allDevices.Values.FirstOrDefault(d => d.Address == targetAddress);
            if (null != targetDevice)
                message.TargetName = targetDevice.Name;
            else
                message.TargetName = targetAddress.StringAddress;

            return message;
        }
 public string SendStandardCommand(DeviceAddress deviceAddress, byte command1, byte command2, byte flags)
 {
     return SendStandardCommand(deviceAddress, command1, command2, flags, false);
 }
Example #9
0
 public Device(string name, DeviceAddress address)
 {
     Name = name;
     Address = address;
     Status = -1;
 }
Example #10
0
        public DeviceStatus GetDeviceStatus(DeviceAddress deviceAddress)
        {
            byte[] command = new byte[8];
            DeviceStatus status = new DeviceStatus();
            try
            {
                if (_allDevices[deviceAddress.ToString()] is ThermostatDevice)
                {
                    _gettingThermostat = true;

                    command[0] = 0x02;
                    command[1] = 0x62;
                    command[2] = deviceAddress.Byte1;
                    command[3] = deviceAddress.Byte2;
                    command[4] = deviceAddress.Byte3;
                    command[5] = 0x0F;
                    command[6] = Constants.STD_COMMAND_THERMOSTAT_STATUS;
                    command[7] = 0x00; // temp

                    _gettingTemp = true;
                    _plm.Write(command, 0, 8);

                    _lastSentCommand = command;

                    _statusEventWaitHandle.Reset();
                    log.Info("Calling WaitOne on StatusEventWaitHandle for Thermostat Temp");
                    _statusEventWaitHandle.WaitOne(10000);
                    log.Info("Completed waiting on temp");

                    Thread.Sleep(300);

                    command[0] = 0x02;
                    command[1] = 0x62;
                    command[2] = deviceAddress.Byte1;
                    command[3] = deviceAddress.Byte2;
                    command[4] = deviceAddress.Byte3;
                    command[5] = 0x0F;
                    command[6] = Constants.STD_COMMAND_THERMOSTAT_STATUS;
                    command[7] = 0x20; // set point

                    _gettingSetPoint = true;
                    _plm.Write(command, 0, 8);

                    _lastSentCommand = command;

                    _statusEventWaitHandle.Reset();
                    log.Info("Calling WaitOne on StatusEventWaitHandle for Thermostat set point");
                    _statusEventWaitHandle.WaitOne(10000);
                    log.Info("Completed waiting on set point");

                    Thread.Sleep(300);

                    command[0] = 0x02;
                    command[1] = 0x62;
                    command[2] = deviceAddress.Byte1;
                    command[3] = deviceAddress.Byte2;
                    command[4] = deviceAddress.Byte3;
                    command[5] = 0x0F;
                    command[6] = Constants.STD_COMMAND_THERMOSTAT_STATUS;
                    command[7] = 0x60; // humidity

                    _gettingHumidity = true;
                    _plm.Write(command, 0, 8);

                    _lastSentCommand = command;

                    _statusEventWaitHandle.Reset();
                    log.Info("Calling WaitOne on StatusEventWaitHandle for Thermostat humidity");
                    _statusEventWaitHandle.WaitOne(10000);
                    log.Info("Completed waiting on humidity");

                    Thread.Sleep(300);

                    _gettingThermostat = false;

                    return null;
                }

                // send a get status command
                command[0] = 0x02;
                command[1] = 0x62;
                command[2] = deviceAddress.Byte1;
                command[3] = deviceAddress.Byte2;
                command[4] = deviceAddress.Byte3;
                command[5] = 0x0F;
                command[6] = Constants.STD_COMMAND_STATUS_REQUEST;
                command[7] = 0x00;

                _gettingStatus = true;

                _plm.Write(command, 0, 8);

                _lastSentCommand = command;

                _statusEventWaitHandle.Reset();
                log.Info("Calling WaitOne on StatusEventWaitHandle");
                _statusEventWaitHandle.WaitOne(10000);
                log.Info("Completed waiting device status handle");

                status = new DeviceStatus();
                status.Delta = _allDevices[deviceAddress.ToString()].Delta;
                status.OnLevel = Math.Round(_allDevices[deviceAddress.ToString()].Status,1);

                _gettingStatus = false;
            }
            catch (Exception ex)
            {
                log.Error(string.Format("Error getting device status for {0}", deviceAddress.ToString()));
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
            }

            return status;
        }
 public InsteonExtendedMessage(DeviceAddress sourceAddress, DeviceAddress targetAddress, byte command1, byte command2, byte[] data, byte flag)
     : base(sourceAddress, targetAddress, command1, command2, flag)
 {
     _data = data;
 }
Example #12
0
 public RelayDevice(string deviceName, DeviceAddress deviceAddress)
     : base(deviceName, deviceAddress)
 {
 }
Example #13
0
 public SensorDevice(string deviceName, DeviceAddress deviceAddress)
     : base(deviceName, deviceAddress)
 {
 }
Example #14
0
        private DeviceAddress GetCustomAddress()
        {
            if (txtDevAddress.Text.Trim().Length != 6)
            {
                MessageBox.Show("Invalid Device address to link");
                return null;
            }

            string textAddress = txtDevAddress.Text.Trim();

            byte addr1 = StringToByte(textAddress.Substring(0, 2));
            byte addr2 = StringToByte(textAddress.Substring(2, 2));
            byte addr3 = StringToByte(textAddress.Substring(4));

            DeviceAddress devAddress = new DeviceAddress(addr1, addr2, addr3);

            return devAddress;
        }
Example #15
0
        private void btnSendStdCommand_Click(object sender, EventArgs e)
        {
            byte cmd1 = StringToByte(txtCmd1.Text);
            byte cmd2 = StringToByte(txtCmd2.Text);
            byte flags = StringToByte(txtFlags.Text);
            string commandResult = null;
            // for sending commands to devices not in our config yet...
            if (null == _selectedDevice || _selectedDevice is PLMDevice)
            {
                DeviceAddress destinationAddress = new DeviceAddress(
                    StringToByte(txtUD1.Text),
                    StringToByte(txtUD2.Text),
                    StringToByte(txtUD3.Text));

                commandResult = _handler.SendStandardCommand(destinationAddress,
                    cmd1, cmd2, flags,true);

                return;
            }

            commandResult = _handler.SendStandardCommand(_selectedDevice.Address, cmd1, cmd2, flags);

            rtCommandResults.Text = commandResult;
        }
 public MultiButtonDimmerDevice(string deviceName, DeviceAddress deviceAddress)
     : base(deviceName, deviceAddress)
 {
 }
Example #17
0
        //public void ParseCommand(byte[] commandBytes)
        //{
        //    //if (commandBytes.Length < 5)
        //    //{
        //    //    log.Error(string.Format("Received command not of sufficient length ({0}), command: {1}", commandBytes.Length, BytesToString(commandBytes)));
        //    //    return;
        //    //}
        //    if (commandBytes[0] != 0x02)
        //    {
        //        log.Error(string.Format("Received Command must start with 0x02.  Received command: {0}", BytesToString(commandBytes)));
        //        return;
        //    }
        //    // determine whether the command is an ack
        //    if (CompareToLastSentCommand(commandBytes))
        //    {
        //        // no need to parse ACK commands
        //        if (commandBytes[_lastSentCommand.Length] == 0x06)
        //        {
        //            if (commandBytes.Length > _lastSentCommand.Length + 1)
        //            {
        //                byte[] remainingBytes = new byte[commandBytes.Length - (_lastSentCommand.Length + 1)];
        //                Buffer.BlockCopy(commandBytes, _lastSentCommand.Length + 1, remainingBytes, 0, remainingBytes.Length);
        //                ParseCommand(remainingBytes);
        //            }
        //            _lastSentCommand = null;
        //            return;
        //        }
        //        else if (commandBytes[_lastSentCommand.Length] == 0x15)
        //        {
        //            log.Warn(string.Format("Received NAK for Command {0}", BytesToString(commandBytes)));
        //            _lastSentCommand = null;
        //            return;
        //        }
        //    }
        //    if (0x50 == commandBytes[1]) // STD message received (11 bytes)
        //    {
        //        if (commandBytes.Length < 11)
        //        {
        //            log.Error(string.Format("Bad standard command received {0}", BytesToString(commandBytes)));
        //            return;
        //        }
        //        byte[] singleCommand = new byte[11];
        //        for (int i = 0; i < 11; i++)
        //        {
        //            singleCommand[i]=commandBytes[i];
        //        }
        //        ProcessStandardReceivedMessage(singleCommand);
        //        if (commandBytes.Length > 11)
        //        {
        //            byte[] remainingBytes = new byte[commandBytes.Length - 11];
        //            Buffer.BlockCopy(commandBytes, 11, remainingBytes, 0, commandBytes.Length - 11);
        //            ParseCommand(remainingBytes);
        //        }
        //    }
        //    else if (0x51 == commandBytes[1]) // EXT message received
        //    {
        //        if (commandBytes.Length < 25)
        //        {
        //            log.Error(string.Format("Bad extended command received {0}", BytesToString(commandBytes)));
        //            return;
        //        }
        //        byte[] singleCommand = new byte[25];
        //        for (int i = 0; i < 25; i++)
        //        {
        //            singleCommand[i]=commandBytes[i];
        //        }
        //    }
        //}
        //public void SetLastCommand(byte[] cmd)
        //{
        //    _lastSentCommand = cmd;
        //}
        private void ProcessStandardReceivedMessage(byte[] message)
        {
            DeviceAddress fromAddress = new DeviceAddress(message[2],message[3],message[4]);
            DeviceAddress toAddress = new DeviceAddress(message[5], message[6], message[7]);

            // check flags for group/device
            byte flagByte = (byte)(message[8] & (byte)0xE0);
            MessageFlag flag = (MessageFlag)flagByte;
            string flagDescription = "unknown";

            switch (flag)
            {
                case MessageFlag.DirectMessage:
                    flagDescription = "Direct Message";
                    break;
                case MessageFlag.ACKDirectMessage:
                    flagDescription = "ACK Direct Message";
                    break;
                case MessageFlag.ACKGroupCleanupDirectMessage:
                    flagDescription = "ACK Group Cleanup DM";
                    break;
                case MessageFlag.BroadcastMessage:
                    flagDescription = "Broadcast Message";
                    break;
                case MessageFlag.GroupBroadcastMessage:
                    flagDescription = "Group Broadcast Message";
                    break;
                case MessageFlag.GroupCleanupDirectMessage:
                    flagDescription = "Group Cleanup DM";
                    break;
                case MessageFlag.NAKDirectMessage:
                    flagDescription = "NAK Direct Message";
                    break;
                case MessageFlag.NAKGroupCleanupDirectMessage:
                    flagDescription = "NAK Group Cleanup DM";
                    break;
                default:
                    break;
            }

            if ((message[8] & 0x10) != 0) // standard message
            {
                log.Error(string.Format("Process Standard Received Message got extended message flag"));
                return;
            }

            int retransmissions = (message[8] & 0x0C) >> 2;

            int maxHops = message[8] & 0x03;

            byte command1 = message[9];
            byte command2=message[10];

            string commandType = "unknown";
            Device sourceDevice = FindDeviceForAddress(fromAddress.ToString());
            Device targetDevice = FindDeviceForAddress(toAddress.ToString());
            if (null != targetDevice && targetDevice is PLMDevice)
            {
                if (_gettingStatus)
                {
                    byte delta = 0x00;
                    //if (_gettingOpFlags)
                    //{
                    //    delta = message[10];
                    //    sourceDevice.Delta = delta;
                    //    log.InfoFormat("Attempting to read database delta from ops flags, result: {0}", delta);
                    //}
                    //else
                    //{
                        // read the command2 and 1 of the response to get the level as well

                    byte level = message[10];
                    delta = message[9];

                    sourceDevice.Status = ((int)level / 255m) * 100m;
                    sourceDevice.Delta = delta;

                    //}
                    _statusEventWaitHandle.Set();
                }
                else if (sourceDevice is ThermostatDevice)
                {
                    if (_gettingThermostat)
                    {
                        if (command1 == 0x6A)
                        {
                            if (_gettingTemp)
                            {
                                ((ThermostatDevice)sourceDevice).AmbientTemperature = (int)Math.Round(((decimal)command2) / 2m,0);
                                _gettingTemp = false;
                            }
                            else if (_gettingSetPoint)
                            {
                                if (((ThermostatDevice)sourceDevice).CurrentMode == ThermostatDevice.Mode.Cooling)
                                    ((ThermostatDevice)sourceDevice).CoolSetPoint = (int)Math.Round(((decimal)command2) / 2m, 0);
                                else
                                    ((ThermostatDevice)sourceDevice).HeatSetPoint = (int)Math.Round(((decimal)command2) / 2m, 0);

                                _gettingSetPoint = false;

                            }
                            else if (_gettingHumidity)
                            {
                                ((ThermostatDevice)sourceDevice).Humidity = (int)command2;

                                _gettingHumidity = false;

                            }
                            else
                                log.WarnFormat("Received thermostat update {0} and unsure of what we requested.", command2.ToString("X"));

                            _statusEventWaitHandle.Set();

                        }
                        return;
                    }

                    ThermostatDevice thermostat = sourceDevice as ThermostatDevice;

                    switch (command1)
                    {
                        case Constants.STD_COMMAND_THERMOSTAT_STATUS_TEMP:
                            thermostat.AmbientTemperature = (int)Math.Round(((decimal)command2) * 0.5m, 0);

                            log.InfoFormat("Received temperature update: {0}", thermostat.AmbientTemperature);
                            SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(thermostat.Name,
                                string.Format("Temperature detected: {0}°F", thermostat.AmbientTemperature)));

                            break;
                        case Constants.STD_COMMAND_THERMOSTAT_STATUS_HUMIDITY:
                            thermostat.Humidity = (int)command2;
                            log.InfoFormat("Received humidity update: {0}", thermostat.Humidity);

                            break;
                        case Constants.STD_COMMAND_THERMOSTAT_STATUS_MODE_FAN:
                            log.InfoFormat("Thermostat mode byte: {0}", command2.ToString("X"));
                            // extract mode, low byte 0=off,1=heat,2=cool,3=auto,4=program
                            if ((command2 & 0x0F) == 0x00)
                                thermostat.CurrentMode = ThermostatDevice.Mode.Off;
                            else if ((command2 & 0x0F) == 0x01)
                                thermostat.CurrentMode = ThermostatDevice.Mode.Heating;
                            else if ((command2 & 0x0F) == 0x02)
                                thermostat.CurrentMode = ThermostatDevice.Mode.Cooling;
                            else if ((command2 & 0x0F) == 0x03)
                                thermostat.CurrentMode = ThermostatDevice.Mode.Auto;
                            else if ((command2 & 0x0F) == 0x04)
                                thermostat.CurrentMode = ThermostatDevice.Mode.Program;
                            else
                                log.WarnFormat("Unable to determine mode from status byte: {0}", command2.ToString("X"));

                            // extract fan info, high byte command 2, 0=auto,1=alwayson
                            if ((command2 & 0xF0) == 0x00)
                                thermostat.Fan = ThermostatDevice.FanMode.Auto;
                            else if ((command2 & 0xF0) == 0x10)
                                thermostat.Fan = ThermostatDevice.FanMode.AlwaysOn;
                            else
                                log.WarnFormat("Unable to determine fan from status byte: {0}", command2.ToString("X"));

                            SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(thermostat.Name,
                                string.Format("Mode: {0}, Fan: {1}", thermostat.CurrentMode, thermostat.Fan)));
                            break;
                        case Constants.STD_COMMAND_THERMOSTAT_STATUS_COOL_SET:
                            thermostat.CoolSetPoint = (int)(command2);
                            log.InfoFormat("Received thermostat cool setpoint update: {0}", thermostat.CoolSetPoint);

                            SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(thermostat.Name,
                                string.Format("Cool set point: {0}", thermostat.CoolSetPoint)));

                            break;
                        case Constants.STD_COMMAND_THERMOSTAT_STATUS_HEAT_SET:
                            thermostat.HeatSetPoint = (int)(command2);
                            log.InfoFormat("Received thermostat heat setpoint update: {0}", thermostat.HeatSetPoint);
                            SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(thermostat.Name,
                                string.Format("Heat set point: {0}", thermostat.HeatSetPoint)));
                            break;
                        default:
                            log.InfoFormat("Unknown message from thermostat device received: {0}", command1.ToString("X"));
                            break;
                    }
                }

                // this is received before the ALDB comes, its part of a sequence of extended messages
                // but 0x2F as a standard message is LightOffAtRampRate
                if (command1 == 0x2F)
                {
                    log.Info(string.Format("Received Message from {0} to {1} of type: ({2}):{3} ({4})", GetDeviceName(fromAddress.ToString()), GetDeviceName(toAddress.ToString()), command1.ToString("X"), command2.ToString("X"), flagDescription));
                    log.Info("Beginning of ALDB records.");
                    return;
                } // same as above but for reading device info
                else if (command1 == 0x2E)
                {
                    log.Info(string.Format("Received Message from {0} to {1} of type: ({2}):{3} ({4})", GetDeviceName(fromAddress.ToString()), GetDeviceName(toAddress.ToString()), command1.ToString("X"), command2.ToString("X"), flagDescription));
                    log.Info("Beginning of Extended Read");
                    return;
                }
            }

            switch (command1)
            {
                case Constants.STD_COMMAND_BEEP:
                    break;
                case Constants.STD_COMMAND_BRIGHT:
                    break;
                case Constants.STD_COMMAND_DIM:
                    commandType = "Dim";
                    break;
                case Constants.STD_COMMAND_FAST_OFF:
                    if (null != sourceDevice && (flag & MessageFlag.ACKDirectMessage) == 0)
                    {
                        if ((null != targetDevice && targetDevice is PLMDevice) || toAddress.Byte3 == 0x01)
                        {
                            sourceDevice.Status = 0;
                            sourceDevice.LastOff = DateTime.Now;
                            SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(sourceDevice.Name,
                                string.Format("Fast off by keypress.")));
                        }
                    }

                    commandType = "FastOff";
                    break;
                case Constants.STD_COMMAND_FAST_ON:
                    if (null != sourceDevice && (flag & MessageFlag.ACKDirectMessage) == 0)
                    {
                        if ((null != targetDevice && targetDevice is PLMDevice) || toAddress.Byte3 == 0x01)
                        {
                            sourceDevice.LastOn = DateTime.Now;
                            if (sourceDevice is DimmerDevice)
                                sourceDevice.Status = (command2 * 100) / 0xFF;
                            else
                                sourceDevice.Status = 100;
                            SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(sourceDevice.Name,
                                string.Format("Fast on by keypress.")));
                        }
                    }

                    // setting a timer on an ack message is redundant
                    if (sourceDevice.DefaultOffMinutes.HasValue && ((flag & MessageFlag.ACKDirectMessage) != MessageFlag.ACKDirectMessage))
                    {
                        log.DebugFormat("Setting default off timer for device: {0} minutes.", sourceDevice.DefaultOffMinutes.Value);
                        sourceDevice.SetTimer(new Devices.DeviceTimerCallBack(DeviceTimerCallBack));
                    }

                    commandType = "FastOn";
                    break;
                case Constants.STD_COMMAND_GET_OP_FLAGS:
                    break;
                case Constants.STD_COMMAND_LIGHT_INSTANT_CHANGE:
                    break;
                case Constants.STD_COMMAND_LIGHT_MANUAL_OFF:
                    commandType = "LightManualOff";
                    break;
                case Constants.STD_COMMAND_LIGHT_MANUAL_ON:
                    commandType = "LightManualOn";
                    break;
                case Constants.STD_COMMAND_LIGHT_RAMP_OFF:
                    if (null != sourceDevice && (flag & MessageFlag.ACKDirectMessage) == 0)
                    {
                        if ((null != targetDevice && targetDevice is PLMDevice) || toAddress.Byte3 == 0x01)
                        {
                            sourceDevice.Status = 0;
                            sourceDevice.LastOff = DateTime.Now;
                        }
                    }

                    commandType = "LightRampOff";
                    break;
                case Constants.STD_COMMAND_LIGHT_RAMP_ON:
                    if (null != sourceDevice && (flag & MessageFlag.ACKDirectMessage) == 0)
                    {
                        if ((null != targetDevice && targetDevice is PLMDevice) || toAddress.Byte3 == 0x01)
                        {
                            sourceDevice.LastOn = DateTime.Now;
                            if (sourceDevice is DimmerDevice)
                                sourceDevice.Status = (command2 * 100) / 0xFF;
                            else
                                sourceDevice.Status = 100;
                        }
                    }

                    if (sourceDevice.DefaultOffMinutes.HasValue)
                    {
                        log.DebugFormat("Setting default off timer for device: {0} minutes.", sourceDevice.DefaultOffMinutes.Value);
                        sourceDevice.SetTimer(new DeviceTimerCallBack(DeviceTimerCallBack));
                    }

                    commandType = "LightRampOn";
                    break;

                case Constants.STD_COMMAND_LIGHT_SET_STATUS:
                    commandType = "LightSetStatus";
                    break;

                case Constants.STD_COMMAND_OFF:
                    if (null != sourceDevice && (flag & MessageFlag.ACKDirectMessage) == 0)
                    {
                        if ((null != targetDevice && targetDevice is PLMDevice) || toAddress.Byte3 == 0x01)
                        {
                            sourceDevice.Status = 0;
                            sourceDevice.LastOff = DateTime.Now;

                            if (!(sourceDevice is ThermostatDevice))
                            {
                                SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(sourceDevice.Name,
                                      string.Format("Turned off by keypress.")));
                            }
                        }
                    }
                    commandType = "CommandOff";
                    break;
                case Constants.STD_COMMAND_ON:

                    if (null != sourceDevice && (flag & MessageFlag.ACKDirectMessage) == 0)
                    {
                        if ((null != targetDevice && targetDevice is PLMDevice) || toAddress.Byte3 == 0x01)
                        {
                            sourceDevice.LastOn = DateTime.Now;
                            if (sourceDevice is DimmerDevice)
                                sourceDevice.Status = (command2 * 100) / 0xFF;
                            else if (sourceDevice is SensorDevice)
                                sourceDevice.Status = 0;// dont actually turn on
                            else
                                sourceDevice.Status = 100;

                            if (!(sourceDevice is ThermostatDevice))
                            {
                                if (sourceDevice is SensorDevice)
                                    SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(sourceDevice.Name,
                                        string.Format("Motion Detected")));
                                else
                                    SlapsteonEventLog.AddLogEntry(new SlapsteonEventLogEntry(sourceDevice.Name,
                                        string.Format("Turned on by keypress.")));
                            }
                        }
                    }

                    if (sourceDevice.DefaultOffMinutes.HasValue)
                    {
                        log.DebugFormat("Setting default off timer for device: {0} minutes.", sourceDevice.DefaultOffMinutes.Value);
                        sourceDevice.SetTimer(new DeviceTimerCallBack(DeviceTimerCallBack));
                    }

                    if (sourceDevice.Name == "zone1IOLinc")
                    {
                        if (null != PartyDetected)
                        {
                            PartyDetected(this);
                        }
                    }

                    commandType = "CommandOn";
                    break;
                case Constants.STD_COMMAND_REMOTE_SET_BUTTON_TAP:
                    break;
                case Constants.STD_COMMAND_SET_OP_FLAGS:
                    break;
                case Constants.STD_COMMAND_START_MANUAL:
                    commandType = "StartManual";
                    break;
                case Constants.STD_COMMAND_STATUS_REQUEST:
                    break;
                case Constants.STD_COMMAND_STOP_MANUAL:
                    commandType = "StopManual";
                    break;
                default:
                    break;
            }

            ProcessRelatedDeviceEvents(command1, command2, fromAddress, toAddress);

            log.Info(string.Format("Received Message from {0} to {1} of type: {2}({3}):{4} ({5})", GetDeviceName(fromAddress.ToString()), GetDeviceName(toAddress.ToString()), commandType, command1.ToString("X"), command2.ToString("X"), flagDescription));

            if (null != InsteonTrafficDetected)
            {
                InsteonTrafficEventArgs args = new InsteonTrafficEventArgs();
                args.Source = _allDevices.ContainsKey(fromAddress.ToString()) ? _allDevices[fromAddress.ToString()] : null;
                args.Destination = toAddress;
                args.Flags = flag;
                args.Command1 = command1;
                args.Command2 = command2;
                args.Description = string.Format("Command={0}/DestName={1}", commandType, GetDeviceName(toAddress.ToString()));
                InsteonTrafficDetected(this, args);
            }
        }
Example #18
0
        public void GetThermostatExtendedInformation(DeviceAddress deviceAddress)
        {
            byte[] command = new byte[22];
            try
            {
                // send a get status command
                command[0] = 0x02;
                command[1] = 0x62;
                command[2] = deviceAddress.Byte1;
                command[3] = deviceAddress.Byte2;
                command[4] = deviceAddress.Byte3;
                command[5] = 0x1F;
                command[6] = Constants.EXT_COMMAND_EXTENDED_GET_SET;
                command[7] = 0x00;
                command[8] = 0x00;

                _plm.Write(command, 0, 22);

                _lastSentCommand = command;

                _gettingThermostatExtended = true;

                _extendedGetWaitHandle.Reset();
                log.Info("Calling WaitOne on ExtendedGetWaitHandle");
                _extendedGetWaitHandle.WaitOne(5000);
                log.Info("ExtendedGetWaitHandle finished");

                _gettingThermostatExtended = false;
            }
            catch (Exception ex)
            {
                log.Error(string.Format("Error getting thermostat extended Information for device: {0}", deviceAddress.ToString()));
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
            }
        }
Example #19
0
        public void GetALDBForDevice(DeviceAddress address)
        {
            GetAddressRecords(address);

            log.Info("Waiting on ALDB Event Handle");
            _aldbEventWaitHandle.WaitOne(10000);
            log.Info("Finished Waiting on ALDB entry.");
        }
Example #20
0
 public void SendExtendedCommand(DeviceAddress deviceAddress, byte command1, byte command2, byte flags, bool checksum, params byte[] userData)
 {
     SendExtendedCommand(deviceAddress, command1, command2, flags,checksum, false, userData);
 }
Example #21
0
        public InsteonHandler(string comPort, bool saveALDB)
        {
            // read the configuration file
            SlapsteonConfigurationSection slapsteonConfiguration =
                ConfigurationManager.GetSection("slapsteon") as SlapsteonConfigurationSection;

            try
            {
                _plm = new SerialPort(comPort, 19200, Parity.None, 8, StopBits.One);
                log.Info("Opening serial port " + comPort);
                _plm.Open();
                log.Info("Successfully connected to PLM.");

            }
            catch (Exception ex)
            {
                log.Error("Error opening serial port", ex);
                throw ex;
            }
            _plm.DataReceived += new SerialDataReceivedEventHandler(_plm_DataReceived);
            Thread.Sleep(500);
            this.SetMonitorMode();

            string deviceALDBPathSetting = ConfigurationManager.AppSettings["deviceXMLPath"];
            if (!string.IsNullOrEmpty(deviceALDBPathSetting))
                _deviceALDBPath=deviceALDBPathSetting;

            if (null == slapsteonConfiguration)
                throw new ConfigurationErrorsException("The configuration needs a <slapsteon> section.");

            foreach (SlapsteonDeviceConfigurationElement element in slapsteonConfiguration.SlapsteonDevices)
            {
                string deviceName = element.Name;

                byte address1 = StringToByte(element.Address.Substring(0, 2));
                byte address2 = StringToByte(element.Address.Substring(2, 2));
                byte address3 = StringToByte(element.Address.Substring(4, 2));

                DeviceAddress deviceAddress= new DeviceAddress(address1, address2, address3);
                Device dev = null;
                if ((element.IsKPL.HasValue && element.IsKPL.Value) && (!element.IsDimmable.HasValue || !element.IsDimmable.Value))
                    dev = new MultiButtonRelayDevice(deviceName, deviceAddress);
                else if ((element.IsKPL.HasValue && element.IsKPL.Value) && (element.IsDimmable.HasValue && element.IsDimmable.Value))
                    dev = new MultiButtonDimmerDevice(deviceName, deviceAddress);
                else if (element.IsBatteryDevice.HasValue && element.IsBatteryDevice.Value)
                    dev = new SensorDevice(deviceName, deviceAddress);
                else if (element.IsFan.HasValue && element.IsFan.Value)
                    dev = new FanDevice(deviceName, deviceAddress);
                else if (element.IsDimmable.HasValue && element.IsDimmable.Value)
                    dev = new DimmerDevice(deviceName, deviceAddress);
                else if (element.IsPLM.HasValue && element.IsPLM.Value)
                    dev = new PLMDevice(deviceName, deviceAddress);
                else if (element.IsIODevice.HasValue && element.IsIODevice.Value)
                    dev = new IODevice(deviceName, deviceAddress);
                else if (element.IsThermostat.HasValue && element.IsThermostat.Value)
                {
                    int setPoint = 0;
                    if (!int.TryParse(element.ThermostatSetPoint, out setPoint))
                    {
                        setPoint = 70;
                    }
                    ThermostatDevice.Mode thermostatMode = ThermostatDevice.Mode.Cooling;
                    if (element.ThermostatMode == "cool")
                        thermostatMode = ThermostatDevice.Mode.Cooling;
                    else
                        thermostatMode = ThermostatDevice.Mode.Heating;

                    dev = new ThermostatDevice(deviceName, deviceAddress, thermostatMode, setPoint);
                }
                else
                    dev = new RelayDevice(deviceName, deviceAddress);

                dev.DefaultOffMinutes = element.DefaultOffMinutes;
                dev.IsOnAtSunset = element.IsOnAtSunset ?? false;
                dev.IsOffAtSunrise = element.IsOffAtSunrise ?? false;
                dev.Floor = element.Floor;

                // load random schedule settings
                dev.IsRandomOn = element.IsRandomOn ?? false;
                dev.RandomOnStart = element.RandomStartTime;
                dev.RandomRunDuration = element.RandomRunDuration;
                dev.RandomDurationMin = element.RandomDurationMin;
                dev.RandomDurationMax = element.RandomDurationMax;
                dev.RandomOnChance = element.RandomOnChance;

                _allDevices.Add(deviceAddress.ToString(), dev);
            }

            // iterate through the list once more for slave devices
            foreach (SlapsteonDeviceConfigurationElement element in slapsteonConfiguration.SlapsteonDevices)
            {
                if (string.IsNullOrEmpty(element.SlaveDevices))
                    continue;

                byte address1 = StringToByte(element.Address.Substring(0, 2));
                byte address2 = StringToByte(element.Address.Substring(2, 2));
                byte address3 = StringToByte(element.Address.Substring(4, 2));

                DeviceAddress deviceAddress = new DeviceAddress(address1, address2, address3);

                string[] slaveDeviceList = element.SlaveDevices.Split(',', '|', ' ');
                List<Device> slaveDevices = new List<Device>();
                foreach (string slaveDeviceName in slaveDeviceList)
                {
                    Device slaveDevice = _allDevices.Values.FirstOrDefault(d => d.Name.ToUpper() == slaveDeviceName.ToUpper());

                    if (null == slaveDevice)
                        continue;
                    slaveDevice.IsSlaveDevice = true;

                    slaveDevices.Add(slaveDevice);
                }

                _allDevices[deviceAddress.ToString()].SlaveDevices = slaveDevices;
                log.Debug(string.Format("added {0} slave device(s) for device {1}", slaveDevices.Count, element.Name));
            }

            // deserialize the DeviceALDB
            DeserializeStoredDeviceALDB();

            GetStatusForAllDevices();
            Thread.Sleep(300);
            GetALDBForAllDevices();

            if (saveALDB)
                SerializeDeviceALDB();
        }
Example #22
0
 public DimmerDevice(string deviceName, DeviceAddress deviceAddress)
     : base(deviceName, deviceAddress)
 {
 }
Example #23
0
 public void RefreshThermostatDevice(DeviceAddress address)
 {
 }
Example #24
0
        private InsteonStandardMessage CommandBytesToStandardMessage(byte[] command)
        {
            DeviceAddress sourceAddress = new DeviceAddress(command[2], command[3], command[4]);
            DeviceAddress targetAddress =new DeviceAddress(command[5], command[6], command[7]);
            byte messageFlag = command[8];
            InsteonStandardMessage message = new InsteonStandardMessage(sourceAddress, targetAddress, command[9], command[10], messageFlag);

            message.CommandDescription = StdCommandToString(command[9]);
            Device sourceDevice = _allDevices.Values.FirstOrDefault(d => d.Address.StringAddress == sourceAddress.StringAddress);
            if (null != sourceDevice)
                message.SourceName = sourceDevice.Name;
            else
                message.SourceName = sourceAddress.StringAddress;

            Device targetDevice = _allDevices.Values.FirstOrDefault(d => d.Address.StringAddress == targetAddress.StringAddress);
            if (null != targetDevice)
                message.TargetName = targetDevice.Name;
            else
                message.TargetName = targetAddress.StringAddress;

            return message;
        }
Example #25
0
        public void SendExtendedCommand(DeviceAddress deviceAddress, byte command1, byte command2, byte flags, bool checksum, bool isUnknownDevice, params byte[] userData)
        {
            byte[] command = new byte[22];

            Device targetDevice = null;
            if (!isUnknownDevice && !_allDevices.TryGetValue(deviceAddress.ToString(), out targetDevice))
                throw new Exception("No known device matched the specified address.");

            if (userData.Length > 14)
                throw new Exception("Invalid userdata specified");

            try
            {
                lock (this)
                {
                    int total = command1 + command2;

                    command[0] = 0x02; // Insteon start byte
                    command[1] = 0x62; // Standard Command
                    command[2] = deviceAddress.Byte1;
                    command[3] = deviceAddress.Byte2;
                    command[4] = deviceAddress.Byte3;
                    command[5] = flags |= 0x10; // for standard 0x0F is good
                    command[6] = command1;
                    command[7] = command2;
                    if (null != userData)
                    {
                        for (int i = 0; i < userData.Length; i++)
                        {
                            command[8 + i] = userData[i];
                            total += userData[i];
                        }
                    }
                    if (checksum)
                        command[21] = (byte)((total ^ 0xFF) + 1);

                    _plm.Write(command, 0, 22);
                    Thread.Sleep(250);
                    log.Info(string.Format("Sent command {0} to device {1}.  (Command2: {2}, Flags: {3})", command1.ToString("X"), null != targetDevice ? targetDevice.Name : "Unknown", command2.ToString("X"), flags.ToString("X")));
                    _lastSentCommand = command;
                }
            }
            catch (Exception ex)
            {
                log.Error(string.Format("Error sending command {0} to {1}. (Flags: {2})", command1.ToString("X"), null != targetDevice ? targetDevice.Name : "Unknown", flags.ToString("X")), ex);
            }
        }
Example #26
0
        private void GetAddressRecords(DeviceAddress address)
        {
            try
            {

                // send the get address command
                byte[] command = new byte[22];
                command[0] = 0x02;
                command[1] = 0x62; // Standard Command
                command[2] = address.Byte1;
                command[3] = address.Byte2;
                command[4] = address.Byte3;
                command[5] = 0x1F; // for standard 0x0F is good, this is extended
                command[6] = Constants.EXT_COMMAND_READ_WRITE_ALDB;
                command[7] = 0x00;

                _plm.Write(command, 0, 22);

            }
            catch (Exception ex)
            {

            }
        }
Example #27
0
        public string SendStandardCommand(DeviceAddress deviceAddress, byte command1, byte command2, byte flags, bool isUnknownDevice)
        {
            string results = null;

            Device targetDevice = null;
            if (!isUnknownDevice && !_allDevices.TryGetValue(deviceAddress.ToString(), out targetDevice))
                throw new Exception("No known device matched the specified address.");

            byte[] command = new byte[8];

            try
            {

                command[0] = 0x02; // Insteon start byte
                command[1] = 0x62; // Standard Command
                command[2] = deviceAddress.Byte1;
                command[3] = deviceAddress.Byte2;
                command[4] = deviceAddress.Byte3;
                command[5] = flags; // for standard 0x0F is good
                command[6] = command1;
                command[7] = command2;

                _plm.Write(command, 0, 8);

                log.Debug(string.Format("Sent Standard Command {0} to device {1} (address: {2})", command1.ToString("X"), null != targetDevice ? targetDevice.Name : "Unknown", null != targetDevice ? targetDevice.AddressString : deviceAddress.ToString()));

                if (null == targetDevice)
                    return null;

                // write more to the command for slave devices
                foreach (Device slaveDevice in targetDevice.SlaveDevices)
                {
                    Thread.Sleep(250);
                    log.Debug(string.Format("Sending duplicate command {0} for slave device {1} (address: {2})", command1.ToString("X"), slaveDevice.Name, slaveDevice.AddressString));
                    command = new byte[8];

                    command[0] = 0x02; // Insteon start byte
                    command[1] = 0x62; // Standard Command
                    command[2] = slaveDevice.Address.Byte1;
                    command[3] = slaveDevice.Address.Byte2;
                    command[4] = slaveDevice.Address.Byte3;
                    command[5] = flags; // for standard 0x0F is good
                    command[6] = command1;
                    command[7] = command2;

                    _plm.Write(command, 0, 8);
                }

            }
            catch (Exception ex)
            {
                log.Error(string.Format("Error sending command {0} to {1}. (Flags: {2})", command1.ToString("X"), null != targetDevice ? targetDevice.Name : deviceAddress.ToString(), flags.ToString("X")), ex);
            }

            return results;
        }
Example #28
0
        private void ProcessALDBResponse(byte[] message)
        {
            try
            {
                _lastALDBRecordTime = DateTime.Now;

                byte deviceAddress1 = message[2];
                byte deviceAddress2 = message[3];
                byte deviceAddress3 = message[4];

                DeviceAddress deviceAddress = new DeviceAddress(deviceAddress1, deviceAddress2, deviceAddress3);
                Device device = _allDevices[deviceAddress.ToString()];

                DeviceALDB deviceALDB = null;
                // record isnt in out ALDB Library yet
                if (!_aldbLibrary.Devices.Exists(a => a.DeviceAddress == deviceAddress.ToString()))
                {
                    deviceALDB = new DeviceALDB();
                    deviceALDB.DeviceAddress = deviceAddress.ToString();
                    deviceALDB.Delta = device.Delta;

                    _aldbLibrary.Devices.Add(deviceALDB);
                }
                else
                    deviceALDB = _aldbLibrary.Devices.First(a => a.DeviceAddress == deviceAddress.ToString());

                // redundant...we should be doing this before we even pull the ALDB
                //if (device.Delta != device.DeviceALDB.Delta)
                //    log.DebugFormat("Device Delta {0} did not match the stored version {1}", device.Delta.ToString("X"), device.DeviceALDB.Delta.ToString("X"));

                ALDBRecord record = new ALDBRecord();
                record.AddressMSB = message[13];
                record.AddressLSB = message[14];
                record.Flags = message[16];
                record.Group = message[17];
                record.Address1 = message[18];
                record.Address2 = message[19];
                record.Address3 = message[20];
                record.LocalData1 = message[21];
                record.LocalData2 = message[22];
                record.LocalData3 = message[23];

                if ((record.Flags == 0x00) && ((record.Address1 == 0x00) && (record.Address2 == 0x00) && (record.Address3 == 0x00)))
                {
                    _aldbFinishedForDevice = true;
                    log.Info("Reached last address record.");
                    _aldbEventWaitHandle.Set();

                    return;
                }
                deviceALDB.ALDBRecords.Add(record);
            }
            catch (Exception ex)
            {
                log.ErrorFormat("Error processing ALDB Response");
            }
        }
Example #29
0
        private void ProcessAllLinkResponse(byte[] allLinkMessage)
        {
            // 02 57 A2/E2 GRP ADR1 ADR2 ADR3 Local Data

            DeviceAddress address = new DeviceAddress(allLinkMessage[4], allLinkMessage[5], allLinkMessage[6]);
            LinkRecord linkRecord = new LinkRecord(allLinkMessage[2], allLinkMessage[3], address, allLinkMessage[7], allLinkMessage[8], allLinkMessage[9]);

            linkRecord.ReferenceDeviceName = GetDeviceName(address.StringAddress);

            _imLinks.Add(linkRecord);
        }
 public MultiButtonRelayDevice(string deviceName, DeviceAddress deviceAddress)
     : base(deviceName, deviceAddress)
 {
 }