def handle_on_off(controller, outlet, pin, targetstate):

    currentOutletState = GPIO.input(pin)

    # log any change
    if controller.AppPrefs.outletDict[outlet].enable_log == "True":
        if currentOutletState != targetstate:
            #defs_common.logtoconsole("I need to log this! " + outlet, fg="YELLOW", bg="BLUE", style="BRIGHT")
            # lets record 1 or 0 in the log
            if currentOutletState == PIN_ON:
                val = 1
            else:
                val = 0
            defs_common.logprobedata(outlet + "_", val)
            # lets record 1 or 0 in the log
            if targetstate == PIN_ON:
                val = 1
            else:
                val = 0
            defs_common.logprobedata(outlet + "_", val)
            defs_common.logtoconsole(
                "***Logged*** Outlet Change " + "[" + outlet + "] " +
                str(controller.AppPrefs.outletDict[outlet].outletname) +
                " = " + str(val),
                fg="CYAN",
                style="BRIGHT")
            controller.logger.info(
                "***Logged*** Outlet Change " + "[" + outlet + "] " +
                str(controller.AppPrefs.outletDict[outlet].outletname) +
                " = " + str(val))

    if targetstate == PIN_ON:
        GPIO.output(pin, False)
    elif targetstate == PIN_OFF:
        GPIO.output(pin, True)
Пример #2
0
    def initialize_logger(self, output_dir, output_file, loglevel_console,
                          loglevel_logfile):

        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)

        # check if log dir exists, if not create it
        if not os.path.exists(output_dir):
            defs_common.logtoconsole("Logfile directory not found")
            os.mkdir(output_dir)
            defs_common.logtoconsole("Logfile directory created: " +
                                     os.getcwd() + "/" + str(output_dir))

        # create console handler and set level to info
        self.handler = logging.StreamHandler()
        self.handler.setLevel(loglevel_console)
        self.formatter = logging.Formatter('%(asctime)s %(message)s')
        self.handler.setFormatter(self.formatter)
        self.logger.addHandler(self.handler)

        # create log file handler and set level to info
        self.handler = logging.handlers.RotatingFileHandler(os.path.join(
            output_dir, output_file),
                                                            maxBytes=2000000,
                                                            backupCount=5)
        self.handler.setLevel(loglevel_logfile)
        self.formatter = logging.Formatter(
            '%(asctime)s <%(levelname)s> [%(threadName)s:%(module)s] %(message)s'
        )
        self.handler.setFormatter(self.formatter)
        self.logger.addHandler(self.handler)
Пример #3
0
    def __init__(self, master):
        defs_common.logtoconsole("Initializing ProbeWidget...",
                                 fg="YELLOW",
                                 bg="MAGENTA",
                                 style="BRIGHT")
        #initialize the messaging queues
        self.connection = pika.BlockingConnection(
            pika.ConnectionParameters(host='localhost'))
        self.channel = self.connection.channel()
        result = self.channel.queue_declare(exclusive=True)
        self.callback_queue = result.method.queue

        self.channel.basic_consume(self.rpc_response,
                                   no_ack=True,
                                   queue=self.callback_queue)

        self.probeid = StringVar()
        self.name = StringVar()
        self.probetype = StringVar()
        self.probeval = StringVar()

        self.probeval.set("----")  # give a default value

        self.figprobe = Figure(figsize=(1, 1), dpi=100)
        self.aniprobe = self.figprobe.add_subplot(111, axisbg="gainsboro")
        self.probeframe = LabelFrame(master, text=self.name, relief=RAISED)
        self.probeframe.pack(fill=X, side=TOP)
        self.frame_probeval = LabelFrame(self.probeframe, relief=FLAT)
        self.frame_probeval.pack(side=LEFT)
        self.lbl_probeval = Label(self.frame_probeval,
                                  text="00.0",
                                  textvariable=self.probeval,
                                  relief=FLAT,
                                  font=("Helvetica", 44),
                                  padx=10)
        self.lbl_probeval.pack(side=TOP)
        self.lbl_probeSN = Label(self.frame_probeval,
                                 textvariable=self.probeid,
                                 padx=10)
        # self.lbl_probeSN.pack(side=TOP) # dont display this, but its used to match the probe values on update

        #set up mini plot
        #some definitions for the plots
        LARGE_FONT = ("Verdana", 12)
        style.use("ggplot")
        self.figprobe = Figure(figsize=(1, 1), dpi=100)
        self.figprobe.set_facecolor("gainsboro")
        self.aniprobe = self.figprobe.add_subplot(111, axisbg="gainsboro")
        self.canvasprobe = FigureCanvasTkAgg(self.figprobe, self.probeframe)
        self.canvasprobe.show()
        self.canvasprobe.get_tk_widget().pack(side=LEFT,
                                              fill=BOTH,
                                              expand=True)
        #canvasprobe.get_tk_widget().grid(padx=10, sticky=W, row=0, column=2, columnspan=2)

        ani = animation.FuncAnimation(self.figprobe,
                                      self.animate_probe,
                                      interval=300000)
Пример #4
0
    def __init__(self, parent, controller):
        defs_common.logtoconsole("Initializing Dashboard...", fg = "YELLOW", bg = "MAGENTA", style = "BRIGHT")
        tk.Frame.__init__(self,parent)

        #initialize the messaging queues      
        self.connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
        self.channel = self.connection.channel()
        
        result = self.channel.queue_declare(exclusive=True)
        self.callback_queue = result.method.queue

        self.channel.basic_consume(self.rpc_response, no_ack=True,
                                   queue=self.callback_queue)

        # create dictionary to hold assigned probes and outlets
        self.probeDict = {}
        self.outletDict = {}

        self.canvas = tk.Canvas(self, borderwidth=0)

        self.frame_master=Frame(self.canvas, relief=FLAT)
        self.frame_master.pack(side=LEFT, fill=BOTH)
        self.frame_left_column=LabelFrame(self.frame_master, relief = RAISED)
        self.frame_left_column.pack(side=LEFT, anchor=N, fill=Y)
        self.frame_mid_column=LabelFrame(self.frame_master, relief = RAISED)
        self.frame_mid_column.pack(side=LEFT, anchor=N, fill=Y)
        self.frame_right_column=LabelFrame(self.frame_master, relief = RAISED)
        self.frame_right_column.pack(side=LEFT, anchor=N)

        self.frameProbes = tk.Frame(self.frame_left_column, width=470)
        self.frameProbes.pack(side=TOP, anchor=N, fill=BOTH, expand=True)
        self.frameSpaceFrame = Frame(self.frame_left_column, width=470, height=1)
        self.frameSpaceFrame.pack(side=TOP)
        
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        
        self.canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill=BOTH, expand=True)

        self.canvas.create_window((4,4), window=self.frame_master, anchor="nw", 
                                  tags="self.frame_master")

        self.frameProbes.bind("<Configure>", self.onFrameConfigure)

##        logocanvas=Canvas(self.frame_right_column,width=250,height=250)
##        logocanvas.pack()
##
##        self.img=PhotoImage(file="images/reefberrypi_logo2.gif")
##        logocanvas.create_image(0,0,image=self.img, anchor=NW)

        #  add probe frames to show current data and mini graphs on the GUI
        self.readExistingProbes()
        # add the feed widget
        self.feedFrame = cls_FeedWidget.FeedWidget(self.frame_mid_column)
        # now add the outlets
        self.readOutlets()
