MCE Controller Plugin for Keyboard and Mouse Interface

This looks amazing! Thanks for taking the time and effort to produce this. I’m in the early stages of learning THR, but my setup pretty much revolves around my HTPC so this will be invaluable when I get to the PC end of things.
:clap: :clap:

1 Like

Fixed a bug where the MouseHelper server would not actually attempt to reconnect if it initially failed to connect to the MCE Controller. This could happen, for example, if the MouseHelper server was started before the MCE Controller. This must have been due to some kind of change in node.js, because this used to work correctly, but I recently got bit by this myself, where I had no mouse control on the HTPC.

I’ve updated the post above with the corrected mhserver.js file.

1 Like

I finally got a decent amount of time at the weekend to really start integrating my HTPC with HR (and this MCEC plugin). I’m blown away by how powerful these tools are. At first I struggled to wrap my head around some of the setup but fast forward a day and (almost) everything is working as expected. I’ve even moved onto creating my own MCEC commands to run PC batch scripts. I can now do complex script-driven processes with a single button press (eg: change the display fps > run an app > force fullscreen > change inputs, etc.)

This is such a big leap forward, it already makes my Harmony Hub redundant and very limited by comparison.

But! (there’s always a but!) There are a few things I’m having issue with on the MCEC/plugin side and hoping you can help me out with the following…

1. The mouse right-click doesn’t seem to work on Android (double-finger tap in the mousepad). I’ve tested this on two Samsung devices (tablet and phone) and nothing happens on both.
*Note: The mouse right-click command does work when placed on a button (I also have L/M/R buttons setup at the side, similar to your example layout above)

Any ideas why this doesn’t work on Android? It’s no real biggie as I can use the right-click button instead, but it would be nice if the mousepad worked too for speed/ease of use.

2. How do you deal with long-press (or ‘hold’) functionality in your setup (if you do at all)? The specific example I have come across is…

Left-click mouse button (HOLD) - I tried to set this up to mimic a real mouse whereby you can left-click-hold and drag a selection (icons or text) to highlight them and then copy/paste, etc. I tried this by adding two event triggers onto a button (Pressed = “MouseLeftDown” & Released = “MouseLeftUp”). I then press this button down and drag over some notepad text to highlight it. This all looks good, but when I cut/copy the text it seems the buffer is empty - nothing is pasted. My suspicion is that the Pressed part is fine (putting the left mouse button down) but as soon as the button is released, the button goes back up ‘releasing’ the selected text (even though it is still highlighted in notepad) meaning there is nothing to cut/copy.

Have you come across this issue and if so, have you solved it?? I may be missing something here (very likely!) so feel free to shoot my method to ribbons and point out the obvious.

3. In a similar vein to #2 above, how can I mimic long-pressing a key and it repeating the keystroke/input?

Example: On a normal keyboard (or mobile device) if you press and hold the left arrow key, it will keep repeating the left input until you release the key. Is there any way of doing this in HR with the MCEC plugin - maybe using a specific repeat trigger or script??

Thanks in advance,
Shuggs

Hi @Shuggy, I’m glad it is (mostly) working well for you! I recently got so frustrated with my Nvidia Shield that I had to control over IR with a Global Cache that I put together a spare box to be my HTPC again and I have really enjoyed the experience so much more. I’m glad others find it useful as well :slight_smile:

I’m stumped as to why the right-click (2-finger tap) doesn’t work in Android. My theater remote has always been an iPad, and I’m almost positive it works there (haven’t used 2-finger taps in a while, but will try to play with it this weekend). Unfortunately, I don’t have a spare Android tablet to try to reproduce your exact situation.

I will be honest, I wrote the webpage portion of the MouseHelper back in 2015 and basically haven’t looked at it since. Even the mhserver.js, while I have updated a couple of things over the years, I haven’t really studied since then either–I got it working and have basically left it alone :slight_smile: All of the touch-sensing is handled by the hammer.min.js library, so it seems most likely if there is a bug for Android, it is in that library. Unfortunately, it’s not actively supported anymore. I noticed the github page for it does have some suggested alternatives in the some of the comments/bug reports, so maybe I can find some time to look into using a different library for the touch stuff. If you have any skill with javascript, please feel free to take a stab at it, as I hate javascript…

One other thing to note, in case it was not apparent, is that when you map a THR button to a mouse button, that is actually sent directly to MCEC from THR by the plugin (just like any of the other MediaCommands). When you tap/doubletap/etc in the MouseHelper, those commends get sent to MCEC via mhserver.js. That would explain why the button works when the 2-finger tap doesn’t.

