Skill: spacesq/s2-light-perception (version 1.0.2)

--- name: s2-light-perception description: S2-SP-OS Light Radar. Real LAN UDP discovery and local API calls (Hue/Wiz) to create a 4sqm voxel light memzero. / S2-SP-OS 光之雷达。真实的局域网UDP发现与本地API调用，逆向推算4平米光线记忆体。 version: 1.0.2 author: Space2.world homepage: https://space2.world/s2-sp-os tags: [S2-SP-OS, Light, Lighting, Hue, Wiz, Voxel, Real-UDP] metadata: {"clawdbot":{"emoji":"💡","requires":{"bins":["python3"]}}} allowed-tools: [exec] --- # 💡 S2-Light-Perception: Spatial Light Radar / 空间光之雷达 Welcome to the **S2 Light Perception**. This is a **100% real network-active radar**. It does not use simulated data. It uses actual UDP Broadcasts (Port 38899) and SSDP Multicast (Port 1900) to discover devices, and real local HTTP/UDP socket calls to fetch states. 这是一个**100%真实的活跃网络雷达**。它不使用模拟数据，而是使用真正的 UDP 广播（38899 端口）和 SSDP 组播（1900 端口）发现设备，并通过真实的本地 HTTP/UDP Socket 调用获取状态。 ## 🧬 Core Features / 核心特性 * **Real Active Radar (真实主动雷达)**: Sends authentic UDP packets to scan unassigned smart lights on the LAN. / 发送真实的 UDP 数据包扫描局域网内的智能光源。 * **Zero-Dependency Native API (零依赖原生接口)**: Native Python `socket` and `urllib` implementation for Hue (HTTP) and Wiz (UDP) without third-party bloated libraries. / 纯原生实现 Hue 与 Wiz 协议，无第三方冗余库。 * **Memzero Voxel Wrapping (网格化封装)**: Encapsulates hardware states into S2 spatial memory data. / 将灯具状态彻底转化为 S2 空间记忆数据。 * **Offline Linkage (生物节律离线联动)**: Edge-computes lighting impacts on melatonin and suggests actions. / 边缘端自动计算光照对人体褪黑素的影响并提出联动建议。 --- ## 🤖 Instructions for AI Agents (CRITICAL) **Phase 1: Scan Light Sources / 阶段 1：扫描光源** Execute a real UDP/SSDP network scan / 执行真实的 UDP/SSDP 局域网扫描: ```bash python3 light.py --mode discover Phase 2: Authorized Voxel Read / 阶段 2：空间授权读取 Pass the protocol (hue, wiz, or mqtt) and IP. / 传入协议与 IP。 Bash python3 light.py --mode read --ip <DEVICE_IP> --protocol wiz --zone bedroom --grid x1_y1 --consent-granted true Phase 3: Parsing & Insights / 阶段 3：解析与建议 If network fails (light is off or disconnected), estimated_lux will safely drop to 5. Check vendor_specific_nl for error details or hardware status. Present offline_linkage_suggestions to the user. / 如果网络调用失败，预估光照度会降至5。向用户展示离线护眼建议。