Пример #5
0
 def uploadsettings(self, section, key, value):
     defs_common.logtoconsole("Request settings change: [" + str(section) +
                              "] [" + str(key) + "] = " + str(value))
     # request settings change on server
     request = {
         "rpc_req": "set_writeinifile",
         "section": str(section),
         "key": str(key),
         "value": str(value)
     }
     request = json.dumps(request)
     self.rpc_call(request, "rpc_queue")
Пример #6
0
    def __init__(self):

        defs_common.logtoconsole("Application Start",
                                 fg="WHITE",
                                 style="BRIGHT")
        self.threads = []
        self.queue = queue.Queue()

        self.threadlock = threading.Lock()

        self.INFLUXDB_HOST = "192.168.1.217"
        self.INFLUXDB_PORT = "8086"
        self.INFLUXDB_DBNAME = "reefberrypi"

        self.MQTT_BROKER_HOST = "192.168.1.217"
        self.MQTT_USERNAME = "******"
        self.MQTT_PASSWORD = "******"

        LOG_FILEDIR = "logs"
        LOG_FILENAME = "RBP_controller.log"
        LOGLEVEL_CONSOLE = logging.INFO  # DEBUG, INFO, ERROR
        LOGLEVEL_LOGFILE = logging.INFO

        self.initialize_logger(LOG_FILEDIR, LOG_FILENAME, LOGLEVEL_CONSOLE,
                               LOGLEVEL_LOGFILE)

        self.logger.info("Reefberry Pi controller startup...")

        # read prefs
        self.AppPrefs = cls_Preferences.AppPrefs(self)
        self.refreshPrefs = False

        # set up the GPIO
        GPIO_config.initGPIO()

        # dht11 temperature and humidity sensor
        self.dht_sensor = dht11.DHT11(pin=GPIO_config.dht11)

        # connect to InfluxDB
        self.InfluxDBclient = self.ConnectInfluxDB(self.INFLUXDB_HOST,
                                                   self.INFLUXDB_PORT,
                                                   self.INFLUXDB_DBNAME)

        # connect to MQTT broker
        # create new instance and assign the AppUID to it
        self.MQTTclient = mqtt.Client(self.AppPrefs.appuid)
        # self.MQTTclient.on_message=on_message #attach function to callback
        self.MQTTclient.username_pw_set(self.MQTT_USERNAME, self.MQTT_PASSWORD)
        self.MQTTclient.connect(self.MQTT_BROKER_HOST)
        self.MQTTclient.subscribe("reefberrypi/demo")

        self.threadManager()
Пример #7
0
    def getProbeList(self):
        defs_common.logtoconsole("Request probe list for outlet control")
        # get setting value from server
        request = {
            "rpc_req": "get_probelist",
        }
        request = json.dumps(request)
        val = self.rpc_call(request, "rpc_queue")
        val = val.decode()
        val = json.loads(val)

        #print (val)

        return val
Пример #8
0
    def rpc_call(self, n, queue):
        self.response = None
        self.corr_id = str(uuid.uuid4())

        ##        print(str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + " RPC call: " + n
        ##              + " UID: " + self.corr_id)

        defs_common.logtoconsole(
            str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + " RPC call: " +
            n + " UID: " + self.corr_id,
            fg="GREEN",
            style="BRIGHT")

        if self.connection.is_open:
            defs_common.logtoconsole("Pika connection is OPEN")
        else:
            defs_common.logtoconsole("Pika connection is CLOSED")
            defs_common.logtoconsole("Reopen Pika connection")
            self.initializeConnection()

        self.channel.basic_publish(exchange='',
                                   routing_key=queue,
                                   properties=pika.BasicProperties(
                                       reply_to=self.callback_queue,
                                       correlation_id=self.corr_id,
                                       expiration="300000"),
                                   body=str(n))
        while self.response is None:
            self.connection.process_data_events()
        return self.response
Пример #9
0
    def getConnectedProbes(self):

        self.readExistingProbes()

        defs_common.logtoconsole(
            "Request list of connected temperature probes...")
        # get setting value from server
        request = {
            "rpc_req": "get_connectedtempprobes",
        }
        request = json.dumps(request)
        connectedtempprobes = self.controller.rpc_call(request, "rpc_queue")
        connectedtempprobes = connectedtempprobes.decode()
        connectedtempprobes = json.loads(connectedtempprobes)

        #print (connectedtempprobes)

        # we need to clear widget so we can refresh with current list
        # first grab current selection to it is still highlited after refresh
        selection = self.lst_probes.curselection()
        self.lst_probes.delete(0, END)
        addtolist = True
        newprobeID = ""
        for d in connectedtempprobes['tempprobelist']:
            newprobeid = d.split("/")[-1]
            for p in self.probeDict:
                if str(d.split("/")[-1]) == str(self.probeDict[p].probeid):
                    addtolist = False
                    break
                else:
                    addtolist = True
            if addtolist == True:
                self.lst_probes.insert(END, newprobeid)

        # set back to what was slected
        try:
            self.lst_probes.activate(selection)
            self.lst_probes.selection_set(selection)
        except:
            #print("Error selecting listbox index")
            pass

        # diable the add probe button if nothing left in the list
        if self.lst_probes.size() == 0:
            self.btn_assignprobe["state"] = DISABLED
        else:
            self.btn_assignprobe["state"] = NORMAL
Пример #10
0
    def sendKeepAlive(self):
        # periodically (like every 1 or 2 minutes) send a message to the exchange so it
        # knows this channel is still active and not closed due to inactivity
        defs_common.logtoconsole("send keep alive request: " + "PrefPage",
                                 fg="YELLOW",
                                 style="BRIGHT")
        request = {
            "rpc_req": "set_keepalive",
            "module": "PrefPage",
        }
        request = json.dumps(request)
        self.rpc_call(request, "rpc_queue")

        # every 2 minutes, send out a message on this channel so the exchange server knows
        # we are still alive and doesn't close our connection
        heartbeatThread = threading.Timer(120, self.sendKeepAlive)
        heartbeatThread.daemon = True
        heartbeatThread.start()
Пример #11
0
    def handle_RBPstatus(self, channel):
        result = channel.queue_declare(exclusive=True)
        queue_name = result.method.queue

        channel.queue_bind(exchange='rbp_currentstatus',
                           queue=queue_name)
        def callback(ch, method, properties, body):
            body = body.decode()
            #print(" [x] %r" % body)
            self.queue.put(body)


        channel.basic_consume(callback,
                              queue=queue_name,
                              no_ack=True)

        defs_common.logtoconsole("Listening for status updates on exchange: rbp_currentstatus")
        channel.start_consuming()
Пример #12
0
        def select_feed_mode(mode):
            #DefClr = app.cget("bg")
            #btn_feedA.configure(bg=DefClr)
            #btn_feedB.configure(bg=DefClr)
            #btn_feedC.configure(bg=DefClr)
            #btn_feedD.configure(bg=DefClr)
            #btn_feedCancel.configure(bg=DefClr)

            defs_common.logtoconsole("Feed mode request: " + str(mode),
                                     fg="YELLOW",
                                     style="BRIGHT")

            # request outlet change on server
            request = {
                "rpc_req": "set_feedmode",
                "feedmode": str(mode),
            }
            request = json.dumps(request)
            self.rpc_call(request, "rpc_queue")
Пример #13
0
    def downloadsettings(self, section, key, defaultval):
        defs_common.logtoconsole("Request settings vaue: [" + str(section) +
                                 "] [" + str(key) + "]")
        # get setting value from server
        request = {
            "rpc_req": "get_readinifile",
            "section": str(section),
            "key": str(key),
            "defaultval": str(defaultval)
        }
        request = json.dumps(request)
        val = self.rpc_call(request, "rpc_queue")
        val = val.decode()
        val = json.loads(val)
        val = val.get("readinifile")

        #print (val)

        return val
