Skip to content

tomasmark79/GRemoteX-Solution

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GRemoteX

GRemoteX screenshot

GRemoteX is a schema-driven remote control system for Garmin watches. It pairs a Connect IQ watch app with a PHP backend that renders screens, executes actions, and manages per-device bearer tokens.

Repository layout

gremotex/       Connect IQ watch app (Monkey C)
phpbackend/     PHP backend API and admin UI

This public repository keeps only templates and placeholder values. Real domains, credentials, and deployment settings should stay in untracked local files or in a private fork.

How it works

  1. The watch starts and tries to reuse a stored bearer token.
  2. If no token is available, it starts device pairing with POST /auth/device/start.
  3. The user approves the displayed code through the backend web UI.
  4. The watch polls POST /auth/device/poll until it receives a bearer token.
  5. After authorization, the watch loads /schema/app, /screen/{id}, and /action/{id} as a thin backend-driven client.

Backend setup

Deploy layout

  1. Copy phpbackend/public/ into the public document root.
  2. Keep phpbackend/config/ and phpbackend/data/ outside the document root, or adjust APP_ROOT in phpbackend/public/index.php.
  3. Ensure the web server can write to data/.
  4. Copy phpbackend/config/settings-template.php to local phpbackend/config/settings.php.
  5. Fill in your real domain, admin credentials, and any provider secrets in phpbackend/config/settings.php.
  6. Update phpbackend/config/data.json with your actual schema and data.

If you want the existing Backend: Deploy VS Code task and phpbackend/deploy-backend.ps1 to work without passing command-line arguments, copy phpbackend/deploy-backend.local.example.json to untracked phpbackend/deploy-backend.local.json and keep your real HostName, UserName, and TargetDir there.

Recommended server layout:

/var/www/example.com/
├── private/
│   └── gremotex/
│       ├── config/
│       │   ├── settings.php
│       │   └── data.json
│       ├── data/
│       │   ├── state.json
│       │   └── auth.sqlite
│       └── screen-modules/
└── web/
    └── api/
        ├── .htaccess
        ├── grx.png
        └── index.php

Authentication model

  • Watch and application endpoints use Authorization: Bearer <token>.
  • Device pairing starts unauthenticated and becomes authorized only after admin approval.
  • Admin web pages use a signed-in session.
  • Transitional automation endpoints use HTTP Basic auth with the same admin account.
  • Bearer tokens are non-expiring by default until explicitly revoked.

Main endpoints

Method Path Auth Purpose
GET /health none Liveness probe
POST /auth/device/start none Start device pairing
POST /auth/device/poll none Poll pairing status
GET /auth/device/verify admin session Approve pairing code
GET /auth/devices admin session View and manage devices
GET /schema/app bearer token Fetch app metadata and navigation
GET /screen/{id} bearer token Fetch a rendered screen
POST /action/{id} bearer token Execute an action
GET /ping bearer token Legacy compatibility endpoint
GET /data bearer token Legacy compatibility endpoint
GET /data/{key} bearer token Legacy compatibility endpoint

Authorization header example:

Authorization: Bearer YOUR_ACCESS_TOKEN

Pairing flow examples

Start pairing:

curl -X POST https://example.com/api/auth/device/start \
  -H 'Content-Type: application/json' \
  -d '{"deviceName":"GRemoteX Watch"}'

Successful start response:

{
  "ok": true,
  "deviceId": "...",
  "deviceCode": "...",
  "userCode": "ABCD-EFGH",
  "verificationUri": "https://example.com/auth/device/verify",
  "verificationUriComplete": "https://example.com/auth/device/verify?code=ABCD-EFGH",
  "expiresAt": "2026-06-06T13:32:50Z",
  "intervalSec": 5,
  "message": "Open the verification URL and approve the displayed user code."
}

Poll pairing status:

curl -X POST https://example.com/api/auth/device/poll \
  -H 'Content-Type: application/json' \
  -d '{"deviceCode":"..."}'

Pending response:

{
  "ok": false,
  "error": "authorization_pending",
  "message": "Approval is still pending",
  "intervalSec": 5,
  "expiresAt": "..."
}

Approved response:

{
  "ok": true,
  "deviceId": "...",
  "deviceName": "FR965 Watch",
  "accessToken": "grx_...",
  "tokenType": "Bearer",
  "approvedAt": "...",
  "expiresAt": null
}

Transitional automation example:

curl -u admin:YOUR_ADMIN_PASSWORD https://example.com/auth/device/approve \
  -H 'Content-Type: application/json' \
  -d '{"userCode":"ABCD-EFGH"}'

Operational notes

  • Do not ship shared secrets inside the watch app.
  • Auth storage defaults to SQLite at data/auth.sqlite.
  • The backend can later move to MySQL without changing the watch pairing contract.
  • Admin password rotation can be done during deployment with:
.\phpbackend\deploy-backend.ps1 -PromptAdminPassword

Or with a prepared bcrypt hash:

.\phpbackend\deploy-backend.ps1 -AdminPasswordHash '$2y$12$...'

Watch app setup

The tracked watch source keeps https://example.com/api as a safe placeholder. Real backend URLs are injected only during local scripted builds.

Local watch configuration

Create a local, untracked config file:

Copy-Item .\gremotex\watch-config.local.example.json .\gremotex\watch-config.local.json

Set your real backend URL:

{
  "baseUrl": "https://your-real-host.example/api",
  "developerKeyPath": "C:/path/to/developer_key.der",
  "sdkBinPath": "C:/path/to/ConnectIQ/Sdk/bin"
}

The PowerShell build and deploy scripts read this file and inject the backend URL into a temporary build copy of gremotex/source/Config.mc. The same local file can also hold your untracked developerKeyPath and sdkBinPath values for build and simulator workflows. If you run monkeyc directly against monkey.jungle, this local override is not applied.

Build and run

Build the watch app:

.\gremotex\build-watch.ps1 -ProjectRoot .\gremotex

Run in simulator:

.\gremotex\run-simulator.ps1 -ProjectRoot .\gremotex -BuildFirst -StartSimulator

Deploy to a connected watch:

.\gremotex\deploy-watch.ps1 -ProjectRoot .\gremotex

You can also keep using the existing VS Code tasks for build, simulator, and deploy workflows.

Schema and extensibility

  • phpbackend/config/data.json defines screens, components, actions, and providers.
  • phpbackend/screen-modules/ contains shared PHP handlers used by screens and providers.
  • Tuya integration is supported through provider-backed screen modules and settings in phpbackend/config/settings.php.

See phpbackend/SCHEMA-V1.md for the schema contract and provider model.

About

GRemoteX is a schema-driven remote control system for Garmin watches. It pairs a Connect IQ watch app with a PHP backend that renders screens, executes actions, and manages per-device bearer tokens.

Topics

Resources

License

Stars

Watchers

Forks

Contributors