示例#1
0
class HttpServer:
    def __init__(self, process_obj, wifi_obj, rtc_obj, user_settings_dict):
        self.process = process_obj
        self.wifi = wifi_obj
        self.rtc = rtc_obj
        self.settings = user_settings_dict
        self.app = None
        self.gravity_sg = None
        self.set_temp = None
        self.chamber_temp = None
        self.wort_temp = None
        self.time_mark = None

    def start(self):
        process = self.process
        wifi = self.wifi
        rtc = self.rtc
        settings = self.settings
        this = self

        @MicroWebSrv.route('/connecttest')
        def test_get(httpClient, httpResponse):
            """
            测试前端和后端之间的网络连接
            """
            httpResponse.WriteResponseOk()

        # Define the web routes and functions
        @MicroWebSrv.route('/overview')
        def overview_get(httpClient, httpResponse):
            """
            提供首页所有数据显示,前端每1分钟请求1次
            """
            brewery_name = settings['breweryName']
            wifi_connected = wifi.is_connected()
            real_date = rtc.get_localdate()
            real_time = rtc.get_localtime()
            basic_info = {
                'breweryName': brewery_name,
                'wifiIsConnected': wifi_connected,
                'realDate': real_date,
                'realTime': real_time,
            }
            process_info = process.get_process_info()
            overview = basic_info.copy()
            overview.update(process_info)
            # 以下数据更新用于前端绘制echarts折线图
            this.set_temp = process_info.get('setTemp')
            this.chamber_temp = process_info.get('chamberTemp')
            this.wort_temp = process_info.get('wortTemp')
            this.gravity_sg = process_info.get('hydrometerData').get(
                'currentGravity')
            this.time_mark = real_date + ' ' + real_time
            httpResponse.WriteResponseJSONOk(obj=overview, headers=None)

        @MicroWebSrv.route('/fermentation', 'POST')
        def fermentation_post(httpClient, httpResponse):
            """
            前台向后台提交发酵步骤数据,并且开始发酵过程
            """
            json = httpClient.ReadRequestContentAsJSON()
            beerName = json['beerName']
            fermentationSteps = json['fermentationSteps']
            try:
                process.set_beer_name(beerName)
                process.load_steps(fermentationSteps)
                process.start()
            except:
                # throw 500 error code
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/abort')
        def abort_get(httpClient, httpResponse):
            try:
                process.abort()
            except:
                # throw 500 error code
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/settings')
        def settings_get(httpClient, httpResponse):
            """
            从后台读取设置参数
            """
            wifi_list = wifi.scan_wifi_list()
            temp_sensor_list = process.fermenter_temp_ctrl.chamber_sensor.ds_obj.get_device_list(
            )
            # open user_settings.json and read settings
            with open('user_settings.json', 'r') as f:
                settings_dict = ujson.load(f)
            wort_sensor_dev_num = settings_dict.get('wortSensorDev')
            chamber_sensor_dev_num = settings_dict.get('chamberSensorDev')
            wort_sensor_rom_code = ''
            chamber_sensor_rom_code = ''
            for sensor_dict in temp_sensor_list:
                detail_list = sensor_dict.values()
                if wort_sensor_dev_num in detail_list:
                    wort_sensor_rom_code = sensor_dict.get('label')
                elif chamber_sensor_dev_num in detail_list:
                    chamber_sensor_rom_code = sensor_dict.get('label')

            wort_sensor_dev = {
                'value': wort_sensor_dev_num,
                'label': wort_sensor_rom_code
            }
            chamber_sensor_dev = {
                'value': chamber_sensor_dev_num,
                'label': chamber_sensor_rom_code
            }
            settings_added = {
                'wifiList': wifi_list,
                'wortSensorDev': wort_sensor_dev,
                'chamberSensorDev': chamber_sensor_dev,
                'tempSensorList': temp_sensor_list
            }
            settings_combined = settings_dict.copy()
            settings_combined.update(settings_added)
            # settings_json = ujson.dumps(settings_combined)
            httpResponse.WriteResponseJSONOk(obj=settings_combined,
                                             headers=None)
            # httpResponse.WriteResponseOk(
            #     headers=None,
            #     contentType="application/json",
            #     contentCharset="UTF-8",
            #     content=settings_json
            # )

        @MicroWebSrv.route('/settings', 'POST')
        def settings_post(httpClient, httpResponse):
            """
            向后台保存设置参数,并且重启ESP32
            """
            # json = httpClient.ReadRequestContentAsJSON()
            # settings_dict = ujson.loads(json)
            settings_dict = httpClient.ReadRequestContentAsJSON()
            settings_dict['wortSensorDev'] = settings_dict['wortSensorDev'][
                'value']
            settings_dict['chamberSensorDev'] = settings_dict[
                'chamberSensorDev']['value']
            try:
                with open('user_settings.json', 'w') as f:
                    ujson.dump(settings_dict, f)
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/reboot')
        def reboot_get(httpClient, httpResponse):
            tim = machine.Timer(-1)
            try:
                tim.init(period=3000,
                         mode=machine.Timer.ONE_SHOT,
                         callback=lambda t: machine.reset())
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/wifi')
        def wifi_get(httpClient, httpResponse):
            """
            获取WIFI热点列表,用于刷新热点列表
            """
            wifi_list = wifi.scan_wifi_list()
            wifi_dict = {'wifiList': wifi_list}
            httpResponse.WriteResponseJSONOk(obj=wifi_dict, headers=None)

        @MicroWebSrv.route('/wifi', 'POST')
        def wifi_post(httpClient, httpResponse):
            """
            连接WIFI热点
            """
            wifi_dict = httpClient.ReadRequestContentAsJSON()
            try:
                new_ip = wifi.sta_connect(wifi_dict['ssid'], wifi_dict['pass'])
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                if wifi.is_connected():
                    httpResponse.WriteResponseOk()
                else:
                    httpResponse.WriteResponseInternalServerError()

        @MicroWebSrv.route('/ip')
        def ip_get(httpClient, httpResponse):
            """
            获取IP地址
            """
            ap_ip = wifi.get_ap_ip_addr()
            sta_ip = wifi.get_sta_ip_addr()
            sta_ssid = wifi.get_sta_ssid()
            ip_dict = {'apIp': ap_ip, 'staIp': sta_ip, 'staSsid': sta_ssid}
            httpResponse.WriteResponseJSONOk(obj=ip_dict, headers=None)

        @MicroWebSrv.route('/ftp')
        def ftp_get(httpClient, httpResponse):
            """
            Start FTP service
            """
            try:
                import uftpd
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/mqtttest', 'POST')
        def mqtt_post(httpClient, httpResponse):
            """
            Send test message to MQTT server
            """
            settings_dict = httpClient.ReadRequestContentAsJSON()
            test_msg = ujson.dumps({'test-message': 200})
            from mqtt_client import MQTT
            try:
                test_mqtt = MQTT(settings_dict)
                test_mqtt.publish(test_msg)
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/actuator', 'POST')
        def actuactor_post(httpClient, httpResponse):
            """
            手动控制制冷压缩机或制热器,主要用于测试
            """
            actuactor_dict = httpClient.ReadRequestContentAsJSON()
            heater = process.fermenter_temp_ctrl.heater
            cooler = process.fermenter_temp_ctrl.cooler
            led = process.fermenter_temp_ctrl.led
            try:
                if actuactor_dict.get('element') == 'heater':
                    element = heater
                else:
                    element = cooler
                action = actuactor_dict.get('action')
                if action:
                    element.force_on()
                else:
                    element.force_off()
                if heater.is_on() and not cooler.is_on():
                    led_color = 'red'
                elif not heater.is_on() and cooler.is_on():
                    led_color = 'blue'
                elif not heater.is_on() and not cooler.is_on():
                    led_color = 'green'
                else:
                    led_color = 'orange'
                led.set_color(led_color)
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/tempsensors', 'POST')
        def temp_post(httpClient, httpResponse):
            """
            获取温度传感器读数
            """
            # 获取前端发来的设备序号
            sensor_dict = httpClient.ReadRequestContentAsJSON()
            new_wort_romcode = sensor_dict.get('wortSensorDev').get('value')
            new_chamber_romcode = sensor_dict.get('chamberSensorDev').get(
                'value')
            # 获取温感对象实例
            wort_sensor = process.fermenter_temp_ctrl.wort_sensor
            chamber_sensor = process.fermenter_temp_ctrl.chamber_sensor
            # 更新温感设备序号
            wort_sensor.update_romcode(new_wort_romcode)
            chamber_sensor.update_romcode(new_chamber_romcode)
            try:
                # 测量温度
                wort_temp = wort_sensor.read_temp()
                chamber_temp = chamber_sensor.read_temp()
            except:
                # throw 500 error code
                httpResponse.WriteResponseInternalServerError()
            else:
                temp_dict = {
                    'wortTemp': wort_temp,
                    'chamberTemp': chamber_temp
                }
                httpResponse.WriteResponseJSONOk(obj=temp_dict, headers=None)

        @MicroWebSrv.route('/hydrometer', 'POST')
        def gravity_post(httpClient, httpResponse):
            hydrometer_dict = httpClient.ReadRequestContentAsJSON()
            process.save_hydrometer_data(hydrometer_dict)
            httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/chart')
        def chart_get(httpClient, httpResponse):
            data = {
                'timeMark': this.time_mark,
                'setTemp': this.set_temp,
                'wortTemp': this.wort_temp,
                'chamberTemp': this.chamber_temp,
                'gravitySg': this.gravity_sg
            }
            httpResponse.WriteResponseJSONOk(obj=data, headers=None)

        # Initialize the Web server
        self.app = MicroWebSrv(webPath='/sd/www')
        self.app.Start(threaded=True)  # Starts the server

    def stop(self):
        if self.app:
            self.app.Stop()

    def is_started(self):
        if self.app:
            return self.app.IsStarted()
        else:
            return False