Пример #14
0
    def processIncoming(self):
        """Handle all messages currently in the queue, if any."""
        while self.queue.qsize(  ):
            try:
                msg = self.queue.get(0)
                # Check contents of message and do whatever is needed. As a
                # simple test, print it (in real life, you would
                # suitably update the GUI's display in a richer fashion).
                #defs_common.logtoconsole("processIncoming " + str(msg))
                msg = json.loads(msg)
                 
                for key in msg:
                    if key == "status_currentprobeval":
                        curID = str(msg["status_currentprobeval"]["probeid"])
                        curVal = str(msg["status_currentprobeval"]["probeval"])
                        curName = str(msg["status_currentprobeval"]["probename"])

                        if curID == "dht_h": #if this is a humidity value, tack on the % sign
                            curVal = str(curVal) + "%"
                        self.frames[cls_DashBoard.DashBoard].updateProbeVal(curID, curVal, curName)

                    if key == "status_currentoutletstate":    
                        #defs_common.logtoconsole(str(msg), fg="MAGENTA", bg="GREEN")
                        self.frames[cls_DashBoard.DashBoard].updateOutletStatus(str(msg["status_currentoutletstate"]["outletid"]),
                                                                                str(msg["status_currentoutletstate"]["outletname"]),
                                                                                str(msg["status_currentoutletstate"]["outletbus"]),
                                                                                str(msg["status_currentoutletstate"]["control_type"]),
                                                                                str(msg["status_currentoutletstate"]["button_state"]),
                                                                                str(msg["status_currentoutletstate"]["outletstate"]),
                                                                                str(msg["status_currentoutletstate"]["statusmsg"]))
                    if key == "status_feedmode":
                        defs_common.logtoconsole(str(msg), fg="MAGENTA", bg="GREEN")
                        feedmode = str(msg["status_feedmode"]["feedmode"])
                        timeremaining = str(msg["status_feedmode"]["timeremaining"])
                        self.frames[cls_DashBoard.DashBoard].feedFrame.updatefeedstatus(feedmode, timeremaining)
                        
                        
            except queue.Empty:
                # just on general principles, although we don't
                # expect this branch to be taken in this case
                pass
Пример #15
0
    def rpc_call(self, n, queue):
        self.response = None
        self.corr_id = str(uuid.uuid4())

##        print(str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + " RPC call: " + n
##              + " UID: " + self.corr_id)
        defs_common.logtoconsole("RPC call: " + n + " UID: " + self.corr_id, fg="GREEN", style="BRIGHT")
        
        self.channel.basic_publish(exchange='',
                                   routing_key=queue,
                                   properties=pika.BasicProperties(
                                         reply_to = self.callback_queue,
                                         correlation_id = self.corr_id,
                                         expiration="300000"),
                                   body=str(n))
        while self.response is None:
            self.connection.process_data_events(time_limit=20)
            # if timelimit in seconds is reached, and we don't get a response, lets break out of the loop
            # but we must handle NONE return on the caller
            break
        return self.response        
Пример #16
0
    def readExistingProbes(self):
        # create dictionary to hold assigned temperature probes
        # these are probes that are already saved in config file
        self.probeDict = {}
        self.probeDict.clear()

        # send the command back up to the controller to handle the request
        defs_common.logtoconsole("Request probe list for outlet control")
        # get setting value from server
        request = {
            "rpc_req": "get_probelist",
        }
        request = json.dumps(request)
        probelist = self.controller.rpc_call(request, "rpc_queue")
        probelist = probelist.decode()
        probelist = json.loads(probelist)

        for tempprobe in probelist['probelist']:
            if tempprobe.split("_")[0] == "ds18b20":
                probe = ProbeClass()
                probe.probeid = probelist['probelist'][tempprobe][
                    'probeid'].split("_")[1]
                probe.name = probelist['probelist'][tempprobe]['probename']
                self.probeDict[probe.probeid] = probe
Пример #17
0
    def select_outlet_state(self):
        defs_common.logtoconsole("outlet state change: " +
                                 str(self.outletid.get()) + " to " +
                                 str(self.button_state.get()),
                                 fg="YELLOW",
                                 style="BRIGHT")
        if self.button_state.get() == defs_common.OUTLET_OFF:
            self.statusmsg.set("OFF")
            self.lbl_outlet_status.config(foreground="RED")
            ##            self.channel.basic_publish(exchange='',
            ##                                  routing_key='outlet_change',
            ##                                  properties=pika.BasicProperties(expiration='30000'),
            ##                                  body=str(str(self.outletid.get()) + "," + "OFF"))
            ##                                  #body=str("int_outlet_1" + "," + "OFF"))

            # request outlet change on server
            request = {
                "rpc_req": "set_outletoperationmode",
                "bus": str(self.outletbus.get()),
                "outletnum": str(self.outletid.get().split("_")[2]),
                "opmode": "off"
            }
            request = json.dumps(request)
            self.rpc_call(request, "rpc_queue")

        elif self.button_state.get() == defs_common.OUTLET_AUTO:
            self.statusmsg.set("AUTO")
            self.lbl_outlet_status.config(foreground="DARK ORANGE")
            ##            self.channel.basic_publish(exchange='',
            ##                                  routing_key='outlet_change',
            ##                                  properties=pika.BasicProperties(expiration='30000'),
            ##                                  body=str(str(self.outletid.get()) + "," + "AUTO"))
            ##                                  #body=str("int_outlet_1" + "," + "AUTO"))
            request = {
                "rpc_req": "set_outletoperationmode",
                "bus": str(self.outletbus.get()),
                "outletnum": str(self.outletid.get().split("_")[2]),
                "opmode": "auto"
            }
            request = json.dumps(request)
            self.rpc_call(request, "rpc_queue")

        elif self.button_state.get() == defs_common.OUTLET_ON:
            self.statusmsg.set("ON")
            self.lbl_outlet_status.config(foreground="GREEN")
            ##            self.channel.basic_publish(exchange='',
            ##                                  routing_key='outlet_change',
            ##                                  properties=pika.BasicProperties(expiration='30000'),
            ##                                  body=str(str(self.outletid.get()) + "," + "ON"))
            ##                                  #body=str("int_outlet_1" + "," + "ON"))
            request = {
                "rpc_req": "set_outletoperationmode",
                "bus": str(self.outletbus.get()),
                "outletnum": str(self.outletid.get().split("_")[2]),
                "opmode": "on"
            }
            request = json.dumps(request)
            self.rpc_call(request, "rpc_queue")
        else:
            self.lbl_outlet_status.config(text="UNKNOWN", foreground="BLACK")


##        selection = "Select outlet option " + self.lbl_outlet_status.cget("text")
##        print(Fore.YELLOW + Style.BRIGHT + datetime.now().strftime("%Y-%m-%d %H:%M:%S") +
##          " " + selection + Style.RESET_ALL)
        self.outlet_freezeupdate.set(True)
        defs_common.logtoconsole("Freeze Update: " +
                                 str(self.outletid.get() + " " +
                                     str(self.outlet_freezeupdate.get())),
                                 fg="CYAN")
