Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Module System Discussion - Please contribute. #80

Closed
MichMich opened this issue Feb 7, 2016 · 115 comments
Closed

New Module System Discussion - Please contribute. #80

MichMich opened this issue Feb 7, 2016 · 115 comments
Labels

Comments

@MichMich
Copy link
Collaborator

MichMich commented Feb 7, 2016

Maybe it's a good idea to discuss the new Module System before we writeout the API.

@paviro, I noticed you've contributed. Thanks for this. I really appreciate your help! Just a few questions though:

The functions you proposed, are those method of a module class? I can't really wrap my head around how this would work, could you elaborate?

Also, I think the added regions are a bit unnecessary. In most cases you can just add content in one of the corners (the content will stack) or align right or left in the upper third, center or lower third. I think we should try to keep the layout simple.

Aslo, what do you guys think about using a system like vue.js? I'm not a big fan of jQuery, and prefer a mvvm model. But this might make it to difficult for most users to contribute.

EDIT 2016/3/23: First steps in the development are made. See: #80 (comment)

@paviro
Copy link
Contributor

paviro commented Feb 7, 2016

To be honest with you I haven't thought all that much about how to implement it. I just added what I would need to port my modules to the new system.

  • A way to start helper scripts written in Python and Node.js as background daemons (currently talking to the UI via socket.io - maybe we could provide a general module socket somehow?)
  • A way to switch between multiple views (one for general users and one for people who are logged in via facial recognition). I would therefore love the possibility to be able to define more than one module layout in config.js and also to switch them via a module. Might also be useful if you want to have different views for lets say work related and private stuff. A module could again provide an interface to switch between them for example via a GPIO button.

Since my edits in the wiki are not that useful in their current state, I will remove them, they are here now anyway.

Yeah you are right. Stacking is probably enough.
I guess I am not experienced enough in JavaScript to judge weather we should use jQuery or vue.js.

@bitte-ein-bit
Copy link

This is going to be some random thoughts.

I think if you switch to vue.js most user will not be able to contribute. I'm not sure about stability. I once used a rather new php framework (symfony 1.x) and later regretted it because their api change a LOT when going to 2.0. IMHO jQuery seems to have stabilized. I can't tell for vue.js or angular.js. Never used either. On the other hand not using spaghetti code is nice.

Personally I think it would be a good idea if a module could listen and trigger events. Some events could be defined (e.g. 'User changed', 'User logged out', 'Calendar event starting', 'GPIO x HIGH', ...) and some central instance could route them. This core should be very minimal and all that is needed to run the mirror. I think that everything else should be a module.

I agree with @paviro that some modules should be implemented without any use by themself like socket.io. This makes it necessary that modules can specify depends.

Regarding the helper scripts I think it would be nice to have e.g. a Makefile which will download and install the dependencies and setup an init.d or systemd script. Writing an daemon is rather advanced so IMHO the developer of that plugin should be able to find enough information to provide a Makefile. Other options would be some sort of Chef cookbook, Puppet Manifest, Bash Script, ... which could also setup the system itself. A Makefile would probably be the easiest.

I think the regions will work fine. But we should find a way, that a user can override all region positions without interfering with the main code. Not all mirrors are the same. So they might need some way to adjust margins, etc. For some modules it would be nice to render depending on the screen orientation but that is just eye candy.

@paviro
Copy link
Contributor

paviro commented Feb 10, 2016

I think I will write a Python CLI which could be used to install modules and also list all available modules with a description. I could implement the systemd or init.d scipt setup there :)

CLI

Something like:

  • magic-mirror list (show all plugins with short discription)
  • magic-mirror info module (show long description, dependencies etc. for module)
  • magic-mirror install module (installs module and dependencies)
  • magic-mirror remove (removes module and dependencies, if installed via magic-mirror install)
  • magic-mirror enable/disable module (?)
  • magic-mirror update (Update module list and versions)
  • magic-mirror upgrade (install updates)

@MichMich
Copy link
Collaborator Author

Hi @paviro, before we start building command line tools, It might be a good idea to first finish of the basic concept behind the modules. How they work, and how dependencies are loaded. - Also, since most of it is javascript based, we might consider using existing CLI tools, like npm. This way, we can put our effort in the enhancement of the mirror UI.

@MichMich
Copy link
Collaborator Author

