powerpic
Replacement board for a Casio CA-53W
import xml.etree.ElementTree as ET
from sys import argv
from copy import deepcopy
tree = ET.parse('watch_display.svg')
ns = {
"inkscape": "http://www.inkscape.org/namespaces/inkscape",
"svg": "http://www.w3.org/2000/svg"
}
A=1 # Top Center
B=2 # Top Right
C=4 # Bottom Right
D=8 # Bottom Center
E=0x10 # Bottom Left
F=0x20 # Top Left
G=0x40 # Center Center
P=0x80 # Period (Not implemented)
H=0x100 # Extra segments for the secondary display. (Not implemented)
I=0x200
J=0x400
seg_map = [
'a',
'b',
'c',
'd',
'e',
'f',
'g'
]
font = [
# Punctuation
0x0, # Space
B|C|P, # !
B|F, # "
0x0, # # ???
0x0, # $ ???
0x0, # % ???
0x0, # & ???
F, # ' Top left
B|C, # ( Line on right side
E|F, # ) Line on left side
A|B|F|G, # * Like a degrees sign
D|E, # + Kinda like a shorter L
E, # , Bottom left
G, # -
P, # . This adds a period but takes up a space.
B|E|G, # /
# Numbers 0-9
A|B|C|D|E|F, # 0
B|C, # 1
A|B|D|E|G, # 2
A|B|C|D|G, # 3
B|C|F|G, # 4
A|C|D|F|G, # 5
A|C|D|E|F|G, # 6
A|B|C|F, # 7
A|B|C|D|E|F|G, # 8
A|B|C|D|F|G, # 9
# Punctuation
0x0, # : ???
0x0, # ; ???
D|E|G, # < Like c
D|G, # =
C|D|G, # > Like a backwards c
A|B|E|G, # ? No dot - kinda weird
0x0, # @ ???
# Uppercase alphabet
A|B|C|E|F|G, # A
F|E|G|C|D, # B ** Lowercase
A|D|E|F, # C
B|C|D|E|G, # D ** Lowercase
A|D|E|F|G, # E
A|E|F|G, # F
A|C|D|E|F|G, # G
B|C|E|F|G, # H
E|F, # I Like 1 except on the left
B|C|D|E, # J
B|C|E|F|G, # K Like H and X
D|E|F, # L
A|C|E, # M Kinda weird
A|B|C|E|F, # N ** Big lowercase n
A|B|C|D|E|F, # O
A|B|E|F|G, # P
A|B|C|D|E|F, # Q Like O
A|E|F, # R ** Lowercase, but big
A|C|D|F|G, # S Like a 5
A|E|F, # T Upside down L
B|C|D|E|F, # U Like V
B|C|D|E|F, # V Like U
B|D|F, # W Kinda weird
B|C|E|F|G, # X Like H and K
B|C|F|G, # Y
A|B|D|E|G, # Z
# Punctuation
A|D|E|F, # [ Like C
C|F|G, # \ backslash
A|B|C|D, # ] Like a backwards C
A|B|F, # ^
D, # _
B, # ` Top right
# Lowercase alphabet
A|B|C|E|F|G, # A ** Uppercase
F|E|G|C|D, # b
D|E|G, # c
B|C|D|E|G, # d
A|D|E|F|G, # E ** Uppercase
A|E|F|G, # f
A|B|C|D|F|G, # g
C|E|F|G, # h
E, # i No dot, on left
B|C|D|E, # J
B|C|E|F|G, # K ** Uppercase Like H and X
D|E|F, # l Like a capitol I
A|C|E, # M Kinda weird
C|E|G, # n
C|D|E|G, # o
A|B|E|F|G, # P ** Uppercase
A|B|C|F|G, # q Backwards P
E|G, # R ** Lowercase
A|C|D|F|G, # S Like a 5
D|E|F|G, # t
C|D|E, # u Like v
C|D|E, # v Like u
B|D|F, # W Kinda weird
B|C|E|F|G, # X ** Uppercase Like H and K
B|C|D|F|G, # Y
A|B|D|E|G, # Z ** Uppercase pretty much
# Punctuation
B|C|G, # {
B|C, # | Left side
E|F|G, # }
A, # ~ Top segment
]
def get_segments(ch):
ch = ord(ch)
if ch <= 9:
ch += 16
else:
ch -= 32
return font[ch]
def display_primary_segments(disp, position, segments):
for i in range(7):
if (1 << i) & segments:
segment = disp.findall(f".//*[@inkscape:label='primary']/*/*[@inkscape:label='{position}{seg_map[i]}']", ns)[0]
segment.attrib['style'] = segment.attrib['style'].replace('fill-opacity:0', 'fill-opacity:1')
def display_primary_character(disp, position, ch):
display_primary_segments(disp, position, get_segments(ch))
def display_primary_string(disp, position, st):
for ch in st:
display_primary_character(disp, position, ch)
position += 1
def display_secondary_segments(display, position, segments):
for i in range(7):
if (1 << i) & segments:
segment = display.findall(f".//*[@inkscape:label='secondary']/*/*[@inkscape:label='{position}{seg_map[i]}']", ns)[0]
segment.attrib['style'] = segment.attrib['style'].replace('fill-opacity:0', 'fill-opacity:1')
def display_secondary_character(display, position, ch):
display_secondary_segments(display, position, get_segments(ch))
def display_secondary_string(display, position, st):
for ch in st:
display_secondary_character(display, position, ch)
position += 1
def display_punctuation(display, punctuation):
for p in punctuation:
if p == '0': # Colon
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='colon']", ns)[0]
elif p == '1':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='1']", ns)[0]
elif p == '2':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='2']", ns)[0]
elif p == '3':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='3']", ns)[0]
elif p == '4':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='4']", ns)[0]
elif p == '5':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='5']", ns)[0]
elif p == '6':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='6']", ns)[0]
elif p == '7':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='7']", ns)[0]
elif p == '8':
segment = display.findall(f".//*[@inkscape:label='punctuation']/svg:path[@inkscape:label='8']", ns)[0]
else:
print(f"Unknown punctuation segment: {p}")
continue
segment.attrib['style'] = segment.attrib['style'].replace('fill-opacity:0', 'fill-opacity:1')
def display_signs(display, signs):
for sign in signs:
if sign == '+':
segments = display.findall(f".//*[@inkscape:label='plus']/svg:path", ns)
elif sign == '-':
segments = display.findall(f".//*[@inkscape:label='minus']/svg:path", ns)
elif sign == '*':
segments = display.findall(f".//*[@inkscape:label='multiply']/svg:path", ns)
elif sign == '\\':
segments = display.findall(f".//*[@inkscape:label='divide']/svg:path", ns)
else:
print(f"Unknown sign display segment: {sign}")
continue
for segment in segments:
segment.attrib['style'] = segment.attrib['style'].replace('fill-opacity:0', 'fill-opacity:1')
def display_misc(display, misc):
for m in misc:
if m == 'a':
segment = display.findall(f".//*[@inkscape:label='am']", ns)[0]
elif m == 'p':
segment = display.findall(f".//*[@inkscape:label='pm']", ns)[0]
elif m == 'k':
segment = display.findall(f".//*[@inkscape:label='k']", ns)[0]
elif m == 'b':
segment = display.findall(f".//*[@inkscape:label='bell']", ns)[0]
elif m == 'w':
segment = display.findall(f".//*[@inkscape:label='wave']", ns)[0]
else:
print(f"Unknown misc display segment' : '{m}'")
continue
segment.attrib['style'] = segment.attrib['style'].replace('fill-opacity:0', 'fill-opacity:1')
def gen_display(display):
print(display)
worktree = deepcopy(tree)
workroot = worktree.getroot()
if display[1]:
display_primary_string(workroot, 1, display[1])
if display[2]:
display_secondary_string(workroot, 1, display[2])
if display[3]:
display_signs(workroot, display[3])
if display[4]:
display_misc(workroot, display[4])
if display[5]:
display_punctuation(workroot, display[5])
worktree.write(display[0] + '.svg')
if __name__ == '__main__':
if len(argv) > 1:
if len(argv) == 2 and argv[1].endswith('.csv'):
import csv
with open(argv[1], newline='') as csvfile:
screenreader = csv.reader(csvfile)
header = next(screenreader)
for row in screenreader:
gen_display(row)
elif len(argv) > 2:
# display_primary_string(1, argv[1])
display = ['', '', '', '', '', '']
display[0] = argv[1]
display[1] = argv[2]
if len(argv) > 3:
display[2] = argv[3]
if len(argv) > 4:
display[3] = argv[4]
if len(argv) > 5:
display[4] = argv[5]
if len(argv) > 6:
display[5] = argv[6]
if len(argv) > 7:
print(f"Ignoring args: {argv[7:]}")
gen_display(display)
else:
print('Required args: <name> <primary> [secondary [signs [misc]]]')
print(' or: <filename.csv> of csv displays')
else:
print('Required args: <name> <primary> [secondary [signs [misc]]]')
print(' or: <filename.csv> of csv displays')
# gen_svg()
# tree.write('test.svg')