Пример #18
0
    def __init__(self, master):
        defs_common.logtoconsole("Initializing OutletWidget...",
                                 fg="YELLOW",
                                 bg="MAGENTA",
                                 style="BRIGHT")

        self.outletid = StringVar()  # id of this outlet ex: int_outlet_1
        self.outletname = StringVar()  # user defined name of outlet
        self.outletbus = StringVar()  # int or ext bus
        self.control_type = StringVar(
        )  # control scheme of outlet ex: skimmer, lights, always...
        self.button_state = IntVar(
        )  # button state ON (3), OFF (1), or AUTO (2)
        self.outletstate = StringVar()  # is the outlet currently on or off
        self.statusmsg = StringVar(
        )  # short status message to display above buttons

        self.outlet_freezeupdate = BooleanVar()

        # set initial value...
        self.statusmsg.set("waiting...")
        self.outlet_freezeupdate.set(True)

        self.initializeConnection()
        ##        #initialize the messaging queues
        ##        self.connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost', heartbeat_interval=5))
        ##        self.channel = self.connection.channel()
        ##
        ##        result = self.channel.queue_declare(exclusive=True)
        ##        self.callback_queue = result.method.queue
        ##
        ##        self.channel.basic_consume(self.rpc_response, no_ack=True,
        ##                                   queue=self.callback_queue)

        # frame for internal outlet 1 control
        self.frame_outlet = LabelFrame(master,
                                       text="waiting...",
                                       relief=RAISED)
        self.frame_outlet.pack(fill=X, side=TOP)
        self.frame_outlet_spacer = tk.LabelFrame(self.frame_outlet,
                                                 relief=tk.FLAT)
        self.frame_outlet_spacer.pack(fill=X, side=TOP)

        self.img_cfg16 = PhotoImage(file="images/settings-16.png")
        self.btn_cfg_outlet = Button(
            self.frame_outlet_spacer,
            text="edit",
            image=self.img_cfg16,
            relief=FLAT,
            command=lambda: self.configureOutlet(master))
        self.btn_cfg_outlet.pack(side=LEFT, anchor=W)

        self.lbl_outlet_status = Label(self.frame_outlet_spacer,
                                       text="waiting...",
                                       relief=FLAT,
                                       textvariable=self.statusmsg)
        self.lbl_outlet_status.pack(side=TOP, anchor=E)
        self.rdo_outlet_off = Radiobutton(self.frame_outlet,
                                          text="Off",
                                          variable=self.button_state,
                                          value=1,
                                          command=self.select_outlet_state,
                                          indicatoron=0)
        self.rdo_outlet_off.pack(side=LEFT, expand=1, fill=X)

        self.rdo_outlet_auto = Radiobutton(self.frame_outlet,
                                           text="Auto",
                                           variable=self.button_state,
                                           value=2,
                                           command=self.select_outlet_state,
                                           indicatoron=0)
        self.rdo_outlet_auto.pack(side=LEFT, expand=1, fill=X)

        self.rdo_outlet_on = Radiobutton(self.frame_outlet,
                                         text="On",
                                         variable=self.button_state,
                                         value=3,
                                         command=self.select_outlet_state,
                                         indicatoron=0)
        self.rdo_outlet_on.pack(side=LEFT, expand=1, fill=X)

        self.sendKeepAlive()
