SimItNow's simulated charging stations connect out to whichever CSMS WebSocket URL you configure, exactly like a real charger would. That works without any extra setup once your CSMS is deployed somewhere public. During local development it doesn't: a CSMS listening on localhost:9000 is reachable from your own machine, but SimItNow's servers have no route to it. You need a tunnel that gives your local CSMS a public URL for the duration of your test session.
Why this is needed at all
The connection runs in one direction: SimItNow (cloud) → wss://your-csms-url. Whatever you put on the right-hand side has to be resolvable and reachable from the public internet. A tunnel tool solves this by opening an outbound connection from your machine to a relay service, then handing you back a public hostname that forwards traffic through that tunnel to your local port. Your CSMS code doesn't change at all. It keeps listening on localhost exactly as before.
One detail matters more here than for a typical HTTP tunnel demo. OCPP runs over WebSocket rather than plain HTTP, so the tunnel has to keep a long-lived, bidirectional connection open instead of proxying a single request and response. Both tools below handle this correctly, but it is worth confirming if you reach for a different tunnel product later.
Option A: ngrok
ngrok is the fastest way to get a throwaway public URL. After creating a free account and running ngrok config add-authtoken <token> once, expose your local CSMS with:
ngrok http <port>
ngrok prints a public HTTPS URL. Since OCPP needs WebSocket, swap the scheme: an ngrok URL like https://a1b2c3.ngrok-free.app becomes wss://a1b2c3.ngrok-free.app when you hand it to SimItNow. ngrok upgrades the connection transparently either way.
The free tier has one real limitation for repeated testing. The subdomain is random and changes every time you restart ngrok http, so if you stop and re-run it between test sessions, you'll need to update the CSMS URL on your SimItNow station again.
Option B: Cloudflare Tunnel
Cloudflare Tunnel (via the cloudflared CLI) is free with no rate limits, and unlike ngrok's free tier it gives you a persistent subdomain across restarts once configured. That makes it a better fit if you're doing this more than once. A quick tunnel, with no account needed:
cloudflared tunnel --url http://localhost:<port>
This prints a trycloudflare.com URL for the session, still ephemeral, much like ngrok's quick mode. For a subdomain that survives restarts, authenticate with cloudflared tunnel login and create a named tunnel tied to a domain you control. The setup is a bit more involved, but you stop having to update your SimItNow station's CSMS URL between sessions. The same rule applies: use the wss:// form of whatever hostname it gives you.
Pointing SimItNow at the tunnel
- Create a free SimItNow account and grab your API key.
- Start your CSMS locally and confirm it's listening on the port you intend to tunnel.
- Start the tunnel (ngrok or cloudflared) and copy the public hostname it gives you.
- Create a charging station via the SimItNow API (or dashboard), setting csmsUrl to the wss:// form of that hostname plus whatever path your CSMS expects.
- Watch your CSMS's own logs for the incoming BootNotification, which confirms the tunnel is passing the WebSocket upgrade correctly.
See the API docs for the exact csmsUrl field format, including the chargebox-id path convention SimItNow appends automatically.
Which one should you use?
If you need something quickly and only once, use ngrok. It takes one command with no prior config, and the random subdomain doesn't matter when you're not going to restart it mid-session.
For a recurring local dev workflow, or CI-adjacent scripting where the URL has to stay stable, use Cloudflare Tunnel. The persistent subdomain means you configure your SimItNow station's csmsUrl once and it keeps working across restarts.
Get your free API key and connect SimItNow to your local CSMS in the next few minutes.