Example #1
0
    def __init__(self,
                 configFile,
                 logDir,
                 logScheme='?',
                 bufferSize=4000,
                 startTimeFromFilepathFun=None):
        self.logDir = logDir
        conf = configLoader.load_confDict(configFile)

        if logScheme == '?':
            logScheme = self.detect_logScheme(conf)
            print("Detected logFile scheme:", logScheme)
        self.logScheme = logScheme
        self.conf = conf[logScheme]
        self.columns = collections.OrderedDict()
        self.units = collections.OrderedDict()
        for qualifier in ["essential", "optional"]:
            if not qualifier + "Columns" in conf.keys():
                continue
            for key in conf[qualifier + "Columns"][logScheme].keys():
                self.columns[key] = conf[qualifier + "Columns"][logScheme][key]
                self.units[key] = conf[qualifier + "Columns"]["units"][key]

        self.current = None
        self.dataBuffer = None
        self.lastTime = 0
        self.bufferSize = bufferSize

        self.startTimeFromFilepathFun = startTimeFromFilepathFun

        sys.stdout.write("Filling data buffer...")
        self.fill_dataBuffer()
        sys.stdout.write("done!\n")
Example #2
0
    def __init__(self, master, conf, *args, **kwargs):

        if not type(conf) is dict:
            conf = configLoader.load_confDict(conf)

        self.valveReader = LogFileReader.Reader(conf["valveLogDescriptor"],
                                                conf["valveLogPath"])
        super(ValvePicarroFrame, self).__init__(master, conf, *args, **kwargs)
Example #3
0
    def refresh_configuration(self):

        freshConf = configLoader.load_confDict(self.conf["confFile"])
        for key in freshConf.keys():
            if key in [
                    "autoSwitchEnable", "autoSwitchCooldown",
                    "H2O_yellowAlert", "H2O_redAlert"
            ]:
                self.conf[key] = freshConf[key]
Example #4
0
    def refresh_configuration(self):

        # step 1: reload conf for the valve controller
        super(ValveControlFrame, self).refresh_configuration()

        # step 2: reload conf for the flow controller
        freshFlowConf = configLoader.load_confDict(
            self.metaController.flow.conf["confFile"])
        for key in freshFlowConf["probeType"].keys():
            self.metaController.flow.conf["probeType"][key] = freshFlowConf[
                "probeType"][key]

        self.metaController.flow.fc.set_flowCalibration(
            freshFlowConf["calibration"])
Example #5
0
    def refresh_configuration(self):

        activeSlot = self.conf["ID"][self.activeID]["slot"]

        self.conf = check_valveCfg(
            configLoader.load_confDict(self.conf["confFile"]))

        self.valveDict = self.fill_buttonFrame()
        self.valveSequence = self.fill_sequenceButtonFrame()

        # these lines take care of cases where the previously active slot has been given to a new ID
        for ID in self.valveDict.keys():
            if '%d#%d' % (self.valveDict[ID].box,
                          self.valveDict[ID].slot) == activeSlot:
                self.activeID = ID
            self.valveDict[ID].stateVar = self.conf["ID"][ID]["state"] > 0

        self.update_valveButtons()
