Skip to content

Update README.md

Update README.md #96

name: Altair v8 checks
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
verify:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: '22'
- name: Validate JavaScript and package version
shell: bash
run: |
node --check js/parser.js
node --check js/app.js
node --check js/charts.js
node --check js/v8.js
node --check js/v8-final.js
node --check js/help.js
node --check js/flasher-v5.js
node --check js/serial.js
node --check js/ui.js
node --check js/rotator.js
node --check desktop/main.cjs
node - <<'NODE'
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
if (pkg.version !== '0.8.1') throw new Error(`Expected 0.8.1, got ${pkg.version}`);
if (pkg.build?.win?.icon !== 'assets/altair-logo.png') throw new Error('Altair Windows PNG icon source is not configured');
if (pkg.author !== 'Антон Т.') throw new Error('Application author metadata is missing');
const parser = fs.readFileSync('js/parser.js', 'utf8');
if (!parser.includes('checksumValidation: false')) {
throw new Error('Application checksum validation must be disabled in v8 parser');
}
const app = fs.readFileSync('js/app.js', 'utf8');
if (!app.includes('version: "0.8.1"')) throw new Error('app.js must identify v0.8.1');
if (app.includes('applyV6BrandingAndRadioProfile')) throw new Error('Legacy v6 runtime override is still present');
if (!app.includes('"VOLT", "TEMP", "MODE"')) throw new Error('MCU temperature must follow battery voltage in UI telemetry order');
const index = fs.readFileSync('index.html', 'utf8');
if (!index.includes('<script src="js/v8.js?v=20260902-1"></script>')) throw new Error('Current v8.js revision is not connected in index.html');
if (!index.includes('<script src="js/v8-final.js?v=20260902-1"></script>')) throw new Error('Current v8-final.js revision is not connected in index.html');
if (!index.includes('Температура бортового компьютера')) throw new Error('MCU temperature card is missing');
if (!index.includes('Команды, передаваемые на спутник')) throw new Error('Uplink panel purpose is unclear');
const v8Runtime = fs.readFileSync('js/v8.js', 'utf8');
if (!v8Runtime.includes('control.disabled = !connected')) throw new Error('Visible command controls are not synchronized with serial state');
if (!v8Runtime.includes('oldCustomInput?.cloneNode(true)')) throw new Error('Legacy custom-command handler is still active');
if (!v8Runtime.includes('$CMD,RADIO,SET,FREQ=')) throw new Error('Runtime radio settings command is missing');
if (!v8Runtime.includes('$CMD,RADIO,RESET')) throw new Error('Radio settings reset command is missing');
if (!v8Runtime.includes('id="v8RadioFrequency"')) throw new Error('Radio settings controls are missing');
if (!v8Runtime.includes('id="v8UplinkValue"') || !v8Runtime.includes('id="v8DownlinkValue"')) {
throw new Error('Separate uplink/downlink indicators are missing');
}
if (!v8Runtime.includes('Контрольная сумма (CRC)')) throw new Error('CRC card label is incorrect');
const charts = fs.readFileSync('js/charts.js', 'utf8');
if (!charts.includes('datasetFor(chart, id)')) throw new Error('Multi-ID chart datasets are missing');
if (!charts.includes('pointRadius: 2.7')) throw new Error('Visible chart points are missing');
if (!charts.includes('TEMP: { title: "Температура бортового компьютера"')) throw new Error('MCU temperature chart is not connected');
const finalRuntime = fs.readFileSync('js/v8-final.js', 'utf8');
if (!finalRuntime.includes('bandwidth: "203"')) throw new Error('v8 UI must enforce RX BW 203 kHz');
console.log('Altair v8 JS/package checks OK');
NODE
- name: Validate v8 radio profile and release files
shell: bash
run: |
ground_esp32='firmware/ground_station/esp32/Altair_Ground_ESP32/Altair_Ground_ESP32.ino'
grep -Fq 'RF_FREQ_MHZ = 435.000f' "$ground_esp32"
grep -Fq 'RF_BW_KHZ = 203.0f' "$ground_esp32"
grep -Fq 'APPLICATION_XOR_CHECK=DISABLED' "$ground_esp32"
grep -Fq '$CMD,RF,' "$ground_esp32"
grep -Fq '$CMD,RADIO_STATUS' "$ground_esp32"
grep -Fq 'FW_VERSION[] = "8.3.1"' "$ground_esp32"
grep -Fq 'radio.setPacketReceivedAction(onRfPacketReceived);' "$ground_esp32"
grep -Fq 'const int state = radio.readData(packet);' "$ground_esp32"
grep -Fq '$CMD,RADIO,SET,' "$ground_esp32"
grep -Fq '$CMD,RADIO,RESET' "$ground_esp32"
grep -Fq 'RADIO_CONFIG_APPLIED' "$ground_esp32"
grep -Fq 'Serial.print(",MCU_TEMP=");' "$ground_esp32"
if grep -Fq 'const int state = radio.receive(packet);' "$ground_esp32"; then
echo 'Blocking CC1101 receive must not be used in the ESP32 gateway'
exit 1
fi
grep -Fq 'src_dir = Altair_Ground_ESP32' firmware/ground_station/esp32/platformio.ini
test -f firmware/ground_station/arduino_uno/Altair_Ground_Arduino_Uno/Altair_Ground_Arduino_Uno.ino
test -f firmware/ground_station/arduino_nano/Altair_Ground_Arduino_Nano/Altair_Ground_Arduino_Nano.ino
test -f firmware/satellite/stm32/Altair_Satellite_STM32/Altair_Satellite_STM32.ino
test -f firmware/satellite/arduino_nano/Altair_Satellite_Arduino_Nano/Altair_Satellite_Arduino_Nano.ino
step_01='firmware/satellite/01_static_telemetry_tx/Altair_Satellite_01_Static_Telemetry_TX/Altair_Satellite_01_Static_Telemetry_TX.ino'
grep -Fq 'static const char TELEMETRY_PACKET[] = "02,00001,00015,1.00,4.20,31.6,1,07";' "$step_01"
grep -Fq 'radio.transmit(TELEMETRY_PACKET)' "$step_01"
if grep -Eq 'startReceive|radio\.receive|radio\.readData' "$step_01"; then
echo 'Step 01 must remain transmit-only'
exit 1
fi
step_02='firmware/satellite/02_packet_counter_tx/Altair_Satellite_02_Packet_Counter_TX/Altair_Satellite_02_Packet_Counter_TX.ino'
grep -Fq 'uint32_t packetNumber = 1;' "$step_02"
grep -Fq 'packetNumber + 1' "$step_02"
grep -Fq 'calculateXorChecksum(packetBody)' "$step_02"
grep -Fq 'radio.transmit(telemetryPacket)' "$step_02"
if grep -Eq 'startReceive|radio\.receive|radio\.readData' "$step_02"; then
echo 'Step 02 must remain transmit-only'
exit 1
fi
step_03='firmware/satellite/03_uptime_tx/Altair_Satellite_03_Uptime_TX/Altair_Satellite_03_Uptime_TX.ino'
grep -Fq 'uint32_t getUptimeSeconds()' "$step_03"
grep -Fq 'millis() / 1000UL' "$step_03"
grep -Fq '"02,%05lu,%05lu,1.00,4.20,31.6,1,"' "$step_03"
grep -Fq 'radio.transmit(telemetryPacket)' "$step_03"
if grep -Eq 'startReceive|radio\.receive|radio\.readData' "$step_03"; then
echo 'Step 03 must remain transmit-only'
exit 1
fi
step_04='firmware/satellite/04_mcu_temperature_tx/Altair_Satellite_04_MCU_Temperature_TX/Altair_Satellite_04_MCU_Temperature_TX.ino'
grep -Fq 'float readMcuTemperatureC()' "$step_04"
grep -Fq 'readInternalTemperatureAdc()' "$step_04"
grep -Fq 'dtostrf(temperatureC, 0, 1, temperatureText)' "$step_04"
grep -Fq '"02,%05lu,%05lu,1.00,4.20,%s,1,"' "$step_04"
grep -Fq 'radio.transmit(telemetryPacket)' "$step_04"
if grep -Eq 'startReceive|radio\.receive|radio\.readData' "$step_04"; then
echo 'Step 04 must remain transmit-only'
exit 1
fi
static_nano='firmware/satellite/arduino_nano_static_tx/Altair_Satellite_Arduino_Nano_Static_TX/Altair_Satellite_Arduino_Nano_Static_TX.ino'
grep -Fq '1.00,4.20,' "$static_nano"
grep -Fq 'readMcuTemperatureC()' "$static_nano"
grep -Fq 'calculateXorChecksum' "$static_nano"
grep -Fq '435.000' js/v8.js
grep -Fq 'rawSerialConsole' js/v8.js
grep -Fq 'Сбросить принятые данные' js/v8.js
test -f docs/CUP_Altair_v8_Manual.tex
test -f docs/RELEASE_V8.md
test -f docs/media/mcc-technoprom.jpg
test -f docs/media/cubesat-technoprom.jpg
test -f assets/altair-logo.png