Пример #19
0
    def __init__(self, parent, controller, ChannelID, channelName):
        tk.Frame.__init__(self, parent)

        defs_common.logtoconsole("Initializing CalibPH...",
                                 fg="YELLOW",
                                 bg="MAGENTA",
                                 style="BRIGHT")

        self.controller = controller
        self.parent = parent
        self.ChannelID = ChannelID
        self.ChannelName = channelName

        # registering validation command
        #self.vldt_ifnum_cmd = (self.register(self.ValidateIfNum),'%s', '%S')

        self.isCalRunning = False
        self.calType = "none"
        self.calPoints = []
        self.currentDVlistCounter = 0
        self.currentDVlist = []

        strHeadLabel = "Channel " + str(self.ChannelID) + " [" + str(
            self.ChannelName) + "]"
        headlabel = tk.Label(self, text=strHeadLabel, font=LARGE_FONT)
        headlabel.grid(row=0, column=0, pady=10, sticky=W, columnspan=3)

        lbl_calPoint = headlabel = tk.Label(self, text="Cal Point")
        lbl_calPoint.grid(row=1, column=0, padx=10)
        lbl_refVal = headlabel = tk.Label(self, text="PH Reference")
        lbl_refVal.grid(row=1, column=1, padx=10)
        lbl_digVal = headlabel = tk.Label(self, text="Digital Value")
        lbl_digVal.grid(row=1, column=2, padx=10)

        # we want to underline the header, so:
        # clone the font, set the underline attribute,
        # and assign it to our widget
        f = font.Font(lbl_calPoint, lbl_calPoint.cget("font"))
        f.configure(underline=True)
        lbl_calPoint.configure(font=f)
        lbl_refVal.configure(font=f)
        lbl_digVal.configure(font=f)

        # read values from config file
        # Low Val
        lbl_pointLow = tk.Label(self, text="Low")
        lbl_pointLow.grid(row=2, column=0)
        lbl_phrefLow = tk.Label(self, text="4.0")
        lbl_phrefLow.grid(row=2, column=1)
        strval = "ch" + str(ChannelID) + "_ph_low"
        val = self.controller.controller.controller.controller.downloadsettings(
            "mcp3008", strval, "900")
        self.lbl_low_val = tk.Label(self, text=val)
        self.lbl_low_val.grid(row=2, column=2)
        btn_LowCalStart = Button(self,
                                 text="Start Low Calibration",
                                 command=lambda: self.startCalLoop('low'))
        btn_LowCalStart.grid(row=2, column=3, sticky=EW)
        # Med Val
        lbl_pointMed = tk.Label(self, text="Mid")
        lbl_pointMed.grid(row=3, column=0)
        lbl_phrefMed = tk.Label(self, text="7.0")
        lbl_phrefMed.grid(row=3, column=1)
        strval = "ch" + str(ChannelID) + "_ph_med"
        val = self.controller.controller.controller.controller.downloadsettings(
            "mcp3008", strval, "800")
        self.lbl_med_val = tk.Label(self, text=val)
        self.lbl_med_val.grid(row=3, column=2)
        btn_MedCalStart = Button(self,
                                 text="Start Mid Calibration",
                                 command=lambda: self.startCalLoop('med'))
        btn_MedCalStart.grid(row=3, column=3, sticky=EW)
        # High Val
        lbl_pointHigh = tk.Label(self, text="High")
        lbl_pointHigh.grid(row=4, column=0)
        lbl_phrefHigh = tk.Label(self, text="10.0")
        lbl_phrefHigh.grid(row=4, column=1)
        strval = "ch" + str(ChannelID) + "_ph_high"
        val = self.controller.controller.controller.controller.downloadsettings(
            "mcp3008", strval, "700")
        self.lbl_high_val = tk.Label(self, text=val)
        self.lbl_high_val.grid(row=4, column=2)
        btn_HighCalStart = Button(self,
                                  text="Start High Calibration",
                                  command=lambda: self.startCalLoop('high'))
        btn_HighCalStart.grid(row=4, column=3, sticky=EW)

        # Show current PH and DV val
        frame_LiveData = LabelFrame(self, text="Live Data")
        frame_LiveData.grid(row=5, column=0, columnspan=4, sticky=EW)
        lbl_curPH = tk.Label(frame_LiveData, text="Current PH:")
        lbl_curPH.grid(row=5, column=0, sticky=E, columnspan=2)
        self.lbl_curPHval = tk.Label(frame_LiveData, text="waiting...")
        self.lbl_curPHval.grid(row=5, column=2, sticky=W, padx=20)
        lbl_curDV = tk.Label(frame_LiveData, text="Current Digital Value:")
        lbl_curDV.grid(row=6, column=0, sticky=E, columnspan=2)
        self.lbl_curDVval = tk.Label(frame_LiveData, text="waiting...")
        self.lbl_curDVval.grid(row=6, column=2, sticky=W, padx=20, pady=10)

        # calibration data
        frame_CalData = LabelFrame(self, text="Calibration Data")
        frame_CalData.grid(row=7, column=0, columnspan=4, sticky=EW)

        # cal label
        self.calLabel = Label(frame_CalData, text=" ", font=LARGE_FONT_BOLD)
        self.calLabel.grid(row=0,
                           column=0,
                           columnspan=4,
                           padx=5,
                           pady=4,
                           sticky=W)

        # progress bar
        self.calprogress = ttk.Progressbar(frame_CalData,
                                           orient='horizontal',
                                           mode='determinate',
                                           maximum=NUMCALPOINTS,
                                           length=450)
        self.calprogress.grid(row=1,
                              column=0,
                              sticky=EW,
                              pady=10,
                              padx=5,
                              columnspan=6)

        # data points plot
        style.use("ggplot")
        self.figprobe = Figure(figsize=(6, 2.5), dpi=100)
        self.figprobe.set_facecolor("gainsboro")
        self.aniprobe = self.figprobe.add_subplot(111)
        self.aniprobe.set_title("Data Points")

        self.canvasprobe = FigureCanvasTkAgg(self.figprobe, frame_CalData)

        self.canvasprobe.show()
        self.canvasprobe.get_tk_widget().grid(sticky=EW,
                                              row=2,
                                              column=2,
                                              columnspan=4)

        # histogram plot
        ##        self.fighist, self.axhist = plt.subplots()
        ##        plt.title("Histogram")
        self.fighist = Figure(figsize=(6, 2.5), dpi=100)
        self.axhist = self.fighist.add_subplot(111)
        self.axhist.set_title("Histogram")
        self.fighist.set_facecolor("gainsboro")
        self.fighist.set_size_inches(6, 2.5)
        self.fighist.set_dpi(100)
        self.axhist.axes.tick_params(axis='x', labelsize=8)
        self.axhist.axes.tick_params(axis='y', labelsize=8)
        self.axhist.axes.set_xlim([0, 1023])

        self.canvashist = FigureCanvasTkAgg(self.fighist, frame_CalData)
        self.canvashist.show()
        self.canvashist.get_tk_widget().grid(sticky=EW,
                                             row=3,
                                             column=2,
                                             columnspan=4)

        ani = animation.FuncAnimation(self.figprobe,
                                      self.animate_probe,
                                      interval=1000)

        # scrolled textbox for calibration values
        self.txt_calPoints = tkst.ScrolledText(frame_CalData,
                                               width=15,
                                               height=10,
                                               wrap='word')
        self.txt_calPoints.grid(row=2,
                                column=0,
                                sticky=NSEW,
                                padx=5,
                                columnspan=2)

        # results area
        self.frame_Results = LabelFrame(frame_CalData, text="Results")
        self.frame_Results.grid(row=3, column=0, sticky=NSEW, columnspan=2)

        self.lbl_num_Samples = Label(self.frame_Results, text="Num. Samples:")
        self.lbl_num_Samples.grid(row=0, column=0, sticky=E)
        self.lbl_num_SamplesVal = Label(self.frame_Results, text="", width=10)
        self.lbl_num_SamplesVal.grid(row=0, column=1, sticky=EW)

        self.lbl_resultMin = Label(self.frame_Results, text="Min:")
        self.lbl_resultMin.grid(row=1, column=0, sticky=E)
        self.lbl_resultMinVal = Label(self.frame_Results, text="", width=10)
        self.lbl_resultMinVal.grid(row=1, column=1, sticky=EW)

        self.lbl_resultMax = Label(self.frame_Results, text="Max:")
        self.lbl_resultMax.grid(row=2, column=0, sticky=E)
        self.lbl_resultMaxVal = Label(self.frame_Results, text="", width=10)
        self.lbl_resultMaxVal.grid(row=2, column=1, sticky=EW)

        self.lbl_resultMean = Label(self.frame_Results, text="Mean:")
        self.lbl_resultMean.grid(row=3, column=0, sticky=E)
        self.lbl_resultMeanVal = Label(self.frame_Results, text="", width=10)
        self.lbl_resultMeanVal.grid(row=3, column=1, sticky=EW)

        self.lbl_resultStdDev = Label(self.frame_Results,
                                      text="Std. Deviation:")
        self.lbl_resultStdDev.grid(row=4, column=0, sticky=E)
        self.lbl_resultStdDevVal = Label(self.frame_Results, text="", width=10)
        self.lbl_resultStdDevVal.grid(row=4, column=1, sticky=EW)

        self.lbl_resultCalval = Label(self.frame_Results,
                                      text="Calibration Value:")
        self.lbl_resultCalval.grid(row=5, column=0, sticky=E)
        self.lbl_resultCalvalVal = Label(self.frame_Results,
                                         text="",
                                         width=10,
                                         font=LARGE_FONT_BOLD)
        self.lbl_resultCalvalVal.grid(row=5, column=1, sticky=EW, pady=20)

        self.btn_ApplyCal = Button(self.frame_Results,
                                   text="Apply Calibration Value",
                                   command=self.ApplyCal)
        self.btn_ApplyCal.grid(row=6, column=0, columnspan=2, sticky=EW)

        self.currentADCLoop(self.ChannelID)
Пример #20
0
 def endApplication(self):
     defs_common.logtoconsole("Exiting application")
     self.running = 0
Пример #21
0
    def __init__(self, master, queue, endCommand):
        self.queue = queue
        #tk.Tk.__init__(self, *args, **kwargs)

        defs_common.logtoconsole("Application startup...")
        
        #self.iconbitmap('@images/reefberrypi_logo.xbm')
        master.wm_title("Reefberry Pi")
        #set minimum size of the window
        master.minsize(400,400)
        master.geometry("800x680")
        
        #self.toolbar = cls_Toolbar.Toolbar()

        #create a menubar
        master.menubar = Menu(master)

        # create a pulldown menu, and add it to the menu bar
        master.filemenu = Menu(master.menubar, tearoff=0)
        #master.filemenu.add_command(label="Exit", command=master.quit)
        master.filemenu.add_command(label="Quit", command=self.on_closing)
        master.menubar.add_cascade(label="File", menu=master.filemenu)
        # display the menu
        master.config(menu=master.menubar)

        
        ######################### 
        #create toolbar frame
        self.frame_toolbar = tk.LabelFrame(master, relief = tk.FLAT)
        self.frame_toolbar.pack(side=tk.TOP, fill=tk.X)

        self.img_dashboard = PhotoImage(file="images/dashboard-64.png")
        self.btn_DashBoard = ttk.Button(self.frame_toolbar, text="Dashboard", image=self.img_dashboard, 
                            compound=TOP, command=lambda: self.show_frame(cls_DashBoard.DashBoard))
        self.btn_DashBoard.pack(side=LEFT)

        self.img_graph = PhotoImage(file="images/line-chart-64.png")
        self.btn_GraphPage = ttk.Button(self.frame_toolbar, text="Graphs", image=self.img_graph,
                            compound=TOP, command=lambda: self.show_frame(cls_GraphPage.GraphPage))
        self.btn_GraphPage.pack(side=LEFT)

        self.img_prefs = PhotoImage(file="images/gears-64.png")
        self.btn_prefs = ttk.Button(self.frame_toolbar, text="Settings", image=self.img_prefs,
                            compound=TOP, command=lambda: self.show_frame(cls_PrefPage.PrefPage))
        self.btn_prefs.pack(side=LEFT)

        self.img_about = PhotoImage(file="images/reefberrypi_logo-64.png")
        self.btn_About = ttk.Button(self.frame_toolbar, text="About", image=self.img_about,
                            compound=TOP, command=lambda: self.show_frame(cls_SplashPage.SplashPage))
        self.btn_About.pack(side=LEFT)

        # create statusbar
        statusbar = StatusBar(master)
        statusbar.pack(side=BOTTOM, fill=X)
        #statusbar.set("connected to server")

        
        #########################
        #self.sizegrip = ttk.Sizegrip(master)
        #self.sizegrip.pack(side="right", anchor="s")
        
        container = tk.Frame(master)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (cls_DashBoard.DashBoard, cls_GraphPage.GraphPage, cls_PrefPage.PrefPage, cls_SplashPage.SplashPage):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")


        self.show_frame(cls_DashBoard.DashBoard)