Example #6
0
    def __init__(self,
                 master,
                 vc,
                 valveConfigFile="../config/valve.cfg",
                 *args,
                 **kwargs):
        super(ValveControlFrame, self).__init__(master, *args, **kwargs)

        self.master = master
        self.vc = vc

        self.switchCode = const.SWITCH_START

        self.activeID = ""
        self.sequencePosition = -1
        self.flowMode = "measure"
        self.sequMode = "inactive"
        self.startTime = 0

        self.conf = check_valveCfg(configLoader.load_confDict(valveConfigFile))

        # ----- prepare valve log file ----

        parActiveValve = DataBuffer.Parameter(name="ID", unit="active valve")
        parMeasurement = DataBuffer.Parameter(name="measurement", unit="state")
        parSwitchCode = DataBuffer.Parameter(name = "switchCode", unit = "%d = manual | %d = timeout | %d = optimal | %d = alert"\
                                                                          %(const.SWITCH_MANUAL, const.SWITCH_TIMEOUT,
                                                                            const.SWITCH_OPTIMUM, const.SWITCH_ALERT))

        self.valveBuffer = DataBuffer.Buffer(
            100,
            self.conf["logFile"],
            parameters=[parActiveValve, parMeasurement, parSwitchCode])

        #--------------------------------------------------------------
        if not vc.check_status():
            self.infoFrame = tk.Frame(master)
            self.infoFrame.place(relheight=1, relwidth=1, x=0, y=0)
            self.infoFrame.config(bg="#fbb")
            tk.Button(
                self.infoFrame,
                command=self.hide_infoFrame,
                text=
                "No valve controller connected\n Click to proceed without functional valve controller"
            ).pack(side=tk.TOP)

        # create basic frames for layout
        self.buttonFrame = tk.Frame(self)
        self.buttonFrame.grid(row=0, column=0, sticky="nsew")

        self.rightFrame = tk.Frame(self)
        self.rightFrame.grid(row=0, column=1, sticky="nsew")

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=2)

        # ---- right frame (mainly valve sequence)------------- -----------

        self.rightFrame.rowconfigure(0, weight=0)
        self.rightFrame.rowconfigure(1, weight=5)
        self.rightFrame.columnconfigure(0, weight=1)

        self.upperRightFrame = tk.Frame(self.rightFrame)
        self.upperRightFrame.grid(row=0, column=0, sticky="nsew")
        self.upperRightFrame.rowconfigure(0, weight=1)
        self.upperRightFrame.columnconfigure(0, weight=1)
        self.upperRightFrame.columnconfigure(1, weight=3)
        self.upperRightFrame.columnconfigure(2, weight=1)

        self.lowerRightFrame = tk.Frame(self.rightFrame)
        self.lowerRightFrame.grid(row=1, column=0, sticky="nsew")
        self.lowerRightFrame.rowconfigure(0, weight=1)
        self.lowerRightFrame.columnconfigure(0, weight=0)
        self.lowerRightFrame.columnconfigure(1, weight=1)

        self.progressFrame = tk.Frame(self.lowerRightFrame)
        self.progressFrame.grid(row=0, column=0, sticky="nsew")

        self.sequenceFrame = tk.Frame(self.lowerRightFrame)
        self.sequenceFrame.grid(row=0, column=1, sticky="nsew")
        self.sequenceFrame.rowconfigure(1, weight=1)
        self.sequenceFrame.columnconfigure(0, weight=1)

        self.sequenceControlFrame = tk.Frame(self.sequenceFrame)
        self.sequenceControlFrame.grid(row=0, column=0, sticky="nsew")
        self.sequenceControlFrame.columnconfigure(0, weight=1)
        self.sequenceControlFrame.columnconfigure(1, weight=2)

        self.sequenceButtonFrame = tk.Frame(self.sequenceFrame)
        self.sequenceButtonFrame.grid(row=1, column=0, sticky="nsew")

        # ------------ create valve control buttons -------------------
        self.valveDict = self.fill_buttonFrame()

        #-------- schedule, status and refresh -----------------------------
        self._scheduleButtonImage = tk.PhotoImage(file="../images/time_24.gif")
        self.scheduleButton = tk.Button(self.upperRightFrame,
                                        text="Schedule",
                                        image=self._scheduleButtonImage,
                                        command=self.schedule,
                                        width=24)
        self.scheduleButton.grid(row=0, column=0, sticky="nsew")
        ExtraWidgets.ToolTip(self.scheduleButton, u"To be implemented...")

        self.extraLabel = tk.Label(self.upperRightFrame,
                                   text="~~~~~~~~~~~",
                                   bg='#ddd')
        self.extraLabel.grid(row=0, column=1, sticky='nsew')
        self.extraLabel.bind("<Button-1>", self.extraLabel_click)

        self._refreshButtonImage = tk.PhotoImage(
            file="../images/refresh_16.gif")
        self.refreshButton = tk.Button(self.upperRightFrame,
                                       text="Refresh",
                                       image=self._refreshButtonImage,
                                       command=self.refresh_configuration)
        self.refreshButton.grid(row=0, column=2, sticky="nsew")
        ExtraWidgets.ToolTip(self.refreshButton, u"Reload flow profiles (from flow.cfg) and H\u2082O thresholds (from valve.cfg)\n"+\
                                                  "Changing the logfile path requires a restart")

        #-------- progress bars ------------------------------------------

        self.progBars = {}

        for mode, side, anchor in [("flush", 'bottom', 'n'),
                                   ("measure", 'top', 's')]:
            style = ttk.Style()
            style.configure("%s.Vertical.TProgressbar" % mode,
                            background=colors[mode])
            progBar = ttk.Progressbar(self.progressFrame,
                                      style="%s.Vertical.TProgressbar" % mode,
                                      orient=tk.VERTICAL,
                                      maximum=50,
                                      mode='determinate')
            label = tk.Label(progBar,
                             text=u"\u221e",
                             bg=colors[mode],
                             wraplength=1)
            label.place(relx=0.2, rely=0.5)
            progBar.pack(side=side, anchor=anchor, expand=2, fill=tk.BOTH)

            self.progBars[mode] = {"bar": progBar, "label": label}

        #----- sequence buttons --------------------------------------

        self.valveSequence = self.fill_sequenceButtonFrame()

        #------ sequence control buttons--------------------------------
        self._sequenceButtonImages = []
        for name in ["start_32", "stop_32", "next_32", "hourglass_32"]:
            try:
                image = tk.PhotoImage(file="../images/" + name + ".gif")
            except:
                image = None
            self._sequenceButtonImages.append(image)

        buttonFont = tkFont.Font(family="Sans", weight="bold")
        self.sequenceButton = tk.Button(self.sequenceControlFrame,
                                        command=self.toggle_sequence,
                                        text="start\nsequence",
                                        font=buttonFont,
                                        image=self._sequenceButtonImages[0])

        self.sequenceButton_skip = tk.Button(
            self.sequenceControlFrame,
            command=lambda: self.continueSequence(skip=True),
            text="start\nsequence",
            font=buttonFont,
            image=self._sequenceButtonImages[2])

        self.sequenceButton.grid(row=0, column=0, sticky="nsew")
        self.sequenceButton_skip.grid(row=0, column=1, sticky="nsew")

        ExtraWidgets.ToolTip(
            self.sequenceButton,
            text=
            "Start/Stop the valve sequence\nThe seuquence goes from left to right and from top to bottom"
        )
        ExtraWidgets.ToolTip(
            self.sequenceButton_skip,
            text=
            "Skip current valve and continue with the next one in the sequence"
        )

        colors["neutralButton"] = self.sequenceButton.cget("bg")

        self.set_probeProfile()

        self._job = None
        self.sequencePaused = False

        print("Giving the valve controller some time...")
        self.after(2500, self.startup)
