You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.6 KiB
JavaScript
179 lines
4.6 KiB
JavaScript
const Modules = {
|
|
UI: (1 << 0),
|
|
INFO: (1 << 1),
|
|
SET: (1 << 2),
|
|
READ: (1 << 3),
|
|
GET: (1 << 4),
|
|
DATA: (1 << 5),
|
|
|
|
REBOOT: (1 << 6),
|
|
FILES: (1 << 7),
|
|
FORMAT: (1 << 8),
|
|
DELETE: (1 << 9),
|
|
RENAME: (1 << 10),
|
|
CREATE: (1 << 11),
|
|
FETCH: (1 << 12),
|
|
UPLOAD: (1 << 13),
|
|
OTA: (1 << 14),
|
|
OTA_URL: (1 << 15),
|
|
MQTT: (1 << 16),
|
|
};
|
|
|
|
// http
|
|
async function http_get(url, tout) {
|
|
const res = await fetch(url, {
|
|
signal: AbortSignal.timeout(tout)
|
|
})
|
|
if (!res.ok)
|
|
throw new DOMException(res.statusText);
|
|
return await res.text();
|
|
}
|
|
|
|
function http_fetch_blob(url, type, onprogress, tout) {
|
|
return new Promise((res, rej) => {
|
|
async function handle(e) {
|
|
if (xhr.response === null) throw new HubError("Network error");
|
|
|
|
if (e.loaded !== e.total || xhr.status !== 200) {
|
|
const ab = type === 'url' ? await readFileAsArrayBuffer(xhr.response) : xhr.response;
|
|
const text = new TextDecoder().decode(ab);
|
|
throw new HubError(text);
|
|
}
|
|
|
|
if (type === 'url') return await readFileAsDataUrl(xhr.response);
|
|
if (type === 'text') return new TextDecoder().decode(xhr.response);
|
|
}
|
|
|
|
onprogress(0);
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.onprogress = (e) => onprogress(Math.round(e.loaded * 100 / e.total));
|
|
xhr.onloadend = (e) => handle(e).then(res).catch(rej);
|
|
xhr.ontimeout = () => rej(new DeviceError(HubErrors.Timeout));
|
|
xhr.timeout = tout;
|
|
xhr.responseType = type === 'url' ? 'blob' : 'arraybuffer';
|
|
xhr.open('GET', url, true);
|
|
xhr.send();
|
|
});
|
|
}
|
|
|
|
async function http_post(url, data) {//TODO tout
|
|
const res = await fetch(url, {
|
|
method: 'POST',
|
|
body: data
|
|
});
|
|
if (!res.ok)
|
|
throw await res.text();
|
|
return await res.text();
|
|
}
|
|
|
|
// ip
|
|
function getIPs(ip, netmask) {
|
|
let ip_a = ip.split('.');
|
|
let sum_ip = (ip_a[0] << 24) | (ip_a[1] << 16) | (ip_a[2] << 8) | ip_a[3];
|
|
let cidr = Number(netmask);
|
|
let mask = ~(0xffffffff >>> cidr);
|
|
let network = 0, broadcast = 0, start_ip = 0, end_ip = 0;
|
|
if (cidr === 32) {
|
|
network = sum_ip;
|
|
broadcast = network;
|
|
start_ip = network;
|
|
end_ip = network;
|
|
} else {
|
|
network = sum_ip & mask;
|
|
broadcast = network + (~mask);
|
|
if (cidr === 31) {
|
|
start_ip = network;
|
|
end_ip = broadcast;
|
|
} else {
|
|
start_ip = network + 1;
|
|
end_ip = broadcast - 1;
|
|
}
|
|
}
|
|
let ips = ['192.168.4.1']; // for esp
|
|
for (let ip = start_ip; ip <= end_ip; ip++) {
|
|
ips.push(`${(ip >>> 24) & 0xff}.${(ip >>> 16) & 0xff}.${(ip >>> 8) & 0xff}.${ip & 0xff}`);
|
|
}
|
|
return ips;
|
|
}
|
|
|
|
function sleep(time) {
|
|
return new Promise(res => setTimeout(res, time));
|
|
}
|
|
|
|
function readFileAsArrayBuffer(file) {
|
|
return new Promise((res, rej) => {
|
|
let reader = new FileReader();
|
|
reader.addEventListener('load', e => {
|
|
res(reader.result);
|
|
});
|
|
reader.addEventListener('error', e => {
|
|
rej(reader.error);
|
|
});
|
|
reader.readAsArrayBuffer(file);
|
|
});
|
|
}
|
|
|
|
function readFileAsDataUrl(file) {
|
|
return new Promise((res, rej) => {
|
|
let reader = new FileReader();
|
|
reader.addEventListener('load', e => {
|
|
res(reader.result);
|
|
});
|
|
reader.addEventListener('error', e => {
|
|
rej(reader.error);
|
|
});
|
|
reader.readAsDataURL(file);
|
|
});
|
|
}
|
|
|
|
function crc32(data) {
|
|
let crc = new Uint32Array(1);
|
|
crc[0] = 0;
|
|
crc[0] = ~crc[0];
|
|
let str = (typeof (data) == 'string');
|
|
for (let i = 0; i < data.length; i++) {
|
|
crc[0] ^= str ? data[i].charCodeAt(0) : data[i];
|
|
for (let i = 0; i < 8; i++) crc[0] = (crc[0] & 1) ? ((crc[0] / 2) ^ 0x4C11DB7) : (crc[0] / 2);
|
|
}
|
|
crc[0] = ~crc[0];
|
|
return crc[0];
|
|
}
|
|
|
|
function getMime(name) {
|
|
const mime_table = {
|
|
'avi': 'video/x-msvideo',
|
|
'bin': 'application/octet-stream',
|
|
'bmp': 'image/bmp',
|
|
'css': 'text/css;charset=utf-8',
|
|
'csv': 'text/csv;charset=utf-8',
|
|
'gz': 'application/gzip',
|
|
'gif': 'image/gif',
|
|
'html': 'text/html;charset=utf-8',
|
|
'jpeg': 'image/jpeg',
|
|
'jpg': 'image/jpeg',
|
|
'js': 'text/javascript;charset=utf-8',
|
|
'json': 'application/json',
|
|
'png': 'image/png',
|
|
'svg': 'image/svg+xml;charset=utf-8',
|
|
'txt': 'text/plain;charset=utf-8',
|
|
'wav': 'audio/wav',
|
|
'xml': 'application/xml;charset=utf-8',
|
|
};
|
|
let ext = name.split('.').pop();
|
|
if (ext in mime_table) return mime_table[ext];
|
|
else return 'text/plain';
|
|
}
|
|
|
|
function Array_maxBy(arr, fn) {
|
|
return arr.reduce((best, next) => {
|
|
const value = fn(next);
|
|
if (best && Math.max(best[0], value) == best[0]) return best;
|
|
return [ value, next ];
|
|
}, null)[1];
|
|
}
|
|
|
|
function Array_remove(arr, value) {
|
|
let index;
|
|
while ((index = arr.indexOf(value)) !== -1) arr.splice(index, 1);
|
|
}
|