diff --git a/UserInterface/Views/AddCommandDialog.axaml.cs b/UserInterface/Views/AddCommandDialog.axaml.cs index a7d7a1f..000d3e3 100644 --- a/UserInterface/Views/AddCommandDialog.axaml.cs +++ b/UserInterface/Views/AddCommandDialog.axaml.cs @@ -78,6 +78,26 @@ namespace UserInterface.Views item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#logoffcommand"; item.ShowCommandInput = false; break; + case AvailableCommands.KeyCommand: + item.Description = "This commands can be used to send emulate a keystroke."; + item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#keycommand"; + item.ShowCommandInput = false; + break; + case AvailableCommands.PlayPauseCommand: + item.Description = "This command plays or pauses currently playing media."; + item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#playpausecommand"; + item.ShowCommandInput = false; + break; + case AvailableCommands.NextCommand: + item.Description = "This command skips to the next media."; + item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#nextcommand"; + item.ShowCommandInput = false; + break; + case AvailableCommands.PreviousCommand: + item.Description = "This command plays previous media."; + item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#previouscommand"; + item.ShowCommandInput = false; + break; default: item.Description = null; item.MoreInfoLink = null; diff --git a/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs b/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs index d724082..9d18fb6 100644 --- a/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs +++ b/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs @@ -188,6 +188,18 @@ namespace hass_workstation_service.Communication.InterProcesCommunication case AvailableCommands.CustomCommand: commandToCreate = new CustomCommand(this._publisher, model.Command, model.Name); break; + case AvailableCommands.PlayPauseCommand: + commandToCreate = new MediaPlayPauseCommand(this._publisher, model.Name); + break; + case AvailableCommands.NextCommand: + commandToCreate = new MediaNextCommand(this._publisher, model.Name); + break; + case AvailableCommands.PreviousCommand: + commandToCreate = new MediaPreviousCommand(this._publisher, model.Name); + break; + case AvailableCommands.KeyCommand: + commandToCreate = new KeyCommand(this._publisher, (byte)model.KeyCode, model.Name); + break; default: Log.Logger.Error("Unknown sensortype"); break; diff --git a/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs b/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs index 7c5a7bc..ccfaad5 100644 --- a/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs +++ b/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs @@ -60,5 +60,9 @@ namespace hass_workstation_service.Communication.InterProcesCommunication.Models ShutdownCommand, LogOffCommand, RestartCommand, + KeyCommand, + PlayPauseCommand, + NextCommand, + PreviousCommand } } diff --git a/hass-workstation-service/Data/ConfigurationService.cs b/hass-workstation-service/Data/ConfigurationService.cs index 8337d35..f9f2987 100644 --- a/hass-workstation-service/Data/ConfigurationService.cs +++ b/hass-workstation-service/Data/ConfigurationService.cs @@ -174,6 +174,18 @@ namespace hass_workstation_service.Data case "CustomCommand": command = new CustomCommand(publisher, configuredCommand.Command, configuredCommand.Name, configuredCommand.Id); break; + case "MediaPlayPauseCommand": + command = new MediaPlayPauseCommand(publisher, configuredCommand.Name, configuredCommand.Id); + break; + case "MediaNextCommand": + command = new MediaNextCommand(publisher, configuredCommand.Name, configuredCommand.Id); + break; + case "MediaPreviousCommand": + command = new MediaPreviousCommand(publisher, configuredCommand.Name, configuredCommand.Id); + break; + case "KeyCommand": + command = new KeyCommand(publisher, configuredCommand.KeyCode, configuredCommand.Name, configuredCommand.Id); + break; default: Log.Logger.Error("unsupported command type in config"); break; @@ -292,9 +304,13 @@ namespace hass_workstation_service.Data Log.Logger.Information($"writing configured commands to: {stream.Name}"); foreach (AbstractCommand command in this.ConfiguredCommands) { - if (command is CustomCommand customcommand) + if (command is CustomCommand customCommand) + { + configuredCommandsToSave.Add(new ConfiguredCommand() { Id = customCommand.Id, Name = customCommand.Name, Type = customCommand.GetType().Name, Command = customCommand.Command }); + } + if (command is KeyCommand customKeyCommand) { - configuredCommandsToSave.Add(new ConfiguredCommand() { Id = customcommand.Id, Name = customcommand.Name, Type = customcommand.GetType().Name, Command = customcommand.Command }); + configuredCommandsToSave.Add(new ConfiguredCommand() { Id = customKeyCommand.Id, Name = customKeyCommand.Name, Type = customKeyCommand.GetType().Name, KeyCode = customKeyCommand.KeyCode }); } } diff --git a/hass-workstation-service/Data/ConfiguredCommand.cs b/hass-workstation-service/Data/ConfiguredCommand.cs index d5d6b48..49544f6 100644 --- a/hass-workstation-service/Data/ConfiguredCommand.cs +++ b/hass-workstation-service/Data/ConfiguredCommand.cs @@ -9,5 +9,6 @@ namespace hass_workstation_service.Data public Guid Id { get; set; } public string Name { get; set; } public string Command { get; set; } + public byte KeyCode { get; set; } } } \ No newline at end of file diff --git a/hass-workstation-service/Domain/Commands/KeyCommand.cs b/hass-workstation-service/Domain/Commands/KeyCommand.cs new file mode 100644 index 0000000..58a3142 --- /dev/null +++ b/hass-workstation-service/Domain/Commands/KeyCommand.cs @@ -0,0 +1,57 @@ +using hass_workstation_service.Communication; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace hass_workstation_service.Domain.Commands +{ + public class KeyCommand : AbstractCommand + { + public const int KEYEVENTF_EXTENTEDKEY = 1; + public const int KEYEVENTF_KEYUP = 0; + public const int VK_MEDIA_NEXT_TRACK = 0xB0; + public const int VK_MEDIA_PLAY_PAUSE = 0xB3; + public const int VK_MEDIA_PREV_TRACK = 0xB1; + + public byte KeyCode { get; protected set; } + + public KeyCommand(MqttPublisher publisher, byte keyCode, string name = "Key", Guid id = default(Guid)) : base(publisher, name ?? "Key", id) { + this.KeyCode = keyCode; + } + + public override CommandDiscoveryConfigModel GetAutoDiscoveryConfig() + { + return new CommandDiscoveryConfigModel() + { + Name = this.Name, + Unique_id = this.Id.ToString(), + Availability_topic = $"homeassistant/sensor/{Publisher.DeviceConfigModel.Name}/availability", + Command_topic = $"homeassistant/{this.Domain}/{Publisher.DeviceConfigModel.Name}/{this.Name}/set", + State_topic = $"homeassistant/{this.Domain}/{Publisher.DeviceConfigModel.Name}/{this.Name}/state", + Device = this.Publisher.DeviceConfigModel, + }; + } + + [DllImport("user32.dll")] + public static extern void keybd_event(byte virtualKey, byte scanCode, uint flags, IntPtr extraInfo); + + + public override string GetState() + { + return "OFF"; + } + + public override void TurnOff() + { + + } + + public override void TurnOn() + { + keybd_event(this.KeyCode, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); + } + } +} diff --git a/hass-workstation-service/Domain/Commands/MediaNextCommand.cs b/hass-workstation-service/Domain/Commands/MediaNextCommand.cs new file mode 100644 index 0000000..6f7cb7f --- /dev/null +++ b/hass-workstation-service/Domain/Commands/MediaNextCommand.cs @@ -0,0 +1,14 @@ +using hass_workstation_service.Communication; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace hass_workstation_service.Domain.Commands +{ + public class MediaNextCommand : KeyCommand + { + public MediaNextCommand(MqttPublisher publisher, string name = "Next", Guid id = default(Guid)) : base(publisher, KeyCommand.VK_MEDIA_NEXT_TRACK, name ?? "Next", id) { } + } +} diff --git a/hass-workstation-service/Domain/Commands/MediaPlayPauseCommand.cs b/hass-workstation-service/Domain/Commands/MediaPlayPauseCommand.cs new file mode 100644 index 0000000..695b258 --- /dev/null +++ b/hass-workstation-service/Domain/Commands/MediaPlayPauseCommand.cs @@ -0,0 +1,14 @@ +using hass_workstation_service.Communication; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace hass_workstation_service.Domain.Commands +{ + public class MediaPlayPauseCommand : KeyCommand + { + public MediaPlayPauseCommand(MqttPublisher publisher, string name = "PlayPause", Guid id = default(Guid)) : base(publisher, KeyCommand.VK_MEDIA_PLAY_PAUSE, name ?? "PlayPause", id) { } + } +} diff --git a/hass-workstation-service/Domain/Commands/MediaPreviousCommand.cs b/hass-workstation-service/Domain/Commands/MediaPreviousCommand.cs new file mode 100644 index 0000000..fe35544 --- /dev/null +++ b/hass-workstation-service/Domain/Commands/MediaPreviousCommand.cs @@ -0,0 +1,14 @@ +using hass_workstation_service.Communication; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace hass_workstation_service.Domain.Commands +{ + public class MediaPreviousCommand : KeyCommand + { + public MediaPreviousCommand(MqttPublisher publisher, string name = "Previous", Guid id = default(Guid)) : base(publisher, KeyCommand.VK_MEDIA_PREV_TRACK, name ?? "Previous", id) { } + } +}