Exemplo n.º 1
0
class DashApp:
    def __init__(self):
        self.server = Flask(__name__)
        self.app = dash.Dash(
            name="dashboard",
            server=self.server,
            external_stylesheets=[dbc.themes.BOOTSTRAP],
            routes_pathname_prefix="/somethingsomethin/",
            suppress_callback_exceptions=True,
        )

        #makes sure that the login is required for data vis
        for view_func in self.server.view_functions:
            if view_func.startswith("/dashboard/"):
                print(view_func)
                self.server.view_functions[view_func] = login_required(
                    self.server.view_functions[view_func])

        self.comp = Components()
        # self.pi = Pi_Control()
        self.data = {}
        self.latLng = {}
        self.prev_data = {}
        self.default_plant_img = "https://ichef.bbci.co.uk/news/976/cpsprodpb/10ECF/production/_107772396_treesmall.jpg"
        self.water_button_counter = 0
        self.suggestions = None
        #ending variables

        #basic layout for the dash app dashboard
        self.app.layout = html.Div([
            self.comp.navbar,
        ])
        #end of layout

#call back for in the input value

    def output_text(self, value):
        if value != None:
            return "Your Input: " + str(value)
        else:
            "What are you waiting for..."

    #Funtion that displays the current date and time
    def update_time(self, n):
        style = {"padding": "12px", "fontsize": "25px"}
        return html.Span(
            datetime.datetime.now().strftime("%m/%d/%Y %I:%M:%S %p"),
            style=style)

    #Funtion that updates the map url when an address is entered
    def update_map_img(self, _, address):
        self.latLng = {}
        self.data = {'time': [], 'temperature': []}
        self.prev_data = {}
        if address != None and address != "":
            geoman = GeolocationManager(address)
            geolocation_str = geoman.__str__()
            print(geolocation_str)
            geolocation_dict = eval(geoman.__str__())
            self.latLng['lat'], self.latLng['lng'] = geolocation_dict[
                'lat'], geolocation_dict['lng']
            return (html.Img(src=geolocation_dict['img_url'],
                             style={"width":
                                    "100%"}), self.comp.graph_output(address))
        else:
            return "Please enter a valid address", html.Div()

    #Funtion to update the graph based on the active tab and the n_interval
    def updateGraph(self, n, active_tab):
        print(n)
        active_tab = active_tab.split("-")[0]
        lat, lng = self.latLng['lat'], self.latLng['lng']
        print(self.data)
        time.sleep(1)
        df = pd.DataFrame.from_dict(self.data, orient="index")
        df = df.transpose()
        fig = px.area(df, x='time', y=active_tab, template="plotly_white")
        return fig

    def updateData(self, n):
        weatherman = WeatherManager(self.latLng['lat'], self.latLng['lng'])
        weatherman_data = eval(weatherman.__str__())
        self.data = weatherman_data['data']

    #Uses cutting edge computer vision research to classify plants and give suggestions based on a picture of that plant
    def updateImg(self, contents):
        print("in update image")
        if contents == None or not contents[0:10] == "data:image":
            card = self.comp.initializePlantCard(self.default_plant_img, [])
            print(card)
            return card
        self.plantRecognizer = Recognizer(contents)
        request_id = self.plantRecognizer.identify()
        suggestions = self.plantRecognizer.get_suggestions(request_id)
        suggestions = [
            elem for elem in suggestions
            if not elem['plant']['common_name'] == ""
        ]
        print(suggestions)
        self.suggestions = suggestions
        return self.comp.initializePlantCard(
            contents,
            html.Div([
                html.H6(suggestions[0]['plant']['common_name'],
                        id="plant_name",
                        style={
                            "text-align": "center",
                            "font-size": "13px"
                        }),
                dbc.Button("Confirm",
                           id="confirm",
                           color="success",
                           className="mr-1",
                           style={"width": "30%"}),
                dbc.Button("Reject",
                           id="reject",
                           color="danger",
                           className="mr-1",
                           style={"width": "30%"}),
            ],
                     style={"text-align": "center"}))

    #Confirms the suggestion and returns the name of the plant
    def confirmSuggestion(self):
        print(self.suggestions[0]['id'])
        self.plantRecognizer.confirm_suggestion(self.suggestions[0]['id'])
        print("Thank you for confirming my suggestion")
        return html.H6(self.suggestions[0]['plant']['common_name'],
                       id="plant_name",
                       style={
                           "text-align": "center",
                           "font-size": 13
                       })

    def rejectSuggestion(self):
        print("Ok we are rejecting the suggestion")
        print(self.suggestions[0]['id'])
        self.plantRecognizer.reject_suggestion(self.suggestions[0]['id'])
        if len(self.suggestions) > 1:
            self.suggestions.pop(0)
            print(self.suggestions)
            return html.Div([
                html.H6(self.suggestions[0]['plant']['common_name'],
                        id="plant_name",
                        style={
                            "text-align": "center",
                            "font-size": "13px"
                        }),
                dbc.Button("Confirm",
                           id="confirm",
                           color="success",
                           className="mr-1",
                           style={"width": "30%"}),
                dbc.Button("Reject",
                           id="reject",
                           color="danger",
                           className="mr-1",
                           style={"width": "30%"}),
            ],
                            style={"text-align": "center"})
        if len(self.suggestions) == 1:
            self.suggestions.pop(0)
            print("Suggestions length == 1", self.suggestions)
            #return a div with an input field and a button to submit the plant name
            return dbc.Row([
                dbc.Col(
                    dbc.Input(id="plant_input",
                              placeholder="Plant Name",
                              type="text"),
                    width=9,
                ),
                dbc.Col(
                    dbc.Button("Submit",
                               id="submit_plant_name",
                               color="dark",
                               className="mr-1"),
                    width=3,
                )
            ],
                           no_gutters=True,
                           id="plant_stuff")

    #alter this code once you get the pi back working
    def toggleWater(self, _):
        if self.water_button_counter % 2 == 0:
            self.water_button_counter += 1
            # Code to turn raspberry pi off with the solenoid config
            self.pi.off()
            return dbc.Button("Water On",
                              color="primary",
                              className="mr-1",
                              id="pi")
        self.water_button_counter += 1
        #Code to turn the water counter on with the soleniod config
        self.pi.on()
        return dbc.Button("Water Off",
                          color="danger",
                          className="mr-1",
                          id="pi")

    #alteration for pi code ends here

    def update_layout(self, current_user):
        print(current_user.username)
        WATER_BENDER_LOGO = "https://raw.githubusercontent.com/csmjoshi/WaterBender/master/waterbender.png"
        ef = dbc.ButtonGroup([
            dbc.DropdownMenu(
                [
                    dbc.DropdownMenuItem("Add Community",
                                         href="/add_community",
                                         external_link=True),
                    dbc.DropdownMenuItem(
                        "Add Plant", href="/add_plant", external_link=True)
                ],
                group=True,
                right=True,
                label="+",
                in_navbar=True,
                color="primary",
            ),
            dbc.DropdownMenu([
                dbc.DropdownMenuItem(
                    "My Profile", href="/my_profile", external_link=True),
                dbc.DropdownMenuItem("My Communities",
                                     href="/my_communities",
                                     external_link=True),
                dbc.DropdownMenuItem(
                    "My Plants", href="/my_plants", external_link=True),
                dbc.DropdownMenuItem(
                    "Sign Out", href="/logout", external_link=True)
            ],
                             group=True,
                             right=True,
                             label=current_user.username,
                             in_navbar=True,
                             color="primary"),
        ],
                             className="ml-auto flex-nowrap mt-3 mt-md-0")

        navbar = dbc.Navbar(
            [
                html.A(
                    dbc.Row(
                        [
                            dbc.Col(
                                html.Img(src=WATER_BENDER_LOGO,
                                         height="30px")),
                            dbc.Col(
                                dbc.NavbarBrand("Water Bender",
                                                className="ml-2")),
                        ],
                        align="center",
                        no_gutters=True,
                    ),
                    href="/#",
                ), ef
            ],
            color="dark",
            dark=True,
        )

        self.app.layout = html.Div([
            navbar,
            html.P(id="live_time_updates", style={"margin-left": "10px"}),
            dcc.Interval(id="time_interval", interval=1000, n_intervals=0),
            dbc.Row([
                dbc.Col(
                    html.Div([
                        self.comp.plantCard, self.comp.imgUpload.uploads,
                        self.comp.location_input,
                        html.P(id="output_da_input"),
                        html.Div(id="render_map")
                    ]),
                    width=3,
                    style={"padding-top": "10px"},
                ),
                dbc.Col(id="grapher", width=9)
            ]),
        ])