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, "id": 1283,
"pin": 12, "pin": 12,
"angle_minus": 115, "angle_minus": 115,
"angle_plus": 65 "angle_plus": 70
}, },
{ {
"id": 1272, "id": 1272,
"pin": 13, "pin": 13,
"angle_minus": 115, "angle_minus": 110,
"angle_plus": 65 "angle_plus": 65
}, },
{ {
"id": 1444, "id": 1444,
"pin": 2, "pin": 2,
"angle_minus": 115, "angle_minus": 110,
"angle_plus": 65 "angle_plus": 65
}, },
{ {
"id": 1274, "id": 1274,
"pin": 3, "pin": 3,
"angle_minus": 115, "angle_minus": 115,
"angle_plus": 65 "angle_plus": 70
}, },
{ {
"id": 1457, "id": 1457,
@@ -64,5 +64,19 @@
"id": 7007, "id": 7007,
"pin": 26 "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 time import sleep_ms, ticks_diff, ticks_ms
from ir_pair import IRRxTxPollPair from ir_pair import IRRxTxPollPair
from double_ir import DoubleIr from double_ir import DoubleIr
from railway_signal import RailwaySignal, Lamp
SEMINSU_V1 = dict() SEMINSU_V1: dict[int, IRRxTxPollPair] = dict()
SEMINSU_V2 = dict() SEMINSU_V2: dict[int, DoubleIr] = dict()
SWITCHES = dict() SWITCHES: dict[int, Switch] = dict()
LAMPS: dict[int, Lamp] = dict()
_SEMAPHORES: dict[int, RailwaySignal] = dict()
LED = Pin("LED", Pin.OUT) # "LED" — специальное имя для встроенного индикатора LED = Pin("LED", Pin.OUT) # "LED" — специальное имя для встроенного индикатора
@@ -18,7 +21,7 @@ def load_switches():
import json import json
config = json.load(file) config = json.load(file)
for sw_cfg in config["switches"]: for sw_cfg in config.get("switches", []):
sw = Switch( sw = Switch(
id=sw_cfg["id"], id=sw_cfg["id"],
pin=sw_cfg["pin"], pin=sw_cfg["pin"],
@@ -65,6 +68,33 @@ def load_seminsus_v2():
SEMINSU_V2[sem_cfg["id"]] = seminsu 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): def resolve_command(command: str):
parts = command.split() parts = command.split()
if len(parts) == 4 and parts[0] == "SWITCH" and parts[2] == "TURN": 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}") evts.append(f"EVENT IK_MODULE {id} {seminsu.last_state}")
for id, seminsu in SEMINSU_V2.items(): for id, seminsu in SEMINSU_V2.items():
evts.append(f"EVENT IK_MODULE {id} {seminsu.last_state}") 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) 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_ids = []
_seminsu_idx = 0 _seminsu_idx = 0
@@ -225,4 +274,5 @@ if __name__ == "__main__":
load_switches() load_switches()
load_seminsus_v1() load_seminsus_v1()
load_seminsus_v2() load_seminsus_v2()
load_semaphores()
work() work()
+9 -5
View File
@@ -28,11 +28,12 @@ class Lamp:
- blink: мигает (переключение ON/OFF с периодом period_ms) - blink: мигает (переключение ON/OFF с периодом period_ms)
""" """
MODE_OFF = "off" ERROR = 1
MODE_ON = "on" MODE_OFF = 2
MODE_BLINK = "blink" 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._signal = signal
self.id = lamp_id self.id = lamp_id
self.pixel = pixel_index self.pixel = pixel_index
@@ -52,6 +53,9 @@ class Lamp:
def blink(self, period_ms: int = 500): def blink(self, period_ms: int = 500):
self._signal._set_lamp_mode(self, Lamp.MODE_BLINK, period_ms=period_ms) 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: class RailwaySignal:
"""Контейнер ламп светофора. """Контейнер ламп светофора.
@@ -264,7 +268,7 @@ class RailwaySignal:
return True return True
return False 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: if mode == Lamp.MODE_BLINK:
lamp.mode = Lamp.MODE_BLINK lamp.mode = Lamp.MODE_BLINK
lamp._blink_period_ms = int(period_ms) lamp._blink_period_ms = int(period_ms)