You are reading a single comment by @allObjects and its replies. Click here to read the full conversation.
  • @d0773d, I got side tracked / delayed in talking about some of the things had in mind when elaborating on the CRC analysis and design technique. I had already some lines, when I tried to better understand what you want to achieve.

    Of course, I could just badmouth your code to everyones frustration... including mine... so I did not want to say anything before better understanding what the challenges actually are across all the layers of your application, hardware and software.

    Therefore I'd ask you to provide a bit more detail about the whole system. Even without that detail, I conclude, there is something in place - such as a central control / monitor node - that will receive the serialized object as string in JSON and then do something with it. Of course, the first part is the easy part: making an object out of JSON with ```var readings = JSON.parse(receivedByteArrayOrString);''­'.

    To give some hints how to decouple the systems, I would let the sensor node (or agent) to its job and read from some place (queue) your high level commands sent by the central control/monitor node, such as: '''takeAllReadings()'''. Since this takes a while, you best end up with an asynchronous coupling of your sensor and central nodes. Since readings are the most important things to you - I assume - you could let that happen with an initiating command that sets up an interval on the particular sensor node. When a reading - including time and all the other things - is complete, you just store it in a variable replacing the previous reading. When the central node is interested in a reading from a particular sensor node, it just asks and gets the most recent. Many of the sensor chips actually work this way, because having to sequence and wait for things all the way up through all layers of an application is a nightmare... indicated already in the amount of code you had to write for your sensor class. Split the it up into more classes / objects covering just a reasonable amount of functionality on a particular level and let lover levels be handled by collaborators... that's why I brought up the CRC stuff in the first place.

    Looking at the challenges here are timing, sequencing, which are purely technically and have 'basically' nothing to with your overall application architecture. This simplistic statement is though not completely truthful and does not good justice to the cause. Underlaying details - and in particular restrictions - have an impact on the UEberlaying (sorry for the word creation) overall architecture. For example: do not design something in an upper layer that expects a real time value within 100 ms... it will just not go-n-a happen... EXCEPT you say: is getting values within 100ms that are may be 5 seconds old? I guess you see where I'm heading for.

    Therefore, in your agent has a property mostRecentReadings and this is updated on an decent, reasonable, and implementable interval - actually a particular event, which is triggered by the completion of updates of the property readingsInProcess. Readings of the individual sensors go update latter property (in the way you do update readings right now, but on setting the last 'outstanding' reading, you just set mostRecentReadings to (now completed) readingsInProcess, and set readingsInProcess a new object { resTemp: null, ph: null, ec: null}. With a timeout you start taking all readings to not keep your agent not too busy burning power... (in case that matters).

    Furthermore, your sensor object looks like a 3 in one (or even more) object. If you can split these out, it could be of help. On the other hand, it looks that only the command sequences and their timings are different... Dividing up the knowledge into separate things that know just about sequencing micro commands singleton as a helper to a more generic sensor object, and similar sequencing of the agent to sequence the the sensors with macro commands. The separation simplifies the understanding and increases grokking by everyone else - including you - especially after you have left the working code alone for some time and need not to go in and make some changes, enhancements, extensions,... or just some simple version maintenance triggered by component version changes.

    In particular, the sonsor object does a lot of repeated things - including eating up memory - even though after being created as a particular sensor, it is never even need. For example you command sequences you can keep outside of your generic sensor code as singleton and pass them in as reference on construction. Furthermore, you can add a reference to a result processing function to get rid of the case-logic in lines 118..138 (I may though be mistaken, since I do not know with what hardware you are dealing...).

    Since these sensors could be looked at as just being a bunch of static declarations - such as your commands already are, you could go even further and make a complete declaration for each individual sensor that also includes the type.

    As dynamic part of the application you write a visitor that takes some parameter and then works itself through the declarations with the collaboration of some helpers, such as a queue, a time sequencer, etc... The problem that you already solved - the solution - of managing timing is not go-n-away, you just express (specify) it in a little bit different way and the so implement the processing - visiting - code. Lookup the visitor pattern... Combined with some timing - which you already do - you will get to the point where you comfortably collect data and stick it into complete / consistent readings that can be picked up anytime - with no delay - by a command from the central.

About

Avatar for allObjects @allObjects started