@bitte-ein-bit I agree with the idea of event triggering. Besides a module instance, there should be indeed a MagicMirror shared instance (singleton concept) which can receive messages of the module instance (in other words, a delegate for the module).

The MagicMirror share instance (the main instance) could have methods to load and unload modules. A broadcasting system for notifications between modules (so no direct module to module communication). A method to reload the HTML/dom for a specific module ... etc.

Regarding the overriding for region positions: this can all be done by css. The region is just a simple way to load a module in a specific location, but the module is free to adjust it's design using CSS. (As long as it doesn't interfere with other visuals.)

CSS based, it might be a good idea to define some standard elements modules can be used. If all modules use the same css elements, we could also implement a tempting system in later stage.

Regarding dependencies and installing libs. I think this should be taken case of if we have the base of the module system running. IMHO we could use existing systems like NPM.

Most importantly: thanks for your effort and contributions. I love the fact we are working on the future of the Magic Mirror.

@MichMich
Copy link
Collaborator Author

As a small side note: If we start using NPM, we could also consider building a small node web server to host the magic mirror. This way, users don't need to install Apache & PHP.

@gefangenimnetz
Copy link

I would love a JS only implementation. That would allow for easy porting to to Android or IOS using build tools like cordova (phonegap), etc. Basically that’s what I am currently doing.

@paviro
Copy link
Contributor

paviro commented Mar 2, 2016

@MichMich Your are right :)

@MichMich
Copy link
Collaborator Author

MichMich commented Mar 2, 2016

Not sure yet, but I might have some spare time end of this month to work on this version.

@sclausen
Copy link

sclausen commented Mar 8, 2016

@gefangenimnetz I'm currently working on this. It's based on angular2 and I'm still not sure, if I'll add a backend. Meteor (still with an angular2 frontend) is one idea and works really well, especially with realtime server side functionality like motion detection.

@Vaggan Vaggan mentioned this issue Mar 9, 2016
@paviro
Copy link
Contributor

paviro commented Mar 9, 2016

@MichMich @bitte-ein-bit any news on your side? Any way I can help you with the module system with my limited JS knowledge?

@sclausen
Copy link

@gefangenimnetz @MichMich I started a javascript-only clone sclausen/MagicalMirror

@bitte-ein-bit
Copy link

Unfortunately I'm packed with other stuff to do. Don't have the time to
lock into a new backend right now. Sorry.

Am Do, 10. Mär 2016, um 14:46, schrieb Sebastian Clausen:

@gefangenimnetz @MichMich I started a javascript-only clone
sclausen/MagicalMirror


Reply to this email directly or view it on GitHub:
#80 (comment)

@sclausen
Copy link

@bitte-ein-bit currently it has no backend and works frontend only with calendar, news, weather and time.

@MichMich
Copy link
Collaborator Author

I'll be probable be working on a new version coming weeks. I'll keep you guys posted.

@paviro
Copy link
Contributor

paviro commented Mar 18, 2016

Nice looking forward to it!

@MichMich
Copy link
Collaborator Author

Hi Guys,

Today, I FINALLY started working on the module system. Although I only have the very simple foundation up and running, I think I'm really on the right track.

A small overview so far:

config.js
Used to define all the modules that need to be loaded, including the configuration for the specific module.
Adding a module to this config will ensure the module will be loaded, including all nessecery .js and .css files. So other than downloading a module to the module folder and adding it to the config, no further actions are required to add it to the mirror.

    var config = {
        modules: [
            {
                module: 'clock',
                position: 'middle_center',
                config: {
                    foo: 'Bar'
                }
            },
            {
                module: 'compliments',
                position: 'middle_center',
                config: {
                    compliment: 'You look hot!'
                }
            },
            {
                module: 'compliments',
                position: 'top_right',
            }
        ]
    };

