234 lines
9.2 KiB
Python
Executable File
234 lines
9.2 KiB
Python
Executable File
#!/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)
|