Example #7
0
from tkinter import font as tkFont
import datetime
import time
import os
import math
import collections
import gc

import PlotCanvas
import ExtraWidgets
import DataBuffer
import configLoader
import support
import const

colors = configLoader.load_confDict("../config/default/colors.cfg")

MAX_VALVES_PER_COLUMN = const.MAX_VALVES_PER_COLUMN


def check_valveCfg(cfg):
    # make sure that a group and state is assigned (even if not specified in cfg file)
    for ID in cfg["ID"].keys():
        if not "group" in cfg["ID"][ID].keys():
            cfg["ID"][ID]["group"] = "A"

        if not "state" in cfg["ID"][ID].keys():
            cfg["ID"][ID]["state"] = 1

    if not "sequence" in cfg.keys():
        cfg["sequence"] = [
Example #8
0
    def __init__(self, master, conf, *args, **kwargs):

        super(PicarroFrame, self).__init__(master, *args, **kwargs)

        self.master = master

        if type(conf) is dict:
            self.conf = conf
        else:
            self.conf = configLoader.load_confDict(confFile)

        # try to locate the picarro log dir
        if type(conf["rawLogSearchPaths"]) is list:
            for entry in conf["rawLogSearchPaths"]:
                if os.path.exists(entry):
                    logDir = entry
                    break
        else:
            logDir = conf["rawLogSearchPaths"]

        # initialize the picarro log file reader
        self.reader = LogFileReader.Reader(
            conf["logDescriptor"],
            logDir,
            bufferSize=int(conf["bufferSize"]),
            startTimeFromFilepathFun=startTimeFromFilepathFun)

        self.parCanvas = []
        self.parListboxLabel = []
        self.statLabels = []
        self.recentStats = None
        self.conf = conf

        self.current = collections.OrderedDict()
        for p in self.conf["plotPars"]:
            self.current[p] = 0

        self.currentSelection = None
        self.latestInfo = None

        self.currentRecord = 0

        #------------------------------

        self.canvasHolders = collections.OrderedDict()

        dummySummary = summary([0, 1, 2, 3, 4, 5])

        for i, parName in enumerate(self.conf["plotPars"]):

            x = tk.Frame(self)
            x.grid(row=i, column=0, sticky='nsew', pady=0)
            self.rowconfigure(i, weight=1)

            x.columnconfigure(0, weight=1)
            x.columnconfigure(1, weight=1)

            self.parCanvas.append(
                PlotCanvas.PlotCanvas(x,
                                      plotRangeX=[0, 20],
                                      plotRangeY=[0, 20],
                                      marginX=60,
                                      marginY=17,
                                      axes=True,
                                      bg="white",
                                      selectionHandler=self.change_selection,
                                      height=117,
                                      width=600))

            self.parCanvas[i].grid(row=0,
                                   column=0,
                                   rowspan=len(dummySummary.keys()) + 2,
                                   sticky='nsew')
            #x.rowconfigure(0, weight=1)

            self.parListboxLabel.append(
                ExtraWidgets.ListboxLabel(x, self.reader.dataBuffer.keys(), i))
            self.parListboxLabel[i].grid(row=1, column=1, sticky='we')

            tk.Label(x, text='').grid(row=4,
                                      column=1)  # dummy label for spacing

            labelDict = collections.OrderedDict()
            for n, key in enumerate(dummySummary.keys()):
                if key.startswith("_"): continue
                labelDict[key] = tk.Label(x, text=key)
                labelDict[key].grid(row=n + 2, column=1, sticky="nsew")
                x.rowconfigure(2 * n, weight=1)
                x.rowconfigure(2 * n + 1, weight=1)

            self.statLabels.append(labelDict)

            self.canvasHolders[parName] = x

        self.bind("<Configure>", self.on_resize)

        #----------

        self._buttonImages = collections.OrderedDict()
        for name in ["start_24", "pause_24", "refresh_16"]:
            try:
                image = tk.PhotoImage(file="../images/" + name + ".gif")
            except:
                image = None
            self._buttonImages[name] = image

        refreshButton = tk.Button(self.canvasHolders[parName],
                                  text="Reload",
                                  command=self.reload_configuration,
                                  image=self._buttonImages["refresh_16"])
        refreshButton.place(rely=1.0, relx=1.0, x=0, y=0, anchor=tk.SE)
        ExtraWidgets.ToolTip(
            refreshButton, text="Reload evaluation specs\n(from piccaro.cfg)")

        self.pauseButton = tk.Button(self.canvasHolders[parName],
                                     text="Reload",
                                     command=self.toggle_plotState,
                                     image=self._buttonImages["pause_24"])
        self.pauseButton.place(rely=1., relx=1.0, x=-40, y=0, anchor=tk.SE)
        ExtraWidgets.ToolTip(self.pauseButton, text="Pause/Resume plotting")
        self.do_plots = True

        #----------
        self.master.bind("<KeyPress>", self.keydown)
        self.maxZoomOutMinutes = self.conf["plotMinutes"]
        self.lastPlotRange = [time.time() - 60, time.time()]
        #---------

        self.update()
Example #9
0
 def reload_configuration(self):
     freshConf = configLoader.load_confDict(self.conf["confFile"])
     self.conf = freshConf.copy()
Example #10
0
    def __init__(self,
                 master,
                 fc,
                 flowConfigFile="../config/flow.cfg",
                 *args,
                 **kwargs):
        super(FlowControlFrame, self).__init__(master, *args, **kwargs)

        self.fc = fc
        self.status = -1
        self.master = master
        self.master.grid_columnconfigure(0, weight=1)
        self.master.grid_rowconfigure(0, weight=1)

        self.isFlushing = True
        self.isCycling = False
        self.cycleStartTime = time.time()
        self.job = None

        self.conf = configLoader.load_confDict(flowConfigFile)
        self.profiles = [
            self.conf["profile"][key] for key in self.conf["profile"].keys()
        ]

        if not self.conf["logfile"]:
            logfilePath = None

        #self.fc.apply_calibration(configLoader.load_confDict("../config/flow.cal"))

        #----------- preapre the dataBuffer (and logfile) ----------
        rD = self.conf["relevantDifference"]
        parList = [
            DataBuffer.Parameter(name="flowValueA",
                                 unit="mL/min",
                                 relevantDifference=rD),
            DataBuffer.Parameter(name="flowValueB",
                                 unit="mL/min",
                                 relevantDifference=rD),
            DataBuffer.Parameter(name="targetValueA",
                                 unit="mL/min",
                                 relevantDifference=0),
            DataBuffer.Parameter(name="targetValueB",
                                 unit="mL/min",
                                 relevantDifference=0)
        ]

        if "logfile" in self.conf.keys():
            logfile = self.conf["logfile"]
        else:
            None

        self.dataBuffer = DataBuffer.Buffer(int(self.conf["bufferSize"]),
                                            logfile,
                                            parList,
                                            flushChunk=20)

        #----left frame: controls and labels----------------
        self.font = tkFont.Font(family="Sans", size=11, weight="bold")
        self.leftFrame = tk.Frame(self, width=100)
        self.leftFrame.pack(side=tk.LEFT, fill=tk.Y)

        for n in range(4):
            self.leftFrame.grid_rowconfigure(n, weight=n > 1)

        tk.Label(self.leftFrame, text="flow [mL/min]",
                 font=self.font).grid(row=0,
                                      column=1,
                                      columnspan=3,
                                      sticky="nsew")
        tk.Label(self.leftFrame, text="A", font=self.font,
                 bg=colors["fcA"]).grid(row=1,
                                        column=2,
                                        columnspan=1,
                                        sticky="nsew")
        tk.Label(self.leftFrame, text="B", font=self.font,
                 bg=colors["fcB"]).grid(row=1,
                                        column=3,
                                        columnspan=1,
                                        sticky="nsew")

        self.button_flush = tk.Button(self.leftFrame,
                                      command=self.toggle_mode,
                                      text="flush",
                                      font=self.font,
                                      wraplength=1,
                                      relief=tk.SUNKEN,
                                      bg=colors["active"])
        self.button_flush.grid(row=3, column=1, sticky="nsew")
        self.button_measure = tk.Button(self.leftFrame,
                                        command=self.toggle_mode,
                                        text="measure",
                                        font=self.font,
                                        wraplength=1,
                                        relief=tk.RAISED)
        self.button_measure.grid(row=2, column=1, sticky="nsew")
        colors["neutralButton"] = self.button_measure.cget("bg")

        self.flushScaleA = tk.Scale(self.leftFrame,
                                    from_=fc.maxFlowA,
                                    to=0,
                                    orient=tk.VERTICAL,
                                    length=50,
                                    bg=colors["flush"])
        self.flushScaleA.grid(row=3, column=2, sticky="nsew")
        self.flushScaleA.set(self.profiles[0]["fRateA"])
        self.flushScaleA.bind("<ButtonRelease-1>", self.changeFlowRate)

        self.measureScaleA = tk.Scale(self.leftFrame,
                                      from_=fc.maxFlowA,
                                      to=0,
                                      orient=tk.VERTICAL,
                                      length=50,
                                      bg=colors["measure"])
        self.measureScaleA.grid(row=2, column=2, sticky="nsew")
        self.measureScaleA.set(self.profiles[0]["mRateA"])
        self.measureScaleA.bind("<ButtonRelease-1>", self.changeFlowRate)

        self.flushScaleB = tk.Scale(self.leftFrame,
                                    from_=fc.maxFlowB,
                                    to=0,
                                    orient=tk.VERTICAL,
                                    length=50,
                                    bg=colors["flush"])
        self.flushScaleB.grid(row=3, column=3, sticky="nsew")
        self.flushScaleB.set(self.profiles[0]["fRateB"])
        self.flushScaleB.bind("<ButtonRelease-1>", self.changeFlowRate)

        self.measureScaleB = tk.Scale(self.leftFrame,
                                      from_=fc.maxFlowB,
                                      to=0,
                                      orient=tk.VERTICAL,
                                      length=50,
                                      bg=colors["measure"])
        self.measureScaleB.grid(row=2, column=3, sticky="nsew")
        self.measureScaleB.set(self.profiles[0]["mRateB"])
        self.measureScaleB.bind("<ButtonRelease-1>", self.changeFlowRate)

        #------ right frame: plot canvas ------
        self.plotCanvas = PlotCanvas.PlotCanvas(self,
                                                plotRangeX=[0, 20],
                                                plotRangeY=[0, 50],
                                                axes=True,
                                                bg="white",
                                                marginX=50,
                                                marginY=25,
                                                height=300,
                                                width=400)
        self.plotCanvas.create_text(400,
                                    50,
                                    text="waiting for connection...",
                                    font=tkFont.Font(size=20),
                                    tags="initial")

        self.plotCanvas.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)

        #-------------------

        self.bind("<Configure>", self.on_resize)

        self.changeFlowRate()

        self.update()
        self.after(5000, self.after_startup)