示例#2
0
class HttpServer:
    def __init__(self, gy521_obj, wifi_obj, user_settings_dict):
        self.gy521 = gy521_obj
        self.wifi = wifi_obj
        self.settings = user_settings_dict
        self.app = None

    def start(self):
        gy521 = self.gy521
        wifi = self.wifi
        settings = self.settings

        @MicroWebSrv.route('/connecttest')
        def test_get(httpClient, httpResponse):
            """
            测试前端和后端之间的网络连接
            """
            httpResponse.WriteResponseOk()

        # Define the web routes and functions
        @MicroWebSrv.route('/tilt')
        def tilt_get(httpClient, httpResponse):
            """
            读取比重计倾角,前端每10秒请求1次
            """
            try:
                _, tilt, _ = gy521.read_angles()
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseJSONOk(obj={'tilt': tilt},
                                                 headers=None)

        @MicroWebSrv.route('/calibration', 'POST')
        def calibration_post(httpClient, httpResponse):
            """
            前台进行倾角与比重的拟合计算后,将比重单位和拟合系数发回后台保存
            """
            result = httpClient.ReadRequestContentAsJSON()
            try:
                with open('regression.json', 'w') as f:
                    ujson.dump(result, f)
            except:
                # throw 500 error code
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/calibration')
        def calibration_get(httpClient, httpResponse):
            """
            将上一次保存的校准参数从json文件中读取并发送到前台
            """
            try:
                with open('regression.json', 'r') as f:
                    params = ujson.load(f)
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseJSONOk(obj={'params': params},
                                                 headers=None)

        @MicroWebSrv.route('/settings')
        def settings_get(httpClient, httpResponse):
            """
            从后台读取设置参数
            """
            wifi_list = wifi.scan_wifi_list()
            settings_added = {'wifiList': wifi_list}
            settings_combined = settings.copy()
            settings_combined.update(settings_added)
            httpResponse.WriteResponseJSONOk(obj=settings_combined,
                                             headers=None)

        @MicroWebSrv.route('/settings', 'POST')
        def settings_post(httpClient, httpResponse):
            """
            向后台保存设置参数
            """
            settings_dict = httpClient.ReadRequestContentAsJSON()
            try:
                with open('user_settings.json', 'w') as f:
                    ujson.dump(settings_dict, f)
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/reboot')
        def reboot_get(httpClient, httpResponse):
            """
            重启ESP32
            """
            tim = machine.Timer(-1)
            try:
                tim.init(period=3000,
                         mode=machine.Timer.ONE_SHOT,
                         callback=lambda t: machine.reset())
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/deepsleep')
        def deepsleep_get(httpClient, httpResponse):
            """
            使ESP32进入深度睡眠,唤醒后便进入工作模式
            """
            with open('hardware_config.json', 'r') as f:
                json = f.read()
            config = ujson.loads(json)

            FIRSTSLEEP_TRIGGER = config['firstsleep_trigger']

            def first_sleep():
                with open(FIRSTSLEEP_TRIGGER, 'w') as s:
                    pass
                machine.reset()

            tim = machine.Timer(-1)
            try:
                tim.init(period=3000,
                         mode=machine.Timer.ONE_SHOT,
                         callback=lambda t: first_sleep())
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/wifi')
        def wifi_get(httpClient, httpResponse):
            """
            获取WIFI热点列表,用于刷新热点列表
            """
            wifi_list = wifi.scan_wifi_list()
            wifi_dict = {'wifiList': wifi_list}
            httpResponse.WriteResponseJSONOk(obj=wifi_dict, headers=None)

        @MicroWebSrv.route('/wifi', 'POST')
        def wifi_post(httpClient, httpResponse):
            """
            连接WIFI热点
            """
            wifi_dict = httpClient.ReadRequestContentAsJSON()
            new_ip = wifi.sta_connect(wifi_dict['ssid'], wifi_dict['pass'])
            if new_ip:
                # 200
                httpResponse.WriteResponseOk()
            else:
                # throw 500 error code
                httpResponse.WriteResponseInternalServerError()

        @MicroWebSrv.route('/ftp')
        def ftp_get(httpClient, httpResponse):
            """
            Start FTP service
            """
            with open('hardware_config.json', 'r') as f:
                json = f.read()
            config = ujson.loads(json)

            FTP_TRIGGER = config['ftp_trigger']

            def start_ftp():
                with open(FTP_TRIGGER, 'w') as s:
                    pass
                machine.reset()

            tim = machine.Timer(-1)
            try:
                tim.init(period=3000,
                         mode=machine.Timer.ONE_SHOT,
                         callback=lambda t: start_ftp())
            except:
                httpResponse.WriteResponseInternalServerError()
            else:
                httpResponse.WriteResponseOk()

        @MicroWebSrv.route('/mqtttest', 'POST')
        def mqtt_post(httpClient, httpResponse):
            """
            Send test message to MQTT server
            """
            settings_dict = httpClient.ReadRequestContentAsJSON()
            test_msg = {'test-message': 200}
            str_data = ujson.dumps(test_msg)
            from mqtt_client import MQTT
            try:
                client = MQTT(settings_dict)
                client.publish(str_data)
            except:
                print('Failed to send the message to the MQTT broker.')
                httpResponse.WriteResponseInternalServerError()
            else:
                print('The test message has been sent successfully.')
                httpResponse.WriteResponseOk()

        # Initialize the Web server
        self.app = MicroWebSrv(webPath='/www')
        self.app.Start(threaded=True)  # Starts the server

    def stop(self):
        if self.app:
            self.app.Stop()

    def is_started(self):
        if self.app:
            return self.app.IsStarted()
        else:
            return False
