#!/bin/env python3 import socket import time import random import argparse mw1 = 0 mw2 = 0 t1 = 0 t2 = 0 t3 = 0 t4 = 0 t5 = 0 t6 = 0 t7 = 0 t8 = 0 t9 = 0 pr1 = 0 pr2 = 0 mw1_max = 5000 mw2_max = 5000 t_max = 35000 pr1_max = 20000 pr2_max = 15000 ENTRY_RATE = 20 / 20 PUMP_RATE = 5 / 20 rw = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] def are_valves_open(valves, *ns): mask = 0 for n in ns: mask |= 1 << (n - 1) return (~valves & mask) == mask def send_cmd(cmd: str, data: str) -> None: msg = f'(A01{cmd}{data}&' chk = sum(c for c in msg.encode('ascii')) & 0xFF msg += f'{chk:02X})\r' time.sleep(len(msg) * 8 / 9600 * 2) print(f'-> {msg}') client.send(msg.encode('ascii')) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('socket') args = parser.parse_args() client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) client.connect(args.socket) while True: line = b'' while b'\r' not in line: line += client.recv(256) cmds = line.split(b'\r') line = cmds[-1] cmds = [c.decode('ascii') for c in cmds[:-1]] for cmd in cmds: print(f'<- {cmd}') time.sleep(len(cmd) * 8 / 9600 * 2) if not cmd.startswith('(A01') or not cmd.endswith(')') or len(cmd) < 7: send_cmd('CE', '02') continue c, d = cmd[4:6], cmd[6:-1] if cmd[-4] == '&': chk1 = int(cmd[-3:-1], 16) chk2 = sum(c for c in cmd[:-3].encode('ascii')) & 0xFF if chk1 != chk2: send_cmd('CE', '03') continue d = d[:-3] if c == 'TS': send_cmd('TS', d) elif c == 'ST': send_cmd('ST', '0002') elif c == 'DR': # FIXME d = d.split(',') s = int(d[0][2:]) l = int(d[1]) send_cmd('DR', ''.join(f'{r:04X}' for r in rw[s:s+l])) elif c == 'DW': # FIXME d = d.split(',') s = int(d[0][2:]) l = int(d[1]) for i in range(l): rw[s + i] = int(d[2 + i], 16) send_cmd('ST', '0002') else: send_cmd('CE', '01') # tick - valves for i in range(0, 60): want_open = rw[i // 16] & (1 << (i % 16)) == 0 is_open = rw[10 + i // 16] & (1 << (i % 16)) != 0 if want_open and not is_open: if random.random() > 0.875: rw[10 + i // 16] |= 1 << (i % 16) elif not want_open and is_open: if random.random() > 0.875: rw[10 + i // 16] &= ~(1 << (i % 16)) # tick - wannen want_a1_selected = (rw[5] & 0x0004) != 0 want_a2_selected = not want_a1_selected is_a1_selected = (rw[14] & 0x0200) != 0 is_a2_selected = (rw[14] & 0x0100) != 0 if is_a1_selected and not want_a1_selected: rw[14] &= 0xFDFF elif not is_a1_selected and want_a1_selected: if random.random() > 0.875: rw[14] |= 0x0200 if is_a2_selected and not want_a2_selected: rw[14] &= 0xFEFF elif not is_a2_selected and want_a2_selected: if random.random() > 0.875: rw[14] |= 0x0100 # tick - pipeline valves = (rw[13] << 48) | (rw[12] << 32) | (rw[11] << 16) | rw[10] wannen_schnecke = (rw[5] & 0x1) != 0 mp1 = (rw[4] & 0x002) != 0 mp2 = (rw[4] & 0x004) != 0 p12 = (rw[4] & 0x010) != 0 p3 = (rw[4] & 0x020) != 0 p4 = (rw[4] & 0x040) != 0 p5 = (rw[4] & 0x080) != 0 p6 = (rw[4] & 0x100) != 0 if wannen_schnecke and is_a1_selected: mw1 += ENTRY_RATE elif wannen_schnecke and is_a2_selected: mw2 += ENTRY_RATE if mp1 and mw1 > 0: mw1 -= PUMP_RATE if are_valves_open(valves, 1, 6, 51) or are_valves_open(valves, 4, 8, 52): pr1 += PUMP_RATE elif are_valves_open(valves, 1, 6, 55) or are_valves_open(valves, 4, 8, 56): pr2 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 22) or are_valves_open(valves, 4, 7, 9, 13, 23): t1 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 24) or are_valves_open(valves, 4, 7, 9, 13, 25): t2 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 26) or are_valves_open(valves, 4, 7, 9, 13, 27): t3 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 28, 30) or are_valves_open(valves, 4, 7, 9, 13, 29, 31): t4 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 28, 32) or are_valves_open(valves, 4, 7, 9, 13, 29, 33): t5 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 28, 34, 37) or are_valves_open(valves, 4, 7, 9, 13, 29, 35, 36): t6 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 28, 34, 39) or are_valves_open(valves, 4, 7, 9, 13, 29, 35, 38): t7 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 28, 34, 41) or are_valves_open(valves, 4, 7, 9, 13, 29, 35, 40): t8 += PUMP_RATE elif are_valves_open(valves, 1, 5, 12, 28, 34, 43) or are_valves_open(valves, 4, 7, 9, 13, 29, 35, 42): t9 += PUMP_RATE if mp2 and mw2 > 0: mw2 -= PUMP_RATE if are_valves_open(valves, 2, 8, 52) or are_valves_open(valves, 3, 6, 51): pr1 += PUMP_RATE elif are_valves_open(valves, 2, 8, 56) or are_valves_open(valves, 3, 6, 55): pr2 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 22) or are_valves_open(valves, 2, 7, 9, 13, 23): t1 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 24) or are_valves_open(valves, 2, 7, 9, 13, 25): t2 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 26) or are_valves_open(valves, 2, 7, 9, 13, 27): t3 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 28, 30) or are_valves_open(valves, 2, 7, 9, 13, 29, 31): t4 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 28, 32) or are_valves_open(valves, 2, 7, 9, 13, 29, 33): t5 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 28, 34, 37) or are_valves_open(valves, 2, 7, 9, 13, 29, 35, 36): t6 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 28, 34, 39) or are_valves_open(valves, 2, 7, 9, 13, 29, 35, 38): t7 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 28, 34, 41) or are_valves_open(valves, 2, 7, 9, 13, 29, 35, 40): t8 += PUMP_RATE elif are_valves_open(valves, 3, 5, 12, 28, 34, 43) or are_valves_open(valves, 2, 7, 9, 13, 29, 35, 42): t9 += PUMP_RATE if p6 and (t6 > 0 or t7 > 0 or t8 > 0 or t9 > 0): if t6 > 0: t6 -= PUMP_RATE if t7 > 0: t7 -= PUMP_RATE if t8 > 0: t8 -= PUMP_RATE if t9 > 0: t9 -= PUMP_RATE if are_valves_open(valves, 53): pr1 += PUMP_RATE elif are_valves_open(valves, 57): pr2 += PUMP_RATE # tick - fill levels rw[14] &= 0xFF00 rw[14] |= 0x0004 if mw1 > 50 else 0 rw[14] |= 0x0002 if mw1 > mw1_max / 2 else 0 rw[14] |= 0x0001 if mw1 > mw1_max * 0.875 else 0 rw[14] |= 0x0020 if mw2 > 50 else 0 rw[14] |= 0x0010 if mw2 > mw2_max / 2 else 0 rw[14] |= 0x0008 if mw2 > mw2_max * 0.875 else 0 rw[14] |= 0x0040 if pr1 > pr1_max * 0.875 else 0 rw[14] |= 0x0080 if pr2 > pr2_max * 0.875 else 0 rw[16] &= 0xC000 rw[16] |= 0x0001 if t1 > 50 else 0 rw[16] |= 0x0002 if t1 > t_max * 0.875 else 0 rw[16] |= 0x0004 if t2 > 50 else 0 rw[16] |= 0x0008 if t2 > t_max * 0.875 else 0 rw[16] |= 0x0010 if t3 > 50 else 0 rw[16] |= 0x0020 if t3 > t_max * 0.875 else 0 rw[16] |= 0x0040 if t4 > 50 else 0 rw[16] |= 0x0080 if t4 > t_max * 0.875 else 0 rw[16] |= 0x0100 if t5 > 50 else 0 rw[16] |= 0x0200 if t5 > t_max * 0.875 else 0 rw[16] |= 0x0400 if t6 > t_max * 0.875 else 0 rw[16] |= 0x0800 if t7 > t_max * 0.875 else 0 rw[16] |= 0x1000 if t8 > t_max * 0.875 else 0 rw[16] |= 0x2000 if t9 > t_max * 0.875 else 0 print(mw1, mw2, t1, t2, t3, t4, t5, t6, t7, t8, t9, pr1, pr2)