Пример #22
0
    def apploop(self):
        while True:
            #defs_common.logtoconsole("app loop")

            ##########################################################################################
            # read ds18b20 temperature sensor
            #
            # we support multiple probes, so work from the probe dictionary and get data
            # for each
            ##########################################################################################
            # read data from the temperature probes
            if (int(round(time.time() * 1000)) -
                    self.AppPrefs.ds18b20_SamplingTimeSeed
                ) > self.AppPrefs.ds18b20_SamplingInterval:
                for p in self.AppPrefs.tempProbeDict:
                    try:
                        timestamp = datetime.now()
                        dstempC = float(
                            ds18b20.read_temp(
                                self.AppPrefs.tempProbeDict[p].probeid, "C"))
                        dstempF = defs_common.convertCtoF(float(dstempC))
                        dstempF = float(dstempF)
                        tempData = str(dstempC) + "," + str(dstempF)

                        if str(self.AppPrefs.temperaturescale) == str(
                                defs_common.SCALE_F):
                            broadcasttemp = str("%.1f" % dstempF)
                        else:
                            broadcasttemp = str("%.1f" % dstempC)

                        #self.tempProbeDict[p].lastLogTime = self.ds18b20_LastLogTimeDict


# json_body = [
# {
# "measurement": "probevalues",
# "tags": {
# "appuid": self.AppPrefs.appuid,
# "probeid": "ds18b20_" + self.AppPrefs.tempProbeDict[p].probeid
# },
# "time": datetime.utcnow(),
# "fields": {
# "value": float(dstempC),
# }
# }
# ]

                        if (int(round(time.time() * 1000)) -
                                int(self.AppPrefs.tempProbeDict[p].lastLogTime)
                            ) > self.AppPrefs.ds18b20_LogInterval:
                            # log and broadcast temperature value
                            defs_common.logprobedata(
                                "ds18b20_" +
                                self.AppPrefs.tempProbeDict[p].probeid + "_",
                                tempData)
                            defs_common.logtoconsole(
                                "***Logged*** [ds18b20_" +
                                self.AppPrefs.tempProbeDict[p].probeid + "] " +
                                self.AppPrefs.tempProbeDict[p].name +
                                str(" = {:.1f}".format(dstempC)) + " C | " +
                                str("{:.1f}".format(dstempF)) + " F",
                                fg="CYAN",
                                style="BRIGHT")
                            self.logger.info(
                                str("***Logged*** [ds18b20_" +
                                    self.AppPrefs.tempProbeDict[p].probeid +
                                    "] " +
                                    self.AppPrefs.tempProbeDict[p].name +
                                    str(" = {:.1f}".format(dstempC)) +
                                    " C | " + str("{:.1f}".format(dstempF))) +
                                " F")
                            # log to InfluxDB
                            # self.WriteDataInfluxDB(json_body)
                            self.WriteProbeDataInfluxDB(
                                "ds18b20_" +
                                self.AppPrefs.tempProbeDict[p].probeid,
                                dstempC)
                            #self.broadcastProbeStatus("ds18b20", "ds18b20_" + self.AppPrefs.tempProbeDict[p].probeid, str(broadcasttemp), self.AppPrefs.tempProbeDict[p].name)

                            #self.ds18b20_LastLogTimeDict = int(round(time.time()*1000))
                            self.AppPrefs.tempProbeDict[p].lastLogTime = int(
                                round(time.time() * 1000))

                            #self.AppPrefs.tempProbeDict[p].lastTemperature = dstempC
                            self.AppPrefs.tempProbeDict[
                                p].lastTemperature = broadcasttemp
                        else:
                            self.logger.info(
                                str("[ds18b20_" +
                                    self.AppPrefs.tempProbeDict[p].probeid +
                                    "] " +
                                    self.AppPrefs.tempProbeDict[p].name +
                                    str(" = {:.1f}".format(dstempC)) +
                                    " C | " + str("{:.1f}".format(dstempF))) +
                                " F")

                            # broadcast temperature value
                            # self.MQTTclient.publish("reefberrypi/demo",str(dstempC))
                            self.broadcastProbeStatus(
                                "ds18b20", "ds18b20_" +
                                str(self.AppPrefs.tempProbeDict[p].probeid),
                                str(broadcasttemp),
                                self.AppPrefs.tempProbeDict[p].name)
                            self.AppPrefs.tempProbeDict[
                                p].lastTemperature = broadcasttemp
                    except Exception as e:
                        defs_common.logtoconsole(
                            str("<<<Error>>> Can not read ds18b20_" +
                                self.AppPrefs.tempProbeDict[p].probeid +
                                " temperature data!"),
                            fg="WHITE",
                            bg="RED",
                            style="BRIGHT")
                        self.logger.error(
                            "<<<Error>>> Can not read ds18b20_" +
                            self.AppPrefs.tempProbeDict[p].probeid +
                            " temperature data!")
                        self.logger.error(e)
                # record the new sampling time
                self.AppPrefs.ds18b20_SamplingTimeSeed = int(
                    round(time.time() * 1000))  # convert time to milliseconds

            ################################################################################################################
            # read dht11 temperature and humidity sensor
            #
            # these sensors are slow to refresh and should not be read more
            # than once every second or two (ie: dht_SamplingInterval = 3000ms or 5000ms for 3s or 5s) would be safe
            ################################################################################################################
            if self.AppPrefs.DHT_Sensor.get("enabled") == "True":
                if (int(round(time.time() * 1000)) -
                        self.AppPrefs.DHT_Sensor.get("dht11_samplingtimeseed")
                    ) > int(
                        self.AppPrefs.DHT_Sensor.get(
                            "dht11_samplinginterval")):
                    # let's read the dht11 temp and humidity data
                    result = self.dht_sensor.read()
                    if result.is_valid():
                        temp_c = result.temperature
                        temp_f = defs_common.convertCtoF(float(temp_c))
                        temp_f = float(temp_f)
                        hum = result.humidity
                        timestamp = datetime.now()

                        if str(self.AppPrefs.temperaturescale) == str(
                                defs_common.SCALE_F):
                            broadcasttemp = str("%.1f" % temp_f)
                        else:
                            broadcasttemp = str("%.1f" % temp_c)

                        if (int(round(time.time() * 1000)) - self.AppPrefs.
                                DHT_Sensor.get("dht11_lastlogtime")) > int(
                                    self.AppPrefs.DHT_Sensor.get(
                                        "dht11_loginterval")):
                            tempData = str(
                                "{:.1f}".format(temp_c)) + "," + str(temp_f)

                            # log and broadcast temperature value
                            defs_common.logprobedata("dht_t_", tempData)
                            defs_common.logtoconsole(
                                "***Logged*** [dht_t] " +
                                self.AppPrefs.DHT_Sensor.get(
                                    "temperature_name") +
                                " = %.1f C" % temp_c + " | %.1f F" % temp_f,
                                fg="CYAN",
                                style="BRIGHT")
                            self.logger.info(
                                str("***Logged*** [dht_t] " +
                                    self.AppPrefs.DHT_Sensor.get(
                                        "temperature_name") +
                                    " = %.1f C" % temp_c +
                                    " | %.1f F" % temp_f))
                            self.broadcastProbeStatus(
                                "dht", "dht_t", str(broadcasttemp),
                                self.AppPrefs.DHT_Sensor.get(
                                    "temperature_name"))

                            # json_body = [
                            # {
                            # "measurement": "probevalues",
                            # "tags": {
                            # "appuid": self.AppPrefs.appuid,
                            # "probeid": "dht_t"
                            # },
                            # "time": datetime.utcnow(),
                            # "fields": {
                            # "value": float(temp_c),
                            # }
                            # }
                            # ]

                            # log to InfluxDB
                            # self.WriteDataInfluxDB(json_body)
                            self.WriteProbeDataInfluxDB("dht_t", temp_c)

                            # log and broadcast humidity value
                            defs_common.logprobedata("dht_h_",
                                                     "{:.0f}".format(hum))
                            defs_common.logtoconsole(
                                "***Logged*** [dht_h] " +
                                self.AppPrefs.DHT_Sensor.get("humidity_name") +
                                " = %d %%" % hum,
                                fg="CYAN",
                                style="BRIGHT")
                            self.logger.info(
                                str("***Logged*** [dht_h] " +
                                    self.AppPrefs.DHT_Sensor.get(
                                        "humidity_name") + " = %d %%" % hum))
                            self.broadcastProbeStatus(
                                "dht", "dht_h", str(hum),
                                self.AppPrefs.DHT_Sensor.get("humidity_name"))
                            # json_body = [
                            # {
                            # "measurement": "probevalues",
                            # "tags": {
                            # "appuid": self.AppPrefs.appuid,
                            # "probeid": "dht_h"
                            # },
                            # "time": datetime.utcnow(),
                            # "fields": {
                            # "value": float(hum),
                            # }
                            # }
                            # ]
                            # log to InfluxDB
                            # self.WriteDataInfluxDB(json_body)
                            self.WriteProbeDataInfluxDB("dht_h", hum)

                            self.AppPrefs.DHT_Sensor[
                                "dht11_lastlogtime"] = int(
                                    round(time.time() * 1000))
                        else:
                            self.logger.info(
                                str("[dht_t] " + self.AppPrefs.DHT_Sensor.get(
                                    "temperature_name") +
                                    " = %.1f C" % temp_c +
                                    " | %.1f F" % temp_f))
                            self.logger.info(
                                str("[dht_h] " + self.AppPrefs.DHT_Sensor.get(
                                    "humidity_name") + " = %d %%" % hum))

                            # broadcast humidity value
                            self.broadcastProbeStatus(
                                "dht", "dht_h", str(hum),
                                self.AppPrefs.DHT_Sensor.get("humidity_name"))
                            # broadcast temperature value
                            self.broadcastProbeStatus(
                                "dht", "dht_t", str(broadcasttemp),
                                self.AppPrefs.DHT_Sensor.get(
                                    "temperature_name"))

                        # record the new sampling time
                        self.AppPrefs.DHT_Sensor[
                            "dht11_samplingtimeseed"] = int(
                                round(time.time() *
                                      1000))  # convert time to milliseconds

            ##########################################################################################
            # read each of the 8 channels on the mcp3008
            # channels (0-7)
            ##########################################################################################
            # only read the data at every ph_SamplingInterval (ie: 500ms or 1000ms)
            if (int(round(time.time() * 1000)) -
                    self.AppPrefs.dv_SamplingTimeSeed
                ) > self.AppPrefs.dv_SamplingInterval:
                # for x in range (0,8):
                for ch in self.AppPrefs.mcp3008Dict:
                    if self.AppPrefs.mcp3008Dict[ch].ch_enabled == "True":
                        #defs_common.logtoconsole(str(self.mcp3008Dict[ch].ch_num) + " " + str(self.mcp3008Dict[ch].ch_name) + " " + str(self.mcp3008Dict[ch].ch_enabled) + " " + str(len(self.mcp3008Dict[ch].ch_dvlist)))
                        dv = mcp3008.readadc(
                            int(self.AppPrefs.mcp3008Dict[ch].ch_num),
                            GPIO_config.SPICLK, GPIO_config.SPIMOSI,
                            GPIO_config.SPIMISO, GPIO_config.SPICS)

                        self.AppPrefs.mcp3008Dict[ch].ch_dvlist.append(dv)
                        #self.logger.info(str(self.mcp3008Dict[ch].ch_num) + " " + str(self.mcp3008Dict[ch].ch_name) + " " + str(self.mcp3008Dict[ch].ch_dvlist))
                    # once we hit our desired sample size of ph_numsamples (ie: 120)
                    # then calculate the average value
                    if len(self.AppPrefs.mcp3008Dict[ch].ch_dvlist) >= int(
                            self.AppPrefs.mcp3008Dict[ch].ch_numsamples):
                        # The probes may pick up noise and read very high or
                        # very low values that we know are not good values. We are going to use numpy
                        # to calculate the standard deviation and remove the outlying data that is
                        # Sigma standard deviations away from the mean.  This way these outliers
                        # do not affect our results
                        self.logger.info(
                            "mcp3008 ch" +
                            str(self.AppPrefs.mcp3008Dict[ch].ch_num) +
                            " raw data " +
                            str(self.AppPrefs.mcp3008Dict[ch].ch_name) + " " +
                            str(self.AppPrefs.mcp3008Dict[ch].ch_dvlist))
                        dv_FilteredCounts = numpy.array(
                            self.AppPrefs.mcp3008Dict[ch].ch_dvlist)
                        dv_FilteredMean = numpy.mean(dv_FilteredCounts, axis=0)
                        dv_FlteredSD = numpy.std(dv_FilteredCounts, axis=0)
                        dv_dvlistfiltered = [
                            x for x in dv_FilteredCounts
                            if (x > dv_FilteredMean -
                                float(self.AppPrefs.mcp3008Dict[ch].ch_sigma) *
                                dv_FlteredSD)
                        ]
                        dv_dvlistfiltered = [
                            x for x in dv_dvlistfiltered
                            if (x < dv_FilteredMean +
                                float(self.AppPrefs.mcp3008Dict[ch].ch_sigma) *
                                dv_FlteredSD)
                        ]

                        self.logger.info(
                            "mcp3008 ch" +
                            str(self.AppPrefs.mcp3008Dict[ch].ch_num) +
                            " filtered " +
                            str(self.AppPrefs.mcp3008Dict[ch].ch_name) + " " +
                            str(dv_dvlistfiltered))

                        # calculate the average of our filtered list
                        try:
                            dv_AvgCountsFiltered = int(
                                sum(dv_dvlistfiltered) /
                                len(dv_dvlistfiltered))
                            # delete this line
                            print("{:.2f}".format(dv_AvgCountsFiltered))
                        except:
                            # need to revisit this error handling. Exception thrown when all
                            dv_AvgCountsFiltered = 1
                            # values were 1023
                            print("Error collecting data")

                        # self.mcp3008Dict[ch].ch_dvlist.clear()  ## delete  this line

                        if self.AppPrefs.mcp3008Dict[ch].ch_type == "pH":
                            # bug, somtimes value is coming back high, like really high, like 22.0.  this is an impossible
                            # value since max ph is 14.  need to figure this out later, but for now, lets log this val to aid in
                            # debugging
                            orgval = dv_AvgCountsFiltered

                            # convert digital value to ph
                            lowCal = self.AppPrefs.mcp3008Dict[ch].ch_ph_low
                            medCal = self.AppPrefs.mcp3008Dict[ch].ch_ph_med
                            highCal = self.AppPrefs.mcp3008Dict[ch].ch_ph_high

                            dv_AvgCountsFiltered = ph_sensor.dv2ph(
                                dv_AvgCountsFiltered, ch, lowCal, medCal,
                                highCal)
                            dv_AvgCountsFiltered = float(
                                "{:.2f}".format(dv_AvgCountsFiltered))

                            if dv_AvgCountsFiltered > 14:
                                self.logger.error("Invalid PH value: " +
                                                  str(dv_AvgCountsFiltered) +
                                                  " " + str(orgval) + " " +
                                                  str(dv_dvlistfiltered))
                                defs_common.logtoconsole(
                                    "Invalid PH value: " +
                                    str(dv_AvgCountsFiltered) + " " +
                                    str(orgval) + " " + str(dv_dvlistfiltered),
                                    fg="RED",
                                    style="BRIGHT")

                        # if enough time has passed (ph_LogInterval) then log the data to file
                        # otherwise just print it to console
                        timestamp = datetime.now()
                        if (int(round(time.time() * 1000)) -
                                self.AppPrefs.mcp3008Dict[ch].LastLogTime
                            ) > self.AppPrefs.dv_LogInterval:
                            # sometimes a high value, like 22.4 gets recorded, i need to fix this, but for now don't log that
                            # if ph_AvgFiltered < 14.0:
                            #RBP_commons.logprobedata(config['logs']['ph_log_prefix'], "{:.2f}".format(ph_AvgFiltered))
                            # log data to InfluxDB
                            self.WriteProbeDataInfluxDB(
                                "mcp3008_ch" +
                                str(self.AppPrefs.mcp3008Dict[ch].ch_num),
                                "{:.2f}".format(dv_AvgCountsFiltered))
                            defs_common.logprobedata(
                                "mcp3008_ch" +
                                str(self.AppPrefs.mcp3008Dict[ch].ch_num) +
                                "_", "{:.2f}".format(dv_AvgCountsFiltered))
                            print(
                                timestamp.strftime(Fore.CYAN + Style.BRIGHT +
                                                   "%Y-%m-%d %H:%M:%S") +
                                " ***Logged*** dv = " +
                                "{:.2f}".format(dv_AvgCountsFiltered) +
                                Style.RESET_ALL)
                            self.AppPrefs.mcp3008Dict[ch].LastLogTime = int(
                                round(time.time() * 1000))
                        else:
                            print(
                                timestamp.strftime("%Y-%m-%d %H:%M:%S") +
                                " dv = " +
                                "{:.2f}".format(dv_AvgCountsFiltered))

                        self.broadcastProbeStatus(
                            "mcp3008", "mcp3008_ch" +
                            str(self.AppPrefs.mcp3008Dict[ch].ch_num),
                            str(dv_AvgCountsFiltered),
                            str(self.AppPrefs.mcp3008Dict[ch].ch_name))
                        self.AppPrefs.mcp3008Dict[ch].lastValue = str(
                            dv_AvgCountsFiltered)
                        # clear the list so we can populate it with new data for the next data set
                        self.AppPrefs.mcp3008Dict[ch].ch_dvlist.clear()
                        # record the new sampling time
                        self.AppPrefs.dv_SamplingTimeSeed = int(
                            round(time.time() *
                                  1000))  # convert time to milliseconds

            ##########################################################################################
            # pause to slow down the loop, otherwise CPU usage spikes as program is busy waiting
            ##########################################################################################
            time.sleep(.5)
