Metadata-Version: 2.4
Name: alaska2
Version: 0.1.2
Summary: GigE 카메라 · 공유메모리 영상 · PC 랜카드 · LS PLC · 알고리즘 프로세스 호스트 (표준 라이브러리만으로 도는 코어)
Author: aainka
License: Proprietary
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: image
Requires-Dist: numpy>=1.24; extra == "image"
Requires-Dist: opencv-contrib-python>=4.8; extra == "image"
Provides-Extra: fast
Requires-Dist: numba>=0.58; extra == "fast"
Provides-Extra: serial
Requires-Dist: pyserial>=3.5; extra == "serial"
Provides-Extra: ui
Requires-Dist: PySide6>=6.5; extra == "ui"
Requires-Dist: numpy>=1.24; extra == "ui"
Requires-Dist: opencv-contrib-python>=4.8; extra == "ui"
Provides-Extra: all
Requires-Dist: numpy>=1.24; extra == "all"
Requires-Dist: opencv-contrib-python>=4.8; extra == "all"
Requires-Dist: numba>=0.58; extra == "all"
Requires-Dist: pyserial>=3.5; extra == "all"
Requires-Dist: PySide6>=6.5; extra == "all"
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"

﻿# alaska2

GigE 카메라 · 공유메모리 영상 · PC 랜카드 · LS PLC · 알고리즘 프로세스 호스트를 한 꾸러미로 (판 0.1.0).
벤더 SDK 없이 GigE Vision(GVCP/GVSP)을 직접 말한다. 코어는 **표준 라이브러리만** 쓰고,
numpy · OpenCV · PySide6 · pyserial · numba 는 필요한 기능에서만 고른다(extras).

설계 문서: `docs/alaska2/` — 0 제품기획 · 1 개발계획 · 2 기능명세 · 3 클래스정의 · 4 소스블록 · 5 시험계획 · 6 성능지표.

## 소스 배치 (기능별, src 배치)

```
src/alaska2/
├─ __init__.py   공개 이름(게으르게 부름) · _bundle_hints (exe 로 묶을 때 하위 모듈 목록)
├─ common/       예외(errors) · 설정(config) · 화소 형식 · 파일 · IPv4 · 로그 고리      — 표준 라이브러리만
├─ camera/
│  ├─ gige/      GVCP 찾기 · FORCEIP · 레지스터 · GenICam XML · GVSP 수신(재전송) · Camera · IP 바꾸기 · 진단
│  ├─ image/     화소 → 화면용 · JPEG · 저장 (numpy/OpenCV 있으면 빠른 길)
│  ├─ session/   CameraSession — 수신 루프 · 공유메모리 생산 · 자동 복구 · 콜백
│  └─ server/    RB Express 호환 사이드카 (python -m alaska2.camera.server)
├─ shm/          영상 판(Producer/ShmView · 카메라는 open(shm=N)) · 결과 고리(RingWriter/RingReader) · gc
├─ network/      PC 랜카드(NicManager) · 대역 스캔 · 자동 설정 · 채널 등록부
├─ plc/          LS FEnet · Cnet · PlcManager(태그 · 폴링 · 에지) · Handshake · FakePlc
├─ algo/         알고리즘 프로세스 호스트 — AlgoSupervisor · Algorithm · 제어/영상/결과 세 채널
├─ ui/           PySide6 — 차콜 테마 · 예제 창 틀(exapp) · NetCanvas · LiveView · 속성창 · 데모 앱
├─ bench/        성능 지표 측정 (alaska2 bench)
├─ testing/      가짜 GigE 카메라 · 가짜 생산자 · 가짜 랜카드 (설비 없이 시험 · 예제)
└─ _pyinstaller/ PyInstaller 꽂개
tests/<기능>/   examples/NN_*.py   tools/   bench/baseline.json   docs/alaska2/
```

## 설치

```bash
pip install -e .                 # 코어만 (찾기 · IP · 원본 장 · shm · PLC FEnet)
pip install -e ".[all,test]"     # 전부 + pytest
```
저장소에서 설치 없이 돌릴 때는 `PYTHONPATH=src` (예제는 스스로 `src/` 를 길에 넣는다).

| extra | 끌고 오는 것 | 없으면 |
|---|---|---|
| `image` | numpy · opencv-contrib-python | 색 입히기 · JPEG 이 `ImagingUnavailable` |
| `fast` | numba | 10/12비트 → 8비트가 numpy 길 (5MP 약 5ms, numba 면 약 1.1ms) |
| `serial` | pyserial | Cnet(RS-232C) 만 선다 |
| `ui` | PySide6 · numpy · opencv | `alaska2.ui` · 예제 창이 선다 |
| `all` · `test` | 위 전부 · pytest | |

## 한눈에

```python
import alaska2

for c in alaska2.discover():                       # 모든 랜카드에서 찾기
    print(c.ip, c.mac, c.model, "닿음" if c.reachable else "대역 다름")

with alaska2.open("192.168.10.10") as cam:         # 열기 → 한 장
    cam.start()
    frame = cam.grab()
    cam.stop()

alaska2.force_temp("00:11:22:33:44:55", "192.168.10.20", "255.255.255.0")   # IP 임시로 (재부팅하면 사라짐)

from alaska2.shm import ShmView                    # 다른 프로세스가 쓰는 영상 읽기 — 없으면 None
r = ShmView.open("cam0")
f = r and r.latest()
data = f.copy() if f else None                     # 덮였으면 None
```

## 예제 — 모두 PySide6 창

예제 32개는 모두 같은 틀(`alaska2.ui.exapp`) 위의 창이다. 테마는 **차콜**(보기 › 테마 에서 다크 · 라이트).