Example #11
0
import tkinter as tk
from tkinter import font as tkFont
import datetime
import time
import os

import PlotCanvas
import DataBuffer
import configLoader

colors = configLoader.load_confDict("../config/default/colors.cfg")


class FlowControlFrame(tk.Frame):
    def __init__(self,
                 master,
                 fc,
                 flowConfigFile="../config/flow.cfg",
                 *args,
                 **kwargs):
        super(FlowControlFrame, self).__init__(master, *args, **kwargs)

        self.fc = fc
        self.status = -1
        self.master = master
        self.master.grid_columnconfigure(0, weight=1)
        self.master.grid_rowconfigure(0, weight=1)

        self.isFlushing = True
        self.isCycling = False
        self.cycleStartTime = time.time()
Example #12
0
    def __init__(self,
                 master,
                 vc,
                 valveConfigFile="../config/valve.cfg",
                 *args,
                 **kwargs):
        super(ValveControlFrame, self).__init__(master, *args, **kwargs)

        self.master = master
        self.vc = vc

        self.switchCodeDict = {
            "startup": 0,
            "manual": 1,
            "timeout": 2,
            "optimal": 3,
            "alert": 4
        }
        self.switchCode = 0

        self.activeID = ""
        self.sequencePosition = -1
        self.flowMode = "measure"
        self.sequMode = "inactive"
        self.startTime = 0

        self.conf = configLoader.load_confDict(valveConfigFile)

        # make sure that a group and state is assigned (even if not specified in cfg file)
        for ID in self.conf["ID"].keys():
            if not "group" in self.conf["ID"][ID].keys():
                self.conf["ID"][ID]["group"] = "A"

            if not "state" in self.conf["ID"][ID].keys():
                self.conf["ID"][ID]["state"] = 1

        # ----- prepare valve log file ----

        parActiveValve = DataBuffer.Parameter(name="ID", unit="active valve")
        parMeasurement = DataBuffer.Parameter(name="measurement", unit="state")
        parSwitchCode = DataBuffer.Parameter(
            name="switchCode",
            unit="0 = manual | 1 = timeout | 2 = optimal | 3 = alert")

        self.valveBuffer = DataBuffer.Buffer(
            100,
            self.conf["logFile"],
            parameters=[parActiveValve, parMeasurement, parSwitchCode])

        #--------------------------------------------------------------
        if not vc.check_status():
            self.infoFrame = tk.Frame(master)
            self.infoFrame.place(relheight=1, relwidth=1, x=0, y=0)
            self.infoFrame.config(bg="#fbb")
            tk.Button(
                self.infoFrame,
                command=self.hide_infoFrame,
                text=
                "No valve controller connected\n Click to proceed without functional valve controller"
            ).pack(side=tk.TOP)

        if not "sequence" in self.conf.keys():
            self.conf["sequence"] = [
                self.conf["ID"][key]["name"]
                for key in self.conf["valve"].keys()
            ]

        # create basic frames for layout
        self.buttonFrame = tk.Frame(self)
        self.buttonFrame.grid(row=0, column=0, sticky="nsew")

        self.rightFrame = tk.Frame(self)
        self.rightFrame.grid(row=0, column=1, sticky="nsew")

        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=2)

        # ---- right frame (mainly valve sequence)------------- -----------

        self.rightFrame.rowconfigure(0, weight=0)
        self.rightFrame.rowconfigure(1, weight=5)
        self.rightFrame.columnconfigure(0, weight=1)

        self.upperRightFrame = tk.Frame(self.rightFrame)
        self.upperRightFrame.grid(row=0, column=0, sticky="nsew")
        self.upperRightFrame.rowconfigure(0, weight=1)
        self.upperRightFrame.columnconfigure(0, weight=1)
        self.upperRightFrame.columnconfigure(1, weight=3)
        self.upperRightFrame.columnconfigure(2, weight=1)

        self.lowerRightFrame = tk.Frame(self.rightFrame)
        self.lowerRightFrame.grid(row=1, column=0, sticky="nsew")
        self.lowerRightFrame.rowconfigure(0, weight=1)
        self.lowerRightFrame.columnconfigure(0, weight=0)
        self.lowerRightFrame.columnconfigure(1, weight=1)

        self.progressFrame = tk.Frame(self.lowerRightFrame)
        self.progressFrame.grid(row=0, column=0, sticky="nsew")

        self.sequenceFrame = tk.Frame(self.lowerRightFrame)
        self.sequenceFrame.grid(row=0, column=1, sticky="nsew")
        self.sequenceFrame.rowconfigure(1, weight=1)
        self.sequenceFrame.columnconfigure(0, weight=1)

        self.sequenceControlFrame = tk.Frame(self.sequenceFrame)
        self.sequenceControlFrame.grid(row=0, column=0, sticky="nsew")
        self.sequenceControlFrame.columnconfigure(0, weight=1)
        self.sequenceControlFrame.columnconfigure(1, weight=2)

        self.sequenceButtonFrame = tk.Frame(self.sequenceFrame)
        self.sequenceButtonFrame.grid(row=1, column=0, sticky="nsew")

        # ------------ create valve control buttons -------------------
        self.valveDict = collections.OrderedDict()

        N = len(self.conf["ID"].keys())
        columnCount = math.ceil(N / maxValvesPerColumn)
        rowCount = math.ceil(N / columnCount)

        for i, ID in enumerate(self.conf["ID"].keys()):
            button = tk.Button(self.buttonFrame,
                               command=lambda j=i: self.valveButton_click(j),
                               font=tkFont.Font(family="Sans",
                                                size=9,
                                                weight="bold"),
                               text=ID,
                               bg=colors["group_" +
                                         self.conf["ID"][ID]["group"]],
                               disabledforeground="#866")
            button.bind('<Button-3>', self.rightClick)

            stateVar = tk.IntVar()
            checkbox = tk.Checkbutton(self.buttonFrame,
                                      text="",
                                      variable=stateVar,
                                      command=self.update_valveButtons,
                                      relief=tk.FLAT)

            self.valveDict[ID] = Valve(ID, self.conf["ID"][ID]["slot"],
                                       self.conf["ID"][ID]["profile"], button,
                                       checkbox, stateVar,
                                       self.conf["ID"][ID]["group"])

            row = math.floor(i / columnCount)
            column = i - math.floor(row * columnCount)
            self.valveDict[ID].grid(row=row, column=column)
            self.buttonFrame.rowconfigure(row, weight=1)
            self.buttonFrame.columnconfigure(column, weight=1)

        #-------- schedule, status and refresh -----------------------------
        self._scheduleButtonImage = tk.PhotoImage(file="../images/time_24.gif")
        self.scheduleButton = tk.Button(self.upperRightFrame,
                                        text="Schedule",
                                        image=self._scheduleButtonImage,
                                        command=self.schedule,
                                        width=24)
        self.scheduleButton.grid(row=0, column=0, sticky="nsew")
        ExtraWidgets.ToolTip(self.scheduleButton, u"To be implemented...")

        self.extraLabel = tk.Label(self.upperRightFrame,
                                   text="~~~~~~~~~~~",
                                   bg='#ddd')
        self.extraLabel.grid(row=0, column=1, sticky='nsew')
        self.extraLabel.bind("<Button-1>", self.extraLabel_click)

        self._refreshButtonImage = tk.PhotoImage(
            file="../images/refresh_16.gif")
        self.refreshButton = tk.Button(self.upperRightFrame,
                                       text="Refresh",
                                       image=self._refreshButtonImage,
                                       command=self.refresh_configuration)
        self.refreshButton.grid(row=0, column=2, sticky="nsew")
        ExtraWidgets.ToolTip(self.refreshButton, u"Reload flow profiles (from flow.cfg) and H\u2082O thresholds (from valve.cfg)\n"+\
                                                  "Changes to the valve sequence require a restart")

        #-------- progress bars ------------------------------------------

        self.progBars = {}

        for mode, side, anchor in [("flush", 'bottom', 'n'),
                                   ("measure", 'top', 's')]:
            style = ttk.Style()
            style.configure("%s.Vertical.TProgressbar" % mode,
                            background=colors[mode])
            progBar = ttk.Progressbar(self.progressFrame,
                                      style="%s.Vertical.TProgressbar" % mode,
                                      orient=tk.VERTICAL,
                                      maximum=50,
                                      mode='determinate')
            label = tk.Label(progBar,
                             text=u"\u221e",
                             bg=colors[mode],
                             wraplength=1)
            label.place(relx=0.2, rely=0.5)
            progBar.pack(side=side, anchor=anchor, expand=2, fill=tk.BOTH)

            self.progBars[mode] = {"bar": progBar, "label": label}

        #----- sequence buttons --------------------------------------

        N = len(self.conf["sequence"])
        columnCount = math.ceil(N / maxValvesPerColumn)
        rowCount = math.ceil(N / columnCount)

        #for col in range(columnCount):
        #    self.sequenceButtonFrame.columnconfigure(col, weight=1)

        #for row in range(rowCount):
        #    self.sequenceButtonFrame.rowconfigure(row, weight=1)

        self.valveSequence = []

        for i, ID in enumerate(self.conf["sequence"]):

            button = (tk.Button(
                self.sequenceButtonFrame,
                command=lambda j=i: self.sequenceButton_click(j),
                font=tkFont.Font(family="Sans", size=9, weight="bold"),
                text=ID,
                bg=colors["group_" + self.conf["ID"][ID]["group"]]))
            button.bind('<Button-3>', self.rightClick)

            stateVar = tk.IntVar()
            checkbox = tk.Checkbutton(self.sequenceButtonFrame,
                                      text="",
                                      variable=stateVar,
                                      command=self.update_valveButtons,
                                      relief=tk.FLAT)

            self.valveSequence.append(
                Valve(ID, self.conf["ID"][ID]["slot"],
                      self.conf["ID"][ID]["profile"], button, checkbox,
                      stateVar, self.conf["ID"][ID]["group"]))

            row = math.floor(i / columnCount)
            column = i - math.floor(row * columnCount)
            self.valveSequence[-1].grid(row=row, column=column)
            self.sequenceButtonFrame.rowconfigure(row, weight=1)
            self.sequenceButtonFrame.columnconfigure(column, weight=1)

        #------ sequence control buttons--------------------------------
        self._sequenceButtonImages = []
        for name in ["start_32", "stop_32", "next_32", "hourglass_32"]:
            try:
                image = tk.PhotoImage(file="../images/" + name + ".gif")
            except:
                image = None
            self._sequenceButtonImages.append(image)

        buttonFont = tkFont.Font(family="Sans", weight="bold")
        self.sequenceButton = tk.Button(self.sequenceControlFrame,
                                        command=self.toggle_sequence,
                                        text="start\nsequence",
                                        font=buttonFont,
                                        image=self._sequenceButtonImages[0])

        self.sequenceButton_skip = tk.Button(
            self.sequenceControlFrame,
            command=lambda: self.continueSequence(skip=True),
            text="start\nsequence",
            font=buttonFont,
            image=self._sequenceButtonImages[2])

        self.sequenceButton.grid(row=0, column=0, sticky="nsew")
        self.sequenceButton_skip.grid(row=0, column=1, sticky="nsew")

        ExtraWidgets.ToolTip(
            self.sequenceButton,
            text=
            "Start/Stop the valve sequence\nThe seuquence goes from left to right and from top to bottom"
        )
        ExtraWidgets.ToolTip(
            self.sequenceButton_skip,
            text=
            "Skip current valve and continue with the next one in the sequence"
        )

        colors["neutralButton"] = self.sequenceButton.cget("bg")

        self.set_probeProfile()

        self._job = None
        self.sequencePaused = False

        # give the val

        print("Giving the valve controller some time...")
        self.after(2500, self.startup)
Example #13
0
                                                       propagate=False)

    def on_resize(self, event):
        self.plotCanvas.on_resize(self.master.winfo_width() - 120,
                                  self.master.winfo_height() - 30)


class PicarroFrame(GUI_Picarro.ValvePicarroFrame):
    def broadcast(self, message):
        pass


if __name__ == "__main__":

    # load the flow calibration before initializing the hardware
    flowCalibration = configLoader.load_confDict(
        "../config/flow.cfg")["calibration"]

    # scan all ports to find the one, where the "IsWISaS_Controller" is connected
    #deviceDict, portDict = SerialDevices.scan_serialPorts(9600, "../temp/serial.cch")

    dInfo = SerialDevices.find_device("IsWISaS_Controller", [9600],
                                      cachePath="../temp/serial.cch")
    d = SerialDevices.IsWISaS_Controller(dInfo["port"], dInfo["baudRate"],
                                         flowCalibration)

    root = tk.Tk()
    root.title("IsWISaS2")
    root.geometry("%dx%d+%d+%d" % (1200, 850, 1, 0))

    tab_parent = ttk.Notebook(root)