|
|
@ -6,7 +6,7 @@ import serial.tools.list_ports |
|
|
|
|
|
|
|
|
|
|
|
from collections import namedtuple |
|
|
|
from collections import namedtuple |
|
|
|
from datetime import datetime, timedelta |
|
|
|
from datetime import datetime, timedelta |
|
|
|
|
|
|
|
from openpyxl import load_workbook |
|
|
|
|
|
|
|
|
|
|
|
__version__ = '0.0.1' |
|
|
|
__version__ = '0.0.1' |
|
|
|
|
|
|
|
|
|
|
@ -77,6 +77,67 @@ def parse_time_table(timetable, available_commands): |
|
|
|
return timed_commands |
|
|
|
return timed_commands |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_excel_file(path, available_commands): |
|
|
|
|
|
|
|
''' parses an time table in an excel file into a list of ScheduledCommands |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
path: |
|
|
|
|
|
|
|
path to excel file |
|
|
|
|
|
|
|
the time must be in the first column of the first sheet, the command in |
|
|
|
|
|
|
|
the second column |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
available_commands: |
|
|
|
|
|
|
|
a dictionary containing the available human readable commands as |
|
|
|
|
|
|
|
keys and the commands to send as values |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{'open': 0, 'close': 1} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
returns a list consisting of ScheduledCommands |
|
|
|
|
|
|
|
''' |
|
|
|
|
|
|
|
workbook = load_workbook(path, read_only=True) |
|
|
|
|
|
|
|
sheets = workbook.get_sheet_names() |
|
|
|
|
|
|
|
sheet_name = sheets[0] |
|
|
|
|
|
|
|
sheet = workbook[sheet_name] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
is_header = True |
|
|
|
|
|
|
|
timed_commands = [] |
|
|
|
|
|
|
|
for i, row in enumerate(sheet.rows): |
|
|
|
|
|
|
|
delta = parse_time_cell(row[0]) |
|
|
|
|
|
|
|
print(i, row[0].value, delta) |
|
|
|
|
|
|
|
if delta is None: |
|
|
|
|
|
|
|
# no time in the cell |
|
|
|
|
|
|
|
if is_header: |
|
|
|
|
|
|
|
# this is still a header |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
# not the header and not a time cell |
|
|
|
|
|
|
|
# premature end of list |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
# a time in the cell, this is not a header any more |
|
|
|
|
|
|
|
is_header = False |
|
|
|
|
|
|
|
raw_command = row[1].value |
|
|
|
|
|
|
|
cmd = parse_command(raw_command, available_commands) |
|
|
|
|
|
|
|
# add a ScheduledCommand to the resulting list |
|
|
|
|
|
|
|
tc = ScheduledCommand(delta, raw_command, cmd) |
|
|
|
|
|
|
|
timed_commands.append(tc) |
|
|
|
|
|
|
|
return timed_commands |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_time_cell(excel_cell): |
|
|
|
|
|
|
|
if excel_cell.is_date: |
|
|
|
|
|
|
|
return time_as_timedelta(excel_cell.value) |
|
|
|
|
|
|
|
if isinstance(excel_cell.value, float): |
|
|
|
|
|
|
|
return timedelta(days=excel_cell.value) |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
delta = parse_time(excel_cell.value) |
|
|
|
|
|
|
|
return delta |
|
|
|
|
|
|
|
except ValueError: |
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_time(time_str): |
|
|
|
def parse_time(time_str): |
|
|
|
''' parses a string to extract the time information |
|
|
|
''' parses a string to extract the time information |
|
|
|
|
|
|
|
|
|
|
@ -95,14 +156,18 @@ def parse_time(time_str): |
|
|
|
else: |
|
|
|
else: |
|
|
|
msg = "time data '{}' does not match any format".format(time_str) |
|
|
|
msg = "time data '{}' does not match any format".format(time_str) |
|
|
|
raise ValueError(msg) |
|
|
|
raise ValueError(msg) |
|
|
|
|
|
|
|
return time_as_timedelta(time_obj) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def time_as_timedelta(time_object): |
|
|
|
|
|
|
|
''' converts a time object to a timedelta ''' |
|
|
|
return timedelta( |
|
|
|
return timedelta( |
|
|
|
hours=time_obj.hour, |
|
|
|
hours=time_object.hour, |
|
|
|
minutes=time_obj.minute, |
|
|
|
minutes=time_object.minute, |
|
|
|
seconds=time_obj.second, |
|
|
|
seconds=time_object.second, |
|
|
|
microseconds=time_obj.microsecond |
|
|
|
microseconds=time_object.microsecond |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_command(command, available_commands): |
|
|
|
def parse_command(command, available_commands): |
|
|
|
''' parses a string and checks if it is a valid command |
|
|
|
''' parses a string and checks if it is a valid command |
|
|
|
|
|
|
|
|
|
|
|