import json, time from pathlib import Path import numpy as np import pyautogui as pg import win32clipboard from pywinauto import Desktop ROOT=Path(__file__).resolve().parent w=Desktop(backend='win32').window(handle=4721434) u=Desktop(backend='uia').window(handle=4721434) w.set_focus() u.child_window(title='停止',control_type='Hyperlink').invoke() time.sleep(1) w.child_window(title='键盘输入').click() time.sleep(.5) canvas=next(c.rectangle() for c in w.children() if c.rectangle().width()==720 and c.rectangle().height()==408) ROIS={0:[(15,82,165,118)],1:[(374,82,525,118),(555,146,706,185)],2:[(555,82,706,118)],3:[(374,146,525,185)],4:[(195,146,345,185)],5:[(195,82,345,118)],6:[(15,241,345,272)],7:[(375,241,705,272)],8:[(15,311,165,341)],9:[(195,311,345,341)],10:[(375,311,525,341)],11:[(555,311,705,341)],12:[(15,375,165,405)],13:[(195,375,345,405)],14:[(375,375,525,405)],15:[(555,375,705,405)]} records=[] def execute(code): win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() win32clipboard.SetClipboardText(code,win32clipboard.CF_UNICODETEXT) win32clipboard.CloseClipboard() r=w.rectangle() pg.click(r.left+180,r.top+915) pg.hotkey('ctrl','a') pg.hotkey('ctrl','v') w.child_window(title='执行所有代码').click() time.sleep(.5) def check(name,states): shot=pg.screenshot(region=(canvas.left,canvas.top,canvas.width(),canvas.height())) shot.save(str(ROOT/f'sim_{name}.png')) pixels=np.asarray(shot) for index,state in enumerate(states): for x1,y1,x2,y2 in ROIS[index]: a=pixels[y1:y2,x1:x2,:3].astype(np.int16) r,g,b=a[:,:,0],a[:,:,1],a[:,:,2] counts=[int(((r>75)&(r<180)&(abs(r-g)<8)&(abs(r-b)<8)).sum()),int(((g>180)&(r<80)&(b<80)).sum()),int(((r>180)&(g<80)&(b<80)).sum())] assert counts[state]>20 and (state==1 or counts[1]==0) and (state==2 or counts[2]==0),(name,index,state,counts) records.append({'name':name,'states':states,'screenshot':f'sim_{name}.png','passed':True}) (ROOT/'simulator-results.json').write_text(json.dumps({'scope':'Keyboard input simulation, not physical CAN/UART display proof','checks':records},indent=2),encoding='utf-8') print(name+' passed',flush=True) execute('\n'.join([f'd{i}=0' for i in range(16)]+['page debug'])) check('initial_unknown',[0]*16) for index,signal in [(5,'left_motor_interlock'),(6,'RES'),(7,'control_box')]: for state in (1,2,0): execute(f'd{index}={state}') states=[0]*16 states[index]=state check(f'{signal}_{state}',states) execute('\n'.join(f'd{i}=1' for i in range(15))) check('all_normal',[1]*15+[0]) execute('\n'.join(f'd{i}=2' for i in range(15))) check('all_fault',[2]*15+[0]) execute('\n'.join(f'd{i}=0' for i in range(16))) check('final_unknown',[0]*16) w.child_window(title='用户MCU输入').click() time.sleep(.4) u.child_window(title='开始',control_type='Hyperlink').invoke() print('13 keyboard simulation checks passed; returned to User MCU input')