class Webserver():

    def __init__(self, dev_state):
        self.wlan_agent = dev_state.wlan_agent
        self.mws = MicroWebSrv(webPath='www/')
        self.dev_state = dev_state

    def start(self):
        log('Start webserver.')
        if not self.wlan_agent.isActive():
            raise Exception("Cant start webserver without wlan.")

        self.mws.Start()

        now = time()
        while not self.mws.IsStarted():
            sleep(0.1)
            if (time()-now > 10):
                raise Exception('Webserver start is failed.')

        log('Webserver is started.')

    def stop(self):
        log('Stop webserver.')
        self.mws.Stop()

        now = time()
        while self.mws.IsStarted():
            sleep(0.1)
            if (time()-now > 10):
                raise Exception('Webserver stop is failed.')

        log('Webserver is stopped.')

    def init_webserver(self):
        def httpHandlerGETState(httpClient, httpResponse):
            httpResponse.WriteResponseJSONOk(   headers = None,
                                                obj = self.dev_state.get_state())

        def httpHandlerPOSTsearchOnewire(httpClient, httpResponse):
            if self.dev_state.onewire_interface is not None:
                try:
                    log('Request new search for one wire devices.')
                    one_wire_inf = self.dev_state.onewire_interface
                    one_wire_inf.interfacereset()
                    one_wire_inf.getallid()
                    one_wire_inf.checkdevices()

                    self.dev_state.clear_sensors()
                    one_wire_inf.update_state(self.dev_state)

                    log('Find {} devices.'.format(one_wire_inf.num_devices))
                    res = { "numDevices": one_wire_inf.num_devices }
                    httpResponse.WriteResponseJSONOk(   headers = None,
                                                        obj = res)
                except Exception as e:
                    sys.print_exception(e)
                    httpResponse.WriteResponseBadRequest()
            else:
                httpResponse.WriteResponseBadRequest()


        self.routeHandlers = [
            ( '/state', 'GET', httpHandlerGETState),
            ( '/search_onewire', 'POST', httpHandlerPOSTsearchOnewire)
        ]

        self.mws = MicroWebSrv(
            webPath='www/',
            routeHandlers=self.routeHandlers )