For UIBUILDER you might also want to look at the Github project
I though that if I get uibuilder
that I don't need to use the dashboard
as it is a kind of replacement.
But thanks.
Tab opened for the link.
(Gee this last O/S update is taking a L-O-N-G time.)
Then I'll have to update NR, then install uibuilder
.
Personally, I suggest going with the new dashboard rather than uibuilder. That is what I have done.
Terminology. Not really "on top of". More "as well as".
It is possible to have uibuilder pages included as iframe
s in D1/D2 and may be possible the other way around as well. That would be "on top of" I think. But this can be somewhat more complex due to browser restrictions on cross-site security.
But, as Colin says, running all 3 side-by-side is perfectly possible and I do that as well on my test device. My live device runs D1 and uibuilder. I do simple things using D1 if they happen to fit into the standard layout restrictions of D1. Everything else I do in uibuilder.
Keep the questions coming in the forum Andrew. There are various people in the forum who can help including myself but I'm keen that we keep conversations open so that others can benefit in the future.
You don't need to be concerned, this is, after all, by far the friendliest forum on the Internet!
Everyone starts somewhere. In any case, I'm keen also to get any feedback from new users as I can use it to improve things for future new users. That can be hard when you are so close to the project.
This is the documentation for the live version (currently v6)
And don't forget my video series. And if you have any suggestions for future video topics, let me know.
The documentation is also built into node-red when you install uibuilder.
And, of course, there is a tag here in the forum: Topics tagged node-red-contrib-uibuilder which includes release info and some FAQ's. The GitHub site also has a WIKI and there are some flows on the flows site.
And finally, not forgetting that uibuilder has a number of example flows that you can install from the Node-RED import library varying from simple to complex.
I fear I am going to make mistakes soon as I have both machines up and running.
(See my other thread/question/post abut help updating)
After getting the new machine up and working I am getting errors when I try to configure NR.
But this - I fear - is getting off topic for this thread and what it is meant to do.
(But to digress)
I'm sitting here with 2 x keyboards
, 2 x mice
and 2 x monitors
. I have to be careful what I do as I may use the wrong one if I don't keep an eye on myself.
I'm trying to set up VNC, but that too is a whole other thread - yet another one.
Ah, just saw your other post - on the other thread - read on the other machine.
Yes, lets keep that in a separate thread.
Haha, I sympathise. I develop on my standard desktop which also does paid work(!) and other stuff. But my "live" services are on an old laptop repurposed as a Debian server. Some stuff for work also needs me to use a remote desktop.
You may want to get used to using command lines to do things like updating the OS and checking logs, that way you can "simply" SSH to the remote device in a terminal window, generally much faster than trying to use VNC. Also, if you can get to a point where you don't run a GUI desktop on your servers, they will perform MUCH better generally.
Once you have caught up your installations, you should rarely need to dip into the remote command line - especially if you learn how to do automatic updates of the remote OS (for Linux, this is pretty simple, there is a package for that). Then virtually everthing else only needs a browser.
But do try to keep on top of OS updates, it will make your life a LOT easier.
@TotallyInformation
Got the machine working again. (Phew)
Yeah, it is MY project and I decided to take it on.
But I am still not fully understanding the mechanics of how to do it.
Be it all fancy or even just the basic idea.
(Yeah, so I maybe should have kept my mouth shut)
So this is my understanding of how things would work.
I appreciate that it is better to know at least SOME knowledge of what is needed. I hope what is below shows I am not too innocent to that which I have taken on.
(basic)
Starting with no names:
There is an array which is empty.
When someone logs in their name is added to the array.
The array is thenupdated (on the screen) and their name is shown.
This repeats as more people arrive.
As people leave their entry in the array is changed to indicate they have left.
At the end of the day (new day) the array is wiped/reset to no one being there.
So that is fine, but that's about where my understanding ends.
I have no idea how to do that even in a basic way.
Let alone with the existing NR and even less with ui-builder
.
That isn't saying ui-builder
is bad. I am stating my limits.
Someone mind helping me get past this roadblock?
Lets start with just Node-RED.
Work up the process you've just described using just node-red, forget about the front end for a bit.
You've described it well enough so now have a go at creating some data and simulating the process.
That should give you some more insight.
Ok, shall try.
Just now I'm watching your videos on ui-builder.
I see we are similar that we both have LOT of tabs open.
So should I continue watching or work on the base code?
Not trying to make you do any hard lifting but I am not sure the kind of tricks needed to do this are in my scope.
But I'll give it a go.
Go. You've got the basic idea so have a play with that first.
STUCK ALREADY
Very much near the start, I have no idea how to sort the names.
If it was a simple array: no worries.
But - alas how I've done it (right or wrong) - I'm stuck.
Very basic flow:
(press the create attendance day
button before you start)
[{"id":"3debcbb5496f6fa6","type":"inject","z":"f838263ce79e696b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Andrew","payloadType":"str","x":180,"y":440,"wires":[["1a227c92ce826f75"]]},{"id":"16ec9f717ac04713","type":"inject","z":"f838263ce79e696b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Barry","payloadType":"str","x":180,"y":480,"wires":[["1a227c92ce826f75"]]},{"id":"dfeb03e0598f9afc","type":"inject","z":"f838263ce79e696b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Barney","payloadType":"str","x":180,"y":520,"wires":[["1a227c92ce826f75"]]},{"id":"0782f361710d99e1","type":"inject","z":"f838263ce79e696b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Colin","payloadType":"str","x":180,"y":560,"wires":[["1a227c92ce826f75"]]},{"id":"6301dc94c94613ad","type":"inject","z":"f838263ce79e696b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Clive","payloadType":"str","x":180,"y":600,"wires":[["1a227c92ce826f75"]]},{"id":"7259b305663811d4","type":"inject","z":"f838263ce79e696b","name":"Create attendance array","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":300,"wires":[["b335992cc023d801"]]},{"id":"b335992cc023d801","type":"change","z":"f838263ce79e696b","name":"","rules":[{"t":"set","p":"attendance","pt":"flow","to":"{}","tot":"json"},{"t":"set","p":"count","pt":"flow","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":300,"wires":[[]]},{"id":"1a227c92ce826f75","type":"function","z":"f838263ce79e696b","name":"function 1","func":"const name = msg.payload\n\nlet attendance = flow.get(\"attendance\")\nlet count =flow.get(\"count\") || 0;\nnode.status({text:count})\n\nattendance[count] = name\n\n\nflow.set(\"attendance\",attendance)\ncount = count + 1\nflow.set(\"count\",count)\n\nmsg.payload = attendance\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":440,"wires":[["f462036af12b3de3","7a618fc675b82b2f"]]},{"id":"f462036af12b3de3","type":"debug","z":"f838263ce79e696b","name":"Sign in order","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":380,"wires":[]},{"id":"4652319886a54d75","type":"debug","z":"f838263ce79e696b","name":"Alphabetical","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":800,"y":380,"wires":[]},{"id":"7a618fc675b82b2f","type":"function","z":"f838263ce79e696b","name":"function 2","func":"let incoming = msg.payload\n\nconst sortedKeys = Object.keys(incoming).sort()\n\nmsg.payload = sortedKeys\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":590,"y":440,"wires":[["4652319886a54d75"]]}]
The first list shows names in the order they sign in.
The second is supposed to be sorted on the name.
Yes, there is code there, but it doesn't work.
I've looked at a lot of links how to sort, but it is written in a foreign language to me.
If I change the code in function 1
to:
const name = msg.payload
let attendance = flow.get("attendance")
let count =flow.get("count") || 0;
node.status({text:count})
attendance[count] = { "name": name,"count":count}
flow.set("attendance",attendance)
count = count + 1
flow.set("count",count)
msg.payload = attendance
return msg;
(Slight change in structure, but....)
All I get out are the numbers in the sorted
node.
But that is kind of to be expected. I totally changed the structure of the message.
Just a thought, use a set
rather than an object. And add an entry and an exit timestamp as these are things likely to be important.
Thanks, but I seem to (still) not understand that.
I can live with an unsorted list - for now.
Then if it sees the same name input it marks the person as Gone home and puts the time they left beside their name.
But I am having the devils own time trying to understand how to create a structure I can sort and see if there is a second entry for an existing one.
I have done SIMILAR things but they weren't a one by one entry thing.
It was a whole preconstructed list that was done.
And the search was easy.
But I am swimming in circles - getting more and more dizzy the longer I do it - and not getting anywhere.
If you have an identifier for a person, then you can use either an object or a set. Both will give you unique entries.
So assuming that you use a person's name as the id and use an object, doing something like
// Assuming the msg payload contains the name of someone entering
const attendence = flow.get('attendence) || {}
attendence[msg.payload] = { entrance: new Date(), present: true }
flow.set('attendence', attendence)
Gives you a unique entry for each person.
Similarly, this gives you the exit.
const attendence = flow.get('attendence) || {}
attendence[msg.payload] = { exit: new Date(), present: false }
flow.set('attendence', attendence)
I've assumed function nodes here but you could use change nodes if preferred.
Hang on while I try to get my head around it.
Just now I have a lot of other attempts open and active.
I'll have to shut them down, read your latest idea and see if I can understand it.
Alas I am worried as you have (not intentionally) concatenated commands - I believe.
Oh, one thing that caught my eye.
const attendence = flow.get('attendence) || {}
attendance
needs to be closed with the '
at the end - yes?
Well spotted, my typo, yes.
Sorry, I'm having difficulty understanding the structure of each entry.
(To digress)
As said: I have a similar thing and I can search it.
Indulge me.
The inject
I have all the stuff so if I get new channels I edit that, rather than a file.
It gets injected (on change - which is also handy) and it written to a file.
Not sure if that is good or even needed.
Anyway, the file is read, goes through a JSON
node and the flow.context
is set.
You can see that is correct on the right side of the screen.
So, sort of taking on what you said, and making the file structure a bit more complex - allowing easier searching, etc - I am seeing this:
File: on local machine for testing.
cat members.txt
{
"name":"Andrew","status":"",
"name":"Barney","staus":""
}
I'll check the `JSON`` node, but.....
I'll post now. Not to go too far down the wrong road.
Ok, I did have a SLIGHT difference in structure there.
Tried the harder structure - from the first screen shot - and I still don't get the correct output in the context
view.
It is always only text. No matter what I set in the JSON
node.
All 3 tried. All 3 give text.
(Got it working)
Honestly, there was a slight oops with the structure.
So I have to have the entire list of members loaded also?
The msg.payload
comes in - indicating they are arriving - and it marks them with the time in.
I'm missing something.
New Day - everything is cleared.
First person comes in.
I am with you to this point.
So now i have to created a list of people who have interacted with the system TODAY.
So I will have to extract that information.
Or did I get 1 step ahead of where you are?
Na.
Stuck again.
So if I put the first bit of code and the payload
arrives, the person is marked as in attendance.
So the code would have to return
after that.
So if/when the second time the name is received it will have to go to the second part.
I'm not seeing an if
line in here to split where things go if the person has already clicked once today and is now leaving.
Or, (noticing the exit
in the second block: Does it go before the first one?
Seriously, I really don't understand it. I only have a concept of what is going on.
My problem/fault/what ever.
Oh, I've renamed the present
as in
and out
.
But that may be another downfall for me.
I don't understand the structure for the names.
Oh, and sorry, with the { entrance: new Date(), present: true }
Should that be
{"entrance":new Date(),"present":true}
And why is it new Date()
and not new_Date()
?
Or something?
My structure parsing system has just hung.
(No offense to you.)