diff --git a/mock-api/Handler.ts b/mock-api/Handler.ts new file mode 100644 index 000000000..f42283e6c --- /dev/null +++ b/mock-api/Handler.ts @@ -0,0 +1,2870 @@ +import { Router } from 'itty-router'; +import { Encoder } from '@msgpack/msgpack'; +import busboy from 'busboy'; +// import multer from 'multer'; + +const encoder = new Encoder(); +const router = Router(); +// const upload = multer({ dest: '../mock-api/uploads' }); // TODO remove + +const REST_ENDPOINT_ROOT = '/rest/'; +const API_ENDPOINT_ROOT = '/api/'; +const ES_ENDPOINT_ROOT = '/es/'; + +const restRouter = Router({ base: REST_ENDPOINT_ROOT }); +const apiRouter = Router({ base: API_ENDPOINT_ROOT }); +const esRouter = Router({ base: ES_ENDPOINT_ROOT }); + +// HTTP HEADERS +const headers = { + 'Access-Control-Allow-Origin': '*', + 'Content-type': 'application/json' +}; + +const ESheaders = { + 'Access-Control-Allow-Origin': '*', + 'Content-type': 'text/event-stream', + 'Cache-Control': 'no-cache', + Connection: 'keep-alive' +}; + +// GLOBAL VARIABLES +let countWifiScanPoll = 0; // wifi network scan + +// FUNCTIONS +const delay = (ms) => new Promise((res) => setTimeout(res, ms)); +function delay_blocking(milliseconds) { + var start = new Date().getTime(); + for (var i = 0; i < 1e7; i++) { + if (new Date().getTime() - start > milliseconds) { + break; + } + } +} + +function updateMask(entity: any, de: any, dd: any) { + const current_mask = parseInt(entity.slice(0, 2), 16); + + // strip of any min/max ranges + const shortname_with_customname = entity.slice(2).split('>')[0]; + const shortname = shortname_with_customname.split('|')[0]; + const new_custom_name = shortname_with_customname.split('|')[1]; + const has_min_max = entity.slice(2).split('>')[1]; + + // find in de + const de_objIndex = de.findIndex((obj: any) => obj.id === shortname); + let fullname = ''; + let new_fullname = ''; + if (de_objIndex !== -1) { + // get current name + if (de[de_objIndex].cn) { + fullname = de[de_objIndex].cn; + } else { + fullname = de[de_objIndex].n; + } + + // find in dd, either looking for fullname or custom name + // console.log('looking for ' + fullname + ' in ' + dd.data); + const dd_objIndex = dd.data.findIndex((obj: any) => obj.id.slice(2) === fullname); + if (dd_objIndex !== -1) { + let changed = new Boolean(false); + + // see if the mask has changed + const old_mask = parseInt(dd.data[dd_objIndex].id.slice(0, 2), 16); + if (old_mask !== current_mask) { + changed = true; + console.log('mask has changed to ' + current_mask.toString(16)); + } + + // see if the custom name has changed + const old_custom_name = dd.data[dd_objIndex].cn; + console.log('comparing names, old (' + old_custom_name + ') with new (' + new_custom_name + ')'); + if (old_custom_name !== new_custom_name) { + changed = true; + new_fullname = new_custom_name; + console.log('name has changed to ' + new_custom_name); + } else { + new_fullname = fullname; + } + + // see if min or max has changed + // get current min/max values if they exist + const current_min = dd.data[dd_objIndex].min; + const current_max = dd.data[dd_objIndex].max; + let new_min = current_min; + let new_max = current_max; + if (has_min_max) { + new_min = parseInt(has_min_max.split('<')[0]); + new_max = parseInt(has_min_max.split('<')[1]); + if (current_min !== new_min || current_max !== new_max) { + changed = true; + console.log('min/max has changed to ' + new_min + '/' + new_max); + } + } + + if (changed === true) { + de[de_objIndex].m = current_mask; + de[de_objIndex].cn = new_fullname; + if (new_min) { + de[de_objIndex].mi = new_min; + } + if (new_max) { + de[de_objIndex].ma = new_max; + } + dd.data[dd_objIndex].id = current_mask.toString(16).padStart(2, '0') + new_fullname; + dd.data[dd_objIndex].cn = new_fullname; + } + } + } +} + +// START DATA + +// LOG +const LOG_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'logSettings'; +let log_settings = { + level: 6, + max_messages: 50, + compact: false +}; + +const FETCH_LOG_ENDPOINT = REST_ENDPOINT_ROOT + 'fetchLog'; +const fetch_log = { + events: [ + { + t: '000+00:00:00.001', + l: 3, + i: 1, + n: 'system', + m: 'this is message 3' + }, + { + t: '000+00:00:00.002', + l: 4, + i: 2, + n: 'ntp', + m: 'this is message 4' + }, + { + t: '000+00:00:00.002', + l: 5, + i: 3, + n: 'mqtt', + m: 'this is message 5' + }, + { + t: '000+00:00:00.002', + l: 6, + i: 444, + n: 'command', + m: 'this is message 6' + }, + { + t: '000+00:00:00.002', + l: 7, + i: 5555, + n: 'emsesp', + m: 'this is message 7' + }, + { + t: '000+00:00:00.002', + l: 8, + i: 666666, + n: 'thermostat', + m: 'this is message 8' + } + ] +}; + +// NTP +const NTP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'ntpStatus'; +const NTP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'ntpSettings'; +const TIME_ENDPOINT = REST_ENDPOINT_ROOT + 'time'; +let ntp_settings = { + enabled: true, + server: 'time.google.com', + tz_label: 'Europe/Amsterdam', + tz_format: 'CET-1CEST,M3.5.0,M10.5.0/3' +}; +const ntp_status = { + status: 1, + utc_time: '2021-04-01T14:25:42Z', + local_time: '2021-04-01T16:25:42', + server: 'time.google.com', + uptime: 856 +}; + +// AP +const AP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'apSettings'; +const AP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'apStatus'; +let ap_settings = { + provision_mode: 1, + ssid: 'ems-esp', + password: 'ems-esp-neo', + local_ip: '192.168.4.1', + gateway_ip: '192.168.4.1', + subnet_mask: '255.255.255.0', + channel: 1, + ssid_hidden: true, + max_clients: 4 +}; +const ap_status = { + status: 1, + ip_address: '192.168.4.1', + mac_address: '3C:61:05:03:AB:2D', + station_num: 0 +}; + +// NETWORK +const NETWORK_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'networkSettings'; +const NETWORK_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'networkStatus'; +const SCAN_NETWORKS_ENDPOINT = REST_ENDPOINT_ROOT + 'scanNetworks'; +const LIST_NETWORKS_ENDPOINT = REST_ENDPOINT_ROOT + 'listNetworks'; +let network_settings = { + ssid: 'myWifi', + password: 'myPassword', + hostname: 'ems-esp', + nosleep: true, + tx_power: 20, + bandwidth20: false, + static_ip_config: false, + enableMDNS: true, + enableCORS: false, + CORSOrigin: '*', + enableIPv6: false, + local_ip: '', + gateway_ip: '', + subnet_mask: '', + dns_ip_1: '', + dns_ip_2: '' +}; +const network_status = { + status: 3, + local_ip: '10.10.10.101', + mac_address: '3C:61:05:03:AB:2C', + rssi: -41, + ssid: 'home', + bssid: '06:ED:DA:FE:B4:68', + channel: 11, + subnet_mask: '255.255.255.0', + gateway_ip: '10.10.10.1', + dns_ip_1: '10.10.10.1', + dns_ip_2: '0.0.0.0' +}; +const list_networks = { + networks: [ + { + rssi: -40, + ssid: '', + bssid: 'FC:EC:DA:FD:B4:68', + channel: 11, + encryption_type: 3 + }, + { + rssi: -41, + ssid: 'home', + bssid: '02:EC:DA:FD:B4:68', + channel: 11, + encryption_type: 3 + }, + { + rssi: -42, + ssid: '', + bssid: '06:EC:DA:FD:B4:68', + channel: 11, + encryption_type: 3 + }, + { + rssi: -73, + ssid: '', + bssid: 'FC:EC:DA:17:D4:7E', + channel: 1, + encryption_type: 3 + }, + { + rssi: -73, + ssid: 'office', + bssid: '02:EC:DA:17:D4:7E', + channel: 1, + encryption_type: 3 + }, + { + rssi: -75, + ssid: 'Erica', + bssid: 'C8:D7:19:9A:88:BD', + channel: 2, + encryption_type: 3 + }, + { + rssi: -75, + ssid: '', + bssid: 'C6:C9:E3:FF:A5:DE', + channel: 2, + encryption_type: 3 + }, + { + rssi: -76, + ssid: 'Bruin', + bssid: 'C0:C9:E3:FF:A5:DE', + channel: 2, + encryption_type: 3 + } + ] +}; + +// OTA +const OTA_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'otaSettings'; +let ota_settings = { + enabled: true, + port: 8266, + password: 'ems-esp-neo' +}; + +// MQTT +const MQTT_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'mqttSettings'; +const MQTT_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'mqttStatus'; +let mqtt_settings = { + enabled: true, + host: '192.168.1.4', + port: 1883, + base: 'ems-esp', + username: '', + password: '', + client_id: 'ems-esp', + keep_alive: 60, + clean_session: true, + entity_format: 1, + publish_time_boiler: 10, + publish_time_thermostat: 10, + publish_time_solar: 10, + publish_time_mixer: 10, + publish_time_other: 10, + publish_time_sensor: 10, + publish_time_heartbeat: 60, + mqtt_qos: 0, + rootCA: '', + mqtt_retain: false, + ha_enabled: true, + nested_format: 1, + discovery_type: 0, + discovery_prefix: 'homeassistant', + send_response: true, + publish_single: false +}; +const mqtt_status = { + enabled: true, + connected: true, + client_id: 'ems-esp', + disconnect_reason: 0, + mqtt_fails: 0, + mqtt_queued: 1, + connect_count: 2 +}; + +// SYSTEM +const FEATURES_ENDPOINT = REST_ENDPOINT_ROOT + 'features'; +const VERIFY_AUTHORIZATION_ENDPOINT = REST_ENDPOINT_ROOT + 'verifyAuthorization'; +const SYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'systemStatus'; +const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings'; +const RESTART_ENDPOINT = REST_ENDPOINT_ROOT + 'restart'; +const FACTORY_RESET_ENDPOINT = REST_ENDPOINT_ROOT + 'factoryReset'; +const UPLOAD_FILE_ENDPOINT = REST_ENDPOINT_ROOT + 'uploadFile'; +const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn'; +const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'; +const system_status = { + emsesp_version: '3.6-demo', + esp_platform: 'ESP32', + max_alloc_heap: 89, + psram_size: 0, + free_psram: 0, + cpu_freq_mhz: 240, + free_heap: 143, + sdk_version: 'v4.4.2', + flash_chip_size: 4096, + flash_chip_speed: 40000000, + fs_used: 40, + fs_free: 24, + app_used: 1863, + app_free: 121, + uptime: '000+00:15:42.707' +}; +let security_settings = { + jwt_secret: 'naughty!', + users: [ + { username: 'admin', password: 'admin', admin: true }, + { username: 'guest', password: 'guest', admin: false } + ] +}; +const features = { + project: true, + security: true, + mqtt: true, + ntp: true, + ota: true, + upload_firmware: true, + version: 'v3.6-demo', + // platform: 'ESP32' + platform: 'ESP32-S3' +}; +const verify_authentication = { access_token: '1234' }; +const signin = { + access_token: + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWUsInZlcnNpb24iOiIzLjAuMmIwIn0.MsHSgoJKI1lyYz77EiT5ZN3ECMrb4mPv9FNy3udq0TU' +}; +const generate_token = { token: '1234' }; + +// EMS-ESP Project specific +const EMSESP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'settings'; +const EMSESP_CORE_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'coreData'; +const EMSESP_SENSOR_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'sensorData'; +const EMSESP_DEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'devices'; +const EMSESP_SCANDEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'scanDevices'; +const EMSESP_DEVICEDATA_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceData/:id'; +const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities/:id'; +const EMSESP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'status'; +const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'; +const EMSESP_WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue'; +const EMSESP_WRITE_SENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeTemperatureSensor'; +const EMSESP_WRITE_ANALOG_ENDPOINT = REST_ENDPOINT_ROOT + 'writeAnalogSensor'; +const EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customizationEntities'; +const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations'; +const EMSESP_WRITE_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule'; +const EMSESP_WRITE_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'entities'; + +const emsesp_info = { + System: { + version: '3.6-demo', + uptime: '001+06:40:34.018', + 'uptime (seconds)': 110434, + freemem: 131, + 'reset reason': 'Software reset CPU / Software reset CPU', + 'Dallas sensors': 3 + }, + Network: { + connection: 'Ethernet', + hostname: 'ems-esp', + MAC: 'A8:03:2A:62:64:CF', + 'IPv4 address': '192.168.1.134/255.255.255.0', + 'IPv4 gateway': '192.168.1.1', + 'IPv4 nameserver': '192.168.1.1' + }, + Status: { + 'bus status': 'connected', + 'bus protocol': 'Buderus', + 'telegrams received': 84986, + 'read requests sent': 14748, + 'write requests sent': 3, + 'incomplete telegrams': 8, + 'tx fails': 0, + 'rx line quality': 100, + 'tx line quality': 100, + MQTT: 'connected', + 'MQTT publishes': 46336, + 'MQTT publish fails': 0, + 'Dallas reads': 22086, + 'Dallas fails': 0 + }, + Devices: [ + { + type: 'Boiler', + name: 'Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i (DeviceID:0x08 ProductID:123, Version:06.01)', + handlers: + '0x10 0x11 0xC2 0x14 0x15 0x1C 0x18 0x19 0x1A 0x35 0x16 0x33 0x34 0x26 0x2A 0xD1 0xE3 0xE4 0xE5 0xE6 0xE9 0xEA' + }, + { + type: 'Thermostat', + name: 'RC20/Moduline 300 (DeviceID:0x17, ProductID:77, Version:03.03)', + handlers: '0xA3 0x06 0xA2 0x12 0x91 0xA8' + } + ] +}; + +const emsesp_allvalues = { + 'Boiler Nefit GBx72/Trendline/Cerapur/Greenstar Si (DeviceID:0x08, ProductID:123, Version:06.01)': { + 'force heating off': 'off', + 'heating active': 'off', + 'tapwater active': 'off', + 'selected flow temperature': 5, + 'heating pump modulation': 0, + 'current flow temperature': 41.4, + 'return temperature': 37.7, + 'system pressure': 1.3, + 'actual boiler temperature': 44.2, + gas: 'off', + 'gas stage 2': 'off', + 'flame current': 0, + fan: 'off', + ignition: 'off', + 'oil preheating': 'off', + 'burner min power': 0, + 'burner max power': 50, + 'burner min period': 10, + 'hysteresis on temperature': -6, + 'hysteresis off temperature': 6, + 'heating activated': 'on', + 'heating temperature': 70, + 'heating pump': 'off', + 'boiler pump max power': 70, + 'boiler pump min power': 50, + 'boiler pump mode': 'proportional', + 'pump delay': 2, + 'burner selected max power': 0, + 'burner current power': 0, + 'burner starts': 394602, + 'total burner operating time': '480 days 4 hours 23 minutes', + 'burner stage 2 operating time': '0 days 0 hours 0 minutes', + 'total heat operating time': '395 days 2 hours 14 minutes', + 'burner starts heating': 46245, + 'total UBA operating time': '3932 days 23 hours 58 minutes', + 'last error code': '2E(207) 100.75.2000 65:00 (0 min)', + 'service code': '0H', + 'service code number': 203, + 'maintenance message': 'H00', + 'maintenance scheduled': 'manual', + 'time to next maintenance': 6000, + 'next maintenance date': '01.01.2012', + 'dhw turn on/off': 'on', + 'dhw set temperature': 62, + 'dhw selected temperature': 60, + 'dhw type': 'flow', + 'dhw comfort': 'hot', + 'dhw flow temperature offset': 40, + 'dhw max power': 100, + 'dhw circulation pump available': 'off', + 'dhw charging type': '3-way valve', + 'dhw hysteresis on temperature': -5, + 'dhw hysteresis off temperature': 0, + 'dhw disinfection temperature': 70, + 'dhw circulation pump mode': 'off', + 'dhw circulation active': 'off', + 'dhw current intern temperature': 33.5, + 'dhw current tap water flow': 0, + 'dhw storage intern temperature': 33.5, + 'dhw activated': 'on', + 'dhw one time charging': 'off', + 'dhw disinfecting': 'off', + 'dhw charging': 'off', + 'dhw recharging': 'off', + 'dhw temperature ok': 'on', + 'dhw active': 'off', + 'dhw 3-way valve active': 'on', + 'dhw set pump power': 0, + 'dhw starts': 348357, + 'dhw active time': '85 days 2 hours 9 minutes', + 'nominal Power': 30, + 'total energy': 3088.69, + 'energy heating': 2532.94, + 'dhw energy': 555.75 + }, + 'Thermostat RC20/Moduline 300 (DeviceID:0x17, ProductID:77, Version:03.03)': { + 'date/time': '10.12.2023 13:49', + 'hc1 how hot lounge should be': 19, + 'hc1 current room temp': 19.5, + 'hc1 Discovery current room temperature': 'roomTemp', + 'hc1 mode': 'auto', + 'hc1 manual temperature': 21.5, + 'hc1 temperature when mode is off': 7, + 'hc1 day temperature T2': 20, + 'hc1 day temperature T3': 20, + 'hc1 day temperature T4': 20, + 'hc1 night temperature T1': 15, + 'hc1 program switchtime': '00 mo 00:00 T1' + }, + 'Controller Module BC10 (DeviceID:0x09, ProductID:190, Version:01.03)': {}, + 'Custom Entities': { + boiler_flowtemp: 5, + nominalpower: 30, + minmodulation: 23, + maxmodulation: 115 + }, + 'Analog Sensors': {}, + 'Temperature Sensors': { + zolder: 18.3 + } +}; + +let settings = { + locale: 'en', + tx_mode: 4, + ems_bus_id: 11, + syslog_enabled: false, + syslog_level: 3, + trace_raw: false, + syslog_mark_interval: 0, + syslog_host: '192.168.1.4', + syslog_port: 514, + shower_timer: true, + shower_alert: true, + shower_alert_trigger: 7, + shower_alert_coldshot: 10, + rx_gpio: 23, + tx_gpio: 5, + phy_type: 0, + eth_power: 0, + eth_phy_addr: 0, + eth_clock_mode: 0, + dallas_gpio: 3, + dallas_parasite: false, + led_gpio: 2, + hide_led: false, + notoken_api: false, + readonly_mode: false, + low_clock: false, + boiler_heatingoff: false, + telnet_enabled: true, + analog_enabled: false, + pbutton_gpio: 0, + board_profile: 'S32', + bool_format: 1, + bool_dashboard: 1, + enum_format: 1, + fahrenheit: false +}; + +const emsesp_devices = { + devices: [ + { + i: 2, + s: 'Thermostat (RC20/Moduline 300)', + t: 5, + tn: 'thermostat' + }, + { + i: 7, + s: 'Boiler (GBx72/Trendline/Cerapur/Greenstar Si/27i)', + t: 4, + tn: 'boiler' + }, + { + i: 4, + s: 'Thermostat (RC100/Moduline 1000/1010)', + t: 5, + tn: 'thermostat' + } + ] +}; + +const emsesp_coredata = { + connected: true, + // devices: [], + devices: [ + { + id: 7, + t: 4, + tn: 'Boiler', + b: 'Nefit', + n: 'GBx72/Trendline/Cerapur/Greenstar Si/27i', + // n: 'Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i', + d: 8, + p: 123, + v: '06.01', + e: 69 + }, + { + id: 3, + t: 4, + tn: 'Boiler', + b: 'Buderus', + n: 'GB125/GB135/MC10', + d: 8, + p: 123, + v: '06.01', + e: 73 + }, + { + id: 1, + t: 5, + tn: 'Thermostat', + b: 'Buderus', + n: 'RC35', + d: 24, + p: 86, + v: '04.01', + e: 57 + }, + { + id: 2, + t: 5, + tn: 'Thermostat', + b: '', + n: 'RC20/Moduline 300', + d: 23, + p: 77, + v: '03.03', + e: 6 + }, + { + id: 4, + t: 5, + tn: 'Thermostat', + b: 'Buderus', + n: 'RC100/Moduline 1000/1010', + d: 16, + p: 165, + v: '04.01', + e: 3 + }, + { + id: 5, + t: 6, + tn: 'Mixer Module', + b: 'Buderus', + n: 'MM10', + d: 32, + p: 69, + v: '01.01', + e: 6 + }, + { + id: 6, + t: 7, + tn: 'Solar Module', + b: 'Buderus', + n: 'SM10', + d: 48, + p: 73, + v: '01.02', + e: 22 + }, + { + id: 99, + t: 17, + tn: 'Custom', + b: '', + n: 'User defined entities', + d: 1, + p: 1, + v: '', + e: 1 + } + ] +}; + +const emsesp_sensordata = { + // ts: [], + ts: [ + { id: '28-233D-9497-0C03', n: 'Dallas 1', t: 25.7, o: 1.2, u: 1 }, + { id: '28-243D-7437-1E3A', n: 'Dallas 2 outside', t: 26.1, o: 0, u: 1 }, + { id: '28-243E-7437-1E3B', n: 'Zolder', t: 27.1, o: 0, u: 16 }, + { id: '28-183D-1892-0C33', n: 'Roof', o: 2, u: 1 } // no temperature + ], + // as: [], + as: [ + { id: 1, g: 36, n: 'motor', v: 0, u: 0, o: 17, f: 0, t: 0, d: false }, + { id: 2, g: 37, n: 'External switch', v: 13, u: 0, o: 17, f: 0, t: 1, d: false }, + { id: 3, g: 39, n: 'Pulse count', v: 144, u: 0, o: 0, f: 0, t: 2, d: false }, + { id: 4, g: 40, n: 'Pressure', v: 16, u: 17, o: 0, f: 0, t: 3, d: false } + ], + analog_enabled: true +}; + +const status = { + status: 0, + // status: 2, + tx_mode: 1, + uptime: 77186, + num_devices: 2, + num_sensors: 1, + num_analogs: 1, + stats: [ + { id: 0, s: 56506, f: 11, q: 100 }, + { id: 1, s: 9026, f: 0, q: 100 }, + { id: 2, s: 33, f: 2, q: 95 }, + { id: 3, s: 56506, f: 11, q: 100 }, + { id: 4, s: 0, f: 0, q: 100 }, + { id: 5, s: 12, f: 10, q: 20 }, + { id: 6, s: 0, f: 0, q: 0 } + ] +}; + +// Dashboard data +// 1 - RC35 thermo +// 2 - RC20 thermo +// 3 - Buderus GB125 boiler +// 4 - RC100 themo +// 5 - Mixer MM10 +// 6 - Solar SM10 +// 7 - Nefit Trendline boiler +// 99 - Custom + +const emsesp_devicedata_1 = { + data: [ + { + v: '22(816) 01.05.2023 13:07 (1 min)', + u: 0, + id: '00last error code' + }, + { + v: '05.05.2023 09:44', + u: 0, + id: '00date/time', + c: 'datetime', + h: '< NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >' + }, + { + v: -2.4, + u: 2, + id: '00internal temperature offset', + c: 'intoffset', + m: -5, + x: 5, + s: 0.1 + }, + { + v: -11, + u: 1, + id: '00minimal external temperature', + c: 'minexttemp', + m: -30, + x: 0, + s: 1 + }, + { + v: 29.5, + u: 1, + id: '00temperature sensor 1' + }, + { + v: 32.5, + u: 1, + id: '00temperature sensor 2' + }, + { + v: 'on', + u: 0, + id: '00damping outdoor temperature', + c: 'damping', + l: ['off', 'on'] + }, + { + v: 13, + u: 1, + id: '00damped outdoor temperature' + }, + { + v: 'medium', + u: 0, + id: '00building type', + c: 'building', + l: ['light', 'medium', 'heavy'] + }, + { + v: 'auto', + u: 0, + id: '00dhw mode', + c: 'wwmode', + l: ['off', 'on', 'auto'] + }, + { + v: 'off', + u: 0, + id: '00dhw circulation pump mode', + c: 'wwcircmode', + l: ['off', 'on', 'auto'] + }, + { + v: 'std prog', + u: 0, + id: '00dhw program', + c: 'wwprogmode', + l: ['std prog', 'own prog'] + }, + { + v: 'std prog', + u: 0, + id: '00dhw circulation program', + c: 'wwcircprog', + l: ['std prog', 'own prog'] + }, + { + v: 'off', + u: 0, + id: '00dhw disinfecting', + c: 'wwdisinfecting', + l: ['off', 'on'] + }, + { + v: 'tu', + u: 0, + id: '00dhw disinfection day', + c: 'wwdisinfectday', + l: ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su', 'all'] + }, + { + v: 1, + u: 0, + id: '00dhw disinfection hour', + c: 'wwdisinfecthour', + m: 0, + x: 23, + s: 1 + }, + { + v: 60, + u: 1, + id: '00dhw maximmu temperature', + c: 'wwmaxtemp', + m: 60, + x: 80, + s: 1 + }, + { + v: 'on', + u: 0, + id: '00dhw one time key function', + c: 'wwonetimekey', + l: ['off', 'on'] + }, + { + v: '00 mo 06:00 on', + u: 0, + id: '00dhw program switchtime', + c: 'wwswitchtime', + h: ' [ not_set | day hh:mm on|off ]' + }, + { + v: '00 mo 06:30 on', + u: 0, + id: '00dhw circulation program switchtime', + c: 'wwcircswitchtime', + h: ' [ not_set | day hh:mm on|off ]' + }, + { + v: '01.01.2000-01.01.2000', + u: 0, + id: '00dhw holiday dates', + c: 'wwholidays', + h: 'dd.mm.yyyy-dd.mm.yyyy' + }, + { + v: '01.01.2019-12.01.2019', + u: 0, + id: '00dhw vacation dates', + c: 'wwvacations', + h: 'dd.mm.yyyy-dd.mm.yyyy' + }, + { + v: 21, + u: 1, + id: '00hc2 selected room temperature', + c: 'hc2/seltemp', + m: 0, + x: 30, + s: 0.5 + }, + { + v: 'auto', + u: 0, + id: '00hc2 mode', + c: 'hc2/mode', + l: ['night', 'day', 'auto'] + }, + { + v: 'day', + u: 0, + id: '00hc2 mode type' + }, + { + v: 21, + u: 1, + id: '00hc2 day temperature', + c: 'hc2/daytemp', + m: 5, + x: 30, + s: 0.5 + }, + { + v: 17, + u: 1, + id: '00hc2 night temperature', + c: 'hc2/nighttemp', + m: 5, + x: 30, + s: 0.5 + }, + { + v: 58, + u: 1, + id: '00hc2 design temperature', + c: 'hc2/designtemp', + m: 30, + x: 90, + s: 1 + }, + { + v: 0, + u: 2, + id: '00hc2 offset temperature', + c: 'hc2/offsettemp', + m: -5, + x: 5, + s: 0.5 + }, + { + v: 15, + u: 1, + id: '00hc2 holiday temperature', + c: 'hc2/holidaytemp', + m: 5, + x: 30, + s: 0.5 + }, + { + v: 34, + u: 1, + id: '00hc2 target flow temperature' + }, + { + v: 17, + u: 1, + id: '00hc2 summer temperature', + c: 'hc2/summertemp', + m: 9, + x: 25, + s: 1 + }, + { + v: 'winter', + u: 0, + id: '00hc2 summer mode' + }, + { + v: 'off', + u: 0, + id: '00hc2 holiday mode' + }, + { + v: -10, + u: 1, + id: '00hc2 nofrost temperature', + c: 'hc2/nofrosttemp', + m: -20, + x: 10, + s: 1 + }, + { + v: 'outdoor', + u: 0, + id: '00hc2 nofrost mode', + c: 'hc2/nofrostmode', + l: ['off', 'outdoor', 'room'] + }, + { + v: 0, + u: 2, + id: '00hc2 room influence', + c: 'hc2/roominfluence', + m: 0, + x: 10, + s: 1 + }, + { + v: 15, + u: 1, + id: '00hc2 min flow temperature', + c: 'hc2/minflowtemp', + m: 5, + x: 70, + s: 1 + }, + { + v: 85, + u: 1, + id: '00hc2 max flow temperature', + c: 'hc2/maxflowtemp', + m: 30, + x: 90, + s: 1 + }, + { + v: 0, + u: 2, + id: '00hc2 flow temperature offset for mixer', + c: 'hc2/flowtempoffset', + m: 0, + x: 20, + s: 1 + }, + { + v: 'radiator', + u: 0, + id: '00hc2 heating type', + c: 'hc2/heatingtype', + l: ['off', 'radiator', 'convector', 'floor'] + }, + { + v: 'outdoor', + u: 0, + id: '00hc2 reduce mode', + c: 'hc2/reducemode', + l: ['nofrost', 'reduce', 'room', 'outdoor'] + }, + { + v: 'outdoor', + u: 0, + id: '00hc2 control mode', + c: 'hc2/controlmode', + l: ['outdoor', 'room'] + }, + { + v: 'RC3x', + u: 0, + id: '00hc2 control device', + c: 'hc2/control', + l: ['off', 'RC20', 'RC3x'] + }, + { + v: '01.01.2000-01.01.2000', + u: 0, + id: '00hc2 holiday dates', + c: 'hc2/holidays', + h: 'dd.mm.yyyy-dd.mm.yyyy' + }, + { + v: '01.01.2020-12.01.2020', + u: 0, + id: '00hc2 vacation dates', + c: 'hc2/vacations', + h: 'dd.mm.yyyy-dd.mm.yyyy' + }, + { + v: 'own 1', + u: 0, + id: '00hc2 program', + c: 'hc2/program', + l: ['own 1', 'family', 'morning', 'evening', 'am', 'pm', 'midday', 'singles', 'seniors', 'new', 'own 2'] + }, + { + v: 0, + u: 7, + id: '00hc2 pause time', + c: 'hc2/pause', + m: 0, + x: 99, + s: 1 + }, + { + v: 0, + u: 7, + id: '00hc2 party time', + c: 'hc2/party', + m: 0, + x: 99, + s: 1 + }, + { + v: 0, + u: 1, + id: '00hc2 temporary set temperature automode', + c: 'hc2/tempautotemp', + m: 0, + x: 30, + s: 0.5 + }, + { + v: -20, + u: 1, + id: '00hc2 no reduce below temperature', + c: 'hc2/noreducetemp', + m: -30, + x: 10, + s: 1 + }, + { + v: 8, + u: 1, + id: '00hc2 off/reduce switch temperature', + c: 'hc2/reducetemp', + m: -20, + x: 10, + s: 1 + }, + { + v: 5, + u: 1, + id: '00hc2 vacations off/reduce switch temperature', + c: 'hc2/vacreducetemp', + m: -20, + x: 10, + s: 1 + }, + { + v: 'outdoor', + u: 0, + id: '00hc2 vacations reduce mode', + c: 'hc2/vacreducemode', + l: ['nofrost', 'reduce', 'room', 'outdoor'] + }, + { + v: 'off', + u: 0, + id: '00hc2 dhw priority', + c: 'hc2/wwprio', + l: ['off', 'on'] + }, + { + v: '00 mo 05:50 on', + u: 0, + id: '00hc2 own1 program switchtime', + c: 'hc2/switchtime1', + h: ' [ not_set | day hh:mm on|off ]' + }, + { + v: '00 mo 06:30 on', + u: 0, + id: '00hc2 own2 program switchtime', + c: 'hc2/switchtime2', + h: ' [ not_set | day hh:mm on|off ]' + } + ] +}; + +const emsesp_devicedata_2 = { + data: [ + { + v: '(0)', + u: 0, + id: '08my custom error code' + }, + { + v: '14:54:39 06/06/2021', + u: 0, + id: '00date/time' + }, + { + v: 18.2, + u: 1, + id: '00Chosen Room Temperature', + c: 'hc1/seltemp', + m: 5, + x: 52, + s: 0.5 + }, + { + v: 22.6, + u: 1, + id: '00hc1 current room temperature' + }, + { + v: 'auto', + u: 0, + id: '00hc1 mode', + c: 'hc1/mode', + l: ['off', 'on', 'auto'] + }, + { + v: '00 mo 00:00 T1', + u: 0, + id: '00hc1 program switchtime', + c: 'hc1/switchtime', + h: ' [ not_set | day hh:mm Tn ]' + } + ] +}; + +const emsesp_devicedata_3 = { + data: [ + { + v: '', + u: 0, + id: '08reset', + c: 'reset', + l: ['-', 'maintenance', 'error'] + }, + { + v: 34, + u: 1, + id: '08selected flow temperature', + c: 'selflowtemp', + m: 0, + x: 90, + s: 1 + }, + { + v: 30.7, + u: 1, + id: '08current flow temperature' + }, + { + v: 176544, + u: 0, + id: '08burner starts' + }, + { + v: '6L(517) 18.01.2023 10:18 (0 min)', + u: 0, + id: '08last error code' + }, + { + v: 'off', + u: 0, + id: '00force heating off', + c: 'heatingoff', + l: ['off', 'on'] + }, + { + v: 'off', + u: 0, + id: '00heating active' + }, + { + v: 'off', + u: 0, + id: '00tapwater active' + }, + { + v: 0, + u: 3, + id: '00heating pump modulation' + }, + { + v: 15, + u: 1, + id: '00outside temperature' + }, + { + v: 30.7, + u: 1, + id: '00actual boiler temperature' + }, + { + v: 29, + u: 1, + id: '00exhaust temperature' + }, + { + v: 'off', + u: 0, + id: '00gas' + }, + { + v: 'off', + u: 0, + id: '00gas stage 2' + }, + { + v: 0, + u: 9, + id: '00flame current' + }, + { + v: 'off', + u: 0, + id: '00heating pump' + }, + { + v: 'off', + u: 0, + id: '00fan' + }, + { + v: 'off', + u: 0, + id: '00ignition' + }, + { + v: 'off', + u: 0, + id: '00oil preheating' + }, + { + v: 'on', + u: 0, + id: '00heating activated', + c: 'heatingactivated', + l: ['off', 'on'] + }, + { + v: 90, + u: 1, + id: '00heating temperature', + c: 'heatingtemp', + m: 0, + x: 90, + s: 1 + }, + { + v: 100, + u: 3, + id: '00boiler pump max power', + c: 'pumpmodmax', + m: 0, + x: 100, + s: 1 + }, + { + v: 100, + u: 3, + id: '00boiler pump min power', + c: 'pumpmodmin', + m: 0, + x: 100, + s: 1 + }, + { + v: 'deltaP-2', + u: 0, + id: '00boiler pump mode', + c: 'pumpmode', + l: ['proportional', 'deltaP-1', 'deltaP-2', 'deltaP-3', 'deltaP-4'] + }, + { + v: 6, + u: 8, + id: '00pump delay', + c: 'pumpdelay', + m: 0, + x: 60, + s: 1 + }, + { + v: 15, + u: 8, + id: '00burner min period', + c: 'burnminperiod', + m: 0, + x: 120, + s: 1 + }, + { + v: 0, + u: 3, + id: '00burner min power', + c: 'burnminpower', + m: 0, + x: 100, + s: 1 + }, + { + v: 100, + u: 3, + id: '00burner max power', + c: 'burnmaxpower', + m: 0, + x: 254, + s: 1 + }, + { + v: -8, + u: 2, + id: '00hysteresis on temperature', + c: 'boilhyston', + m: -20, + x: 0, + s: 1 + }, + { + v: 15, + u: 2, + id: '00hysteresis off temperature', + c: 'boilhystoff', + m: 0, + x: 20, + s: 1 + }, + { + v: -8, + u: 2, + id: '00hysteresis stage 2 on temperature', + c: 'boil2hyston', + m: -20, + x: 0, + s: 1 + }, + { + v: 8, + u: 2, + id: '00hysteresis stage 2 off temperature', + c: 'boil2hystoff', + m: 0, + x: 20, + s: 1 + }, + { + v: 34, + u: 1, + id: '00set flow temperature' + }, + { + v: 100, + u: 3, + id: '00burner set power' + }, + { + v: 100, + u: 3, + id: '00burner selected max power', + c: 'selburnpow', + m: 0, + x: 254, + s: 1 + }, + { + v: 0, + u: 3, + id: '00burner current power' + }, + { + v: 822273, + u: 8, + id: '00total burner operating time' + }, + { + v: 0, + u: 8, + id: '00burner stage 2 operating time' + }, + { + v: 787124, + u: 8, + id: '00total heat operating time' + }, + { + v: 173700, + u: 0, + id: '00burner starts heating' + }, + { + v: 5495341, + u: 8, + id: '00total UBA operating time' + }, + { + v: '0Y', + u: 0, + id: '00service code' + }, + { + v: 0, + u: 0, + id: '00service code number' + }, + { + v: 'H00', + u: 0, + id: '00maintenance message' + }, + { + v: 'date', + u: 0, + id: '00maintenance scheduled', + c: 'maintenance', + l: ['off', 'time', 'date', 'manual'] + }, + { + v: 6000, + u: 7, + id: '00time to next maintenance', + c: 'maintenancetime', + m: 0, + x: 31999, + s: 1 + }, + { + v: '30.06.2023', + u: 0, + id: '00next maintenance date', + c: 'maintenancedate', + h: 'dd.mm.yyyy' + }, + { + v: 46, + u: 1, + id: '00dhw set temperature' + }, + { + v: 47, + u: 1, + id: '00dhw selected temperature', + c: 'wwseltemp', + m: 0, + x: 254, + s: 1 + }, + { + v: 'buffer', + u: 0, + id: '00dhw type' + }, + { + v: 'hot', + u: 0, + id: '00dhw comfort', + c: 'wwcomfort', + l: ['hot', 'eco', 'intelligent'] + }, + { + v: 40, + u: 2, + id: '00dhw flow temperature offset', + c: 'wwflowtempoffset', + m: 0, + x: 100, + s: 1 + }, + { + v: 'on', + u: 0, + id: '00dhw circulation pump available', + c: 'wwcircpump', + l: ['off', 'on'] + }, + { + v: 'chargepump', + u: 0, + id: '00dhw charging type' + }, + { + v: -5, + u: 2, + id: '00dhw hysteresis on temperature', + c: 'wwhyston', + m: -126, + x: 126, + s: 1 + }, + { + v: -1, + u: 2, + id: '00dhw hysteresis off temperature', + c: 'wwhystoff', + m: -126, + x: 126, + s: 1 + }, + { + v: 70, + u: 1, + id: '00dhw disinfection temperature', + c: 'wwdisinfectiontemp', + m: 0, + x: 254, + s: 1 + }, + { + v: 'continuous', + u: 0, + id: '00dhw circulation pump mode', + c: 'wwcircmode', + l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] + }, + { + v: 'off', + u: 0, + id: '00dhw circulation active', + c: 'wwcirc', + l: ['off', 'on'] + }, + { + v: 60.7, + u: 1, + id: '00dhw current intern temperature' + }, + { + v: 0, + u: 4, + id: '00dhw current tap water flow' + }, + { + v: 60.7, + u: 1, + id: '00dhw storage intern temperature' + }, + { + v: 'on', + u: 0, + id: '00dhw activated', + c: 'wwactivated', + l: ['off', 'on'] + }, + { + v: 'off', + u: 0, + id: '00dhw one time charging', + c: 'wwonetime', + l: ['off', 'on'] + }, + { + v: 'off', + u: 0, + id: '00dhw disinfecting', + c: 'wwdisinfecting', + l: ['off', 'on'] + }, + { + v: 'off', + u: 0, + id: '00dhw charging' + }, + { + v: 'off', + u: 0, + id: '00dhw recharging' + }, + { + v: 'on', + u: 0, + id: '00dhw temperature ok' + }, + { + v: 'off', + u: 0, + id: '00dhw active' + }, + { + v: 'off', + u: 0, + id: '00dhw 3-way valve active' + }, + { + v: 0, + u: 3, + id: '00dhw set pump power' + }, + { + v: 6976, + u: 0, + id: '00dhw starts' + }, + { + v: 80644, + u: 8, + id: '00dhw active time' + } + ] +}; + +const emsesp_devicedata_4 = { + data: [ + { + v: 16, + u: 1, + id: '08hc2 selected room temperature', + c: 'hc2/seltemp' + }, + { + v: 18.6, + u: 1, + id: '02hc2 current room temperature', + c: '' + }, + { + v: 'off', + u: 0, + id: '02hc2 mode', + c: 'hc2/mode', + l: ['off', 'on', 'auto'] + } + ] +}; + +const emsesp_devicedata_5 = { + data: [ + { + v: 30, + u: 1, + id: '00hc2 flow temperature (TC1)' + }, + { + v: 100, + u: 3, + id: '00hc2 mixing valve actuator (VC1)' + }, + { + v: 34, + u: 1, + id: '00hc2 setpoint flow temperature', + c: 'hc2/flowsettemp', + m: 0, + x: 254, + s: 1 + }, + { + v: 'off', + u: 0, + id: '00hc2 pump status (PC1)', + c: 'hc2/pumpstatus', + l: ['off', 'on'] + }, + { + v: 'on', + u: 0, + id: '00hc2 activated', + c: 'hc2/activated', + l: ['off', 'on'] + }, + { + v: 120, + u: 14, + id: '00hc2 time to set valve', + c: 'hc2/valvesettime', + m: 10, + x: 120, + s: 10 + } + ] +}; + +const emsesp_devicedata_6 = { + data: [ + { + v: 43.9, + u: 1, + id: '00collector temperature (TS1)' + }, + { + v: 28.3, + u: 1, + id: '00cylinder bottom temperature (TS2)' + }, + { + v: 'on', + u: 0, + id: '00pump (PS1)' + }, + { + v: 181884, + u: 8, + id: '00pump working time' + }, + { + v: 90, + u: 1, + id: '00maximum cylinder temperature', + c: 'cylmaxtemp', + m: 0, + x: 254, + s: 1 + }, + { + v: 'off', + u: 0, + id: '00collector shutdown' + }, + { + v: 'off', + u: 0, + id: '00cyl heated' + }, + { + v: 32, + u: 3, + id: '00pump modulation (PS1)' + }, + { + v: 30, + u: 3, + id: '00minimum pump modulation', + c: 'pumpminmod', + m: 0, + x: 100, + s: 1 + }, + { + v: 10, + u: 2, + id: '00pump turn on difference', + c: 'turnondiff', + m: 0, + x: 254, + s: 1 + }, + { + v: 5, + u: 2, + id: '00pump turn off difference', + c: 'turnoffdiff', + m: 0, + x: 254, + s: 1 + }, + { + v: 899, + u: 12, + id: '00actual solar power' + }, + { + v: 94, + u: 6, + id: '00energy last hour' + }, + { + v: 3, + u: 4, + id: '00maximum solar flow', + c: 'maxflow', + m: 0, + x: 25, + s: 0.1 + }, + { + v: 37, + u: 1, + id: '00dhw minimum temperature', + c: 'wwmintemp', + m: 0, + x: 254, + s: 1 + }, + { + v: 'on', + u: 0, + id: '00solarmodule enabled', + c: 'solarenabled', + l: ['off', 'on'] + }, + { + v: 11, + u: 0, + id: '00unknown setting 3', + c: 'setting3', + m: 0, + x: 254, + s: 1 + }, + { + v: 2, + u: 0, + id: '00unknown setting 4', + c: 'setting4', + m: 0, + x: 254, + s: 1 + }, + { + v: 0, + u: 0, + id: '00unknown datafield 11' + }, + { + v: 1, + u: 0, + id: '00unknown datafield 12' + }, + { + v: 0, + u: 0, + id: '00unknown datafield 1' + }, + { + v: 0, + u: 0, + id: '00unknown datafield 0' + } + ] +}; + +const emsesp_devicedata_7 = { + data: [ + { v: '', u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] }, + { v: 'off', u: 0, id: '08heating active' }, + { v: 'off', u: 0, id: '04tapwater active' }, + { v: 5, u: 1, id: '04selected flow temperature', c: 'selflowtemp' }, + { v: 0, u: 3, id: '0Eburner selected max power', c: 'selburnpow' }, + { v: 0, u: 3, id: '00heating pump modulation' }, + { v: 53.4, u: 1, id: '00current flow temperature' }, + { v: 52.7, u: 1, id: '00return temperature' }, + { v: 1.3, u: 10, id: '00system pressure' }, + { v: 54.9, u: 1, id: '00actual boiler temperature' }, + { v: 'off', u: 0, id: '00gas' }, + { v: 'off', u: 0, id: '00gas stage 2' }, + { v: 0, u: 9, id: '00flame current' }, + { v: 'off', u: 0, id: '00heating pump' }, + { v: 'off', u: 0, id: '00fan' }, + { v: 'off', u: 0, id: '00ignition' }, + { v: 'off', u: 0, id: '00oil preheating' }, + { v: 'on', u: 0, id: '00heating activated', c: 'heatingactivated', l: ['off', 'on'] }, + { v: 80, u: 1, id: '00heating temperature', c: 'heatingtemp' }, + { v: 70, u: 3, id: '00burner pump max power', c: 'pumpmodmax' }, + { v: 30, u: 3, id: '00burner pump min power', c: 'pumpmodmin' }, + { v: 1, u: 8, id: '00pump delay', c: 'pumpdelay' }, + { v: 10, u: 8, id: '00burner min period', c: 'burnminperiod' }, + { v: 0, u: 3, id: '00burner min power', c: 'burnminpower' }, + { v: 50, u: 3, id: '00burner max power', c: 'burnmaxpower' }, + { v: -6, u: 2, id: '00hysteresis on temperature', c: 'boilhyston' }, + { v: 6, u: 2, id: '00hysteresis off temperature', c: 'boilhystoff' }, + { v: 0, u: 1, id: '00set flow temperature' }, + { v: 0, u: 3, id: '00burner set power' }, + { v: 0, u: 3, id: '00burner current power' }, + { v: 326323, u: 0, id: '00burner starts' }, + { v: 553437, u: 8, id: '00total burner operating time' }, + { v: 451286, u: 8, id: '00total heat operating time' }, + { v: 4672173, u: 8, id: '00total UBA operating time' }, + { v: '1C(210) 06.06.2020 12:07 (0 min)', u: 0, id: '00last error code' }, + { v: '0H', u: 0, id: '00service code' }, + { v: 203, u: 0, id: '00service code number' }, + { v: 'H00', u: 0, id: '00maintenance message' }, + { v: 'manual', u: 0, id: '00maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] }, + { v: 6000, u: 7, id: '00time to next maintenance', c: 'maintenancetime' }, + { v: '01.01.2012', u: 0, id: '00next maintenance date', c: 'maintenancedate', h: 'dd.mm.yyyy' }, + { v: 'on', u: 0, id: '00dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] }, + { v: 62, u: 1, id: '00dhw set temperature' }, + { v: 60, u: 1, id: '00dhw selected temperature', c: 'wwseltemp' }, + { v: 'flow', u: 0, id: '00dhw type' }, + { v: 'hot', u: 0, id: '00dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] }, + { v: 40, u: 2, id: '00dhw flow temperature offset', c: 'wwflowtempoffset' }, + { v: 100, u: 3, id: '00dhw max power', c: 'wwmaxpower' }, + { v: 'off', u: 0, id: '00dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] }, + { v: '3-way valve', u: 0, id: '00dhw charging type' }, + { v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'wwhyston' }, + { v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'wwhystoff' }, + { v: 70, u: 1, id: '00dhw disinfection temperature', c: 'wwdisinfectiontemp' }, + { + v: 'off', + u: 0, + id: '00dhw circulation pump mode', + c: 'wwcircmode', + l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'] + }, + { v: 'off', u: 0, id: '00dhw circulation active', c: 'wwcirc', l: ['off', 'on'] }, + { v: 47.3, u: 1, id: '00dhw current intern temperature' }, + { v: 0, u: 4, id: '00dhw current tap water flow' }, + { v: 47.3, u: 1, id: '00dhw storage intern temperature' }, + { v: 'on', u: 0, id: '00dhw activated', c: 'wwactivated', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw one time charging', c: 'wwonetime', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] }, + { v: 'off', u: 0, id: '00dhw charging' }, + { v: 'off', u: 0, id: '00dhw recharging' }, + { v: 'on', u: 0, id: '00dhw temperature ok' }, + { v: 'off', u: 0, id: '00dhw active' }, + { v: 'on', u: 0, id: '00dhw 3way valve active' }, + { v: 0, u: 3, id: '00dhw set pump power' }, + { v: 288768, u: 0, id: '00dhw starts' }, + { v: 102151, u: 8, id: '00dhw active time' } + ] +}; + +const emsesp_devicedata_99 = { + data: [ + { + v: 5, + u: 1, + id: '00boiler_flowtemp', + c: 'boiler_flowtemp' + } + ] +}; + +// CUSTOM ENTITIES +let emsesp_customentities = { + // entities: [] + entities: [ + { + id: 0, + device_id: 8, + type_id: 24, + offset: 0, + factor: 1, + name: 'boiler_flowtemp', + uom: 1, + value_type: 1, + writeable: true + } + ] +}; + +// SCHEDULE +let emsesp_schedule = { + schedule: [ + { + id: 1, + active: true, + flags: 6, + time: '07:30', + cmd: 'hc1/mode', + value: 'day', + name: 'day_mode' + }, + { + id: 2, + active: true, + flags: 31, + time: '23:00', + cmd: 'hc1/mode', + value: 'night', + name: 'night_mode' + }, + { + id: 3, + active: true, + flags: 10, + time: '00:00', + cmd: 'thermostat/hc2/seltemp', + value: '20', + name: 'temp_20' + }, + { + id: 4, + active: false, + flags: 1, + time: '04:00', + cmd: 'system/restart', + value: '', + name: 'auto_restart' + } + ] +}; + +// CUSTOMIZATION +const emsesp_deviceentities_1 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; +const emsesp_deviceentities_3 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; +const emsesp_deviceentities_5 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; +const emsesp_deviceentities_6 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }]; + +const emsesp_deviceentities_2 = [ + { + v: '(0)', + n: 'error code', + cn: 'my custom error code', + id: 'errorcode', + m: 8, + w: false + }, + { + v: '14:54:39 06/06/2021', + n: 'date/time', + id: 'datetime', + m: 0, + w: false + }, + { + v: 18.2, + n: 'Chosen Room Temperature', + id: 'hc1/seltemp', + m: 0, + mi: 5, + ma: 52, + w: true + }, + { + v: 22.6, + n: 'hc1 current room temperature', + id: 'hc1/curtemp', + m: 0, + w: false + }, + { + v: 'auto', + n: 'hc1 mode', + id: 'hc1/mode', + m: 0, + w: true + } +]; + +const emsesp_deviceentities_7 = [ + { u: 0, n: '!reset', id: 'reset', m: 8, w: false }, + { v: false, n: 'heating active', id: 'heatingactive', m: 8, w: false }, + { v: false, n: 'tapwater active', id: 'tapwateractive', m: 4, w: false }, + { v: 5, n: 'selected flow temperature', id: 'selflowtemp', m: 4, w: true }, + { v: 0, n: 'burner selected max power', id: 'selburnpow', m: 14, w: true }, + { v: 0, n: 'heating pump modulation', id: 'heatingpumpmod', m: 0, w: false }, + { n: 'heating pump 2 modulation', id: 'heatingpump2mod', m: 0, w: false }, + { n: 'outside temperature', id: 'outdoortemp', m: 0, w: false }, + { v: 53, n: 'current flow temperature', id: 'curflowtemp', m: 0, w: false }, + { v: 51.8, n: 'return temperature', id: 'rettemp', m: 0, w: false }, + { n: 'mixing switch temperature', id: 'switchtemp', m: 0, w: false }, + { v: 1.3, n: 'system pressure', id: 'syspress', m: 0, w: false }, + { v: 54.6, n: 'actual boiler temperature', id: 'boiltemp', m: 0, w: false }, + { n: 'exhaust temperature', id: 'exhausttemp', m: 0, w: false }, + { v: false, n: 'gas', id: 'burngas', m: 0, w: false }, + { v: false, n: 'gas stage 2', id: 'burngas2', m: 0, w: false }, + { v: 0, n: 'flame current', id: 'flamecurr', m: 0, w: false }, + { v: false, n: 'heating pump', id: 'heatingpump', m: 0, w: false }, + { v: false, n: 'fan', id: 'fanwork', m: 0, w: false }, + { v: false, n: 'ignition', id: 'ignwork', m: 0, w: false }, + { v: false, n: 'oil preheating', id: 'oilpreheat', m: 0, w: false }, + { v: true, n: 'heating activated', id: 'heatingactivated', m: 0, w: false }, + { v: 80, n: 'heating temperature', id: 'heatingtemp', m: 0, w: false }, + { v: 70, n: 'burner pump max power', id: 'pumpmodmax', m: 0, w: false }, + { v: 30, n: 'burner pump min power', id: 'pumpmodmin', m: 0, w: false }, + { v: 1, n: 'pump delay', id: 'pumpdelay', m: 0, w: false }, + { v: 10, n: 'burner min period', id: 'burnminperiod', m: 0, w: false }, + { v: 0, n: 'burner min power', id: 'burnminpower', m: 0, w: false }, + { v: 50, n: 'burner max power', id: 'burnmaxpower', m: 0, w: false }, + { v: -6, n: 'hysteresis on temperature', id: 'boilhyston', m: 0, w: false }, + { v: 6, n: 'hysteresis off temperature', id: 'boilhystoff', m: 0, w: false }, + { v: 0, n: 'set flow temperature', id: 'setflowtemp', m: 0, w: true }, + { v: 0, n: 'burner set power', id: 'setburnpow', m: 0, w: false }, + { v: 0, n: 'burner current power', id: 'curburnpow', m: 0, w: false }, + { v: 326323, n: 'burner starts', id: 'burnstarts', m: 0, w: false }, + { v: 553437, n: 'total burner operating time', id: 'burnworkmin', m: 0, w: false }, + { v: 451286, n: 'total heat operating time', id: 'heatworkmin', m: 0, w: false }, + { v: 4672175, n: 'total UBA operating time', id: 'ubauptime', m: 0, w: false }, + { v: '1C(210) 06.06.2020 12:07 (0 min)', n: 'last error code', id: 'lastcode', m: 0, w: false }, + { v: '0H', n: 'service code', id: 'servicecode', m: 0, w: false }, + { v: 203, n: 'service code number', id: 'servicecodenumber', m: 0, w: false }, + { v: 'H00', n: 'maintenance message', id: 'maintenancemessage', m: 0, w: false }, + { v: 'manual', n: 'maintenance scheduled', id: 'maintenance', m: 0, w: false }, + { v: 6000, n: 'time to next maintenance', id: 'maintenancetime', m: 0, w: false }, + { v: '01.01.2012', n: 'next maintenance date', id: 'maintenancedate', m: 0, w: false }, + { v: true, n: 'dhw turn on/off', id: 'wwtapactivated', m: 0, w: false }, + { v: 62, n: 'dhw set temperature', id: 'wwsettemp', m: 0, w: false }, + { v: 60, n: 'dhw selected temperature', id: 'wwseltemp', m: 0, w: true }, + { n: 'dhw selected lower temperature', id: 'wwseltemplow', m: 2 }, + { n: 'dhw selected temperature for off', id: 'wwseltempoff', m: 2 }, + { n: 'dhw single charge temperature', id: 'wwseltempsingle', m: 2 }, + { v: 'flow', n: 'dhw type', id: 'wwtype', m: 0, w: false }, + { v: 'hot', n: 'dhw comfort', id: 'wwcomfort', m: 0, w: false }, + { v: 40, n: 'dhw flow temperature offset', id: 'wwflowtempoffset', m: 0, w: false }, + { v: 100, n: 'dhw max power', id: 'wwmaxpower', m: 0, w: false }, + { v: false, n: 'dhw circulation pump available', id: 'wwcircpump', m: 0, w: false }, + { v: '3-way valve', n: 'dhw charging type', id: 'wwchargetype', m: 0, w: false }, + { v: -5, n: 'dhw hysteresis on temperature', id: 'wwhyston', m: 0, w: false }, + { v: 0, n: 'dhw hysteresis off temperature', id: 'wwhystoff', m: 0, w: false }, + { v: 70, n: 'dhw disinfection temperature', id: 'wwdisinfectiontemp', m: 0, w: false }, + { v: 'off', n: 'dhw circulation pump mode', id: 'wwcircmode', m: 0, w: false }, + { v: false, n: 'dhw circulation active', id: 'wwcirc', m: 0, w: false }, + { v: 46.4, n: 'dhw current intern temperature', id: 'wwcurtemp', m: 0, w: false }, + { n: 'dhw current extern temperature', id: 'wwcurtemp2', m: 2 }, + { v: 0, n: 'dhw current tap water flow', id: 'wwcurflow', m: 0, w: false }, + { v: 46.3, n: 'dhw storage intern temperature', id: 'wwstoragetemp1', m: 0, w: false }, + { n: 'dhw storage extern temperature', id: 'wwstoragetemp2', m: 2 }, + { v: true, n: 'dhw activated', id: 'wwactivated', m: 0, w: false }, + { v: false, n: 'dhw one time charging', id: 'wwonetime', m: 0, w: false }, + { v: false, n: 'dhw disinfecting', id: 'wwdisinfecting', m: 0, w: false }, + { v: false, n: 'dhw charging', id: 'wwcharging', m: 0, w: false }, + { v: false, n: 'dhw recharging', id: 'wwrecharging', m: 0, w: false }, + { v: true, n: 'dhw temperature ok', id: 'wwtempok', m: 0, w: false }, + { v: false, n: 'dhw active', id: 'wwactive', m: 0, w: false }, + { v: true, n: 'dhw 3way valve active', id: 'ww3wayvalve', m: 0, w: false }, + { v: 0, n: 'dhw set pump power', id: 'wwsetpumppower', m: 0, w: true }, + { n: 'dhw mixer temperature', id: 'wwmixertemp', m: 2 }, + { n: 'dhw cylinder middle temperature (TS3)', id: 'wwcylmiddletemp', m: 2 }, + { v: 288768, n: 'dhw starts', id: 'wwstarts', m: 0, w: false }, + { v: 102151, n: 'dhw active time', id: 'wwworkm', m: 0, w: false } +]; + +const emsesp_deviceentities_4 = [ + { + v: 16, + n: 'hc2 selected room temperature', + id: 'hc2/seltemp', + m: 8, + w: true + }, + { + v: 18.5, + n: 'hc2 current room temperature', + id: 'hc2/curtemp', + m: 2, + w: false + }, + { + v: 'off', + n: 'hc2 mode', + id: 'hc2/mode', + m: 2, + w: true + } +]; + +// END DATA + +// ROUTING STARTS HERE + +// LOG +router + .post(FETCH_LOG_ENDPOINT, () => { + const encoded = encoder.encode(fetch_log); + // TODO check if still need this or just send a 200 since ES will catch up? + return new Response(encoded, { headers }); + }) + .get(LOG_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(log_settings), { headers })) + .post(LOG_SETTINGS_ENDPOINT, async (request: any) => { + log_settings = await request.json(); + return new Response('OK', { status: 200 }); + }); + +// NETWORK +router + .get(NETWORK_STATUS_ENDPOINT, () => new Response(JSON.stringify(network_status), { headers })) + .get(NETWORK_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(network_settings), { headers })) + .get(LIST_NETWORKS_ENDPOINT, () => { + if (countWifiScanPoll++ === 3) { + console.log('done, sending list'); + return new Response(JSON.stringify(list_networks), { headers }); // send list + } else { + console.log('...waiting #' + countWifiScanPoll); + return new Response('OK', { status: 200 }); + } + }) + .get(SCAN_NETWORKS_ENDPOINT, () => { + console.log('start scan networks'); + countWifiScanPoll = 0; // stop the poll + return new Response('OK', { status: 202 }); // always 202, poll for list + }) + .post(NETWORK_SETTINGS_ENDPOINT, async (request: any) => { + network_settings = await request.json(); + return new Response('OK', { status: 200 }); + }); + +// AP +router + .get(AP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ap_settings), { headers })) + .get(AP_STATUS_ENDPOINT, () => new Response(JSON.stringify(ap_status), { headers })) + .post(AP_SETTINGS_ENDPOINT, async (request: any) => { + ap_settings = await request.json(); + return new Response('OK', { status: 200 }); + }); + +// OTA +router + .get(OTA_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ota_settings), { headers })) + .post(OTA_SETTINGS_ENDPOINT, async (request: any) => { + ota_settings = await request.json(); + return new Response('OK', { status: 200 }); + }); + +// MQTT +router + .get(MQTT_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(mqtt_settings), { headers })) + .get(MQTT_STATUS_ENDPOINT, () => new Response(JSON.stringify(mqtt_status), { headers })) + .post(MQTT_SETTINGS_ENDPOINT, async (request: any) => { + mqtt_settings = await request.json(); + return new Response('OK', { status: 200 }); + }); + +// NTP +router + .get(NTP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ntp_settings), { headers })) + .get(NTP_STATUS_ENDPOINT, () => new Response(JSON.stringify(ntp_status), { headers })) + .post(TIME_ENDPOINT, () => new Response('OK', { status: 200 })) + .post(NTP_SETTINGS_ENDPOINT, async (request: any) => { + ntp_settings = await request.json(); + return new Response('OK', { status: 200 }); + }); + +// SYSTEM +router + .get(SYSTEM_STATUS_ENDPOINT, () => new Response(JSON.stringify(system_status), { headers })) + .post(SECURITY_SETTINGS_ENDPOINT, async (request: any) => { + security_settings = await request.json(); + return new Response('OK', { status: 200 }); + }) + .get(FEATURES_ENDPOINT, () => new Response(JSON.stringify(features), { headers })) + .get(VERIFY_AUTHORIZATION_ENDPOINT, () => new Response(JSON.stringify(verify_authentication), { headers })) + .post(RESTART_ENDPOINT, () => new Response('OK', { status: 200 })) + .post(FACTORY_RESET_ENDPOINT, () => new Response('OK', { status: 200 })) + .post(UPLOAD_FILE_ENDPOINT, () => new Response('OK', { status: 404 })) // TODO remove + .post(SIGN_IN_ENDPOINT, () => new Response(JSON.stringify(signin), { headers })) + .get(GENERATE_TOKEN_ENDPOINT, () => new Response(JSON.stringify(generate_token), { headers })); + +// uploads // TODO fix later + +// const progress_middleware = async (req: any) => { +// console.log('progress_middleware'); +// let progress = 0; +// const file_size = req.headers['content-length']; + +// // set event listener +// req.on('data', async (chunk) => { +// progress += chunk.length; +// const percentage = (progress / file_size) * 100; +// console.log(`Progress: ${Math.round(percentage)}%`); +// delay_blocking(200); // slow it down +// }); +// // next(); // invoke next middleware which is multer +// }; + +// const withContent = async (request) => { +// const { headers } = request; +// const type = headers.get('content-type'); + +// // console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(request))); + +// if (type?.includes('form-data')) { +// console.log('withContent: got formdata'); +// // request.content = await request.formData(); + +// // const bb = busboy({ headers: request.headers }); +// // console.log('bb created'); +// // bb.on('file', (name, file, info) => { +// // const { filename, encoding, mimeType } = info; +// // console.log(`File [${name}]: filename: %j, encoding: %j, mimeType: %j`, filename, encoding, mimeType); +// // request.filename = filename; + +// // file +// // .on('data', (data) => { +// // console.log(`File [${name}] got ${data.length} bytes`); +// // }) +// // .on('close', () => { +// // console.log(`File [${name}] done`); +// // }); +// // }); +// // bb.on('field', (name, val, info) => { +// // console.log(`Field [${name}]: value: %j`, val); +// // }); +// // bb.on('close', () => { +// // console.log('Done parsing form!'); +// // // res.writeHead(303, { Connection: 'close', Location: '/' }); +// // // res.end(); +// // }); +// } +// }; + +// const makeMiddleware = (req) => { +// console.log('makeMiddleware'); +// // const bb = busboy({ headers: req.headers }); + +// // bb.on('error', (err) => { +// // // Send this error along to the global error handler +// // console.log('Error' + err); +// // return; +// // }); +// // bb.on('file', (name, file, info) => { +// // const { filename, encoding, mimeType } = info; +// // console.log(`File [${name}]: filename: %j, encoding: %j, mimeType: %j`, filename, encoding, mimeType); +// // req.filename = filename; + +// // file +// // .on('data', (data) => { +// // console.log(`File [${name}] got ${data.length} bytes`); +// // }) +// // .on('close', () => { +// // console.log(`File [${name}] done`); +// // }); +// // }); +// // bb.end(req.rawBody); +// // req.pipe(bb); +// }; + +// router.post(UPLOAD_FILE_ENDPOINT, withContent, makeMiddleware, progress_middleware, ({ filename }) => { +// console.log('filename: ' + filename); + +// // if (req.file) { +// // const filename = req.file.originalname; +// // const ext = filename.substring(filename.lastIndexOf('.') + 1); +// // console.log(req.file); +// // console.log('ext: ' + ext); + +// // if (ext === 'bin' || ext === 'json') { +// // return res.sendStatus(200); +// // } else if (ext === 'md5') { +// // return res.json({ md5: 'ef4304fc4d9025a58dcf25d71c882d2c' }); +// // } +// // } +// return new Response('OK', { status: 200 }); +// }); + +// +// EMS-ESP Project stuff +// +router + .post(EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT, async (request: any) => { + return new Response('OK', { status: 200 }); + }) + .get(EMSESP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(settings), { headers })) + .post(EMSESP_SETTINGS_ENDPOINT, async (request: any) => { + settings = await request.json(); + return new Response('OK', { status: 200 }); // no restart needed + // return new Response('OK', { status: 205 }); // restart needed + }) + .get(EMSESP_CORE_DATA_ENDPOINT, () => new Response(JSON.stringify(emsesp_coredata), { headers })) + .get(EMSESP_SENSOR_DATA_ENDPOINT, () => new Response(JSON.stringify(emsesp_sensordata), { headers })) + .get(EMSESP_DEVICES_ENDPOINT, () => new Response(JSON.stringify(emsesp_devices), { headers })) + .post(EMSESP_SCANDEVICES_ENDPOINT, () => new Response('OK', { status: 200 })) + .get(EMSESP_STATUS_ENDPOINT, () => new Response(JSON.stringify(status), { headers })) + .get(EMSESP_DEVICEDATA_ENDPOINT, (request) => { + const id = Number(request.params.id); + if (id == 1) { + return new Response(encoder.encode(emsesp_devicedata_1), { headers }); + } + if (id == 2) { + return new Response(encoder.encode(emsesp_devicedata_2), { headers }); + } + if (id == 3) { + return new Response(encoder.encode(emsesp_devicedata_3), { headers }); + } + if (id == 4) { + return new Response(encoder.encode(emsesp_devicedata_4), { headers }); + } + if (id == 5) { + return new Response(encoder.encode(emsesp_devicedata_5), { headers }); + } + if (id == 6) { + return new Response(encoder.encode(emsesp_devicedata_6), { headers }); + } + if (id == 7) { + return new Response(encoder.encode(emsesp_devicedata_7), { headers }); + } + if (id == 99) { + return new Response(encoder.encode(emsesp_devicedata_99), { headers }); + } + }) + .get(EMSESP_DEVICEENTITIES_ENDPOINT, (request) => { + const id = Number(request.params.id); + if (id == 1) { + return new Response(encoder.encode(emsesp_deviceentities_1), { headers }); + } + if (id == 2) { + return new Response(encoder.encode(emsesp_deviceentities_2), { headers }); + } + if (id == 3) { + return new Response(encoder.encode(emsesp_deviceentities_3), { headers }); + } + if (id == 4) { + return new Response(encoder.encode(emsesp_deviceentities_4), { headers }); + } + if (id == 5) { + return new Response(encoder.encode(emsesp_deviceentities_5), { headers }); + } + if (id == 6) { + return new Response(encoder.encode(emsesp_deviceentities_6), { headers }); + } + if (id == 7) { + return new Response(encoder.encode(emsesp_deviceentities_7), { headers }); + } + }) + .post(EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT, async (request: any) => { + const content = await request.json(); + const id = content.id; + for (const entity of content.entity_ids) { + if (id === 7) { + updateMask(entity, emsesp_deviceentities_7, emsesp_devicedata_7); + } else if (id === 1) { + updateMask(entity, emsesp_deviceentities_1, emsesp_devicedata_1); + } else if (id === 2) { + updateMask(entity, emsesp_deviceentities_2, emsesp_devicedata_2); + } else if (id === 3) { + updateMask(entity, emsesp_deviceentities_3, emsesp_devicedata_3); + } else if (id === 4) { + updateMask(entity, emsesp_deviceentities_4, emsesp_devicedata_4); + } else if (id === 5) { + updateMask(entity, emsesp_deviceentities_5, emsesp_devicedata_5); + } else if (id === 6) { + updateMask(entity, emsesp_deviceentities_6, emsesp_devicedata_6); + } + } + return new Response('OK', { status: 200 }); + }) + .post(EMSESP_WRITE_SCHEDULE_ENDPOINT, async (request: any) => { + const content = await request.json(); + emsesp_schedule = content; + return new Response('OK', { status: 200 }); + }) + .post(EMSESP_WRITE_ENTITIES_ENDPOINT, async (request: any) => { + const content = await request.json(); + emsesp_customentities = content; + return new Response('OK', { status: 200 }); + }) + .post(EMSESP_WRITE_VALUE_ENDPOINT, async (request: any) => { + const content = await request.json(); + const command = content.c; + const value = content.v; + const id = content.id; + + var objIndex; + if (id === 1) { + objIndex = emsesp_devicedata_1.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_1.data[objIndex].v = value; + } + if (id === 2) { + objIndex = emsesp_devicedata_2.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_2.data[objIndex].v = value; + } + if (id === 3) { + objIndex = emsesp_devicedata_3.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_3.data[objIndex].v = value; + } + if (id === 4) { + objIndex = emsesp_devicedata_4.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_4.data[objIndex].v = value; + } + if (id === 5) { + objIndex = emsesp_devicedata_5.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_5.data[objIndex].v = value; + } + if (id === 6) { + objIndex = emsesp_devicedata_6.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_6.data[objIndex].v = value; + } + if (id === 7) { + objIndex = emsesp_devicedata_7.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_7.data[objIndex].v = value; + } + if (id === 99) { + // custom entities + objIndex = emsesp_devicedata_99.data.findIndex((obj) => obj.c == command); + emsesp_devicedata_99.data[objIndex].v = value; + } + + await delay(1000); // wait to show spinner + return new Response('OK', { status: 200 }); // or 400 for bad request + }) + .post(EMSESP_WRITE_SENSOR_ENDPOINT, async (request: any) => { + const ts = await request.json(); + var objIndex = emsesp_sensordata.ts.findIndex((obj) => obj.id == ts.id_str); + if (objIndex !== -1) { + emsesp_sensordata.ts[objIndex].n = ts.name; + emsesp_sensordata.ts[objIndex].o = ts.offset; + } + return new Response('OK', { status: 200 }); + }) + .post(EMSESP_WRITE_ANALOG_ENDPOINT, async (request: any) => { + const as = await request.json(); + var objIndex = emsesp_sensordata.as.findIndex((obj) => obj.g == as.gpio); + if (objIndex === -1) { + emsesp_sensordata.as.push({ + id: as.id, + g: as.gpio, + n: as.name, + f: as.factor, + o: as.offset, + u: as.uom, + t: as.type, + d: as.deleted, + v: 0 // must be added for demo only + }); + } else { + if (as.deleted) { + emsesp_sensordata.as[objIndex].d = true; + var filtered = emsesp_sensordata.as.filter(function (value, index, arr) { + return !value.d; + }); + emsesp_sensordata.as = filtered; + } else { + emsesp_sensordata.as[objIndex].n = as.name; + emsesp_sensordata.as[objIndex].f = as.factor; + emsesp_sensordata.as[objIndex].o = as.offset; + emsesp_sensordata.as[objIndex].u = as.uom; + emsesp_sensordata.as[objIndex].t = as.type; + } + } + + return new Response('OK', { status: 200 }); + }) + .post(EMSESP_BOARDPROFILE_ENDPOINT, async (request: any) => { + const content = await request.json(); + const board_profile = content.code; + + const data = { + led_gpio: settings.led_gpio, + dallas_gpio: settings.dallas_gpio, + rx_gpio: settings.rx_gpio, + tx_gpio: settings.tx_gpio, + pbutton_gpio: settings.pbutton_gpio, + phy_type: settings.phy_type, + eth_power: settings.eth_power, + eth_phy_addr: settings.eth_phy_addr, + eth_clock_mode: settings.eth_clock_mode + }; + + if (board_profile == 'S32') { + // BBQKees Gateway S32 + data.led_gpio = 2; + data.dallas_gpio = 18; + data.rx_gpio = 23; + data.tx_gpio = 5; + data.pbutton_gpio = 0; + data.phy_type = 0; + data.eth_power = 0; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } else if (board_profile == 'E32') { + // BBQKees Gateway E32 + data.led_gpio = 2; + data.dallas_gpio = 4; + data.rx_gpio = 5; + data.tx_gpio = 17; + data.pbutton_gpio = 33; + data.phy_type = 1; + data.eth_power = 16; + data.eth_phy_addr = 1; + data.eth_clock_mode = 0; + } else if (board_profile == 'MH-ET') { + // MH-ET Live D1 Mini + data.led_gpio = 2; + data.dallas_gpio = 18; + data.rx_gpio = 23; + data.tx_gpio = 5; + data.pbutton_gpio = 0; + data.phy_type = 0; + data.eth_power = 0; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } else if (board_profile == 'NODEMCU') { + // NodeMCU 32S + data.led_gpio = 2; + data.dallas_gpio = 18; + data.rx_gpio = 23; + data.tx_gpio = 5; + data.pbutton_gpio = 0; + data.phy_type = 0; + data.eth_power = 0; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } else if (board_profile == 'LOLIN') { + // Lolin D32 + data.led_gpio = 2; + data.dallas_gpio = 18; + data.rx_gpio = 17; + data.tx_gpio = 16; + data.pbutton_gpio = 0; + data.phy_type = 0; + data.eth_power = 0; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } else if (board_profile == 'OLIMEX') { + // Olimex ESP32-EVB (uses U1TXD/U1RXD/BUTTON, no LED or Dallas) + data.led_gpio = 0; + data.dallas_gpio = 0; + data.rx_gpio = 36; + data.tx_gpio = 4; + data.pbutton_gpio = 34; + data.phy_type = 1; + data.eth_power = -1; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } else if (board_profile == 'OLIMEXPOE') { + // Olimex ESP32-POE + data.led_gpio = 0; + data.dallas_gpio = 0; + data.rx_gpio = 36; + data.tx_gpio = 4; + data.pbutton_gpio = 34; + data.phy_type = 1; + data.eth_power = 12; + data.eth_phy_addr = 0; + data.eth_clock_mode = 3; + } else if (board_profile == 'C3MINI') { + // Lolin C3 mini + data.led_gpio = 7; + data.dallas_gpio = 1; + data.rx_gpio = 4; + data.tx_gpio = 5; + data.pbutton_gpio = 9; + data.phy_type = 0; + data.eth_power = 0; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } else if (board_profile == 'S2MINI') { + // Lolin C3 mini + data.led_gpio = 15; + data.dallas_gpio = 7; + data.rx_gpio = 11; + data.tx_gpio = 12; + data.pbutton_gpio = 0; + data.phy_type = 0; + data.eth_power = 0; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } else if (board_profile == 'S3MINI') { + // Liligo S3 mini + data.led_gpio = 17; + data.dallas_gpio = 18; + data.rx_gpio = 8; + data.tx_gpio = 5; + data.pbutton_gpio = 0; + data.phy_type = 0; + data.eth_power = 0; + data.eth_phy_addr = 0; + data.eth_clock_mode = 0; + } + + return new Response(JSON.stringify(data), { headers }); + }); + +// API and calls +const SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info'; +const GET_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'getSettings'; +const GET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'getCustomizations'; +const GET_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'getEntities'; +const GET_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'getSchedule'; +const SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule'; +const ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customentities'; + +router + .post(SYSTEM_INFO_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers })) + .get(SYSTEM_INFO_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers })) + .get(GET_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers })) + .get(GET_CUSTOMIZATIONS_ENDPOINT, () => new Response(JSON.stringify(emsesp_deviceentities_1), { headers })) + .get(GET_ENTITIES_ENDPOINT, () => new Response(JSON.stringify(emsesp_customentities), { headers })) + .get(GET_SCHEDULE_ENDPOINT, () => new Response(JSON.stringify(emsesp_schedule), { headers })) + .get(SCHEDULE_ENDPOINT, () => new Response(JSON.stringify(emsesp_schedule), { headers })) + .get(ENTITIES_ENDPOINT, () => new Response(JSON.stringify(emsesp_customentities), { headers })) + .post(API_ENDPOINT_ROOT, async (request: any) => { + const data = await request.json(); + if (data.device === 'system') { + if (data.entity === 'info') { + return new Response(JSON.stringify(emsesp_info), { headers }); + } + if (data.entity === 'allvalues') { + return new Response(JSON.stringify(emsesp_allvalues), { headers }); + } + } + return new Response('Not Found', { status: 404 }); + }); + +// Event Source // TODO fix later + +// const data = { +// t: '000+00:00:00.000', +// l: 3, // error +// i: 1, +// n: 'system', +// m: 'incoming message #1' +// }; +// const sseFormattedResponse = `data: ${JSON.stringify(data)}\n\n`; +// router.get('/es/log', () => new Response(sseFormattedResponse, { headers: ESheaders })); + +var count = 8; +var log_index = 0; +const ES_LOG_ENDPOINT = ES_ENDPOINT_ROOT + 'log'; + +// new Response({ +// headers: { +// 'content-type': 'application/json', +// 'Content-Type': 'text/event-stream', +// 'Cache-Control': 'no-cache', +// 'Access-Control-Allow-Origin': '*', +// 'Connection': 'keep-alive' +// }, +// body: '{"foo":"bar"}' +// }) + +// rest_server.get(ES_LOG_ENDPOINT, function (req, res) { +// res.setHeader('Content-Type', 'text/event-stream'); +// res.setHeader('Cache-Control', 'no-cache'); +// res.setHeader('Access-Control-Allow-Origin', '*'); +// res.setHeader('Connection', 'keep-alive'); +// res.flushHeaders(); + +let sseFormattedResponse = ''; + +// var timer = setInterval(function () { +// count += 1; +// log_index += 1; +// const data = { +// t: '000+00:00:00.000', +// l: 3, // error +// i: count, +// n: 'system', +// m: 'incoming message #' + count + '/' + log_index +// }; +// sseFormattedResponse = `data: ${JSON.stringify(data)}\n\n`; +// console.log('done'); +// // res.write(sseFormattedResponse); +// // res.flush(); // this is important + +// // if buffer is full, start over +// if (log_index > 50) { +// fetch_log.events = []; +// log_index = 0; +// } +// fetch_log.events.push(data); // append to buffer +// }, 300); + +router.get(ES_LOG_ENDPOINT, () => new Response(sseFormattedResponse, { headers: ESheaders })); + +// Tie it all together +const missingHandler = () => new Response('Not found.', { status: 404 }); + +router + .all('/api/*', apiRouter.handle) + .all('/rest/*', restRouter.handle) + .all('/es/*', esRouter.handle) + .all('*', missingHandler); + +const errorHandler = (error: any) => new Response(error.message || 'Server Error', { status: error.status || 500 }); +export const handleRequest = (request: any) => router.handle(request).catch(errorHandler); diff --git a/mock-api/README.md b/mock-api/README.md index 0d9e1f82b..222f8e3f2 100644 --- a/mock-api/README.md +++ b/mock-api/README.md @@ -1,5 +1,12 @@ -(Based on ) - When developing and testing the web interface, it's handy not to bother with re-flashing an ESP32 each time. The idea is to mimic the ESP using a mock/stub server that responds to the REST (HTTP POST & GET) and WebSocket calls. -To use first make sure you have nodejs installed (>v18) then install yarn (`npm install -g yarn`). Now type `yarn` from this `mock-api` folder. To run EMS-ESP's WebUI navigate up to the `interface` folder and type `yarn standalone`. This will start the mock API server on port 3080 using static dummy data from `mock-api/server.js` and also the web server which is at . +# prerequisites + +- Install the latest LTS of NodeJS +- Install yarn (`npm install -g yarn`) +- Install bun () +- type `yarn` from this `mock-api` folder to build + +# To run + +- `yarn standalone` from the main `interface` folder and then navigate to diff --git a/mock-api/package-lock.json b/mock-api/package-lock.json new file mode 100644 index 000000000..9f5078090 --- /dev/null +++ b/mock-api/package-lock.json @@ -0,0 +1,311 @@ +{ + "name": "api", + "version": "3.6.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "api", + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "@msgpack/msgpack": "^2.8.0", + "itty-router": "^4.0.23", + "multer": "^1.4.5-lts.1" + }, + "devDependencies": { + "@types/multer": "^1.4.11" + } + }, + "node_modules/@msgpack/msgpack": { + "version": "2.8.0", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/multer": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/node": { + "version": "20.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.2.tgz", + "integrity": "sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/itty-router": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-4.0.23.tgz", + "integrity": "sha512-tP1NI8PVK43vWlBnIPqj47ni5FDSczFviA4wgBznscndo8lEvBA+pO3DD1rNbIQPcZhprr775iUTunyGvQMcBw==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/xtend": { + "version": "4.0.2", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/mock-api/package.json b/mock-api/package.json index 5dc8922cc..89545aa8c 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -1,19 +1,20 @@ { "name": "api", - "version": "1.0.0", + "version": "3.6.0", "description": "mock api for EMS-ESP", "author": "proddy", - "main": "server.js", + "main": "server.ts", "license": "MIT", "scripts": { - "dev": "node --watch ./server.js localhost 3080", - "test": "echo \"Error: no test specified\" && exit 1" + "standalone": "bun --watch server.ts" }, "dependencies": { "@msgpack/msgpack": "^2.8.0", - "compression": "^1.7.4", - "express": "^4.18.2", - "multer": "^1.4.5-lts.1" + "busboy": "^1.6.0", + "itty-router": "^4.0.23" }, - "packageManager": "yarn@4.0.2" + "packageManager": "yarn@4.0.2", + "devDependencies": { + "@types/multer": "^1.4.11" + } } diff --git a/mock-api/server.ts b/mock-api/server.ts new file mode 100644 index 000000000..612e7a9ab --- /dev/null +++ b/mock-api/server.ts @@ -0,0 +1,6 @@ +import { handleRequest } from './Handler'; + +export default { + port: 3080, + fetch: (request) => handleRequest(request) +}; diff --git a/mock-api/server.js b/mock-api/server_notused.js similarity index 100% rename from mock-api/server.js rename to mock-api/server_notused.js diff --git a/mock-api/yarn.lock b/mock-api/yarn.lock index ff64be4fd..ef925865d 100644 --- a/mock-api/yarn.lock +++ b/mock-api/yarn.lock @@ -12,13 +12,113 @@ __metadata: languageName: node linkType: hard -"accepts@npm:~1.3.5, accepts@npm:~1.3.8": - version: 1.3.8 - resolution: "accepts@npm:1.3.8" +"@types/body-parser@npm:*": + version: 1.19.5 + resolution: "@types/body-parser@npm:1.19.5" dependencies: - mime-types: "npm:~2.1.34" - negotiator: "npm:0.6.3" - checksum: 67eaaa90e2917c58418e7a9b89392002d2b1ccd69bcca4799135d0c632f3b082f23f4ae4ddeedbced5aa59bcc7bdf4699c69ebed4593696c922462b7bc5744d6 + "@types/connect": "npm:*" + "@types/node": "npm:*" + checksum: 1e251118c4b2f61029cc43b0dc028495f2d1957fe8ee49a707fb940f86a9bd2f9754230805598278fe99958b49e9b7e66eec8ef6a50ab5c1f6b93e1ba2aaba82 + languageName: node + linkType: hard + +"@types/connect@npm:*": + version: 3.4.38 + resolution: "@types/connect@npm:3.4.38" + dependencies: + "@types/node": "npm:*" + checksum: 7eb1bc5342a9604facd57598a6c62621e244822442976c443efb84ff745246b10d06e8b309b6e80130026a396f19bf6793b7cecd7380169f369dac3bfc46fb99 + languageName: node + linkType: hard + +"@types/express-serve-static-core@npm:^4.17.33": + version: 4.17.41 + resolution: "@types/express-serve-static-core@npm:4.17.41" + dependencies: + "@types/node": "npm:*" + "@types/qs": "npm:*" + "@types/range-parser": "npm:*" + "@types/send": "npm:*" + checksum: 7647e19d9c3d57ddd18947d2b161b90ef0aedd15875140e5b824209be41c1084ae942d4fb43cd5f2051a6a5f8c044519ef6c9ac1b2ad86b9aa546b4f1f023303 + languageName: node + linkType: hard + +"@types/express@npm:*": + version: 4.17.21 + resolution: "@types/express@npm:4.17.21" + dependencies: + "@types/body-parser": "npm:*" + "@types/express-serve-static-core": "npm:^4.17.33" + "@types/qs": "npm:*" + "@types/serve-static": "npm:*" + checksum: 7a6d26cf6f43d3151caf4fec66ea11c9d23166e4f3102edfe45a94170654a54ea08cf3103d26b3928d7ebcc24162c90488e33986b7e3a5f8941225edd5eb18c7 + languageName: node + linkType: hard + +"@types/http-errors@npm:*": + version: 2.0.4 + resolution: "@types/http-errors@npm:2.0.4" + checksum: 1f3d7c3b32c7524811a45690881736b3ef741bf9849ae03d32ad1ab7062608454b150a4e7f1351f83d26a418b2d65af9bdc06198f1c079d75578282884c4e8e3 + languageName: node + linkType: hard + +"@types/mime@npm:*, @types/mime@npm:^1": + version: 1.3.5 + resolution: "@types/mime@npm:1.3.5" + checksum: e29a5f9c4776f5229d84e525b7cd7dd960b51c30a0fb9a028c0821790b82fca9f672dab56561e2acd9e8eed51d431bde52eafdfef30f643586c4162f1aecfc78 + languageName: node + linkType: hard + +"@types/multer@npm:^1.4.11": + version: 1.4.11 + resolution: "@types/multer@npm:1.4.11" + dependencies: + "@types/express": "npm:*" + checksum: 5abbc9a8b0d7bb817a52429c52f052152ebe2fb212e7138359c0c0b9207486ef7b1e54f65915c968300a0874cee546dbfc850415584fc9d14eff2b27bb926e7f + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 20.10.2 + resolution: "@types/node@npm:20.10.2" + dependencies: + undici-types: "npm:~5.26.4" + checksum: e88d0e92870ec4880642cc39250903a098443d791e864a08d08f4e7fdca0c4c9c0233a6fd98bec356f0ebabc6551152a4590d1c9c34b73a95c2b33935f59185f + languageName: node + linkType: hard + +"@types/qs@npm:*": + version: 6.9.10 + resolution: "@types/qs@npm:6.9.10" + checksum: 3e479ee056bd2b60894baa119d12ecd33f20a25231b836af04654e784c886f28a356477630430152a86fba253da65d7ecd18acffbc2a8877a336e75aa0272c67 + languageName: node + linkType: hard + +"@types/range-parser@npm:*": + version: 1.2.7 + resolution: "@types/range-parser@npm:1.2.7" + checksum: 95640233b689dfbd85b8c6ee268812a732cf36d5affead89e806fe30da9a430767af8ef2cd661024fd97e19d61f3dec75af2df5e80ec3bea000019ab7028629a + languageName: node + linkType: hard + +"@types/send@npm:*": + version: 0.17.4 + resolution: "@types/send@npm:0.17.4" + dependencies: + "@types/mime": "npm:^1" + "@types/node": "npm:*" + checksum: 28320a2aa1eb704f7d96a65272a07c0bf3ae7ed5509c2c96ea5e33238980f71deeed51d3631927a77d5250e4091b3e66bce53b42d770873282c6a20bb8b0280d + languageName: node + linkType: hard + +"@types/serve-static@npm:*": + version: 1.15.5 + resolution: "@types/serve-static@npm:1.15.5" + dependencies: + "@types/http-errors": "npm:*" + "@types/mime": "npm:*" + "@types/node": "npm:*" + checksum: 49aa21c367fffe4588fc8c57ea48af0ea7cbadde7418bc53cde85d8bd57fd2a09a293970d9ea86e79f17a87f8adeb3e20da76aab38e1c4d1567931fa15c8af38 languageName: node linkType: hard @@ -27,54 +127,13 @@ __metadata: resolution: "api@workspace:." dependencies: "@msgpack/msgpack": "npm:^2.8.0" - compression: "npm:^1.7.4" - express: "npm:^4.18.2" - multer: "npm:^1.4.5-lts.1" + "@types/multer": "npm:^1.4.11" + busboy: "npm:^1.6.0" + itty-router: "npm:^4.0.23" languageName: unknown linkType: soft -"append-field@npm:^1.0.0": - version: 1.0.0 - resolution: "append-field@npm:1.0.0" - checksum: afb50f5ff668af1cb66bc5cfebb55ed9a1d99e24901782ee83d00aed1a499835f9375a149cf27b17f79595ecfcc3d1de0cd5b020b210a5359c43eaf607c217de - languageName: node - linkType: hard - -"array-flatten@npm:1.1.1": - version: 1.1.1 - resolution: "array-flatten@npm:1.1.1" - checksum: e13c9d247241be82f8b4ec71d035ed7204baa82fae820d4db6948d30d3c4a9f2b3905eb2eec2b937d4aa3565200bd3a1c500480114cff649fa748747d2a50feb - languageName: node - linkType: hard - -"body-parser@npm:1.20.1": - version: 1.20.1 - resolution: "body-parser@npm:1.20.1" - dependencies: - bytes: "npm:3.1.2" - content-type: "npm:~1.0.4" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" - on-finished: "npm:2.4.1" - qs: "npm:6.11.0" - raw-body: "npm:2.5.1" - type-is: "npm:~1.6.18" - unpipe: "npm:1.0.0" - checksum: 5f8d128022a2fb8b6e7990d30878a0182f300b70e46b3f9d358a9433ad6275f0de46add6d63206da3637c01c3b38b6111a7480f7e7ac2e9f7b989f6133fe5510 - languageName: node - linkType: hard - -"buffer-from@npm:^1.0.0": - version: 1.1.2 - resolution: "buffer-from@npm:1.1.2" - checksum: 0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb - languageName: node - linkType: hard - -"busboy@npm:^1.0.0": +"busboy@npm:^1.6.0": version: 1.6.0 resolution: "busboy@npm:1.6.0" dependencies: @@ -83,585 +142,10 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.0.0": - version: 3.0.0 - resolution: "bytes@npm:3.0.0" - checksum: a2b386dd8188849a5325f58eef69c3b73c51801c08ffc6963eddc9be244089ba32d19347caf6d145c86f315ae1b1fc7061a32b0c1aa6379e6a719090287ed101 - languageName: node - linkType: hard - -"bytes@npm:3.1.2": - version: 3.1.2 - resolution: "bytes@npm:3.1.2" - checksum: a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 - languageName: node - linkType: hard - -"call-bind@npm:^1.0.0": - version: 1.0.2 - resolution: "call-bind@npm:1.0.2" - dependencies: - function-bind: "npm:^1.1.1" - get-intrinsic: "npm:^1.0.2" - checksum: ca787179c1cbe09e1697b56ad499fd05dc0ae6febe5081d728176ade699ea6b1589240cb1ff1fe11fcf9f61538c1af60ad37e8eb2ceb4ef21cd6085dfd3ccedd - languageName: node - linkType: hard - -"compressible@npm:~2.0.16": - version: 2.0.18 - resolution: "compressible@npm:2.0.18" - dependencies: - mime-db: "npm:>= 1.43.0 < 2" - checksum: 58321a85b375d39230405654721353f709d0c1442129e9a17081771b816302a012471a9b8f4864c7dbe02eef7f2aaac3c614795197092262e94b409c9be108f0 - languageName: node - linkType: hard - -"compression@npm:^1.7.4": - version: 1.7.4 - resolution: "compression@npm:1.7.4" - dependencies: - accepts: "npm:~1.3.5" - bytes: "npm:3.0.0" - compressible: "npm:~2.0.16" - debug: "npm:2.6.9" - on-headers: "npm:~1.0.2" - safe-buffer: "npm:5.1.2" - vary: "npm:~1.1.2" - checksum: 469cd097908fe1d3ff146596d4c24216ad25eabb565c5456660bdcb3a14c82ebc45c23ce56e19fc642746cf407093b55ab9aa1ac30b06883b27c6c736e6383c2 - languageName: node - linkType: hard - -"concat-stream@npm:^1.5.2": - version: 1.6.2 - resolution: "concat-stream@npm:1.6.2" - dependencies: - buffer-from: "npm:^1.0.0" - inherits: "npm:^2.0.3" - readable-stream: "npm:^2.2.2" - typedarray: "npm:^0.0.6" - checksum: 71db903c84fc073ca35a274074e8d26c4330713d299f8623e993c448c1f6bf8b967806dd1d1a7b0f8add6f15ab1af7435df21fe79b4fe7efd78420c89e054e28 - languageName: node - linkType: hard - -"content-disposition@npm:0.5.4": - version: 0.5.4 - resolution: "content-disposition@npm:0.5.4" - dependencies: - safe-buffer: "npm:5.2.1" - checksum: b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 - languageName: node - linkType: hard - -"content-type@npm:~1.0.4": - version: 1.0.5 - resolution: "content-type@npm:1.0.5" - checksum: 585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 - languageName: node - linkType: hard - -"cookie-signature@npm:1.0.6": - version: 1.0.6 - resolution: "cookie-signature@npm:1.0.6" - checksum: f4e1b0a98a27a0e6e66fd7ea4e4e9d8e038f624058371bf4499cfcd8f3980be9a121486995202ba3fca74fbed93a407d6d54d43a43f96fd28d0bd7a06761591a - languageName: node - linkType: hard - -"cookie@npm:0.5.0": - version: 0.5.0 - resolution: "cookie@npm:0.5.0" - checksum: aae7911ddc5f444a9025fbd979ad1b5d60191011339bce48e555cb83343d0f98b865ff5c4d71fecdfb8555a5cafdc65632f6fce172f32aaf6936830a883a0380 - languageName: node - linkType: hard - -"core-util-is@npm:~1.0.0": - version: 1.0.3 - resolution: "core-util-is@npm:1.0.3" - checksum: 9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99 - languageName: node - linkType: hard - -"debug@npm:2.6.9": - version: 2.6.9 - resolution: "debug@npm:2.6.9" - dependencies: - ms: "npm:2.0.0" - checksum: e07005f2b40e04f1bd14a3dd20520e9c4f25f60224cb006ce9d6781732c917964e9ec029fc7f1a151083cd929025ad5133814d4dc624a9aaf020effe4914ed14 - languageName: node - linkType: hard - -"depd@npm:2.0.0": - version: 2.0.0 - resolution: "depd@npm:2.0.0" - checksum: c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca - languageName: node - linkType: hard - -"destroy@npm:1.2.0": - version: 1.2.0 - resolution: "destroy@npm:1.2.0" - checksum: 0acb300b7478a08b92d810ab229d5afe0d2f4399272045ab22affa0d99dbaf12637659411530a6fcd597a9bdac718fc94373a61a95b4651bbc7b83684a565e38 - languageName: node - linkType: hard - -"ee-first@npm:1.1.1": - version: 1.1.1 - resolution: "ee-first@npm:1.1.1" - checksum: 1b4cac778d64ce3b582a7e26b218afe07e207a0f9bfe13cc7395a6d307849cfe361e65033c3251e00c27dd060cab43014c2d6b2647676135e18b77d2d05b3f4f - languageName: node - linkType: hard - -"encodeurl@npm:~1.0.2": - version: 1.0.2 - resolution: "encodeurl@npm:1.0.2" - checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c - languageName: node - linkType: hard - -"escape-html@npm:~1.0.3": - version: 1.0.3 - resolution: "escape-html@npm:1.0.3" - checksum: 6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 - languageName: node - linkType: hard - -"etag@npm:~1.8.1": - version: 1.8.1 - resolution: "etag@npm:1.8.1" - checksum: 571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff - languageName: node - linkType: hard - -"express@npm:^4.18.2": - version: 4.18.2 - resolution: "express@npm:4.18.2" - dependencies: - accepts: "npm:~1.3.8" - array-flatten: "npm:1.1.1" - body-parser: "npm:1.20.1" - content-disposition: "npm:0.5.4" - content-type: "npm:~1.0.4" - cookie: "npm:0.5.0" - cookie-signature: "npm:1.0.6" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - finalhandler: "npm:1.2.0" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - merge-descriptors: "npm:1.0.1" - methods: "npm:~1.1.2" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.7" - proxy-addr: "npm:~2.0.7" - qs: "npm:6.11.0" - range-parser: "npm:~1.2.1" - safe-buffer: "npm:5.2.1" - send: "npm:0.18.0" - serve-static: "npm:1.15.0" - setprototypeof: "npm:1.2.0" - statuses: "npm:2.0.1" - type-is: "npm:~1.6.18" - utils-merge: "npm:1.0.1" - vary: "npm:~1.1.2" - checksum: 869ae89ed6ff4bed7b373079dc58e5dddcf2915a2669b36037ff78c99d675ae930e5fe052b35c24f56557d28a023bb1cbe3e2f2fb87eaab96a1cedd7e597809d - languageName: node - linkType: hard - -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" - dependencies: - debug: "npm:2.6.9" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - statuses: "npm:2.0.1" - unpipe: "npm:~1.0.0" - checksum: 635718cb203c6d18e6b48dfbb6c54ccb08ea470e4f474ddcef38c47edcf3227feec316f886dd701235997d8af35240cae49856721ce18f539ad038665ebbf163 - languageName: node - linkType: hard - -"forwarded@npm:0.2.0": - version: 0.2.0 - resolution: "forwarded@npm:0.2.0" - checksum: 29ba9fd347117144e97cbb8852baae5e8b2acb7d1b591ef85695ed96f5b933b1804a7fac4a15dd09ca7ac7d0cdc104410e8102aae2dd3faa570a797ba07adb81 - languageName: node - linkType: hard - -"fresh@npm:0.5.2": - version: 0.5.2 - resolution: "fresh@npm:0.5.2" - checksum: 64c88e489b5d08e2f29664eb3c79c705ff9a8eb15d3e597198ef76546d4ade295897a44abb0abd2700e7ef784b2e3cbf1161e4fbf16f59129193fd1030d16da1 - languageName: node - linkType: hard - -"function-bind@npm:^1.1.1": - version: 1.1.2 - resolution: "function-bind@npm:1.1.2" - checksum: 185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 - languageName: node - linkType: hard - -"get-intrinsic@npm:^1.0.2": - version: 1.2.1 - resolution: "get-intrinsic@npm:1.2.1" - dependencies: - function-bind: "npm:^1.1.1" - has: "npm:^1.0.3" - has-proto: "npm:^1.0.1" - has-symbols: "npm:^1.0.3" - checksum: aee631852063f8ad0d4a374970694b5c17c2fb5c92bd1929476d7eb8798ce7aebafbf9a34022c05fd1adaa2ce846d5877a627ce1986f81fc65adf3b81824bd54 - languageName: node - linkType: hard - -"has-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "has-proto@npm:1.0.1" - checksum: eab2ab0ed1eae6d058b9bbc4c1d99d2751b29717be80d02fd03ead8b62675488de0c7359bc1fdd4b87ef6fd11e796a9631ad4d7452d9324fdada70158c2e5be7 - languageName: node - linkType: hard - -"has-symbols@npm:^1.0.3": - version: 1.0.3 - resolution: "has-symbols@npm:1.0.3" - checksum: 464f97a8202a7690dadd026e6d73b1ceeddd60fe6acfd06151106f050303eaa75855aaa94969df8015c11ff7c505f196114d22f7386b4a471038da5874cf5e9b - languageName: node - linkType: hard - -"has@npm:^1.0.3": - version: 1.0.4 - resolution: "has@npm:1.0.4" - checksum: c245f332fe78c7b6b8753857240ac12b3286f995f656a33c77e0f5baab7d0157e6ddb1c34940ffd2bffc51f75ede50cd8b29ff65c13e336376aca8cf3df58043 - languageName: node - linkType: hard - -"http-errors@npm:2.0.0": - version: 2.0.0 - resolution: "http-errors@npm:2.0.0" - dependencies: - depd: "npm:2.0.0" - inherits: "npm:2.0.4" - setprototypeof: "npm:1.2.0" - statuses: "npm:2.0.1" - toidentifier: "npm:1.0.1" - checksum: 0e7f76ee8ff8a33e58a3281a469815b893c41357378f408be8f6d4aa7d1efafb0da064625518e7078381b6a92325949b119dc38fcb30bdbc4e3a35f78c44c439 - languageName: node - linkType: hard - -"iconv-lite@npm:0.4.24": - version: 0.4.24 - resolution: "iconv-lite@npm:0.4.24" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3" - checksum: 6d3a2dac6e5d1fb126d25645c25c3a1209f70cceecc68b8ef51ae0da3cdc078c151fade7524a30b12a3094926336831fca09c666ef55b37e2c69638b5d6bd2e3 - languageName: node - linkType: hard - -"inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:~2.0.3": - version: 2.0.4 - resolution: "inherits@npm:2.0.4" - checksum: cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 - languageName: node - linkType: hard - -"ipaddr.js@npm:1.9.1": - version: 1.9.1 - resolution: "ipaddr.js@npm:1.9.1" - checksum: 864d0cced0c0832700e9621913a6429ccdc67f37c1bd78fb8c6789fff35c9d167cb329134acad2290497a53336813ab4798d2794fd675d5eb33b5fdf0982b9ca - languageName: node - linkType: hard - -"isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - -"media-typer@npm:0.3.0": - version: 0.3.0 - resolution: "media-typer@npm:0.3.0" - checksum: 38e0984db39139604756903a01397e29e17dcb04207bb3e081412ce725ab17338ecc47220c1b186b6bbe79a658aad1b0d41142884f5a481f36290cdefbe6aa46 - languageName: node - linkType: hard - -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 - languageName: node - linkType: hard - -"methods@npm:~1.1.2": - version: 1.1.2 - resolution: "methods@npm:1.1.2" - checksum: a385dd974faa34b5dd021b2bbf78c722881bf6f003bfe6d391d7da3ea1ed625d1ff10ddd13c57531f628b3e785be38d3eed10ad03cebd90b76932413df9a1820 - languageName: node - linkType: hard - -"mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": - version: 1.52.0 - resolution: "mime-db@npm:1.52.0" - checksum: 54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 - languageName: node - linkType: hard - -"mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": - version: 2.1.35 - resolution: "mime-types@npm:2.1.35" - dependencies: - mime-db: "npm:1.52.0" - checksum: 89aa9651b67644035de2784a6e665fc685d79aba61857e02b9c8758da874a754aed4a9aced9265f5ed1171fd934331e5516b84a7f0218031b6fa0270eca1e51a - languageName: node - linkType: hard - -"mime@npm:1.6.0": - version: 1.6.0 - resolution: "mime@npm:1.6.0" - bin: - mime: cli.js - checksum: b7d98bb1e006c0e63e2c91b590fe1163b872abf8f7ef224d53dd31499c2197278a6d3d0864c45239b1a93d22feaf6f9477e9fc847eef945838150b8c02d03170 - languageName: node - linkType: hard - -"minimist@npm:^1.2.6": - version: 1.2.8 - resolution: "minimist@npm:1.2.8" - checksum: 908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f - languageName: node - linkType: hard - -"mkdirp@npm:^0.5.4": - version: 0.5.6 - resolution: "mkdirp@npm:0.5.6" - dependencies: - minimist: "npm:^1.2.6" - bin: - mkdirp: bin/cmd.js - checksum: 0c91b721bb12c3f9af4b77ebf73604baf350e64d80df91754dc509491ae93bf238581e59c7188360cec7cb62fc4100959245a42cfe01834efedc5e9d068376c2 - languageName: node - linkType: hard - -"ms@npm:2.0.0": - version: 2.0.0 - resolution: "ms@npm:2.0.0" - checksum: 0e6a22b8b746d2e0b65a430519934fefd41b6db0682e3477c10f60c76e947c4c0ad06f63ffdf1d78d335f83edee8c0aa928aa66a36c7cd95b69b26f468d527f4 - languageName: node - linkType: hard - -"ms@npm:2.1.3": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d - languageName: node - linkType: hard - -"multer@npm:^1.4.5-lts.1": - version: 1.4.5-lts.1 - resolution: "multer@npm:1.4.5-lts.1" - dependencies: - append-field: "npm:^1.0.0" - busboy: "npm:^1.0.0" - concat-stream: "npm:^1.5.2" - mkdirp: "npm:^0.5.4" - object-assign: "npm:^4.1.1" - type-is: "npm:^1.6.4" - xtend: "npm:^4.0.0" - checksum: 957c09956f3b7f79d8586cac5e2a50e9a5c3011eb841667b5e4590c5f31d9464f5b46aecd399c83e183a15b88b019cccf0e4fa5620db40bf16b9e3af7fab3ac6 - languageName: node - linkType: hard - -"negotiator@npm:0.6.3": - version: 0.6.3 - resolution: "negotiator@npm:0.6.3" - checksum: 2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 - languageName: node - linkType: hard - -"object-assign@npm:^4.1.1": - version: 4.1.1 - resolution: "object-assign@npm:4.1.1" - checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f - languageName: node - linkType: hard - -"object-inspect@npm:^1.9.0": - version: 1.13.0 - resolution: "object-inspect@npm:1.13.0" - checksum: d64609c3738a916d4c6d8306436427bfab87d5a68c017306aee9e8ebf39c9c08e6619f8397e520a64ff9b8545a2dcee9f4704157020700e324ccd179bd5ef931 - languageName: node - linkType: hard - -"on-finished@npm:2.4.1": - version: 2.4.1 - resolution: "on-finished@npm:2.4.1" - dependencies: - ee-first: "npm:1.1.1" - checksum: 8e81472c5028125c8c39044ac4ab8ba51a7cdc19a9fbd4710f5d524a74c6d8c9ded4dd0eed83f28d3d33ac1d7a6a439ba948ccb765ac6ce87f30450a26bfe2ea - languageName: node - linkType: hard - -"on-headers@npm:~1.0.2": - version: 1.0.2 - resolution: "on-headers@npm:1.0.2" - checksum: 870766c16345855e2012e9422ba1ab110c7e44ad5891a67790f84610bd70a72b67fdd71baf497295f1d1bf38dd4c92248f825d48729c53c0eae5262fb69fa171 - languageName: node - linkType: hard - -"parseurl@npm:~1.3.3": - version: 1.3.3 - resolution: "parseurl@npm:1.3.3" - checksum: 407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 - languageName: node - linkType: hard - -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 701c99e1f08e3400bea4d701cf6f03517474bb1b608da71c78b1eb261415b645c5670dfae49808c89e12cea2dccd113b069f040a80de012da0400191c6dbd1c8 - languageName: node - linkType: hard - -"process-nextick-args@npm:~2.0.0": - version: 2.0.1 - resolution: "process-nextick-args@npm:2.0.1" - checksum: 1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf - languageName: node - linkType: hard - -"proxy-addr@npm:~2.0.7": - version: 2.0.7 - resolution: "proxy-addr@npm:2.0.7" - dependencies: - forwarded: "npm:0.2.0" - ipaddr.js: "npm:1.9.1" - checksum: f24a0c80af0e75d31e3451398670d73406ec642914da11a2965b80b1898ca6f66a0e3e091a11a4327079b2b268795f6fa06691923fef91887215c3d0e8ea3f68 - languageName: node - linkType: hard - -"qs@npm:6.11.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" - dependencies: - side-channel: "npm:^1.0.4" - checksum: 5a3bfea3e2f359ede1bfa5d2f0dbe54001aa55e40e27dc3e60fab814362d83a9b30758db057c2011b6f53a2d4e4e5150194b5bac45372652aecb3e3c0d4b256e - languageName: node - linkType: hard - -"range-parser@npm:~1.2.1": - version: 1.2.1 - resolution: "range-parser@npm:1.2.1" - checksum: ce21ef2a2dd40506893157970dc76e835c78cf56437e26e19189c48d5291e7279314477b06ac38abd6a401b661a6840f7b03bd0b1249da9b691deeaa15872c26 - languageName: node - linkType: hard - -"raw-body@npm:2.5.1": - version: 2.5.1 - resolution: "raw-body@npm:2.5.1" - dependencies: - bytes: "npm:3.1.2" - http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" - unpipe: "npm:1.0.0" - checksum: 280bedc12db3490ecd06f740bdcf66093a07535374b51331242382c0e130bb273ebb611b7bc4cba1b4b4e016cc7b1f4b05a6df885a6af39c2bc3b94c02291c84 - languageName: node - linkType: hard - -"readable-stream@npm:^2.2.2": - version: 2.3.8 - resolution: "readable-stream@npm:2.3.8" - dependencies: - core-util-is: "npm:~1.0.0" - inherits: "npm:~2.0.3" - isarray: "npm:~1.0.0" - process-nextick-args: "npm:~2.0.0" - safe-buffer: "npm:~5.1.1" - string_decoder: "npm:~1.1.1" - util-deprecate: "npm:~1.0.1" - checksum: 8500dd3a90e391d6c5d889256d50ec6026c059fadee98ae9aa9b86757d60ac46fff24fafb7a39fa41d54cb39d8be56cc77be202ebd4cd8ffcf4cb226cbaa40d4 - languageName: node - linkType: hard - -"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": - version: 5.1.2 - resolution: "safe-buffer@npm:5.1.2" - checksum: 7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a - languageName: node - linkType: hard - -"safe-buffer@npm:5.2.1": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: 32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 - languageName: node - linkType: hard - -"safer-buffer@npm:>= 2.1.2 < 3": - version: 2.1.2 - resolution: "safer-buffer@npm:2.1.2" - checksum: 7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 - languageName: node - linkType: hard - -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" - dependencies: - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - mime: "npm:1.6.0" - ms: "npm:2.1.3" - on-finished: "npm:2.4.1" - range-parser: "npm:~1.2.1" - statuses: "npm:2.0.1" - checksum: ec66c0ad109680ad8141d507677cfd8b4e40b9559de23191871803ed241718e99026faa46c398dcfb9250676076573bd6bfe5d0ec347f88f4b7b8533d1d391cb - languageName: node - linkType: hard - -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" - dependencies: - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - parseurl: "npm:~1.3.3" - send: "npm:0.18.0" - checksum: 699b2d4c29807a51d9b5e0f24955346911437aebb0178b3c4833ad30d3eca93385ff9927254f5c16da345903cad39d9cd4a532198c95a5129cc4ed43911b15a4 - languageName: node - linkType: hard - -"setprototypeof@npm:1.2.0": - version: 1.2.0 - resolution: "setprototypeof@npm:1.2.0" - checksum: fde1630422502fbbc19e6844346778f99d449986b2f9cdcceb8326730d2f3d9964dbcb03c02aaadaefffecd0f2c063315ebea8b3ad895914bf1afc1747fc172e - languageName: node - linkType: hard - -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" - dependencies: - call-bind: "npm:^1.0.0" - get-intrinsic: "npm:^1.0.2" - object-inspect: "npm:^1.9.0" - checksum: c4998d9fc530b0e75a7fd791ad868fdc42846f072734f9080ff55cc8dc7d3899abcda24fd896aa6648c3ab7021b4bb478073eb4f44dfd55bce9714bc1a7c5d45 - languageName: node - linkType: hard - -"statuses@npm:2.0.1": - version: 2.0.1 - resolution: "statuses@npm:2.0.1" - checksum: 18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb +"itty-router@npm:^4.0.23": + version: 4.0.23 + resolution: "itty-router@npm:4.0.23" + checksum: b412f80f7d3bf78293144a43c47053c9873c98565e58aa188a66306cc6018ad3801fa157b0d694e9e1719cbc0424fcd89951f1916699eff6606f30b0645afa3e languageName: node linkType: hard @@ -672,70 +156,9 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:~1.1.1": - version: 1.1.1 - resolution: "string_decoder@npm:1.1.1" - dependencies: - safe-buffer: "npm:~5.1.0" - checksum: 7c41c17ed4dea105231f6df208002ebddd732e8e9e2d619d133cecd8e0087ddfd9587d2feb3c8caf3213cbd841ada6d057f5142cae68a4e62d3540778d9819b4 - languageName: node - linkType: hard - -"toidentifier@npm:1.0.1": - version: 1.0.1 - resolution: "toidentifier@npm:1.0.1" - checksum: 952c29e2a85d7123239b5cfdd889a0dde47ab0497f0913d70588f19c53f7e0b5327c95f4651e413c74b785147f9637b17410ac8c846d5d4a20a5a33eb6dc3a45 - languageName: node - linkType: hard - -"type-is@npm:^1.6.4, type-is@npm:~1.6.18": - version: 1.6.18 - resolution: "type-is@npm:1.6.18" - dependencies: - media-typer: "npm:0.3.0" - mime-types: "npm:~2.1.24" - checksum: 0bd9eeae5efd27d98fd63519f999908c009e148039d8e7179a074f105362d4fcc214c38b24f6cda79c87e563cbd12083a4691381ed28559220d4a10c2047bed4 - languageName: node - linkType: hard - -"typedarray@npm:^0.0.6": - version: 0.0.6 - resolution: "typedarray@npm:0.0.6" - checksum: 2cc1bcf7d8c1237f6a16c04efc06637b2c5f2d74e58e84665445cf87668b85a21ab18dd751fa49eee6ae024b70326635d7b79ad37b1c370ed2fec6aeeeb52714 - languageName: node - linkType: hard - -"unpipe@npm:1.0.0, unpipe@npm:~1.0.0": - version: 1.0.0 - resolution: "unpipe@npm:1.0.0" - checksum: 4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2 - languageName: node - linkType: hard - -"util-deprecate@npm:~1.0.1": - version: 1.0.2 - resolution: "util-deprecate@npm:1.0.2" - checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 - languageName: node - linkType: hard - -"utils-merge@npm:1.0.1": - version: 1.0.1 - resolution: "utils-merge@npm:1.0.1" - checksum: 5d6949693d58cb2e636a84f3ee1c6e7b2f9c16cb1d42d0ecb386d8c025c69e327205aa1c69e2868cc06a01e5e20681fbba55a4e0ed0cce913d60334024eae798 - languageName: node - linkType: hard - -"vary@npm:~1.1.2": - version: 1.1.2 - resolution: "vary@npm:1.1.2" - checksum: 31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242 - languageName: node - linkType: hard - -"xtend@npm:^4.0.0": - version: 4.0.2 - resolution: "xtend@npm:4.0.2" - checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd languageName: node linkType: hard