Compost study · run guide

Running a composter in the study

From a fresh laptop to a machine running the study, then the daily routine, then training. It works for any machine and any laptop. Do the steps in order. Every command is for PowerShell on Windows, run from the RND_AI_DynamicAlgo folder unless the step says otherwise.

Decisions
every 4 h, per chamber
Readings
every 42 s
Actions in use
A1 and A3 (of A0–A4)
Policy now
random, 50 % each

In the commands, replace <PORT> with your machine's port and <SERIAL> with its serial number. Step 2 and step 3 show you both. <NUM> is the last three digits of the serial, for example 312 for LL01-00000000312.

Before Phase A

A new laptop or a new machine

Commands are for PowerShell: the prompt starts with PS. If it does not (Command Prompt), type powershell and press Enter first. Run them from the RND_AI_DynamicAlgo folder unless a step says otherwise.

  1. i

    Get the code from GitHub once per laptop

    Can skipif this laptop already has the RND_AI_DynamicAlgo folder with a hidden .git folder inside.

    The repository is private: sign in with a GitHub account that is a member of virgohomeio. Use one of the two ways.

    With Git in PowerShell. Install Git once, then close PowerShell and open a new one:

    winget install --id Git.Git -e --source winget

    Go to the folder that should hold the project (for example C:\Vcycene) and copy it down. A GitHub sign-in window opens the first time.

    git clone https://github.com/virgohomeio/RND_AI_DynamicAlgo.git
    cd RND_AI_DynamicAlgo

    With GitHub Desktop (no commands): install it from desktop.github.com, sign in, then File → Clone repository → URL → https://github.com/virgohomeio/RND_AI_DynamicAlgo → Clone.

    Getting updates later: git pull in PowerShell, or Fetch origin → Pull origin in GitHub Desktop. If neither works, download the ZIP from the repository page (Code → Download ZIP), extract it, and copy its RL and docs folders over this laptop's, choosing Replace. Your machine_<NUM>.yaml, the unlock and the keys are not in the download, so they stay.

  2. ii

    The settings file: what it must say

    Each machine has its own settings file on each laptop: RL\harness\config\machine_<NUM>.yaml, named after the last three digits of its serial, so machine_312.yaml for LL01-00000000312 (step 4 makes it). It never goes to GitHub, so a pull never brings these settings: check them by hand on every laptop. Open the file in Notepad and make these lines read as below. Lines under transport: and firmware: keep their two spaces in front; every other line has none. If a line is missing, add it at the end of the file.

    serial: <SERIAL>
    transport:
      uart: {port: <PORT>, baud: 115200, timeout_s: 0.5}
    gas_saturation_ohm: 102400000
    ptc_guard_c: {off_at: 58, on_below: 51, alarm_at: 75}
    firmware:
      stop_process_on_start: false
      start_process_on_exit: false
    stage: 1
    policy: {kind: random}
    scores_drive_decisions: false
    firmware_modes_only: true

    Replace <SERIAL> with the machine's serial (step 3) and <PORT> with this laptop's port for it (step 2).

    LineWhat it isChanges when
    serial:the machine this laptop drives (step 3 reads it)new machine
    port: inside uart:where the USB cable shows up on this laptop (step 2 finds it)new laptop, or a new machine or cable
    stop_process_on_start, start_process_on_exitfalse: these machines take commands directly and refuse the hand-overnever, for now
    firmware_modes_onlytrue: decisions use only A1 light and A3 heavyonly when the study says so
    scores_drive_decisionsfalse: scores are recorded, not used to steeronly when the study says so
    gas_saturation_ohm, ptc_guard_c, stage, policythe study's current valuesonly when the study says so

    Every laptop driving the study must have the same values, apart from serial and port, so the study runs the same whichever laptop is plugged in.

  3. iii

    What to do for a new laptop, and for a new machine

    Do
    New laptopi (get the code), step 1 (packages), step 2 (port), step 4 with the lines in ii, step 5 (unlock), step 6 (keys), step 7 (tests), then step 8 (machine check)
    New machine on a laptop already set upstep 2 (its port), step 3 (its serial), copy an existing machine_<NUM>.yaml to the new machine's name (step 4), change its serial and port, then step 8 (machine check)
    Two or more machines on one laptopEach machine runs in its own windows with its own file: one harness and one safety guard per machine (steps 10 and 11 with that machine's machine_<NUM>.yaml). The commands are the same for every machine; only the file name changes. Each harness's small local page takes the next free port by itself (8443, then 8444, …)
    Same machine, other laptopstop the harness and the safety guard on the first laptop, move the USB cable, then step 8 on the second. The run picks up where it was

    A machine appears on Compost Control (Insights, Quick score, Full check) by itself once it has sent any data, on any device.

Phase A

Set up the laptop and the machine

  1. 1

    Install the Python packages once per laptop

    Can skipif this laptop already has them installed.

    pip install -r requirements-bench.txt
    pip install -r RL\requirements.txt

    Python 3.11 or newer.

  2. 2

    Find the machine's port

    Can skipif you already know the port from an earlier run on this laptop.

    Run this once with the machine unplugged and once with it plugged in by USB. The port that appears the second time is the machine, for example COM5.

    python -m serial.tools.list_ports -v

    Only one program can use the port at a time, so close any other script first.

  3. 3

    Read the sensors for two minutes

    Can skipif this machine was checked before and you already have its serial.

    python read_sensors.py --port <PORT> --seconds 120 --no-upload
    • The first line shows the machine's serial number. You need it in step 4.
    • This only reads, and --no-upload keeps the test out of the study data.
    • Temperatures and humidity should look sensible.
  4. 4

    Create this laptop's settings file once per laptop

    Can skipif RL\harness\config\machine_<NUM>.yaml already exists on this laptop for this machine.

    Each machine gets its own file on this laptop, named after the last three digits of its serial. It is never shared through GitHub, because it holds this laptop's port. Start from the shared template, or copy another machine's file and change its serial and port:

    Copy-Item RL\harness\config\machine.example.yaml RL\harness\config\machine_<NUM>.yaml

    Open RL\harness\config\machine_<NUM>.yaml in Notepad and set the lines shown in ii at the top of this guide: serial from step 3, port from step 2, and the study values exactly as shown.

    • Leave seed and decision_times_local as they are, so a run can move between laptops without breaking its cycle.
    • The harness checks the serial against the machine at start and refuses to run if they differ.
  5. 5

    Allow this laptop to control a machine once per laptop

    Can skipif this laptop is already allowed, or if it will only log (read-only runs).

    As it comes from GitHub, the harness only reads a machine and refuses to drive it. Each laptop that will run the study switches this on for itself. Open RL\harness\config\actions.yaml and change the line

    placeholders_confirmed: false

    to

    placeholders_confirmed: true
    • Never commit or push this change. The copy on GitHub stays locked on purpose; each laptop unlocks its own.
    • If you see "placeholders are not confirmed" when starting a run, this step was skipped.
  6. 6

    Create this laptop's own keys once per laptop

    Can skipif RL\harness\secrets\ already has api_token, harness_cert.pem and harness_key.pem.

    The harness serves a small page on the laptop and needs three key files for it. Do not copy them from another laptop: each laptop makes its own. Without them, the harness will not start.

    Run in RND_AI_DynamicAlgo\RL

    cd RL
    python -m harness.api.certs --out harness\secrets
    File in RL\harness\secretsNeeded?
    api_token, harness_cert.pem, harness_key.pemYes: made by the command above, on this laptop
    supabase_service_keyNo. It stays only on the first laptop. Without it, the harness uses the shared key from the repository, which can add and read rows: all a run needs

    The folder is never sent to GitHub: the command puts a "keep out of git" file inside it.

  7. 7

    Run the tests

    Run in RND_AI_DynamicAlgo\RL

    python -m pytest harness\tests -q

    Every test should pass. If any fails: stop and save the output.

Phase B

Load and start

  1. 8

    Check the machine

    Fit both chambers, empty, and close both lids. Then run the check. It confirms every sensor answers, every actuator responds under laptop control, and the data can be saved and uploaded.

    Run in RND_AI_DynamicAlgo\RL

    python -m harness.tools.machine_check --config harness\config\machine_<NUM>.yaml
    • The blower, intake fan, each pad heater, the PTC and each mixer run for a few seconds each. Stay beside the machine; the mixers turn.
    • Every line says PASS, WARN, FAIL or SKIP. It ends with READY or NOT READY.
    • Fix every FAIL before loading. WARN lines are worth a look but don't block a run.
    • The actuators are skipped while a lid is open.
    • A report is saved next to the machine's study files.
    FAIL lineWhat to do
    lid: front lid openClose the lid, then run the check again.
    chamber air (BME) answers with zerosThe chamber's air sensor is missing or not connected.
    firmware hands over: STOP_PROCESS refusedThe machine's firmware does not accept laptop control. It needs the PC-control firmware build.
    mixer: no motor currentThe mixer did not turn. Check its connector and the chamber seating.
    Supabase not reachableCheck the internet connection. A run still saves locally and uploads later.
  2. 9

    Fill both chambers and close both lids again

    Only the front lid has a switch. The mixers never run while it reads open.

  3. 10

    Start a read-only run for about 5 minutes

    Run in RND_AI_DynamicAlgo\RL

    python -m harness.run --config harness\config\machine_<NUM>.yaml --read-only --verbose --hours 0.08
    • The harness reads and logs, and uploads the readings, but makes no decisions and sends nothing to the machine. The firmware keeps running it.
    • Open Insights and pick your machine, or add ?machine=<SERIAL> to the address. New readings should appear within a few minutes.
    • Decisions only appear at the 4-hourly times. You don't need to wait for one.
    • --verbose prints every reading to the screen; without it the terminal only shows events and looks idle while it logs.
    • --hours 0.08 stops it by itself after about 5 minutes. To stop earlier, press Ctrl+C once and wait.
  4. 11

    Start the real run

    Run in RND_AI_DynamicAlgo\RL

    python -m harness.run --config harness\config\machine_<NUM>.yaml --verbose

    For a run you will leave, also start the safety guard in a second terminal. It is a separate safety process: if the harness stops answering, it switches everything off and hands the machine back to its firmware. It reports to Supabase, so Insights (Health tab) shows from any device whether it is on, and when it stepped in.

    python -m harness.run --config harness\config\machine_<NUM>.yaml --watchdog
    • The harness pauses the firmware's program and runs the blower, heaters and mixers itself.
    • It picks one of A0 to A4 at random for each chamber at each 4-hourly decision.
    • Every row goes to the local CSV files and to Supabase.
Phase C

Every day while it runs

Your scores are the only thing the system learns from. A decision with no score in the 30 hours after it teaches nothing.

  1. 12

    Score each chamber at least twice a day

    For example once in the morning and once in the evening. Use whichever way suits the moment. All three save to the same place and count the same.

    WayUse it forWhat it records
    Quick scoreThe routine daily checkSqueeze, smell, or why it was missed, and a feed with an optional note
    Full checkA detailed check, or anything beyond a feedScore with a photo, feed, water added, unload, service done, plus the machine's status, recent events and latest scores. The Entries tab fixes or deletes a wrong entry; every add, edit and delete is kept in Supabase (entry_changes)
    Terminal questions (score.py)When you are at the laptop and don't want to open a browserAsks you questions in the PowerShell window, chamber L then R: scored or missed, squeeze 1 to 6, smell level 0 to 2, and if it smells, what kind and where. No photo and no feed. If the internet is down it keeps the score and sends it the next time you run it.
    python score.py --observer <YOUR NAME>
    SqueezeWhat you seeGrade
    1Crumbles, dry−1
    2Holds briefly, then crumbles−1
    3Holds its shape, no water+1
    4A few drops+1
    5Steady drips+1
    6Water runs, slurry−2
    any, sour smell in the materialGone wrong−2
  2. 13

    Check progress

    On the Progress tab of Insights: decisions and scores so far for each chamber, against the current stage targets.

Reference

The five actions

Every 4 hours each chamber gets one action. A1 and A3 are the firmware's own light and heavy modes; A0, A2 and A4 are built from them. The blower always runs at 30 % power, and mixing starts after 20.7 min of idle time in every action.

SettingA0 dormantA1 lightA2 middleA3 heavyA4 boost
SourceBuilt from lightFirmware light modeBuilt: halfwayFirmware heavy modeBuilt from heavy
Blower on / off47.5 s / 930 s47.5 s / 930 s47.5 s / 329 s47.5 s / 186 s47.5 s / 71 s
Air time4.9 %4.9 %12.6 %20.3 %40 %
Pad heatersoffto 70 °Cto 70 °Cto 70 °Cto 70 °C
Blower PTCoffoff 58, on below 51 °Coff 58, on below 51 °Coff 58, on below 51 °Coff 58, on below 51 °C
Mix phases12 s / 6 s12 s / 6 s18 s / 9 s24 s / 12 s24 s / 12 s
What it is forCuring chamber: air on, heat offLight householdBetween the two modesHeavy householdBig wet feed, or too wet

In use now: A1 and A3 only. firmware_modes_only: true in machine_<NUM>.yaml limits every decision to the two firmware modes, 50 % each, until further notice. A4 needs an odour smoke test of the enclosure before it is used.

Differences from the firmware: the PTC switches off at 58 °C (back on below 51, as in BUILD_PLAN) instead of 70, because it overshoots by about 12 °C and should peak near the firmware's 70 °C; heavy's mix phases are 24 s / 12 s where the firmware source uses 12 s / 6 s.

During a run

Checking a chamber

There is no pause button. Opening a lid is the pause: the run keeps logging and stays on its 4-hourly schedule.

  1. a

    Open the front lid

    The mixers stop at once and do not start while the lid is open. The blower and heaters keep their current setting.

  2. b

    Check and close

    Do the squeeze test and smell, then close the lid. Mixing resumes on its own. Each opening is logged as a lid event.

  3. c

    Enter the score

    On the Quick score or Full check page. The run picks it up from Supabase.

Good to knowWhy
Keep a check to a minute or twoA lid open for more than 60 s is half of how an unload is spotted. It only counts as an unload if the next mix also draws much less current, so a normal check will not trigger it.
Opening the lid is not a feedA feed is only inferred when the chamber's humidity jumps after the lid closes. Log real feeds on the page.
For maintenance, emptying or moving the machineStop the run with Ctrl+C once (see Stopping below), and start it again with the same command when you are done. It carries on the same cycle.
Do not unplug the USB cable to pauseThe safety guard would catch it and hand the machine back to its firmware, but it is an untidy stop.
Phase D

Stopping, and moving between laptops

The random cycle belongs to the machine, not to the laptop. Decisions fall on the same clock times everywhere, and each draw is fixed by the seed, the machine's serial, the chamber and the decision time. Any laptop with the same settings makes the same draw.

SituationWhat happens
You press Ctrl+C onceThe harness finishes the current step, sends what is left to Supabase, puts the machine in a safe state and hands it back to the firmware.
The laptop crashes or the harness diesThe safety guard notices the harness has stopped answering, sends the safe state and hands the machine back to the firmware.
Another laptop takes over the same machineFirst stop this laptop's harness (Ctrl+C) and its safety guard, and move the USB cable: only one laptop can drive a machine. Then do steps 1 to 7 there with the same serial, and step 11. It reads Supabase and carries on: the actions already chosen for the current 4-hour block stay, the sensor history and latest scores are reloaded, and the next decision is the one the old laptop would have made.
A laptop moves to a different machineUse that machine's own machine_<NUM>.yaml, or make one (step 4). Each machine keeps its own cycle under its own serial, so neither machine's cycle is disturbed.
You change machine_<NUM>.yaml during a runNo restart needed. The change applies at the next 4-hourly decision.

Only one laptop can drive a machine at a time. Stop the old one before starting the new one.

Phase E

Train and use the learned policy

When the Progress tab shows the stage targets reached.

  1. 14

    Train

    Run in RND_AI_DynamicAlgo\RL

    python -m Machine_Learning validate --since <STUDY START DATE>
    python -m Machine_Learning train --since <STUDY START DATE> --out runs\r1

    Training reads everything straight from Supabase, from every laptop and every web page, so no files need copying. --since leaves out the bench tests from before the study; add --serial to train on one machine. It writes runs\r1\policy_<version>.json only if a learned policy beats the firmware's own modes. If no file appears, keep collecting and train again later.

  2. 15

    Switch the machine to the learned policy

    In RL\harness\config\machine_<NUM>.yaml, replace the policy: line with:

    policy: {kind: loaded, path: runs/r1/policy_<version>.json, epsilon: 0.1}

    It applies at the next decision. One decision in ten stays random so the data keeps growing.

Optional

Weekly feed profile

A label for how each chamber was fed that week. The machine runs the same without it.

FieldSet byUsed for
Role: fed or curingAutomatic. A chamber is fed if a feed was logged in the last 24 hours, otherwise curing.Deciding which chamber sets the shared blower when the two chambers want different air.
Profile: heavy, light, switcher, holiday, binge or noneYou, once a week per chamber, with the command below.Never an input to any policy. Training uses it to compare policies week type by week type, and the matched comparison uses it to pick heavy or light mode.

Training needs it. Training only exports a learned policy if it holds up on each week type, and it can only check that on weeks that carry a profile. Weeks left as none are still used for learning but cannot count toward that check.

Run in RND_AI_DynamicAlgo, while the harness is running. Change chamber (L or R) and profile each time.

$t = (Get-Content RL\harness\secrets\api_token -Raw).Trim()
Invoke-RestMethod -Method Post -Uri https://localhost:8443/intervals -SkipCertificateCheck `
  -Headers @{Authorization = "Bearer $t"} -ContentType "application/json" `
  -Body '{"kind":"feed_week","chamber":"L","profile":"heavy","stage":1}'

This command has not been tried on a machine yet. If it answers with an error, keep the message.

If something goes wrong

Problems and fixes

You seeDo this
No new port appearsMachine off, unplugged or a bad cable. Try another cable.
"Access denied" on the portAnother program has it. Close other scripts and terminals.
"machine serial … does not match config"The serial in machine_<NUM>.yaml is for a different machine. Fix it from step 3.
"placeholders are not confirmed"Control is still locked on this laptop. See step 5.
"the firmware refused STOP_PROCESS"In this laptop's machine_<NUM>.yaml, under firmware:, set stop_process_on_start: false and start_process_on_exit: false (step 4).
"Access denied" on the port while another laptop ran the machineThe other laptop still holds the cable. Stop its harness and safety guard first.
A test failsDon't start. Save the output.
Nothing new on Insights after 5 minutesCheck the terminal for upload errors. Rows are still saved locally and sent later.
Mixers never runA lid reads open. Run the machine check (step 8).
Machine runs on its own after a stopExpected. The firmware takes over whenever the harness is not running.