I’m not entirely sure I follow what you tried to set up to address this. However, I can tell you there is no long-press (as I understand that term) support for the mouse buttons in the MouseHelper interface. If you hold a single-finger press (vs a tap; so you don’t have to hold super-long, but I think it’s set to half a second), then the MouseHelper enters “dragging” mode, and so then it will be as if the mouse button is being held down and you can, for example, drag a window around or a highlighting cursor. Then any other input that isn’t a drag (tap, doubletap, another press, etc) will “release” from dragging mode and return things to normal. So you shouldn’t need to do anything complicated in THR to get that behavior–it’s handled in the MouseHelper interface.

That said, that isn’t a long-press as I understand the term. That’s just a hold-down-the-mouse-button-so-I-can-drag/drop-in-the-interface. My understanding of long-press is that you get a different behavior when you hold down the button for some period of time vs a shorter click.

I suppose if you were appropriately quick, you could use the dragging mode to simulate a long-press: press on the MouseHelper interface and then after a brief period of time (long enough for a long-press) tap it again and to the computer it would appear as the left mouse button having been help down for that interval.

I think that’s the best you can do, because hammer.min.js doesn’t have any long-press support that I’m aware of.

Having re-read this, I think the dragging mode is probably what you’re after here. One possibility (and this may tie in to the 2-finger tap issue you mentioned as well) is that the MouseHelper interface (really, hammer.min.js) can be very sensitive to slight movements of your fingers in the actions. So, for example, right click may not work because your 2 fingers don’t come down close enough together in time (in hammer.min.js's opinion) or they move slightly, and so it just doesn’t register it correctly (thinks it is a rotate instead of a 2-finger tap or something). I don’t think there’s anything you can do about that beyond trying to be more careful (which is annoying). You could try repeatedly 2-finger tapping and see if you are ever able to get a right-click sent. Tying back to the select and drag thing, it is possible your release at the end also involves enough movement that Windows drops the highlighting. But that’s just pure speculation.

This is, I believe, both a THR limitation and an MCEC limitation. THR does not, to my knowledge, support long-presses (or if it does, it is platform dependent), which I think in this context would actually be thought of as “continuous” presses (again, I think long-press has a different, specific meaning). THR also doesn’t support continuous presses as far as I know. I haven’t looked into it a ton because it’s not something I’ve ever needed (except maybe on arrow keys); I don’t know that there is any reliable way to simulate it in THR, but I’m sure others have asked this before.

From a quick look through MCEC's documentation, I don’t believe it supports long-presses or continuous presses (except of mouse buttons) either. If what you’re after is continuous press, as long as you can get THR to repeatedly fire the button, MCEC would “do the right thing” at least.

Sorry I can’t be more help with some of these issues. But please let me know if you find solutions, as I would love to incorporate them. My intention with this plugin and the MouseHelper was to make it as full-featured/general purpose as possible because sometimes it’s just nice to have your own keyboard/mouse on your HTPC :slight_smile:

1 Like

Wow! Thanks for the detailed reply and help @hotelfoxtrotnovember. Way above and beyond what I expected.

Yeah, I’ve had various media boxes - the most recent I’m moving from is the Vero4K+. As amazing as that box is, it’s starting to struggle with my Kodi skin and various OSMC-related issues that I can’t be bothered to keep fixing. We also want to manage Kodi, TV, web browsing and gaming (Steam & emulation) from a single box - so HTPC is the way.

No problem…don’t worry about looking into the Android functionality - as I said I’ll just use the right-click button and forget about the double-fingers on the touchpad.

Unfortunately, zero js skill. I’m from an Art/design/UI background so very much on the aesthetic side. However, I do pick up some technical things quickly once I grasp the method.

Aha! I didn’t know there was a built-in ‘drag-select’ mode in the mousehelper. I’ve since tested this out and it works really well tbh - moreso on the bigger mousepad obviously so it looks like I’m going to stick to using a 10" tablet rather than a smaller mobile screen.

You are correct - I defer to your terminology. I wasn’t thinking too much about the terminology when I wrote the post, so yes - a long-press would be a defined longer period of time (1-2 secs, etc) and I was really talking about a hold/continuous mouse (or button) press.

Yeah I’d thought about the ‘granularity’ issue and that it was either too sensitive or not judged to be close enough together. So I tested a THR page containing only a full screen mousepad on a 10" android tablet and even that didn’t work so I don’t think it’s that (though it is still very possible). If it is down to the sensitivity/granularity, even on a 10" tablet, then I’d need something the size of my 65" TV. :wink:
Regardless, I’ll just use a ‘right-click’ button next to the mousepad.

I’ve got a big list of THR/MCEC stuff to test and setup this weekend so I will look into trying to repeat a button press. If I get anywhere with it I will let you know. There’s probably a way to do it with a script, but alas I’m no scripter.

Absolutely!..I’d love to get as fully-featured a keyboard/mouse setup as possible too. I’ll report back anything of relevance and any other issues I come across. I really appreciate the help and your efforts in producing this in the first place. :+1:

Shuggs

1 Like

@Shuggy one thing just popped into my head so I did a little poking around. You should be able to use the RepeatInterval property on the button to get it to fire multiple times when continuously held down. I haven’t personally tested it, but see here. I don’t have it enabled (or I just never held it long enough, 250ms is pretty long) on my buttons so that is why I probably never knew you could do it, but THR is pretty awesome :slight_smile:

1 Like

@Shuggy a second thing popped into my head as well (the thoughts do eventually work their way up out of the depths)… I tried the 2-finger tap on my iPad and it also did not work for a right-click, which brought up a vague memory that I thought I had discussed years ago with @bill that this was a THR limitation, but after some searching I couldn’t find it anywhere, so who knows. Regardless, I believe THR’s WebBrowser control (maybe THR itself?) does not support multi-touch. You could test this by bringing up a web browser app on your device and going to: http://IP-address-of-your-HTPC:6224/index.html and that should bring up the MouseHelper interface in your web browser, which most likely does support multi-touch, so you could experiment with that. It’s not real practical for interacting with your HTPC, but I thought it might be useful to know.

@hotelfoxtrotnovember Yes! I just got around to playing with the repeat button and realised that the interval was quite high (it doesn’t sound that much, but you’re right it’s a long time on a button press). Down at 50/60ms it works a treat. My arrow keys work perfectly now - they act pretty much like a physical keyboard and I can traverse documents, etc easily. :+1:

I have tried this before on both devices but just for sanity I tested it again (Android mobile and 10" tablet). Even using the web browser (index.html) I get absolutely no response with the double-finger tap, so you are correct - it looks like there is no support for that in the WebBrowser control.
Thanks for looking into it and confirming the behaviour (or lack of).

On the subject of the index.html…
I played around with the settings/options at the top of the file to customise the touchpad a little. One issue is that even on the larger tablet screen, the scrollpad by default is very sensitive! You just have to move your finger a hair’s width and you have scrolled a page. Do you see similar sensitivity on your ipad?

I have managed to find a workaround for web browsers by installing a scroll addon/extension and vastly reducing the scroll step size. However, this obviously does not apply to windows explorer and other apps.

Is it correct that the ‘SCROLL_INCREMENT’ in the index.html only obeys whole numbers? I tried reducing this to 0.2, 0.3, etc but the scrollpad stops working completely unless set to a whole number. I was kind of hoping it would be some sort of multiplier so I could reduce the scroll speed.
Is this to be expected and if so, is there any way of reducing the scroll speed?

Thanks again,
Shuggs

EDIT: By contrast I changed the ‘MOUSE_MOVE_SCALE’ and that works really well (I have it set around 2.5.)

I do find the scrollpad a little more sensitive than I’d like, but it’s generally been sufficiently workable for me. You are correct about the SCROLL_INCREMENT being an integer. That is passed through to MCEC as a mouse:vs command, which takes the SCROLL_INCREMENT as the parameter corresponding to “the amount to scroll in clicks”. I interpret “clicks” in this context to be clicks of the scroll wheel in rotation. So 1 would be the minimum you can do, unfortunately.

That said, in Windows you can set how many lines to scroll each time the wheel is turned (Settings → Devices → Mouse). Also, you might want to play with the SCROLL_THRESHOLD parameter in the index.html, as that is how far your finger has to travel before it registers a scroll event. That would also make it a little less sensitive from the standpoint of scroll events not firing as often per distance traveled in the scrollpad.

If you find a value for SCROLL_THRESHOLD you like, please let me know and I’ll try it out too. Maybe the MouseHelper just needs an updated default value to make it a little more friendly.

1 Like

I’d been playing around with the SCROLL_THRESHOLD parameter as well - this yielded slight results. But I’d completely forgotten about the Windows setting on scroll lines. Good shout! So I’ve dropped this from the default of 3 lines to 1 line (minimum) in the Win10 settings. The scrollpad is still not perfect, but it is much more stable and easier to control now. :+1:

I’m getting the remaining building blocks in place for PC control before I start looking into a design & UI layout. The power and flexibility of all this blows my mind. The fact that I’m controlling the devices through ethernet LAN too - which means the response is instant and I can be as far away as I like and not worry about IR/Bluetooth dropouts. :sunglasses:

I agree completely about the Ethernet/IP control – I vowed I would never buy another non-IP controllable device again, ended up experimenting with the Nvidia Shield (the latest one, which removed IP control and can only be controlled over IR), and finally had enough after a few months to dust off an old computer and build my current HTPC :slight_smile:

One word of warning–MCEC seems to have some limitations with some of Window’s security features (UAC is the most notable) and when one of those boxes and/or a window requiring Admin rights pops up, Windows stops responding to MCEC's virtual keyboard/mouse inputs. It doesn’t happen much, but it is very frustrating when it does, because the only solution I’ve found is to plug a keyboard/mouse into the computer to try to clear it. If you (or anyone else!) knows how to get around those issues, I would love to know!

Sure do! I set my new HTPC up with full admin access from the get-go (with a bespoke debloated version of Win10.) I’ve also got 2 older PCs running in this fashion and I’ve never had any issues with those.

The key is to only run a single account and make sure it is an Administrator. Then you can disable the Admin approval, stopping any popups and notifications. The extra win here is even when you change things like the display fps, you do not get popups asking you to revert changes, etc - it just changes the display.

**Note: This is for Windows 10 only - I do not know if this works the same in Win7/Win11, etc.


1. So the first thing is to check your user account is an Administrator. Follow the image instructions to check your account status…

If you already have an Administrator account, then jump down to step 2 below. If not, then this is how you change your account type…

  • Open Control Panel
  • Under the User Accounts section, click Change account type
  • Select your account
  • Click the Change the account type option
  • Select Administrator
  • Click the Change Account Type button
  • Restart you PC (or log out) for the account to be updated

2. Now we need to turn off the Admin approvals for the account. This is very simple…

  • Click the Start menu
  • Type in "group policy"
  • Click Edit Group Policy in the Start menu results
  • In the Group Policy window, navigate to: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options

  • Scroll down to the bottom and make sure the highlighted Admin Approval option is Disabled (to change it, right-click > properties and check the ‘Disabled’ option)
  • Apply any changes and close the Group Policy window
  • Restart your PC for the changes to take effect

After restart you should test running some of the apps, etc that required admin approval to see whether they still generate pop-ups and (hopefully) they have been disabled correctly.

Let me know if you have any problems or it doesn’t work - there’s a possibility I changed some other settings to do this and I’ve forgotten some of it!

Shuggs

P.S: I recommend only using the HTPC for your media purposes and do any sensitive work/finances, etc on other devices. That’s just me though - I’m paranoid like that. :upside_down_face:

1 Like

Thanks for the awesome write-up on this, @Shuggy! I have done some of those things, but I don’t think all of them, so hopefully that will take care of the few random annoyances I still encounter!

1 Like

No problem! :+1:

I wonder if you can help with another THR/MCEC issue I’m having? The “PowerOn” command refuses to power-on / wake-up my HTPC (the “PowerOff” command works fine.)

All relevant WOL settings are enabled on the HTPC (BIOS, NIC adapter, Power management, magic packets, etc.)

If I run a simple WOL command from any another PC in the network, the HTPC always turns on.
If I use my FLIRC USB dongle (set with a simple ‘wake’ button) it always wakes up the HTPC via my Logitech Harmony remote (using a mapped button).

Strangely, if I run a ‘Startup Activity’ from a THR button (start PC > start TV > change input > launch a youtube browser), the HTPC will not power up. However, if I then manually press the power button, a short time after it comes out of standby, the remainder of the activity occurs (launching the youtube browser.)

I’m assuming this is something to do with the power-off/suspend state of the HTPC (so MCEC is not able to receive inputs.) When a PC is sent the ‘standby’ command from the THR plugin which power state is the PC going into (S1-S5)?

Any ideas what might be the issue here? It’s frustrating because I’m pretty much fishing in the dark at this point.

Thanks!

I’ll be honest, I had thought that my WoL functionality was working fine but I discovered it might have only been working when the HTPC turned the display off (but hadn’t actually gone to sleep), so I may need to experiment more myself.

What do you use to send the WoL command that works? I recall that some devices need to have the IP address specified in the WoL magic packet and not just the MAC address. Perhaps that is what is going on here? I also recall there are a couple of different port options that are sometimes needed as well. I have a more complicated WoL routine I wrote for another plugin that needed it, but I’ll have to dig up which one it was.

That’s really weird about the delayed set of commands, but I wonder if the HTPC when asleep is still buffering the network data to MCEC and that is why Youtube launches as you’re seeing? Alternatively, perhaps the TCP connection from THR to MCEC to send the commands is trying to send and when the HTPC wakes up, it eventually gets through?

Regarding what power state the standby command triggers, I honestly do not know. The command is built in to MCEC (see MCE Controller Documentation | MCE Controller). I’m guessing S3, but I honestly don’t know.

No problem - I only have S1, S2, S3 and hibernate available on the HTPC so my suspicion was that it was S3 too. I guess it’s irrelevant really - a WOL command should wake any of them up. It’s good to know that yours may not be actually sleeping/waking up too (just for my sanity’s sake) :wink:

It does feel like the commands are stored and repeated once the HTCP does wake up (it takes ~5+ seconds after wake-up for the commands to start executing.)
I’ve tested this theory a little further by running the activity 3 or 4 times before manually waking up the PC with the power button. Sure enough, all of the commands are then executed and I end up with 3 or 4 instances of youtube web browsers.

Waking up the HTPC from any other PC on my network, I send a magic packet using wolcmd. I run a simple batch script as follows…

wolcmd [mac address] [ip address] [subnet mask] [port number]

wolcmd 11:22:33:44:55:66 192.168.1.99 255.255.255.0 9
timeout /t 2
exit

It would be great if you have the time to look into it and hunt down ‘the other WOL’ you had - it might just do the trick.
As always, thanks for your support and helping me out!

I threw together a quick and dirty plugin with the more complex WoL code:
MCEController.plugin - 2023-05-27-TEST.js.txt (20.6 KB)

If this works, I will clean it up a little and add some additional plugin settings. For now, this way you only need to copy/paste the new code in and not worry about any additional plugin setup.

To use it, your Host setting needs to be an IP address. Also, it currently doesn’t use a port by default, but if you want to force it to use port 9 (as your wolcmd takes as a parameter) you need to set the WOLPORT variable up at the top to be "9" (it might work if it’s the number 9, but it is intended that you give it the string).

I haven’t had a chance to test this myself, but wanted to try to keep things moving for you. Please let me know what you discover and/or if you have any questions/problems.

1 Like

Tested by copy-pasting the code from this plugin and replacing my existing one. It works a treat! Thanks very much for quick fixing this - your support is amazing.

FYI, my setup was tested with the WOL port left blank and set to ‘9’ (to mimic the wolcmd wake-up). Both ways it reliably wakes the HTPC up now (tested 20-30 times with various sleep durations). :sunglasses:

It got me thinking on whether there is any way of knowing the power status of the HTPC in THR? (similar to the .Switch property on other devices) Asides being able to provide status feedback for the user, it would also be handy for other reasons (triggering events based on the HTPC on/off states.)

What do you think…is this possible?

Thanks for testing, @Shuggy and I’m glad it worked! I have updated the top post with a more polished version of the plugin. This one adds some additional Settings, so technically I think you need to delete and re-add the plugin in its entirety (otherwise the new Settings don’t get added). The defaults are set based on what you discovered (using the IP address and port 9) because, as far as I know, MCEC only runs on Windows, so those seemed like the best defaults for this plugin.

I tested it out and it seems to work for me as well, but I did rearrange the code a bit since I didn’t like where the WOL stuff was located. It should be cleaner and hopefully I didn’t break anything in the process :slight_smile: As always, please let me know if you have any problems.

Regarding knowing the power status of the HTPC, I think the answer is no. There’s nothing magical about the Switch Attribute–the value for it just gets set based on feedback from the device in the plugins/built-in devices that support it. But if the HTPC is off, there’s no way to query that (you might be able to infer it based on a connection timeout, but that is pretty clunky because THR doesn’t provide reliable timeouts on connection attempts, as I recall, and it takes a long time).

I think some home automation hubs may have a little better support for tracking the state of a PC device (using pings or something), but I’ve never played around with those–I got into THR to control my home theater setup and not for more general home automation. That might be your best avenue, at least for triggering events, I’d think.

All of that said, in other plugins I have added some internal psuedo-power state tracking, just to reduce trying to connect to a device that I don’t know whether it is on yet not, so it avoid some timeout-type behavior which is annoying. That might be possible here, but I’m not sure it really makes sense–there’s no harm in sending WOL when it’s already on, so the assumption is that it is always on, and the internal power state tracking adds some complexity.

1 Like