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; }
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"); } }
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); }
public Device(string name, DeviceAddress address) { Name = name; Address = address; Status = -1; }
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; }
public RelayDevice(string deviceName, DeviceAddress deviceAddress) : base(deviceName, deviceAddress) { }
public SensorDevice(string deviceName, DeviceAddress deviceAddress) : base(deviceName, deviceAddress) { }
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; }
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) { }
//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); } }
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); } }
public void GetALDBForDevice(DeviceAddress address) { GetAddressRecords(address); log.Info("Waiting on ALDB Event Handle"); _aldbEventWaitHandle.WaitOne(10000); log.Info("Finished Waiting on ALDB entry."); }
public void SendExtendedCommand(DeviceAddress deviceAddress, byte command1, byte command2, byte flags, bool checksum, params byte[] userData) { SendExtendedCommand(deviceAddress, command1, command2, flags,checksum, false, userData); }
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(); }
public DimmerDevice(string deviceName, DeviceAddress deviceAddress) : base(deviceName, deviceAddress) { }
public void RefreshThermostatDevice(DeviceAddress address) { }
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; }
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); } }
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) { } }
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; }
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"); } }
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) { }