TRIGGERcmd
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login
    1. Home
    2. Russ
    • Profile
    • Following 1
    • Followers 42
    • Topics 229
    • Posts 2,671
    • Best 167
    • Controversial 6
    • Groups 1

    Russ

    @Russ

    administrators

    I'm a tech enthusiast with about 30 years experience in IT. Recently I'm also a TRIGGERcmd developer.

    165
    Reputation
    3.8k
    Profile views
    2.7k
    Posts
    42
    Followers
    1
    Following
    Joined Last Online
    Website triggercmd.com Location Haslett, MI

    Russ Unfollow Follow
    administrators

    Best posts made by Russ

    • RE: Laptop Battery Management - Automated On/Off Cycle

      @philip-nguyen, there's a similar question here.

      These are the high level steps:

      1. Create 2 commands that just run echo (doesn't matter what), and name them PlugOn and PlugOff.
      2. Setup two Alexa routines - one that turns on your smart plug when the PlugOn command runs, and other that turns it off when the PlugOff command runs.
      3. Create a script. At the beginning of the script, do the following:
      4. Set variable called PLUG_IS_ON with a default value of true.
      5. To make sure the plug is on at first, run the tcmd utility like this: tcmd -t plugon -c (your TRIGGERcmd computer name)
      6. Create a loop that repeats every minute. Inside the loop, do the following:
      7. Check your battery level with BatteryInfoView.exe
      8. When the level is below 30 percent and PLUG_IS_ON = false, run tcmd utility like this: tcmd -t plugon -c (your TRIGGERcmd computer name)
      9. When the level is above 99 percent and PLUG_IS_ON = true, run tcmd utility like this: tcmd -t plugoff -c (your TRIGGERcmd computer name)
      10. Also set PLUG_IS_ON to true when you run plugon, and set it to false when you run plugoff

      I think that should work. Do you know how to do that? Let me know if you get stuck, and where you get stuck. I can look at your script if you paste it here.

      posted in Example Commands
      RussR
      Russ
    • List of ways to trigger your commands

      You can use this web page of course, but don't stop there. Check out this list of ways to run your commands on your computers.

      The Smart Home version of the Alexa skill and Google Assistant action does the best job of matching your spoken words to your commands.

      Smart Home voice assistant skills (Example: "Alexa, turn on calculator") <--Recommended

      • "TRIGGERcmd Smart Home" Alexa skill
      • "TRIGGERcmd Smart Home" Google Assistant action

      Original "conversational" voice assistant skills (Example: "Alexa, ask TRIGGERcmd to run calculator"):

      • Original Alexa skill
      • Original Google Assistant action (deprecated)

      Progressive Web App (PWA)

      • https://app.triggercmd.com

      Mobile apps:

      • Apple App Store: TRIGGERcmd
      • Google Play Store: TRIGGERcmd (supports widgets)
      • Amazon App Store: TRIGGERcmd

      Run your commands when things happen in other Internet services:

      • Zapier - create a "Zap" that runs your command when something happens on one of their 1500+ supported apps.
      • Make - create "scenarios" that run commands on your computers.
      • IFTTT - If This Then run a command, or if a TRIGGERcmd command runs, run an IFTTT applet.
      • Microsoft Power Automate (aka Flow) - run commands when things happen in Office 365 and other services.
      • Pipedream - build workflows that run your commands.

      IoT Smart Home hubs:

      • Home Assistant - Flip virtual HA switches to run your TRIGGERcmd commands.
      • Samsung SmartThings - Create virtual switches for each command, then flip the switches to run them. (Not working as of 6/21/2025)
      • Homey - Use the ‘run command’ flow action.
      • Hubitat - Trigger a command like you'd flip a switch.
      • Node-RED - Run commands using an "http request".
      • HomeKit - Use the homebridge-http-switch plugin with a bookmark URL.

      Other cool methods:

      • Run an Alexa routine - when one of your TRIGGERcmd commands runs.
      • Google Assistant routine (aka automation) - use one of your TRIGGERcmd commands as a "starter" to run your routine when the command runs, or run one of your commands as a routine's "action." Either way, you must use the google automations script editor, not the Home app.
      • Local stdio MCP - Run commands from local AI LLM chat tools like Claude Desktop or VS Code. Use the "MCP Tool Description" field of each command to tell the LLM what the command does, and how to use the parameters.
      • Online Streamable HTTP MCP - Same as above but for online AI tools like Mistral AI.
      • n8n community node - Run your commands from n8n AI workflows.
      • Bookmarks - Create and share URL's that run your commands without authentication. You can set an optional timeout to make bookmark URL's expire. People can also scan your bookmark's QR code to run the command.
      • iOS shortcut - Use the iOS Shortcuts app to run your commands with Siri.
      • REST API - Use curl or other client to call the TRIGGERcmd API.
      • tcmd - Command line tool written in Go.
      • Tasker - Tasker is an Android app for automating things with your phone.
      • Slack app - Run your commands with Slack "slash" commands.
      • Powershell - Run a command on a computer across the Internet from your powershell script.
      • Roku channel - Run a command from your Roku.
      • Unity - Run a command from a Unity game or utility you made.
      • Streamdeck - Configure a Streamdeck button to run a command on a remote computer.
      • Python - Run a command on a remote computer from a python script.
      • Paywall URL's - Similar to bookmark URL's, you can also charge people via Paypal to run your commands.
      • viaSocket - Run commands from your viaSocket flow.
      posted in Instructions trigger methods
      RussR
      Russ
    • Autohotkey script for Play, Pause, Volume Up/Down, Next/Previous

      You'll need to install this on your Windows box to make it work: https://autohotkey.com

      This is my media.ahk autohotkey script:

      Gosub, %1%
      return

      next:
      Send {Media_Next}
      return

      previous:
      Send {Media_Prev}
      return

      pause:
      Send {Media_Play_Pause}
      return

      play:
      Send {Media_Play_Pause}
      return

      stop:
      Send {Media_Stop}
      return

      volup:
      Send {Volume_Up}
      return

      voldown:
      Send {Volume_Down}
      return

      mute:
      Send {Volume_Mute}
      return

      These are the corresponding commands.json entries:

      {"trigger":"Mute","command":"start C:\\autohotkeyscripts\\media.ahk mute","ground":"foreground","voice":"mute"},
      {"trigger":"Volume Up","command":"start C:\\autohotkeyscripts\\media.ahk volup","ground":"foreground","voice":"volume up"},
      {"trigger":"Volume Down","command":"start C:\\autohotkeyscripts\\media.ahk voldown","ground":"foreground","voice":"volume down"},
      {"trigger":"Media Next","command":"start C:\\autohotkeyscripts\\media.ahk next","ground":"foreground","voice":"next"},
      {"trigger":"Media Stop","command":"start C:\\autohotkeyscripts\\media.ahk stop","ground":"foreground","voice":"stop"},
      {"trigger":"Media Previous","command":"start C:\\autohotkeyscripts\\media.ahk previous","ground":"foreground","voice":"previous"},
      {"trigger":"Media Play Pause","command":"start C:\\autohotkeyscripts\\media.ahk pause","ground":"foreground","voice":"pause"},

      NOTE: You don't need a Play and a Pause because they do the same thing - they just toggle between play and pause.

      This is optional, but I'm also using my Raspberry Pi based IR receiver to trigger the above commands with a VCR remote.

      I have these entries in my /etc/lirc/lircrc file on the Pi:

        begin
             prog = irexec
             button = KEY_1
             config = export HOME=/root ; /root/triggertest.sh play downstairs
        end
        begin
             prog = irexec
             button = KEY_2
             config = export HOME=/root ; /root/triggertest.sh notepad downstairs
        end
        begin
             prog = irexec
             button = KEY_PLAY
             config = export HOME=/root ; /root/triggertest.sh "Media Play Pause" downstairs
        end
        begin
             prog = irexec
             button = KEY_PAUSE
             config = export HOME=/root ; /root/triggertest.sh "Media Play Pause" downstairs
        end
        begin
             prog = irexec
             button = KEY_RIGHT
             config = export HOME=/root ; /root/triggertest.sh "Media Next" downstairs
        end
        begin
             prog = irexec
             button = KEY_LEFT
             config = export HOME=/root ; /root/triggertest.sh "Media Previous" downstairs
        end
        begin
             prog = irexec
             button = KEY_STOP
             config = export HOME=/root ; /root/triggertest.sh "Media Stop" downstairs
        end
        begin
             prog = irexec
             button = KEY_UP
             config = export HOME=/root ; /root/triggertest.sh "Volume Up" downstairs
        end
        begin
             prog = irexec
             button = KEY_DOWN
             config = export HOME=/root ; /root/triggertest.sh "Volume Down" downstairs
        end
        begin
             prog = irexec
             button = KEY_MUTE
             config = export HOME=/root ; /root/triggertest.sh "Mute" downstairs
        end
      
      posted in Windows
      RussR
      Russ
    • RE: internal server error

      @Micael-Sousa, good to know. I'm glad you figured this out.

      posted in Alexa
      RussR
      Russ
    • RE: Doc Api

      @Ruan-Santana, I added two pages to the documentation this morning:

      https://docs.triggercmd.com/#/./API/TriggerCommand
      https://docs.triggercmd.com/#/./API/ListCommands

      Is that what you're looking for?

      posted in API
      RussR
      Russ
    • RE: New Bookmark option for each trigger

      @tim-s, that's right - you could even just change the trigger name and change it back, and it would invalidate the bookmark URL.

      posted in Announcements
      RussR
      Russ
    • RE: Shutdown não funciona no mac

      @Waldex-Santos, I think this should work:

      osascript -e 'delay 60' -e 'tell app "System Events" to shut down'
      
      posted in Mac
      RussR
      Russ
    • RE: Triggercmd smart home not reachable

      It's back up now.

      One of my servers went down last night, and Kubernetes didn't handle the fail-over well.

      I got an email from my monitoring system while I was sleeping. I'll need to setup something else that will actually wake me up.

      I'm sorry about this outage.

      posted in Google Home
      RussR
      Russ
    • Hubitat integration

      @Royski created this Hubitat integration that works just like the SmartThings integration.

      His write up is here, on the Hubitat community forum:
      https://community.hubitat.com/t/release-triggercmd-for-hubitat/22715

      The code and instructions are here:
      https://github.com/rvmey/HubitatTRIGGERcmd

      Here's quick video showing it working:
      https://youtu.be/V90B7jbEYxI

      posted in Instructions
      RussR
      Russ
    • Alexa bug fixed

      Some of you might have noticed, when you'd say something like:

      Alexa, ask TRIGGER cmd to run notepad on downstairs

      You'd get an answer like this:

      "Could not find a command with voice word cmd notepad on downstairs, ..."

      I fixed that today.

      For some reason Alexa started sending the "cmd" part of "TRIGGER cmd" as a prefix in the command name. I actually had to add code to strip that out.

      posted in Announcements
      RussR
      Russ

    Latest posts made by Russ

    • RE: TRIGGERcmd setup on Google Assistant

      @Nuno-Gomes, thanks for telling me. Please try again. It should work now.

      posted in Google Home
      RussR
      Russ
    • RE: Firest time setting up, oauth failure

      @Asit-Mishra, thanks for telling me. Please try again. It should work now.

      posted in General Discussion
      RussR
      Russ
    • RE: How to use Off Command

      @Yoni, thanks for letting me know. I'll make it case-insensitive in the next version.

      posted in Instructions
      RussR
      Russ
    • RE: I want to be able to trigger an Alexa routine from a command line with the triggercmdagent installed on my Raspberry Pi

      @Matt-Lodder, what OS are you running? I just tried echo on my Windows laptop and it did not pop up a window.

      posted in Raspberry Pi
      RussR
      Russ
    • RE: Email says command didn't run, but it did.

      @David-Coulson, I'll look into it.

      One thing you can check in the meantime make sure this checkbox is unchecked in your profile:

      fa9d5c2b-e823-4313-b84c-7c27e2afd8fa-image.png

      Can you show me one of the emails? I wonder if it's reminding you to subscribe because you're running more than 1 command per minute. I'll add an option to disable those emails too.

      Also, did you enable "Home Assistant Offline Configuration"?

      EDIT: I added this checkbox that you can uncheck to stop the subscription reminder emails:

      9edb18d9-cec9-4ebf-92ac-a40b6612bfbe-image.png

      posted in General Discussion
      RussR
      Russ
    • Python script to change my wifi color LED light bulb state

      My PC talks to my wifi light bulb directly, not via Tuya's cloud API.

      I can say, "Alexa, bulb 1 red" or "Alexa bulb 1 off" etc.

      I can also say, "Use @TRIGGERcmd to turn bulb 1 blue" using the MCP tool with ChatGPT.

      Example commands:

      Turn the bulb on:

      python3 c:\tools\tuyabulb.py --id abcdefghijklmnop123456 --key "123456!@ABCcdefh" --ip 192.168.86.25 on
      

      Set the color to red:

      python3 c:\tools\tuyabulb.py --id abcdefghijklmnop123456 --key "123456!@ABCcdefh" --ip 192.168.86.25 red
      

      Set the brightness to 60 percent:

      python3 c:\tools\tuyabulb.py --id abcdefghijklmnop123456 --key "123456!@ABCcdefh" --ip 192.168.86.25 60
      

      Here's the script:

      #!/usr/bin/env python3
      import argparse
      import ipaddress
      import platform
      import subprocess
      import sys
      import tinytuya
      
      # Predefined color presets (RGB values)
      COLOR_PRESETS = {
          "red": (255, 0, 0),
          "green": (0, 255, 0),
          "blue": (0, 0, 255),
          "white": (255, 255, 255),
          "yellow": (255, 255, 0),
          "cyan": (0, 255, 255),
          "magenta": (255, 0, 255),
          "orange": (255, 165, 0),
          "purple": (128, 0, 128),
          "pink": (255, 192, 203),
      }
      
      
      def ping_host(ip: str, timeout: int = 1) -> bool:
          """Ping a host to check if it's reachable. Returns True if ping succeeds."""
          param = "-n" if platform.system().lower() == "windows" else "-c"
          timeout_param = "-w" if platform.system().lower() == "windows" else "-W"
          timeout_value = str(timeout * 1000) if platform.system().lower() == "windows" else str(timeout)
          
          command = ["ping", param, "1", timeout_param, timeout_value, ip]
          try:
              result = subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=timeout + 1)
              return result.returncode == 0
          except (subprocess.TimeoutExpired, Exception):
              return False
      
      
      def make_device(device_id: str, ip: str, local_key: str, version: str | None):
          # BulbDevice works for most Tuya bulbs. If yours isn't a "bulb" type, use Device instead.
          d = tinytuya.BulbDevice(device_id, ip, local_key)
          d.set_socketPersistent(True)   # keep socket open for reliability
          d.set_socketTimeout(5)         # seconds
      
          # Many Tuya WiFi bulbs are 3.3. Some are 3.1. If you're unsure, try 3.3 first.
          if version:
              d.set_version(float(version))
          else:
              d.set_version(3.3)
      
          return d
      
      
      def main():
          p = argparse.ArgumentParser(description="Local control of a Tuya bulb via tinytuya (no cloud).")
          p.add_argument("--id", required=True, help="Tuya device id")
          p.add_argument("--ip", help="Bulb IP address on your LAN")
          p.add_argument("--subnet", help="Subnet to scan (e.g. 192.168.1.0/24)")
          p.add_argument("--start-from", help="IP address to start scanning from (only with --subnet)")
          p.add_argument("--key", required=True, help="Tuya localKey (16+ chars)")
          p.add_argument("--ver", default=None, help="Protocol version (e.g. 3.3 or 3.1). Default: 3.3")
          p.add_argument("cmd", help="Command: off, on, status, color name (red, green, etc.), or brightness 0-100")
          args = p.parse_args()
      
          # Determine command type
          cmd_lower = args.cmd.lower()
          if cmd_lower in ["off", "on", "status"]:
              cmd_type = cmd_lower
          elif cmd_lower in COLOR_PRESETS:
              cmd_type = "color"
              preset_color = cmd_lower
          elif args.cmd.isdigit():
              brightness_val = int(args.cmd)
              if 0 <= brightness_val <= 100:
                  cmd_type = "brightness"
              else:
                  p.error("Brightness must be between 0-100")
          else:
              p.error(f"Invalid command: {args.cmd}. Use: off, on, status, color name, or brightness (0-100)")
      
          # Validate that either --ip or --subnet is provided
          if not args.ip and not args.subnet:
              p.error("Either --ip or --subnet must be specified")
          if args.ip and args.subnet:
              p.error("Cannot specify both --ip and --subnet")
          if args.start_from and not args.subnet:
              p.error("--start-from can only be used with --subnet")
      
          # Determine which IPs to try
          if args.subnet:
              try:
                  network = ipaddress.ip_network(args.subnet, strict=False)
                  all_ips = [str(ip) for ip in network.hosts()]
                  
                  # Filter to start from specified IP if provided
                  if args.start_from:
                      start_ip = ipaddress.ip_address(args.start_from)
                      # Verify start IP is in the subnet
                      if start_ip not in network:
                          print(f"ERROR: Start IP {args.start_from} is not in subnet {args.subnet}", file=sys.stderr)
                          return 1
                      # Filter to IPs >= start_from
                      ips_to_try = [ip for ip in all_ips if ipaddress.ip_address(ip) >= start_ip]
                      print(f"Scanning subnet {args.subnet} from {args.start_from} ({len(ips_to_try)} hosts)...", file=sys.stderr)
                  else:
                      ips_to_try = all_ips
                      print(f"Scanning subnet {args.subnet} ({len(ips_to_try)} hosts)...", file=sys.stderr)
              except ValueError as e:
                  print(f"ERROR: Invalid subnet or IP format: {e}", file=sys.stderr)
                  return 1
          else:
              ips_to_try = [args.ip]
      
          # Try each IP until one works
          last_error = None
          for ip in ips_to_try:
              if args.subnet:
                  print(f"Trying {ip}...", file=sys.stderr)
                  # Quick ping check to skip unreachable hosts
                  if not ping_host(ip):
                      continue
              
              dev = make_device(args.id, ip, args.key, args.ver)
      
              dev = make_device(args.id, ip, args.key, args.ver)
      
              try:
                  if cmd_type == "off":
                      r = dev.turn_off()
                  elif cmd_type == "on":
                      r = dev.turn_on()
                  elif cmd_type == "brightness":
                      r = dev.set_brightness_percentage(brightness_val)
                  elif cmd_type == "color":
                      # Get RGB values from preset
                      rgb = COLOR_PRESETS[preset_color]
                      # Set the color
                      r = dev.set_colour(rgb[0], rgb[1], rgb[2])
                  else:
                      r = dev.status()
      
                  # Check if the device responded with an errora
                  if isinstance(r, dict) and r.get("Error"):
                      if args.subnet:
                          # During subnet scan, continue to next IP on error
                          last_error = r.get("Error")
                          continue
                      else:
                          # For direct IP, print error and exit
                          print(r)
                          return 2
      
                  # Success! Print result and exit
                  if args.subnet:
                      print(f"SUCCESS: Device found at {ip}", file=sys.stderr)
                  print(r)
                  return 0
      
              except Exception as e:
                  last_error = e
                  if not args.subnet:
                      print(f"ERROR: {e}", file=sys.stderr)
                      return 1
                  # For subnet scan, continue to next IP
                  continue
              finally:
                  try:
                      dev.set_socketPersistent(False)
                  except Exception:
                      pass
      
          # If we get here with subnet scan, none of the IPs worked
          if args.subnet:
              print(f"ERROR: Device not found in subnet {args.subnet}. Last error: {last_error}", file=sys.stderr)
              return 1
      
      
      if __name__ == "__main__":
          raise SystemExit(main())
      

      This is my commands.json entry:

       {
        "trigger": "Tuya Bulb 1",
        "command": "python3 c:\\tools\\tuyabulb.py --id abcdefghijklmnop123456 --key \"123456!@ABCcdefh\" --ip 192.168.86.25",
        "offCommand": "",
        "ground": "foreground",
        "voice": "bulb 1",
        "voiceReply": "",
        "allowParams": "true",
        "mcpToolDescription": "Controls the state of light bulb 1.  Parameters are: on, off, red, green, blue, white, yellow, cyan, magenta, orange, purple, pink, or brightness percentage from 0 to 100"
       }
      
      posted in Windows
      RussR
      Russ
    • RE: Unable to Subscribe - Link Appears to be Broken

      @Timothy-Martin, please try again. It should work now. Thanks again for telling me it was broken.

      posted in General Discussion
      RussR
      Russ
    • RE: Unable to Subscribe - Link Appears to be Broken

      @Timothy-Martin thanks for telling me! It works now.

      I recently tightened my Content-Security-Policy and I needed to add something to make that Paypal link work.

      posted in General Discussion
      RussR
      Russ
    • RE: Windows Defender triggered by installer

      Thanks @kellanist. I'll take a look.

      I hoped Microsoft would whitelist apps signed by my code signing certificate by now. Maybe I'm missing something.

      If it's new, I think it must be because I recently renewed my certificate.

      EDIT: I submitted the agent to Microsoft just now, so hopefully they'll whitelist it soon. Otherwise I just have to wait for its reputation to build as users install it.

      0cde63ea-3d0e-4b4a-b6e0-13c398ae26ef-image.png

      This is what I saw when I submitted the agent installer:

      "The SmartScreen warning that you reported indicates that the application and/or certificate used to sign it do not yet have a reputation established in our system. Applications without a known reputation will show warnings when downloaded or installed. This does not prevent users from still clicking through to download or run the application. To do so, they can select "More info" -> "Run anyway" option within SmartScreen prompt window.

      Reputation is established by how your download is used by Windows, Edge, Internet Explorer users and the SmartScreen® Service intelligence algorithms. Downloads are assigned a reputation rating based on many criteria, such as download traffic, download history, past anti-virus results and URL reputation.  This reputation may be based on the downloaded program or can also be assigned to the publisher, based on digital certificate information.

      Once your signing certificate has gained reputation in our system, all applications or releases signed with your certificate should have warn-free experience"

      posted in General Discussion
      RussR
      Russ
    • RE: OAuth support for MCP server

      @Kevin-0, it should work now, but only if you have a paid ChatGPT "plus" subscription or greater.

      To add the TRIGGERcmd MCP server (https://www.triggercmd.com/mcp) to your ChatGPT account:

      1. Enable development mode here: https://chatgpt.com/#settings/Connectors/Advanced
        8704bf08-29d3-4e8b-9382-599dd8e2f552-image.png

      2. Go here: https://chatgpt.com/#settings/Connectors
        237586cd-f0c4-4b06-9744-6cfeedef3867-image.png

      3. Click "Create app" and set it up like this:
        2a885474-3eb8-4734-80f7-9c37750770e3-image.png

      I paid for the ChatGPT plus upgrade and tested it:

      121d4d94-e7af-4eda-966a-7d8e1af29114-image.png

      EDIT: I submitted the MCP server to OpenAI to be included in their app store. That should solve the issue I've seen where ChatGPT runs the command twice. If they reject the app I'll do something to debounce it.

      posted in MCP
      RussR
      Russ