modules/compliments/compliments.js
This is a very simple example of a module. Of course, this doesn't include any logic yes, but shows how simple a module is.

    Module.create({

        // Define the default config. This is optional.

        defaults: {
            compliment: "This is the default compliment"
        },


        // Define a start method. For example if you want to schedule timers,
        // or want to make connections to socket servers. Again: this is optional.

        start: function() {
            Log.info('Starting module: ' + this.name);
        },


        // Return an array of scripts that need to be loaded.
        // All scripts are loaded before the module is started.
        // Loading might be skipped if the file is already loaded.
        // The system contains a vendor folder for default libs like jQuery.
        // See comments below for more info.
        // This method is optional.

        getScripts: function() {
            return [
                'dummy.js', // Loaded (if available) form vendor folder, otherwise from module folder. Loaded only once.
                'http://server.com/js/file.js', // External file. Always loaded.
                this.file('foo.js'), // File from module folder. Multiple foo.js files might be loaded.
            ];
        },


        // Same system as getScripts().
        // This method is optional.

        getStyles: function() {
            return [
                'compliments.css'
            ];
        },


        // Returns the dom to be inserted in the mirror.
        // This method is optional.

        getDom: function() {
            var compliment = document.createTextNode(this.config.compliment);       
            var div = document.createElement("div");
            div.appendChild(compliment);

            return div; 
        }

    });

And thats all there is to write a module! Of course, I will continue to work on this. If I have any news I'll let you know. Hope to share a basic version next week.

All code so far is pure javascript. But of course, modules are free to use additional libs like jQuery.

Open for feedback.

@CFenner
Copy link
Contributor

CFenner commented Mar 23, 2016

Looks great. I like the js only approach.

@MichMich
Copy link
Collaborator Author

And, as an example, a super simple module to show something on the mirror:

modules/helloworld/helloworld.js:

Module.create({
    defaults: {
        text: "Hello World!"
    },
    getDom: function() {
        return document.createTextNode(this.config.text);  
    }
});

This allows you to display a text on the mirror via the config:

var config = {
    modules: [
        {
            module: 'helloworld',
            position: 'middle_center',
            config: {
                text: 'This works perfect!'
            }
        },
    ]
};

@paviro
Copy link
Contributor

paviro commented Mar 24, 2016

Looks great! :) How are we going about socket connections? Should each module create their own (also if it uses helper scripts) or should we create a connection module which serves information from one socket to all the modules which need it and helper scripts have to talk to our socket?

@MichMich
Copy link
Collaborator Author

I've implemented a notification system to communicate between modules. This will also be used for the incoming socket messages, and probably also for the outgoing messages (although I don't see a use case for outgoing messages yet ...).

@paviro
Copy link
Contributor

paviro commented Mar 24, 2016

There is a use case. I would like to implement voice control and also use that for example to set my alarm clock which would need outgoing connections.

@MichMich
Copy link
Collaborator Author

But in that case you might want to communicate with a socket other then the mirror's backend. For now, the backend won't include a module system. (Will definitely be on the todo list.)

@MichMich
Copy link
Collaborator Author

I pushed a very simple first version of the v2-beta to a separate branch. Unfortunately I did not have the time yet to write a readme, but most files have sufficient comments. I probably won't be able to work on this version coming few days, but will definitely continue the project next week.

Feel free to give it a spin!

https://github.com/MichMich/MagicMirror/tree/v2-beta

@Miyasashi
Copy link

Can someone explain what the module system does I dont really get it.

@MichMich
Copy link
Collaborator Author

It will (eventually) allow everyone to built modules for the magic mirror without the need of modifying the core of the system. This way everyone can provide modules that can be installer on the mirror.

@Miyasashi
Copy link

Thanks for the fast response, funny coincidence i had problems with implementing my own stuff and I think this will help a lot.

@paviro
Copy link
Contributor

paviro commented Apr 1, 2016

Any idea why this module overlaps with the calendar?
Screenshot

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 1, 2016

Are they in the same position? If so please open a separate issue with example code.

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 1, 2016

Found the issue. It's fixed. As well as the fading that didn't work at all times.

@paviro
Copy link
Contributor

paviro commented Apr 1, 2016

Nice!

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 1, 2016

I made a small start with the module documentation:
https://github.com/MichMich/MagicMirror/tree/v2-beta/modules/clock
https://github.com/MichMich/MagicMirror/tree/v2-beta/modules/calendar

I will continue to add documentation of the other models on a later stage. If anyone feels the urge to document the other modules, feel free! ;)

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 1, 2016

All module README.md's are ready. :)

@CFenner
Copy link
Contributor

CFenner commented Apr 1, 2016

Is the module system in a 'nearly complete' state by now?

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 1, 2016

Can't promise anything ... ;)

I'm working on one major change now. But that won't be a breaking change. After that, the next step will be the full documentation.

@paviro
Copy link
Contributor

paviro commented Apr 1, 2016

Do you have time to add the UI notifications or should I give it try this evening? :)