- 메뉴: 파일(로그 저장 · 끝) · 실행(▶ 시작 F5 · ■ 정지 Shift+F5 · 다시 Ctrl+R) · **옵션** · (예제 메뉴) · 보기 · 도움말
- **시작 옵션은 [옵션] 메뉴**로 고른다. 명령줄 `--이름` 은 같은 옵션의 시작 값이다 (`python examples/NN_*.py --help`).
- 설비가 없으면 옵션 › 가짜 장치(`--fake`). 결과는 표 · 그림 · 라이브 화면 + 아래 로그 판.
- `--auto` 곧바로 시작하고 끝나면 그 종료코드로 닫힘 · `--quit-after 초` · `--theme charcoal|dark|light`.

```bash
python examples/03_live_cv.py                         # 찾기 → 고르기 → IP 변경(Ctrl+I) → 라이브(F6)
python examples/03_live_cv.py --fake                  # 가짜 카메라 2대로
python examples/01_discover.py --fake --auto          # 곧바로 찾고 닫힘 (시험 · 스크립트용)
```

| 묶음 | 예제 |
|---|---|
| 카메라 | 01 찾기 · 02 한 장 저장 · **03 찾기 → IP → 라이브** · 04 피처 · 05 트리거 · 06 IP 옮기기 · 10 두 대 · 28 설정 꾸러미 · 29 진단 · 30 가짜 카메라 |
| 공유메모리 | 07 생산자 · 08 소비자 · 09 REST · 26 복사 없이 numpy · 27 소비자 셋 · 31 성능 맛보기 |
| 랜카드 · PLC | 11 랜카드 보기/바꾸기 · 12 자동 설정 · 13 FEnet · 14 Cnet · 15 태그 · 16 PLC 요청 → 촬영 → 결과 · 32 핸드셰이크 |
| 알고리즘 | 19 최소 · 20 감독자 · 21 장 알림 → 결과 고리 · 22 PLC 에지 → 알고리즘 · 23 죽음 → 다시 띄움 · 24 시간 초과 · 25 결과 겹쳐 그리기 |
| 화면 | 17 네트워크 그림 · 18 뷰어 앱 |

⚠ 랜카드 쓰기(11 · 12)는 옵션 `apply` 를 켜야만 바꾼다(기본은 계획만). 관리자 권한이 필요하다.

## 명령

```bash
alaska2 --help                     # = python -m alaska2
alaska2 discover --json
alaska2 ip temp 00:11:22:33:44:55 192.168.10.20/24
alaska2 shm list                   # 공유메모리에 올라온 카메라
alaska2 nic set 이더넷 192.168.10.2/24          # 계획만 — 실제로 바꾸려면 --apply (관리자)
alaska2 doctor                     # 이 PC 훑기 · alaska2 doctor 192.168.10.10 (그 카메라 원인 가르기)
alaska2 serve                      # RB Express 호환 사이드카 (= python -m alaska2.camera.server)
```
명령: `discover · ip · grab · features · shm · nic · plc · algo · bench · serve · doctor`.
종료코드: 0 성공 · 1 실패 · 2 인자 틀림 · 3 관리자 필요.

## 시험

```bash
python -m pytest                          # 전부 (설비 없이 — 가짜 카메라 · 가짜 PLC · 가짜 랜카드)
python -m pytest -m "not slow"            # 찢김 등 오래 걸리는 것 빼고
python -m pytest tests/camera tests/plc   # 기능 하나씩 (tests/<기능>/)
python tools/deps_check.py                # import 허용표 (소스블록명세서 §13) — 위반 0
```
- 예제 시험은 `--auto` 와 `QT_QPA_PLATFORM=offscreen` 으로 창 없이 돈다.
- `alaska2_TEAR_SECS=60` — 찢김 시험 길이(기본 20초).
- `alaska2_RBX_PY=<RB Express>/py` — RB Express 원본 pyshm 과의 호환 시험. 없으면 건너뜀.

## 성능 지표

```bash
alaska2 bench --quick --json out.json --md out.md       # = python -m alaska2.bench
alaska2 bench --only PM-S01,PM-S02
alaska2 bench --save-baseline bench/baseline.json       # 개발 기준 PC 에서만
alaska2 bench --baseline bench/baseline.json --strict   # 회귀 · ★ 목표 실패면 종료코드 1
```
지표 정의 · 목표 · 판정은 `docs/alaska2/6_alaska2_성능지표계획서.md`, 첫 측정은 `bench/first_run.md`.

## exe 로 묶기 (PyInstaller)

빌드 서버에는 소스만 주면 된다. alaska2 을 찾을 길만 알려 준다 — `--paths src` 또는 먼저 `pip install .`.

```bash
pip install pyinstaller
pyinstaller --noconfirm --paths src examples/03_live_cv.py           # → dist/03_live_cv/03_live_cv.exe
python tools/build_exe.py examples/03_live_cv.py --onefile --console # 같은 일 (개발 PC 용 도우미)
```
- alaska2 은 공개 이름을 글자로(importlib) 불러 PyInstaller 가 못 본다 → `alaska2._bundle_hints()`(부르지 않는 함수)에
  하위 모듈 전부를 import 문으로 적어 두어, 어떻게 빌드하든 다 들어간다. 모듈을 더하면 거기에도 — 시험이 빠진 것을 잡는다.
- 가짜 카메라 견본 XML 은 코드로도 들어 있다(`alaska2.testing._xml`) — exe 에 자료 파일이 없어도 `--fake` 가 돈다.
- `pip install` 한 환경에서는 꽂개(`src/alaska2/_pyinstaller`, entry point `pyinstaller40`)도 저절로 읽힌다.
- ⚠ 알고리즘 예제(19~25)는 알고리즘을 별도 파이썬 프로세스(`python -m alaska2.algo.host`)로 띄우므로 exe 만으로는 돌지 않는다.

