Update configuration and enhance railway signal functionality

- Adjust angle parameters for switches in config.json
- Implement semaphore loading in main.py
- Refactor Lamp modes to use integers in railway_signal.py
- Add set_mode method for Lamp class to control lamp states
This commit is contained in:
Artem Kashaev
2026-01-27 15:17:56 +05:00
parent 5ae313defd
commit 30feef708c
3 changed files with 81 additions and 13 deletions
+18 -4
View File
@@ -4,25 +4,25 @@
"id": 1283,
"pin": 12,
"angle_minus": 115,
"angle_plus": 65
"angle_plus": 70
},
{
"id": 1272,
"pin": 13,
"angle_minus": 115,
"angle_minus": 110,
"angle_plus": 65
},
{
"id": 1444,
"pin": 2,
"angle_minus": 115,
"angle_minus": 110,
"angle_plus": 65
},
{
"id": 1274,
"pin": 3,
"angle_minus": 115,
"angle_plus": 65
"angle_plus": 70
},
{
"id": 1457,
@@ -64,5 +64,19 @@
"id": 7007,
"pin": 26
}
],
"semaphores": [
{
"id": 1,
"pin": 15,
"bpp": 4,
"lamps": [
{"color": "MOON_WHITE", "id": 1630},
{"color": "YELLOW", "id": 1631},
{"color": "RED", "id": 1632},
{"color": "GREEN", "id": 1633},
{"color": "BLUE", "id": 1634}
]
}
]
}
+54 -4
View File
@@ -5,11 +5,14 @@ from machine import Pin
from time import sleep_ms, ticks_diff, ticks_ms
from ir_pair import IRRxTxPollPair
from double_ir import DoubleIr
from railway_signal import RailwaySignal, Lamp
SEMINSU_V1 = dict()
SEMINSU_V2 = dict()
SWITCHES = dict()
SEMINSU_V1: dict[int, IRRxTxPollPair] = dict()
SEMINSU_V2: dict[int, DoubleIr] = dict()
SWITCHES: dict[int, Switch] = dict()
LAMPS: dict[int, Lamp] = dict()
_SEMAPHORES: dict[int, RailwaySignal] = dict()
LED = Pin("LED", Pin.OUT) # "LED" — специальное имя для встроенного индикатора
@@ -18,7 +21,7 @@ def load_switches():
import json
config = json.load(file)
for sw_cfg in config["switches"]:
for sw_cfg in config.get("switches", []):
sw = Switch(
id=sw_cfg["id"],
pin=sw_cfg["pin"],
@@ -65,6 +68,33 @@ def load_seminsus_v2():
SEMINSU_V2[sem_cfg["id"]] = seminsu
def load_semaphores():
with open("config.json", "r") as file:
import json
config = json.load(file)
for sem in config.get("semaphores", []):
sem_id = sem.get("id")
pin = sem.get("pin")
bpp = sem.get("bpp", 4)
lamps = sem.get("lamps", [])
if sem_id is None or pin is None:
continue
signal = RailwaySignal(pin=int(pin), num_leds=len(lamps), bpp=int(bpp), timing=1)
_SEMAPHORES[int(sem_id)] = signal
for pxl_ind, lamp_cfg in enumerate(lamps):
lamp_id = lamp_cfg.get("id")
color = lamp_cfg.get("color", "OFF")
if lamp_id is None:
continue
lamp = signal.add_lamp(int(lamp_id), pxl_ind, str(color))
LAMPS[int(lamp_id)] = lamp
def resolve_command(command: str):
parts = command.split()
if len(parts) == 4 and parts[0] == "SWITCH" and parts[2] == "TURN":
@@ -96,8 +126,27 @@ def resolve_command(command: str):
evts.append(f"EVENT IK_MODULE {id} {seminsu.last_state}")
for id, seminsu in SEMINSU_V2.items():
evts.append(f"EVENT IK_MODULE {id} {seminsu.last_state}")
for id, lamp in LAMPS.items():
evts.append(f"EVENT LAMP {id} {lamp.mode}")
return "\n".join(evts)
elif len(parts) == 4 and parts[0] == "LAMP" and parts[2] == "SET":
try:
lamp_id = int(parts[1])
except ValueError:
return "ERROR Invalid lamp ID"
if parts[3].isdigit():
mode = int(parts[3])
else:
return "ERROR Invalid mode"
if lamp_id not in LAMPS:
return f"ERROR Lamp {lamp_id} not found"
lamp = LAMPS[lamp_id]
lamp.set_mode(mode)
return f"EVENT LAMP {lamp_id} {mode}"
_seminsu_ids = []
_seminsu_idx = 0
@@ -225,4 +274,5 @@ if __name__ == "__main__":
load_switches()
load_seminsus_v1()
load_seminsus_v2()
load_semaphores()
work()
+9 -5
View File
@@ -28,11 +28,12 @@ class Lamp:
- blink: мигает (переключение ON/OFF с периодом period_ms)
"""
MODE_OFF = "off"
MODE_ON = "on"
MODE_BLINK = "blink"
ERROR = 1
MODE_OFF = 2
MODE_ON = 3
MODE_BLINK = 4
def __init__(self, signal, lamp_id: int, pixel_index: int, rgba):
def __init__(self, signal: "RailwaySignal", lamp_id: int, pixel_index: int, rgba):
self._signal = signal
self.id = lamp_id
self.pixel = pixel_index
@@ -52,6 +53,9 @@ class Lamp:
def blink(self, period_ms: int = 500):
self._signal._set_lamp_mode(self, Lamp.MODE_BLINK, period_ms=period_ms)
def set_mode(self, mode: int, *, period_ms: int = 500):
self._signal._set_lamp_mode(self, mode, period_ms=period_ms)
class RailwaySignal:
"""Контейнер ламп светофора.
@@ -264,7 +268,7 @@ class RailwaySignal:
return True
return False
def _set_lamp_mode(self, lamp: Lamp, mode: str, *, period_ms: int = 500):
def _set_lamp_mode(self, lamp: Lamp, mode: int, *, period_ms: int = 500):
if mode == Lamp.MODE_BLINK:
lamp.mode = Lamp.MODE_BLINK
lamp._blink_period_ms = int(period_ms)