Am 01.04.2016 um 17:07 schrieb Michael Teeuw notifications@github.com:

Can't promise anything ... ;)

I'm working on one major change now. But that won't be a breaking change. After that, the next step will be the full documentation.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 1, 2016

No, sorry. No time for it. You can try, but I can't promise I will include/use it. Make sure you just make a separate module for it. (No core changes should be necessary);

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 1, 2016

I made a few huge changes on the loader. You should now be able to put modules in folder.
In the config you should be able to use module: 'foldername/modulename'. The default modules don't need the default/ prefix.

This way you can make packages of multiple modules.

@CFenner
Copy link
Contributor

CFenner commented Apr 1, 2016

Do I need to wrap a module in an extra folder or does the old way still work?

@paviro
Copy link
Contributor

paviro commented Apr 1, 2016

Still works :)

@CFenner
Copy link
Contributor

CFenner commented Apr 1, 2016

thanks, just found the error :)

@konzeptplus-gmbh
Copy link

Hi,

@MichMich Thanks for your great Codes.
Do you have an idea how I can add a calender with an auto-login?
As I'm not a Java-scripter I do not know how I should add the html code in the Java.

<HTML>
<HEAD>
<TITLE>Cal</TITLE>
<script>
    function loginForm() {
        document.myform.action = "https://ox.hostkonzept.ch/ox6/#m=calendar&f=26";
        document.myform.submit();
    }
</script>
</HEAD>
<BODY onLoad="loginForm()">
    <FORM NAME="myform" METHOD="POST">
        <INPUT TYPE="hidden" NAME="email" VALUE="myemail"> 
        <INPUT TYPE="hidden" NAME="password" VALUE="mypassw">
    </FORM>
</BODY>
</HTML>

Thanks for the help. :-)

@CFenner
Copy link
Contributor

CFenner commented Apr 6, 2016

@konzeptplus-gmbh, this would be better discussed in a separate issue.

@konzeptplus-gmbh
Copy link

Yes you are right. Sorry. :-)

@3vidar
Copy link

3vidar commented Apr 7, 2016

Hi guys

I love this project and decided to build my own mirror. But I'm not a coder;o( because of that i just would ask you pros if it is possible to implement in de middle of the screen a smart calendar? just like this shown in the picture (just the calendar connected to google calendar)?
fa6yc5bilche9z8 large

sglpazb6nupgo31sjxjt

Source of the pictures: http://www.instructables.com/id/Raspberry-Pi-Wall-Mounted-Calender-and-Notificatio/

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 7, 2016

The new system has a calendar module, but not in the way the above calendar looks like. It could easily be built, but as you said, you're not a coder ... ;)

@3vidar
Copy link

3vidar commented Apr 7, 2016

Because of that I ask you coder if you could build something like this for me? ;o) please

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 8, 2016

FYI: I've just added the following feature:

In some cases, you want to start the application without an actual app window. In this case, exectute the following command from the MagicMirror folder: node serveronly. This will start the server, after which you can open the application in your browser of choice.

a34a5c4

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 9, 2016

I started working on the developer documentation:
https://github.com/MichMich/MagicMirror/tree/v2-beta/modules/README.md

@MichMich
Copy link
Collaborator Author

MichMich commented Apr 9, 2016

I think most of the documentation is done. Please review.

@paviro
Copy link
Contributor

paviro commented Apr 9, 2016

Looks good, nice work! :) Spotted some typos but I have to learn right now.. Will fix them later if nobody else does until then.

@MichMich
Copy link
Collaborator Author

Guys, I've just announced this version on my blog: http://michaelteeuw.nl/post/142629029062/magicmirror²-a-huge-announcement

Including a special thank you to you guys! :)

@paviro
Copy link
Contributor

paviro commented Apr 11, 2016

Nice one! Happy I could help and thanks again for this now even more awesome project!

Am 11.04.2016 um 15:58 schrieb Michael Teeuw notifications@github.com:

Guys, I've just announced this version on my blog: http://michaelteeuw.nl/post/142629029062/magicmirror²-a-huge-announcement

Including a special thank you to you guys! :)


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@MichMich
Copy link
Collaborator Author

Since the new version is up and running, I close this issue. Please open separate issues for new feature requests and bugs.

DonIsaac pushed a commit to DonIsaac/MagicMirror that referenced this issue Sep 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants