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
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 )