I guess lowest I would go is -30°C. Ideally something varying between 20°C and -30°C.
raldone01
Fixed. Blame it on typing this on mobile and being in a rush to the underground.
Hahah I guess both. You learn a lot with either. 😅
I like to think that I am good at root causing software issues.
Cold*. You can always put on more but once you're naked, well you're naked.
*Limits apply.
I don't think the promise chain is really needed here.
I used this script:
import Axios from 'axios'
import OldFS from 'fs'
import { PromiseChain } from '@feather-ink/ts-utils'
const fs = OldFS.promises
const image = process.argv[2]
const destination = `http://${process.argv[3]}/vfs/ota`
const now = process.argv[4] === 'now'
const once = process.argv[4] === 'once'
async function triggerUpdate(): Promise<void> {
console.log('Uploading new binary')
const file = await fs.readFile(image)
await Axios({
method: 'POST',
url: destination,
headers: {
'Content-Type': 'application/octet-stream',
'Content-Length': file.byteLength
},
data: file
})
console.log('Finished uploading')
}
(async () => {
const updateChain = new PromiseChain()
console.log(`Watching file '${image}' for changes\nWill upload to '${destination}'!`)
if (once) {
await triggerUpdate()
return
}
if (now)
await updateChain.enqueue(triggerUpdate)
OldFS.watch(image, async (eventType) => {
if (eventType !== 'change')
return
let succ = false
do {
try {
console.log('Change detected')
await updateChain.enqueue(triggerUpdate)
succ = true
} catch (e) {
console.error(e)
console.log('Retrying upload')
}
} while (!succ)
console.log('Upload finished')
})
})()
Relevent code on the esp:
You can ignore my cpp stuff and just put this in the handler of the stock webserver.
auto ota = vfs->addHandler(makeDirectory("ota"));
{
ota->addHandler(makeDirect([](auto &con) {
if (con.req->method != HTTP_POST)
return HandlerReturn::UNHANDLED;
// https://github.com/espressif/esp-idf/tree/master/examples/system/ota/native_ota_example/main
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/ota.html
auto updatePartition = esp_ota_get_next_update_partition(nullptr);
if (updatePartition == nullptr)
return sendError(con,500, "No free ota partition found!");
esp_ota_handle_t otaHandle;
auto err = esp_ota_begin(updatePartition, con.req->content_len, &otaHandle);
if (err != ESP_OK)
return sendError(con, 500, std::string{"Can't start ota update: "} + esp_err_to_name(err), true);
int receivedBytes = 0;
do {
auto end = httpd_req_recv(con.req, buf.data(), buf.size());
// ESP_LOGE(TAG, "Received %d", receivedBytes);
// hexDump("RECV:", buf.data(), end);
if (end <= 0) {
esp_ota_abort(otaHandle);
return sendError(con, 500, "Error receiving", true);
}
err = esp_ota_write(otaHandle, buf.data(), end);
if (err != ESP_OK) {
esp_ota_abort(otaHandle);
return sendError(con, 500, std::string{"Error writing: "} + esp_err_to_name(err), true);
}
receivedBytes += end;
} while (receivedBytes < con.req->content_len);
err = esp_ota_end(otaHandle);
if (err != ESP_OK)
return sendError(con, 500, std::string{"Failed to end: "} + esp_err_to_name(err), true);
err = esp_ota_set_boot_partition(updatePartition);
if (err != ESP_OK)
return sendError(con, 500, std::string{"esp_ota_set_boot_partition failed: "} + esp_err_to_name(err), true);
auto ret = sendOK(con);
FactoryResetServiceCon().reboot(1000 / portTICK_PERIOD_MS);
return ret;
}));
}
I also used a custom partition table for 2 partitions so that when my program crashes it can just go back to boot the previous version.
Here it is for reference:
partitions.csv
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, 0x011000, 0x006000,
otadata, data, ota, 0x017000, 0x002000,
phy_init, data, phy, 0x019000, 0x001000,
ota_0, app, ota_0, 0x020000, 0x1F0000,
ota_1, app, ota_1, 0x210000, 0x1F0000,
Note: This partition table is for a special model of the ESP32 though.
Also another disclaimer: This code does not represent my current coding abilities and may be outdated - it worked well though.
Hahahah. Awesome. Have fun! You just need a simple webserver. The builtin one will do and then you use the ota functions of the ESP IDF.
Back in school my friends all flashed their mcus with 4-8MB images over serial with 115200 baud. I set up ota updates over wifi. They were all fascinated by my speedy flashes. However when I offered to help them set it up, not one was interested because their setup was working as is and slow flashing is not a "bad" thing since it gave them an excuse to do other things.
We are talking minutes vs seconds here.
The teachers were surprised by my quick progress and iterations. When I told them my "trick" the gave me bonus points but also were not interested in learning how to do ota which was very easy. A simple 20 minute first time setup would have saved sooo much time during the year.
Very interesting. I hope this passes as an actual Standart. I looked around but couldn't find information on how to enable it in the Webbrowser. It just says firefox is not supported.
Nevermind I found the extension will try it again.
I would love a if there was a standard websites would use to receive donations. An integrated browser addon that track what you visit and gives you a review before distributing funds after each month would be great. It should accumulate money to avoid transaction fees for tiny amounts.
MacLeod is so great! Good pick.
I would probably go for Urban Conspiracy by Jules Gaia. https://music.youtube.com/watch?v=3_6ka9EV1i4
Maybe just alternate between these two.
I actually like the taste of unseasoned food.