Help Bites


  • Discourse touched me in a no-no place

    @hungrier said in Help Bites:

    But is it Windows only?

    Nah, it's Java so it'll run on MacOS or Linux.

    @hungrier said in Help Bites:

    extremely fiddly to work with token authentication redirects and json payloads

    Depends what you need but probably. It's at least possible to script it with other stuff if needed.


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    weird cookie issues

    Ah, yeah, if your API is fucking around with cookies, good luck. That shit is janky on web browsers as it is...


  • Fake News

    @loopback0 said in Help Bites:

    @hungrier said in Help Bites:

    What's the best HTTP API test software? It can't possibly be Postman

    I use SoapUI or good ol' curl depending on what I need to do.

    Do you use the "free" version or the paid version ($600 a year)?

    Main downsides is that pricing, the fact that it has been originally made for SOAP calls while REST got added in later (big surprise given the name) and the fact it's UI is stuck in the year 2003 (unless they rewrote that less than a year ago, but I'm not holding my breath).

    However, my opinion might be somewhat colored by a test project setup by an external consultant. We asked for a way to quickly get multiple scenarios up and running without too much boilerplate, and we ended up with some inner-platform SoapUI thing driven by an Excel file.


  • Discourse touched me in a no-no place

    @JBert said in Help Bites:

    Do you use the "free" version or the paid version ($600 a year)?

    Free.

    @JBert said in Help Bites:

    the fact that it has been originally made for SOAP calls while REST got added in later

    The REST stuff works, although a lot of our stuff is still SOAP, so that's not really an issue.

    @JBert said in Help Bites:

    UI is stuck in the year 2003 (unless they rewrote that less than a year ago, but I'm not holding my breath).

    Yeah the UI is the same.



  • So I'm working on my task using postman, when suddenly it stops working. I do the normal thing of quitting and restarting, and this is what I get:

    42e367f7-9774-4428-b759-14391fc13baf-image.png

    Thanks Postman, very cool


  • Discourse touched me in a no-no place

    @hungrier Much beige, such wow.


  • And then the murders began.

    @hungrier said in Help Bites:

    For my current purpose I need something that'll work in Linux
    Curl may work for what I need but I think it would be extremely fiddly to work with token authentication redirects and json payloads

    Maybe PowerShell Core? Invoke-WebRequest can deal with cookies, and ConvertTo-JSON/ConvertFrom-JSON will handle the payloads. Not 100% sure on token authentication redirects.



  • @Unperverted-Vixen For now, at least when it works, I've got a setup working in postman that works for what I need. I don't really want to mess around with auth tokens on CLI tools



  • @loopback0 Cosmic Latte?



  • Linux file permissions and groups

    Say I have a root media folder, with subfolders for music, tv, and movies. Each of these has to be writable by some management app running under its own user with its own group, as I understand well-behaved Linux programs should do. They also all should be accessible and writable by Plex and preferably by a user logged into the desktop.

    Right now I'm thinking:

    • add all the users to a media group
    • media group owns the folder
    • each app owns its own folder
    • 775 permissions on everything

    Does that make sense, and/or is there some horrible pitfall that I don't see?


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    Does that make sense, and/or is there some horrible pitfall that I don't see?

    Seems fine to me. :mlp_shrug:

    Plex only needs read permission usually unless you want to make transcode versions of stuff.



  • @Tsaukpaetra I thought it also added some metadata, but maybe it doesn't put it next to the actual media. I don't know for sure


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    @Tsaukpaetra I thought it also added some metadata, but maybe it doesn't put it next to the actual media. I don't know for sure

    No, the metadata is kept in Plex's own application data folder.



  • @Tsaukpaetra I've got metadata together with my media but that must all be from Sonarr if it's not Plex


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    @Tsaukpaetra I've got metadata together with my media but that must all be from Sonarr if it's not Plex

    One easy trick is to see the owner of the files. 👍



  • @Tsaukpaetra It would be if these files were created by their respective programs on the Linux machine, but they're all copied from my (Windows) desktop


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    @Tsaukpaetra It would be if these files were created by their respective programs on the Linux machine, but they're all copied from my (Windows) desktop

    Whelp.


  • Discourse touched me in a no-no place

    @hungrier said in Help Bites:

    @Tsaukpaetra I've got metadata together with my media but that must all be from Sonarr if it's not Plex

    It is.



  • re: Plex requiring write access

    Something I hadn't thought of: If you need to pre-encode an H264 version for compatibility with things because the shitty computer can't convert 1080p VC1 on the fly, it needs to be somewhere that Plex has write access to. I ended up using another external "Plex versions" folder for now because I didn't feel like fiddling with Linux's shitty permission system any more for now.



  • Anyway the real reason I came back to this topic is something unrelated.

    I got the idea into my head to convert an old computer PSU into a bench power supply, and most of the guides I've seen mention that it may or may not need a dummy load on 5V in order to work. However I haven't seen any of them mention how to tell if it does. If it's something simple like it won't turn on without it, then I think I'm fine. However I don't want to go ahead without it if it's something like "it'll work fine for 37 minutes, then explode into flaming shards"

    Does anyone here have experience with this and/or know how to determine if my PSU requires the dummy load or not?


  • Fake News

    @hungrier As far as I know it boils down to testing it. I believe running without a load shouldn't do any damage, it's just that the PSU might shut down when it detects no load.

    Anyway, I was thinking of doing the same until I read someone correctly mentioning that those power supplies have a good bunch of power, but no real configurable protection circuits. As a result it will make not shut down when it is frying your circuits. Only use it on something you can risk to fry, or learn / buy kits to add it yourself.

    (In the end I splurged on a professional model bench power supply one late night, which I did regret the week after when I read that those too can burn up sometimes. Still, if I don't do reckless things with it then I guess it'll last me a lifetime. At least it's more likely that I'm doing something wrong in the circuit rather than the PSU failing to deliver. 😛 )


  • Considered Harmful

    @hungrier Depends on what you mean by "old computer PSU". If it's not total no-name, check if there are any schematics available - HardwareSecrets and JonnyGuru, maybe even Tom's Hardware. The idea is: if it's DC-DC topology (that is, it converts first to 12V, then feeds minor rails from that), you're fine. If there's no schematics, only thing is to become good at electronicks to open it up and figure out what goes where.



  • @JBert said in Help Bites:

    Anyway, I was thinking of doing the same until I read someone correctly mentioning that those power supplies have a good bunch of power, but no real configurable protection circuits. As a result it will make not shut down when it is frying your circuits. Only use it on something you can risk to fry, or learn / buy kits to add it yourself.

    I'm not terribly concerned about that for now. I don't have any real plans, but I like tinkering with stuff like that in general. It'd be nice to have something to show for it at the end, especially if it can be useful later on for whatever else I want to do.



  • @Applied-Mediocrity I did a quick search on the brand name, and the first thing is a forum where someone mentioned that the only thing they can find searching for it is that very thread :yodawg:


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    However I haven't seen any of them mention how to tell if it does.

    You bridge the power-supply-turn-on pin with ground (if memory serves) and if it turns on then it doesn't need anything more. 😉

    There's no way (visually) to tell, and it's not like it's listed on the box.



  • @Tsaukpaetra That's what it seems like from what I can see. I've seen the suggestion to verify that the voltages and PG are correct and steady, which sounds to me like they're saying "if it works, it's good"


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    "if it works, it's good"

    Yeah. The alternative "If it doesn't work, it should definitely not have been in a PC because shit's sensitive, man!"



  • @Tsaukpaetra If it's in a PC it wouldn't need a dummy load anyway


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    @Tsaukpaetra If it's in a PC it wouldn't need a dummy load anyway

    That's why it's not labeled or put on a spec or anything. 😛


  • Notification Spam Recipient

    Status: I think I'm doing evil. Is this evil?

    private:
      Client* m_client;
      void setClient(const Client& newClient) {m_client = const_cast<Client*>(&newClient);};
    
    
    ... In receiver function....
    
    template <class ServerT>
    void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen)
    {
      setClient(ServerInterface.available());
    ... blah blah....
    }
    

    the ServerT type is expected to be a passed-by-value object of Server, which has a function available() that returns an object subclassing the abstract class Client, but (as far as I can tell) I can't get it to make a copy constructor for it, so I'm doing the above.

    I don't care about the child class's shit, just the base class's methods (and being able to call them from the virtual table thingy of the sub-class whatever).

    Is this really the way?

    I also believe I'm going to have a memory leak before all is said and actually attempted to run, but I don't into C++ all that well and from the last conversation touting const I feel a little out of depth.

    Edit: Yeah, crashing hard. 🎉

    02:11:41.351 -> Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
    02:11:41.451 -> Core 1 register dump:
    02:11:41.485 -> PC      : 0x400d139e  PS      : 0x00060b30  A0      : 0x800d13fb  A1      : 0x3ffb1e10  
    02:11:41.587 -> A2      : 0x00000000  A3      : 0x3ffb8718  A4      : 0x000020a6  A5      : 0x3ffc0910  
    02:11:41.655 -> A6      : 0x00000021  A7      : 0x3ffc0198  A8      : 0x800d1395  A9      : 0x3ffb1df0  
    02:11:41.755 -> A10     : 0x3ffb1e8c  A11     : 0x3ffc0575  A12     : 0x67230001  A13     : 0x0000ff00  
    02:11:41.856 -> A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x0000000a  EXCCAUSE: 0x0000001c  
    02:11:41.959 -> EXCVADDR: 0x0000003c  LBEG    : 0x4000c428  LEND    : 0x4000c42d  LCOUNT  : 0x00000000  
    02:11:42.028 -> 
    02:11:42.028 -> Backtrace: 0x400d139e:0x3ffb1e10 0x400d13f8:0x3ffb1e30 0x400d14e5:0x3ffb1e50 0x400d2ec5:0x3ffb1e70 0x400d2f99:0x3ffb1ec0 0x400d2fb5:0x3ffb1f10 0x400d178d:0x3ffb1f30 0x400d19df:0x3ffb1f70 0x400d2e15:0x3ffb1f90 0x400d7fd1:0x3ffb1fb0 0x400889d9:0x3ffb1fd0
    02:11:42.299 -> 
    02:11:42.299 -> Rebooting...
    


  • @Tsaukpaetra said in Help Bites:

    object of Server, which has a function available() that returns an object subclassing the abstract class Client, but (as far as I can tell) I can't get it to make a copy constructor for it

    So, the Client-subclassed object is returned by value, its type could be "anything derived from Client", but you want to take WebDuino::processConnection to take ownership of it? Can you use move semantics inside the templated method to put the object on the heap, then stuff that pointer into m_client? Are you allowed to change Client if it turns out to forbid both copy-construction and move-construction?

    It would have been much easier if ServerInterface.available() returned a pointer. Or a std::unique_ptr<Client> if they wanted the caller to take ownership.

    so I'm doing the above.

    Yeah, you seem to be taking a pointer to a temporary object that only exists for the duration of the setClient() call.



  • @Tsaukpaetra const_cast is indeed evil. But also, as aitap said, it sounds like move semantics are what you want. Passing stuff by value goes well with move semantics, no need for copying anything since copying wouldn't make sense in this case.


  • BINNED

    @Tsaukpaetra what is ServerInterface.available() actually returning, a reference Client& or an actual object SomeClientImplementation?
    If it’s the latter, it should have at least a move constructor (not technically required anymore, but would be unusual). You are definitely storing a stale pointer to a temporary, which is worse than leaking memory and will crash.
    If it’s the former, it really depends on what the lifetime of the object is (are you taking ownership or not) how long that pointer is valid.

    As has been pointed out, your const cast is evil one way or another.


  • Notification Spam Recipient

    @aitap said in Help Bites:

    Can you use move semantics

    I have no idea what this is. Reading now.

    @aitap said in Help Bites:

    Are you allowed to change Client if it turns out to forbid both copy-construction and move-construction?

    This is the base Arduino api-thing, I'm already dealing with a breaking change the ESP32 devs decided to fuck up for some reason.

    @LB_ said in Help Bites:

    no need for copying anything since copying wouldn't make sense in this case.

    Yeah I'm trying to avoid copying, but I'm no so good with this memory stuff. I'm not even sure how to figure out if I'm fucking up the heap with this.

    @topspin said in Help Bites:

    @Tsaukpaetra what is ServerInterface.available() actually returning, a reference Client& or an actual object SomeClientImplementation?

    In this case it's a ServerInterface's Client object. Specfically:

    EthernetClient EthernetServer::available() {
    	//blah code to find sockindex, a uint8_t
    	return EthernetClient(sockindex);
    }
    

    If it’s the latter, it should have at least a move constructor (not technically required anymore, but would be unusual). You are definitely storing a stale pointer to a temporary, which is worse than leaking memory and will crash.

    Yes, it's definitely crashing! :surprised-pikachu:

    If it’s the former, it really depends on what the lifetime of the object is (are you taking ownership or not) how long that pointer is valid.

    I suppose I'm completely missing what is meant by "taking ownership". But I would agree that the pointer seems definitely invalid by the time it's actually used. 🙃

    As has been pointed out, your const cast is evil one way or another.

    I've added another thingy to the template, it now looks like this:

    
    template <class ClientT, class ServerT>
    void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen)
    {
      delete m_client;
      m_client = (Client*)new ClientT(ServerInterface.available());
    }
    

    But I'm sure this is also wrong in some way too, though it does seem to be working... (I'd have to spam the port with connections for some time to see if it fucks up, but my money is on YES).


  • BINNED

    @Tsaukpaetra said in Help Bites:

    I've added another thingy to the template, it now looks like this:

    
    template <class ClientT, class ServerT>
    void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen)
    {
      delete m_client;
      m_client = (Client*)new ClientT(ServerInterface.available());
    }
    

    But I'm sure this is also wrong in some way too, though it does seem to be working... (I'd have to spam the port with connections for some time to see if it fucks up, but my money is on YES).

    Looks better.
    You should wrap your m_client in a unique_ptr, then you can get rid of the delete.
    Also, didn't you say there is no copy constructor? 🤔


  • Notification Spam Recipient

    @topspin said in Help Bites:

    You should wrap your m_client in a unique_ptr, then you can get rid of the delete.

    I don't know what that is. Researching....

    Also, didn't you say there is no copy constructor? 🤔

    I didn't see one defined? Is that one of the automagic ones? I just typed words until it seemed to work...



  • Is this the code you're having to use? https://github.com/arduino-libraries/Ethernet/blob/75a3c37b5e513305b82e926ca6a4f8190f536c9d/src/Ethernet.h#L214-L250

    I can't find "Client.h", but I haven't spent more than a few minutes searching. So far though my impressions of this are... not good. It's a polymorphic class type, but they have left the copy and move ctors to be implicit, which means there is potential for slicing if you assign a more derived type to a less derived type.

    But anyway, it looks like move semantics will not work for you after all due to the polymorphism. You do need to use a smart pointer. Pretty simple:

    private:
        std::unique_ptr<Client> m_client;
        template<typename ClientT>
        void setClient(ClientT newClient)
        {
            m_client = std::make_unique<ClientT>(std::move(new_client));
        }
    

    This will take any client and move it into a smart pointer, then the m_client var will hold it as long as ClientT is derived from Client.

    template <class ServerT>
    void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen)
    {
        setClient(ServerInterface.available());
        //... blah blah....
    }
    

    Then this original code you had can remain unchanged, it will just work with the new code above. We are using move semantics here, to move the return value of ServerInterface.available() from the stack to the heap (pointed to by the uniue_ptr), but that's of the same type as the fully derived type that the available() function returns by value (copy or move). You could avoid using unique_ptr and just move it into the class directly if you knew the fully derived type in advance, but since you want to accept anything that derives from Client you need to use a pointer here.

    The full chain of operations now is:

    1. ServerInterface.available() returns some concrete type by value that derives from Client
    2. that return value gets passed into the parameter of setClient by value (copy or move, likely elided by the compiler)
    3. a dynamic allocation happens to hold the ClientT
    4. the parameter is given to the move constructor of the new dynamically allocated one, and thus from our perspective moved from the stack to the heap (this can also be elided by the compiler)
    5. the pointer is stored as a member variable, thanks to the = being overloaded to allow more-derived unique_ptr to be assigned to less-derived unique_ptr. Any previous value in the member variable is freed.

    With compiler optimizations it can probably go straight from step 1 to the end of step 4, only needing to keep the dynamic memory allocation.


  • Notification Spam Recipient

    @LB_ said in Help Bites:

    Is this the code you're having to use? https://github.com/arduino-libraries/Ethernet/blob/75a3c37b5e513305b82e926ca6a4f8190f536c9d/src/Ethernet.h#L214-L250

    Yes.

    I can't find "Client.h", but I haven't spent more than a few minutes searching. So far though my impressions of this are... not good. It's a polymorphic class type, but they have left the copy and move ctors to be implicit, which means there is potential for slicing if you assign a more derived type to a less derived type.

    Yeah, Client.h is an almost completely-abstract class. (if I'm understanding how that works) consisting of all virtual methods and looks basically identical with exception of the ints there.

    But anyway, it looks like move semantics will not work for you after all due to the polymorphism. You do need to use a smart pointer. Pretty simple:

    private:
        std::unique_ptr<Client> m_client;
        template<typename ClientT>
        void setClient(ClientT newClient)
        {
            m_client = std::make_unique<ClientT>(std::move(new_client));
        }
    

    This will take any client and move it into a smart pointer, then the m_client var will hold it as long as ClientT is derived from Client.

    template <class ServerT>
    void WebDuino::processConnection(ServerT &ServerInterface, char *buff, int *bufflen)
    {
        setClient(ServerInterface.available());
        //... blah blah....
    }
    

    Then this original code you had can remain unchanged, it will just work with the new code above. We are using move semantics here, to move the return value of ServerInterface.available() from the stack to the heap (pointed to by the uniue_ptr), but that's of the same type as the fully derived type that the available() function returns by value (copy or move). You could avoid using unique_ptr and just move it into the class directly if you knew the fully derived type in advance, but since you want to accept anything that derives from Client you need to use a pointer here.

    Yeah, originally the Webduino code (that I'm shamelessly ripping from) explicitly called upon the EthernetClient and EthernetServer classes directly, but since I wanted it to be interchangable that's why I want it to be a pointer.

    The full chain of operations now is:

    1. ServerInterface.available() returns some concrete type by value that derives from Client
    2. that return value gets passed into the parameter of setClient by value (copy or move, likely elided by the compiler)
    3. a dynamic allocation happens to hold the ClientT
    4. the parameter is given to the move constructor of the new dynamically allocated one, and thus from our perspective moved from the stack to the heap (this can also be elided by the compiler)
    5. the pointer is stored as a member variable, thanks to the = being overloaded to allow more-derived unique_ptr to be assigned to less-derived unique_ptr. Any previous value in the member variable is freed.

    With compiler optimizations it can probably go straight from step 1 to the end of step 4, only needing to keep the dynamic memory allocation.

    Sounds like a plan. But, I'm assuming I missed a step somewhere, it's complaining weirdly...

     error: 'unique_ptr' in namespace 'std' does not name a template type
    
       std::unique_ptr<Client> m_client;
    

  • BINNED

    @Tsaukpaetra add #include <memory>.


  • Notification Spam Recipient

    @topspin said in Help Bites:

    @Tsaukpaetra add #include <memory>.

    Discoverable...

    And for this then?

     error: 'make_unique' is not a member of 'std'
       m_client = std::make_unique<ClientT>(std::move(ServerInterface.available()));
                  ^
     error: expected primary-expression before '>' token
       m_client = std::make_unique<ClientT>(std::move(ServerInterface.available()));
                                          ^
    

    I kinda wish I could just stuff my head back into the sludge that is PHP. In fact, Imma do that now....


  • BINNED

    @Tsaukpaetra guessing (on the phone) you need to change your compiler flags. Increase to -std=c++14 for make_unique or go directly to 17.
    If that’s not supported, you could skip the make_unique<ClientT>(...) part and replace it with unique_ptr<ClientT>(new ClientT(...)).


  • Notification Spam Recipient

    @topspin said in Help Bites:

    @Tsaukpaetra guessing (on the phone) you need to change your compiler flags. Increase to -std=c++14 for make_unique or go directly to 17.
    If that’s not supported, you could skip the make_unique<ClientT>(...) part and replace it with unique_ptr<ClientT>(new ClientT(...)).

    No, can't do c++ bigger than 11 without annoying hacks to the device definitions. Chaining the unique_ptr and new seems to work. I'm wondering why that makes me not need to delete it though? More reading is in store for me I guess...


  • BINNED

    @Tsaukpaetra said in Help Bites:

    Chaining the unique_ptr and new seems to work. I'm wondering why that makes me not need to delete it though? More reading is in store for me I guess...

    That is exactly the point of unique_ptr. Its destructor calls delete, so you can’t forget it (even in the case of exceptions) or call it twice. One fewer source of common bugs (99infinitely many remaining).



  • @Tsaukpaetra said in Help Bites:

    More reading is in store for me I guess...

    cppreference is an always-useful resource for me: https://en.cppreference.com/w/cpp/memory/unique_ptr

    std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope.

    The object is disposed of using the associated deleter when either of the following happens:

    • the managing unique_ptr object is destroyed
    • the managing unique_ptr object is assigned another pointer via operator= or reset().

    The object is disposed of using a potentially user-supplied deleter by calling get_deleter()(ptr). The default deleter uses the delete operator, which destroys the object and deallocates the memory.

    If you want to, for example, use std::free instead (e.g. when needing to manage something given by a C library that was allocated with std::malloc or std::calloc) you can do this:

    struct StdFreeDeleter final { void operator()(void *p) noexcept { std::free(p); } };
    template<typename T>
    using c_unique_ptr = std::unique_ptr<T, StdFreeDeleter>;
    
    c_unique_ptr<some_c_struct> ptr (some_c_function());
    use_some_c_struct(ptr.get());
    ptr.reset(some_other_c_function());
    

  • Considered Harmful

    I've got some fucking obnoxious settings enforced on my work laptop by Group Policy (eg, screen lock with password after 5 minutes of idle). Is there any way that I, a user that has managed to obtain local admin rights, can override or disable GPOs?


  • Notification Spam Recipient

    @error said in Help Bites:

    override or disable GPOs?

    Sounds like this question:



  • So I was looking at my Linux machine in the basement again, trying to get5.1 channel audio working.

    My janky Rube Goldberg setup has a bunch of HDMI sources plugged into an HDMI switcher with audio extraction, which connects with HDMI to my TV and with toslink to my (old, pre-HDMI) audio receiver. This works great for my Playstations that support the right format of digital audio over HDMI that can be extracted in this way. Not so great for my Nintendo consoles that apparently can only output 5.1 PCM. I've also got the computer hooked up to this thing with HDMI, and stereo works but 5.1 seems to be PCM only as well.

    What I did find that works is connecting the optical output directly from my computer to the receiver. It's not immediately available but with some additional software I could enable AC3 5.1-channel output on the optical port, and my receiver is perfectly happy with that. However, it's kind of flaky when plugging it in and out, and I'd prefer to have everything going through the HDMI switcher.

    Is there any way to enable the AC3 format for 5.1 over HDMI? I spent a bunch of time looking at (old, crappy) guides that I could find online, but none of them worked. The worst was trying to use Xplayer's AC3 passthrough with an AC3 encoded file, which seemed to work for 4 seconds then crashed the entire audio system so hard that the HDMI sound device was completely gone until I rebooted.


  • Notification Spam Recipient

    @hungrier said in Help Bites:

    my Linux machine

    Well first you're going to need the kernel sources...



  • Docking Station Status: I recently got an additional work laptop with a USBC docking station, and they work together great. Power, network, display, probably USB (haven't tried yet, :kneeling_warthog:). But I've also got another work laptop with USBC, which I've verified can be powered over USBC, so I figured I would try replacing the (proprietary) dock that that one uses with this new dock, to make better use of my desk space.

    Everything worked right off the bat, with one exception: power. For some reason, the laptop that's just fine being plugged into a USBC power brick rated for 65W, is unable to draw power from the dock that, according to the manual, should work with laptops that need up to 130W. :wtf:



  • There's more to USB-C power than just wattage. It's actually a :wtf: standard with plenty of variations and options. So compatibility problems are not rare.

    I don't think there's much you can do to solve the problem while keeping your existing dock, unfortunately. A firmware update for the dock and/or the laptop, maybe?


Log in to reply