void _handler_InsteonTrafficDetected(object sender, InsteonTrafficEventArgs e) { }
//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 InsteonTrafficDetected(object sender, InsteonTrafficEventArgs e) { this.InsertConsoleText(e.ToString() + Environment.NewLine); }