mafredri / asustor_as-6xxt

All things ASUSTOR AS-6XXT sans ADM
20 stars 4 forks source link

Question about LCD Display #1

Closed artvel closed 3 years ago

artvel commented 3 years ago

Hi @mafredri

Great job! Any progress on the LCD display so far?

mafredri commented 3 years ago

Thanks. Yeah I believe I've captured most of the functionality. Writing message(s), clearing the screen, turning it on/off and reading button presses. (It can also be turned off by changing a gpio output on the it87 chip). I, however, never got around to finishing the program and actually making it useful 😄.

Would you mind telling me what your interest in it is? Are you running a custom Linux distro on your Asustor? Would you simply like it to be more powerful? Do you have a specific feature in mind?

artvel commented 3 years ago

Thanks for your quick response! Yeah, I am using it with debian and other tools on top of it. I would love to make it more powerful. Wanted to try to create a simple library for the display. So far, I was able to achieve that goal with a Qnap TVS-x72XT but not with the Asustor.

mafredri commented 3 years ago

Cool. I haven't really touched this code since 2018, but I'll try to clean it up a bit and push it to GitHub tomorrow. It's currently implemented like a client/server where the server is dumb to allow running it on the NAS and do quick iteration on the client (much good that did me 😅). (It's written in Go, btw)

artvel commented 3 years ago

Wow, that would be awesome. Thanks a lot in advance.

artvel commented 3 years ago

Btw, I love Go. My tools are written in Go too. Don't clean up to much just because of me.. I could clean it up too and share it afterwards.. Can't wait to play around with your solution.

mafredri commented 3 years ago

Nice, Go is pretty awesomely, yeah ☺️. Didn’t get around to this yesterday but I’ll make a new attempt tonight. Tomorrow at the latest. Not planning to delay it until it’s perfect but it was in the middle of a refactor so need to pick up the pieces. 😅

That said, your timing was pretty good because it had been on my mind this week before you asked, so it inspired me a bit. But anyway, like I said, won’t polish it too much, just want the code to be clear enough to pick up on wth is going on.

mafredri commented 3 years ago

Sorry I couldn't do this sooner @artvel, but here you go: https://github.com/mafredri/lcm. I added a README to help make sense of the project structure.

PRs are very much welcome! 😄

artvel commented 3 years ago

Wow! This is huge. Didn't expect that much code end structure :-) Looks nice, great job. Will let you know if it works for me soon. Hope I can return the favor if it does.. very nice!

mafredri commented 3 years ago

Thanks! I don't think they've updated the protocol since the original NASes but you never know. At least it works on both AS604T and AS6204T for me.

Some things to keep in mind if you run into issues:

These are just some observations, and you can look at some of the logs I've intercepted from the ASUSTOR daemon to see if those help, if you run into any trouble (linked them in the readme).

artvel commented 3 years ago

Works great! I have Asustor AS6404T. I think, I had some issues that could be related to Sync because I had to try it a couple of times until it finally worked.

Anyways, as I already said more than I expected! Really great job! Didn't expect to see a custom message on this display so soon.

artvel commented 3 years ago

I managed to implement a stable version based on the information/source you provided incl. button handling. Need to improve the quality a bit. But I am not sure if a PR would make sense. Up to you to decide.

I have a generic interface for displays like this and the asustor implementation is currently the second one. You are using it somehow differently. So this is my interface, it is not perfect but it does already more than I need. Would it suit your needs?

type (
    LCD interface {
        // Listen blocking for button events
        // Please note, not all devices support released=true
        Listen(l func(btn int, released bool) bool)
        // Enable(turn on) or disable(turn off) the display
        Enable(yes bool) error
        // Write a string message on line one or two
        Write(line Line, text string) error
        // Reopen the instance after a Close call
        Open() error
        // Close the connection to the display
        Close() error
    }
    // The line on the display. Most of them support only 0 and 1.
    Line int
    // Placeholder for an actual implementation
    dummy struct{}
)

/*
 Dummy functions to use as an actual display.
 As the display is mostly a nice to have feature anyways.
 */
func (d *dummy) Listen(l func(btn int, released bool) bool) {}
func (d *dummy) Enable(yes bool) error                      { return nil }
func (d *dummy) Write(line Line, text string) error         { return nil }
func (d *dummy) Open() error                                { return nil }
func (d *dummy) Close() error                               { return nil }

I use the dummy in case there is no implementation for a display to not break the common usage.

Example usage:

package main

import (
    "awesomeProject/display"
    "fmt"
    "time"
)

func main() {
    l, err := display.NewQnapLCD("")
        // l, err := display.NewAsustorLCD("")
    panicCheck(err)
    panicCheck(l.Write(0, "The first line?"))
    panicCheck(l.Write(1, "Hello second line"))
    go l.Listen(func(btn int, released bool) bool {
        _ = l.Write(0, "button clicked")
        _ = l.Write(1, fmt.Sprintf("id:%d, released:%v", btn, released))
        return true
    })
    time.Sleep(20 * time.Second)
    panicCheck(l.Enable(false))
    time.Sleep(5 * time.Second)
    panicCheck(l.Close())
}

func panicCheck(err error){
    if err != nil {
        panic(err)
    }
}

Let me know what you think.

mafredri commented 3 years ago

That's awesome, I'm stoked you managed to make use of it!

Regarding the project, I think what I'd be looking for is improvements that make the communication more robust and/or improvements to the lcm API to cover more use-cases, but I think the interface is well suited for a separate wrapper package that calls the lcm methods to expose the unified LCD API. Alternatively if there's a widely used standard API (for LCDs) it could be a good fit for the project. Btw, if you've had to make changes to the lcm package to accommodate the interface, it'd be interesting to see if we can make some general tweaks to the lcm API to make it more suited for the use case.

Thanks for reporting back on your results! ☺️

artvel commented 3 years ago

Yeah, I would have done it sooner. But didn't know how to start the communication from scratch with zero commands. Btw. where did you find those command?

My results are pretty slight compared to your delivery.

-dispaly(package):
---asustor.go // asustor impl.
---qnap.go //qnap impl.
---generic.go //interface...

How do you want me to share it? Could create a new repository and you could check if you can use it for your purposes or if it is trash :-)

artvel commented 3 years ago

@mafredri I fixed the sync issue almost like you suggested here: https://github.com/mafredri/asustor_as-6xxt/issues/1#issuecomment-851050407

None of my tests failed so far. Should be rock solid now.

Repo: https://github.com/artvel/display

mafredri commented 2 years ago

@mafredri I fixed the sync issue almost like you suggested here: #1 (comment)

Glad it worked out 👍🏻.

Could you btw include the MIT license from mafredri/lcm for the relevant parts that were copied/based on the project? I had originally thought you would use lcm as a library in your project and call its functions, but the way you implemented it works fine too, of course.

It's great that you published your project, hope it can be beneficial for some other people too. ☺️

Yeah, I would have done it sooner. But didn't know how to start the communication from scratch with zero commands. Btw. where did you find those command?

By intercepting communication between the LCM daemon on ADM and the screen, and reverse-engineering the protocol. Took a while to figure everything out. 😄