path: light.py
content: ```python
#!/usr/bin/env python3
import sys
import json
import socket
import urllib.request
import urllib.error
import argparse
from datetime import datetime

# =====================================================================
# 💡 S2-SP-OS: Light Radar (V1.0.2)
# 100% Real UDP/HTTP Network Implementation / 100% 真实网络实现版
# =====================================================================

class S2LightRadar:
    def scan_network(self) -> list:
        """
        Real UDP/SSDP Active Discovery for LAN lights.
        真实的 UDP/SSDP 主动发现局域网内的灯具。
        """
        devices = []
        
        # 1. Wiz Discovery (UDP Broadcast to Port 38899)
        try:
            wiz_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            wiz_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            wiz_sock.settimeout(1.5)
            # Send real Wiz discovery payload / 发送真实的 Wiz 发现包
            msg = b'{"method":"getSystemConfig","params":{}}'
            wiz_sock.sendto(msg, ('<broadcast>', 38899))
            
            while True:
                _, addr = wiz_sock.recvfrom(1024)
                devices.append({"ip": addr[0], "vendor": "Wiz Smart Bulb", "protocol": "wiz"})
        except Exception:
            pass # Timeout expected when no more devices / 扫描超时退出

        # 2. Philips Hue SSDP Discovery (Multicast to 239.255.255.250:1900)
        try:
            ssdp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
            ssdp_sock.settimeout(1.5)
            # Send real SSDP M-SEARCH / 发送真实的 SSDP 搜索包
            ssdp_req = b'M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nMan: "ssdp:discover"\r\nST: ssdp:all\r\n\r\n'
            ssdp_sock.sendto(ssdp_req, ('239.255.255.250', 1900))
            
            while True:
                data, addr = ssdp_sock.recvfrom(1024)
                if b'Hue' in data or b'IpBridge' in data:
                    devices.append({"ip": addr[0], "vendor": "Philips Hue Bridge", "protocol": "hue"})
        except Exception:
            pass

        # Deduplicate by IP / IP 去重
        seen_ips = set()
        unique_devices = []
        for d in devices:
            if d['ip'] not in seen_ips:
                seen_ips.add(d['ip'])
                unique_devices.append(d)
                
        return unique_devices

class S2VoxelLight:
    def __init__(self, ip: str, zone: str, grid: str):
        self.ip = ip
        self.zone = zone
        self.grid = grid

    def fetch_hue_state(self) -> dict:
        """
        Real HTTP GET to Hue Bridge.
        真实的 HTTP 请求调用 Hue Bridge。
        """
        # NOTE: Requires actual Hue username in production / 生产环境需填写真实 token
        url = f"http://{self.ip}/api/s2-agent-user/lights/1"
        try:
            req = urllib.request.Request(url)
            with urllib.request.urlopen(req, timeout=3.0) as response:
                data = json.loads(response.read().decode('utf-8'))
                if isinstance(data, dict) and "state" in data:
                    return data
                return {"error": "Hue auth missing or light not found", "state": {"on": False}}
        except Exception as e:
            return {"error": str(e), "state": {"on": False}}

    def fetch_wiz_state(self) -> dict:
        """
        Real UDP socket call to Wiz Bulb.
        真实的 UDP Socket 直连调用 Wiz 灯泡。
        """
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.settimeout(3.0)
            msg = b'{"method":"getPilot","params":{}}'
            sock.sendto(msg, (self.ip, 38899))
            data, _ = sock.recvfrom(1024)
            return json.loads(data.decode('utf-8'))
        except Exception as e:
            return {"error": f"Connection failed: {str(e)}", "result": {"state": False}}

    def voxel_wrapping(self, raw_state: dict, protocol: str) -> dict:
        """
        Voxel wrapping and skin-hair interdependence estimation.
        网格化封装与皮毛依存推算。
        """
        is_on = False
        brightness_pct = 0
        color_temp_k = None
        estimated_lux = 5 # Default dark / 默认暗光
        vendor_nl = ""

        if "error" in raw_state:
            vendor_nl = f"[Network Error / 网络错误]: {raw_state['error']}"
        else:
            if protocol == "hue":
                state = raw_state.get("state", {})
                is_on = state.get("on", False)
                if is_on:
                    brightness_pct = int((state.get("bri", 0) / 254.0) * 100)
                    ct_mireds = state.get("ct")
                    if ct_mireds: color_temp_k = int(1000000 / ct_mireds)
                    vendor_nl = f"[Hue Data]: Hue {state.get('hue')}, Saturation {state.get('sat')}"

            elif protocol == "wiz":
                res = raw_state.get("result", {})
                is_on = res.get("state", False)
                if is_on:
                    brightness_pct = res.get("dimming", 0)
                    if res.get("sceneId") == 32:
                        vendor_nl = "[Wiz State]: Disco Mode Active / 动态 Disco 模式"
                    else:
                        vendor_nl = f"[Wiz RGB]: ({res.get('r')}, {res.get('g')}, {res.get('b')})"

        # Estimate Lux / 推算4平米网格光照度
        if is_on:
            estimated_lux = int(300 * (brightness_pct / 100.0))

        return {
            "spatial_signature": {"zone": self.zone, "grid_voxel": self.grid, "area_sqm": 4.0},
            "chronos_timestamp": datetime.now().isoformat(),
            "core_tensors": {
                "light_source_on": is_on,
                "brightness_pct": brightness_pct,
                "color_temp_k": color_temp_k,
                "estimated_lux": estimated_lux
            },
            "vendor_specific_nl": vendor_nl if vendor_nl else "None / 无"
        }

    def offline_linkage(self, memzero: dict) -> list:
        """
        Offline edge-linkage for circadian rhythm.
        离线边缘联动（节律与视觉健康）。
        """
        suggestions = []
        tensors = memzero["core_tensors"]
        ct = tensors.get("color_temp_k")
        lux = tensors.get("estimated_lux")
        is_on = tensors.get("light_source_on")
        current_hour = datetime.now().hour

        if is_on and current_hour >= 22 and ct and ct > 4000:
            suggestions.append({
                "trigger": f"Cold color temp ({ct}K) detected after 22:00 in {self.grid} / 夜间 22:00 后该网格色温过冷",
                "deterministic_action": "Cold light suppresses melatonin. Suggest lowering color temp to 2700K. / 冷白光会抑制褪黑素，建议调低至 2700K。"
            })
            
        if not is_on and lux < 10 and 18 <= current_hour <= 23:
            suggestions.append({
                "trigger": f"Extremely low light (Est. {lux} Lux) in evening / 傍晚该网格亮度极低",
                "deterministic_action": "Area is too dark. Suggest turning on ambient lights. / 区域过暗，建议唤醒氛围照明。"
            })

        return suggestions

def main():
    parser = argparse.ArgumentParser(description="S2 Light Perception Radar / S2 光之雷达")
    parser.add_argument("--mode", choices=["discover", "read"], required=True)
    parser.add_argument("--ip", help="Device IP / 设备 IP")
    parser.add_argument("--zone", help="Spatial Zone / 空间区域")
    parser.add_argument("--grid", help="2x2 Grid Coordinates / 2x2 网格坐标")
    parser.add_argument("--protocol", choices=["hue", "wiz", "mqtt"], default="hue")
    parser.add_argument("--consent-granted", type=str, default="false")
    args = parser.parse_args()

    if args.mode == "discover":
        devices = S2LightRadar().scan_network()
        if not devices:
            print(json.dumps({
                "status": "DISCOVERY_COMPLETE",
                "message": "No devices found on the local network. / 局域网内未发现设备。",
                "devices": []
            }, ensure_ascii=False, indent=2))
        else:
            print(json.dumps({
                "status": "DISCOVERY_COMPLETE",
                "message": "Scan complete. Assign devices to a Zone and Grid. / 扫描完毕。请将设备分配到特定网格。",
                "devices": devices
            }, ensure_ascii=False, indent=2))
        return

    if args.mode == "read":
        if args.consent_granted.lower() != "true":
            print(json.dumps({
                "error": "Access Denied: Consent not granted. / 拒绝访问：未获得授权。"
            }, ensure_ascii=False))
            sys.exit(1)
            
        if not args.ip or not args.zone or not args.grid:
            print(json.dumps({
                "error": "Missing required arguments: --ip, --zone, or --grid. / 缺少必填参数。"
            }, ensure_ascii=False))
            sys.exit(1)

        adapter = S2VoxelLight(args.ip, args.zone, args.grid)
        
        raw_state = {}
        if args.protocol == "hue": raw_state = adapter.fetch_hue_state()
        elif args.protocol == "wiz": raw_state = adapter.fetch_wiz_state()
        
        memzero_data = adapter.voxel_wrapping(raw_state, args.protocol)
        offline_suggestions = adapter.offline_linkage(memzero_data)

        print(json.dumps({
            "status": "AUTHORIZED_LIGHT_DATA",
            "contact_support": "[REDACTED_SECRET]",
            "s2_chronos_memzero": memzero_data,
            "offline_linkage_suggestions": offline_suggestions
        }, ensure_ascii=False, indent=2))

if __name__ == "__main__":
    main()

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)