Пример #23
0
    def __init__(self, master):

        defs_common.logtoconsole("Initializing FeedWidget...",
                                 fg="YELLOW",
                                 bg="MAGENTA",
                                 style="BRIGHT")

        ##        #initialize the messaging queues
        ##        connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
        ##        channel = connection.channel()

        #initialize the messaging queues

        self.initializeConnection()
        ##        self.connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
        ##        self.channel = self.connection.channel()
        ##
        ##        result = self.channel.queue_declare(exclusive=True)
        ##        self.callback_queue = result.method.queue
        ##
        ##        self.channel.basic_consume(self.rpc_response, no_ack=True,
        ##                                   queue=self.callback_queue)

        #queue for posting outlet changes
        #channel.queue_declare(queue='outlet_change')

        # frame for feed timers
        self.frame_feedtimers = LabelFrame(master,
                                           text="Feed Mode",
                                           relief=RAISED)
        self.frame_feedtimers.pack(fill=X, side=TOP)
        self.frame_feed_spacer = tk.LabelFrame(self.frame_feedtimers,
                                               relief=tk.FLAT)
        self.frame_feed_spacer.pack(fill=X, side=TOP)

        self.img_cfg16 = PhotoImage(file="images/settings-16.png")
        self.btn_cfg_feed = Button(
            self.frame_feed_spacer,
            text="edit",
            image=self.img_cfg16,
            relief=FLAT,
            command=lambda: self.configureFeedmode(master))
        self.btn_cfg_feed.pack(side=LEFT, anchor=W)

        self.lbl_feedtimers_status = Label(self.frame_feed_spacer,
                                           text=" ",
                                           relief=FLAT)
        self.lbl_feedtimers_status.pack(side=TOP, anchor=E)
        self.btn_feedA = Button(self.frame_feedtimers,
                                text="A",
                                width=2,
                                command=lambda: select_feed_mode("A"))
        self.btn_feedA.pack(side=LEFT, padx=2)
        self.btn_feedB = Button(self.frame_feedtimers,
                                text="B",
                                width=2,
                                command=lambda: select_feed_mode("B"))
        self.btn_feedB.pack(side=LEFT, padx=2)
        self.btn_feedC = Button(self.frame_feedtimers,
                                text="C",
                                width=2,
                                command=lambda: select_feed_mode("C"))
        self.btn_feedC.pack(side=LEFT, padx=2)
        self.btn_feedD = Button(self.frame_feedtimers,
                                text="D",
                                width=2,
                                command=lambda: select_feed_mode("D"))
        self.btn_feedD.pack(side=LEFT, padx=2)
        self.btn_feedCancel = Button(
            self.frame_feedtimers,
            text="Cancel",
            width=6,
            command=lambda: select_feed_mode("CANCEL"))
        self.btn_feedCancel.pack(side=RIGHT, anchor=E, padx=2)

        self.sendKeepAlive()

        def select_feed_mode(mode):
            #DefClr = app.cget("bg")
            #btn_feedA.configure(bg=DefClr)
            #btn_feedB.configure(bg=DefClr)
            #btn_feedC.configure(bg=DefClr)
            #btn_feedD.configure(bg=DefClr)
            #btn_feedCancel.configure(bg=DefClr)

            defs_common.logtoconsole("Feed mode request: " + str(mode),
                                     fg="YELLOW",
                                     style="BRIGHT")

            # request outlet change on server
            request = {
                "rpc_req": "set_feedmode",
                "feedmode": str(mode),
            }
            request = json.dumps(request)
            self.rpc_call(request, "rpc_queue")