This project syncs real-time Amber Electric import/export prices into your Sigen Energy Controller.
It can run every 5 or 30 minutes via systemd timer to keep your Sigen tariffs up to date.
- Pulls Amber API 5-minute or 30-minute prices (
perKwhfor buy,spotPerKwhfor sell). - Supports
--advanced-price {low,predicted,high}for Amber’sadvancedPrice. - Seeds the current active slot from Amber’s
/prices/current(optional, enabled by default). - Authenticates to Sigen Cloud with either:
SIGEN_USER,SIGEN_PASS,SIGEN_DEVICE_ID(recommended - plain password, auto-encoded), orSIGEN_USER,SIGEN_PASS_ENC,SIGEN_DEVICE_ID(advanced - pre-encoded password), orSIGEN_BEARER(manual bearer token).
- Dry-run mode prints JSON payload without posting to Sigen.
- Works with both
--interval 5and--interval 30.- Note: Sigen only supports
--interval 30right now, setting to 5 will break writing to Sigen.
- Note: Sigen only supports
- Supports 30 minute billing for Amber customers (Eg, Victoria?)
- Use
--no-use-currentorUSE_CURRENT=FalseENV Flag - to force 30 minute Amber billing data (aka "Current Active Slot")
- Use
Choose one of the following installation methods:
- Docker (Recommended) - Easiest setup, automatic restarts
- Manual/systemd - Traditional Linux service installation
- Docker and Docker Compose installed
- Amber API token from https://app.amber.com.au/developers
- Sigen credentials (see Sigen Authentication)
-
Clone the repository
git clone https://github.com/bolagnaise/amber2sigen.git cd amber2sigen -
Configure environment
Copy the example env file and edit with your credentials:
cp amber2sigen.env.example amber2sigen.env nano amber2sigen.env
AMBER_TOKEN=psk_xxxxxxxxxxxxxxxxxxxx SIGEN_USER=your@email.com SIGEN_DEVICE_ID=1756353655250 SIGEN_PASS=YourSigenPassword # Optional tuning INTERVAL=30 TZ_OVERRIDE=Australia/Adelaide ALIGN=end PLAN_NAME=Amber Live ADVANCED=predicted USE_CURRENT=1 STATION_ID=<Your Station ID>
-
Start the container
docker compose up -d
-
View logs
docker compose logs -f
# Start
docker compose up -d
# Stop
docker compose down
# Restart
docker compose restart
# View logs
docker compose logs -f amber2sigen
# Rebuild after updates
docker compose build --no-cache
docker compose up -d- Python 3.9+
requests,pycryptodome,python-dateutil
Install:
pip install -r requirements.txtFor security, run this under a dedicated system user:
sudo useradd --system --home /opt/amber2sigen --shell /usr/sbin/nologin amber2sigen
sudo mkdir -p /opt/amber2sigen
sudo chown amber2sigen:amber2sigen /opt/amber2sigenClone or copy this repo into /opt/amber2sigen.
Ensure the python script and run.sh files are also owned by amber2sigen:amber2sigen
Run the helper to create your env file:
cd /opt/amber2sigen
python3 sigen_make_env.pyYou will be prompted for:
- Amber API token (
AMBER_TOKEN) - Sigen username (
SIGEN_USER) (See Below) - Sigen encoded password (
SIGEN_PASS_ENC) (See below) - Sigen device ID (
SIGEN_DEVICE_ID) (See below)
Then move the generated env file to /etc:
sudo mv amber2sigen.env /etc/amber2sigen.env
sudo chown root:root /etc/amber2sigen.env
sudo chmod 600 /etc/amber2sigen.envYou have two options for authenticating with Sigen:
Simply use your Sigen account password directly:
SIGEN_USER=your@email.com
SIGEN_PASS=YourSigenPassword
SIGEN_DEVICE_ID=1756353655250The password will be automatically encoded using Sigenergy's AES-128-CBC encryption before being sent to the API.
If you already have an encoded password from browser dev tools, you can use it directly:
SIGEN_USER=your@email.com
SIGEN_PASS_ENC=aZ9ejFf8Ya3lUFlQL9sprw==
SIGEN_DEVICE_ID=1756353655250The SIGEN_DEVICE_ID is a 13-digit identifier that you need to capture from browser dev tools:
-
Open the Sigen web portal in your browser (https://app-aus.sigencloud.com/)
-
Open Developer Tools → Network tab.
-
Log in normally.
-
Look for a request to:
https://api-aus.sigencloud.com/auth/oauth/token -
In the request payload you will see:
userDeviceId→ this is the device ID (copy intoSIGEN_DEVICE_ID).
Copy this value exactly into your configuration.
The STATION_ID is a unique numeric ID assigned to your Sigen Energy Controller by Sigen Cloud.
It must be included in the payload or Sigen won’t know which unit to update.
Easiest way to find it:
- Ask SigenAI to "Tell me my StationID"
Complex Ways to find it:
- HAR capture: In your browser, open the Sigen web portal, perform a tariff save, then export the HAR.
Look for"stationId": <your station ID>in the JSON payload. - App/device info: Sometimes shown in the app under device details.
- Once known, add it to your
.envfile asSTATION_ID=....
This value is specific to your unit — not random or generated locally.
AMBER_TOKEN=psk_xxxxxxxxxxxxxxxxxxxx
SIGEN_USER=your@email.com
SIGEN_DEVICE_ID=1756353655250
SIGEN_PASS=YourSigenPassword
# Optional tuning
INTERVAL=30
TZ_OVERRIDE=Australia/Adelaide
ALIGN=end
PLAN_NAME=Amber Live
ADVANCED=predicted
USE_CURRENT=True
STATION_ID=<Ask SigenAI for your Station ID>
PAYLOAD_DEBUG=1cd /opt/amber2sigen
sudo -u amber2sigen bash run.sh --dry-run
sudo -u amber2sigen bash run.sh/etc/systemd/system/amber2sigen.service
[Unit]
Description=Amber -> Sigen price sync
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
Environment=PYTHONUNBUFFERED=1
EnvironmentFile=/etc/amber2sigen.env
WorkingDirectory=/opt/amber2sigen
ExecStart=/bin/bash /opt/amber2sigen/run.sh
User=amber2sigen
Group=amber2sigen/etc/systemd/system/amber2sigen.timer
[Unit]
Description=Run amber2sigen periodically at absolute 5-min marks +20s
Wants=amber2sigen.service
[Timer]
OnBootSec=2min
OnCalendar=*:0/5:20
Unit=amber2sigen.service
Persistent=true
AccuracySec=1s
[Install]
WantedBy=timers.targetEnable:
sudo systemctl daemon-reexec
sudo systemctl enable --now amber2sigen.timer-
Check last run:
journalctl -u amber2sigen.service -n 200 --no-pager
-
Follow logs:
journalctl -u amber2sigen.service -f
-
Verify timer:
systemctl list-timers | grep amber2sigen -
Watch Timer:
watch -n 10 "systemctl list-timers | grep amber2sigen"
| Flag | Type / Values | Default | Purpose |
|---|---|---|---|
--amber-token |
String | from env AMBER_TOKEN |
Amber API token used to authenticate and fetch prices. |
--site-id |
String | auto-detected | Amber site ID. If omitted, first active site is used. |
--tz |
Timezone string | Australia/Adelaide |
Time zone for converting and labeling price slots. |
--interval |
5 or 30 |
from env INTERVAL (default 30) |
Slot size in minutes; determines whether 5-minute or 30-minute Amber prices are used. |
--align |
start / end |
end |
Whether to align Amber rows to slot start or end. Amber app convention is end. |
--slot-shift |
Integer | 0 |
Rotate/shift the entire BUY/SELL series by N slots. Positive = later, negative = earlier. |
--advanced-price |
low / predicted / high |
none | Use Amber’s advancedPrice.<field> for BUY price instead of perKwh. |
--use-current |
Flag (on/off) | true (unless USE_CURRENT=False) |
Enable fetching /prices/current to override the current slot with the latest interval. |
--no-use-current |
Flag (on/off) | — | Explicitly disable /prices/current override. |
--station-id |
Integer | Required | The numeric stationId for your Sigen Energy Controller. |
--plan-name |
String | "SAPN TOU" |
Label to use for the tariff plan in the payload sent to Sigen. |
--sigen-url |
URL | SIGEN_SAVE_URL or default Sigen API URL |
Endpoint to POST prices into Sigen Cloud. |
--sigen-user |
String | from env SIGEN_USER |
Sigen account username (email). Used for authentication. |
--device-id |
String | from env SIGEN_DEVICE_ID or "1756353655250" |
Sigen userDeviceId. Required for password-grant authentication. |
--dry-run |
Flag | off | Print JSON payload instead of POSTing to Sigen. Useful for testing. |
--allow-zero-buy |
Flag | off | Allow posting to Sigen even if final BUY prices include 0.0. By default, posting is skipped if zeros are detected. |
- Environment variables (
AMBER_TOKEN,INTERVAL,SIGEN_*, etc.) can be set in/etc/amber2sigen.envinstead of CLI flags. - By default, if BUY prices contain
0.0the script will not POST unless--allow-zero-buyis specified. /prices/currentoverride improves accuracy by seeding with the current active slot. Disable with--no-use-current.
| Flag | Type / Values | Default | Purpose |
|---|---|---|---|
--user |
String | Required | Sigen account email/username. |
--password |
String | Required | (Old behavior) Plaintext Sigen password to be AES-encoded. |
--device-id |
String (13-digit) | Randomly generated if omitted | Sigen userDeviceId. If not supplied, a random 13-digit ID is generated. |
--env-path |
Path | amber2sigen.env |
Output path for the generated environment file. |
--overwrite |
Flag | off | Allow overwriting an existing env file. |
--interval |
5 or 30 |
30 |
Default Amber interval in minutes. |
--tz |
Timezone string | Australia/Adelaide |
Default time zone override. |
--align |
start / end |
end |
Default slot alignment label. |
--plan-name |
String | Amber Live |
Default plan name label. |
--advanced |
low / predicted / high |
predicted |
Default advanced price field to use for BUY. |
--use-current |
0 or 1 |
1 |
Whether to use Amber’s /prices/current endpoint for active slot seeding. |
- The script writes a clean
.envfile with the variables needed byamber_to_sigen.pyandrun.sh. - In the newer workflow,
--passwordencoding must be bypassed (not used) and replaced with manual entry ofSIGEN_PASS_ENCfrom browser dev tools.