Skip Navigation

InitialsDiceBearhttps://github.com/dicebear/dicebearhttps://creativecommons.org/publicdomain/zero/1.0/„Initials” (https://github.com/dicebear/dicebear) by „DiceBear”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/)RA
Posts
4
Comments
215
Joined
2 yr. ago

  • I don't think the promise chain is really needed here.

    I used this script:

     js
        
    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.

     cpp
        
    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.

  • 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.

  • I don't think a semicolon is semantically correct in this case. It suggest you want to add something. That's why it is used in programming. You are making statements.

    Maybe we should use a . after return statements to signal the end of our statement stream.

  • That sucks.

    Makes me ponder though:

    Humans are more or less designed for nature like mountains/dirt trails. I think sidewalks/asphalt while great designs for society and big cities are actually less ideal for the individual human.

    Since living in the city I have learned to respect wet manhole covers.

  • I have also broken my pinky twice on the same doorframe on the way from the lunch table to the Xbox 360 in my aunts house. :)

    A third time I only sprained it if I remember correctly.

    Didn't keep me from playing on these days though. 😅

  • I tried displayport too. My main dell 4k monitor had some issues with it. I updated the firmware maybe it works better now.

    I have two monitors. Depending on where I plug in, it uses MST or no mst.

    Also good tip about the overheating but the dock has a fan and remains quite cool during operation.

    It's difficult to debug since sometimes it works for two days and on other days it hap'ens constantly.

  • I have had the problem with a variety of cables. I think its a software issue. Wiggeling the cable does not cause any issues. The screen never looses signal its just briefly black.

    But I guess it can't hurt to try more cables.

    1. My docking station. The screen sometimes goes black for a second or two randomly. I have had this problem with all kinds of docking stations.
    2. My egpu dock. It works great but I have to plug it in after boot or it won't be detected.
    3. My samsung galaxy S22 (my last sasmung phone). The camera sometimes doesn't work presumably because a ribbon cable inside is loose.
  • Rust Programming @lemmy.ml

    Runtime Const Generics

    Programmer Humor @lemmy.ml

    Using comments as arguments in python.

    Selfhosted @lemmy.world

    Do I need a second domain to run my own authoritative dns server?

    Selfhosted @lemmy.world

    Setting Up a Secure Tunnel Between Two Machines