diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..125ec8b --- /dev/null +++ b/AUTHORS @@ -0,0 +1,24 @@ +EMA Libre Cliente nace en el 2018 de la formulación de un proyecto de Investigación +denominado proyecto EMA Libre, este software es parte de un conjunto de tres sistema: +EMA Libre Cliente (Capincho), EMA Libre Center (Capibara) y EMA Liber Visor (Ronsoco). + +Desarrollado por el Laboratorio de Investigación Gugler perteneciente a la Facultad +de Ciencia y Tecnología de la Universidad Autónoma de Entre Ríos. A continuación +se detalla la lista de colaboradores y desarrolladores: + + Exequiel Aramburu . + Mario Martin Sbarbaro . + José Luis Mengarelli . + Federico Bonnet . + Alexis Sostersich . + Marcos Elias Rios Nuñez . + +Se agradece a la Facultad de Ciencia y Tecnología de la Universidad Autónoma de Entre Ríos +por permitir la conformación de este equipo interdisciplinario de profesionales y alumnos +colaboradores. Para llevar acabo una investigación de esta magnitud, permitiendo mostrar +las cualidades y bondades del Software Libre. + +Finalmente, no se solicito declaración de renuncia de copyright a la facultad, ya que por Medio +de la Resolución CS Nº 063/18, el Consejo Directivo de la Facultad de Ciencia y Tecnología +de la Universidad Autónoma de Entre Ríos, aprueba el proyecto Investigación, el cual especifica +que el software utilizara una licencia libre. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..e9057b4 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md index 9268249..70afe6f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,150 @@ -# Carpincho +# EMA Libre Cliente :: Carpincho -El objetivo de recolectar, registrar y publicar información meteorológica. Los datos son obtenidos a través de los diferentes sensores de una estación USB compatible, para así enviarlos a “Capibara” para ser validados y almacenados. Carpincho puede operar en modo "Recolector", realizando la tarea antes descripta, u operar en modo "Visor", sin la necesidad de contar con una estación meteorológica, donde se convierte un visualizador de información meteorológica obtenida desde una estación de EMA Center a través de una llave de lectura. +EMA Libre + +## Índice + + + +* [Introducción ](#introducci%C3%B3n) + * [¿Porque iniciamos el proyecto?](#porque-iniciamos-el-proyecto) + * [Nuevas características](#nuevas-caracteristicas-) +* [Plataforma Soportadas](#plataforma-soportadas) + * [Plataformas soportadas (binarios)](#plataformas-soportadas-binarios) + * [Plataformas soportadas (no binarios)](#plataformas-soportadas-no-binarios) +* [Repositorio Oficial](#repositorio-oficial) +* [código fuente](#obten-el-c%C3%B3digo-fuente) +* [Equipo de Desarrollo](#equipo-de-desarrollo) +* [Agradecimientos](#agradecimientos) +* [Contactanos](#contactanos) +* [Sitio Oficial](#sitio-oficial) + + +_ _ _ + +[![Build Status](https://travis-ci.org/joemccann/dillinger.svg?branch=master)](https://travis-ci.org/joemccann/dillinger) + + + +## Introducción +**Carpincho** tiene el objetivo de recolectar, registrar y publicar información meteorológica. Los datos son obtenidos a través de los diferentes sensores de una estación USB compatible, para así enviarlos a “Capibara” para ser validados y almacenados. Carpincho puede operar en modo "Recolector", realizando la tarea antes descripta, u operar en modo "Visor", sin la necesidad de contar con una estación meteorológica, donde se convierte un visualizador de información meteorológica obtenida desde una estación de Ema Center a través de una llave de lectura. + +Actualmente, soporta tres sistemas operativos y tres modos (GUI o Desktop, Web y Consola): + +* GNU/Linux (los tres modos) +* Microsoft Windows (sólo GUI) +* Raspberry PI (los tres modos) + +Instale el que más se adapte a sus necesidades, por ejemplo el modo consola es mas liviano, no posee interfaz gráfica, ideal para producción. + +### ¿Porqué iniciamos el proyecto? +Decidimos encarar este proyecto, por diversas razones, una de ellas es que la información meteorológica en la actualidad es una de las herramientas más importantes para la toma de decisiones, tanto en las actividades agropecuarias, turísticas, de transporte y hasta la protección de la salud se ven beneficiadas con la misma, entre otras tantas aplicaciones. +Pero, la principal motivación y justificación para el desarrollo de este proyecto es que en la actualidad no se cuenta con un software integral que permita no solo recolectar, sino almacenar y visualizar eficientemente los datos recabados por múltiples estaciones meteorológicas, y que la licencia del software no posea restricciones de uso, distribución, modificación y análisis. +Por ello, es que decimos adaptar y desarrollar software, con licencias libres y crear EMA Libre, así cualquier persona u organismo pueda descargar y hacer uso, y si quisiera podría modificar el modo de operar EMA o proveer alguna nueva funcionalidad que le de valor agregado al producto ya definido. + +### Nuevas características ! + +#### Versión 1.35: (Diciembre 10, 2024) + + + Se actualizó la versión de nwjs → 0.94.0 + + Se actualizó la versión de node → 22.07.0. + + Se actualizó la versión de RGraph -> 6.20. + + Se actualizó la versión de bootstrap → 4.6.2 + +#### Versión 1.26: (Diciembre 1, 2019) + ++ Se modifica la publicación de redes el parámetro intensidad de luz, modificando la medida. ++ Se actualizó node a la versión 13.2.0 en modo consola. ++ Se actualizó la versión de nwjs 0.42.6. ++ Se actualizó la versión de RGraph a la 5.11 ++ Se actualizó la versión de Charjs a la 2.9 ++ Se actualizó la versión de node-hid a la 1.0.0 ++ Se actualizó a Datatable v1.10.20 + +#### Versión 1.25: (Octubre 26, 2019) + ++ Se incorpora el servicio de monitor, el cual reinicia el equipo, si no detecta registros. + Este solo se permite habilitar, si se encuentra establecido el inicio automático en true. + Por defecto: + * Umbral = 10 minutos -> Si supera este umbral reinicia. + * Control = 3 minutos -> Cada cuánto controla. ++ Se actualizó node a la versión 12.11.1 en modo consola. + + +## Plataforma Soportadas + +### Plataformas soportadas (binarios) + +- Linux x64 +- Linux ARM / Raspberry Pi +- Windows x64 (64-bit) + +### Plataformas soportadas (no binarios) +- Windows x86 (32-bit) (¹) +- Linux x86 (¹) + +(¹) No precompilamos paquetes para la arquitectura x86, pero pueden ser compilados por el usuario y funcionan. + + +## Repositorio Oficial + +Recomendamos utilizar nuestro repositorio oficial de paquetes Deb, agréguelo y reciba actualizaciones más fácilmente: + +``` +echo 'deb http://deb.gugler.com.ar all contrib' > /etc/apt/sources.list.d/emalibre.list +curl -sL http://deb.gugler.com.ar/repo-gpg.key | apt-key add - +apt-get update +apt-get install emalibre-console , emalibre-gui o emalibre-web + +``` + +## Obtén el código fuente + +Para empezar a contribuir con el código de EMA Center, necesitas hacer una copia +del repositorio principal de desarrollo: + +HTTP: +``` +git clone https://git.gugler.com.ar/EMA_Libre/Carpincho.git + +``` + +SSH: +``` +git clone git@git.gugler.com.ar:2222/EMA_Libre/Carpincho.git + +``` + +## Equipo de Desarrollo: +##### A continuación se detalla la lista de colaboradores y desarrolladores: + +|Integrante del Equipo|Email Contacto| +| ------ | ------ | +|Exequiel Aramburu|exequiel@gugler.com.ar +|Federico Bonnet|federico@gugler.com.ar +|José Luis Mengarelli |jlmenga@gugler.com.ar +|Alexis Sostersich |alexis@gugler.com.ar +|Marcos Elias Rios Nuñez |marcos@gugler.com.ar + +## Agradecimientos + +Se agradece a la Facultad de Ciencia y Tecnología de la Universidad Autónoma de Entre Ríos por permitir la conformación de este equipo interdisciplinario de profesionales y alumnos colaboradores, y llevar a cabo una investigación de esta magnitud, permitiendo mostrar las cualidades y bondades del Software Libre. +Finalmente, no se solicitó declaración de renuncia de copyright a la facultad, ya que por Medio +de la Resolución CS Nº 063/18, el Consejo Directivo de la Facultad de Ciencia y Tecnología +de la Universidad Autónoma de Entre Ríos, aprueba el proyecto Investigación, el cual especifica +que el software utilizará una licencia libre. + +## Contactanos + +Si deseas realizar consultas, sugerencias o simplemente tenes alguna duda sobre nuestros productos/servicios, puedes comunicarte con nosotros a través de los siguientes medios oficiales: + Teléfono: (+54 343) - 4975044 - Interno 119 + Correo Electrónico: contacto@gugler.com.ar + Sitio Oficial: https://www.gugler.com.ar + +## Sitio Oficial + +* [Servidor/Recolector de datos](https://emacenter.gugler.com.ar/ "EMA Center") +* [Visor de datos via web](https://ema.gugler.com.ar/ "EMA Visor") + +[![N|Solid](https://ema.gugler.com.ar/imgs/LogoLGPLv3-mobile.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) +[![N|Solid](https://ema.gugler.com.ar/imgs/logo_gugler_lab-mobile.png)](https://www.gugler.com.ar)[![N|Solid](https://ema.gugler.com.ar/imgs/logo_uader_mini-mobile.png)](http://fcyt.uader.edu.ar/web/) diff --git a/build/Deb64/DEBIAN/postinst b/build/Deb64/DEBIAN/postinst new file mode 100755 index 0000000..8414a80 --- /dev/null +++ b/build/Deb64/DEBIAN/postinst @@ -0,0 +1,26 @@ +#!/bin/sh +# postinst script for EmaLibre +set -e +printf "\033[1;4m3) Se aplican los permisos necesarios.\033[0m" +chmod -R 777 /usr/share/emalibre +chmod a-x /usr/share/menu/emalibre +chmod 777 /usr/share/applications/emalibre.desktop +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;4m4) Se actualizan los menus del sistema.\033[0m" +if [ "$1" = "configure" ] && [ -x /usr/bin/update-menus ]; then update-menus ; fi +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;4m5) Se actualizan las reglas de udev..\033[0m" +udevadm control --reload-rules +printf "\033[1;32m --> OK. \033[0m\n" +if [ -f "/tmp/ConfiguracionGeneral.js" ]; then + printf "\033[1;4m6) Se restaura el archivo de configuracion.\033[0m" + mv -f /tmp/ConfiguracionGeneral.js /usr/share/emalibre/conf/ || true + chmod 777 /usr/share/emalibre/conf/ConfiguracionGeneral.js + printf "\033[1;32m --> OK. \033[0m\n" + else + echo "" + echo "IMPORTANTE: Archivo de configuracion por defecto. Por favor configurelo antes de comenzar: " + printf "\033[1;36m --> /usr/share/emalibre/conf/ConfiguracionGeneral.js. \033[0m\n" + echo "" +fi +exit 0 diff --git a/build/Deb64/DEBIAN/postrm b/build/Deb64/DEBIAN/postrm new file mode 100755 index 0000000..a2b4290 --- /dev/null +++ b/build/Deb64/DEBIAN/postrm @@ -0,0 +1,4 @@ +#!/bin/sh +set -e +echo "Se actualiza los menus y reglas de control..." +if [ "$1" = "configure" ] && [ -x /usr/bin/update-menus ]; then update-menus ; fi diff --git a/build/Deb64/DEBIAN/preinst b/build/Deb64/DEBIAN/preinst new file mode 100755 index 0000000..63c8385 --- /dev/null +++ b/build/Deb64/DEBIAN/preinst @@ -0,0 +1,51 @@ +#!/bin/sh +# preinstalador script for Emalibre +# resumen de los parametros de este script: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' +set -e +pidFile="/var/run/emalibre.pid" +pidMonitorFile="/var/run/monitor_emalibre.pid" +echo "" +printf "\033[1;35m***************************************************************\n" +printf "Estimado, gracias por instalar EMA Libre Cliente (Carpincho)!!.\n" +printf '***************************************************************\033[0m\n' +echo "" +printf "\033[1;4m1) Comenzamos por verificar si ya existe configuracion personal...\033[0m\n" +case "$1" in + install|upgrade) + + printf "\033[1;10m * 1.0) Se verifica y detiene si existe EMA Libre corriendo.\033[0m" + # 0. Se detiene emalibre si existe instancia corriendo. + if [ -f $pidFile ]; then + rm -f /var/run/emalibre.pid + rm -f /var/run/emalibre.log + fi + if [ -f $pidMonitorFile ]; then + rm -f /var/run/monitor_emalibre.pid + rm -f /var/run/monitor_emalibre.log + fi + printf "\033[1;32m --> OK. \033[0m\n" + # 1. Se consulta si existe el archivo de configuracion + if [ -f "/usr/share/emalibre/conf/ConfiguracionGeneral.js" ]; then + printf "\033[1;10m * 1.1) Existe un archivo de configuracion, se realiza backups.\033[0m" + cp -f /usr/share/emalibre/conf/ConfiguracionGeneral.js /tmp || true + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[1;10m * 1.1) Es una instalación nueva, no existe archivo de configuracion.\033[0m" + printf "\033[1;32m --> OK. \033[0m\n" + fi + printf "\033[1;4m2) Comienza la instalacion:\033[0m\n" + ;; + abort-upgrade) + printf "\033[1;31m Opps... ocurrio un error!!. \033[0m\n" + ;; + + *) + printf "\033[1;31mOpps. preinst llamado con un argumento desconocido \`$1' \033[0m\n" >&2 + exit 1 + ;; +esac +exit 0 diff --git a/build/Deb64/etc/emalibre_modo b/build/Deb64/etc/emalibre_modo new file mode 100755 index 0000000..c077218 --- /dev/null +++ b/build/Deb64/etc/emalibre_modo @@ -0,0 +1 @@ +web diff --git a/build/Deb64/etc/init.d/emalibre b/build/Deb64/etc/init.d/emalibre new file mode 100755 index 0000000..5d42bb5 --- /dev/null +++ b/build/Deb64/etc/init.d/emalibre @@ -0,0 +1,258 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: EMA Libre Carpincho +# Required-Start: $syslog +# Required-Stop: $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: EMA Libre Carpincho demonio +# Description: Start/stop/Restart EMA Libre Carpincho +### END INIT INFO + +### CONFIG ZONE +# Get function from functions library +#set -e +. /lib/lsb/init-functions + +RETVAL=0 + +# Nombre del servicio. +serviceName="emalibre" + +# Ubicacion de la APP +appFilePath="/usr/share/emalibre" + +# Archivo de Inicio. +web="gui_web/express.js" +console="core/ema.js" + +### END CONFIG ZONE + +# Ubicacion de logs y del pid. +pidFile="/var/run/$serviceName.pid" +logFile="/var/run/$serviceName.log" + +# Ubicacion de node como modulo de carpincho. +nodemodule="$appFilePath/node_modules/node/bin" + +# Ubicacion de forever como modulo de carpincho. +foreverApp="$appFilePath/node_modules/forever/bin/forever" + +# Ubicacion de logs de EMA Libre +emaLogs="$appFilePath/logs/debug.log" + +export PATH=$PATH:$nodemodule + +start() { + if [ ! -f /etc/emalibre_modo ] + then + `echo "consola" > /etc/emalibre_modo` + fi + MODO=`cat /etc/emalibre_modo` + if [ -f $pidFile ]; then + log_daemon_msg "EMA libre Carpincho se encuentra corriendo." + RETVAL=$? + else + if [ $MODO = 'consola' ] + then + log_daemon_msg "Comenzando EMA Libre Carpincho en modo consola" + echo "$(date '+%d/%m/%Y %H:%M:%S') - 0|SERVICIO|Inicio el servicio en modo consola." >> $emaLogs + $foreverApp start --uid "EMA_Consola" --id "EMA_Consola" --minUptime 5000 --spinSleepTime 5000 --sourceDir $appFilePath --workingDir $appFilePath --pidFile $pidFile -l $logFile -a -d -c node "$console" console + RETVAL=$? + else + log_daemon_msg "Comenzando EMA Libre Carpincho en modo web" + echo "$(date '+%d/%m/%Y %H:%M:%S') - 0|SERVICIO|Inicio el servicio en modo web." >> $emaLogs + $foreverApp start --uid "EMA_Web" --id "EMA_Web" --minUptime 5000 --spinSleepTime 5000 --sourceDir $appFilePath --workingDir $appFilePath --pidFile $pidFile -l $logFile -a -d -c node "$web" encender + RETVAL=$? + fi + fi + RETVAL=$? +} + +restart() { + log_daemon_msg "Reiniciando EMA Libre Carpincho" + echo "$(date '+%d/%m/%Y %H:%M:%S') - 0|SERVICIO|Reiniciando el servicio." >> $emaLogs + $foreverApp restart $nodemodule + RETVAL=$? +} + +stop() { + if [ -f $pidFile ]; then + log_daemon_msg "Deteniendo EMA Libre Carpincho." + echo "$(date '+%d/%m/%Y %H:%M:%S') - 0|SERVICIO|Detenido el servicio." >> $emaLogs + $foreverApp stopall + RETVAL=$? + else + log_daemon_msg "EMA libre Carpincho no se encuentra ejecutandose." + fi + RETVAL=$? +} + + +status() { + log_daemon_msg "Mostrando estado nativo del servicio." + RETVAL=$? +} + + +uptime() { + echo "$(date '+%d/%m/%Y %H:%M:%S') - 0|SERVICIO|Mostrando el uptime del servicio (consola)." >> $emaLogs + $foreverApp list + RETVAL=$? +} + +reporte() { + echo "$(date '+%d/%m/%Y %H:%M:%S') - 0|SERVICIO|Mostrando el reporte de consola." >> $emaLogs + pushd "$appFilePath/core" + node reporte.js + RETVAL=$? +} + +if [ -d /usr/share/emalibre/gui_web ] +then + # SI EXISTE EL MODULO GUI_WEB se habilitan algunas opciones + case "$1" in + start) + start + + ;; + stop) + stop + + ;; + status) + status + + ;; + restart) + restart + + ;; + reporte) + reporte + + ;; + uptime) + uptime + + ;; + set-web) + log_daemon_msg "Se configuró EMA Libre en modo web." + `echo "web" > /etc/emalibre_modo` + + ;; + set-consola) + log_daemon_msg "Se configuró EMA Libre en modo consola." + `echo "consola" > /etc/emalibre_modo` + + ;; + set-inicio-enabled) + log_daemon_msg "Se Habilito el servicio para inicio automatico." + systemctl enable emalibre + + ;; + set-inicio-disable) + log_daemon_msg "Se Deshabilito el inicio automatico del servicio." + systemctl disable emalibre + + ;; + view-conf) + log_daemon_msg "Configuración de EMA Libre Carpincho" + log_daemon_msg "-------------------------------------" + if [ -f /etc/emalibre_modo ] + then + log_daemon_msg "Modo actual: `cat /etc/emalibre_modo` " + else + `echo "consola" > /etc/emalibre_modo` + log_daemon_msg "Modo actual: `cat /etc/emalibre_modo` " + fi + log_daemon_msg "Inicio Automatico (servicio): `systemctl is-enabled emalibre 2> echo`" + log_daemon_msg "" + log_daemon_msg "----------------------" + log_daemon_msg "Configuracion Global:" + log_daemon_msg "->`grep "Version" /usr/share/emalibre/conf/ConfiguracionGlobal.js`" + log_daemon_msg "->`grep "Nombre" /usr/share/emalibre/conf/ConfiguracionGlobal.js`" + log_daemon_msg "----------------------" + log_daemon_msg "Configuracion General:" + log_daemon_msg "" + log_daemon_msg "-> Tiempo de Recolección: `sed -E 's/.*"Tiempo_de_Recoleccion":"?([^,"]*)"?.*/\1/' /usr/share/emalibre/conf/ConfiguracionGeneral.js |sed '1d' | sed '/^$/d'`" + log_daemon_msg "-> UTC: `sed -E 's/.*"UTC":"?([^,"]*)"?.*/\1/' /usr/share/emalibre/conf/ConfiguracionGeneral.js |sed '1d' | sed '/^$/d'`" + log_daemon_msg "-> Nivel Debug: `sed -E 's/.*"debug":"?([^,"]*)"?.*/\1/' /usr/share/emalibre/conf/ConfiguracionGeneral.js |sed '1d' | sed '/^$/d'`" + + ;; + *) + echo "Utilice: {start|stop|status|restart|set-web|set-consola|set-inicio-enabled|set-inicio-disable|view-conf|reporte|uptime}" + exit 1 + + ;; + esac +else + # SI NO EXISTE EL MODULO GUI_WEB se habilitan solo modo consola + case "$1" in + start) + start + + ;; + stop) + stop + + ;; + status) + status + + ;; + restart) + restart + + ;; + reporte) + reporte + + ;; + uptime) + uptime + + ;; + set-inicio-enabled) + log_daemon_msg "Se Habilito el servicio para inicio automatico." + systemctl enable emalibre + + ;; + set-inicio-disable) + log_daemon_msg "Se Deshabilito el inicio automatico del servicio." + systemctl disable emalibre + + ;; + view-conf) + log_daemon_msg "Configuración de EMA Libre Carpincho" + log_daemon_msg "-------------------------------------" + if [ -f /etc/emalibre_modo ] + then + log_daemon_msg "Modo actual: `cat /etc/emalibre_modo` " + else + `echo "consola" > /etc/emalibre_modo` + log_daemon_msg "Modo actual: `cat /etc/emalibre_modo` " + fi + log_daemon_msg "Inicio Automatico (servicio): `systemctl is-enabled emalibre 2> echo`" + log_daemon_msg "" + log_daemon_msg "----------------------" + log_daemon_msg "Configuracion Global:" + log_daemon_msg "->`grep "Version" /usr/share/emalibre/conf/ConfiguracionGlobal.js`" + log_daemon_msg "->`grep "Nombre" /usr/share/emalibre/conf/ConfiguracionGlobal.js`" + log_daemon_msg "----------------------" + log_daemon_msg "Configuracion General:" + log_daemon_msg "" + log_daemon_msg "-> Tiempo de Recolección: `sed -E 's/.*"Tiempo_de_Recoleccion":"?([^,"]*)"?.*/\1/' /usr/share/emalibre/conf/ConfiguracionGeneral.js |sed '1d' | sed '/^$/d'`" + log_daemon_msg "-> UTC: `sed -E 's/.*"UTC":"?([^,"]*)"?.*/\1/' /usr/share/emalibre/conf/ConfiguracionGeneral.js |sed '1d' | sed '/^$/d'`" + log_daemon_msg "-> Nivel Debug: `sed -E 's/.*"debug":"?([^,"]*)"?.*/\1/' /usr/share/emalibre/conf/ConfiguracionGeneral.js |sed '1d' | sed '/^$/d'`" + + ;; + *) + echo "Utilice: {start|stop|status|restart|set-inicio-enabled|set-inicio-disable|view-conf|reporte|uptime}" + exit 1 + + ;; + esac +fi + +exit $RETVAL \ No newline at end of file diff --git a/build/Deb64/etc/udev/rules.d/99-emalibreusb.rules b/build/Deb64/etc/udev/rules.d/99-emalibreusb.rules new file mode 100755 index 0000000..8e9b268 --- /dev/null +++ b/build/Deb64/etc/udev/rules.d/99-emalibreusb.rules @@ -0,0 +1,3 @@ +SUBSYSTEM=="input", GROUP="input", MODE="0666" +SUBSYSTEM=="usb", ATTRS{idVendor}=="1941", ATTRS{idProduct}=="8021", MODE:="666", GROUP="plugdev" +KERNEL=="hidraw*", ATTRS{idVendor}=="1941", ATTRS{idProduct}=="8021", MODE="0666", GROUP="plugdev" \ No newline at end of file diff --git a/build/Deb64/usr/share/applications/emalibre.desktop b/build/Deb64/usr/share/applications/emalibre.desktop new file mode 100755 index 0000000..91b42bb --- /dev/null +++ b/build/Deb64/usr/share/applications/emalibre.desktop @@ -0,0 +1,18 @@ +[Desktop Entry] +Type=Application +Terminal=false +Exec=emalibre --user-data-dir=/tmp/emalibre/cache_temporal +Name=EMA Libre +GenericName=EMA Libre +Comment=Estación Meteorológica Automática Libre +Categories=Utility; +Icon=/usr/share/emalibre/gui_common/iconos/icono_app.png +Actions=RootWindow;Window + +[Desktop Action Window] +Name=EmaLibre +Exec=emalibre --user-data-dir=/tmp/emalibre/cache_temporal + +[Desktop Action RootWindow] +Name=emalibre +Exec=gnome-terminal -e "bash -c 'sudo -i emalibre --user-data-dir=/tmp/emalibre/cache_temporal;'" \ No newline at end of file diff --git a/build/Deb64/usr/share/doc/emaLibre/AUTHORS b/build/Deb64/usr/share/doc/emaLibre/AUTHORS new file mode 100755 index 0000000..125ec8b --- /dev/null +++ b/build/Deb64/usr/share/doc/emaLibre/AUTHORS @@ -0,0 +1,24 @@ +EMA Libre Cliente nace en el 2018 de la formulación de un proyecto de Investigación +denominado proyecto EMA Libre, este software es parte de un conjunto de tres sistema: +EMA Libre Cliente (Capincho), EMA Libre Center (Capibara) y EMA Liber Visor (Ronsoco). + +Desarrollado por el Laboratorio de Investigación Gugler perteneciente a la Facultad +de Ciencia y Tecnología de la Universidad Autónoma de Entre Ríos. A continuación +se detalla la lista de colaboradores y desarrolladores: + + Exequiel Aramburu . + Mario Martin Sbarbaro . + José Luis Mengarelli . + Federico Bonnet . + Alexis Sostersich . + Marcos Elias Rios Nuñez . + +Se agradece a la Facultad de Ciencia y Tecnología de la Universidad Autónoma de Entre Ríos +por permitir la conformación de este equipo interdisciplinario de profesionales y alumnos +colaboradores. Para llevar acabo una investigación de esta magnitud, permitiendo mostrar +las cualidades y bondades del Software Libre. + +Finalmente, no se solicito declaración de renuncia de copyright a la facultad, ya que por Medio +de la Resolución CS Nº 063/18, el Consejo Directivo de la Facultad de Ciencia y Tecnología +de la Universidad Autónoma de Entre Ríos, aprueba el proyecto Investigación, el cual especifica +que el software utilizara una licencia libre. diff --git a/build/Deb64/usr/share/doc/emaLibre/COPYING b/build/Deb64/usr/share/doc/emaLibre/COPYING new file mode 100755 index 0000000..f288702 --- /dev/null +++ b/build/Deb64/usr/share/doc/emaLibre/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/build/Deb64/usr/share/doc/emaLibre/README b/build/Deb64/usr/share/doc/emaLibre/README new file mode 100755 index 0000000..e69de29 diff --git a/build/Deb64/usr/share/menu/emalibre b/build/Deb64/usr/share/menu/emalibre new file mode 100755 index 0000000..ecb110d --- /dev/null +++ b/build/Deb64/usr/share/menu/emalibre @@ -0,0 +1,4 @@ +?package(emalibre):needs="X11" section="Applications" \ +title="emalibre" command="emalibre --user-data-dir=/tmp/emalibre/cache_temporal" \ +description="Estación Meteorológica Automática Libre" \ +icon="/usr/share/emalibre/gui_common/iconos/icono_app.png" diff --git a/build/conf/ConfiguracionGeneral.js b/build/conf/ConfiguracionGeneral.js new file mode 100755 index 0000000..ef66322 --- /dev/null +++ b/build/conf/ConfiguracionGeneral.js @@ -0,0 +1,28 @@ +// Configuraciones generales de EMA RECOLECTOR + +module.exports = { + "ConfGeneral": { + "Tiempo_de_Recoleccion": 40, + "UTC": -3, + "SistemaMetrico": "SI", + "debug": 3, + "debugTamanio": 10, + "NombreEstacion": "-", + "Modo": "Recolector", + "Llave_R": "e5303ab3-2a8b-4d42-90ab-1c8367d8521d", + "inicio_automatico": false, + "Audio": true, + "notificar_cambios": true, + "audioVoces": "Spanish_(Latin_America) espeak-ng" + }, + "ConfEmail": { + "ActivarCorreos": false, + "ReceptorEmail": "-", + "Servicio": "Deshabilitado", + "Usuario": "", + "Password": "", + "Server": "", + "Puerto": "" + }, + "ConfPublicador": [] +}; \ No newline at end of file diff --git a/build/controlDeb/control_arm_console b/build/controlDeb/control_arm_console new file mode 100644 index 0000000..cf774b5 --- /dev/null +++ b/build/controlDeb/control_arm_console @@ -0,0 +1,15 @@ +Package: emalibre-console +Architecture: armhf +Version: 1.30 +Priority: optional +Section: application +Maintainer: Laboratorio de Investigacion Gugler +Homepage: https://ema.gugler.com.ar +Depends: +Conflicts: emalibre-gui, emalibre-web +Description: EMA Libre Cliente (Carpincho) - Software Libre en modo consola para Estaciones Meteorológica Automáticas. + EMA Libre es Libre y Gratuito desarrollado por el Laboratorio de Investigación Gugler + perteneciente a la Facultad de Ciencia y Tecnología de la Universidad + Autónoma de Entre Ríos, con el objetivo de recolectar, registrar y publicar + información meteorológica a través de los diferentes sensores de una estación USB compatible + (ej: ws1080, wh3101, wh3104 y otras). diff --git a/build/controlDeb/control_arm_gui b/build/controlDeb/control_arm_gui new file mode 100644 index 0000000..b456229 --- /dev/null +++ b/build/controlDeb/control_arm_gui @@ -0,0 +1,15 @@ +Package: emalibre-gui +Architecture: armhf +Version: 1.30 +Priority: optional +Section: application +Maintainer: Laboratorio de Investigacion Gugler +Homepage: https://ema.gugler.com.ar +Depends: +Conflicts: emalibre-console, emalibre-web +Description: EMA Libre Cliente (Carpincho) - Software Libre en modo GUI (desktop) para Estaciones Meteorológica Automáticas. + EMA Libre es Libre y Gratuito desarrollado por el Laboratorio de Investigación Gugler + perteneciente a la Facultad de Ciencia y Tecnología de la Universidad + Autónoma de Entre Ríos, con el objetivo de recolectar, registrar y publicar + información meteorológica a través de los diferentes sensores de una estación USB compatible + (ej: ws1080, wh3101, wh3104 y otras). diff --git a/build/controlDeb/control_arm_web b/build/controlDeb/control_arm_web new file mode 100644 index 0000000..0186a21 --- /dev/null +++ b/build/controlDeb/control_arm_web @@ -0,0 +1,15 @@ +Package: emalibre-web +Architecture: armhf +Version: 1.30 +Priority: optional +Section: application +Maintainer: Laboratorio de Investigacion Gugler +Homepage: https://ema.gugler.com.ar +Depends: +Conflicts: emalibre-gui, emalibre-console +Description: EMA Libre Cliente (Carpincho) - Software Libre en modo web y consola para Estaciones Meteorológica Automáticas. + EMA Libre es Libre y Gratuito desarrollado por el Laboratorio de Investigación Gugler + perteneciente a la Facultad de Ciencia y Tecnología de la Universidad + Autónoma de Entre Ríos, con el objetivo de recolectar, registrar y publicar + información meteorológica a través de los diferentes sensores de una estación USB compatible + (ej: ws1080, wh3101, wh3104 y otras). diff --git a/build/controlDeb/control_linux_console b/build/controlDeb/control_linux_console new file mode 100644 index 0000000..6f5fa84 --- /dev/null +++ b/build/controlDeb/control_linux_console @@ -0,0 +1,15 @@ +Package: emalibre-console +Architecture: amd64 +Version: 1.30 +Priority: optional +Section: application +Maintainer: Laboratorio de Investigacion Gugler +Homepage: https://ema.gugler.com.ar +Depends: +Conflicts: emalibre-gui, emalibre-web +Description: EMA Libre Cliente (Carpincho) - Software Libre en modo consola para Estaciones Meteorológica Automáticas. + EMA Libre es Libre y Gratuito desarrollado por el Laboratorio de Investigación Gugler + perteneciente a la Facultad de Ciencia y Tecnología de la Universidad + Autónoma de Entre Ríos, con el objetivo de recolectar, registrar y publicar + información meteorológica a través de los diferentes sensores de una estación USB compatible + (ej: ws1080, wh3101, wh3104 y otras). diff --git a/build/controlDeb/control_linux_gui b/build/controlDeb/control_linux_gui new file mode 100644 index 0000000..4d18136 --- /dev/null +++ b/build/controlDeb/control_linux_gui @@ -0,0 +1,15 @@ +Package: emalibre-gui +Architecture: amd64 +Version: 1.30 +Priority: optional +Section: application +Maintainer: Laboratorio de Investigacion Gugler +Homepage: https://ema.gugler.com.ar +Depends: +Conflicts: emalibre-console, emalibre-web +Description: EMA Libre Cliente (Carpincho) - Software Libre en modo GUI (desktop) para Estaciones Meteorológica Automáticas. + EMA Libre es Libre y Gratuito desarrollado por el Laboratorio de Investigación Gugler + perteneciente a la Facultad de Ciencia y Tecnología de la Universidad + Autónoma de Entre Ríos, con el objetivo de recolectar, registrar y publicar + información meteorológica a través de los diferentes sensores de una estación USB compatible + (ej: ws1080, wh3101, wh3104 y otras). diff --git a/build/controlDeb/control_linux_web b/build/controlDeb/control_linux_web new file mode 100644 index 0000000..15127b9 --- /dev/null +++ b/build/controlDeb/control_linux_web @@ -0,0 +1,15 @@ +Package: emalibre-web +Architecture: amd64 +Version: 1.30 +Priority: optional +Section: application +Maintainer: Laboratorio de Investigacion Gugler +Homepage: https://ema.gugler.com.ar +Depends: +Conflicts: emalibre-gui, emalibre-console +Description: EMA Libre Cliente (Carpincho) - Software Libre en modo web y consola para Estaciones Meteorológica Automáticas. + EMA Libre es Libre y Gratuito desarrollado por el Laboratorio de Investigación Gugler + perteneciente a la Facultad de Ciencia y Tecnología de la Universidad + Autónoma de Entre Ríos, con el objetivo de recolectar, registrar y publicar + información meteorológica a través de los diferentes sensores de una estación USB compatible + (ej: ws1080, wh3101, wh3104 y otras). diff --git a/build/debs/readme.md b/build/debs/readme.md new file mode 100644 index 0000000..954a085 --- /dev/null +++ b/build/debs/readme.md @@ -0,0 +1 @@ +En este directorio quedan los debs, al compilar diff --git a/build/tmp/readme.md b/build/tmp/readme.md new file mode 100644 index 0000000..dbc12ce --- /dev/null +++ b/build/tmp/readme.md @@ -0,0 +1 @@ +Directorio temporal para la compilacion. diff --git a/emalibre b/emalibre new file mode 120000 index 0000000..6fd1a70 --- /dev/null +++ b/emalibre @@ -0,0 +1 @@ +../share/emalibre/emalibre \ No newline at end of file diff --git a/empaquetarArm.js b/empaquetarArm.js new file mode 100644 index 0000000..b9146b8 --- /dev/null +++ b/empaquetarArm.js @@ -0,0 +1,21 @@ +// Libreria de NWBuilder +var NwBuilder = require('nw-builder'); +// Definiciones +var nw = new NwBuilder({ + appDir: './src', // COMPILADOR: Directorio de la Aplicacion + files: ['./src/**', '!./src/node_module/mocha/**', '!./src/node_module/chai/**', '!./src/package-lock.json'], // COMPILADOR: Directorio de Codigo Fuente a compilar + platforms: ['linux64'], // COMPILADOR: Plataformas Linux a compilar + version: '0.28.4', // COMPILADOR: Version del Compilador + flavor: 'normal', // opciones sdk, normal + buildDir: 'build', // COMPILADOR: Destino de la compilacion. + zip: false, // COMPILADOR: No comprimir (False) + appName: 'emalibre' // APLICACION: Nombre de la aplicacion. +}); +// Logs +nw.on('log', console.log); +// Construir +nw.build().then(function () { + console.log('Correcto!'); +}).catch(function (error) { + console.error(error); +}); diff --git a/empaquetarLinux.js b/empaquetarLinux.js new file mode 100644 index 0000000..a4170cd --- /dev/null +++ b/empaquetarLinux.js @@ -0,0 +1,22 @@ +// Libreria +var NwBuilder = require('nw-builder'); +// Definiciones +var nw = new NwBuilder({ + appDir: './src', // COMPILADOR: Directorio de la Aplicacion + files: ['./src/**', '!./src/node_module/mocha/**', '!./src/node_module/chai/**', '!./src/package-lock.json'], // COMPILADOR: Directorio de Codigo Fuente a compilar + platforms: ['linux64'], // COMPILADOR: Plataformas Linux a compilar + version: '0.94.0', // COMPILADOR: Version del Compilador + flavor: 'normal', // opciones sdk, normal + buildDir: 'build', // COMPILADOR: Destino de la compilacion. + zip: false, // COMPILADOR: No comprimir (False) + appName: 'emalibre' // APLICACION: Nombre de la aplicacion. +}); +// Logs +//nw.on('log', console.log); +nw.onLog = console.log; +// Construir +nw.build().then(function () { + console.log('Correcto!'); +}).catch(function (error) { + console.error(error); +}); diff --git a/empaquetarWindows.js b/empaquetarWindows.js new file mode 100644 index 0000000..bc613d3 --- /dev/null +++ b/empaquetarWindows.js @@ -0,0 +1,26 @@ +var NwBuilder = require('nw-builder'); +var nw = new NwBuilder({ + appDir: './build/emalibre', // COMPILADOR: Directorio de la Aplicacion + files: ['./build/emalibre/**'], // COMPILADOR: Directorio de Codigo Fuente a compilar + platforms: ['win64'], // COMPILADOR: Plataformas Windows a compilar ['win32','win64'] + version: '0.94.0', // COMPILADOR: Version del Compilador + flavor: 'normal', // opciones sdk, normal + buildDir: 'build/debs', // COMPILADOR: Destino de la compilacion. + zip: false, // COMPILADOR: No comprimir (False) + appName: 'emalibre', // APLICACION: Nombre de la aplicacion. + winIco: './build/emalibre/gui_common/iconos/icono_app.ico', // APLICACION: Icono (Solo Windows) + winVersionString: { + 'CompanyName': 'Laboratorio De Investigación Gugler', + 'FileDescription': 'Ema Libre Cliente', + 'ProductName': 'Ema Libre', + 'LegalCopyright': 'GPL v3' + } +}); + +nw.onLog = console.log; + +nw.build().then(function () { + console.log('Se termino el armado de EmaLibre Para Windows, correctamente!'); +}).catch(function (error) { + console.error(error); +}); diff --git a/generarDeb64.sh b/generarDeb64.sh new file mode 100755 index 0000000..88eb500 --- /dev/null +++ b/generarDeb64.sh @@ -0,0 +1,278 @@ +#!/bin/bash + +#PARAMETRIA +VERSION=`grep Version src/conf/ConfiguracionGlobal.js | sed -e "s/'Version': //g" | sed -e "s/,//g" | sed -e "s/^[ \t]*//"` +NWJS_VERSION='0.94.0' + +# DEPENDENCIAS +NW_GYP_INST=`npm list -g | grep nw-gyp@ | grep -v deduped | wc -l` +NW_BUILDER_INST=`npm list | grep nw-builder@ | grep -v deduped | wc -l` +node=`node -v | wc -l` +npm=`npm -v | wc -l` + +# Metodo Spinner +function spinner() { + local info="$1" + local pid=$! + local delay=0.25 + local spinstr='|/-\' + while kill -0 $pid 2> /dev/null; do + local temp=${spinstr#?} + printf " [%c] $info" "$spinstr" + local spinstr=$temp${spinstr%"$temp"} + sleep $delay + local reset="\b\b\b\b\b" + for ((i=1; i<=$(echo $info | wc -c); i++)); do + reset+="\b" + done + printf $reset + done + printf " \b\b\b\b" +} +# *********************************************************** +# EJECUCION DE CODIGO -- LIMPIA Y VERIFICA ENTORNO +# *********************************************************** +echo "" +echo "*************************************************" +echo "* Comprobando y preparando el entorno ***" +echo "*************************************************" +echo "" +printf "\033[1;4m--->Version de EmaL: $VERSION \033[0m\n" +printf "\033[1;4m--->Version de NWJs: $NWJS_VERSION \033[0m\n" +echo "" +printf "\033[1;10m1) Limpiando compilacion anterior. \033[0m" +sudo mkdir build/Deb64/usr/bin 2> /dev/null +sudo mkdir build/Deb64/usr/share/emalibre 2> /dev/null +sudo rm -fr build/emalibre/linux64 +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Instalando/comprobando paquetes con APT necesarios. \033[0m" +sudo apt-get -y -qq install build-essential git wget libusb-1.0-0 libusb-1.0-0-dev libudev-dev +sudo chmod -R 777 build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Verificando node y dependencias: \033[0m\n" +printf "\033[1;10m 3.1) Comprobando si esta node global. \033[0m" +if [ $node -eq 1 ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[1;31m --> NO. \033[0m" + printf "\033[1;32m --> Se sale, por favor instale manualmente. \033[0m\n" + exit 0 +fi +printf "\033[1;10m 3.2) Comprobando si esta npm global. \033[0m" +if [ $npm -eq 1 ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[1;31m --> NO. \033[0m" + printf "\033[1;32m --> Se sale, por favor instale manualmente. \033[0m\n" + exit 0 +fi +printf "\033[1;10m 3.3) Comprobando si esta nw-gyp como global. \033[0m" +if [ $NW_GYP_INST -eq 1 ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[1;31m --> NO. \033[0m" + npm install -g nw-gyp -no-audit -silent 2> /tmp/ema.log 1> /dev/null + printf "\033[1;32m --> Se instalo. \033[0m\n" +fi +printf "\033[1;10m 3.4) Comprobando si nw-builder localmente. \033[0m" +if [ $NW_BUILDER_INST -eq 1 ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[1;31m --> NO. \033[0m" + npm install -no-audit -silent 2> /tmp/ema.log 1> /dev/null + printf "\033[1;32m --> Se instalo. \033[0m\n" +fi +printf "\033[1;10m4) Empaquetando el proyecto emalibre. \033[0m" +CHECK_EMPAQUETADO=`node empaquetarLinux.js | grep "Correcto!" | wc -l` +if [ "${CHECK_EMPAQUETADO}" -eq "1" ]; then printf "\033[1;32m --> OK. \033[0m\n"; else printf "\033[5;91m --> ERROR. Problema empaquetando con nw-builder. \033[0m\n";exit 1; fi +printf "\033[1;10m5) Aplicando Permisos al proyecto. \033[0m" +sudo chmod -R 777 build/emalibre/linux64 & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m6) Eliminando node_modules del proyecto. \033[0m" +sudo rm -fr build/emalibre/linux64/node_modules & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m7) Generando node_modules con NPM del proyecto. \033[0m" +cd build/emalibre/linux64 +npm install ---production -no-audit -silent 2> /tmp/ema.log 1> /dev/null +printf "\033[1;32m --> OK. \033[0m\n"; +printf "\033[1;10m8) Se purgan los tanques y logs. \033[0m" +sudo echo "" > logs/debug.log +sudo echo "[]" > logs/TanquePendientes.log +sudo echo "[]" > logs/registro_diario.log +printf "\033[1;32m --> OK. \033[0m\n"; +printf "\033[1;10m9) Se blanquea el archivo de Configuracion General. \033[0m" +sudo cp ../../conf/ConfiguracionGeneral.js conf/ConfiguracionGeneral.js +printf "\033[1;32m --> OK. \033[0m\n"; +cd .. +sudo cp -R linux64 Linux64_nogui # Se copia antes del postLINUX (que implementa NWJS) para el modo consola y web +sudo chmod -R 777 Linux64_nogui +cd linux64 +npm run postLINUX -no-audit -silent 2> /tmp/ema.log 1> /dev/null & spinner "Procesando..." +CHECK_NW_NODE_BUILD=`cat /tmp/ema.log | grep "gyp info ok" | wc -l` +if [ "${CHECK_NW_NODE_BUILD}" -eq "1" ]; then printf "\033[1;32m --> OK. \033[0m\n"; else printf "\033[5;91m --> ERROR. Verifique el modulo NW con node-hid. \033[0m\n";exit 1; fi +cd ../../.. + +# ************************************************************** +# Compilar EMA Libre Cliente (Carpincho) en modo GRAFICO Desktop +# ************************************************************** +echo "" +echo "" +echo "*************************************************" +echo "* Build EMA Libre Cliente Grafico - GNU/Linux *" +echo "*************************************************" +echo "" +printf "\033[1;10m1) Limpiando archivos temporales. \033[0m" +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Copiando los fuentes de EMA Libre para 64bit. \033[0m" +sudo cp -R build/emalibre/linux64/* build/Deb64/usr/share/emalibre/ +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Remplazando el archivo de control DEB. \033[0m" +sudo cp -f build/controlDeb/control_linux_gui build/Deb64/DEBIAN/control & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m4) Aplicando permisos necesarios. \033[0m" +sudo chmod +x build/Deb64/usr/share/emalibre/emalibre +sudo chmod 0755 build/Deb64/DEBIAN +sudo chmod 0755 build/Deb64/DEBIAN/postrm +sudo chmod 0755 build/Deb64/DEBIAN/postinst +sudo chmod 0755 build/Deb64/DEBIAN/preinst +sudo chown -R root:root build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m5) Generando enlaces simbolicos del binario. \033[0m" +cd build/Deb64/usr/bin/ +sudo ln -s ../share/emalibre/emalibre emalibre +cd ../../.. +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m6) Eliminando node/web/express/forever/servicio para modo GUI y la intefaz para consola/web. \033[0m" +# se mueve el servicio desde al temporal +sudo mv Deb64/etc/init.d tmp +sudo mv Deb64/etc/emalibre_modo tmp +sudo rm -fr Deb64/usr/share/emalibre/node_modules/node +sudo rm -fr Deb64/usr/share/emalibre/node_modules/express +sudo rm -fr Deb64/usr/share/emalibre/node_modules/forever +sudo rm -fr Deb64/usr/share/emalibre/node_modules/forever-agent +sudo rm -fr Deb64/usr/share/emalibre/node_modules/forever-monitor +sudo rm -fr Deb64/usr/share/emalibre/gui_web +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m7) Generando Paquete Deb para GUI 64bit Linux. \033[0m\n" +sudo dpkg -b Deb64 debs/"emalibre-gui-linux_$VERSION.deb" +# se vuelve el servicio desde el temporal +sudo mv tmp/init.d Deb64/etc +sudo mv tmp/emalibre_modo Deb64/etc/emalibre_modo +printf "\033[5;10m Finalizo con exito, build/debs/emalibre-gui-linux_$VERSION.deb. \033[0m" +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m8) Limpiando archivos temporales. \033[0m" +cd .. +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" + +# *********************************************************** +# Compilar EMA Libre Cliente (Carpincho) en modo CONSOLA +# *********************************************************** +echo "" +echo "" +echo "*************************************************" +echo "* Build EMA Libre Cliente Consola - GNU/Linux *" +echo "*************************************************" +echo "" +printf "\033[1;10m1) Limpiando archivos temporales. \033[0m" +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Copiando los fuentes de EMA Libre para 64bit. \033[0m" +sudo cp -R build/emalibre/Linux64_nogui/core build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/logs build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/conf build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/tmp build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/node_modules build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/CHANGELOG build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/COPYING build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/AUTHORS build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/package.json build/Deb64/usr/share/emalibre/ +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Remplazando el archivo de control DEB. \033[0m" +sudo cp -f build/controlDeb/control_linux_console build/Deb64/DEBIAN/control & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m4) Aplicando permisos necesarios. \033[0m" +sudo chmod 0755 build/Deb64/DEBIAN +sudo chmod 0755 build/Deb64/DEBIAN/postrm +sudo chmod 0755 build/Deb64/DEBIAN/postinst +sudo chmod 0755 build/Deb64/DEBIAN/preinst +sudo chown -R root:root build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +cd build +printf "\033[1;10m7) Generando Paquete Deb para Consola 64bit Linux. \033[0m\n" +sudo dpkg -b Deb64 debs/"emalibre-consola-linux_$VERSION.deb" +printf "\033[5;10m Finalizo con exito, build/debs/emalibre-console-linux_$VERSION.deb. \033[0m" +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m8) Limpiando archivos temporales. \033[0m" +cd .. +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +echo "" + +# *********************************************************** +# Compilar EMA Libre Cliente (Carpincho) en modo CONSOLA/WEB +# *********************************************************** +echo "" +echo "" +echo "*************************************************" +echo "* Build EMA Libre Cliente Web - GNU/Linux *" +echo "*************************************************" +echo "" +printf "\033[1;10m1) Limpiando archivos temporales. \033[0m" +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Copiando los fuentes de EMA Libre para 64bit. \033[0m" +sudo cp -R build/emalibre/Linux64_nogui/core build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/logs build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/conf build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/gui_web build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/gui_common build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/tmp build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/node_modules build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/CHANGELOG build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/COPYING build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/AUTHORS build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/Linux64_nogui/package.json build/Deb64/usr/share/emalibre/ +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Remplazando el archivo de control DEB. \033[0m" +sudo cp -f build/controlDeb/control_linux_web build/Deb64/DEBIAN/control & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m4) Aplicando permisos necesarios. \033[0m" +sudo echo "web" > build/Deb64/etc/emalibre_modo +sudo chmod 0755 build/Deb64/DEBIAN +sudo chmod 0755 build/Deb64/DEBIAN/postrm +sudo chmod 0755 build/Deb64/DEBIAN/postinst +sudo chmod 0755 build/Deb64/DEBIAN/preinst +sudo chown -R root:root build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +cd build +printf "\033[1;10m7) Generando Paquete Deb para Web 64bit Linux. \033[0m\n" +sudo dpkg -b Deb64 debs/"emalibre-web-linux_$VERSION.deb" +printf "\033[5;10m Finalizo con exito, build/debs/emalibre-console-linux_$VERSION.deb. \033[0m" +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m8) Limpiando archivos temporales. \033[0m" +cd .. +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +sudo rm -fr build/emalibre +printf "\033[1;32m --> OK. \033[0m\n" +echo "" + diff --git a/generarDebArm.sh b/generarDebArm.sh new file mode 100755 index 0000000..f9140f4 --- /dev/null +++ b/generarDebArm.sh @@ -0,0 +1,308 @@ +#!/bin/bash + +#PARAMETRIA +VERSION=`grep Version src/conf/ConfiguracionGlobal.js | sed -e "s/'Version': //g" | sed -e "s/,//g" | sed -e "s/^[ \t]*//"` +NWJS_VERSION='0.28.4' # Es la ultima compilada para ARM, siempre mirar la url https://github.com/LeonardLaszlo/nw.js-armv7-binaries/releases +#NWJS_ARM='https://github.com/LeonardLaszlo/nw.js-armv7-binaries/releases/download/v' Se comenta se copio el tar al server de gugler por velocidad- +NODE_CONSOLE='https://nodejs.org/dist/v14.4.0/node-v14.14.0-linux-armv7l.tar.xz' # Version node, siempre mirar la url +NODE_NOMBRE='node-v14.14.0-linux-armv7l' +DESCARGA_NWJS='https://nube.gugler.com.ar/index.php/s/iznYtBE7aBtXYdN/download' #server de gugler nwjs 28.4 + +# DEPENDENCIAS +NW_GYP_INST=`npm list -g | grep nw-gyp@ | wc -l` +NW_BUILDER_INST=`npm list | grep nw-builder@ | wc -l` +node=`node -v | wc -l` +npm=`npm -v | wc -l` + +# Metodo Spinner +function spinner() { + local info="$1" + local pid=$! + local delay=0.25 + local spinstr='|/-\' + while kill -0 $pid 2> /dev/null; do + local temp=${spinstr#?} + printf " [%c] $info" "$spinstr" + local spinstr=$temp${spinstr%"$temp"} + sleep $delay + local reset="\b\b\b\b\b" + for ((i=1; i<=$(echo $info | wc -c); i++)); do + reset+="\b" + done + printf $reset + done + printf " \b\b\b\b" +} + +# *********************************************************** +# EJECUCION DE CODIGO -- LIMPIA Y VERIFICA ENTORNO +# *********************************************************** + +echo "" +echo "*************************************************" +echo "* Comprobando y preparando el entorno ***" +echo "*************************************************" +echo "" +printf "\033[1;4m--->Versión de EMAl: $VERSION \033[0m\n" +printf "\033[1;4m--->Versión de NWJs: $NWJS_VERSION \033[0m\n" +echo "" +printf "\033[1;10m1) Limpiando compilación anterior. \033[0m" +sudo mkdir build/Deb64/usr/bin 2> /dev/null +sudo mkdir build/Deb64/usr/share/emalibre 2> /dev/null +sudo rm -fr build/emalibre +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Instalando/comprobando paquetes necesarios con APT. \033[0m" +sudo apt-get -y -qq install build-essential git wget libusb-1.0-0 libusb-1.0-0-dev libudev-dev wget +sudo chmod -R 777 build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Verificando node y dependencias: \033[0m\n" +printf "\033[1;10m 3.1) Comprobando NWJS descargado en cache para arm. \033[0m" +if [ -d "cache/$NWJS_VERSION-normal" ]; then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[5;91m --> NO. \033[0m" + printf "\033[1;10m -> Se descarga de NWJS. \033[0m\n" + mkdir -p "cache/$NWJS_VERSION-normal" + cd "cache/$NWJS_VERSION-normal" + wget $DESCARGA_NWJS -O nwjs.tar.xz -q --show-progress + tar -xf nwjs.tar.xz + rm -fr nwjs.tar.xz + mv nwjs-v${NWJS_VERSION}-linux-arm linux64 + rm -fr nwjs-v${NWJS_VERSION}-linux-arm + cd ../.. + printf "\033[1;32m --> OK. \033[0m\n" +fi +printf "\033[1;10m 3.2) Comprobando si esta node global. \033[0m" +if [ $node = "1" ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[5;91m --> NO. \033[0m" + printf "\033[1;32m --> Se sale, por favor instale manualmente. \033[0m\n" + exit 0 +fi +printf "\033[1;10m 3.3) Comprobando si esta npm global. \033[0m" +if [ $npm = "1" ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[5;91m --> NO. \033[0m" + printf "\033[1;32m --> Se sale, por favor instale manualmente. \033[0m\n" + exit 0 +fi +printf "\033[1;10m 3.4) Comprobando si esta nw-gyp como global. \033[0m" +if [ $NW_GYP_INST = "1" ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[5;91m --> NO. \033[0m" + npm install -g nw-gyp -no-audit -silent 2> /tmp/ema.log 1> /dev/null + printf "\033[1;32m --> Se instalo. \033[0m\n" +fi +printf "\033[1;10m 3.5) Comprobando si nw-builder localmente. \033[0m" +if [ $NW_BUILDER_INST = "1" ] +then + printf "\033[1;32m --> OK. \033[0m\n" + else + printf "\033[5;91m --> NO. \033[0m" + npm install -no-audit -silent 2> /tmp/ema.log 1> /dev/null + printf "\033[1;32m --> Se instalo. \033[0m\n" +fi +printf "\033[1;10m4) Empaquetando el proyecto. \033[0m" +CHECK_EMPAQUETADO=`node empaquetarArm.js | grep "Correcto!" | wc -l` +if [ "${CHECK_EMPAQUETADO}" -eq "1" ]; then printf "\033[1;32m --> OK. \033[0m\n"; else printf "\033[5;91m --> ERROR. Problema empaquetando con nw-builder. \033[0m\n";exit 1; fi +sudo mv build/emalibre/linux64 build/emalibre/arm +printf "\033[1;10m5) Aplicando permisos al proyecto. \033[0m" +sudo chmod -R 777 build/emalibre/arm & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m6) Eliminando node_modules. \033[0m" +sudo rm -fr build/emalibre/arm/node_modules & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m7) Generando node_modules con NPM. \033[0m" +cd build/emalibre/arm +npm install forever express node-hid nodemailer targz terminal-kit bootstrap bootstrap-select datatables datatables-buttons jquery notify-js-lib nprogress popper.js chart.js --production 2> /tmp/ema.log 1> /dev/null & spinner "Procesando..." +printf "\033[1;32m \033[0m\n" +printf "\033[1;10m8)Descargando la version de NWJS para ARM: \033[0m\n" +wget $NODE_CONSOLE -O node -q --show-progress +tar xf node +rm -f node +rm -f *.tar.xz +mv $NODE_NOMBRE node_modules/node +cp -R node_modules/node-hid ../ +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m 8.1) Corriendo postscript particular para ARM y NW.js. \033[0m" +npm run postARM 2> /tmp/ema.log 1> /dev/null & spinner "Procesando..." +CHECK_NW_NODE_BUILD=`cat /tmp/ema.log | grep "gyp info ok" | wc -l` +if [ "${CHECK_NW_NODE_BUILD}" -eq "1" ]; then printf "\033[1;32m --> OK. \033[0m\n"; else printf "\033[5;91m --> ERROR. Verifique el modulo NW con node-hid. \033[0m\n";exit 1; fi +printf "\033[1;10m9) Se purgan los tanques y logs. \033[0m" +sudo echo "" > logs/debug.log +sudo echo "[]" > logs/TanquePendientes.log +sudo echo "[]" > logs/registro_diario.log +printf "\033[1;32m --> OK. \033[0m\n"; +printf "\033[1;10m 9.1) Se blanque el archivo de Configuracion General. \033[0m" +sudo cp ../../conf/ConfiguracionGeneral.js conf/ConfiguracionGeneral.js +cd ../../.. +printf "\033[1;32m --> OK. \033[0m\n"; + +# ************************************************************** +# Compilar EMA Libre Cliente (Carpincho) en modo GRAFICO Desktop +# ************************************************************** +echo "" +echo "" +echo "*************************************************" +echo "* Build EMA Libre Cliente Grafico - ARM *" +echo "*************************************************" +echo "" +printf "\033[1;10m1) Limpiando archivos temporales. \033[0m" +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Copiando los fuentes de EMA Libre para 64bit. \033[0m" +sudo cp -R build/emalibre/arm/* build/Deb64/usr/share/emalibre/ +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Remplazando el archivo de control DEB. \033[0m" +sudo cp -f build/controlDeb/control_arm_gui build/Deb64/DEBIAN/control & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m4) Aplicando permisos necesarios. \033[0m" +sudo chmod +x build/Deb64/usr/share/emalibre/emalibre +sudo chmod 0755 build/Deb64/DEBIAN +sudo chmod 0755 build/Deb64/DEBIAN/postrm +sudo chmod 0755 build/Deb64/DEBIAN/postinst +sudo chmod 0755 build/Deb64/DEBIAN/preinst +sudo chown -R root:root build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m5) Generando enlaces simbolicos del binario. \033[0m" +cd build/Deb64/usr/bin/ +sudo ln -s ../share/emalibre/emalibre emalibre +cd ../../.. +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m6) Eliminando node para modo GUI y la intefaz para consola/web. \033[0m" +# se mueve el servicio desde al temporal +sudo mv Deb64/etc/init.d tmp +sudo mv Deb64/etc/emalibre_modo tmp +sudo rm -fr Deb64/usr/share/emalibre/node_modules/node +sudo rm -fr Deb64/usr/share/emalibre/node_modules/express +sudo rm -fr Deb64/usr/share/emalibre/gui_web +sudo rm -fr Deb64/usr/share/emalibre/node_modules/forever +sudo rm -fr Deb64/usr/share/emalibre/node_modules/forever-agent +sudo rm -fr Deb64/usr/share/emalibre/node_modules/forever-monitor +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m7) Generando Paquete Deb para GUI ARM. \033[0m\n" +sudo dpkg -b Deb64 debs/"emalibre-gui-arm_$VERSION.deb" +# se vuelve el servicio desde el temporal +sudo mv tmp/init.d Deb64/etc +sudo mv tmp/emalibre_modo Deb64/etc/emalibre_modo +printf "\033[5;10m Finalizo con exito, build/debs/emalibre-gui-arm_$VERSION.deb. \033[0m" +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m8) Limpiando archivos temporales. \033[0m" +cd .. +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" + +# *********************************************************** +# Compilar EMA Libre Cliente (Carpincho) en modo CONSOLA +# *********************************************************** +echo "" +echo "" +echo "*************************************************" +echo "* Build EMA Libre Cliente Consola - ARM *" +echo "*************************************************" +echo "" +printf "\033[1;10m1) Limpiando archivos temporales. \033[0m" +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Copiando los fuentes de EMA Libre para ARM. \033[0m" +sudo cp -R build/emalibre/arm/core build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/logs build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/conf build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/tmp build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/node_modules build/Deb64/usr/share/emalibre/ +sudo rm -fr build/Deb64/usr/share/emalibre/node_modules/node-hid +sudo cp -R build/emalibre/node-hid build/Deb64/usr/share/emalibre/node_modules +sudo cp -R build/emalibre/arm/CHANGELOG build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/COPYING build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/AUTHORS build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/package.json build/Deb64/usr/share/emalibre/ +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Remplazando el archivo de control DEB. \033[0m" +sudo cp -f build/controlDeb/control_arm_console build/Deb64/DEBIAN/control & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m4) Aplicando permisos necesarios. \033[0m" +sudo chmod 0755 build/Deb64/DEBIAN +sudo chmod 0755 build/Deb64/DEBIAN/postrm +sudo chmod 0755 build/Deb64/DEBIAN/postinst +sudo chmod 0755 build/Deb64/DEBIAN/preinst +sudo chown -R root:root build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +cd build +printf "\033[1;10m7) Generando Paquete Deb para Consola ARM. \033[0m\n" +sudo dpkg -b Deb64 debs/"emalibre-consola-arm_$VERSION.deb" +printf "\033[5;10m Finalizo con exito, build/debs/emalibre-console-arm_$VERSION.deb. \033[0m" +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m8) Limpiando archivos temporales. \033[0m" +cd .. +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +echo "" + +# *********************************************************** +# Compilar EMA Libre Cliente (Carpincho) en modo CONSOLA/WEB +# *********************************************************** +echo "" +echo "" +echo "*************************************************" +echo "* Build EMA Libre Cliente Web - ARM *" +echo "*************************************************" +echo "" +printf "\033[1;10m1) Limpiando archivos temporales. \033[0m" +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m2) Copiando los fuentes de EMA Libre para ARM. \033[0m" +sudo cp -R build/emalibre/arm/core build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/logs build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/conf build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/gui_web build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/gui_common build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/tmp build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/node_modules build/Deb64/usr/share/emalibre/ +sudo rm -fr build/Deb64/usr/share/emalibre/node_modules/node-hid +sudo cp -R build/emalibre/node-hid build/Deb64/usr/share/emalibre/node_modules +sudo cp -R build/emalibre/arm/CHANGELOG build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/COPYING build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/AUTHORS build/Deb64/usr/share/emalibre/ +sudo cp -R build/emalibre/arm/package.json build/Deb64/usr/share/emalibre/ +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m3) Remplazando el archivo de control DEB. \033[0m" +sudo cp -f build/controlDeb/control_arm_web build/Deb64/DEBIAN/control & spinner "Procesando..." +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m4) Aplicando permisos necesarios. \033[0m" +sudo chmod 0755 build/Deb64/DEBIAN +sudo chmod 0755 build/Deb64/DEBIAN/postrm +sudo chmod 0755 build/Deb64/DEBIAN/postinst +sudo chmod 0755 build/Deb64/DEBIAN/preinst +sudo chown -R root:root build/Deb64 +printf "\033[1;32m --> OK. \033[0m\n" +cd build +printf "\033[1;10m7) Generando Paquete Deb para WEB en ARM. \033[0m\n" +sudo dpkg -b Deb64 debs/"emalibre-web-arm_$VERSION.deb" +printf "\033[5;10m Finalizo con exito, build/debs/emalibre-web-arm_$VERSION.deb. \033[0m" +printf "\033[1;32m --> OK. \033[0m\n" +printf "\033[1;10m8) Limpiando archivos temporales. \033[0m" +cd .. +sudo rm -f build/Deb64/DEBIAN/control +sudo rm -fr build/Deb64/usr/bin/* +sudo rm -fr build/Deb64/usr/share/emalibre/* +sudo rm -fr build/emalibre +printf "\033[1;32m --> OK. \033[0m\n" +echo "" diff --git a/generarWin.bat b/generarWin.bat new file mode 100644 index 0000000..61873a1 --- /dev/null +++ b/generarWin.bat @@ -0,0 +1,50 @@ +@echo off +cls +echo. +echo //------------------------------------------------// +echo // Preparando entorno para M. Windows +echo // -----------------------------------------------// +echo // Importante verifique las dependencias: +echo // * python 2.7.* +echo // * node v15.12.0 +echo // * nw-gyp (global en node) +echo //------------------------------------------------// +echo. +echo 1) Limpiando temporales ... +rd /S /Q build\emalibre > nul +echo. +echo 2) Copiando codigo Fuente para EMA Libre GUI (Desktop) Windows. +xcopy src build\emalibre /s /I /Y /Q +echo. +echo 3) Copiando archivo de configuracion por default +xcopy build\conf\ConfiguracionGeneral.js build\emalibre\conf /s /I /Y /Q +echo. +echo 3) Quitando archivos y depurando tanques. +rd /S /Q build\emalibre\node_modules > nul +rd /S /Q build\emalibre\gui_web > nul +del /f build\emalibre\package-lock.json > nul +echo "" > build/emalibre/logs/debug.log +echo "[]" > build/emalibre/logs/TanquePendientes.log +echo "[]" > build/emalibre/logs/registro_diario.log +echo. +echo 4) Generando el node modules +cd build\emalibre +call npm install -silent node-hid nodemailer targz bootstrap bootstrap-select datatables datatables-buttons jquery notify-js-lib nprogress popper.js > nul +echo. +echo 5) Regenerando el modulo node-hid adaptandolo a NW.js. +call npm run postWIN -no-audit -silent > nul +cd .. +cd .. +echo 5) Empaquetando el EMA Libre Cliente. +node empaquetarWindows.js +echo. +echo 6) Limpiando temporales ... +rd /S /Q build\emalibre > nul +rmdir /Q build\emalibre > nul +cls +echo EMA Libre Cliente (Carpincho) Windows +echo --------------------------------------------- +echo 7) Termino el empaquetado, y esta listo para ejecutarse en: +echo Directorio Destino: build\debs\win32 +pause +exit \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..d10ed88 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "main": "CompilarEmaLibreWindows.js", + "name": "emalibre", + "description": "EMA Compilador", + "version": "1.35.0", + "window": { + "frame": false, + "toolbar": false + }, + "keywords": [ + "CompiladorEMA", + "EMACompiler" + ], + "licenses": [ + { + "type": "GPLv3", + "url": "https://www.gnu.org/licenses/gpl-3.0.html" + } + ], + "scripts": { + "test": "mocha --exit|| true", + "global": "npm i -g nw-gyp nw@0.94.0-sdk", + "nw_rebuild_linux": "nw-gyp rebuild --target=0.94.0 --verbose --arch=x64 --directory=src/node_modules/node-hid", + "nw_rebuild_windows": "nw-gyp rebuild --target=0.94.0 --verbose --arch=x64 --directory=src/node_modules/node-hid", + "nw_rebuild_arm": "nw-gyp rebuild --target=0.28.4 --verbose --arch=arm --directory=src/node_modules/node-hid" + }, + "devDependencies": { + "chai": "^4.3.4", + "mocha": "^8.3.2", + "nw-builder": "^3.5.7" + } +} diff --git a/src/AUTHORS b/src/AUTHORS new file mode 100644 index 0000000..0dc179a --- /dev/null +++ b/src/AUTHORS @@ -0,0 +1,23 @@ +EMA Libre Cliente nace en el 2018 de la formulación de un proyecto de Investigación +denominado proyecto EMA Libre, este software es parte de un conjunto de tres sistema: +EMA Libre Cliente (Capincho), EMA Libre Center (Capibara) y EMA Liber Visor (Ronsoco). + +Desarrollado por el Laboratorio de Investigación Gugler perteneciente a la Facultad +de Ciencia y Tecnología de la Universidad Autónoma de Entre Ríos. A continuación +se detalla la lista de colaboradores y desarrolladores: + + Exequiel Aramburu . + José Luis Mengarelli . + Federico Bonnet . + Alexis Sostersich . + Marcos Elias Rios Nuñez . + +Se agradece a la Facultad de Ciencia y Tecnología de la Universidad Autónoma de Entre Ríos +por permitir la conformación de este equipo interdisciplinario de profesionales y alumnos +colaboradores. Para llevar acabo una investigación de esta magnitud, permitiendo mostrar +las cualidades y bondades del Software Libre. + +Finalmente, no se solicito declaración de renuncia de copyright a la facultad, ya que por Medio +de la Resolución CS Nº 063/18, el Consejo Directivo de la Facultad de Ciencia y Tecnología +de la Universidad Autónoma de Entre Ríos, aprueba el proyecto Investigación, el cual especifica +que el software utilizara una licencia libre. diff --git a/src/CHANGELOG b/src/CHANGELOG new file mode 100644 index 0000000..b2e6c3f --- /dev/null +++ b/src/CHANGELOG @@ -0,0 +1,251 @@ +** Versión 1.35: (Diciembre 10 , 2024) + + Se actualizó la versión de nwjs → 0.94.0 + + Se actualizó la versión de node → 22.07.0. + + Se actualizó la versión de RGraph -> 6.20. + + Se actualizó la versión de bootstrap → 4.6.2 + + Mejoras menores de estilo. + +** Versión 1.34: (Marzo 20 , 2021) + + Se actualizó la versión de nwjs → 0.52.0 + + Se actualizó la versión de node → 15.12.0 + + Se actualizó la versión de jquery ^3.5.1 → ^3.6.0 + + Se actualizó la versión de nodemailer ^6.4.17 → ^6.5.0 + + Se actualizó la versión de terminal-kit ^1.47.0 → ^2.0.6 + + Se actualizó la versión de chai ^4.2.0 → ^4.3.4 + + Se actualizó la versión de mocha ^8.2.0 → ^8.3.2 + + Se mejora color y mensajes del compilador. + + +** Versión 1.29: (Octubre 18, 2020) ++ Se actualizó la versión de nwjs -> 0.49.0. ++ Se actualizó la versión de node -> 14.14.0 en modo consola. ++ Se actualizó la versión de node-hid -> 1.3.1. ++ Se actualizó la versión de chart.js ^2.9.3 → ^2.9.4. ++ Se actualizó la versión de forever ^3.0.0 → ^3.0.2. ++ Se actualizó la versión de jquery ^3.4.1 → ^3.5.1. ++ Se actualizó la versión de nodemailer ^6.4.10 → ^6.4.14. ++ Se actualizó la versión de terminal-kit ^1.35.2 → ^1.44.0. ++ Se actualizó la versión de bootstrap ^4.5.0. → ^4.5.3. ++ Se arregla ruta del icono del menu. + +** Versión 1.28: (Junio 28, 2020) ++ Se actualizó la versión de nwjs -> 0.46.3. ++ Se actualizó la versión de node -> 14.4.0 en modo consola. ++ Se actualizó la versión de nodemailer -> 6.4.10. ++ Se actualizó la versión de node-hid -> 1.3.0. ++ Se actualizó la versión de bootstrap -> 4.5.0. ++ Se actualizó la versión de bootstrap-select -> 1.13.18. ++ Se actualizó la versión de forever -> 3.0.0. ++ Se actualizó la versión de RGraph -> 5.24. + +** Versión 1.27: (Marzo 21, 2020) + ++ Se incorporó la red AWEKAS(https://www.awekas.at/) para su publicación. + -Usuario/ID: el ID de la estación (no utilizar el usuario). + -Password: Su password de AWEKAS. ++ Se incorporó la red WINDY(https://stations.windy.com/) para su publicación. + -Usuario/ID: es la API KEY del usuario. + -Password: Es numero de estaciones dada de alta en windy(ej: la primera->0, la segunda->1, la X->X). ++ Se actualizó la versión de nwjs 0.44.5. ++ Se actualizó al nuevo sistema de ventanas de nw llamado nw2 (quitando -disable-features=nw2 del package.json) ++ Se actualizó la versión de node-hid a la 1.2.0. ++ Se actualizó la versión de nodemailer a la 6.4.4. ++ Se actualizó la versión de forever a la 2.0.0. ++ Se actualizó node a la versión 13.11.1 en modo consola. ++ Se actualizó la versión de terminal-kit a la 1.34.3. ++ Se actualizó la versión de RGraph a la 5.22. ++ Se remplazó el método deprecado res.sendfile() por res.sendFile(). ++ Se incorporo como paquetes de npm a:Charjs, Bootstrap, bootstrap-select, Notify, jquery, datatable, + nprogress y popper. De esta forma se eliminando espacio del proyecto en el repositorio git, + quitandolo como librería en el directrio gui y gui-web. ++ Se crea el directorio gui_common, que contiene librerías, imágenes,css y otros, en común, entre el desktop y el web. + Se reduce el tamaño del proyecto. ++ Se modifico los compiladores para eliminar la cache de ARM, ahora lo descarga al compilar (no esta en el proyecto). ++ Fix: Se arregla un error en el menú linux de permisos. ++ Fix: Servicio de monitor -> se modificó el tiempo a 10 minutos el primer control. ++ Fix: En el paquete de modo-web se setea por defecto el modo web. ++ Fix: En el modo web se arregla el estado del usb. ++ Fix: En los compiladores se verifica si esta instalado global node,npm y nw-gyp. ++ Fix: modo visor en web, ahora funciona. + +** Versión 1.26: (Diciembre 1, 2019) + ++ Se modifica la publicación de redes el parámetro intensidad de luz, modificando la medida. ++ Se actualizó node a la versión 13.2.0 en modo consola. ++ Se actualizó la versión de nwjs 0.42.6. ++ Se actualizó la versión de RGraph a la 5.11 ++ Se actualizó la versión de Charjs a la 2.9 ++ Se actualizó la versión de node-hid a la 1.0.0 ++ Se actualizó a Datatable v1.10.20 + +** Versión 1.25: (Octubre 26, 2019) + ++ Se incorpora el servicio de monitor, el cual reinicia el equipo, si no detecta registros. + Este solo se permite habilitar, si se encuentra establecido el inicio automático en true. + Por defecto: + * Umbral = 10 minutos -> Si supera este umbral reinicia. + * Control = 3 minutos -> Cada cuánto controla. + ++ Se actualizó node a la versión 12.11.1 en modo consola. + +** Versión 1.24: (Septiembre 26, 2019) + ++ Se incorpora el servicio con los parámetros: + {start|stop|status|restart|set-web|set-consola|set-inicio-enabled|set-inicio-disable|view-conf|report}. ++ Se incorpora el inicio automático, dentro del servicio. ++ Se arregla el almacenado y visualización del Tamaño del log. ++ Se baja el tamaño del log por defecto a 10MB. ++ Se arregla el visor adaptado a la modificación de la API de EMA Center. ++ Se actualizó la versión de nwjs 0.41.2. ++ Se actualizó la versión de node-hid a la 0.7.9 ++ Se actualizó node a la versión 12.10.0 en modo consola. ++ Se actualizó la versión de RGraph a la 5.1. + + +** Versión 1.23: (Agosto 7, 2019) + ++ Se modifica el modo consola, migrando de bash a node consola(terminal-kit). ++ Se incorpora el carpincho web, puerto 8080 (por defecto). ++ Se incorpora un menu de Estadisticas y graficos históricos múltiples (charjs). ++ Se incorpora que carpincho informe los cambios climáticos. ++ Se incorpora la configuración para activar o desactivar los cambios climáticos. ++ Se incorpora tamaño máximo del archivo de debug antes de depurar + y la configuración del mismo (por defecto 100 MB). ++ Se actualizó la versión de nwjs 0.40.0. ++ Se cambia la barra de progreso por alto consumo de CPU a una barra más performance. ++ Se acomoda un bug en el menú de configuración. ++ Se adecua la estructura de directorios. ++ Se incorporan test básicos, con mocha y chai. ++ Se mejora el empaquetador y compilador. ++ Se incorpora node como dependencia para el modo consola. ++ Las imágenes se migraron al formato webp(se modificaron algunas imagenes). ++ Se modificaron dos imágenes de fondo. ++ Se modificaron textos en general. ++ Se arregla el reload en registros de logs. ++ Se arregla el tamaño inicial de la ventana. ++ Mejora general en el código, incorporando algunas promesas. + + +** Versión 1.22: (Mayo 7, 2019) + ++ Mejora general en el código y las excepciones dentro de ema.js. ++ Se mejora el cargador de inicio. ++ Se mejora el performance, eliminando cpu y mem info. ++ Se agrega la opción de zoom in y zoom out. ++ Mejora en el Deb de Linux y arm, ahora en una actualización mantiene el archivo de configuración personal, en windows ya lo hacía. ++ Adecuaciones al archivo preinst y postinst en modo consola. ++ Se actualizó la versión de nwjs 0.38.2 (se mantiene en ARM 0.28.3). ++ Se actualizó la versión de node-hid a la 0.7.8 ++ Se incorpora FullScreen en modo grafico, acción por icono. ++ Se actualizó la versión de RGraph utilizando los js min. ++ Se incorporó la opción de selección de voces para el audio. ++ Se actualizó a bootstrap-select v1.13.1 ++ Se actualizó a Jquery v3.4.1. ++ Se actualizó a Jquery datatable v1.10.19 ++ Se agrega redimensionamiento automático. ++ Se arregla el contador de registros y de tanque en modo consola. + +** Versión 1.21: (Febrero 26, 2019) + ++ Se incorpora soporte para la interfaz gráfica en ARM (emalibre-gui). ++ Se adecua los nombres en los distintos paquetes DEB's. + +** Versión 1.20: (Febrero 19, 2019) + ++ Se incorpora soporte para la interfaz gráfica en ARM (emalibre-gui). ++ Se adecua los nombres en los distintos paquetes DEB's. ++ Se actualizó la versión de nwjs 0.36.2 (en ARM 0.28.3) ++ Se actualizó la versión de node-hid a la 0.7.7 ++ Se actualizó la versión Bootstrap v4.3.1 ++ Se actualizó node a la versión 10.0.0 a 11.10.0 en modo consola + +** Versión 1.19: (Enero 28, 2019) + ++ Se actualizó la versión de nwjs 0.35.4 ++ Se actualizó la versión de node-hid a la 0.7.6 ++ Se actualizó la versión de RGraph a la 5.0 ++ Se actualizó la versión Bootstrap v4.2.1 + +** Versión 1.18: (Diciembre 20, 2018) + ++ Se actualizó la versión de nwjs 0.35.0 (Chromium 71.0.3578.80 y node 11.3.0) ++ Se arregla el tanque informado en las emacenter. ++ Se arregla el datatable en los logs en tiempo real. ++ Se depura librerías no utilizadas de RGraph. + +** Versión 1.17: (Noviembre 26, 2018) + ++ Se actualizó la versión de nwjs 0.34.5 (Chromium 70.0.35 y node 11.2.0) ++ Se actualizó la versión de node-hid 0.7.4 ++ Se adecua el publicador para la red emacenter enviado un parámetro tanque=true cuando un registro proviene del tanque. + +** Versión 1.16: (Noviembre 2, 2018) + ++ Se actualizó la versión de nwjs 0.34.1 (Chromium 70 y node 11.0.0) ++ Se actualizó la versión de RGraph 4.68 ++ Se arregla el navbar al utilizar el botón del medio del mouse y se cambia estilo del cursor. ++ Se mejora el botón actualizar, alertando por S.O. ++ Se elimina algunas alertas por SMTP. + +** Versión 1.15: (Septiembre 26, 2018) + ++ Se cambia la numeración en el versionado. ++ Se adecua el actualizador a la nueva versión. ++ Se arregla mensaje en modo visor en la barra. ++ Se re-diseña el menú de configuración. ++ Se actualizó la versión de nwjs 0.33.4 (Chromium 69 y node 10.11.0) + +** Versión 14: (Septiembre 25, 2018) + ++ Cambios de diseño en la GUI. ++ Se arregla el modo visor y se incorpora un icono distinto. ++ Se mejora el datatable. ++ El fondo de adecua al estado del clima. ++ Se mejora el actualizador. ++ Se actualizó a Bootstrap v4.1.3. ++ Se actualizó la versión de nwjs 0.33.3 (Chromium 69 y node 10.10) + +** Versión 13: (Septiembre 17, 2018) + ++ Cambios de tema en la GUI. ++ Se migra a Bootstrap 4.0.0 la gui. ++ Se agrega audio a carpincho. ++ Se cambia la manera de exponer los mensajes de carpincho. ++ Se realizan cambios en el iconizado. ++ Se agregan dos submenú al menuitem (ocultar y mostrar). ++ Se actualizó la versión de nwjs 0.33.2 (Chromium 69 y node 10.10) ++ Se actualizó bootstrap-select v1.13.2 + +** Versión 12: (Septiembre 3, 2018) + ++ Se agrega el control de estado de los sensores. ++ Se mejora la barra de proceso y la sincronización. ++ Se depuran variables, y se mejora el control de los archivos de logs. ++ Se actualizó la versión de nwjs 0.32.4 (Chromium 68 y node 10.9) ++ Se actualizó lib datatable 1.10.18,RGraph 4.67,Notify.js 0.4.2 y jquery 3.3.1. ++ Se mantiene versión de Bootstrap v3.3.7, y se actualizó bootstrap-select v1.13.1 + +** Versión 11: (Julio 2, 2018) + ++ Se adapta el recolector y el visor al nuevo servidor de emacenter en HTTPS. ++ Se mejora el validador. ++ Se actualizó la versión de nwjs 0.31.4 y Chromium 67. + +** Versión 10: (Mayo 5, 2018) + ++ Se modifica el actualizador. ++ Se elimina el parámetro gui en la configuración general. ++ Se mejora el logs. ++ Se mejora el listado de versiones de módulos de NWJS. ++ Se actualizó la versión de nwjs 0.30.2 y Node v10.0.0. + +** Versión 9: (Abril 20, 2018) + ++ Se mejora el aspecto visual y se incluye la función (zoom) ++ Se actualizó la versión de nwjs 0.30.0 y Node v9.11.1 ++ Se agrega el estado de RF y su correspondiente icono. + +** Versión 8: (Abril 17, 2018) ++ Se actualizó el aspecto visual, mejorado lo responsivo. ++ Se actualizó la versión de nwjs 0.29.3 y Node v9.11.1 ++ Se agregan máximos y mínimos internos y externos. diff --git a/src/COPYING b/src/COPYING new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/src/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/src/build/config.gypi b/src/build/config.gypi new file mode 100644 index 0000000..9f16fa1 --- /dev/null +++ b/src/build/config.gypi @@ -0,0 +1,419 @@ +# Do not edit. File was generated by nw-gyp's "configure" step +{ + "target_defaults": { + "cflags": [], + "default_configuration": "Release", + "defines": [ + "NODE_OPENSSL_CONF_NAME=nodejs_conf", + "NODE_OPENSSL_HAS_QUIC", + "ICU_NO_USER_DATA_OVERRIDE" + ], + "include_dirs": [], + "libraries": [] + }, + "variables": { + "asan": 0, + "coverage": "false", + "dcheck_always_on": 0, + "debug_nghttp2": "false", + "debug_node": "false", + "enable_lto": "false", + "enable_pgo_generate": "false", + "enable_pgo_use": "false", + "error_on_warn": "false", + "force_dynamic_crt": 0, + "gas_version": "2.35", + "host_arch": "x64", + "icu_data_in": "../../deps/icu-tmp/icudt73l.dat", + "icu_endianness": "l", + "icu_gyp_path": "tools/icu/icu-generic.gyp", + "icu_path": "deps/icu-small", + "icu_small": "false", + "icu_ver_major": "73", + "is_debug": 0, + "libdir": "lib", + "llvm_version": "0.0", + "napi_build_version": "9", + "node_builtin_shareable_builtins": [ + "deps/cjs-module-lexer/lexer.js", + "deps/cjs-module-lexer/dist/lexer.js", + "deps/undici/undici.js" + ], + "node_byteorder": "little", + "node_debug_lib": "false", + "node_enable_d8": "false", + "node_enable_v8_vtunejit": "false", + "node_fipsinstall": "false", + "node_install_corepack": "true", + "node_install_npm": "true", + "node_library_files": [ + "lib/_http_agent.js", + "lib/_http_client.js", + "lib/_http_common.js", + "lib/_http_incoming.js", + "lib/_http_outgoing.js", + "lib/_http_server.js", + "lib/_stream_duplex.js", + "lib/_stream_passthrough.js", + "lib/_stream_readable.js", + "lib/_stream_transform.js", + "lib/_stream_wrap.js", + "lib/_stream_writable.js", + "lib/_tls_common.js", + "lib/_tls_wrap.js", + "lib/assert.js", + "lib/assert/strict.js", + "lib/async_hooks.js", + "lib/buffer.js", + "lib/child_process.js", + "lib/cluster.js", + "lib/console.js", + "lib/constants.js", + "lib/crypto.js", + "lib/dgram.js", + "lib/diagnostics_channel.js", + "lib/dns.js", + "lib/dns/promises.js", + "lib/domain.js", + "lib/events.js", + "lib/fs.js", + "lib/fs/promises.js", + "lib/http.js", + "lib/http2.js", + "lib/https.js", + "lib/inspector.js", + "lib/inspector/promises.js", + "lib/internal/abort_controller.js", + "lib/internal/assert.js", + "lib/internal/assert/assertion_error.js", + "lib/internal/assert/calltracker.js", + "lib/internal/async_hooks.js", + "lib/internal/blob.js", + "lib/internal/blocklist.js", + "lib/internal/bootstrap/node.js", + "lib/internal/bootstrap/realm.js", + "lib/internal/bootstrap/shadow_realm.js", + "lib/internal/bootstrap/switches/does_not_own_process_state.js", + "lib/internal/bootstrap/switches/does_own_process_state.js", + "lib/internal/bootstrap/switches/is_main_thread.js", + "lib/internal/bootstrap/switches/is_not_main_thread.js", + "lib/internal/bootstrap/web/exposed-wildcard.js", + "lib/internal/bootstrap/web/exposed-window-or-worker.js", + "lib/internal/buffer.js", + "lib/internal/child_process.js", + "lib/internal/child_process/serialization.js", + "lib/internal/cli_table.js", + "lib/internal/cluster/child.js", + "lib/internal/cluster/primary.js", + "lib/internal/cluster/round_robin_handle.js", + "lib/internal/cluster/shared_handle.js", + "lib/internal/cluster/utils.js", + "lib/internal/cluster/worker.js", + "lib/internal/console/constructor.js", + "lib/internal/console/global.js", + "lib/internal/constants.js", + "lib/internal/crypto/aes.js", + "lib/internal/crypto/certificate.js", + "lib/internal/crypto/cfrg.js", + "lib/internal/crypto/cipher.js", + "lib/internal/crypto/diffiehellman.js", + "lib/internal/crypto/ec.js", + "lib/internal/crypto/hash.js", + "lib/internal/crypto/hashnames.js", + "lib/internal/crypto/hkdf.js", + "lib/internal/crypto/keygen.js", + "lib/internal/crypto/keys.js", + "lib/internal/crypto/mac.js", + "lib/internal/crypto/pbkdf2.js", + "lib/internal/crypto/random.js", + "lib/internal/crypto/rsa.js", + "lib/internal/crypto/scrypt.js", + "lib/internal/crypto/sig.js", + "lib/internal/crypto/util.js", + "lib/internal/crypto/webcrypto.js", + "lib/internal/crypto/webidl.js", + "lib/internal/crypto/x509.js", + "lib/internal/debugger/inspect.js", + "lib/internal/debugger/inspect_client.js", + "lib/internal/debugger/inspect_repl.js", + "lib/internal/dgram.js", + "lib/internal/dns/callback_resolver.js", + "lib/internal/dns/promises.js", + "lib/internal/dns/utils.js", + "lib/internal/encoding.js", + "lib/internal/error_serdes.js", + "lib/internal/errors.js", + "lib/internal/event_target.js", + "lib/internal/events/symbols.js", + "lib/internal/file.js", + "lib/internal/fixed_queue.js", + "lib/internal/freelist.js", + "lib/internal/freeze_intrinsics.js", + "lib/internal/fs/cp/cp-sync.js", + "lib/internal/fs/cp/cp.js", + "lib/internal/fs/dir.js", + "lib/internal/fs/promises.js", + "lib/internal/fs/read/context.js", + "lib/internal/fs/recursive_watch.js", + "lib/internal/fs/rimraf.js", + "lib/internal/fs/streams.js", + "lib/internal/fs/sync_write_stream.js", + "lib/internal/fs/utils.js", + "lib/internal/fs/watchers.js", + "lib/internal/heap_utils.js", + "lib/internal/histogram.js", + "lib/internal/http.js", + "lib/internal/http2/compat.js", + "lib/internal/http2/core.js", + "lib/internal/http2/util.js", + "lib/internal/idna.js", + "lib/internal/inspector_async_hook.js", + "lib/internal/js_stream_socket.js", + "lib/internal/legacy/processbinding.js", + "lib/internal/linkedlist.js", + "lib/internal/main/check_syntax.js", + "lib/internal/main/embedding.js", + "lib/internal/main/eval_stdin.js", + "lib/internal/main/eval_string.js", + "lib/internal/main/inspect.js", + "lib/internal/main/mksnapshot.js", + "lib/internal/main/print_help.js", + "lib/internal/main/prof_process.js", + "lib/internal/main/repl.js", + "lib/internal/main/run_main_module.js", + "lib/internal/main/test_runner.js", + "lib/internal/main/watch_mode.js", + "lib/internal/main/worker_thread.js", + "lib/internal/mime.js", + "lib/internal/modules/cjs/loader.js", + "lib/internal/modules/esm/assert.js", + "lib/internal/modules/esm/create_dynamic_module.js", + "lib/internal/modules/esm/fetch_module.js", + "lib/internal/modules/esm/formats.js", + "lib/internal/modules/esm/get_format.js", + "lib/internal/modules/esm/handle_process_exit.js", + "lib/internal/modules/esm/hooks.js", + "lib/internal/modules/esm/initialize_import_meta.js", + "lib/internal/modules/esm/load.js", + "lib/internal/modules/esm/loader.js", + "lib/internal/modules/esm/module_job.js", + "lib/internal/modules/esm/module_map.js", + "lib/internal/modules/esm/package_config.js", + "lib/internal/modules/esm/resolve.js", + "lib/internal/modules/esm/shared_constants.js", + "lib/internal/modules/esm/translators.js", + "lib/internal/modules/esm/utils.js", + "lib/internal/modules/esm/worker.js", + "lib/internal/modules/helpers.js", + "lib/internal/modules/package_json_reader.js", + "lib/internal/modules/run_main.js", + "lib/internal/navigator.js", + "lib/internal/net.js", + "lib/internal/options.js", + "lib/internal/per_context/domexception.js", + "lib/internal/per_context/messageport.js", + "lib/internal/per_context/primordials.js", + "lib/internal/perf/event_loop_delay.js", + "lib/internal/perf/event_loop_utilization.js", + "lib/internal/perf/nodetiming.js", + "lib/internal/perf/observe.js", + "lib/internal/perf/performance.js", + "lib/internal/perf/performance_entry.js", + "lib/internal/perf/resource_timing.js", + "lib/internal/perf/timerify.js", + "lib/internal/perf/usertiming.js", + "lib/internal/perf/utils.js", + "lib/internal/policy/manifest.js", + "lib/internal/policy/sri.js", + "lib/internal/priority_queue.js", + "lib/internal/process/esm_loader.js", + "lib/internal/process/execution.js", + "lib/internal/process/per_thread.js", + "lib/internal/process/permission.js", + "lib/internal/process/policy.js", + "lib/internal/process/pre_execution.js", + "lib/internal/process/promises.js", + "lib/internal/process/report.js", + "lib/internal/process/signal.js", + "lib/internal/process/task_queues.js", + "lib/internal/process/warning.js", + "lib/internal/process/worker_thread_only.js", + "lib/internal/promise_hooks.js", + "lib/internal/querystring.js", + "lib/internal/readline/callbacks.js", + "lib/internal/readline/emitKeypressEvents.js", + "lib/internal/readline/interface.js", + "lib/internal/readline/promises.js", + "lib/internal/readline/utils.js", + "lib/internal/repl.js", + "lib/internal/repl/await.js", + "lib/internal/repl/history.js", + "lib/internal/repl/utils.js", + "lib/internal/socket_list.js", + "lib/internal/socketaddress.js", + "lib/internal/source_map/prepare_stack_trace.js", + "lib/internal/source_map/source_map.js", + "lib/internal/source_map/source_map_cache.js", + "lib/internal/stream_base_commons.js", + "lib/internal/streams/add-abort-signal.js", + "lib/internal/streams/compose.js", + "lib/internal/streams/destroy.js", + "lib/internal/streams/duplex.js", + "lib/internal/streams/duplexify.js", + "lib/internal/streams/end-of-stream.js", + "lib/internal/streams/from.js", + "lib/internal/streams/lazy_transform.js", + "lib/internal/streams/legacy.js", + "lib/internal/streams/operators.js", + "lib/internal/streams/passthrough.js", + "lib/internal/streams/pipeline.js", + "lib/internal/streams/readable.js", + "lib/internal/streams/state.js", + "lib/internal/streams/transform.js", + "lib/internal/streams/utils.js", + "lib/internal/streams/writable.js", + "lib/internal/test/binding.js", + "lib/internal/test/transfer.js", + "lib/internal/test_runner/coverage.js", + "lib/internal/test_runner/harness.js", + "lib/internal/test_runner/mock/mock.js", + "lib/internal/test_runner/mock/mock_timers.js", + "lib/internal/test_runner/reporter/dot.js", + "lib/internal/test_runner/reporter/junit.js", + "lib/internal/test_runner/reporter/lcov.js", + "lib/internal/test_runner/reporter/spec.js", + "lib/internal/test_runner/reporter/tap.js", + "lib/internal/test_runner/reporter/v8-serializer.js", + "lib/internal/test_runner/runner.js", + "lib/internal/test_runner/test.js", + "lib/internal/test_runner/tests_stream.js", + "lib/internal/test_runner/utils.js", + "lib/internal/timers.js", + "lib/internal/tls/secure-context.js", + "lib/internal/tls/secure-pair.js", + "lib/internal/trace_events_async_hooks.js", + "lib/internal/tty.js", + "lib/internal/url.js", + "lib/internal/util.js", + "lib/internal/util/colors.js", + "lib/internal/util/comparisons.js", + "lib/internal/util/debuglog.js", + "lib/internal/util/embedding.js", + "lib/internal/util/inspect.js", + "lib/internal/util/inspector.js", + "lib/internal/util/iterable_weak_map.js", + "lib/internal/util/parse_args/parse_args.js", + "lib/internal/util/parse_args/utils.js", + "lib/internal/util/types.js", + "lib/internal/v8/startup_snapshot.js", + "lib/internal/v8_prof_polyfill.js", + "lib/internal/v8_prof_processor.js", + "lib/internal/validators.js", + "lib/internal/vm.js", + "lib/internal/vm/module.js", + "lib/internal/wasm_web_api.js", + "lib/internal/watch_mode/files_watcher.js", + "lib/internal/watchdog.js", + "lib/internal/webidl.js", + "lib/internal/webstreams/adapters.js", + "lib/internal/webstreams/compression.js", + "lib/internal/webstreams/encoding.js", + "lib/internal/webstreams/queuingstrategies.js", + "lib/internal/webstreams/readablestream.js", + "lib/internal/webstreams/transfer.js", + "lib/internal/webstreams/transformstream.js", + "lib/internal/webstreams/util.js", + "lib/internal/webstreams/writablestream.js", + "lib/internal/worker.js", + "lib/internal/worker/io.js", + "lib/internal/worker/js_transferable.js", + "lib/module.js", + "lib/net.js", + "lib/os.js", + "lib/path.js", + "lib/path/posix.js", + "lib/path/win32.js", + "lib/perf_hooks.js", + "lib/process.js", + "lib/punycode.js", + "lib/querystring.js", + "lib/readline.js", + "lib/readline/promises.js", + "lib/repl.js", + "lib/stream.js", + "lib/stream/consumers.js", + "lib/stream/promises.js", + "lib/stream/web.js", + "lib/string_decoder.js", + "lib/sys.js", + "lib/test.js", + "lib/test/reporters.js", + "lib/timers.js", + "lib/timers/promises.js", + "lib/tls.js", + "lib/trace_events.js", + "lib/tty.js", + "lib/url.js", + "lib/util.js", + "lib/util/types.js", + "lib/v8.js", + "lib/vm.js", + "lib/wasi.js", + "lib/worker_threads.js", + "lib/zlib.js" + ], + "node_module_version": 115, + "node_no_browser_globals": "false", + "node_prefix": "/", + "node_release_urlbase": "https://nodejs.org/download/release/", + "node_section_ordering_info": "", + "node_shared": "false", + "node_shared_brotli": "false", + "node_shared_cares": "false", + "node_shared_http_parser": "false", + "node_shared_libuv": "false", + "node_shared_nghttp2": "false", + "node_shared_nghttp3": "false", + "node_shared_ngtcp2": "false", + "node_shared_openssl": "false", + "node_shared_zlib": "false", + "node_tag": "", + "node_target_type": "executable", + "node_use_bundled_v8": "true", + "node_use_node_code_cache": "true", + "node_use_node_snapshot": "true", + "node_use_openssl": "true", + "node_use_v8_platform": "true", + "node_with_ltcg": "false", + "node_without_node_options": "false", + "node_write_snapshot_as_array_literals": "false", + "openssl_is_fips": "false", + "openssl_quic": "true", + "ossfuzz": "false", + "shlib_suffix": "so.115", + "single_executable_application": "true", + "target_arch": "x64", + "v8_enable_31bit_smis_on_64bit_arch": 0, + "v8_enable_extensible_ro_snapshot": 0, + "v8_enable_gdbjit": 0, + "v8_enable_hugepage": 0, + "v8_enable_i18n_support": 1, + "v8_enable_inspector": 1, + "v8_enable_javascript_promise_hooks": 1, + "v8_enable_lite_mode": 0, + "v8_enable_maglev": 0, + "v8_enable_object_print": 1, + "v8_enable_pointer_compression": 0, + "v8_enable_shared_ro_heap": 1, + "v8_enable_short_builtin_calls": 1, + "v8_enable_v8_checks": 0, + "v8_enable_webassembly": 1, + "v8_no_strict_aliasing": 1, + "v8_optimized_debug": 1, + "v8_promise_internal_field_count": 1, + "v8_random_seed": 0, + "v8_trace_maps": 0, + "v8_use_siphash": 1, + "want_separate_host_toolset": 0 + } +} diff --git a/src/core/actualizar.js b/src/core/actualizar.js new file mode 100644 index 0000000..da962b6 --- /dev/null +++ b/src/core/actualizar.js @@ -0,0 +1,159 @@ +/** + * Archivo de Actualizacion de EMA Libre. + * + * Archivo se ejectuta cuando se lanza EMA libre con el parametro update y + * contiene las funciones para realizar dicha tarea. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +/*************************************** + *** DECLARACIONES INICIALES ****** + **************************************/ + +var ConfGlobal = require('./../conf/ConfiguracionGlobal.js'); +var targz = require('targz'); +var fs = require('fs'); +var path = require('path'); +var rutaNube = '/index.php/s/dpOA4iZs9GIUUKg/download?path=%2F'; +if (process.platform === 'win32' || process.platform === 'win64') { rutaNube = rutaNube + 'Windows'; } else { rutaNube = rutaNube + 'GNULinux'; } + +module.exports = FUNCIONACTUALIZAR = { + Control: function (actualizar) { + FUNCIONACTUALIZAR.BorrarDescarga('./tmp'); + const https = require('https'); + const options = { + hostname: 'nube.gugler.com.ar', + port: 443, + path: rutaNube + '&files=Control_UltimaVersion.txt', + method: 'GET' + }; + + const req = https.request(options, (res) => { + res.on('data', (datos) => { + // Compatibilidad con version anterior + var VersionActual = ConfGlobal.ConfGlobal.Version; + if (VersionActual < datos) { actualizar(true, true, datos); } else { actualizar(false, true, datos); } + }); + }); + + req.on('error', (e) => { + actualizar(false, false, e); + }); + req.end(); + }, + + Descargar: function (version, resultado) { + FUNCIONACTUALIZAR.BorrarDescarga('./tmp'); + var versionactualizada = 'EMA_Carpincho_v' + version + '.tar.gz'; + var nombredescarga = 'EMA_Carpincho.tar.gz'; + var file = fs.createWriteStream('./tmp/' + nombredescarga); + const https = require('https'); + const options = { + hostname: 'nube.gugler.com.ar', + port: 443, + path: rutaNube + '&files=' + versionactualizada, + method: 'GET' + }; + const req = https.request(options, (res) => { + var len = parseInt(res.headers['content-length'], 10); + var body = ''; + var cur = 0; + var total = len / 1048576; // 1048576 - bytes in 1Megabyte + res.pipe(file); + + file.on('finish', function () { + file.close(); + resultado(true, true, true); + }); + res.on('data', function (chunk) { + body += chunk; + cur += chunk.length; + var descargadoPorcentaje = (100.0 * cur / len).toFixed(2); + var descargado = (cur / 1048576).toFixed(2); + var texto = 'Bajando ' + descargadoPorcentaje + '% ' + descargado + ' Mb'; + resultado(false, texto, descargadoPorcentaje); + }); + }); + req.on('error', (e) => { + resultado(false, false, false); + }); + req.end(); + }, + + Descomprimir: function (resultado) { + var nombredescarga = './tmp/EMA_Carpincho.tar.gz'; + targz.decompress({ + src: nombredescarga, + dest: './tmp/' + }, function (err) { + if (err) { + resultado(false); + } else { + // Luego de descomprimir se borrar el archivo tar.gz + fs.unlink(nombredescarga, function (err) { + if (err) return resultado(false); + }); + resultado(true); + } + }); + }, + + Desplegar: function (resultado) { + var despliegeOrigen = './tmp'; + var despliegeDestino = './'; + // se borrar los archivos de configuracion y tanques antes de desplegar, para no pisar. + // Manteniendo el archivo de configuracion particular, del usuario. + fs.unlink('./tmp/conf/ConfiguracionGeneral.js', function (err) { if (err) return resultado(false); }); + fs.unlink('./tmp/logs/debug.log', function (err) { if (err) return resultado(false); }); + fs.unlink('./tmp/logs/registro_diario.log', function (err) { if (err) return resultado(false); }); + fs.unlink('./tmp/logs/TanquePendientes.log', function (err) { if (err) return resultado(false); }); + // Despliege recursivo + resultado(true); + }, + + LanzarAplicativoIndependiente: function () { + const { spawn } = require('child_process'); + const child = spawn('./tmp/EmaLibre.exe', ['update', '--user-data-dir=./tmp/tmp/cache_temporal'], { detached: true, stdio: 'ignore' }); + child.unref(); + gui.App.closeAllWindows(); + gui.App.quit(); + process.exit(1); + win.close(); + }, + + BorrarDescarga: function (despliegeOrigen) { + if (fs.existsSync(despliegeOrigen)) { + fs.readdirSync(despliegeOrigen).forEach(function (entry) { + var rutaArchivo = path.join(despliegeOrigen, entry); + if (fs.lstatSync(rutaArchivo).isDirectory()) { + FUNCIONACTUALIZAR.BorrarDescarga(rutaArchivo); + } else { + fs.unlinkSync(rutaArchivo); + } + }); + + if (despliegeOrigen !== './tmp') { fs.rmdirSync(despliegeOrigen); } + } else { fs.mkdirSync(despliegeOrigen); } // Crea directorio que no existe + } +}; + +// termina el Objeto/Clase diff --git a/src/core/ema.js b/src/core/ema.js new file mode 100644 index 0000000..9894110 --- /dev/null +++ b/src/core/ema.js @@ -0,0 +1,973 @@ +/** + * Archivo Core de EMA Libre Cliente (Carpincho). + * + * Archivo que se ejecuta en segundo plano y es el encargado, de obtener, registrar, + * calcular y publicar los registros, incluyendo los modulos necesarios para realizar + * estas tareas. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (https://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link https://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +/************************************** + *** DECLARACIONES INICIALES ****** + **************************************/ + +var configGeneralEMA = require('./../conf/ConfiguracionGeneral.js'); // Configuracion General +const configGlobalEMA = require('./../conf/ConfiguracionGlobal.js'); // Configuracion Global +const Correo = require('./mail.js'); // Envio de correo. +var recolector = require('./recolector.js'); // Recolector de informacion USB. +const Redes = require('./redes_meteorologicas.js'); // Redes Meteorologicas disponibles. +const Validador = require('./validaciones.js'); // Validador de registros. +const fs = require('fs'); // Libreria fs para el manejo de archivos. +const util = require('util'); // Utilidades. +var Guardar = []; // Tanque diario de registros leidos (para acumulados). +var versionEMA = configGlobalEMA.ConfGlobal.Nombre + ' v' + configGlobalEMA.ConfGlobal.Version; + +APP = module.exports = { + Configuracion: { + debug: configGeneralEMA.ConfGeneral.debug, // Se obtiene el nivel de debug del archivo de Conf General. + utc: configGeneralEMA.ConfGeneral.UTC, // Se obtiene la fecha en formato UTC del archivo de Conf General. + Errores: '', // Errores detectado en el funcionamiento de EMA. + TiempoContinuo: 0, // Tiempo en segundos(s) de recoleccion. + Cantidad_No_Lectura: 99999, // Cantidad de lecturas falsas admitidas. + Repeticiones: 0, // Contador de repeticiones. No parametrizable, siempre 0. + RepeticionesConError: 0, // Contador de repeticiones. No parametrizable, siempre 0. + TiempoMaximo: 0, // Contador de repeticiones. No parametrizable, siempre 0. + TiempoFueraDeLinea: 0, // Contador de tiempo fuera de linea.. No parametrizable, siempre 0. + TiempoMaximoFueraDeLinea: 300, // Tiempo en segundo fuera de linea para el envio de mail (default:3600 = 2hs). + IdsSetTimeouts: [], // Id del TimeOut del blucle continuo. + EstadoSensores: [], // Solo estado Sensores + Estado_Val_Ant: 0, // Solo estado Sensores del registro anterior para almacenar errores, ya que no se almacenan. + FechaLanzadoTimeout: 0, // fecha real de lanzamiento del TimeOut para el blucle continuo. + Run: 0, // Variable que indica que esta encendida EMA. + RunTime: 0, // Variable que indica que esta ejecutandose el Recolector. + BanderaPendientes: 0, // Bandera de Tanque enviando + CantidadPendientes: 0, // Tanque Pendientes + TanquePendiente: [], // Tanque Pendientes + UltimoRegistro: '', // Ultimo Registro Recolectado con datos de los sensores. + UltimoPublicado: [], // Ultimo Registro de las Redes Publicadas. + tempAlmacenadoPendientes: [] // Ultimo Registro de las Redes Publicadas. + }, + RegistrarLog: function (reg, depurar) { + if (typeof depurar !== 'undefined') { depurar = false; } + // se convierte la fecha a la UTC parametrizada + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var fechaHora = new Date(utc + (3600000 * (APP.Configuracion.utc))); + var horas = fechaHora.getHours(); + var minutos = fechaHora.getMinutes(); + var segundos = fechaHora.getSeconds(); + var mes = fechaHora.getMonth() + 1; + var dia = fechaHora.getDate(); + if (dia <= 9) { dia = '0' + dia; } + if (mes <= 9) { mes = '0' + mes; } + if (horas < 10) { horas = '0' + horas; } + if (minutos < 10) { minutos = '0' + minutos; } + if (segundos < 10) { segundos = '0' + segundos; } + var fecha = dia + '/' + mes + '/' + fechaHora.getFullYear() + ' ' + horas + ':' + minutos + ':' + segundos; + var registrologs = fecha + ' - ' + util.format(reg) + '\n'; + // SE CONTROLA EL TAMAÑO DEL LOG SEGUN PARAMETRIA + var estadoarchivoD = fs.statSync("logs/debug.log"); + var TamanioenMegaD = (estadoarchivoD.size)/ 1000000.0; + if (depurar || (TamanioenMegaD >= configGeneralEMA.ConfGeneral.debugTamanio)) + { + // SE DEPURA EL ARCHIVO DE REGISTROS DE LOGS + fs.writeFile('./logs/debug.log', '', { + encoding: 'utf8', + autoClose: true + }, function (err) { + if (err) { APP.RegistrarLog('0|ERROR|Depurando archivo registro de logs :' + err); } + APP.RegistrarLog('0|PURGADO|Depurando automaticamente archivo registro de logs.'); + }); + } else { + // GUARDA LOS REGISTROS DE LOGS + fs.appendFile('./logs/debug.log', registrologs, { + encoding: 'utf8', + autoClose: true + }, function (err) { + if (err) { + APP.RegistrarLog('0|ERROR|Guardando registro de logs en archivo :' + err); + } + }); + } + registrologs=null;fecha=null;dia=null;mes=null;segundos=null;minutos=null;horas=null;fechaHora=null;utc=null;d=null; + }, + RepeticionesConError: function () { + return APP.Configuracion.RepeticionesConError; + }, + Estado: function () { + if (APP.Configuracion.Run === 0 && APP.Configuracion.RunTime === 0) { + return [false, APP.Configuracion.Errores]; + } + if (APP.Configuracion.Run === 1 && APP.Configuracion.RunTime === 0) { + return [false, APP.Configuracion.Errores]; + } + if (APP.Configuracion.Run === 1 && APP.Configuracion.RunTime === 1) { + return [true, '']; + } + }, + EstadoUSB: function (callback) { + try{ callback(recolector.status()); }catch(e){APP.RegistrarLog('0|CORE|Error: '+e);return false;} + }, + + Salir: function () { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.'); + if (configGeneralEMA.ConfEmail.ActivarCorreos === true) Correo.EnviarEmail(configGeneralEMA,'EMA - OFFLINE', 'Estimado,

Le informamos que la estación ' + configGeneralEMA.ConfGeneral.NombreEstacion + ' se detuvo y se cerro el software EMA LIBRE.

Saludos Cordiales.'); + APP.Configuracion.Errores = 'Se Salio del Recolector'; + }, + Detener: function () { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|DETENER: Se detiene el recolector de EMA LIBRE.'); + APP.Configuracion.RunTime = 0; + APP.Configuracion.Errores = 'Se detuvo manualmente el Recolector'; + APP.LimpiarM(); + }, + Reconfigurar: function () { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|RECONFIGURANDO: Se reconfigura el recolectorde EMA LIBRE.'); + if (configGeneralEMA.ConfEmail.ActivarCorreos === true) Correo.EnviarEmail(configGeneralEMA,'EMA - CONFIG', 'Estimado,

Le informamos que se modificó la configuración de la estación ' + configGeneralEMA.ConfGeneral.NombreEstacion + '.

Saludos Cordiales.'); + APP.Configuracion.TiempoContinuo = configGeneralEMA.ConfGeneral.Tiempo_de_Recoleccion; + APP.Configuracion.debug = configGeneralEMA.ConfGeneral.debug; + recolector.conf.debug = configGeneralEMA.ConfGeneral.debug; + }, + Iniciar: function () { + APP.RegistrarLog('0|CORE|INICIAR:Iniciando.'); + if (APP.Configuracion.Run === 1 && APP.Configuracion.RunTime === 0) { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|INICIAR: Se inicio el recolector de EMA LIBRE.'); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|DEBUG: ' + APP.Configuracion.debug); + APP.Configuracion.RunTime = 1; + APP.Continuo(); + } else { + APP.RegistrarLog('0|CORE|Hay un proceso corriendo, se elimina.'); + APP.LimpiarM(); + APP.Continuo(); + } + }, + LimpiarM: function () { + var tamanio = APP.Configuracion.IdsSetTimeouts.length; + // Se limpias los tiempos identificados + for (tamanio;tamanio>-1;tamanio--){ + clearTimeout(APP.Configuracion.IdsSetTimeouts[tamanio]); + APP.Configuracion.IdsSetTimeouts.splice(tamanio, 1); + } + // Se limpian las variables + tamanio = null; + return true; + }, + Guardar_Diario: function (Datos) { + // GUARDA LOS REGISTROS DIARIOS + fs.writeFile('./logs/registro_diario.log', JSON.stringify(Datos, null, 4), { + encoding: 'utf8', + autoClose: true + }, (err) => { + if (err) { + APP.RegistrarLog('1|ERROR: Guardando registro diario en archivo :' + err); + } + }); + }, + + TiempoActualRecolector: function () { + // APP.RegistrarLog(APP.Configuracion.IdsSetTimeouts); + var fechaTiempo = APP.Configuracion.FechaLanzadoTimeout; + var tiempoC = APP.Configuracion.TiempoContinuo; + if (fechaTiempo > 0) { + var Resto = 0; + Resto = (tiempoC - ((Date.now() - fechaTiempo) / 1000)); + if(Resto > -1 && Resto < 150){ + var porcentaje = (100 - ((Resto * 100) / tiempoC)).toFixed(0); + var segundos = (tiempoC - Resto).toFixed(1); + return [porcentaje,segundos]; + }else{return [false,false];} + } else { + return [false,false]; + } + }, + UltimoRegistro: function () { + if (typeof APP.Configuracion.UltimoRegistro !== 'undefined' && APP.Configuracion.UltimoRegistro !== '') { + return APP.Configuracion.UltimoRegistro; + } else { + return false; + } + }, + EstadoSensores: function () { + if (typeof APP.Configuracion.EstadoSensores !== 'undefined' && APP.Configuracion.EstadoSensores !== '') { + return APP.Configuracion.EstadoSensores; + } else { + return false; + } + }, + UltimoPublicado: function () { + if (typeof APP.Configuracion.UltimoPublicado !== 'undefined' && APP.Configuracion.UltimoPublicado !== '') { + return APP.Configuracion.UltimoPublicado; + } else { + return false; + } + }, + HayPendientes: function () { + if (APP.Configuracion.CantidadPendientes !== 0) { + return APP.Configuracion.CantidadPendientes; + } else { + return false; + } + }, + + // Metodo para conectar/verificar la conexion USB de la EMA USB. + Conectar: function () { + try { + APP.RegistrarLog('0|CORE|Estableciendo Time Zone UTC ' + configGeneralEMA.ConfGeneral.UTC); + APP.RegistrarLog('0|CORE|Verificando Estado de la EMA...'); + APP.Configuracion.TiempoContinuo = configGeneralEMA.ConfGeneral.Tiempo_de_Recoleccion; + APP.Configuracion.debug = configGeneralEMA.ConfGeneral.debug; + recolector.conf.debug = configGeneralEMA.ConfGeneral.debug; + if (recolector.status() === true || APP.Configuracion.Run === 0) { + // Verifica la plataforma donde esta corriendo + if (APP.Configuracion.Run === 0) { + station = recolector.open(); // No puedo poner var station = -> no funciona ver. + APP.RegistrarLog('0|CORE|Conectando..'); + } // solo si es la primera vez, genera el recolector. + if (station === null || station === false) { + if (station === false) { + APP.Configuracion.Errores = 'Problemas con el USB, por favor desconecte y conecte el mismo'; + APP.Configuracion.Run = 0; + throw new Error('Problemas con el USB, por favor desconecte y conecte el mismo.'); + } else { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|Info de Estado: Fuera de Linea.'); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|Info de Detalle: EMA no conectada.'); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|Info de Acción: Verifique la conexion USB de la EMA.'); + APP.Configuracion.Errores = 'Se espera ' + APP.Configuracion.TiempoContinuo + ' segundos y se prueba conectar nuevamente.'; + throw new Error('Problemas con la lectura USB'); + } + } else { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|ESTADO: Online'); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|PLATAFORMA: ' + recolector.conf.plataforma); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|AUTOR:Gugler Lab'); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|VERSION:' + configGlobalEMA.ConfGlobal.Version); + if (APP.Configuracion.Run === 0) { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|INICIAR: Se inicio el motor de EMA LIBRE.'); + APP.Configuracion.Errores = 'CORE: INICIAR-> Se inicio el motor de EMA LIBRE.'; + APP.Configuracion.Run = 1; + } + APP.Configuracion.TiempoMaximo = 0; + APP.Iniciar(); // Se llama a la funcion INICIO + } + } else { + if (recolector.status() === false && APP.Configuracion.Run === 0) { + throw new Error('Conexión usb no detectada, por favor verifique el cable.'); + } + if (recolector.status() === false && APP.Configuracion.Run === 1) { + APP.Configuracion.Run = 0; + throw new Error('Conexión usb no detectada, se desconectó en funcionamiento.'); + } + } + } catch (ex) { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|EXCEP|Información de la excepcion: -> ' + ex + ''); + APP.Configuracion.Errores = 'EXCEP: Información de la excepcion: -> ' + ex; + var tiempo = (APP.Configuracion.TiempoMaximo + APP.Configuracion.TiempoContinuo) * 1000; + APP.Configuracion.TiempoFueraDeLinea += tiempo; + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|EXCEP|Se espera ' + (tiempo / 1000) + ' segundos y se prueba conectar nuevamente ....'); + APP.Configuracion.IdsSetTimeouts.push(setTimeout(APP.Conectar, tiempo)); + tiempo=null; + } + }, + // Metodo para comprobar el errores. + CompruebaError: function () { + // se comprueba si ya existe otra excepcion en memoria + if (process.listeners('uncaughtException').length === 0) { + process.on('uncaughtException', function (err) { + APP.Configuracion.RunTime = 0; // Se para el recolector + APP.LimpiarM(); + APP.Configuracion.Repeticiones = 0; + var tiempo = (APP.Configuracion.TiempoMaximo + APP.Configuracion.TiempoContinuo) * 1000; + APP.Configuracion.TiempoFueraDeLinea += tiempo; + APP.Configuracion.Errores = err; + if ((configGeneralEMA.ConfEmail.ActivarCorreos === true) && ((APP.Configuracion.TiempoFueraDeLinea > (APP.Configuracion.TiempoMaximoFueraDeLinea * 1000)) || ((APP.Configuracion.TiempoFueraDeLinea - tiempo) < 1))) { + if ((APP.Configuracion.TiempoFueraDeLinea - tiempo) > 1) { + APP.Configuracion.TiempoMaximoFueraDeLinea = APP.Configuracion.TiempoMaximoFueraDeLinea * 2; + } + APP.RegistrarLog('1|MAIL|Se envio correo notificando que la estacion ' + configGeneralEMA.ConfGeneral.NombreEstacion + ' se encuentra fuera de linea por mas de: ' + (APP.Configuracion.TiempoFueraDeLinea / 1000) + 's o ' + (APP.Configuracion.TiempoFueraDeLinea / 1000 / 60).toFixed(2) + ' minutos'); + } + if (APP.Configuracion.debug > -1) APP.RegistrarLog('1|ERROR|' + err + '.'); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('1|ERROR|Se espera ' + (tiempo / 1000) + ' segundos ( Tiempo fuera de linea: ' + (APP.Configuracion.TiempoFueraDeLinea / 1000) + 's o ' + (APP.Configuracion.TiempoFueraDeLinea / 1000 / 60).toFixed(2) + ' minutos), luego se intenta iniciar el recolector.'); + APP.Configuracion.IdsSetTimeouts.push(setTimeout(APP.Conectar, tiempo)); + tiempo = null; + }); + } + }, + + VerificarTanqueDePendientes: function (red) { // REGISTROS PENDIENTES DE ENVIAR (Solo redes Ema Center) + if (APP.Configuracion.BanderaPendientes === 0) { // Pregunto si no esta destanqueando + APP.Configuracion.TanquePendiente = []; + APP.Configuracion.BanderaPendientes = 1; + if (APP.Configuracion.debug > 4) APP.RegistrarLog('3|PENDIENTE|Verificando el Tanque de Pendientes.'); + try { + fs.readFile('./logs/TanquePendientes.log', { + encoding: 'utf8', + autoClose: true + }, function (err, data) { + try { + if (err) { + APP.RegistrarLog('1|ERROR: Intentando destanquear los registros prendientes:'); + APP.Configuracion.BanderaPendientes = 0; + } + if (data.length < 10) { + APP.Configuracion.CantidadPendientes = 0; + APP.Configuracion.BanderaPendientes = 0; + if (APP.Configuracion.debug > 2) APP.RegistrarLog('3|PENDIENTE|Tanque PENDIENTES vacio.'); + } else { + Guardar = []; + var EnviarPendientes = []; + var Pendientes = JSON.parse(data); + var CantRegistros = Pendientes.length; + var intentos = 0; + APP.Configuracion.CantidadPendientes = CantRegistros; + if (APP.Configuracion.debug > 4) APP.RegistrarLog('3|PENDIENTE|Cantidad Registros en Pendientes: ' + CantRegistros); + for (var i = 0, t = CantRegistros; i < t; ++i) { + EnviarPendientes[0] = [Pendientes[i].TipoRed, Pendientes[i].Usuario, Pendientes[i].Password, Pendientes[i].Server, Pendientes[i].Puerto, Pendientes[i].Ruta, Pendientes[i].Llave_W, Pendientes[i].Nombre, 'PENDIENTE']; + EnviarPendientes[1] = Pendientes[i].registro; + EnviarPendientes[2] = Pendientes[i].idRed; + if ((red === Pendientes[i].idRed) && intentos < 3) { // Pregunto si la red online es la del registro en tanque y solo envio 3 registros pendientes + intentos = intentos + 1; + Redes.EviarRedesMeteorologicas(versionEMA, EnviarPendientes, function (red, estadored, errorRedes, idRed, registro) { + var RegistroEnviado = JSON.parse(registro); + if (estadored === 'ERROR') { // si falla el destanqueo + if (APP.Configuracion.debug > 2) APP.RegistrarLog('3|PENDIENTE|Error no se pudo publicar la Red : ' + red + ' - Estado:' + estadored); + var Pendiente = { + idRed: RegistroEnviado[2], + TipoRed: RegistroEnviado[0][0], + Usuario: RegistroEnviado[0][1], + Password: RegistroEnviado[0][2], + Server: RegistroEnviado[0][3], + Puerto: RegistroEnviado[0][4], + Ruta: RegistroEnviado[0][5], + Llave_W: RegistroEnviado[0][6], + Nombre: RegistroEnviado[0][7], + registro: RegistroEnviado[1] + }; + APP.Configuracion.TanquePendiente.push(Pendiente); + Pendiente = null; + } else { // si es correcto, tiene que borrar el registro ya enviado + APP.Configuracion.CantidadPendientes = APP.Configuracion.CantidadPendientes - 1; + if (APP.Configuracion.CantidadPendientes < 0) { + APP.Configuracion.CantidadPendientes = 0; + } + APP.RegistrarLog('0|PENDIENTE_PUB|Fecha Registro:' + RegistroEnviado[1].fecha + ' - Red Publicada: ' + red + ' - Estado:' + estadored); + } + }); // CALLBACK ENVIAR RED + } else { + APP.Configuracion.TanquePendiente.push(Pendientes[i]); + } + } + APP.Configuracion.BanderaPendientes = 0; + APP.Guardar_Pendientes('', false); + EnviarPendientes = null; + } + } catch (ex) { // si hay un error en el archivo tanque de pendiente se blanquea y se vuelve a llamar la misma. + if (APP.Configuracion.debug > 0) APP.RegistrarLog('1|ERROR|Tanque Pendientes corrupto.Se blanqueo el tanque diario para depurar el error. 2: ' + ex); + APP.Configuracion.TanquePendiente = []; + APP.Configuracion.BanderaPendientes = 0; + fs.writeFile('./logs/TanquePendientes.log', JSON.stringify(APP.Configuracion.TanquePendiente, null, 4), { + encoding: 'utf8', + autoClose: true + }, function (err) { + if (err) { + APP.RegistrarLog('1|ERROR: Guardando registro de prendientes de Ema Center en archivo :' + err); + } + }); + } + }); + } catch (ex) { // si hay un error en el archivo tanque de pendiente se blanquea y se vuelve a llamar la misma. + if (APP.Configuracion.debug > 0) APP.RegistrarLog('1|ERROR|Tanque Pendientes corrupto.Se blanqueo el tanque diario para depurar el error. 1: ' +ex); + APP.Configuracion.TanquePendiente = []; + fs.writeFile('./logs/TanquePendientes.log', JSON.stringify([], null, 4), { + encoding: 'utf8', + autoClose: true + }, function (err) { + if (err) { + APP.RegistrarLog('1|ERROR: Guardando registro de prendientes de Ema Center en archivo :' + err); + } + }); + } + } + }, + + Guardar_Pendientes: function (Datos, guardar) { + if (APP.Configuracion.BanderaPendientes === 0) { // Pregunto si no esta destanqueando + try { + if (guardar === true) { + var pendienteCompleto = null; + var TP_temp = fs.readFileSync('./logs/TanquePendientes.log', 'utf8'); + APP.Configuracion.CantidadPendientes = APP.Configuracion.CantidadPendientes + 1; + var pendienteCompleto = JSON.parse(TP_temp); + for (var i = 0, t = Datos.length; i < t; ++i) {pendienteCompleto.push(Datos[i]);} + APP.Configuracion.CantidadPendientes = pendienteCompleto.length; + fs.writeFile('./logs/TanquePendientes.log', JSON.stringify(pendienteCompleto, null, 4), { + encoding: 'utf8', + autoClose: true + }, function (err) { + if (err) { + APP.RegistrarLog('1|ERROR: Guardando registro de prendientes de Ema Center en archivo :' + err); + } + }); + } else { + fs.writeFile('./logs/TanquePendientes.log',JSON.stringify(APP.Configuracion.TanquePendiente, null, 4), { + encoding: 'utf8', + autoClose: true + }, function (err) { + if (err) { + APP.RegistrarLog('1|ERROR: Guardando registro de prendientes de Ema Center en archivo :' + err); + } + }); + } + } catch (ex) { // si hay un error en el archivo tanque de pendiente se blanquea y se vuelve a llamar la misma. + if (APP.Configuracion.debug > 0) APP.RegistrarLog('1|ERROR|Tanque Pendientes corrupto.Se blanqueo el tanque diario para depurar el error. 3:'+ex); + APP.Configuracion.BanderaPendientes = 0; + APP.Configuracion.TanquePendiente = []; + APP.Guardar_Pendientes( '', false); + } + } + }, + // Metodo para publicar en redes meteorologicas + Publicar_en_Redes: function () { + var Publicar = configGeneralEMA.ConfPublicador; + var Cantidad = Publicar.length; + var UltimoRegistro = APP.Configuracion.UltimoRegistro; + var Enviar = []; + if (typeof UltimoRegistro !== 'undefined' && UltimoRegistro !== '') { + var RegistroPublicado = ''; + for (var i = 0, t = Cantidad; i < t; ++i) { + if (Publicar[i].Publicar === true) { + UltimoRegistro.tanque = false; + Enviar[0] = [Publicar[i].TipoRed, Publicar[i].Usuario, Publicar[i].Password, Publicar[i].Server, Publicar[i].Puerto, Publicar[i].Ruta, Publicar[i].Llave_W, Publicar[i].Nombre]; + Enviar[1] = UltimoRegistro; + Enviar[2] = i; + Redes.EviarRedesMeteorologicas(versionEMA, Enviar, function (red, estadored, errorRedes, idRed, registro) { + var RegistroEnviado = JSON.parse(registro); + // APP.RegistrarLog(RegistroEnviado); + if (estadored === 'ERROR') { // Si hay error en publicar la red + var fechaanterior = ''; + if (typeof APP.Configuracion.UltimoPublicado[idRed] === 'undefined') { + fechaanterior = '00/00/0000 00:00:00'; + } else { + fechaanterior = APP.Configuracion.UltimoPublicado[idRed].fecha; + } + RegistroPublicado = { + "red": red, + "estado": false, + "fecha": fechaanterior, + "error": errorRedes + }; + APP.Configuracion.UltimoPublicado[idRed] = RegistroPublicado; + if (APP.Configuracion.debug > 2) APP.RegistrarLog('3|RED|Red No Publicada: ' + red + ' - Estado:' + estadored + ' ' + errorRedes); + if ((red === 'emacenter') || (red === 'emacentergugler')) { + APP.RegistrarLog('0|PENDIENTE_ALM|Se almaceno en el tanque de pendientes red EmaCenter: ' + RegistroEnviado[0][7]); + RegistroEnviado[1].tanque = true; + var PendienteTemp = { + idRed: RegistroEnviado[2], + TipoRed: RegistroEnviado[0][0], + Usuario: RegistroEnviado[0][1], + Password: RegistroEnviado[0][2], + Server: RegistroEnviado[0][3], + Puerto: RegistroEnviado[0][4], + Ruta: RegistroEnviado[0][5], + Llave_W: RegistroEnviado[0][6], + Nombre: RegistroEnviado[0][7], + registro: RegistroEnviado[1] + }; + APP.Configuracion.tempAlmacenadoPendientes.push(PendienteTemp); + } + } else { // Si se publico correctamente + if (((red === 'emacenter' || red === 'emacentergugler')) && ((APP.Configuracion.CantidadPendientes > 0) || (APP.Configuracion.Repeticiones < 3))) { + APP.VerificarTanqueDePendientes(idRed); + } // verifica el tanque de redes Ema Libre Center Solamente + + if (estadored === 430) { + RegistroPublicado = { + "red": red, + "estado": "No enviado", + "fecha": errorRedes, + "error": "No Enviado" + }; + estadored = 'No Enviado'; + }else{ + + if (estadored === 429) { + RegistroPublicado = { + "red": red, + "estado": "Esperar", + "fecha": errorRedes, + "error": "Red Congestionada" + }; + estadored = 'Congestionada'; + } else { + RegistroPublicado = { + "red": red, + "estado": true, + "fecha": RegistroEnviado[1].fecha, + "error": "-" + }; + } + } + APP.Configuracion.UltimoPublicado[idRed] = RegistroPublicado; + if (APP.Configuracion.debug > 2) APP.RegistrarLog('3|RED|Red Publicada: ' + red + ' - Estado:' + estadored); + } + }); // CALLBACK ENVIAR RED + } else { + if (typeof APP.Configuracion.UltimoPublicado[i] !== 'undefined') { + RegistroPublicado = { + "red": APP.Configuracion.UltimoPublicado[i].red, + "estado": false, + "fecha": APP.Configuracion.UltimoPublicado[i].fecha, + "error": "Detenido" + }; + APP.Configuracion.UltimoPublicado[i] = RegistroPublicado; + } + } + } + if(APP.Configuracion.tempAlmacenadoPendientes.length > 0){APP.Guardar_Pendientes(APP.Configuracion.tempAlmacenadoPendientes, true);} + APP.Configuracion.tempAlmacenadoPendientes = []; + // SE eliminan las variables + Publicar = null; + Cantidad = null; + RegistroPublicado = null; + RegistroEnviado = null; + UltimoRegistro = null; + Enviar = null; + } + }, + + // Metodo para obtener datos de EMA CENTER en modo visor por llave de lectura + + Visor: function (cant, callback) { + var http = require('https'); + var timeout = 5000; + var ServidorEMACENTER = { + hostname: 'emacenter.gugler.com.ar', + port: 443, + path: '/api/get/' + configGeneralEMA.ConfGeneral.Llave_R + '/?cant=' + cant, + method: 'GET' + }; + if (typeof callback !== 'function') callback = function () {}; + if (APP.Configuracion.debug > 7) APP.RegistrarLog('8|VISOR|Buscando un registro en EMACENTER(' + ServidorEMACENTER.hostname + ')...'); + var request = http.request(ServidorEMACENTER, function (response) { + if (response.statusCode === 200) { // RESPUESTA HTML Y COMPARA + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + response.on('end', function () { + var result = message.trim(); + var Respuesta = JSON.parse(result); + // Se verifica la Respuesta + // APP.RegistrarLog(Respuesta); + if (typeof Respuesta.error === 'undefined') { + if (APP.Configuracion.debug > 5) APP.RegistrarLog('6|VISOR|Registro obtenido de ' + Respuesta.modelo + ' de Fecha: ' + Respuesta.registros[0].fecha); + callback(null, Respuesta); + } else { + if (APP.Configuracion.debug > 5) APP.RegistrarLog('6|ERROR|Registro con algun error.'); + callback(Respuesta.error, null); + } + }); + } else { + var respuesta = 'Codigo: ' + response.statusCode; + if (APP.Configuracion.debug > 5) APP.RegistrarLog('6|ERROR|No se pudo obtener el registro (Modo Visor). ' + respuesta); + callback(respuesta, null); + } + }); + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + if (APP.Configuracion.debug > 5) APP.RegistrarLog('6|ERROR|TimeOut cuando se intenta obtener el registro (Modo Visor). Codigo: ' + request.statusCode); + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + request.end(); + }, + + // Metodo para el registro de lecturas obtenidas + Registro_Diario: function (Datos,Cambios,Cambio) { + // Leo El archivo de Tanque diario + var LLuviaAcumuladaTotal = 0; + var LLuviaAcumuladaDia = 0; + var LLuviaAcumuladaHora = 99999999; + var LluviaActual = 0; + var LLuviaAcumuladaMinutos = 99999999; + var luxerintencidad1hs = 0; + var tempIntMinDia = 99; + var tempIntMaxDia = -99; + var humIntMaxDia = -99; + var humIntMinDia = 99; + var tempExtMinDia = 99; + var tempExtMaxDia = -99; + var humExtMaxDia = -99; + var humExtMinDia = 99; + var puntoDeRocioMinDia = 99; + var puntoDeRocioMaxDia = -99; + var luxerIntencidadMinDia = 999999; + var luxerIntencidadMaxDia = -999999; + var luxerUvMinDia = 99; + var luxerUvMaxDia = -99; + var presionRelativaMinDia = 999999; + var presionRelativaMaxDia = -999999; + var vientoDireccionPromDia = 0; + var CantidadV = 0; + var vientoVelocidadMaxDia = -999999; + var vientoRafagasMaxDia = -999999; + fs.readFile('./logs/registro_diario.log', { + encoding: 'utf8', + autoClose: true + }, (err, data) => { + var Guardar = []; + if (err) { + if (APP.Configuracion.debug > 0) APP.RegistrarLog('1|ERROR|Tanque diario corrupto.Se blanqueo el tanque diario para depurar el error.'); + APP.Guardar_Diario(Guardar); + } else { + var DepurarLog = false; + if (data.length < 10) { + if (APP.Configuracion.debug > 2) APP.RegistrarLog('3|ARCHIVO|Tanque diario vacio.'); + } else { + try { + var RegistroDiario = JSON.parse(data); + var CantRegistros = RegistroDiario.length; + if (APP.Configuracion.debug > 4) APP.RegistrarLog('5|ARCHIVO|Cantidad registros diarios: ' + CantRegistros); + var RegistroNuevoDia = Datos[0].substring(0, 2); + var RegistroNuevoHora = Datos[0].substring(11, 13); + var RegistroNuevoMinuto = Datos[0].substring(14, 15); + LLuviaAcumuladaTotal = Datos[14]; + LLuviaAcumuladaDia = LLuviaAcumuladaTotal - RegistroDiario[0].lluvia_acumulado_total; + for (var j = 0; j < CantRegistros; j++) { // Comprueba si no cambio de dia + var Dia = RegistroDiario[j].fecha.substring(0, 2); + var Hora = RegistroDiario[j].fecha.substring(11, 13); + var Min = RegistroDiario[j].fecha.substring(14, 15); + if (Dia === RegistroNuevoDia) { + // Se calcula los max y min diarios (ej:terperatura y humedad) + if (RegistroDiario[j].temperatura_interna > parseFloat(tempIntMaxDia)) { + tempIntMaxDia = RegistroDiario[j].temperatura_interna; + } + if (RegistroDiario[j].temperatura_interna < parseFloat(tempIntMinDia)) { + tempIntMinDia = RegistroDiario[j].temperatura_interna; + } + if (RegistroDiario[j].humedad_interna > parseFloat(humIntMaxDia)) { + humIntMaxDia = RegistroDiario[j].humedad_interna; + } + if (RegistroDiario[j].humedad_interna < parseFloat(humIntMinDia)) { + humIntMinDia = RegistroDiario[j].humedad_interna; + } + if (RegistroDiario[j].temperatura_externa > parseFloat(tempExtMaxDia)) { + tempExtMaxDia = RegistroDiario[j].temperatura_externa; + } + if (RegistroDiario[j].temperatura_externa < parseFloat(tempExtMinDia)) { + tempExtMinDia = RegistroDiario[j].temperatura_externa; + } + if (RegistroDiario[j].humedad_externa > parseFloat(humExtMaxDia)) { + humExtMaxDia = RegistroDiario[j].humedad_externa; + } + if (RegistroDiario[j].humedad_externa < parseFloat(humExtMinDia)) { + humExtMinDia = RegistroDiario[j].humedad_externa; + } + if (RegistroDiario[j].punto_de_rocio > parseFloat(puntoDeRocioMaxDia)) { + puntoDeRocioMaxDia = RegistroDiario[j].punto_de_rocio; + } + if (RegistroDiario[j].punto_de_rocio < parseFloat(puntoDeRocioMinDia)) { + puntoDeRocioMinDia = RegistroDiario[j].punto_de_rocio; + } + if (RegistroDiario[j].presion_relativa > parseFloat(presionRelativaMaxDia)) { + presionRelativaMaxDia = RegistroDiario[j].presion_relativa; + } + if (RegistroDiario[j].presion_relativa < parseFloat(presionRelativaMinDia)) { + presionRelativaMinDia = RegistroDiario[j].presion_relativa; + } + if (RegistroDiario[j].viento_velocidad > parseFloat(vientoVelocidadMaxDia)) { + vientoVelocidadMaxDia = RegistroDiario[j].viento_velocidad; + } + if (RegistroDiario[j].viento_rafagas > parseFloat(vientoRafagasMaxDia)) { + vientoRafagasMaxDia = RegistroDiario[j].viento_rafagas; + } + // Solo si existe sensor UV y LUX + if ((RegistroDiario[j].luxer_intencidad != null) || (RegistroDiario[j].luxer_intencidad != null)) { + if (RegistroDiario[j].luxer_intencidad > parseFloat(luxerIntencidadMaxDia)) { + luxerIntencidadMaxDia = RegistroDiario[j].luxer_intencidad; + } + if (RegistroDiario[j].luxer_intencidad < parseFloat(luxerIntencidadMinDia)) { + luxerIntencidadMinDia = RegistroDiario[j].luxer_intencidad; + } + if (RegistroDiario[j].luxer_uv > parseFloat(luxerUvMaxDia)) { + luxerUvMaxDia = RegistroDiario[j].luxer_uv; + } + if (RegistroDiario[j].luxer_uv < parseFloat(luxerUvMinDia)) { + luxerUvMinDia = RegistroDiario[j].luxer_uv; + } + } + vientoDireccionPromDia += RegistroDiario[j].viento_direccion; + CantidadV++; + if (Hora === RegistroNuevoHora) { + // Se calcula la lluvia acumulada hora y actual + if (RegistroDiario[j].lluvia_acumulado_total < LLuviaAcumuladaHora) { + LLuviaAcumuladaHora = RegistroDiario[j].lluvia_acumulado_total; + luxerintencidad1hs = RegistroDiario[j].luxer_intencidad; + } + if (Min === RegistroNuevoMinuto) { + if (RegistroDiario[j].lluvia_acumulado_total < LLuviaAcumuladaMinutos) { + LLuviaAcumuladaMinutos = RegistroDiario[j].lluvia_acumulado_total; + } + } + } + Guardar.push(RegistroDiario[j]); + } else { + DepurarLog = true; + } + } + vientoDireccionPromDia = vientoDireccionPromDia / CantidadV; + RegistroDiario = null; + } catch (ex) { // si hay un error en el archivo registro_diario se blanquea y se vuelve a llamar la misma. + if (APP.Configuracion.debug > 0) APP.RegistrarLog('1|ERROR|Tanque diario corrupto.Se blanqueo el tanque diario para depurar el error.'); + Guardar = []; + APP.Guardar_Diario(Guardar); + } + } + // Se depurar el registro de logs + if (DepurarLog) { + APP.RegistrarLog('6|ARCHIVO|Depurando archivo de logs.', true); + } + // REGISTRO ACTUAL + LLuviaAcumuladaHora = Datos[14] - LLuviaAcumuladaHora; + LLuviaAcumuladaMinutos = Datos[14] - LLuviaAcumuladaMinutos; + if (tempIntMaxDia < -90) { tempIntMaxDia = 'S/D'; } + if (humIntMaxDia < -90) { humIntMaxDia = 'S/D'; } + if (tempIntMinDia > 90) { tempIntMinDia = 'S/D'; } + if (humIntMinDia > 90) { humIntMinDia = 'S/D'; } + if (tempExtMaxDia < -90) { tempExtMaxDia = 'S/D'; } + if (humExtMaxDia < -90) { humExtMaxDia = 'S/D'; } + if (tempExtMinDia > 90) { tempExtMinDia = 'S/D'; } + if (humExtMinDia > 90) { humExtMinDia = 'S/D'; } + if (puntoDeRocioMinDia > 90) { puntoDeRocioMinDia = 'S/D'; } + if (puntoDeRocioMaxDia < -90) { puntoDeRocioMaxDia = 'S/D'; } + if (luxerIntencidadMinDia > 900000) { luxerIntencidadMinDia = 'S/D'; } + if (luxerIntencidadMaxDia < -900000) { luxerIntencidadMaxDia = 'S/D'; } + if (luxerUvMinDia > 90) { luxerUvMinDia = 'S/D'; } + if (luxerUvMaxDia < -90) { luxerUvMaxDia = 'S/D'; } + if (presionRelativaMinDia > 900000) { presionRelativaMinDia = 'S/D'; } + if (presionRelativaMaxDia < -900000) { presionRelativaMaxDia = 'S/D'; } + if (vientoVelocidadMaxDia < -900000) { vientoVelocidadMaxDia = 'S/D'; } + if (vientoRafagasMaxDia < -900000) { vientoRafagasMaxDia = 'S/D'; } + if (LLuviaAcumuladaMinutos > 0) { LluviaActual = LLuviaAcumuladaMinutos; } else { LLuviaAcumuladaMinutos = 0; LluviaActual = 0; } + if (LLuviaAcumuladaHora < 0) { LLuviaAcumuladaHora = 0; } + if (LLuviaAcumuladaDia < 0) { LLuviaAcumuladaDia = 0; } + if (APP.Configuracion.debug > 4) APP.RegistrarLog('5|REGISTRO|Calculado - Lluvia Hora: ' + LLuviaAcumuladaHora.toFixed(2)); + if (APP.Configuracion.debug > 4) APP.RegistrarLog('5|REGISTRO|Calculado - Lluvia Actual: ' + LLuviaAcumuladaMinutos.toFixed(2)); + if (APP.Configuracion.debug > 4) APP.RegistrarLog('5|REGISTRO|Calculado - Lluvia Dia: ' + LLuviaAcumuladaDia.toFixed(2)); + + var RegistroJSON = { + fecha: Datos[0], + fechaISO: Datos[1], + fechaUTC: Datos[16], + temperatura_externa: Datos[2], + temperatura_interna: Datos[3], + humedad_externa: Datos[4], + humedad_interna: Datos[5], + punto_de_rocio: parseFloat(Datos[15].toFixed(2)), + luxer_intencidad: Datos[6], + luxer_intencidad_1hs: luxerintencidad1hs, + luxer_uv: Datos[7], + viento_velocidad: parseFloat(Datos[8].toFixed(2)), + viento_rafagas: parseFloat(Datos[9].toFixed(2)), + viento_direccion: Datos[10], + viento_direccion_nombre: Datos[11], + presion_absoluta: Datos[12], + presion_relativa: Datos[13], + lloviendo: parseFloat(LluviaActual.toFixed(2)), + lluvia_acu_hora: parseFloat(LLuviaAcumuladaHora.toFixed(2)), + lluvia_acu_diaria: parseFloat(LLuviaAcumuladaDia.toFixed(2)), + lluvia_acumulado_total: parseFloat(Datos[14].toFixed(2)), + temperatura_interna_max_dia: tempIntMaxDia, + temperatura_interna_min_dia: tempIntMinDia, + humedad_interna_max_dia: humIntMaxDia, + humedad_interna_min_dia: humIntMinDia, + temperatura_externa_max_dia: tempExtMaxDia, + temperatura_externa_min_dia: tempExtMinDia, + humedad_externa_max_dia: humExtMaxDia, + humedad_externa_min_dia: humExtMinDia, + punto_de_rocio_max_dia: puntoDeRocioMaxDia, + punto_de_rocio_min_dia: puntoDeRocioMinDia, + luxer_intencidad_max_dia: luxerIntencidadMaxDia, + luxer_intencidad_min_dia: luxerIntencidadMinDia, + luxer_uv_max_dia: luxerUvMaxDia, + luxer_uv_min_dia: luxerUvMinDia, + presion_relativa_max_dia: presionRelativaMaxDia, + presion_relativa_min_dia: presionRelativaMinDia, + viento_direccion_prom_dia: parseFloat(vientoDireccionPromDia.toFixed(2)), + viento_velocidad_max_dia: vientoVelocidadMaxDia, + viento_rafagas_max_dia: vientoRafagasMaxDia, + estado_sensores: Datos[17], + diferencia: Cambios, + cambio: Cambio, + estado_validacion_ant: APP.Configuracion.Estado_Val_Ant + }; + APP.Configuracion.Estado_Val_Ant = 0; + APP.Configuracion.UltimoRegistro = RegistroJSON; + Guardar.push(RegistroJSON); + APP.Guardar_Diario(Guardar); + RegistroJSON = null; + Guardar = null; + LLuviaAcumuladaTotal = null; + LLuviaAcumuladaDia = null; + LLuviaAcumuladaHora = null; + LluviaActual = null; + LLuviaAcumuladaMinutos = null; + luxerintencidad1hs = null; + tempIntMinDia = null; + tempIntMaxDia = null; + humIntMaxDia = null; + humIntMinDia = null; + tempExtMinDia = null; + tempExtMaxDia = null; + humExtMaxDia = null; + humExtMinDia = null; + puntoDeRocioMinDia = null; + puntoDeRocioMaxDia = null; + luxerIntencidadMinDia = null; + luxerIntencidadMaxDia = null; + luxerUvMinDia = null; + luxerUvMaxDia = null; + presionRelativaMinDia = null; + presionRelativaMaxDia = null; + vientoDireccionPromDia = null; + CantidadV = null; + vientoVelocidadMaxDia = -null; + vientoRafagasMaxDia = null; + } + }); + }, + + // Metodo de ejecucion continua (repite continuamente). + Continuo: function () { + try { + APP.LimpiarM(); + APP.Configuracion.FechaLanzadoTimeout = -99; + if (APP.Configuracion.Run === 1 && APP.Configuracion.RunTime === 1) { + APP.Configuracion.TiempoMaximo = 0; + APP.CompruebaError(); + APP.Configuracion.RepeticionesConError += 1; + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var db = new Date(utc + (3600000 * (APP.Configuracion.utc))); + var minutos = db.getMinutes(); + if (minutos <= 9) { minutos = '0' + minutos; } + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora; } + var mes = db.getMonth() + 1; + if (mes <= 9) { mes = '0' + mes; } + var dia = db.getDate(); + if (dia <= 9) { dia = '0' + dia; } + var segundo = db.getSeconds(); + if (segundo <= 9) { segundo = '0' + segundo; } + var fechac = dia + '/' + mes + '/' + db.getFullYear() + ' ' + hora + ':' + minutos + ':' + segundo; + dia = null; + mes = null; + hora = null; + minutos = null; + segundo = null; + db = null; + utc = null; + d = null; + if (recolector.status() === true) { + if (APP.Configuracion.debug > 7 && APP.Configuracion.Repeticiones > 1) APP.RegistrarLog('8|LECTURA|Inicio Lectura'); + if (APP.Configuracion.debug > 7) APP.RegistrarLog('8|REGISTRO|Estado: online (' + APP.Configuracion.RepeticionesConError + ')'); + if (APP.Configuracion.debug > 7) APP.RegistrarLog('8|REGISTRO|Fecha: ' + fechac); + if (APP.Configuracion.debug > 7) APP.RegistrarLog('8|REGISTRO|Tiempo Recolección: ' + APP.Configuracion.TiempoContinuo); + if (APP.Configuracion.debug > 7) APP.RegistrarLog('8|REGISTRO|Cant. Lect. sin corte: ' + APP.Configuracion.Repeticiones); + //Se busca un registro usb (PROMESA - resultado(registro,cambios, true o false(si hay cambios)) + recolector.Recolectar().then((resultado)=> + { + //APP.RegistrarLog(resultado[1]); + var datosRecolectados = resultado[0]; + if ((APP.Configuracion.RepeticionesConError) > APP.Configuracion.Cantidad_No_Lectura) { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|IMPORTANTE: No se puede leer la EMA por USB. Supero la Cantidad Máxima de No Lectura definida.'); + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|CORE|IMPORTANTE: Supero la Cantidad Máxima de No Lectura definida.'); + throw new Error('NolecturaUSB'); + } + if (typeof datosRecolectados !== 'undefined') + { + // Estado Sensores + APP.Configuracion.EstadoSensores = datosRecolectados[17]; + var Datos = []; + Datos = ['validar', datosRecolectados,resultado[1],resultado[2]]; + // Se pasa el registro al validador + Validador.Registros(Datos, function (errorvalidador, estadovalidador) + { + if (estadovalidador === true) { + APP.Configuracion.Repeticiones += 1; + APP.Configuracion.RepeticionesConError = 0; + APP.Configuracion.TiempoMaximo = 0; + APP.Configuracion.TiempoFueraDeLinea = 0; + APP.Registro_Diario(Datos[1],resultado[1],resultado[2]); + APP.Publicar_en_Redes(); + APP.Configuracion.FechaLanzadoTimeout = Date.now(); + APP.Configuracion.IdsSetTimeouts.push(setTimeout(APP.Continuo, APP.Configuracion.TiempoContinuo * 1000)); + Datos = null; + } else { + APP.Configuracion.Repeticiones = 0; + APP.Configuracion.Estado_Val_Ant = errorvalidador[0]; + if (APP.Configuracion.debug > 0) APP.RegistrarLog('0|VALIDADOR|Datos recolectados incorrectos: ' + errorvalidador[1]); + APP.Configuracion.FechaLanzadoTimeout = Date.now(); + APP.Configuracion.IdsSetTimeouts.push(setTimeout(APP.Continuo, APP.Configuracion.TiempoContinuo * 1000)); + Datos = null; + } + }); + Datos = null; + } else { + APP.RegistrarLog('0|CORE|Sincronizando.'); + APP.Configuracion.Repeticiones = 0; + APP.Configuracion.RepeticionesConError = 0; + APP.Configuracion.IdsSetTimeouts.push(setTimeout(APP.Continuo, 1000)); + } + }); + } else { + APP.RegistrarLog('0|CORE|Estación no sincronizada.'); + APP.Configuracion.Repeticiones = 0; + APP.Configuracion.IdsSetTimeouts.push(setTimeout(APP.Continuo, 5000)); + } + } else { + APP.RegistrarLog('0|CORE|Recolector detenido.'); + APP.Configuracion.RunTime = 0; + } + } catch (ex) { + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|EXCEP|Información de la excepción: -> ' + ex + ''); + APP.Configuracion.Errores = 'EXCEP: Información de la excepción: -> ' + ex; + var tiempo = (APP.Configuracion.TiempoMaximo + APP.Configuracion.TiempoContinuo) * 1000; + APP.Configuracion.TiempoFueraDeLinea += tiempo; + if (APP.Configuracion.debug > -1) APP.RegistrarLog('0|EXCEP|Se espera ' + (tiempo / 1000) + ' segundos y se prueba conectar nuevamente ....'); + APP.Configuracion.IdsSetTimeouts.push(setTimeout(APP.Conectar, tiempo)); + tiempo = null; + } + } +}; + +// termina el Objeto/Clase +// Control de Ejecucion de Consola +var parametros = process.argv; // Se lee el parametro +if (parametros.indexOf('console') === -1) { + // No se realiza nada ya que se tiene que iniciar desde el aplicativo + APP.RegistrarLog('0|CORE|Se inició el aplicativo EmaLibre gráfico o Web.'); +} else { + APP.Conectar(); + APP.RegistrarLog('0|CORE|Iniciando Ema Libre en Modo Consola!!!.'); +} + diff --git a/src/core/img/icono_app.png b/src/core/img/icono_app.png new file mode 100644 index 0000000..2017b2c Binary files /dev/null and b/src/core/img/icono_app.png differ diff --git a/src/core/mail.js b/src/core/mail.js new file mode 100644 index 0000000..8125930 --- /dev/null +++ b/src/core/mail.js @@ -0,0 +1,107 @@ +/** + * Archivo que contiene brinda la funcionadad enviar correo electronico para EMA Libre. + * + * Contiene un conjunto de funciones de envio de correo electronico para EMA. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +/********************************************** + LIBRERIA PARA ENVIAR EMAIL +***********************************************/ + +// Variables Generales +const nodeMailer = require('nodemailer'); // Se incluye la libreria para enviar Correo. + +/*FUNCION AUXILIARES */ + +function RegistrarLog (reg, depurar) { + if (typeof depurar !== 'undefined') { depurar = false; } + // se convierte la fecha a la UTC parametrizada + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var fechaHora = new Date(utc + (3600000 * (C_EMA.ConfGeneral.UTC))); + var horas = fechaHora.getHours(); + var minutos = fechaHora.getMinutes(); + var segundos = fechaHora.getSeconds(); + var mes = fechaHora.getMonth() + 1; + var dia = fechaHora.getDate(); + if (dia <= 9) { dia = '0' + dia; } + if (mes <= 9) { mes = '0' + mes; } + if (horas < 10) { horas = '0' + horas; } + if (minutos < 10) { minutos = '0' + minutos; } + if (segundos < 10) { segundos = '0' + segundos; } + var fecha = dia + '/' + mes + '/' + fechaHora.getFullYear() + ' ' + horas + ':' + minutos + ':' + segundos; + var registrologs = fecha + ' - ' + util.format(reg) + '\n'; + if (depurar) { + // SE DEPURA EL ARCHIVO DE REGISTROS DE LOGS + fs.writeFile('./logs/debug.log', '', { encoding: 'utf8', autoClose: true }, function (err) { + if (err) { RegistrarLog('0|ERROR|Depurando archivo registro de logs :' + err); } + }); + } else { + // GUARDA LOS REGISTROS DE LOGS + fs.appendFile('./logs/debug.log', registrologs, { encoding: 'utf8', autoClose: true }, function (err) { + if (err) { RegistrarLog('0|ERROR|Guardando registro de logs en archivo :' + err); } + }); + } + registrologs=null;fecha=null;dia=null;mes=null;segundos=null;minutos=null;horas=null;fechaHora=null;utc=null;d=null; +} + +module.exports = { + EnviarEmail: function (ConfGeneral, Asunto, Cuerpo) { + // Definimos el transportador + var transportador; + if (ConfGeneral.ConfEmail.Servicio !== 'Manual') { + transportador = nodeMailer.createTransport({ + service: ConfGeneral.ConfEmail.Servicio, + auth: { + user: ConfGeneral.ConfEmail.Usuario, + pass: ConfGeneral.ConfEmail.Password + } + }); + } else { + transportador = nodeMailer.createTransport({ + host: ConfGeneral.ConfEmail.Server, + port: ConfGeneral.ConfEmail.Puerto, + auth: { + user: ConfGeneral.ConfEmail.Usuario, + pass: ConfGeneral.ConfEmail.Password + } + }); + } + // Definimos el cuerpo del correo + var mailOptions = { + from: 'EMA LIBRE - GUGLER', + to: ConfGeneral.ConfEmail.ReceptorEmail, + subject: Asunto, + html: Cuerpo + }; + // Enviamos el email + transportador.sendMail(mailOptions, function (error, info) { + if (error) { + RegistrarLog('1|CORREO| Error en el envio de correo. Verifique los datos de configuración. '); + } else { + RegistrarLog('1|CORREO| Correo electronico enviado correctamente.'); + } + }); + transportador = null;mailOptions=null; + } +}; diff --git a/src/core/monitor.js b/src/core/monitor.js new file mode 100644 index 0000000..81b779c --- /dev/null +++ b/src/core/monitor.js @@ -0,0 +1,143 @@ +/** + * Archivo que contiene brinda la funcionadad de monitorear los registros de EMA Libre. + * + * Contiene funcionen que controlan que se EMA se encuentra registrando correctamente + * en caso contrario reiniciara el equipo (OJO: reinicia el sistema operativo). + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +/********************************************** + LIBRERIA PARA EL MONITOREO +***********************************************/ +const fs = require('fs'); // Libreria fs para el manejo de archivos. +const C_EMA = require('./../conf/ConfiguracionGeneral.js'); // Configuracion General +const util = require('util'); // Utilidades. +const exec = require('child_process').exec; // Require child_process +const Correo = require('./mail.js'); // Envio de correo. + +// FUNCION QUE CONTROLA EL ULTIMO REGISTRO + +const umbral = 10; // tiempo maximo del ultimo registro en minutos antes de reiniciar. +const blucle = 3; // tiempo del blucle de control (cada cuantos minutos controla) +const bluclePrimerControl = 30; // tiempo del blucle del primer control + +/*FUNCION AUXILIARES */ + +function RegistrarLog (reg, depurar) { + if (typeof depurar !== 'undefined') { depurar = false; } + // se convierte la fecha a la UTC parametrizada + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var fechaHora = new Date(utc + (3600000 * (C_EMA.ConfGeneral.UTC))); + var horas = fechaHora.getHours(); + var minutos = fechaHora.getMinutes(); + var segundos = fechaHora.getSeconds(); + var mes = fechaHora.getMonth() + 1; + var dia = fechaHora.getDate(); + if (dia <= 9) { dia = '0' + dia; } + if (mes <= 9) { mes = '0' + mes; } + if (horas < 10) { horas = '0' + horas; } + if (minutos < 10) { minutos = '0' + minutos; } + if (segundos < 10) { segundos = '0' + segundos; } + var fecha = dia + '/' + mes + '/' + fechaHora.getFullYear() + ' ' + horas + ':' + minutos + ':' + segundos; + var registrologs = fecha + ' - ' + util.format(reg) + '\n'; + if (depurar) { + // SE DEPURA EL ARCHIVO DE REGISTROS DE LOGS + fs.writeFile('./logs/debug.log', '', { encoding: 'utf8', autoClose: true }, function (err) { + if (err) { RegistrarLog('0|ERROR|Depurando archivo registro de logs :' + err); } + }); + } else { + // GUARDA LOS REGISTROS DE LOGS + fs.appendFile('./logs/debug.log', registrologs, { encoding: 'utf8', autoClose: true }, function (err) { + if (err) { RegistrarLog('0|ERROR|Guardando registro de logs en archivo :' + err); } + }); + } + registrologs=null;fecha=null;dia=null;mes=null;segundos=null;minutos=null;horas=null;fechaHora=null;utc=null;d=null; + } + + +// Create shutdown function +function shutdown(callback){ + exec('/sbin/shutdown -r now', function(error, stdout, stderr){ callback(stdout); }); +} + + + + /*FUNCION DE CONTROL */ +function controlUltimoRegistro () + { + //Se lee el archivo de registro + fs.readFile('./logs/registro_diario.log', { + encoding: 'utf8', + autoClose: true + }, (err, data) => { + var RegistroDiario = JSON.parse(data); + var CantRegistros = RegistroDiario.length; + //se obtiene el ultimo registro + var fechaUltimo = RegistroDiario[CantRegistros-1].fecha; + // Viene de esta forma: 07/10/2019 20:20:04 + var Dia = fechaUltimo.substring(0, 2); + var Mes = fechaUltimo.substring(3, 5); + var Anio = fechaUltimo.substring(6, 10); + var Hora = fechaUltimo.substring(11, 13); + var Min = fechaUltimo.substring(14, 16); + var Segundos = fechaUltimo.substring(17, 19); + //se obtiene la fecha del ultmo registro como tipo Date + var fechaUltDate = new Date(parseInt(Anio),(parseInt(Mes)-1),parseInt(Dia),parseInt(Hora),parseInt(Min),parseInt(Segundos)).getTime(); + var f = new Date(); + var FechaActual = new Date(f.getFullYear(), f.getMonth(),f.getDate(), f.getHours(),f.getMinutes(),f.getSeconds()).getTime(); + var diferenciaMinutos = 0; + diferenciaMinutos = ((FechaActual - fechaUltDate) / 1000)/60; + // Se compara la diferencia con el umbral establecido en minutos + if(diferenciaMinutos > umbral){ + // Supero el umbral se reinicia + RegistrarLog("0|MONITOR|Supero el umbral. Tiempo: "+diferenciaMinutos.toFixed(2)); + if (C_EMA.ConfEmail.ActivarCorreos === true){ + Correo.EnviarEmail(C_EMA,'EMA Libre - REINICIO AUTOMATICO', 'Estimado/a,

Le informamos que la estación ' + C_EMA.ConfGeneral.NombreEstacion + ' dejó de recolectar datos por '+diferenciaMinutos.toFixed(2)+' minutos, por lo que se reinicio el equipo automáticamente.

Saludos Cordiales.'); + } + // se reinicia el S.O (esperando 5 segundos para que se envie el correo si esta configurado) + setTimeout(function(){reiniciarSO();}, 5000); + }else{ + // Dentro del umbral todo correcto + RegistrarLog("0|MONITOR|Control dentro del umbral. Minutos: "+diferenciaMinutos.toFixed(2)); + setTimeout(function(){controlUltimoRegistro();}, (blucle*60*1000)); + } + }); + + + } + + +//Funcion de Reinicio del S.O + + function reiniciarSO () + { + RegistrarLog("0|MONITOR|Se reinicio el S.O."); + // Reinicia el equipo + shutdown(function(output){ console.log(output);}); + } + +//Se inicia el Monitor luego tiempo definido en el umbral. +setTimeout(function() { RegistrarLog("0|MONITOR|Se inicio el monitor de EMA Libre."); + RegistrarLog("0|MONITOR|Tiempo de control cada "+blucle+" minutos."); + controlUltimoRegistro(); }, (bluclePrimerControl*60*1000)); + diff --git a/src/core/recolector.js b/src/core/recolector.js new file mode 100644 index 0000000..3966f88 --- /dev/null +++ b/src/core/recolector.js @@ -0,0 +1,634 @@ +/** + * Este archivo es parte del proyecto EMA Libre. + * + * Contiene el codigo fuente, parte principal de EMA Libre Carpincho, + * brindando la funcionalidad de recoleccion de datos + * de una estacion USB compatible. + * + * Este archivo, esta basado en el archivo whid.js del proyectos + * (https://github.com/haricotbean/WeatherStation/blob/master/whid.js) + * fue modificado y adaptado a la necesidades del software actual. + * + * La funcion principal de este modulo, es obtener los difrentes datos recolectados + * por los sensores de una estacion USB, y devolver un vector con los mismos, cada X tiempo, + * este tiempo es configurado en forma general desde el archivo de configuracion + * de EMA Libre. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +const util = require('util'); // Utilidades. +const fs = require('fs'); // Libreria fs para el manejo de archivos. +const C_EMA = require('./../conf/ConfiguracionGeneral.js'); // Configuracion General +const parametros = process.argv; // Se lee el parametro +const SO = process.platform; // Se lee la Sistema Operativo ('aix', 'darwin','freebsd','linux','openbsd','sunos','win32') +var Arquitectura = process.arch; // Se lee la arquitectura ('arm', 'arm64', 'ia32', 'mips', 'mipsel', 'ppc', 'ppc64', 's390', 's390x', 'x32', and 'x64'.) +var ModoConsola = 'gui'; // Modo consola o grafico +if (parametros.indexOf('console') === -1) { ModoConsola = 'gui'; } else { ModoConsola = 'console'; } // Modo EMA +var PlataformaFinal = SO + '_' + Arquitectura + '_' + ModoConsola; +var antes=[]; + +function RegistrarLog (reg, depurar) { + if (typeof depurar !== 'undefined') { depurar = false; } + // se convierte la fecha a la UTC parametrizada + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var fechaHora = new Date(utc + (3600000 * (C_EMA.ConfGeneral.UTC))); + var horas = fechaHora.getHours(); + var minutos = fechaHora.getMinutes(); + var segundos = fechaHora.getSeconds(); + var mes = fechaHora.getMonth() + 1; + var dia = fechaHora.getDate(); + if (dia <= 9) { dia = '0' + dia; } + if (mes <= 9) { mes = '0' + mes; } + if (horas < 10) { horas = '0' + horas; } + if (minutos < 10) { minutos = '0' + minutos; } + if (segundos < 10) { segundos = '0' + segundos; } + var fecha = dia + '/' + mes + '/' + fechaHora.getFullYear() + ' ' + horas + ':' + minutos + ':' + segundos; + var registrologs = fecha + ' - ' + util.format(reg) + '\n'; + if (depurar) { + // SE DEPURA EL ARCHIVO DE REGISTROS DE LOGS + fs.writeFile('./logs/debug.log', '', { encoding: 'utf8', autoClose: true }, function (err) { + if (err) { RegistrarLog('0|ERROR|Depurando archivo registro de logs :' + err); } + }); + } else { + // GUARDA LOS REGISTROS DE LOGS + fs.appendFile('./logs/debug.log', registrologs, { encoding: 'utf8', autoClose: true }, function (err) { + if (err) { RegistrarLog('0|ERROR|Guardando registro de logs en archivo :' + err); } + }); + } + registrologs=null;fecha=null;dia=null;mes=null;segundos=null;minutos=null;horas=null;fechaHora=null;utc=null;d=null; +} + +// Se carga el driver USB NODE-HID Segun la plataforma y modalidad + + +try { + RegistrarLog('0|CORE|Buscando Modulo USB para el S.O - ' + PlataformaFinal); + var HID = require('node-hid'); + RegistrarLog("0|CORE|Modulo node-hid cargado correctamente."); +} catch (e) { + RegistrarLog('0|ERROR|No se pudo levantar el modulo node hid para su plataforma. ' + PlataformaFinal); +} + +// CODIGO DEL RECOLECTOR DE DATOS + +module.exports = wusb = { + + conf: { + vid: 0x1941, // USB Vendedor ID + pid: 0x8021, // USB Producto ID + recent: 10, // Cantidad de registros para mantener en la memoria. + plataforma: SO, // Sistema operativo donde se ejecuta + debug: 0, // Debug del recolector + station: [] // Debug del recolector + }, + sincronizado: false, // Sincronizado - al primer registro distinto (true). + recent: [], // Registro reciente + fecha_registro:'', // Fecha del ultimo registro + registro_ant:'', // Registro Anterior + // Dicccionario de acceso a los datos. + _map: { + // rf = Formato de lectura utilizado en buffer circular + 'rf.delay': [0, 'ub'], // Minutos desde la �ltima lectura almacenada + 'rf.hum_in': [1, 'ub'], + 'rf.temp_in': [2, 'ss', 0.1, 1], + 'rf.hum_out': [4, 'ub'], + 'rf.temp_out': [5, 'ss', 0.1, 1], + 'rf.abs_pressure': [7, 'us', 0.1, 1], + 'rf.wind_ave': [9, 'wa', 0.1, 1], // en Metros/Segundo (velocidad media del viento,) + 'rf.wind_gust': [10, 'wg', 0.1, 1], // en Metros/Segundo (r�faga de velocidad del viento) + 'rf.wind_dir': [12, 'ub', 22.5], // Direccion desde el norte + 'rf.rain': [13, 'us', 0.3, 1], // Lluvia Total + 'rf.status': [15, 'bf', ['b1', 'b2', 'b3', 'b4', 'b5', 'lost_sensor_contact', 'rain_overflow', 'b8']], + 'rf.lux': [16, 'luxer', 0.1, 1], // Nuevo registro para luxer. + 'rf.uv': [19, 'ub'], // Nuevo registro para UV. + // fb = fixed block formats + 'fb.read_period': [16, 'ub'], + 'fb.settings_1': [17, 'bf', ['temp_in_F', 'temp_out_F', 'rain_in', + 'bit3', 'bit4', 'pressure_hPa', + 'pressure_inHg', 'pressure_mmHg' + ]], + 'fb.settings_2': [18, 'bf', ['wind_mps', 'wind_kmph', 'wind_knot', + 'wind_mph', 'wind_bft', 'bit5', + 'bit6', 'bit7' + ]], + 'fb.display_1': [19, 'bf', ['pressure_rel', 'wind_gust', 'clock_12hr', + 'date_mdy', 'time_scale_24', 'show_year', + 'show_day_name', 'alarm_time' + ]], + 'fb.display_2': [20, 'bf', ['temp_out_temp', 'temp_out_chill', + 'temp_out_dew', 'rain_hour', 'rain_day', + 'rain_week', 'rain_month', 'rain_total' + ]], + 'fb.alarm_1': [21, 'bf', ['bit0', 'time', 'wind_dir', 'bit3', + 'hum_in_lo', 'hum_in_hi', + 'hum_out_lo', 'hum_out_hi' + ]], + 'fb.alarm_2': [22, 'bf', ['wind_ave', 'wind_gust', + 'rain_hour', 'rain_day', + 'pressure_abs_lo', 'pressure_abs_hi', + 'pressure_rel_lo', 'pressure_rel_hi' + ]], + 'fb.alarm_3': [23, 'bf', ['temp_in_lo', 'temp_in_hi', + 'temp_out_lo', 'temp_out_hi', + 'wind_chill_lo', 'wind_chill_hi', + 'dew_point_lo', 'dew_point_hi' + ]], + 'fb.timezone': [24, 'sb'], + 'fb.unknown_01': [25, 'pb'], + 'fb.data_changed': [26, 'ub'], + 'fb.data_count': [27, 'us'], + 'fb.display_3': [29, 'bf', ['illuminance_fc', 'bit1', 'bit2', 'bit3', + 'bit4', 'bit5', 'bit6', 'bit7' + ]], + 'fb.current_pos': [30, 'us'], + 'fb.rel_pressure': [32, 'us', 0.1, 1], + 'fb.abs_pressure': [34, 'us', 0.1, 1], + 'fb.lux_wm2_coeff': [36, 'us', 0.1], + 'fb.date_time': [43, 'dt'], + NA: [0, 'XX'] + }, + _pad: function (str, n) { + return (' ' + str).slice(n * -1); + }, + // Coleccion de utilidades de conversi�n de datos + _d: { + // Traduccion de Formato de offset en block/offset + 'x': function (offset) { + return [Math.floor(offset / 8), offset % 8]; + }, + 'bc': function (data, blk, i) { + var byte = data[blk][i]; + return ((Math.floor(byte / 16) & 0x0f) * 10) + (byte & 0x0f); + }, + // Tipo: bit field + 'bf': function (data, blk, i, base, prec) { + var map = {}; + var lo = data[blk][i]; + var bits = [1, 2, 4, 8, 16, 32, 64, 128]; + for (var i = 0; i < bits.length && i < base.length; i++) { + map[base[i]] = (lo & bits[i]) > 0; + } + return map; + }, + // Tipo:signed byte + 'sb': function (data, blk, i, base, prec) { + return (data[blk][i] >= 128) ? (128 - data[blk][i]) : data[blk][i]; + }, + // Tipo: plain byte + 'pb': function (data, blk, i) { + return data[blk][i]; + }, + // Tipo: unsigned byte + 'ub': function (data, blk, i, base, prec) { + var res = (data[blk][i] === 0xFF) ? null : data[blk][i]; + if (base) { + res *= base; + } + return (prec) ? Number(res.toFixed(prec)) : res; + }, + // Tipo: signed short + 'ss': function (data, blk, i, base, prec) { + var hb = (i + 1 < 8) ? blk : blk + 1; + var hbi = (i + 1 < 8) ? i + 1 : (7 - i); + var hi = data[hb][hbi]; + var lo = data[blk][i]; + var res = null; + if (lo === 0xFF && hi === 0xFF) return res; + if (hi >= 128) { + res = ((128 - hi) * 256) - lo; + } else { + res = (hi * 256) + lo; + } + if (base) { + res *= base; + } + return (prec) ? Number(res.toFixed(prec)) : res; + }, + // Tipo: unsigned short + 'us': function (data, blk, i, base, prec) { + var hb = (i + 1 < 8) ? blk : blk + 1; + var hbi = (i + 1 < 8) ? i + 1 : (7 - i); + var hi = data[hb][hbi]; + var lo = data[blk][i]; + if (lo === 0xFF && hi === 0xFF) return null; + var res = (hi * 256) + lo; + if (base) { + res *= base; + } + return (prec) ? Number(res.toFixed(prec)) : res; + }, + // formato para lectura de luz:luxer. + 'luxer': function (data, blk, i, base, prec) { + var hb = (i + 1 < 8) ? blk : blk + 1; + var hbi = (i + 1 < 8) ? i + 2 : (7 - i); + var hi = data[hb][hbi]; + var med = data[hb][(hbi - 1)]; + var lo = data[blk][i]; + if (lo === 0xFF && hi === 0xFF) return null; + var res = (hi * 65536) + (med * 256) + (lo); + if (base) { + res *= base; + } + return (prec) ? Number(res.toFixed(prec)) : res; + }, + + p: function (v, l) { + return ('00000' + v).slice(-l); + }, + 'wa': function (data, blk, i, base, prec) { + var lo = data[blk][i]; + var hi = (data[blk][i + 2] & 0x0f) << 8; + var res = (hi + lo) * base; + return (prec) ? Number(res.toFixed(prec)) : res; + }, + 'wg': function (data, blk, i, base, prec) { + var lo = data[blk][i]; + var hi = (data[blk][i + 1] & 0xf0) << 4; + var res = (hi + lo) * base; + return (prec) ? Number(res.toFixed(prec)) : res; + }, + // Tipo: date time + 'dt': function (data, blk, i, base, prec) { + var yy = wusb._d.bc(data, blk, i); + var mm = wusb._d.bc(data, blk, i + 1); + var dd = wusb._d.bc(data, blk, i + 2); + var hr = wusb._d.bc(data, blk, i + 3); + var mi = wusb._d.bc(data, blk, i + 4); + var ss = wusb._d.bc(data, blk, i + 5); + return '20' + wusb._d.p(yy, 2) + '-' + wusb._d.p(mm, 2) + '-' + wusb._d.p(dd, 2) + ' ' + wusb._d.p(hr, 2) + ':' + wusb._d.p(mi, 2)+ ':' + wusb._d.p(ss, 2); + } + }, + // funcion de conversiones de datos . + d: function (offset, format, base, prec) { + if (offset < this.length * 8) { + var i = wusb._d.x(offset); + if (wusb._d[format]) { + return wusb._d[format](this, i[0], i[1], base, prec); + } else { + // si no se ha registrado convertidor volcar una representacion de la cadena + return [offset, '|', i[0], i[1], '>>', this[i[0]][i[1]], '0x' + Number(this[i[0]][i[1]]).toString(16).toUpperCase()].join(','); + } + } + }, + f: function (data, name) { + var ans = 'NA'; + if (wusb._map[name]) { + ans = wusb.d.apply(data, wusb._map[name]); + } + return ans; + }, + decode: function (data, list_or_bool) { + var block = {}; + if (list_or_bool.length) { + // --- + } else { + // --- + var pre = (list_or_bool) ? 'fb.' : 'rf.'; + + for (var key in wusb._map) { + if (key.indexOf(pre) === 0) { + + block[key] = wusb.f(data, key); + } + } + } + return block; + + + }, + open: function () { + try { + //wusb.conf.plataforma = OS; + var devices = HID.devices(); + var device = null; + for (var d in devices) { + if (devices[d].vendorId === wusb.conf.vid && devices[d].productId === wusb.conf.pid) { + return new HID.HID(devices[d].path); + } + } + } catch (e) { + RegistrarLog('2|ERROR|Problema al intentar conectar el USB, desconecte y conecte nuevamente el USB.'); + APP.Configuracion.Errores = "Problema al intentar conectar el USB, desconecte y conecte nuevamente el USB."; + //throw "Problemas con el USB"; + return false; + } + return device; + }, + + status: function () { + try { + var devices = null + var device = null; + devices = HID.devices(); + for (var d in devices) + { if (devices[d].vendorId === wusb.conf.vid && devices[d].productId === wusb.conf.pid) { return true; } } + return false; + } catch (e) { + throw "Error al buscar dispositivos con node-hid. "+e; + } + }, + + // Devuelve un array + range: function (lo, hi, inc) { + var v = []; + var max = (Math.floor(hi / 8) + 1) * 8; + for (var c = lo; c < max; c += inc) { + v.push(c); + } + return v; + }, + // Construir un bloque de comandos para enviar a un dispositivo USB + cmd: function (address) { + var hi = Math.floor(address / 256); + var lo = address % 256; + if (wusb.conf.plataforma === 'win32' || wusb.conf.plataforma === 'win64') { return [0x00, 0xA1, hi, lo, 0x20, 0xA1, hi, lo, 0x20]; } // se le agrega un 0 antes + else { return [0xA1, hi, lo, 0x20, 0xA1, hi, lo, 0x20]; } + }, + // Funcion --- + removeListeners: function (d, f) { + var listeners = station.listeners(f); + if (listeners.length > 0) { + for (var l = 0; l < listeners.length; l++) { + d.removeListener(f, listeners[l]); + } + } + }, + // Configurar una transferencia masiva y disparar una funcion cuando se completa + getRange: function (station, to, from, finished) { + var locs = wusb.range(to, from, 32); + var count = -1; + var buf = []; + // Solicitar el siguiente bloque de datos enviados por el dispositivo USB + var _next = function () { + if (locs.length > 0) { + var addr = locs.shift(); + var cmd = wusb.cmd(addr); + count = 4; // El n�mero de bytes en la respuesta esperada del dispositivo + station.write(cmd); + // RegistrarLog('2|RECOLECTOR|DATOS PUROS: ' + cmd); + } else { + // Aseg�rese de que todos los lister hayan sido eliminado. + wusb.removeListeners(station, 'data'); + finished(buf); + } + }; + // Recoger los datos y almacenarlos + var _chunk = function (data) { + buf.push(data); + count--; + if (count === 0) { + _next(); + } + }; + // Aseg�rese de eliminar todos los lister + wusb.removeListeners(station, 'data'); + station.on('data', _chunk); + _next(); + }, + diferencia: function(obj1, obj2) { + const result = {}; + if (Object.is(obj1, obj2)) { + return undefined; + } + if (!obj2 || typeof obj2 !== 'object') { + return obj2; + } + Object.keys(obj1 || {}).concat(Object.keys(obj2 || {})).forEach(key => { + if(obj2[key] !== obj1[key] && !Object.is(obj1[key], obj2[key])) { + result[key] = obj2[key]; + } + if(typeof obj2[key] === 'object' && typeof obj1[key] === 'object') { + const value = wusb.diferencia(obj1[key], obj2[key]); + if (value !== undefined) { + result[key] = value; + } + } + }); + return result; + }, + + lastUpdated: function () { + var dt = fixed['fb.date_time'] + 'Z' + ((fixed['fb.timezone'] < 0) ? '-' : '+') + fixed['fb.timezone']; + return dt; + }, + station: function () { + return station; + }, + // consulta a la EMA del ultimo registro. + Recolectar: function () + { + return new Promise((resultado, error)=> + { + var started = process.hrtime(); + wusb.getRange(station, 0x00, 0xff, function (fb) + { + fixed = wusb.decode(fb, true); + var current = fixed['fb.current_pos']; + //RegistrarLog('ENTO AL RECOLECTOR'); + wusb.getRange(station, current, current, function (reading) + { + var completed = process.hrtime(started); + //RegistrarLog('ENTO AL GET'); + //se verifica si es un registro nuevo y los cambios + if(wusb.registro_ant == ''){wusb.registro_ant = reading;} + var nuevo = wusb.decode(reading, false); + var anterior = wusb.decode(wusb.registro_ant, false); + var cambios = wusb.diferencia(anterior,nuevo); + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + wusb.fecha_registro =new Date(utc + (3600000 * (C_EMA.ConfGeneral.UTC))); // UTC - Configurado + delete cambios['rf.delay']; + if(JSON.stringify(cambios['rf.status']) == "{}") {delete cambios['rf.status'];} + + if (JSON.stringify(reading) != JSON.stringify(wusb.registro_ant)) + { + //RegistrarLog('NuevoRegistro:' + wusb.fecha_registro ); + // RegistrarLog( cambios); + wusb.registro_ant = reading; + wusb.sincronizado = true; + resultado([nuevo,fixed,cambios,true]); + }else{ + // carga continua de datos + //weather = wusb.decode(reading, false); + //wusb.recent.unshift(weather); + //wusb.recent = wusb.recent.slice(0, wusb.conf.recent || 5); + //weather.unix = (new Date(wusb.lastUpdated())).getTime() - weather['rf.delay'] * 60000; + //weather.datetime = new Date(weather.unix); + //weather.lastUpdated = new Date(wusb.lastUpdated()); + wusb.poller = wusb.Recolectar; + resultado([nuevo,fixed,cambios,false]); + } + }); + }); + }).then((resultado)=>{ // Fin del then de la promesa + //RegistrarLog('ENTO AL THEN DE LA PROMESA'); + var datos = resultado[0]; + var configuraciones = resultado[1]; + // se convierte la informacion recolectada en otras medidas. + var TemperaturaExternaF = datos['rf.temp_out'] * (9 / 5) + 32; + var TemperaturaInternaF = datos['rf.temp_in'] * (9 / 5) + 32; + var VientoEnKm = datos['rf.wind_ave'] * 3.6; + var RafagaEnKm = datos['rf.wind_gust'] * 3.6; + var VientoEnMh = datos['rf.wind_ave'] * 2.2369; + var RafagaEnMh = datos['rf.wind_gust'] * 2.2369; + var VientoDireccion = ''; + // se convierte la fecha a la UTC parametrizada + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var db = new Date(utc + (3600000 * (C_EMA.ConfGeneral.UTC))); // UTC - Configurado + var dbutc = new Date(utc); // UTC Pura + // Se da formato a la fecha y hora + var minutos = db.getMinutes(); + if (minutos <= 9) { minutos = '0' + minutos; } + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora; } + var mes = db.getMonth() + 1; + if (mes <= 9) { mes = '0' + mes; } + var dia = db.getDate(); + if (dia <= 9) { dia = '0' + dia; } + var segundo = db.getSeconds(); + if (segundo <= 9) { segundo = '0' + segundo; } + var fecha = dia + '/' + mes + '/' + db.getFullYear() + ' ' + hora + ':' + minutos + ':' + segundo; + var fechaISO = db.getFullYear() + '-' + mes + '-' + dia + 'T' + hora + ':' + minutos + ':' + segundo; + dia = null; + mes = null; + hora = null; + minutos = null; + segundo = null; + db = null; + utc = null; + d = null; + // UTC PURA + var minutost = dbutc.getMinutes(); + if (minutost <= 9) { minutost = '0' + minutost; } + var horat = dbutc.getHours(); + if (horat <= 9) { horat = '0' + horat; } + var mest = dbutc.getMonth() + 1; + if (mest <= 9) { mest = '0' + mest; } + var diat = dbutc.getDate(); + if (diat <= 9) { diat = '0' + diat; } + var segundot = dbutc.getSeconds(); + if (segundot <= 9) { segundot = '0' + segundot; } + var fechaUTC = dbutc.getFullYear() + '-' + mest + '-' + diat + '+' + horat + ':' + minutost + ':' + segundot; + diat = null; + mest = null; + horat = null; + minutost = null; + segundot = null; + dbutc = null; + // calculo del punto de rocio + var punto_de_rocio = (Math.pow((datos['rf.hum_out'] / 100), 0.125)) * (112 - (-(0.9 * datos['rf.temp_out']))) - (-(0.1 * datos['rf.temp_out'])) - 112; + punto_de_rocio = (Math.round(punto_de_rocio * 100)) / 100; + var puntoDeRocioF = punto_de_rocio * (9 / 5) + 32; + var x = datos['rf.wind_dir']; + // direccion del viento por nombre + switch (true) { + case x === 0: + VientoDireccion = 'Norte'; + break; + case x > 0 && x < 90: + VientoDireccion = 'Nordeste'; + break; + case x === 90: + VientoDireccion = 'Este'; + break; + case x > 90 && x < 180: + VientoDireccion = 'Sudeste'; + break; + case x === 180: + VientoDireccion = 'Sur'; + break; + case x > 180 && x < 270: + VientoDireccion = 'Sudoeste'; + break; + case x === 270: + VientoDireccion = 'Oeste'; + break; + case x > 270 && x < 360: + VientoDireccion = 'Noroeste'; + break; + default: + VientoDireccion = 'N/A'; + } + x = null; + // Se muestra por consola el registro + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|** Datos recolectados **'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Temperatura Externa: ' + datos['rf.temp_out'] + ' C - ' + TemperaturaExternaF.toFixed(2) + ' F'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Humedad Externa: ' + datos['rf.hum_out'] + '%'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Temperatura Interna: ' + datos['rf.temp_in'] + ' C - ' + TemperaturaInternaF.toFixed(2) + ' F'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Humedad Interna: ' + datos['rf.hum_in'] + '%'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Presion Absoluta: ' + configuraciones['fb.abs_pressure'] + ' hpa'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Presion Relativa: ' + configuraciones['fb.rel_pressure'] + ' hpa'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Viento Direccion: ' + datos['rf.wind_dir'] + ' Direccion: ' + VientoDireccion); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|V.Velocidad: ' + datos['rf.wind_ave'] + ' Mps - ' + VientoEnKm.toFixed(2) + ' Km/h - ' + VientoEnMh.toFixed(2) + ' Mph'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|V.Rafagas: ' + datos['rf.wind_gust'] + ' Mps - ' + RafagaEnKm.toFixed(2) + ' Km/h - ' + RafagaEnMh.toFixed(2) + ' Mph'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Lluvia Acumulada: ' + datos['rf.rain']); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Punto de Rocio: ' + punto_de_rocio.toFixed(2) + ' C - ' + puntoDeRocioF.toFixed(2) + ' F'); + // Solo si posee el sensor UV y Lux + if (datos['rf.lux'] != null && datos['rf.uv'] != null && configuraciones['fb.lux_wm2_coeff'] != null) { + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Luz: ' + datos['rf.lux'] + ' lux - ' + (datos['rf.lux'] / 1000).toFixed(2) + ' Klux - ' + (datos['rf.lux'] / 683).toFixed(2) + ' w/m2'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|Luz coef: ' + configuraciones['fb.lux_wm2_coeff'].toFixed(2) + ' lux'); + if (wusb.conf.debug > 1) RegistrarLog('2|REGISTRO|UV: ' + datos['rf.uv'] + ' uv'); + } + // vector para con la informacion recolectada. + var Vector; + Vector = [fecha, // 0 Fecha + fechaISO, // 1 fechaISO + datos['rf.temp_out'], // 2 Temperatura Ext + datos['rf.temp_in'], // 3 Temperatura Int + datos['rf.hum_out'], // 4 Humedad Ext + datos['rf.hum_in'], // 5 Humedad Int + datos['rf.lux'], // 6 Luz + datos['rf.uv'], // 7 UV + VientoEnKm, // 8 Viento + RafagaEnKm, // 9 Viento Rafaga + datos['rf.wind_dir'], // 10 Viento Direc � + VientoDireccion, // 11 Viento Nombre + datos['rf.abs_pressure'], // 12 Presion abs + configuraciones['fb.rel_pressure'], // 13 Presion rel + datos['rf.rain'], // 14 Luvia total + punto_de_rocio, // 15 Punto de Rocio + fechaUTC, // 16 Fecha UTC + datos['rf.status'] // 17 Estado de los sensores + ]; + // se borran las variables + fecha = null; + fechaISO = null; + VientoEnKm = null; + RafagaEnKm = null; + VientoDireccion = null; + punto_de_rocio = null; + fechaUTC = null; + TemperaturaInternaF = null; + TemperaturaExternaF = null; + VientoEnMh = null; + RafagaEnMh = null; + puntoDeRocioF = null; + datos = null; + configuraciones = null; + //RegistrarLog('FIN DEL THEN DE LA PROMESA'); + //info return(Vector, cambios, true o false - Si hay cambios o no) + return [Vector,resultado[2],resultado[3]]; // Finalmente devuelve el vector, con los datos recolectados del USB. + }); //FIN DEL THEN DE LA PROMESA + } +}; diff --git a/src/core/redes/awekas.js b/src/core/redes/awekas.js new file mode 100644 index 0000000..fef06aa --- /dev/null +++ b/src/core/redes/awekas.js @@ -0,0 +1,219 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red AWEKAS (http://ws.awekas.at) + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2017 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + + +var http = require('http'); + +(function () { + 'use strict'; + var server = { + host: 'ws.awekas.at', + port: 80, + fijo: '/weatherstation/updateweatherstation.php', + path: '/weatherstation/updateweatherstation.php', + method: 'GET' + }; + + var fields = [ + 'action', + 'ID', + 'PASSWORD', + 'dateutc', + 'winddir', + 'windspeedmph', + 'windgustmph', + 'windgustdir', + 'windspdmph_avg2m', + 'winddir_avg2m', + 'windgustmph_10m', + 'windgustdir_10m', + 'humidity', + 'dewptf', + 'tempf', + 'rainin', + 'dailyrainin', + 'baromin', + 'weather', + 'clouds', + 'soiltempf', + 'soilmoisture', + 'leafwetness', + 'solarradiation', + 'UV', + 'visibility', + 'indoortempf', + 'indoorhumidity', + 'AqNO', + 'AqNO2T', + 'AqNO2', + 'AqNO2Y', + 'AqNOX', + 'AqNOY', + 'AqNO3', + 'AqSO4', + 'AqSO2', + 'AqSO2T', + 'AqCO', + 'AqCOT', + 'AqEC', + 'AqOC', + 'AqBC', + 'AqUV', + 'AqPM2.5', + 'AqPM10', + 'AqOZONE', + 'softwaretype' + ]; + + var timeout = 5000; + + function AWEKAS(ID, PASSWORD) { + + if (!(this instanceof AWEKAS)) return new AWEKAS(ID, PASSWORD); + + var payload = { + // action: 'updateraw', + // realtime: 1, + // rtfreq: 1, + ID: ID || '', + PASSWORD: PASSWORD || '', + dateutc: 'now' + }; + + this.setObservations = function () { + if (arguments.length > 0) { + switch (typeof arguments[0]) { + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { + return new Error('Invalid argument for setObservations().'); + } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Observation ' + observation + ' not supported by WU.'); + } + break; + + default: + return new Error('Invalid argument for setObservations().'); + } + } else { + return new Error('No argument supplied to setObservations().'); + } + }; + + this.getObservations = function () { + return payload; + }; + + this.resetObservations = function () { + payload = { + // realtime: 1, + // rtfreq: 5, + // action: 'updateraw', + ID: payload.ID, + PASSWORD: payload.PASSWORD, + dateutc: 'now' + }; + return true; + }; + + this.getFields = function () { + return fields; + }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Invalid timeout.'); + } + }; + + this.getRequestTimeout = function () { + return timeout; + }; + + this.sendObservations = function (callback) { + + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + var that = this; + + Object.keys(payload).forEach(function (observation) { + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + server.path = server.fijo; + server.path += '?' + queryString.join('&'); + var request = http.request(server, function (response) { + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + var result = message.trim(); + if (result === 'OK') { + that.resetObservations(); + callback(null, result); + } else { + var detalle_error = result.substr(result, 100); + callback(new Error(detalle_error), null); + } + }); + }); + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + + request.end(); + }; + + } + module.exports = AWEKAS; +}()); diff --git a/src/core/redes/emacenter.js b/src/core/redes/emacenter.js new file mode 100644 index 0000000..8dba6cc --- /dev/null +++ b/src/core/redes/emacenter.js @@ -0,0 +1,177 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red EMA CENTER. + * + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +(function () { + 'use strict'; + + var server = { + host: '127.0.0.1', + port: 443, + fijo: '/post/', + path: '/post/', + method: 'GET', + llave: '' + }; + + var fields = [ + 'fecha', + 'temperatura_externa', + 'temperatura_interna', + 'humedad_interna', + 'humedad_externa', + 'punto_de_rocio', + 'luxer_uv', + 'luxer_intencidad', + 'viento_direccion', + 'viento_direccion_nombre', + 'viento_rafagas', + 'viento_velocidad', + 'lluvia_actual', + 'lluvia_acumulado_hora', + 'lluvia_acumulado_diario', + 'lluvia_acumulado_semanal', + 'lluvia_acumulado_mensual', + 'lluvia_acumulado_anual', + 'presion_relativa', + 'presion_absoluta', + 'software', + 'tanque' + ]; + + var timeout = 5000; + + function EMACENTER (HOST, PORT, LLAVE) { + server.host = HOST; + server.port = PORT; + server.llave = LLAVE; + // Segun el puerto se carga libreria para HTTPS o HTTP + var http; + if (server.port === 443) { http = require('https'); } else { http = require('http'); } + if (!(this instanceof EMACENTER)) return new EMACENTER(HOST, PORT, LLAVE); + var payload = { HOST: HOST || '', LLAVE: LLAVE || '' }; + + this.setObservations = function () { + if (arguments.length > 0) { + switch (typeof arguments[0]) { + // Consulta el tipo de dato + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { return new Error('Invalido dato en setObservations().'); } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Dato ' + observation + ' no soportado por EMACENTER.'); + } + break; + + default: + return new Error('Invalido argumento en setObservations().'); + } + } else { + return new Error('Dato no soportado en setObservations().'); + } + }; + + this.getObservations = function () { return payload; }; + + this.resetObservations = function () { + payload = {}; + return true; + }; + + this.getFields = function () { return fields; }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Timeout excedido.'); + } + }; + + this.getRequestTimeout = function () { return timeout; }; + + this.sendObservations = function (callback) { + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + var that = this; + Object.keys(payload).forEach(function (observation) { + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + + server.path = server.fijo + server.llave + '/'; + server.path += '?' + queryString.join('&'); + // alert(server.path); + // if(APP.Configuracion.debug>4) console.log('EMACENTER -> URL GET: '+server.path); + var request = http.request(server, function (response) { + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + // alert(response.statusCode); + var result = message.trim(); + if (response.statusCode === 200) { // RESPUESTA HTML Y COMPARA + that.resetObservations(); + callback(null, result); + } else { + var detalleError = 'Codigo de error: ' + response.statusCode; // ERROR + callback(new Error(detalleError + server.path), null); + } + }); + }); + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + + request.end(); + }; + } + module.exports = EMACENTER; +}()); diff --git a/src/core/redes/openweathermap.js b/src/core/redes/openweathermap.js new file mode 100644 index 0000000..589b796 --- /dev/null +++ b/src/core/redes/openweathermap.js @@ -0,0 +1,190 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red openweathermap (https://openweathermap.org/stations) + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2017 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ +var FechaUltimoPublicado = "S/D"; +var http = require('http'); + +(function () { + 'use strict'; + var server = { + host: 'api.openweathermap.org', + port: 80, + fijo: '/data/3.0/measurements', + path: '/data/3.0/measurements', + method: 'POST' + }; + + + var fields = [ + 'station_id', + 'dt', + 'temperature', + 'wind_speed', + 'wind_gust', + 'wind_deg', + 'pressure', + 'humidity', + 'rain_1h', + 'rain_24h', + 'dew_point' + ]; + + + var timeout = 5000; + + function OPEN(station_id) { + + if (!(this instanceof OPEN)) return new OPEN(station_id); + + var payload = { + station_id: station_id || '' + }; + + this.setObservations = function () { + if (arguments.length > 0) { + switch (typeof arguments[0]) { + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { + return new Error('Invalid argument for setObservations().'); + } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Observation ' + observation + ' not supported by WU.'); + } + break; + + default: + return new Error('Invalid argument for setObservations().'); + } + } else { + return new Error('No argument supplied to setObservations().'); + } + }; + + this.getObservations = function () { + return payload; + }; + + this.resetObservations = function () { + payload = { + station_id: payload.station_id + }; + return true; + }; + + this.getFields = function () { + return fields; + }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Invalid timeout.'); + } + }; + + this.getRequestTimeout = function () { + return timeout; + }; + + this.sendObservations = function (callback) { + + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + var that = this; + + Object.keys(payload).forEach(function (observation) { + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + + server.path = server.fijo; + server.path += '?' + queryString.join('&'); + //APP.RegistrarLog(server.host + server.path); + //if(APP.Configuracion.debug>4) console.log('OPEN -> URL GET: '+server.path); + + var request = http.request(server, function (response) { + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + var result = message.trim(); + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var db = new Date(utc + (3600000 * (APP.Configuracion.utc))); + var minutos = db.getMinutes(); + if (minutos <= 9) { minutos = '0' + minutos }; + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora }; + var segundo = db.getSeconds(); + if (segundo <= 9) { segundo = '0' + segundo }; + var fecha = hora + ':' + minutos + ':' + segundo; + if (response.statusCode == 200 || response.statusCode == 429) { // RESPUESTA HTML Y COMPARA + if (response.statusCode == 200) { FechaUltimoPublicado = fecha; + that.resetObservations(); + callback(null, result); } + if (response.statusCode == 429) { that.resetObservations(); + callback(null, [429, FechaUltimoPublicado]); } + } else { + var detalle_error = "Codigo de error: " + response.statusCode + " Tipo:" + result; // ERROR + callback(new Error(detalle_error), null); + } + }); + }); + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + + request.end(); + }; + + } + module.exports = OPEN; +}()); diff --git a/src/core/redes/pws.js b/src/core/redes/pws.js new file mode 100644 index 0000000..eebca49 --- /dev/null +++ b/src/core/redes/pws.js @@ -0,0 +1,189 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red PWS. + * + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2017 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +var http = require('http'); + +(function () { + 'use strict'; + + var server = { + host: 'www.pwsweather.com', + port: 80, + fijo: '/pwsupdate/pwsupdate.php', + path: '/pwsupdate/pwsupdate.php', + method: 'GET' + }; + + var fields = [ + 'ID', + 'PASSWORD', + 'dateutc', + 'baromin', + 'dailyrainin', + 'dewptf', + 'humidity', + 'monthrainin', + 'rainin', + 'tempf', + 'UV', + 'solarradiation', + 'weather', + 'winddir', + 'windgustmph', + 'windspeedmph', + 'yearrainin', + 'softwaretype', + 'action' + ]; + + var timeout = 5000; + + function PW(ID, PASSWORD) { + + if (!(this instanceof PW)) return new PW(ID, PASSWORD); + + var payload = { + ID: ID || '', + PASSWORD: PASSWORD || '' + }; + + this.setObservations = function () { + if (arguments.length > 0) { + switch (typeof arguments[0]) { + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { + return new Error('Invalid argument for setObservations().'); + } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Observation ' + observation + ' not supported by WU.'); + } + break; + + default: + return new Error('Invalid argument for setObservations().'); + } + } else { + return new Error('No argument supplied to setObservations().'); + } + }; + + this.getObservations = function () { + return payload; + }; + + this.resetObservations = function () { + payload = { + ID: payload.ID, + PASSWORD: payload.PASSWORD + }; + return true; + }; + + this.getFields = function () { + return fields; + }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Invalid timeout.'); + } + }; + + this.getRequestTimeout = function () { + return timeout; + }; + + this.sendObservations = function (callback) { + + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + + var that = this; + + Object.keys(payload).forEach(function (observation) { + + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + + server.path = server.fijo; + server.path += '?' + queryString.join('&'); + + //if(APP.Configuracion.debug>4) console.log('PWS -> URL GET: '+server.path); + + var request = http.request(server, function (response) { + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + var result = message.trim(); + if (result.indexOf("Data Logged and posted") != -1) { // ACA COMPARA LA RESPUESTA HTML + that.resetObservations(); + callback(null, result); + } else { + var detalle_error = result.substr(result.indexOf("ERROR"), 100); + callback(new Error(detalle_error), null); + } + }); + }); + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + + request.end(); + }; + + } + module.exports = PW; +}()); diff --git a/src/core/redes/windguru.js b/src/core/redes/windguru.js new file mode 100644 index 0000000..d2a1c18 --- /dev/null +++ b/src/core/redes/windguru.js @@ -0,0 +1,183 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red WindGuru (https://www.windguru.cz) + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2017 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + + +var http = require('http'); + +(function () { + 'use strict'; + var server = { + host: 'www.windguru.cz', + port: 80, + control: 'https://www.windguru.cz/int/wgsapi.php', + fijo: '/upload/api.php', + path: '/upload/api.php', + method: 'GET' + }; + + var fields = [ + 'stationtype', + 'uid', + 'interval', + 'precip_interval', + 'wind_avg', + 'wind_max', + 'wind_direction', + 'temperature', + 'rh', + 'mslp', + 'precip' + ]; + + var timeout = 5000; + + function WINDGURU(ID, PASSWORD) { + + if (!(this instanceof WINDGURU)) return new WINDGURU(ID, PASSWORD); + + var payload = { + stationtype: 'weewx', + uid: ID || '', + }; + + this.setObservations = function () { + if (arguments.length > 0) { + switch (typeof arguments[0]) { + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { + return new Error('Invalid argument for setObservations().'); + } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Observation ' + observation + ' not supported by WU.'); + } + break; + + default: + return new Error('Invalid argument for setObservations().'); + } + } else { + return new Error('No argument supplied to setObservations().'); + } + }; + + this.getObservations = function () { + return payload; + }; + + this.resetObservations = function () { + payload = { + stationtype: payload.stationtype, + uid: payload.uid, + }; + return true; + }; + + this.getFields = function () { + return fields; + }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Invalid timeout.'); + } + }; + + this.getRequestTimeout = function () { + return timeout; + }; + + this.sendObservations = function (callback) { + + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + var that = this; + + Object.keys(payload).forEach(function (observation) { + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + + server.path = server.fijo; + server.path += '?' + queryString.join('&'); + //alert(server.host + server.path); + //APP.RegistrarLog(server.host + server.path); + + //if(APP.Configuracion.debug>4) console.log('WindGuru -> URL GET: '+server.path); + var request = http.request(server, function (response) { + + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + var result = message.trim(); + if (result === 'OK') { + that.resetObservations(); + callback(null, result); + } else { + var detalle_error = result.substr(result.indexOf("ERROR"), 100); + callback(new Error(detalle_error), null); + } + }); + }); + + + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + + request.end(); + }; + + } + module.exports = WINDGURU; +}()); diff --git a/src/core/redes/windy.js b/src/core/redes/windy.js new file mode 100644 index 0000000..45b36a8 --- /dev/null +++ b/src/core/redes/windy.js @@ -0,0 +1,235 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red WINDY (https://stations.windy.com/) + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LIMITE: Envio de registros con frecuencia mayor o igual a 5 minutos. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2017 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + + +var http = require('https'); +var FechaUltimoPublicadoWindy = "S/D"; + +(function () { + 'use strict'; + + var fields = [ + 'ID', + 'station', + 'time', + 'dateutc', + 'ts', + 'temp', + 'tempf', + 'wind', + 'windspeedmph', + 'winddir', + 'gust', + 'windgustmph', + 'rh', + 'dewpoint', + 'pressure', + 'mbar', + 'baromin', + 'precip', + 'rainin', + 'uv' + ]; + + var timeout = 5000; + + function WINDY(ID, PASSWORD) { + + + var server = { + host: 'stations.windy.com', + port: 443, + fijo: '/pws/update/'+ID, // Se agrega la KEY de la estacion + path: '/pws/update/'+ID, // Se agrega la KEY de la estacion + method: 'GET' + }; + + if (!(this instanceof WINDY)) return new WINDY(ID, PASSWORD); + + var payload = { + station: PASSWORD || '' + }; + + this.setObservations = function () { + + if (arguments.length > 0) { + switch (typeof arguments[0]) { + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { + return new Error('Invalid argument for setObservations().'); + } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Observation ' + observation + ' not supported by WU.'); + } + break; + + default: + return new Error('Invalid argument for setObservations().'); + } + } else { + return new Error('No argument supplied to setObservations().'); + } + }; + + this.getObservations = function () { + return payload; + }; + + this.resetObservations = function () { + payload = { + station: payload.station, + dateutc: 'now' + }; + return true; + }; + + this.getFields = function () { + return fields; + }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Invalid timeout.'); + } + }; + + this.getRequestTimeout = function () { + return timeout; + }; + + this.sendObservations = function (callback) { + + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + var that = this; + // SE CONTROLA QUE EL REGISTRO SEA MAYOR A 5 QUE EL ANTERIOR + //se obtiene el ultimo registro + if(FechaUltimoPublicadoWindy != "S/D") + { + // Viene de esta forma: 07/10/2019 20:20:04 + var DiaT = FechaUltimoPublicadoWindy.substring(0, 2); + var MesT = FechaUltimoPublicadoWindy.substring(3, 5); + var AnioT = FechaUltimoPublicadoWindy.substring(6, 10); + var HoraT = FechaUltimoPublicadoWindy.substring(11, 13); + var MinT = FechaUltimoPublicadoWindy.substring(14, 16); + var SegundosT = FechaUltimoPublicadoWindy.substring(17, 19); + //se obtiene la fecha del ultmo registro como tipo Date + var fechaUltDate = new Date(parseInt(AnioT),(parseInt(MesT)-1),parseInt(DiaT),parseInt(HoraT),parseInt(MinT),parseInt(SegundosT)).getTime(); + var f = new Date(); + var FechaActual = new Date(f.getFullYear(), f.getMonth(),f.getDate(), f.getHours(),f.getMinutes(),f.getSeconds()).getTime(); + var diferenciaMinutos = 0; + diferenciaMinutos = ((FechaActual - fechaUltDate) / 1000)/60; + } + if(diferenciaMinutos < 5.5 && FechaUltimoPublicadoWindy != "S/D") + { + that.resetObservations(); callback(null, [430, FechaUltimoPublicadoWindy]); + } + else{ + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var db = new Date(utc + (3600000 * (APP.Configuracion.utc))); + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora }; + var mes = db.getMonth() + 1; + if (mes <= 9) { mes = '0' + mes }; + var dia = db.getDate(); + if (dia <= 9) { dia = '0' + dia }; + var minutos = db.getMinutes(); + if (minutos <= 9) { minutos = '0' + minutos }; + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora }; + var segundo = db.getSeconds(); + if (segundo <= 9) { segundo = '0' + segundo }; + var fecha = dia + "/" + mes + "/" + db.getFullYear() + " " + hora + ':' + minutos + ':' + segundo; + Object.keys(payload).forEach(function (observation) { + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + server.path = server.fijo; + server.path += '?' + queryString.join('&'); + var request = http.request(server, function (response) { + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + var result = message.trim(); + if (result === 'SUCCESS') { + // Registro publicado correctamente + FechaUltimoPublicadoWindy = fecha; + that.resetObservations(); + callback(null, result); + } else { + + if (result.substr(result, 8) == 'SUCCESS ' ) + { // Esta Congestionada + that.resetObservations(); + callback(null, [429, FechaUltimoPublicadoWindy]); + } else { + // Otro error. + var detalle_error = result.substr(result, 100); + callback(new Error(detalle_error), null); + } + } + }); + }); + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + request.end(); + } + }; + } + module.exports = WINDY; +}()); diff --git a/src/core/redes/wow.js b/src/core/redes/wow.js new file mode 100644 index 0000000..104f6ae --- /dev/null +++ b/src/core/redes/wow.js @@ -0,0 +1,235 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red WOW MetOffice (https://wow.metoffice.gov.uk/support/dataformats) + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LIMITE: Envio de registros con frecuencia mayor o igual a 5 minutos. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2017 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ +var FechaUltimoPublicadoWow = "S/D"; +var http = require('http'); + +(function () { + 'use strict'; + var server = { + host: 'wow.metoffice.gov.uk', + port: 80, + fijo: '/automaticreading', + path: '/automaticreading', + method: 'GET' + }; + + var fields = [ + 'siteid', + 'siteAuthenticationKey', + 'dateutc', + 'winddir', + 'windspeedmph', + 'windgustmph', + 'windgustdir', + 'windspdmph_avg2m', + 'winddir_avg2m', + 'windgustmph_10m', + 'windgustdir_10m', + 'humidity', + 'dewptf', + 'tempf', + 'rainin', + 'dailyrainin', + 'baromin', + 'weather', + 'clouds', + 'soiltempf', + 'soilmoisture', + 'leafwetness', + 'solarradiation', + 'UV', + 'visibility', + 'raininm', + 'dailyraininm', + 'softwaretype' + ]; + + var timeout = 5000; + + function WOW(siteid, siteAuthenticationKey) { + + if (!(this instanceof WOW)) return new WOW(siteid, siteAuthenticationKey); + + var payload = { + siteid: siteid || '', + siteAuthenticationKey: siteAuthenticationKey || ''//, + // dateutc: 'now' + }; + + this.setObservations = function () { + if (arguments.length > 0) { + switch (typeof arguments[0]) { + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { + return new Error('Invalid argument for setObservations().'); + } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Observation ' + observation + ' not supported by WU.'); + } + break; + + default: + return new Error('Invalid argument for setObservations().'); + } + } else { + return new Error('No argument supplied to setObservations().'); + } + }; + + this.getObservations = function () { + return payload; + }; + + this.resetObservations = function () { + payload = { + siteid: payload.siteid, + siteAuthenticationKey: payload.siteAuthenticationKey//, + // dateutc: 'now' + }; + return true; + }; + + this.getFields = function () { + return fields; + }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Invalid timeout.'); + } + }; + + this.getRequestTimeout = function () { + return timeout; + }; + + this.sendObservations = function (callback) { + + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + var that = this; + // SE CONTROLA QUE EL REGISTRO SEA MAYOR A 5 QUE EL ANTERIOR + //se obtiene el ultimo registro + if(FechaUltimoPublicadoWow != "S/D") + { + // Viene de esta forma: 07/10/2019 20:20:04 + var DiaT = FechaUltimoPublicadoWow.substring(0, 2); + var MesT = FechaUltimoPublicadoWow.substring(3, 5); + var AnioT = FechaUltimoPublicadoWow.substring(6, 10); + var HoraT = FechaUltimoPublicadoWow.substring(11, 13); + var MinT = FechaUltimoPublicadoWow.substring(14, 16); + var SegundosT = FechaUltimoPublicadoWow.substring(17, 19); + //se obtiene la fecha del ultmo registro como tipo Date + var fechaUltDate = new Date(parseInt(AnioT),(parseInt(MesT)-1),parseInt(DiaT),parseInt(HoraT),parseInt(MinT),parseInt(SegundosT)).getTime(); + var f = new Date(); + var FechaActual = new Date(f.getFullYear(), f.getMonth(),f.getDate(), f.getHours(),f.getMinutes(),f.getSeconds()).getTime(); + var diferenciaMinutos = 0; + diferenciaMinutos = ((FechaActual - fechaUltDate) / 1000)/60; + } + if(diferenciaMinutos < 5.5 && FechaUltimoPublicadoWow != "S/D") + { + that.resetObservations(); callback(null, [430, FechaUltimoPublicadoWow]); + } + else{ + var d = new Date(); + var utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var db = new Date(utc + (3600000 * (APP.Configuracion.utc))); + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora }; + var mes = db.getMonth() + 1; + if (mes <= 9) { mes = '0' + mes }; + var dia = db.getDate(); + if (dia <= 9) { dia = '0' + dia }; + var minutos = db.getMinutes(); + if (minutos <= 9) { minutos = '0' + minutos }; + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora }; + var segundo = db.getSeconds(); + if (segundo <= 9) { segundo = '0' + segundo }; + var fecha = dia + "/" + mes + "/" + db.getFullYear() + " " + hora + ':' + minutos + ':' + segundo; + Object.keys(payload).forEach(function (observation) { + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + server.path = server.fijo; + server.path += '?' + queryString.join('&'); + var request = http.request(server, function (response) { + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + var result = message.trim(); + if (response.statusCode == 200 || response.statusCode == 429) { // RESPUESTA HTML Y COMPARA + if (response.statusCode == 200) { + FechaUltimoPublicadoWow = fecha; + that.resetObservations(); + callback(null, result); } + if (response.statusCode == 429) { that.resetObservations(); + callback(null, [429, FechaUltimoPublicadoWow]); } + } else { + var detalle_error = "Codigo de error: " + response.statusCode + " Tipo:" + result; // ERROR + callback(new Error(detalle_error), null); + } + }); + }); + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + request.end(); + } + }; + } + module.exports = WOW; +}()); diff --git a/src/core/redes/wunderground.js b/src/core/redes/wunderground.js new file mode 100644 index 0000000..4ad6448 --- /dev/null +++ b/src/core/redes/wunderground.js @@ -0,0 +1,225 @@ +/** + * Este archivo es parte de EMA Libre y brinda la funcionalidad de envio de datos + * metorologicos recolectados por EMA Libre a una red WUNDERGROUND (http://wiki.wunderground.com) + * Este archivo, contiene metodos que se encargan de enviar (por POST o GET) y detectar si dicho envio + * fue recibido correctamente por la red, basandose en el mensaje emitido por la red. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2017 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + + +var http = require('https'); + +(function () { + 'use strict'; + var server = { + host: 'rtupdate.wunderground.com', + //host: 'weatherstation.wunderground.com', + port: 443, + fijo: '/weatherstation/updateweatherstation.php', + path: '/weatherstation/updateweatherstation.php', + method: 'GET' + }; + + var fields = [ + 'action', + 'ID', + 'PASSWORD', + 'dateutc', + 'winddir', + 'windspeedmph', + 'windgustmph', + 'windgustdir', + 'windspdmph_avg2m', + 'winddir_avg2m', + 'windgustmph_10m', + 'windgustdir_10m', + 'humidity', + 'dewptf', + 'tempf', + 'rainin', + 'dailyrainin', + 'baromin', + 'weather', + 'clouds', + 'soiltempf', + 'soilmoisture', + 'leafwetness', + 'solarradiation', + 'UV', + 'visibility', + 'indoortempf', + 'indoorhumidity', + 'AqNO', + 'AqNO2T', + 'AqNO2', + 'AqNO2Y', + 'AqNOX', + 'AqNOY', + 'AqNO3', + 'AqSO4', + 'AqSO2', + 'AqSO2T', + 'AqCO', + 'AqCOT', + 'AqEC', + 'AqOC', + 'AqBC', + 'AqUV', + 'AqPM2.5', + 'AqPM10', + 'AqOZONE', + 'softwaretype' + ]; + + var timeout = 5000; + + function WUNDER(ID, PASSWORD) { + + if (!(this instanceof WUNDER)) return new WUNDER(ID, PASSWORD); + + var payload = { + action: 'updateraw', + realtime: 1, + rtfreq: 1, + ID: ID || '', + PASSWORD: PASSWORD || '', + dateutc: 'now' + }; + + this.setObservations = function () { + if (arguments.length > 0) { + switch (typeof arguments[0]) { + case 'object': + var observations = arguments[0]; + if (Object.prototype.toString.call(observations) === '[object Object]') { + Object.keys(observations).forEach(function (observation) { + if (fields.indexOf(observation) > -1) { + payload[observation] = String(observations[observation]).toString(); + } + }); + return true; + } else { + return new Error('Invalid argument for setObservations().'); + } + break; + + case 'string': + var observation = arguments[0]; + var reading = arguments[1] || ''; + if (fields.indexOf(observation) > -1) { + payload[observation] = reading; + return true; + } else { + return new Error('Observation ' + observation + ' not supported by WU.'); + } + break; + + default: + return new Error('Invalid argument for setObservations().'); + } + } else { + return new Error('No argument supplied to setObservations().'); + } + }; + + this.getObservations = function () { + return payload; + }; + + this.resetObservations = function () { + payload = { + realtime: 1, + rtfreq: 5, + action: 'updateraw', + ID: payload.ID, + PASSWORD: payload.PASSWORD, + dateutc: 'now' + }; + return true; + }; + + this.getFields = function () { + return fields; + }; + + this.setRequestTimeout = function (miliseconds) { + if (!isNaN(Number(miliseconds))) { + timeout = miliseconds; + return timeout; + } else { + return new Error('Invalid timeout.'); + } + }; + + this.getRequestTimeout = function () { + return timeout; + }; + + this.sendObservations = function (callback) { + + if (typeof callback !== 'function') callback = function () {}; + var queryString = []; + var that = this; + + Object.keys(payload).forEach(function (observation) { + queryString.push(observation + '=' + encodeURIComponent(payload[observation]).replace('%2B', '+')); + }); + + server.path = server.fijo; + server.path += '?' + queryString.join('&'); + + // if(APP.Configuracion.debug>4) console.log('Wunderground -> URL GET: '+server.path); + //alert(server.path); + var request = http.request(server, function (response) { + var message = ''; + response.on('data', function (chunk) { + message += chunk; + }); + + response.on('end', function () { + var result = message.trim(); + if (result === 'success') { + that.resetObservations(); + callback(null, result); + } else { + //console.log('Wunderground -> ERROR: '+result); + var detalle_error = result.substr(result.indexOf("ERROR"), 100); + callback(new Error(detalle_error), null); + } + }); + }); + + request.on('socket', function (socket) { + socket.setTimeout(timeout); + socket.on('timeout', function () { + request.abort(); + }); + }).on('error', function (error) { + callback(error, null); + }); + + request.end(); + }; + + } + module.exports = WUNDER; +}()); diff --git a/src/core/redes_meteorologicas.js b/src/core/redes_meteorologicas.js new file mode 100644 index 0000000..096df1a --- /dev/null +++ b/src/core/redes_meteorologicas.js @@ -0,0 +1,439 @@ +/** + * Este archivo es parte del proyecto EMA Libre + * + * Contiene el codigo fuente, que brinda la funcionalidad de envio + * de datos metorologicos a una RED ABIERTA (ej:Ema Libre Center, wunderground, pws, etc), + * siendo la principal la red EMA Libre. + * + * El codigo, contiene un metodo el cual recibe como parametro una red, y los datos + * que se desean enviar a la misma, cada red tiene su configuracion particular la cual es incluida + * ej:(require('./redes/wunderground-pws')). + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +module.exports = { + + // --- Informacion recibida ------- + // PARAMETROS[0][X]: 0-TipoRed, 1-Usuario, 2-Password, 3-Server, 4-Puerto, 5-Ruta, 6 - Llave de Escritura, 7-Nombre de Red + // PARAMETROS[1] : Datos meteorologicos registro para enviar + // PARAMETROS[2] : Id red + // --- Informacion devuelta ------- + // cbFunc(nombre_red, estado, error, idRed, ParametrosEnviadosAlaRed) + + EviarRedesMeteorologicas: function (versionEMA,Parametros, cbFunc) { + // Se define las variables. + var temperaturaExternaF = Parametros[1].temperatura_externa * (9 / 5) + 32; // En farenheit + var temperaturaInternaF = Parametros[1].temperatura_interna * (9 / 5) + 32; // En farenheit + var temperaturaExternaC = Parametros[1].temperatura_externa; // En celsius + var temperaturaInternaC = Parametros[1].temperatura_interna; // En celsius + var puntoDeRocioF = Parametros[1].punto_de_rocio * (9 / 5) + 32; // En farenheit + var puntoDeRocioC = Parametros[1].punto_de_rocio; // En celsius + var presionRelIn = Parametros[1].presion_relativa * 0.0295299830714; // En inches + var presionRelhpa = Parametros[1].presion_relativa; // hpa + var vientoEnMh = (Parametros[1].viento_velocidad / 3.6) * 2.2369; // En millas + var rafagaEnMh = (Parametros[1].viento_rafagas / 3.6) * 2.2369; // En millas + var rafagaEnMs = Parametros[1].viento_rafagas / 3.6; // En m/S + var rafagaEnKh = Parametros[1].viento_rafagas; // En Km/h + var vientoEnMs = Parametros[1].viento_velocidad / 3.6; // En m/S + var vientoEnKh = Parametros[1].viento_velocidad; // En Km/h + var vientoEnNudos = (Parametros[1].viento_velocidad) * 0.539957; // En nudos + var vientoNombre = Parametros[1].viento_direccion_nombre; // Texto + var rafagaEnNudos = (Parametros[1].viento_rafagas) * 0.539957; // En nudos + var lluviaHoraMm = Parametros[1].lluvia_acu_hora; // En mm + var lluviaHorain = Parametros[1].lluvia_acu_hora * 0.03937008; // En pulgadas/inches + var lluviaDiaMm = Parametros[1].lluvia_acu_diaria; // En mm + var lluviaDiain = Parametros[1].lluvia_acu_diaria * 0.03937008; // En pulgadas/inches + var luxerIntencidad = Parametros[1].luxer_intencidad / 683; // luxerIntencidad en w/m² + var luxerIntencidadLux = Parametros[1].luxer_intencidad; // luxerIntencidad en Klux + + // Fecha Formatos + var fechaformato = Parametros[1].fecha.substring(6, 10) + '-' + Parametros[1].fecha.substring(3, 5) + '-' + Parametros[1].fecha.substring(0, 2) + '+' + Parametros[1].fecha.substring(11, 19); + + // Se pregunta por el tipo de red + switch (Parametros[0][0]) { + case 'wow': + var WOW = require('./redes/wow'); + var wow = new WOW(Parametros[0][1], Parametros[0][2]); + var idRed = Parametros[2]; + wow.resetObservations(); + wow.setObservations({ + dateutc: Parametros[1].fechaUTC, // fecha actual + tempf: temperaturaExternaF, // Temp. Externa + humidity: Parametros[1].humedad_externa, // Humedad Externa + dewptf: puntoDeRocioF.toFixed(2), // Punto de Rocio + winddir: Parametros[1].viento_direccion, // Direccion del Viento + windgustmph: rafagaEnMh, // Rafagas + windspeedmph: vientoEnMh, // Viento + raininm: lluviaHoraMm, // Lluvia Acumulado Hora + dailyraininm: lluviaDiaMm, // Lluvia Acumulado Dia + baromin: presionRelIn.toFixed(2), // Presion Relativa + softwaretype: versionEMA // Software + }); + var ParametrosTemp1 = JSON.stringify(Parametros, null, 4); + wow.sendObservations(function (err, success) { + if (err !== null) { + cbFunc('wow', 'ERROR', err, idRed, ParametrosTemp1); + } else { + // codigo de respuesta 430 No enviado - por tiempo limite no superado + if (success[0] === 430) { cbFunc('wow', 430, success[1], idRed, ParametrosTemp1);} + else{ + // codigo de respuesta 429 red congestionada + if (success[0] === 429) { + cbFunc('wow', 429, success[1], idRed, ParametrosTemp1); + } else { + cbFunc('wow', 'OK', 'ok', idRed, ParametrosTemp1); + } + } + } + }); + wow = null; + WOW = null; + break; + + case 'wunderground': + var WUNDER = require('./redes/wunderground'); + var wunder = new WUNDER(Parametros[0][1], Parametros[0][2]); + var idRed2 = Parametros[2]; + wunder.resetObservations(); + wunder.setObservations({ + dateutc: 'now', // fecha actual + tempf: temperaturaExternaF, // Temp. Externa + indoortempf: temperaturaInternaF, // Temp. Interna + indoorhumidity: Parametros[1].humedad_interna, // Humedad Interna + humidity: Parametros[1].humedad_externa, // Humedad Externa + dewptf: puntoDeRocioF.toFixed(2), // Punto de Rocio + UV: Parametros[1].luxer_uv, // UV + solarradiation: luxerIntencidad.toFixed(2), // Solar radiacion + winddir: Parametros[1].viento_direccion, // Direccion del Viento + windgustmph: rafagaEnMh.toFixed(2), // Rafagas + windspeedmph: vientoEnMh.toFixed(2), // Viento + rainin: lluviaHorain.toFixed(2), // Lluvia Acumulado Hora + dailyrainin: lluviaDiain.toFixed(2), // Lluvia Acumulado Dia + baromin: presionRelIn.toFixed(2), // Presion Relativa + softwaretype: versionEMA // Software + }); + var ParametrosTemp2 = JSON.stringify(Parametros, null, 4); + wunder.sendObservations(function (err, success) { + if (err != null) { + cbFunc('wunderground', 'ERROR', err, idRed2, ParametrosTemp2); + } else { + cbFunc('wunderground', 'OK', 'ok', idRed2, ParametrosTemp2); + } + }); + wunder = null; + WUNDER = null; + break; + + case 'pws': + var PW = require('./redes/pws'); + var idRed3 = Parametros[2]; + var pw = new PW(Parametros[0][1], Parametros[0][2]); + pw.resetObservations(); + pw.setObservations({ + dateutc: fechaformato, // Fecha actual + tempf: temperaturaExternaF.toFixed(2), // Temp. Externa + humidity: Parametros[1].humedad_externa, // Humedad Externa + dewptf: puntoDeRocioF.toFixed(2), // Punto de Rocio + UV: Parametros[1].luxer_uv, // UV + solarradiation: luxerIntencidad.toFixed(2), // Solar radiacion + windspeedmph: vientoEnMh.toFixed(2), // Viento + winddir: Parametros[1].viento_direccion, // Direccion del Viento + windgustmph: rafagaEnMh.toFixed(2), // Rafagas + rainin: lluviaHorain.toFixed(2), // Lluvia Acumulado Hora + dailyrainin: lluviaDiain.toFixed(2), // Lluvia Acumulado Dia + baromin: presionRelIn.toFixed(2), // Presion Relativa + softwaretype: versionEMA, // Software + action: 'updateraw' // Tipo de actualizacion + }); + var ParametrosTemp3 = JSON.stringify(Parametros, null, 4); + pw.sendObservations(function (err, success) { + if (err != null) { + cbFunc('pws', 'ERROR', err, idRed3, ParametrosTemp3); + } else { + cbFunc('pws', 'OK', 'ok', idRed3, ParametrosTemp3); + } + }); + pw = null; + PW = null; + break; + + case 'windguru': + var WG = require('./redes/windguru'); + var windguru = new WG(Parametros[0][1], Parametros[0][2]); + var idRed4 = Parametros[2]; + windguru.resetObservations(); + windguru.setObservations({ + interval: 60, + precip_interval: 3600, + wind_avg: vientoEnNudos.toFixed(2), // Viento + wind_max: rafagaEnNudos.toFixed(2), // Viento Rafagas + wind_direction: Parametros[1].viento_direccion, // Viento Direccion + temperature: temperaturaExternaC, // Temperatura Externa + rh: Parametros[1].humedad_externa, // Humedad Externa + mslp: presionRelhpa.toFixed(2), // Presion Relativa + precip: lluviaHoraMm // Lluvia Acumulado Hora + }); + var ParametrosTemp4 = JSON.stringify(Parametros, null, 4); + windguru.sendObservations(function (err, success) { + if (err != null) { + cbFunc('windguru', 'ERROR', err, idRed4, ParametrosTemp4); + } else { + cbFunc('windguru', 'OK', 'ok', idRed4, ParametrosTemp4); + } + }); + windguru = null; + WG = null; + break; + + case 'emacenter': + var idRed5 = Parametros[2]; + var EMACENTER_PARTICULAR = require('./redes/emacenter'); + var centerp = new EMACENTER_PARTICULAR(Parametros[0][3], Parametros[0][4], Parametros[0][6]); + // Se convierte la informacion a la medidas que la red utiliza + if (Parametros[1].luxer_uv == null || Parametros[1].luxer_intencidad == null) { + Parametros[1].luxer_uv = 0; + Parametros[1].luxer_intencidad = 0; + } + centerp.resetObservations(); + centerp.setObservations({ + fecha: Parametros[1].fechaISO, // fecha actual + temperatura_externa: temperaturaExternaC, // Temp. Externa + temperatura_interna: temperaturaInternaC, // Temp. Interna + humedad_interna: Parametros[1].humedad_interna, // Humedad Interna % + humedad_externa: Parametros[1].humedad_externa, // Humedad Externa % + punto_de_rocio: puntoDeRocioC, // Punto de Rocio + luxer_uv: Parametros[1].luxer_uv, // UV + luxer_intencidad: luxerIntencidadLux.toFixed(2), // Solar radiacion + viento_direccion: Parametros[1].viento_direccion, // Direccion del Viento + viento_direccion_nombre: vientoNombre, // Direccion Nombre + viento_rafagas: rafagaEnKh, // Rafagas + viento_velocidad: vientoEnKh, // Viento + lluvia_actual: Parametros[1].lloviendo, // Lluvia Actual + lluvia_acumulado_hora: lluviaHoraMm, // Lluvia Acumulado + lluvia_acumulado_diario: lluviaDiaMm, // Lluvia Acumulado Dia + lluvia_acumulado_total: Parametros[1].lluvia_acumulado_total, // Lluvia Acumulado Total + presion_relativa: presionRelhpa, // Presion Relativa + presion_absoluta: presionRelhpa, // Presion Absoluta + software: versionEMA, // Software + tanque: Parametros[1].tanque // Si el registro es tanqueado (true o false) + }); + var ParametrosTemp5 = JSON.stringify(Parametros, null, 4); + centerp.sendObservations(function (err, success) { + if (err != null) { + cbFunc('emacenter', 'ERROR', err, idRed5, ParametrosTemp5); + } else { + cbFunc('emacenter', 'OK', 'ok', idRed5, ParametrosTemp5); + } + }); + centerp = null; + EMACENTER_PARTICULAR = null; + break; + + case 'emacentergugler': + var idRed6 = Parametros[2]; + var EMACENTER = require('./redes/emacenter'); + var center = new EMACENTER('emacenter.gugler.com.ar', 443, Parametros[0][6]); + // Se convierte la informacion a la medidas que la red utiliza + if (Parametros[1].luxer_uv == null || Parametros[1].luxer_intencidad == null) { + Parametros[1].luxer_uv = 0; + Parametros[1].luxer_intencidad = 0; + } + center.resetObservations(); + center.setObservations({ + fecha: Parametros[1].fechaISO, // fecha actual + temperatura_externa: temperaturaExternaC, // Temp. Externa + temperatura_interna: temperaturaInternaC, // Temp. Interna + humedad_interna: Parametros[1].humedad_interna, // Humedad Interna % + humedad_externa: Parametros[1].humedad_externa, // Humedad Externa % + punto_de_rocio: puntoDeRocioC, // Punto de Rocio + luxer_uv: Parametros[1].luxer_uv, // UV + luxer_intencidad: luxerIntencidadLux.toFixed(2), // Solar radiacion + viento_direccion: Parametros[1].viento_direccion, // Direccion del Viento + viento_direccion_nombre: vientoNombre, // Direccion Nombre + viento_rafagas: rafagaEnKh, // Rafagas + viento_velocidad: vientoEnKh, // Viento + lluvia_actual: Parametros[1].lloviendo, // Lluvia Actual + lluvia_acumulado_hora: lluviaHoraMm, // Lluvia Acumulado + lluvia_acumulado_diario: lluviaDiaMm, // Lluvia Acumulado Dia + lluvia_acumulado_total: Parametros[1].lluvia_acumulado_total, // Lluvia Acumulado Total + presion_relativa: presionRelhpa, // Presion Relativa + presion_absoluta: presionRelhpa, // Presion Absoluta + software: versionEMA, // Software + tanque: Parametros[1].tanque // Si el registro es tanqueado (true o false) + }); + var ParametrosTemp6 = JSON.stringify(Parametros, null, 4); + center.sendObservations(function (err, success) { + if (err != null) { + cbFunc('emacentergugler', 'ERROR', err, idRed6, ParametrosTemp6); + } else { + cbFunc('emacentergugler', 'OK', 'ok', idRed6, ParametrosTemp6); + } + }); + center = null; + EMACENTER = null; + break; + + case 'awekas': + var AWEKAS = require('./redes/awekas'); + var awekas = new AWEKAS(Parametros[0][1], Parametros[0][2]); + var idRed7 = Parametros[2]; + awekas.resetObservations(); + awekas.setObservations({ + dateutc: 'now', // fecha actual + tempf: temperaturaExternaF, // Temp. Externa + indoortempf: temperaturaInternaF, // Temp. Interna + indoorhumidity: Parametros[1].humedad_interna, // Humedad Interna + humidity: Parametros[1].humedad_externa, // Humedad Externa + dewptf: puntoDeRocioF.toFixed(2), // Punto de Rocio + UV: Parametros[1].luxer_uv, // UV + solarradiation: luxerIntencidad.toFixed(2), // Solar radiacion + winddir: Parametros[1].viento_direccion, // Direccion del Viento + windgustmph: rafagaEnMh.toFixed(2), // Rafagas + windspeedmph: vientoEnMh.toFixed(2), // Viento + rainin: lluviaHorain.toFixed(2), // Lluvia Acumulado Hora + dailyrainin: lluviaDiain.toFixed(2), // Lluvia Acumulado Dia + baromin: presionRelIn.toFixed(2), // Presion Relativa + softwaretype: versionEMA // Software + }); + var ParametrosTemp7 = JSON.stringify(Parametros, null, 4); + awekas.sendObservations(function (err, success) { + if (err != null) { + cbFunc('awekas', 'ERROR', err, idRed7, ParametrosTemp7); + } else { + cbFunc('awekas', 'OK', 'ok', idRed7, ParametrosTemp7); + } + }); + awekas = null; + AWEKA = null; + break; + + case 'windy': + var WINDY = require('./redes/windy'); + var windy = new WINDY(Parametros[0][1], Parametros[0][2]); + var idRed8 = Parametros[2]; + windy.resetObservations(); + windy.setObservations({ + dateutc: Parametros[1].fechaUTC, // Fecha actual UTC + tempf: temperaturaExternaF.toFixed(2), // Temp. Externa + winddir: Parametros[1].viento_direccion, // Direccion del Viento + windspeedmph: vientoEnMh.toFixed(2), // Viento en millas + windgustmph: rafagaEnMh.toFixed(2), // Rafagas + rh: Parametros[1].humedad_externa, // Humedad Externa + rainin: lluviaHorain.toFixed(2), // Lluvia Acumulado Hora + uv: Parametros[1].luxer_uv, // UV + dewpoint: puntoDeRocioC.toFixed(2), // Punto de Rocio + baromin: presionRelIn.toFixed(2) // Presion Relativa + }); + var ParametrosTemp8 = JSON.stringify(Parametros, null, 4); + windy.sendObservations(function (err, success) { + if (err != null) { + cbFunc('windy', 'ERROR', err, idRed8, ParametrosTemp8); + } else { + // codigo de respuesta 430 No enviado - por tiempo limite no superado + if (success[0] === 430) { cbFunc('windy', 430, success[1], idRed8, ParametrosTemp8);} + else{ + // codigo de respuesta 429 red congestionada + if (success[0] === 429) { + cbFunc('windy', 429, success[1], idRed8, ParametrosTemp8); + } else { + cbFunc('windy', 'OK', 'ok', idRed8, ParametrosTemp8); + } + } + } + }); + windy = null; + WINDY = null; + break; + + case 'openweathermap': + var OPENW = require('./redes/openweathermap'); + var openw = new OPENW(Parametros[0][1]); + var idRed9 = Parametros[2]; + openw.resetObservations(); + openw.setObservations({ + dt: Parametros[1].fechaUTC, // fecha actual UNIX + temperature: temperaturaExternaC, // Temp. Externa + humidity: Parametros[1].humedad_externa, // Humedad Externa % + dew_point: puntoDeRocioC, // Punto de Rocio + wind_deg: Parametros[1].viento_direccion, // Direccion del Viento + wind_gust: rafagaEnMs, // Rafagas + wind_speed: vientoEnMs, // Viento + rain_1h: lluviaHoraMm, // Lluvia Acumulado Hora + rain_24h: lluviaDiaMm, // Lluvia Acumulado Dia + pressure: presionRelhpa // Presion Relativa + }); + var ParametrosTemp9 = JSON.stringify(Parametros, null, 4); + openw.sendObservations(function (err, success) { + if (err != null) { + cbFunc('openweathermap', 'ERROR', err, idRed, ParametrosTemp9); + } else { // codigo de respuesta 429 red congestionada + if (success[0] === 429) { + cbFunc('openweathermap', 429, success[1], idRed9, ParametrosTemp9); + } else { + cbFunc('openweathermap', 'OK', 'ok', idRed9, ParametrosTemp9); + } + } + }); + openw = null; + OPENW = null; + break; + default: + console.log('No Existe la red metorologica: ' + Parametros[0][0]); + } + // Se eliminan las variables utilizadas. + temperaturaExternaF = null; puntoDeRocioF = null; vientoEnMh = null; + presionRelIn = null; rafagaEnMh = null; lluviaHoraMm = null; + lluviaDiaMm = null; lluviaHorain = null; lluviaDiain = null; + luxerIntencidad = null; temperaturaInternaF = null; temperaturaExternaC = null; + luxerIntencidadLux = null; + vientoEnNudos = null; rafagaEnNudos = null; presionRelhpa = null; + fechaformato = null; temperaturaInternaC = null; puntoDeRocioC = null; + vientoEnKh = null; rafagaEnKh = null; vientoNombre = null; + vientoEnMs = null; rafagaEnMs = null; + }, + // En desarrollo + RegistrarRedesMeteorologicas: function (Parametros, cbFunc) { + switch (Parametros[0][0]) { + case 'openweathermap': + var OPENW = require('./redes/openweathermap'); + var openw = new OPENW(Parametros[0][2]); + var idRed8 = Parametros[2]; + var ParametrosTemp8 = JSON.stringify(Parametros, null, 4); + openw.resetObservations(); + openw.sendObservations(function (err, success) { + if (err != null) { + cbFunc('openweathermap', 'ERROR', err, idRed8, ParametrosTemp8); + } else { // codigo de respuesta 429 red congestionada + if (success[0] === 429) { + cbFunc('openweathermap', 429, success[1], idRed8, ParametrosTemp8); + } else { + cbFunc('openweathermap', 'OK', 'ok', idRed8, ParametrosTemp8); + } + } + }); + openw = null; + OPENW = null; + break; + default: + console.log('No Existe la red metorologica: ' + Parametros[0][0]); + } + } +}; diff --git a/src/core/reporte.js b/src/core/reporte.js new file mode 100644 index 0000000..5e318d9 --- /dev/null +++ b/src/core/reporte.js @@ -0,0 +1,493 @@ +/** + * Este archivo es parte del proyecto EMA Libre. + * + * Contiene el codigo fuente, cuya funcion principal + * es presentar una interfaz interactiva en modo consola o shell + * permitiendo iniciar, detener y visualizar el estado y los registros + * de EMA Libre Cliente, tanto en modo web como en modo consola nativo. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +// Require the lib, get a working terminal +//const request = require('request'); +const http = require('http'); +const term = require( 'terminal-kit' ).terminal ; +const fsconf = require('fs'); +var configGeneralEMA = eval(fsconf.readFileSync('./conf/ConfiguracionGeneral.js')+''); +var configGlobalEMA = eval(fsconf.readFileSync('./conf/ConfiguracionGlobal.js')+''); +var intervalo; +var modoTemp; +// CODIGO PRINCIPAL + +function Principal(continuo) +{ + consultarModo().then(modo => + { + if(continuo == false) {ArmarMenu(modo);} + if(!(JSON.stringify(modo) === JSON.stringify(modoTemp))) {ArmarMenu(modo);} + MostrarUltimoRegistro(modo); + }); +} + +///////////////////////// +// METODOS Y FUNCIONES // +///////////////////////// + +function Salir(){ + clearInterval(intervalo); + process.exit() ; +} + +//Consulta si existe el modo Carpincho Web +const consultarModo = function (){ + return new Promise((resultado, error)=> + { + let modoWeb= false; + let estadoServicio = false; + let archivopid; + let pidNodeConsola = false; + let estadoweb= false + // Se encuentra corriendo node consola + if (fsconf.existsSync("/var/run/emalibre.pid")) + { + archivopid = fsconf.readFileSync('/var/run/emalibre.pid'); + //archivopid = JSON.parse(archivopid); + pidNodeConsola = archivopid; + estadoConsola = true; + }else{estadoConsola = false;} + // Existe el modo web instalado + if (fsconf.existsSync("./gui_web")) + { + modoWeb= true; + http.get('http://127.0.0.1:8080/EMA_Estado', (res) => { + const { statusCode } = res; + if (statusCode == 200) + { // Web corriendo + estadoServicio = true; + }else{ // Web detenido + estadoServicio = false; + } + res.setEncoding('utf8'); + let rawData = ''; + res.on('data', (chunk) => { rawData += chunk; }); + res.on('end', () => { + try { + const parsedData = JSON.parse(rawData); + estadoServicio = true; + estadoweb = parsedData[0]; + resultado([modoWeb,estadoServicio, estadoweb, estadoConsola, pidNodeConsola]); + } catch (e) { + estadoServicio = false; + estadoweb = false; + resultado([modoWeb,estadoServicio, estadoweb, estadoConsola, pidNodeConsola]); + } + }); + }); + }else{ + modoWeb=false;estadoServicio=false;estadoweb=false; + resultado([modoWeb,estadoServicio, estadoweb, estadoConsola, pidNodeConsola]); + } + }) + } + +function controlarTamañoConsola() + { + if(term.width < 68 || term.height < 25) + { + term.reset(); + term.wrap.red('\n\nImposible abir la consola, con el tamañno actual de la terminal.'); + term.wrap.red('\nTamaño Actual->Ancho: '+term.width+' Alto:'+term.height) + term.wrap.cyan('\nConfigurar al menos 25x68\n\n\n'); + Salir(); + } + } + +function ArmarMenu (modo) + { + modoTemp = modo; + //EL MODO TIENE true/false de la siguiente forma: [web,estoservicio, estadoweb, estadoconsola] + term.reset(); + var options = { + y: 1 , + separator: ' ', + style: term.inverse , + selectedStyle: term.dim.blue.bgGreen + } ; + var items; + let texto= fsconf.readFileSync('/etc/emalibre_modo'); + items = [ 'EMA Libre ' , 'Logs ' , 'Salir' ] ; + term.singleLineMenu( items , options , function( error , response ) { + term( '\n' ).eraseLineAfter.green( Menu(response.selectedText)) ; + }); + + let modotexto; + if(modo[0]){modotexto ="Web/Consola";}else{modotexto="Consola";} + term.moveTo( 2 , 2 , '' ) ; + term.wrapColumn( { x: 2 , width: 50, height: 2, offset: 0, continue:true } ); + term.wrap.brightCyan('Modos: '); + term.wrap.white(modotexto); + term.wrap.brightCyan(' Modo Actual: '); + term.wrap.brightGreen(texto); + } + +function MostrarUltimoRegistro(modo) + { + obtenerTanques(); + try{ + term.moveTo( 2 , 3 , '' ) ; + term.wrapColumn( { x: 1 , width: 50, height: 50, offset: 0, continue:true } ); + term.wrap.brightCyan('Version: '); + term.wrap.brightWhite(configGlobalEMA.ConfGlobal.Version + 'v'); + term.wrap.brightCyan(' Recolecta: '); + term.wrap.brightGreen(configGeneralEMA.ConfGeneral.Tiempo_de_Recoleccion + ' s'); + term.wrap.brightCyan(' Modo Operación: '); + term.wrap.brightGreen(configGeneralEMA.ConfGeneral.Modo); + term.wrap.cyan('\n' ); + if(modo[0] && modo[1]) + { + // Se consulta por API (modo web) + // ESTADO + http.get('http://127.0.0.1:8080/EMA_Estado', (res) => { + const { statusCode } = res; + term.moveTo( 2 , 4 , '' ) ; + if (statusCode == 200) + { // Web corriendo + estadoServicio = true; + }else{ // Web detenido + estadoServicio = false; + } + res.setEncoding('utf8'); + let rawData = ''; + res.on('data', (chunk) => { rawData += chunk; }); + res.on('end', () => { + try { + term.wrapColumn( { x: 1 , width: 50, height: 50, offset: 0, continue:true } ); + const parsedData = JSON.parse(rawData); + estadoweb = parsedData[0]; + var estado; + term.wrap.brightCyan('Estado: ' ); + if(estadoweb == true){estado='Encendida';term.wrap.brightGreen(estado); } + else{estado='Detenida ';term.wrap.brightRed(estado);} + + } catch (e) { + term.reset(); + term.wrap.brightGreen('\nNo esta corriendo el servicio web\n'); + Principal(false); + return true; + } + }); + }); + + //Ultimo Registro + http.get('http://127.0.0.1:8080/UltimoRegistro', (res) => { + const { statusCode } = res; + term.moveTo( 2 , 4 , '' ) ; + res.setEncoding('utf8'); + let rawData = ''; + res.on('data', (chunk) => { rawData += chunk; }); + res.on('end', () => { + try { + body = JSON.parse(rawData); + term.moveTo( 22 , 4 , '' ) ; + term.wrapColumn( { x: 2 , width: 31, height: 9, offset: 0, continue:true } ); + term.wrap.brightCyan('Ult. Regi: ' ); + term.wrap.brightGreen(body.fecha); + term.moveTo( 2 , 6 , '' ) ; + term.wrapColumn( { x: 2 , width: 24, height: 9, offset: 0, continue:true } ); + term.wrap.yellow('DATOS EXTERNOS' ); + term.wrap.cyan('\nTemperatura: ' ); + term.wrap.brightWhite((body.temperatura_externa || 'S/D') +'°C '); + term.wrap.cyan('\nHumedad: ' ); + term.wrap.brightWhite((body.humedad_externa || 'S/D') + '% '); + term.wrap.cyan('\nPresion R: ' ); + term.wrap.brightWhite((body.presion_relativa || 'S/D') + ' hpa '); + term.wrap.cyan('\nPunto de rocio: ' ); + term.wrap.brightWhite((body.punto_de_rocio || 'S/D') + '°C '); + term.wrap.cyan('\nIluminancia: ' ); + term.wrap.brightWhite((body.luxer_intencidad || '0') + ' lux '); + term.wrap.cyan('\nUV: ' ); + term.wrap.brightWhite((body.luxer_uv || '0') + ' uv '); + term.wrap.cyan('\nViento V.: ' ); + term.wrap.brightWhite((body.viento_velocidad || 'S/D') + ' Km/h '); + term.wrap.cyan('\nViento R.: ' ); + term.wrap.brightWhite((body.viento_rafagas || 'S/D') + ' Km/h '); + term.wrap.cyan('\nViento N.: ' ); + term.wrap.brightWhite((body.viento_direccion_nombre || 'S/D')+ ' '); + term.wrap.yellow('\n\nLLUVIA ACUMULADA' ); + term.wrap.cyan('\nActual: ') + term.wrap.brightWhite((body.lloviendo || '0') + ' mm '); + term.wrap.cyan(' Hora: ') + term.wrap.brightWhite((body.lluvia_acu_hora || '0') + ' mm '); + term.wrap.cyan(' Diaria: ' ); + term.wrap.brightWhite((body.lluvia_acu_diaria || '0') + ' mm '); + term.wrap.cyan(' Total: ' ); + term.wrap.brightWhite((body.lluvia_acumulado_total || '0') + ' mm '); + term.moveTo( 28 , 6 , '' ) ; + term.wrapColumn( { x: 28 , width: 24, height: 3, offset: 0, continue:true } ); + term.wrap.yellow('DATOS INTERNOS' ); + term.wrap.cyan('\nTemperatura: ' ); + term.wrap.brightWhite((body.temperatura_interna || 'S/D') +'°C '); + term.wrap.cyan('\nHumedad: ' ); + term.wrap.brightWhite((body.humedad_interna || 'S/D') + '% '); + + } catch (e) { + term.moveTo( 2 , 6 , '' ) ; + term.wrap.yellow('SIN DATOS' ); + return false; + } + }); + }); + //Ultimo Registro REDES ENVIADAS + http.get('http://127.0.0.1:8080/UltimoRegistro', (res) => { + const { statusCode } = res; + term.moveTo( 1 , 19 , '' ) ; + term.wrapColumn( { x: 2 , width: 80, height: 50, offset: 0, continue:true } ); + term.wrap.yellow('\nREDES ENVIADAS' ); + if (statusCode == 200) + { // Web corriendo + estadoServicio = true; + }else{ // Web detenido + estadoServicio = false; + } + res.setEncoding('utf8'); + let rawData = ''; + res.on('data', (chunk) => { rawData += chunk; }); + res.on('end', () => { + try { + body = JSON.parse(rawData); + if(typeof body[0] !== 'undefined' && body[0] !== null) + { + for (var i=0; i < body.length - 1; ++i) + { + if(typeof body[i].red !== 'undefined' && body[i].red !== null) + { + term.wrap.cyan('\n'+(body[i].red || 0)+':' ); + if (body[i].estado){ + term.wrap.white(body[i].fecha || 0); + term.wrap.green(' - '+ (body[i].estado || false) +' '); + }else{term.wrap.brightRed(body[i].fecha || false); + term.wrap.red(' - '+ (body[i].estado || false) +' '); + } + } + } + }else{ term.wrap.cyan('\n S/D'); } + term.moveTo( 1 , 1 , '' ) ; + + } catch (e) { + return false; + } + }); + }); + + + }else + { // Modo Consola consultar por archivo + obtenerRegistroConsola(); + } + } catch(err){ + Principal(false); + } + // Al final se posiciona en el punto inicial + term.moveTo( 1 , 1 , '' ) ; + } + + +function obtenerRegistroConsola () + { + try{ + //Se trae el archivo de registros diarios y se parcea. + let Archivo = fsconf.readFileSync('./logs/registro_diario.log', {encoding: 'utf8', autoClose: true}); + let RegistroDiario = JSON.parse(Archivo); + let UltimoRegistro = RegistroDiario.length - 1; + if(UltimoRegistro<1){ UltimoRegistro = 0; + RegistroDiarioT = { + fecha: '-', + temperatura_externa: '-', + humedad_externa: '-', + punto_de_rocio: '-', + luxer_intencidad: '-', + luxer_uv: '-', + viento_velocidad: '-', + presion_relativa: '-', + viento_rafagas: '-', + viento_direccion_nombre: '-', + lloviendo: '-', + lluvia_acu_hora: '-', + lluvia_acu_diaria: '-', + lluvia_acumulado_total: '-', + temperatura_interna: '-', + humedad_interna: '-' + }; + RegistroDiario.push(RegistroDiarioT); + } + //ESTADO + term.moveTo( 2 , 4 , '' ) ; + term.wrapColumn( { x: 1 , width: 50, height: 50, offset: 0, continue:true } ); + let estado; + term.wrap.brightCyan('Estado: ' ); + if(fsconf.existsSync("/var/run/emalibre.pid")){estado='Encendida';term.wrap.brightGreen(estado); } + else{estado='Detenida ';term.wrap.brightRed(estado);} + // ULTIMO REGISTRO + term.moveTo( 28 , 4 , '' ) ; + term.wrapColumn( { x: 2 , width: 31, height: 9, offset: 0, continue:true } ); + term.wrap.brightCyan('Ult. Regi: ' ); + term.wrap.yellow( RegistroDiario[UltimoRegistro].fecha); + term.moveTo( 2 , 6 , '' ) ; + term.wrapColumn( { x: 2 , width: 24, height: 9, offset: 0, continue:true } ); + term.wrap.yellow('DATOS EXTERNOS' ); + term.wrap.cyan('\nTemperatura: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].temperatura_externa || 'S/D') +'°C '); + term.wrap.cyan('\nHumedad: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].humedad_externa || 'S/D') + '% '); + term.wrap.cyan('\nPresion R: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].presion_relativa || 'S/D') + ' hpa '); + term.wrap.cyan('\nPunto de rocio: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].punto_de_rocio || 'S/D') + '°C '); + term.wrap.cyan('\nIluminancia: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].luxer_intencidad || '0') + ' lux '); + term.wrap.cyan('\nUV: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].luxer_uv || '0') + ' uv '); + term.wrap.cyan('\nViento V.: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].viento_velocidad || 'S/D') + ' Km/h '); + term.wrap.cyan('\nViento R.: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].viento_rafagas || 'S/D') + ' Km/h '); + term.wrap.cyan('\nViento N.: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].viento_direccion_nombre || 'S/D')+ ' '); + term.wrap.yellow('\n\nLLUVIA ACUMULADA' ); + term.wrap.cyan('\nActual: ') + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].lloviendo || '0') + ' mm '); + term.wrap.cyan(' Hora: ') + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].lluvia_acu_hora || '0') + ' mm '); + term.wrap.cyan(' Diaria: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].lluvia_acu_diaria || '0') + ' mm '); + term.wrap.cyan(' Total: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].lluvia_acumulado_total || '0') + ' mm '); + term.moveTo( 28 , 6 , '' ) ; + term.wrapColumn( { x: 28 , width: 24, height: 3, offset: 0, continue:true } ); + term.wrap.yellow('DATOS INTERNOS' ); + term.wrap.cyan('\nTemperatura: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].temperatura_interna || 'S/D') +'°C '); + term.wrap.cyan('\nHumedad: ' ); + term.wrap.brightWhite((RegistroDiario[UltimoRegistro].humedad_interna || 'S/D') + '% '); + } catch(err){ + setTimeout(function () { Principal(false);}, 2000); + } + + } +function obtenerTanques () + { + // Aplica en todos los modos (mira archivos) + //Datos de los archivo de LOGS, REGISTROS y TANQUE + term.moveTo( 11 , 9 , '' ) ; + term.wrapColumn( { x: 28 , width: 50, height: 50, offset: 0, continue:true } ); + // TANQUE DIARIO + term.wrap.yellow('\nTANQUES DEL SISTEMA' ); + if (fsconf.existsSync("./logs/registro_diario.log")) + {let estadoarchivoTD = fsconf.statSync("./logs/registro_diario.log"); + let TamanioenMegaTD = (estadoarchivoTD.size)/ 1000000.0; + term.wrap.cyan('\nTanque Diario: ' ); + term.wrap.brightWhite(TamanioenMegaTD.toFixed(2) + ' Mb'); + estadoarchivoTD=null;TamanioenMegaTD=null; + }else{term.wrap.brightWhite('No existe');} + // TANQUE PENDIENTE + if (fsconf.existsSync("./logs/TanquePendientes.log")) + {var estadoarchivoTP = fsconf.statSync("./logs/TanquePendientes.log"); + var TamanioenMegaTP = (estadoarchivoTP.size)/ 1000000.0; + term.wrap.cyan('\nTanque Pendiente: ' ); + term.wrap.brightWhite(TamanioenMegaTP.toFixed(2) + ' Mb'); + estadoarchivoTP=null;TamanioenMegaTP=null; + }else{term.wrap.brightWhite('No existe');} + // ARHCIVO DE LOGS + if (fsconf.existsSync("./logs/debug.log")) + {var estadoarchivoD = fsconf.statSync("./logs/debug.log"); + var TamanioenMegaD = (estadoarchivoD.size)/ 1000000.0; + term.wrap.cyan('\nTanque Debug: ' ); + term.wrap.brightWhite(TamanioenMegaD.toFixed(2) + ' Mb'); + estadoarchivoD=null;TamanioenMegaD=null; + }else{term.wrap.brightWhite('No existe');} + term.moveTo( 1 , 1 , '' ) ; + } +function obtenerLog () + { + term.moveTo( 1 , 2 , '' ) ; + term.wrapColumn( { x: 0 , width: 80, height: 50, offset: 0, continue:true } ); + term.wrap.cyan('REGISTROS EN TIEMPO REAL '); + term.moveTo( 1 , 3 , '' ) ; + term.wrapColumn( { x: 0 , width: 80, height: 50, offset: 0, continue:true } ); + let Archivo = fsconf.readFileSync('./logs/debug.log', {encoding: 'utf8', autoClose: true}); + Archivo = Archivo.split('\n'); + let CantidadRegistrosInicio = Archivo.length - 22 + if (CantidadRegistrosInicio < 10) { + term.wrap.cyan('FECHA HORA | DETALLE DEL REGISTRO'); + term.wrap.cyan('\n' ); + term.wrap.cyan(' --------- NO HAY REGISTROS -------------'); + for (var i=0; i < 19; ++i) + {term.brightWhite("\n ");} + } else { + term.wrap.cyan('FECHA HORA | DETALLE DEL REGISTRO'); + term.wrap.cyan('\n' ); + for (var i=CantidadRegistrosInicio; i < Archivo.length - 1; ++i) + { + let Resultado = Archivo[i].split("|"); + term.wrap.eraseLineAfter.brightWhite(Resultado[0].substring(0,16) +'|' + Resultado[2].substring(0,48)); + term.wrap.eraseLineAfter.cyan('\n' ); + } + term.moveTo( 1 , 25 , '' ) ; + term.wrap.cyan('---------------------------------------------------------'); + term.moveTo( 1 , 1 , '' ) ; + } + } + +function Menu(elemento){ + clearInterval(intervalo); + intervalo = setInterval(function () { Principal(true);}, 2000); + switch (elemento) { + case 'EMA Libre ': + // Nada solo se refresca + break; + case 'Logs ': + clearInterval(intervalo); + intervalo = setInterval(function () { obtenerLog();}, 3000); + term.moveTo( 1 , 2 , '' ) ; + term.brightWhite( "\n-----------------------------------------------------------"); + term.brightWhite( "\nObteniendo los logs del sistema, Espere ... "); + term.brightWhite( "\n-----------------------------------------------------------"); + for (var i=0; i < 19; ++i) + {term.brightWhite("\n ");} + break; + case 'Salir': + term.reset(); + term.white( "Hasta Luego!!!") ; + term.magenta('\n' ); + Salir(); + break; + default: + term.magenta( "No existe menu creado para: "+ elemento ) ; + } +setTimeout(function () { Principal(false);}, 2000); +} + +// Intervalo Continuo +term.reset(); +Principal(false); +intervalo = setInterval(function () { Principal(true);}, 2000); + \ No newline at end of file diff --git a/src/core/validaciones.js b/src/core/validaciones.js new file mode 100644 index 0000000..04c0601 --- /dev/null +++ b/src/core/validaciones.js @@ -0,0 +1,125 @@ +/** + * Este archivo es parte del proyecto EMA Libre. + * + * El codigo fuente, brinda la funcionalidad de validacion basica de los + * de datos metorologicos recolectados. + * + * Este archivo, contiene metodos que validan si cada registro recolectado(temperatura, humedad, etc) + * esta dentro de los rangos estipulados como correctos, en caso contrario devuelve un error + * indicando que validacion no fue superada. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +module.exports = { + Registros: function (Parametros, callback) { + switch (Parametros[0]) { + case 'validar': + var Bandera = 0; + var textoerror = ''; + + // Se valida los datos recolectados + + // Sensores Externos + if (Parametros[1][17].rain_overflow === true) { + textoerror += ' VAL: Problemas con el sensor de lluvia.'; + Bandera += 1; + } + if (Parametros[1][17].lost_sensor_contact === true) { + textoerror += ' VAL: Problemas con la RF de la estacion externa.'; + Bandera += 1; + } + // temperatura externa + if (Parametros[1][2] < -40 || Parametros[1][2] > 60 || Parametros[1][2] == null) { + textoerror += ' VAL: Temp. Externa: ' + Parametros[1][2]; + Bandera += 1; + } + // temperatura interna + if (Parametros[1][3] < -10 || Parametros[1][3] > 60 || Parametros[1][3] == null) { + textoerror += ' VAL: Temp. Interna: ' + Parametros[1][3]; + Bandera += 1; + } + // Humedad Interna + if ( Parametros[1][4] < 10 || Parametros[1][4] > 99 ||Parametros[1][4] == null) { + Bandera += 1; + textoerror += ' VAL: Humedad Interna: ' + Parametros[1][4]; + } + // Humedad Externa + if (Parametros[1][5] < 10 || Parametros[1][5] > 99 || Parametros[1][5] == null) { + textoerror += ' VAL: Humedad Externa: ' + Parametros[1][5]; + Bandera += 1; + } + // Luz Intencidad (luxer) - No obligatoria + if (Parametros[1][6] < 0 || Parametros[1][6] > 400000 ||Parametros[1][6] == null) { + textoerror += ' VAL(no obligatoria): Luz Intencidad: ' + Parametros[1][6]; + } + // Rayos UV - No obligatoria + if (Parametros[1][7] > 20 || Parametros[1][7] < 0 || Parametros[1][7] == null) { + textoerror += ' VAL(no obligatoria): Rayos UV: ' + Parametros[1][7]; + } + // Viento vel. + if (Parametros[1][8] < 0 || Parametros[1][8] > 180 || Parametros[1][8] == null) { + Bandera += 1; + textoerror += ' VAL: Viento vel.: ' + Parametros[1][8]; + } + // Viento Rafagas + if (Parametros[1][9] < 0 || Parametros[1][9] > 180 || Parametros[1][9] == null) { + Bandera += 1; + textoerror += ' VAL: Viento rafagas: ' + Parametros[1][9]; + } + // Viento Direccion + if (Parametros[1][10] < 0 || Parametros[1][10] > 360 || Parametros[1][10] == null) { + Bandera += 1; + textoerror += ' VAL: Viento Dir. fuera de rango: ' + Parametros[1][10]; + } + // P. Absoluta + if (Parametros[1][12] < 0 || Parametros[1][12] > 1100 || Parametros[1][12] == null) { + textoerror += ' VAL: Presion Absoluta: ' + Parametros[1][12]; + Bandera += 1; + } + // P.Relativa + if (Parametros[1][13] < 500 || Parametros[1][13] > 1100 ||Parametros[1][13] == null) { + textoerror += ' VAL: Presion Relativa: ' + Parametros[1][13]; + Bandera += 1; + } + // P.Lluvia Totoal + if (Parametros[1][14] < 0 || Parametros[1][14] > 999999 ||Parametros[1][14] == null) { + textoerror += ' VAL: Lluvia total: ' + Parametros[1][14]; + Bandera += 1; + } + // Punto Rocio + if (Parametros[1][15] > 100 || Parametros[1][15] < -50 || Parametros[1][15] == null) { + textoerror += ' VAL: Punto Rocio: ' + Parametros[1][15]; + Bandera += 1; + } + if (Bandera === 0) { + callback(null, true); + } else { + callback([Bandera,textoerror], false); + } + Bandera = null; + textoerror = null; + break; + default: + console.log('N/A Ningun Tipo de validacion'); + } + } +}; diff --git a/src/gui/controlador/admin_update.js b/src/gui/controlador/admin_update.js new file mode 100644 index 0000000..be0b1fc --- /dev/null +++ b/src/gui/controlador/admin_update.js @@ -0,0 +1,172 @@ +/** + * Archivo que brinda funciones para la actualización de EmaLibre + * Solamente para la plataforma Windows. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +// **********************Dependencias ************************************************** + +var gui = require('nw.gui'); // Libreria Grafica +var fs = require('fs'); +var path = require('path'); + +// **********************Vairales Generales******************************************** +var icono_apagado = './gui_common/iconos/icono_off.png'; // Imagen del Icono Apagado +var tray = null; +var Minimizado = false; // Variables Generales + +// **********************COMIENZO ***************************************************** + +var win = gui.Window.get(); // Se genera la ventana +var cantidadArchivosTotal = 0; +var cantidadDirecotirosTotal = -1; +var cantidadDirecotirosTotalActualizados = -1; +var cantidadArchivosActualizados = 0; +var despliegeOrigen = './'; +var despliegeDestino = '../'; + +// **********************Iconizado **************************************************** + +tray = new gui.Tray({ icon: icono_apagado }); +tray.tooltip = 'Ema Libre Carpincho'; + +function ActualizarAPP () { + document.getElementById('barra').style.width = '0%'; + DespliegeRecursivo(despliegeOrigen, despliegeDestino); + $('#botonactualizar').attr('disabled', true); + $('#botonactualizar').addClass('disabled'); + $('#botonreiniciar').attr('disabled', false); + $('#botonreiniciar').removeClass('disabled'); +} + +function ReiniciarAPP () { + const { + spawn + } = require('child_process'); + const child = spawn('../EmaLibre.exe', [], { + detached: true, + stdio: 'ignore' + }); + child.unref(); + gui.App.closeAllWindows(); + gui.App.quit(); + win.close(); + process.exit(1); +} + +function DespliegeRecursivo (src, dest) { + var excluir = true; + var existssrc = fs.existsSync(src); + var statssrc = existssrc && fs.statSync(src); + var isDirectorysrc = existssrc && statssrc.isDirectory(); + if (src === 'tmp') { + excluir = false; + } + sleep(500).then(() => { + if (existssrc && isDirectorysrc && excluir) { + cantidadDirecotirosTotalActualizados++; + fs.readdirSync(src).forEach(function (childItemName) { + var Destino = path.join(dest, childItemName); + var Origen = path.join(src, childItemName); + // Se comprueba si el orgien es directorio + var existssrc = fs.existsSync(Origen); + var statssrc = existssrc && fs.statSync(Origen); + var isDirectoryOrigen = existssrc && statssrc.isDirectory(); + // Se comprueba si el destino existe y es un directorio + var existsdesc = fs.existsSync(Destino); + var statsdesc = existsdesc && fs.statSync(Destino); + var isDirectorydesc = existsdesc && statsdesc.isDirectory(); + if (existsdesc && isDirectorydesc) { + $('#nombreArchivo').html(cantidadArchivosActualizados); + DespliegeRecursivo(Origen, Destino); + } else { + try { + if (!isDirectoryOrigen && !isDirectorydesc) { + cantidadArchivosActualizados++; + $('#nombreArchivo').html(cantidadArchivosActualizados); + copyFile(Origen, Destino); + document.getElementById('barra').style.width = ((cantidadArchivosActualizados * 100) / cantidadArchivosTotal).toFixed() + '%'; + document.getElementById('barra').innerHTML = ((cantidadArchivosActualizados * 100) / cantidadArchivosTotal).toFixed() + '% / ' + 100; + } else { + fs.mkdirSync(Destino); + } // Crea directorio que no existe + } catch (e) { + alert(e); + } + DespliegeRecursivo(Origen, Destino); + } + }); + } else { // Listo + $('#nombreArchivo').html(cantidadArchivosActualizados + ' (' + cantidadDirecotirosTotalActualizados + ' Directorios )'); + if ((cantidadArchivosActualizados) >= cantidadArchivosTotal - 5) { + $('#botonreiniciar').removeClass('hidden'); + $('#botonactualizar').addClass('hidden'); + $('#texto').html('Actualización realizada con exito!!'); + } + } + }); +} + +function copyFile (source, target) { + return new Promise(function (resolve, reject) { + var rd = fs.createReadStream(source); + rd.on('error', rejectCleanup); + var wr = fs.createWriteStream(target); + wr.on('error', rejectCleanup); + + function rejectCleanup (err) { + rd.destroy(); + wr.end(); + reject(err); + } + wr.on('finish', resolve); + rd.pipe(wr); + }); +} + +function ContarArchivos (src, dest) { + var excluir = true; + var existssrc = fs.existsSync(src); + var statssrc = existssrc && fs.statSync(src); + var isDirectorysrc = existssrc && statssrc.isDirectory(); + if (src === 'tmp') { + excluir = false; + } + if (existssrc && isDirectorysrc && excluir) { + cantidadDirecotirosTotal++; + fs.readdirSync(src).forEach(function (childItemName) { + var Origen = path.join(src, childItemName); + var existssrc = fs.existsSync(Origen); + var statssrc = existssrc && fs.statSync(Origen); + var isDirectoryOrigen = existssrc && statssrc.isDirectory(); + if (isDirectoryOrigen) { + ContarArchivos(Origen, '../'); + } else { + cantidadArchivosTotal++; + ContarArchivos(Origen, '../'); + } + }); + } + $('#nombreArchivoT').html(cantidadArchivosTotal + ' (' + cantidadDirecotirosTotal + ' Directorios)'); +} + +function sleep (time) { return new Promise((resolve) => setTimeout(resolve, time)); } diff --git a/src/gui/controlador/admingui.js b/src/gui/controlador/admingui.js new file mode 100644 index 0000000..d0c4bfa --- /dev/null +++ b/src/gui/controlador/admingui.js @@ -0,0 +1,740 @@ +/** + * Archivo principal de la administracion grafica de la aplicacion EMA Libre. + * + * Archivo de inicio el entorno grafico GUI del sistema EMA Libre que nos + * brinda una pantalla con las opciones: Configuracion general del sistema, + * ABM de Redes Meteorologicas,Visualizacion del sensores e informacion enviadas a la redes y + * reportes de log, como historicos registrados. + * + * LICENSE: This file is part of EMA Libre. + * EMA Libre is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EMA Libre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EMA Libre. If not, see . + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +// **********************Dependencias ************************** +const configGeneralEMA = require('./../conf/ConfiguracionGeneral.js'); // Configuracion General +const configGlobalEMA = require('./../conf/ConfiguracionGlobal.js'); // Configuracion Global +const funcionesActualizar = require('./../core/actualizar.js'); // Se incluye el core de EMA. +const EMA = require('./../core/ema.js'); // Se incluye el core de EMA. +const gui = require('nw.gui'); // Libreria Grafica +// **********************Vairales Generales********************* +const iconoEncendido = './gui_common/iconos/icono_enc.png'; // Imagen del Icono Encendido +const iconoApagado = './gui_common/iconos/icono_off.png'; // Imagen del Icono Apagado +const iconoPublicado = './gui_common/iconos/icono_pub.png'; // Imagen del Icono Prublicado --> no utilizada +const iconoNeutro = '../gui_common/img/neutro.webp'; // Imagen del Icono Neutro +const iconoControlTrue = '../gui_common/img/ok.webp'; // Imagen de Control TRUE +const iconoControlFalse = '../gui_common/img/no.webp'; // Imagen de Control FALSE +//var tray = null; +var UltimoReg; +var Ant_UltimoReg; +var ModeloVisor; // Variables Generales - Registros recolectados +var destanqueo = 0; +var intervaloBarra = 0; +var cant = 0; +var tiempovisor=99; +// **********************Iconizado / Menu Superior ********************************************************* +gui.App.clearCache(); // Se limpia cache +win = gui.Window.get(); // Se obtiene la ventana actual +menuItems = new gui.Menu(); +menuItems.append(new gui.MenuItem({ label: 'Iniciar', click: function () { INICIAR(); } })); +menuItems.append(new gui.MenuItem({ label: 'Detener', click: function () { DETENER(); } })); +menu = new gui.Menu({ type: 'menubar' }); +menu.append(new gui.MenuItem({ label: 'EMA CONTROL', submenu: menuItems })); +menu.append(new gui.MenuItem({ label: 'Mostrar', click: function () { win.setShowInTaskbar(true); } })); +menu.append(new gui.MenuItem({ label: 'Ocultar', click: function () { win.setShowInTaskbar(false); } })); +menu.append(new gui.MenuItem({ label: 'Salir', click: function () { EMA.Salir(); gui.App.closeAllWindows();win.close(true); } })); +// se crea el tray icon +tray = new gui.Tray ({title : ' EmaLibre Carpincho ' , icon : iconoApagado }); + + +tray.tooltip = 'Ema Libre Carpincho'; +tray.menu = menu; +tray.on('click', function () { win.show(true); MuestraRegistroActual(false); Graficos(); ClimaActual(); }); +//new gui.Shortcut({ key: 'F11', active: function () { win.toggleFullscreen(); } }) + +// **********************Funciones Principales de la GUI ***************************************************** + +const esperar = ms => new Promise(function(resolve){setTimeout(resolve, ms);}); + +// Captura el redimencionamiento de la ventana +win.on('resize', (width, height) => { + if (width < 775 && height < 555) { win.zoomLevel = -2.4; } + if (width > 775 && height > 555) { win.zoomLevel = -1.8; } + if (width > 800 && height > 600) { win.zoomLevel = -1.5; } + if (width > 850 && height > 690) { win.zoomLevel = -0.6; } + if (width > 1000 && height > 800) { win.zoomLevel = 0; } + if (width > 1200 && height > 820) { win.zoomLevel = 0.3; } + if (width > 1200 && height > 900) { win.zoomLevel = 0.9; } + if (width > 1400 && height > 1000) { win.zoomLevel = 1.2; } +}); + +function INICIAR () { + if (configGeneralEMA.ConfGeneral.Modo === 'Visor') { // se comprueba el modo + HABLA(0, 'Se inicio en modo Visor', 'success'); + $('#signal').addClass('parpadea'); + } else { + EMA.Conectar(); + HABLA(0, 'Se inicio en modo Recolector', 'success'); + $('#signal').addClass('parpadea'); + } + tray.icon = iconoEncendido; + $('td#barralateral').css('background-color', '#11881161'); + $('#estado').html('En Linea'); + $('#mensaje').html('Encendido'); + $('#botoniniciar').attr('disabled', true); + $('#botondetener').attr('disabled', false); + RegistroActual(); + clearInterval(intervaloBarra); + intervaloBarra = window.setInterval(function () { BarradeProgreso();}, 200); + //console.log('Nuevo IntervaloId: '+ intervaloBarra); +} + +async function iniciarAutomaticamente () { + EstadoMenuInicio(); + if (configGeneralEMA.ConfGeneral.inicio_automatico) { + await esperar(4000); + HABLA(0, 'Iniciando Automaticamente..', 'info'); + if ($('#mensaje').html() === 'Encienda EMA Libre') { + await esperar(5000); + INICIAR(); + } else { + HABLA(0, 'No se pudo iniciar automaticamente, verifique el error', 'info'); + } + } +} + +function DETENER () { + clearInterval(intervaloBarra); + tray.icon = iconoApagado; + $('td#barralateral').css('background-color', '#ff000030'); + $('#estado').html('Fuera de Linea'); + $('#img_estado').attr('src', iconoNeutro); + $('#mensaje').html('EMA Libre se encuentra detenida'); + $('#mensajedetalle').html('Se detuvo manualmente.'); + $('#img_detalle').attr('src', iconoNeutro); + $('#img_mensaje').attr('src', iconoNeutro); + $('#botoniniciar').attr('disabled', false); + $('#botondetener').attr('disabled', true); + if (configGeneralEMA.ConfGeneral.Modo === 'Visor') { // se comprueba el modo + HABLA(0, 'Modo visor detenido', 'error'); + $('#signal').removeClass('parpadea'); + } else { + EMA.Detener(); + HABLA(0, 'Modo Recolector detenido', 'error'); + $('#signal').removeClass('parpadea'); + } +} +async function redimensionarInicio () + { + $('#loadinicio').attr('src', '../gui_common/iconos/icono_app_guina.webp'); + await esperar(500); + $('#loadinicio').attr('src', '../gui_common/iconos/icono_app.webp'); + await esperar(600); + $('#cargador').empty(); + $('#cargador').remove(); + $('#principal').show(); + win.setMinimumSize(700, 500); + win.setMaximumSize(4000, 2000); + win.maximize(); + HABLA(0, '...', 'info'); + await esperar(1000); + HABLA(0, 'Bienvenido a Ema Libre Cliente, me llaman Carpincho.', 'info'); + iniciarAutomaticamente(); + } + + + +async function Actualizar () { + var plataforma = process.platform; + var SO_WIN = plataforma.indexOf('win'); + if (SO_WIN === 0) { + funcionesActualizar.Control(function (resultado, VersionActual, nueva) { + $('#botonactualizar').attr('disabled', true); + if (resultado && VersionActual) { + DETENER(); + HABLA(0, 'Descargando nueva versión de Carpincho: ' + nueva, 'info'); + NProgress.set(0); + $('#mensajebarra').html('Descargando nueva versión, espere ....'); + funcionesActualizar.Descargar(nueva, function (resultadoact, avance, porcentaje) { + NProgress.set(porcentaje/100); + $('#mensajebarra').html(avance); + if (resultadoact && avance) { + NProgress.set(1); + $('#mensajebarra').html('Descomprimiendo la nueva versión, espere ....'); + HABLA(0, 'Descomprimiendo la nueva versión, espere ....', 'info'); + funcionesActualizar.Descomprimir(function (resultadoact) { + if (resultadoact) { + $('#mensajebarra').html('Borrado del archivo descargado, espere ....'); + funcionesActualizar.Desplegar(function (resultado) { + if (resultado) { + HABLA(0, 'Ejecutando App de Actualizacion, espere...', 'info'); + setTimeout(funcionesActualizar.LanzarAplicativoIndependiente, 9000); + } else { + HABLA(0, 'Ocurrio un problema en el despliege, intente mas tarde', 'error'); + } + }); + } else { + HABLA(0, 'Ocurrio un problema descomprimiendo, intente mas tarde', 'error'); + } + }); + } + if (!resultadoact && !avance) { + HABLA(0, 'Ocurrio un problema en la descarga, intente mas tarde', 'error'); + } + }); + } + if (!resultado && VersionActual) { + HABLA(0, 'No hay versiones nuevas disponibles', 'success'); + } + if (!resultado && !VersionActual) { + HABLA(0, 'No se pudo conectar al servidor de versiones,pruebe mas tarde...', 'error'); + } + }); + } else { + + HABLA(0, 'Esta opción solo es válida para sistemas operativos Windows.', 'warn'); + await esperar(4000); + HABLA(0, 'Pero usted puede actualizar EMA Libre con su sistema de paquetes nativo.', 'info'); + await esperar(4000); + HABLA(0, 'O puede ingresar a https://ema.gugler.com.ar para más información. ', 'info'); + } + $('#botonactualizar').attr('disabled', false); +} + +async function HABLA (num, mesg, tipo) { + var tamañomsg = mesg.length; + if (num === 0) { + $('#carpincho_img').notify(mesg, { + className: tipo, + position: 'right middle', + autoHideDelay: (tamañomsg * 90) + }); + if (configGeneralEMA.ConfGeneral.Audio) { + window.speechSynthesis.cancel(); + var voices = window.speechSynthesis.getVoices(); + var cantidadVoces = voices.length; + //console.log(cantidadVoces); + if( cantidadVoces > 0){ + var seleccionada = voices.filter(function (voice) { return voice.name === configGeneralEMA.ConfGeneral.audioVoces; })[0]; + //console.log(seleccionada); + var msg = new SpeechSynthesisUtterance (mesg); + msg.voice = seleccionada; + msg.rate = 1.2; + msg.pitch = 1; + window.speechSynthesis.speak(msg); + msg=null;seleccionada=null;voices=null;cantidadVoces=null; + } + } + } + if ($('#carpincho_img').attr('src') === '../gui_common/iconos/icono_app.webp') { + $('#carpincho_img').attr('src', '../gui_common/iconos/icono_app_habla.webp'); + } else { + $('#carpincho_img').attr('src', '../gui_common/iconos/icono_app.webp'); + } + num++; + if (num < tamañomsg) { + await esperar(90); + HABLA(num ,mesg ,0); + } else { + $('#carpincho_img').attr('src', '../gui_common/iconos/icono_app.webp'); + //LimpiarMemoria(true); + } + num=null;tamañomsg = null; +} + +async function GUIÑA (num) + { + if ($('#carpincho_img').attr('src') === '../gui_common/iconos/icono_app.webp') { + $('#carpincho_img').attr('src', '../gui_common/iconos/icono_app_guina.webp'); + } else { + $('#carpincho_img').attr('src', '../gui_common/iconos/icono_app.webp'); + } + num++; + if (num < 2) { + await esperar(400); + GUIÑA(num); + } else { + $('#carpincho_img').attr('src', '../gui_common/iconos/icono_app.webp'); + } + num =null; + } + + +async function controlPendientes () { + var pendientes = EMA.HayPendientes(); + var DIVPENDIENTE = document.getElementById('DIVPendientes'); + var SPANTANQUE = document.getElementById('Destanqueo'); + var DIVModo = document.getElementById('DIVModo'); + if (pendientes !== false) + { + DIVPENDIENTE.style.visibility = 'visible'; + if ((pendientes < destanqueo)) {SPANTANQUE.style.visibility = 'visible'; } else {SPANTANQUE.style.visibility = 'hidden'; } + destanqueo = pendientes; + $('#Pendientes').html(" Cantidad: " + pendientes + '
'); + } else { + destanqueo = 0; + DIVPENDIENTE.style.visibility = 'hidden'; + SPANTANQUE.style.visibility = 'hidden'; + DIVModo.style.visibility = 'hidden'; + } + pendientes = null; + DIVPENDIENTE = null; + SPANTANQUE = null; + DIVModo = null; + return true; + } + +async function mostrarEstados (EstadoSensores) { + // Se consulta por los sensores + var Resultado = !((EstadoSensores.lost_sensor_contact) || (EstadoSensores.rain_overflow)); + if (Resultado && (configGeneralEMA.ConfGeneral.Modo !== 'Visor')) { + $('#signal').attr('src', '../gui_common/img/signal.webp'); + $('#signal').addClass('parpadea'); + } else { + if (!EstadoSensores.lost_sensor_contact) { + HABLA(0, 'Perdida de la señal de Radio Frecuencia', 'warn'); + } + if (!EstadoSensores.rain_overflow) { + HABLA(0, 'Sensor de lluvia externo sobrecargado', 'warn'); + } + $('#signal').attr('src', '../gui_common/img/no_signal.webp'); + $('#signal').addClass('parpadea'); + win.requestAttention(3); + } + EstadoSensores = null; + Resultado = null; + } + +async function RegistroActual (barratermino) + { + //console.log('ENTRO REGISTRO ACTUAL'); + + if (configGeneralEMA.ConfGeneral.Modo === 'Recolector') + { // se comprueba el modo se encuentra en Recolector + if(barratermino == true){ + //BARRA TERMINO + //console.log('ENTRO AL BARRA TERMINO RECOLECTOR'); + await esperar(100); + EstadoMenuInicio(); + await esperar(100); + if (win.x > -10000) MuestraRegistroActual(true); + await esperar(100); + if (win.x > -10000) Graficos(); + await esperar(100); + if (win.x > -10000) ClimaActual(); + await esperar(1500); + if (win.x > -10000) RegistroPublicado(); + cant=0; + } + + var EstadoEMA = EMA.Estado(); + if (EstadoEMA[0] === true) + { + $('#mensaje').html('Recolectando.'); + $('#img_mensaje').attr('src', iconoControlTrue); + $('#mensajedetalle').html('Operando.'); + $('#img_detalle').attr('src', iconoControlTrue); + controlPendientes(); + UltimoReg = EMA.UltimoRegistro(); + var EstadoSensores = EMA.EstadoSensores(); + if(EstadoSensores !== false) + { + mostrarEstados(EstadoSensores); + }else{EstadoSensores=null;} + if (UltimoReg == false) { + // Se consulta por la cantidad de errores + if (EMA.RepeticionesConError() > 2) { + await esperar(10000); + HABLA(0, 'No se pueden obtener registros (Intentos ' + EMA.RepeticionesConError() + '). Desconecte y vuelva a conectar el USB. Se prueba reiniciar el servicio.', 'error'); + await esperar(15000); + DETENER(); + await esperar(5000); + INICIAR(); + return false; + } else { + $('#mensaje').html('(' + EMA.RepeticionesConError() + ') Sincronizando ...'); + $('#img_mensaje').attr('src', iconoNeutro); + await esperar(200); + RegistroActual(); + return false; + } + } + } else { + $('#mensaje').html('EmaLibre detenida.'); + $('#img_mensaje').attr('src', iconoControlFalse); + $('#mensajedetalle').html(EstadoEMA[1]); + $('#img_detalle').attr('src', iconoControlFalse); + await esperar(5000); + RegistroActual(); + return false; + } + } else { // Modo visor + if(barratermino == true){ + //BARRA TERMINO + await esperar(100); + EstadoMenuInicio(); + await esperar(100); + if (win.x > -10000) MuestraRegistroActual(true); + await esperar(100); + if (win.x > -10000) Graficos(); + await esperar(100); + if (win.x > -10000) ClimaActual(); + cant=0; + } + $('#signal').attr('src', '../gui_common/img/visor.webp'); + var cantreg = 1; + EMA.Visor(cantreg, function (error, datos) { + if (error != null) { + HABLA(0, 'No se pueden obtener datos del servidor. ' + error, 'info'); + $('#signal').removeClass('parpadea'); + setTimeout(function(){RegistroActual();}, 10000); + } else { + $('#signal').addClass('parpadea'); + var DIVModo = document.getElementById('DIVModo'); + DIVModo.style.visibility = 'visible'; + document.getElementById('DIVModo').innerHTML = " Modo Visor
" + datos.pais + ', ' + datos.ciudad + "
" + datos.modelo + ''; + UltimoReg = datos.registros[0]; + ModeloVisor = datos.nombre; + // se convierte la fecha + var db = new Date(datos.registros[0].fecha); + var minutos = db.getMinutes(); + if (minutos <= 9) { minutos = '0' + minutos; } + var hora = db.getHours(); + if (hora <= 9) { hora = '0' + hora; } + var mes = db.getMonth() + 1; + if (mes <= 9) { mes = '0' + mes; } + var dia = db.getDate(); + if (dia <= 9) { dia = '0' + dia; } + var segundo = db.getSeconds(); + if (segundo <= 9) { segundo = '0' + segundo; } + var fecha = dia + '/' + mes + '/' + db.getFullYear() + ' ' + hora + ':' + minutos + ':' + segundo; + UltimoReg.fecha = fecha; + fecha=null;dia=null;mes=null;segundo=null;minutos=null;hora=null;db=null; + // ver acumulados de lluvia + UltimoReg.lloviendo = datos.registros[0].lluvia_actual; + UltimoReg.lluvia_acu_hora = datos.registros[0].lluvia_acumulado_hora; + UltimoReg.lluvia_acu_diaria = datos.registros[0].lluvia_acumulado_diario; + UltimoReg.lluvia_acumulado_total = datos.registros[0].lluvia_acumulado_total; + // Maximas y minimas, no llegan de EMACENTER, por el momento se setean en 0. + UltimoReg.temperatura_externa_max_dia = 0; + UltimoReg.temperatura_externa_min_dia = 0; + UltimoReg.temperatura_interna_max_dia = 0; + UltimoReg.temperatura_interna_min_dia = 0; + UltimoReg.punto_de_rocio_max_dia = 0; + UltimoReg.punto_de_rocio_min_dia = 0; + UltimoReg.humedad_externa_max_dia = 0; + UltimoReg.humedad_externa_min_dia = 0; + UltimoReg.humedad_interna_max_dia = 0; + UltimoReg.humedad_interna_min_dia = 0; + UltimoReg.luxer_intencidad_max_dia = 0; + UltimoReg.luxer_intencidad_min_dia = 0; + UltimoReg.luxer_uv_max_dia = 0; + UltimoReg.luxer_uv_min_dia = 0; + UltimoReg.presion_relativa_max_dia = 0; + UltimoReg.presion_relativa_min_dia = 0; + tiempovisor = tiempovisor - 0.2; + } + + }); + } + EstadoEMA = null; +} + +async function BarradeProgreso () { + // const startTime = performance.now(); + // Se consulta el tiempo actual del recolector + if (configGeneralEMA.ConfGeneral.Modo === 'Recolector') + { // EN MODO RECOLECTOR + var tiempoActualRecolector; + tiempoActualRecolector = EMA.TiempoActualRecolector(); + if(tiempoActualRecolector[0] !== false || tiempoActualRecolector[1] > 0) + { + + if ((tiempoActualRecolector[0] < 98 && tiempoActualRecolector[1] > 0.39) ) + { + // CONTINUA ADENTRO + if (win.x > -10000) + { // Solo si no esta minimizado + NProgress.set(tiempoActualRecolector[0]/100); + return false; + } + } else { + // Cuando termine cada barra, publica y luego vuelve al leer el registro actual + cant++; + if(cant == 1){ RegistroActual(true);} else{return true;}; + // solo si esta en modo visor + if (configGeneralEMA.ConfGeneral.Modo !== 'Recolector') {document.getElementById('RedesMet').innerHTML = "" + ModeloVisor + ': ' + UltimoReg.fecha.substring(10, 20) + '
';} + if (win.x > -10000) + { // Solo si no esta minimizado + NProgress.done(); + } + } + }else{ if(cant > 0){return false;} + if (win.x > -10000) + { // Solo si no esta minimizado + NProgress.done(); + } + } + } else { // MODO VISOR + if( tiempovisor != 99) + { + if( tiempovisor >= configGeneralEMA.ConfGeneral.Tiempo_de_Recoleccion) + { + tiempovisor = 0; + RegistroActual(true); + if (win.x > -10000) NProgress.done(); + }else{ + tiempovisor = tiempovisor + 0.2; // se le suma el tiempo del intervalo + var tiempo_barra = ((tiempovisor * 100) / configGeneralEMA.ConfGeneral.Tiempo_de_Recoleccion)/100; + if (win.x > -10000) NProgress.set(tiempo_barra); + } + } + } + + UltimoPub = null;aux=null;tiempoActualRecolector = null; tiempo_barra = null; + /* const duration = performance.now() - startTime; + console.log(` Tiempo barra: ${duration}ms`);*/ + +} + + +// ********************** Menu Acciones ******************************************************************* +function MenuConfig () { + if ($('#Modo').val() === 'Recolector') { + $('#LlaveR').attr('disabled', true); + $('#LlaveR').val(''); + $('#LlaveR').hide(); + } else { + $('#LlaveR').attr('disabled', false); + $('#LlaveR').show(); + $('#Llave_R').val(configGeneralEMA.ConfGeneral.Llave_R); + } + if ($('#Tipo_SMTP').val() === 'Deshabilitado') { + $('#Usuario_SMTP').attr('disabled', true); + $('#Contrasenia_SMTP').attr('disabled', true); + $('#Puerto_SMTP').attr('disabled', true); + $('#Server_SMTP').attr('disabled', true); + $('#Puerto_SMTP').val(''); + $('#puerto').hide(); + $('#Server_SMTP').val(''); + $('#Server').hide(); + } else { + $('#Usuario_SMTP').attr('disabled', false); + $('#Contrasenia_SMTP').attr('disabled', false); + if ($('#Tipo_SMTP').val() === 'Manual') { + $('#Puerto_SMTP').attr('disabled', false); + $('#puerto').show(); + $('#Server_SMTP').attr('disabled', false); + $('#Server').show(); + } else { + $('#Puerto_SMTP').attr('disabled', true); + $('#puerto').hide(); + $('#Server_SMTP').attr('disabled', true); + $('#Server').hide(); + } + $('#Usuario_SMTP').val(configGeneralEMA.ConfEmail.Usuario); + $('#Contrasenia_SMTP').val(configGeneralEMA.ConfEmail.Password); + $('#Server_SMTP').val(configGeneralEMA.ConfEmail.Server); + $('#Puerto_SMTP').val(configGeneralEMA.ConfEmail.Puerto); + } + if ($('#audio').val() === 'Desactivado') { + $('#vocesAudioDiv').attr('disabled', true); + $('#vocesAudioDiv').val(''); + $('#vocesAudioDiv').hide(); + } else { + $('#vocesAudioDiv').attr('disabled', false); + $('#vocesAudioDiv').show(); + $('#vocesAudio').val(configGeneralEMA.ConfGeneral.audioVoces); + $('#vocesAudio').selectpicker('render'); + } +} + +async function MenuGUI (elemento) { + try { + document.getElementById("actualizando_inicio").hidden = false; + document.getElementById("actualizando_inicio").style.display = "block"; + var seleccion; + if (elemento === 'logs') {seleccion = document.getElementById('configuracion');} + else {seleccion = document.getElementById(elemento);} + $(seleccion).empty(); + $(seleccion).hide(); + $(seleccion).load('./view/modelo_' + elemento + '.html', function (datosArchivo) { + switch (elemento) { + case 'logs': + VerRegistrosLog(); + $('#interior').empty();$('#exterior').empty();$('#inicio').empty();$('#contacto').empty();$('#inicio').empty();$('#estadisticas').empty(); + break; + case 'redes': + ListarRedes(); + $('#interior').empty();$('#exterior').empty();$('#contacto').empty();$('#configuracion').empty();$('#inicio').empty();$('#estadisticas').empty(); + break; + case 'redes_alta': + MenuSelectRed(); + break; + case 'inicio': + $('#node_pid').html(process.pid); + $('#node_ppid').html(process.ppid); + $('#versiones').attr('title', versiones); + $('#nwjs_v').html(version_nwjs); + EstadoMenuInicio(); + $('#interior').empty();$('#exterior').empty();$('#contacto').empty();$('#configuracion').empty();$('#redes').empty();$('#estadisticas').empty(); + break; + case 'interior': + MuestraRegistroActual(false,'interior'); + Graficos('interior'); + $('#inicio').empty();$('#exterior').empty();$('#contacto').empty();$('#configuracion').empty();$('#redes').empty();$('#estadisticas').empty(); + break; + case 'exterior': + MuestraRegistroActual(false,'exterior'); + Graficos('exterior'); + $('#interior').empty();$('#inicio').empty();$('#contacto').empty();$('#configuracion').empty();$('#redes').empty();$('#estadisticas').empty(); + break; + case 'estadisticas': + graficoEstadisticas(); + $('#interior').empty();$('#exterior').empty();$('#inicio').empty();$('#contacto').empty();$('#configuracion').empty();$('#redes').empty(); + break; + case 'contacto': + var NombreVersion = ' v' + configGlobalEMA.ConfGlobal.Version; + $('#versioncontacto').html(NombreVersion); + $('#interior').empty();$('#exterior').empty();$('#inicio').empty();$('#configuracion').empty();$('#redes').empty();$('#estadisticas').empty(); + break; + case 'configuracion': + $('#interior').empty();$('#exterior').empty();$('#contacto').empty();$('#inicio').empty();$('#redes').empty();$('#estadisticas').empty(); + // Se obtienen las voces del sistema + var synth = window.speechSynthesis; + const voice = synth.getVoices(); + var voiceSelect = document.getElementById('vocesAudio'); + var cantidadVoces = voice.length; + if( cantidadVoces > 0){ + for (var i = 0; i < cantidadVoces; i++) + { + var option = document.createElement('option'); + option.textContent = voice[i].name; + option.setAttribute('value', voice[i].name); + voiceSelect.appendChild(option); + } + }else{ + var option = document.createElement('option'); + voice[0] = 'Sin Voces'; + option.textContent = 'Sin voces, verifique el SO'; + option.setAttribute('value', 'Sin Voces'); + voiceSelect.appendChild(option); + voiceSelect.selectedIndex = "0"; + } + + $('#NombreEstacion').val(configGeneralEMA.ConfGeneral.NombreEstacion); + $('#Modo').val(configGeneralEMA.ConfGeneral.Modo); + $('#Modo').selectpicker('render'); + $('#SistemaMetrico').val(configGeneralEMA.ConfGeneral.SistemaMetrico); + $('#SistemaMetrico').selectpicker('render'); + $('#Llave_R').val(configGeneralEMA.ConfGeneral.Llave_R); + $('#Tiempo_de_Recoleccion').val(configGeneralEMA.ConfGeneral.Tiempo_de_Recoleccion); + $('#Email_receptor').val(configGeneralEMA.ConfEmail.ReceptorEmail); + $('#Tipo_SMTP').val(configGeneralEMA.ConfEmail.Servicio); + $('#Tipo_SMTP').selectpicker('render'); + $('#Tiempo_de_Recoleccion').selectpicker('render'); + $('#Debug').val(configGeneralEMA.ConfGeneral.debug); + $('#debugMB').val(configGeneralEMA.ConfGeneral.debugTamanio); + $('#Debug').selectpicker('render'); + var automatico; + if (configGeneralEMA.ConfGeneral.inicio_automatico) { automatico = 'Activado'; } else { automatico = 'Desactivado'; } + $('#inicio_auto').val(automatico); + $('#inicio_auto').selectpicker('render'); + var cambios; + if (configGeneralEMA.ConfGeneral.notificar_cambios) { cambios = 'Activado'; } else { cambios = 'Desactivado'; } + $('#notificar_cambios').val(cambios); + $('#notificar_cambios').selectpicker('render'); + var Audio; + if (configGeneralEMA.ConfGeneral.Audio) { Audio = 'Activado'; } else { Audio = 'Desactivado'; } + $('#audio').val(Audio); + $('#audio').selectpicker('render'); + $('#utc').val(configGeneralEMA.ConfGeneral.UTC); + $('#utc').selectpicker('render'); + // Control para el audio + if (configGeneralEMA.ConfGeneral.Audio === false) { + $('#vocesAudioDiv').attr('disabled', true); + $('#vocesAudioDiv').val(''); + $('#vocesAudioDiv').hide(); + } else { + $('#vocesAudioDiv').attr('disabled', false); + $('#vocesAudioDiv').show(); + if (configGeneralEMA.ConfGeneral.audioVoces === null || typeof configGeneralEMA.ConfGeneral.audioVoces === 'undefined') { $('#vocesAudio').val(voice[0].name); } else { $('#vocesAudio').val(configGeneralEMA.ConfGeneral.audioVoces); } + } + $('#vocesAudio').selectpicker('render'); + // Control para el modo + if ($('#Modo').val() === 'Recolector') { + $('#LlaveR').attr('disabled', true); + $('#LlaveR').val(''); + $('#LlaveR').hide(); + } else { + $('#LlaveR').attr('disabled', false); + $('#LlaveR').show(); + $('#Llave_R').val(configGeneralEMA.ConfGeneral.Llave_R); + } + // Control para el SMTP + if ($('#Tipo_SMTP').val() === 'Deshabilitado') { + $('#Usuario_SMTP').attr('disabled', true); + $('#Contrasenia_SMTP').attr('disabled', true); + $('#Puerto_SMTP').attr('disabled', true); + $('#Server_SMTP').attr('disabled', true); + $('#Server').hide(); + $('#puerto').hide(); + } else { + $('#Usuario_SMTP').attr('disabled', false); + $('#Contrasenia_SMTP').attr('disabled', false); + $('#Server_SMTP').attr('disabled', false); + $('#Puerto_SMTP').attr('disabled', false); + $('#Usuario_SMTP').val(configGeneralEMA.ConfEmail.Usuario); + $('#Contrasenia_SMTP').val(configGeneralEMA.ConfEmail.Password); + $('#Server_SMTP').val(configGeneralEMA.ConfEmail.Server); + $('#Puerto_SMTP').val(configGeneralEMA.ConfEmail.Puerto); + if ($('#Tipo_SMTP').val() === 'Manual') { + $('#Server_SMTP').attr('disabled', false); + $('#Puerto_SMTP').attr('disabled', false); + $('#puerto').show(); + $('#Server').show(); + } else { + $('#puerto').hide(); + $('#Server').hide(); + } + } + break; + default: + console.log('No existe el menu seleccionado: ' + elemento); + } + setTimeout(function(){ document.getElementById("actualizando_inicio").style.display = "none"; + document.getElementById("actualizando_inicio").hidden = false; + $(seleccion).show(); + }, 200); + + }); + + } catch (e) { // Si falla se informa y se vuelve a cargar el modelo interior + HABLA(0, 'Se realizó un reload de la libreria grafica interior', 'info'); + } +} + +async function autoLoad () + { + await esperar(6000); + var plataforma = process.platform; + var SO_WIN = plataforma.indexOf('win'); + if (SO_WIN === 0) { funcionesActualizar.Control(function (resultado, VersionActual, nueva) { if (resultado) { HABLA(0, 'Hay una nueva version de Carpincho. Versión ' + nueva, 'error'); } }); } + } +autoLoad(); \ No newline at end of file diff --git a/src/gui/controlador/funcionesgenerales.js b/src/gui/controlador/funcionesgenerales.js new file mode 100644 index 0000000..69926e5 --- /dev/null +++ b/src/gui/controlador/funcionesgenerales.js @@ -0,0 +1,1600 @@ +/** +* Archivo de funciones general o soporte para la interfaz grafica GUI de EMA Libre. +* +* Contiene un conjunto de funciones que brindan soporte al sistema EMA. +* +* LICENSE: This file is part of EMA Libre. +* EMA Libre is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* EMA Libre is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with EMA Libre. If not, see . +* +* @copyright Copyright (c) 2019 GUGLER (https://www.gugler.com.ar) +* @license https://www.gnu.org/licenses/gpl-3.0.html GPL License +* @version 3.0 +* @link https://www.gugler.com.ar +* @since File available since Release 3.0 +*/ + +// VARIABLES GENERALES + +var fsconf = require('fs'); // Libreria para para poder almacenar/leer archivos en disco(funcion leer/guardar Conf.) +var Sube = ""; // Imagen cuando no hay cambios. +var icono_control_true = '../gui_common/img/ok.webp'; // Imagen de Control TRUE +var icono_control_false = '../gui_common/img/no.webp'; // Imagen de Control FALSE +var icono_control_neutro = '../gui_common/img/neutro.webp'; // Imagen de Control NEUTRO - ALERT +const version_nwjs = process.versions['nw']; // Version de NWJS +const plataforma = process.platform; +const arquitectura = process.arch; +var AnteriorViento = false; +// Version de Modulos +const ver = process.versions; +var versiones = '
    '; +$.each(ver, function(i, item) { if(i == 'nw' || i == 'chromium' || i =='node'|| i == 'v8' ) versiones += '
  1. '+i +': '+''+item+ '
  2. ';}); +versiones += '
' + + +// El constructor por defecto de Map para transforar (clave-valor) + +var mapaDatosArray = [ ["rf.temp_out", "Temperatura Externa"], + ["rf.temp_in", "Temperatura Interna"], + ["rf.hum_out", "Humedad Externa"], + ["rf.hum_in", "Humedad Interna"], + ["rf.lux", "Luxer"], + ["rf.uv", "Rayos Ultravioletas"], + ["rf.wind_dir", "Dirección del Viento"], + ["rf.wind_gust", "Rafagas de Vientos"], + ["rf.wind_ave", "Vientos"], + ["rf.abs_pressure", "Presion Atmosferica Relativa"], + ["rf.rel_pressure", "Presion Atmosferica Absoluta"], + ["rf.rain", "Lluvia"] + ]; +var mapaDatos = new Map(mapaDatosArray); + + +// Se inicializan variables globales +var tendenciaTE = Igual; var tendenciaR = Igual; +var tendenciaTI=Igual;var tendenciaPA = Igual; +var tendenciaPR = Igual; var tendenciaLI = Igual; +var tendenciaHE = Igual; var tendenciaHI = Igual; +var tendenciaPDR=Igual;var result = "";var gtempint; +var ghumint; var gviento;var gviento1; var EstadoEMA_Control; +// **********************Funciones Generales de la GUI *************************************************** + +async function EstadoMenuInicio() + { + try{ + // Inicio automatico y audio para el menu de inicio + var audiomenu = '-'; + var autoactivado = '-'; + if(configGeneralEMA.ConfGeneral.Audio) { audiomenu = 'Activado';}else{ audiomenu = 'Desactivado';} + if(configGeneralEMA.ConfGeneral.inicio_automatico) { autoactivado = 'Activado';}else{ autoactivado = 'Desactivado';} + $('#audiomenu').html(audiomenu); + $('#autoactivado').html(autoactivado); + audiomenu=null;autoactivado=null; + // Se calcula la Cantidad y tamaño de los Tanques y Debug + if (fsconf.existsSync("logs/registro_diario.log")) + {var estadoarchivoTD = fsconf.statSync("logs/registro_diario.log"); + var TamanioenMegaTD = (estadoarchivoTD.size)/ 1000000.0; + $('#tamanio_diario').html(TamanioenMegaTD.toFixed(2) + ' Mb'); + estadoarchivoTD=null;TamanioenMegaTD=null; + }else{$('#tamanio_diario').html('No Existe');} + if (fsconf.existsSync("logs/TanquePendientes.log")) + {var estadoarchivoTP = fsconf.statSync("logs/TanquePendientes.log"); + var TamanioenMegaTP = (estadoarchivoTP.size)/ 1000000.0; + $('#tamanio_pendiente').html(TamanioenMegaTP.toFixed(2) + ' Mb'); + estadoarchivoTP=null;TamanioenMegaTP=null; + }else{$('#tamanio_pendiente').html('No_Existe');} + if (fsconf.existsSync("logs/debug.log")) + {var estadoarchivoD = fsconf.statSync("logs/debug.log"); + var TamanioenMegaD = (estadoarchivoD.size)/ 1000000.0; + if (TamanioenMegaD >= configGeneralEMA.ConfGeneral.debugTamanio) { HABLA(0, 'Se depura automaticamente el archivo de debug.',"info");} + $('#tamanio_debug').html(TamanioenMegaD.toFixed(2) + ' Mb'); + estadoarchivoD=null;TamanioenMegaD=null; + }else{$('#tamanio_debug').html('No_Existe');} + //Datos Generales + $('#inombre').html(configGeneralEMA.ConfGeneral.NombreEstacion); + $('#botoniniciar').attr("disabled",true); + $('#botondetener').attr("disabled",true) + if(configGeneralEMA.ConfGeneral.NombreEstacion != ''){$("#img_nombre").attr("src",icono_control_true);}else{$("#img_nombre").attr("src",icono_control_neutro);} + $('#iso').html(plataforma + " (" + arquitectura + ")"); + if(plataforma != ''){$("#img_so").attr("src",icono_control_true);}else{$("#img_so").attr("src",icono_control_false);} + $('#imodo').html(configGeneralEMA.ConfGeneral.Modo); + if(configGeneralEMA.ConfGeneral.Modo != ''){$("#img_modo").attr("src",icono_control_true);}else{$("#img_modo").attr("src",icono_control_false);} + if(configGeneralEMA.ConfGeneral.Modo != 'Visor') // Se consulta el modo (Recolector o Visor) + { + EMA.EstadoUSB(function(EstadoUSB) + { + EstadoEMA_Control = EMA.Estado(); + if(EstadoEMA_Control[0]) + { + $("#img_estado").attr("src",icono_control_true);$('#estado').html("En Linea"); + $('#botoniniciar').attr("disabled",true); + $('#botondetener').attr("disabled",false); + if(EstadoUSB){ + $('#iusb').html("USB conectado");$("#img_estacion").attr("src",icono_control_true); + $("#img_detalle").attr("src",icono_control_true);$("#img_mensaje").attr("src",icono_control_true); + } + else{$("#img_estacion").attr("src",icono_control_false);$('#iusb').html("USB no conectado"); + $("#img_mensaje").attr("src",icono_control_false);$('#mensaje').html("Conecte el USB."); + $("#img_detalle").attr("src",icono_control_false);$('#mensajedetalle').html("Verifique / Conecte la estacion USB."); + } + + }else{ + $("#img_estado").attr("src",icono_control_neutro);$('#estado').html("Fuera de Linea"); + if(EstadoUSB){ + $('#iusb').html("USB conectado");$("#img_estacion").attr("src",icono_control_true); + $("#img_detalle").attr("src",icono_control_true);$("#img_mensaje").attr("src",icono_control_true); + $('#mensaje').html("Encienda EMA Libre"); + $('#botoniniciar').attr("disabled",false); + } + else{$("#img_estacion").attr("src",icono_control_false);$('#iusb').html("USB no conectado"); + $('#botoniniciar').attr("disabled",true); + $("#img_mensaje").attr("src",icono_control_false);$('#mensaje').html("Conecte el USB."); + $("#img_detalle").attr("src",icono_control_false);$('#mensajedetalle').html(EstadoEMA_Control[1]); + } + } + EstadoUSB=null; + }); + }else{ // Modo Visor Control + $('#iusb').html("Por Llave Lectura"); + if($( "#signal" ).hasClass( "parpadea" )) + { + $('#estado').html("En Linea"); + $("td#barralateral").css("background-color","#11881161"); + $("#img_estado").attr("src",icono_control_true); + $('#botoniniciar').attr("disabled",true); + $('#botondetener').attr("disabled",false); + $("#img_detalle").attr("src",icono_control_true);$('#mensajedetalle').html("Obteniendo registros."); + }else{ + $('#estado').html("Fuera de Linea"); + $("td#barralateral").css("background-color","#ff000030"); + $("#img_detalle").attr("src",icono_control_false);$('#mensajedetalle').html("Encienda EMA Libre."); + $("#img_estado").attr("src",icono_control_neutro); + $('#botoniniciar').attr("disabled",false); + $('#botondetener').attr("disabled",true); + } + if(configGeneralEMA.ConfGeneral.Llave_R != ''){ + $("#img_mensaje").attr("src",icono_control_true); + $("#img_estacion").attr("src",icono_control_true); + $('#mensaje').html("Utilizando llave (EMA Center)"); + }else{ $("#img_estado").attr("src",icono_control_false); + $("#img_mensaje").attr("src",icono_control_false);$('#mensaje').html("Ingrese la Llave de Lectura."); + $("#img_detalle").attr("src",icono_control_false);$('#mensajedetalle').html("Ingrese la Llave de Lectura."); + } + } + return false; + }catch (ex) {console.log(ex);} + }; + + async function MuestraRegistroActual(parpadeo,click) + { + if(UltimoReg) + { + if(parpadeo){$('#fecha').addClass( "parpadea" );} + $('#fecha').html(UltimoReg.fecha); + if(typeof Ant_UltimoReg == 'undefined'){Ant_UltimoReg = UltimoReg;} //para la primera carga del anterior + //Conversion de UV a Texto + var texto_uv = 0; + var x = UltimoReg.luxer_uv; + switch (true) { + case x > -1 && x <= 2: texto_uv = "Bajo";break; + case x > 2 && x <= 5: texto_uv = "Moderado";break; + case x > 5 && x <= 7: texto_uv = "Alto";break; + case x > 7 && x <= 10: texto_uv = "Muy Alto";break; + case x > 11: texto_uv = "Extremo";break; + } + x = null; + //Calculo de Sensacion Termina + var ST = (13.12+(0.6215 * UltimoReg.temperatura_externa )- (11.37* (UltimoReg.viento_velocidad^0.16))+((0.3965*UltimoReg.temperatura_externa) * (UltimoReg.viento_velocidad^0.16))).toFixed(2); + //Variables del Sistema Metrico + if(configGeneralEMA.ConfGeneral.SistemaMetrico == "SI"){var TEMP_S = " ºC"; var TEMP_MULT = 1;var TEMP_POND = 0;}else{var TEMP_S = " ºF";var TEMP_MULT = 9/5;var TEMP_POND = 32;}; + //Muestra Interior (Temperatura y Humedad) + if(($('#interior').hasClass('active') && typeof click === "undefined") || (click === 'interior')) + { + //***Temperatura Interna + if (UltimoReg.temperatura_interna != Ant_UltimoReg.temperatura_interna){ if (UltimoReg.temperatura_interna > Ant_UltimoReg.temperatura_interna ) {tendenciaTI = Sube + (Ant_UltimoReg.temperatura_interna*TEMP_MULT+TEMP_POND).toFixed(2) + TEMP_S +"|| Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Sube+"'>";}else{tendenciaTI = Baja+(Ant_UltimoReg.temperatura_interna*TEMP_MULT+TEMP_POND).toFixed(2) + TEMP_S + " || Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Baja+"'>";}}else {result = Igual;} + $('#temp_int').html((UltimoReg.temperatura_interna*TEMP_MULT+TEMP_POND).toFixed(1) + TEMP_S + tendenciaTI);$('#temp_int_img').html(result); + //*** Maximos y Minimos + $('#temp_int_max').html((UltimoReg.temperatura_interna_max_dia*TEMP_MULT+TEMP_POND).toFixed(1) + TEMP_S); + $('#temp_int_min').html((UltimoReg.temperatura_interna_min_dia*TEMP_MULT+TEMP_POND).toFixed(1) + TEMP_S); + //*** humedad interna + if (UltimoReg.humedad_interna != Ant_UltimoReg.humedad_interna){ if (UltimoReg.humedad_interna > Ant_UltimoReg.humedad_interna ) {tendenciaHI = Sube + Ant_UltimoReg.humedad_interna+"% || Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Sube+"'>";}else{tendenciaHI = Baja+Ant_UltimoReg.humedad_interna+"% || Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Baja+"'>";}}else {result = Igual;} + $('#hum_int').html(UltimoReg.humedad_interna + " % " + tendenciaHI);$('#hum_int_img').html(result); + //*** Maximos y Minimos + $('#hum_int_max').html(UltimoReg.humedad_interna_max_dia + " %" ); + $('#hum_int_min').html(UltimoReg.humedad_interna_min_dia + " %" ); + } + //Muestra Exterior + if(($('#exterior').hasClass('active') && typeof click === "undefined") || (click === 'exterior')) + { + //CALCULO DE TENDENCIAS Y MUESTRA REGISTRO + //***Temperatura Externa + if (UltimoReg.temperatura_externa != Ant_UltimoReg.temperatura_externa){ if (UltimoReg.temperatura_externa > Ant_UltimoReg.temperatura_externa ) {tendenciaTE = Sube + (Ant_UltimoReg.temperatura_externa*TEMP_MULT+TEMP_POND).toFixed(2)+ TEMP_S +" || Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Sube+"'>";}else{tendenciaTE = Baja+(Ant_UltimoReg.temperatura_externa*TEMP_MULT+TEMP_POND).toFixed(2)+ TEMP_S +" || Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Baja+"'>";}}else {result = Igual;} + $('#temp_ext').html((UltimoReg.temperatura_externa*TEMP_MULT+TEMP_POND).toFixed(1)+ TEMP_S + tendenciaTE);$('#temp_ext_img').html(result); + //*** Maximos y Minimos + $('#temp_ext_max').html((UltimoReg.temperatura_externa_max_dia *TEMP_MULT+TEMP_POND).toFixed(1) + TEMP_S); + $('#temp_ext_min').html((UltimoReg.temperatura_externa_min_dia *TEMP_MULT+TEMP_POND).toFixed(1) + TEMP_S); + + //*** Punto de Rocio + if (UltimoReg.punto_de_rocio != Ant_UltimoReg.punto_de_rocio){ if(UltimoReg.punto_de_rocio > Ant_UltimoReg.punto_de_rocio ) {tendenciaPDR = Sube + (Ant_UltimoReg.punto_de_rocio*TEMP_MULT+TEMP_POND).toFixed(2) + TEMP_S +"|| Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Sube;}else{tendenciaPDR = Baja + (Ant_UltimoReg.punto_de_rocio*TEMP_MULT+TEMP_POND).toFixed(2) + TEMP_S +" || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Baja +"'>";}}else {result = Igual;} + $('#punto_ext').html((UltimoReg.punto_de_rocio*TEMP_MULT+TEMP_POND).toFixed(2) + TEMP_S + tendenciaPDR);$('#punto_ext_img').html(result); + //*** Maximos y Minimos + $('#punto_ext_max').html((UltimoReg.punto_de_rocio_max_dia*TEMP_MULT+TEMP_POND).toFixed(2) + TEMP_S); + $('#punto_ext_min').html((UltimoReg.punto_de_rocio_min_dia*TEMP_MULT+TEMP_POND).toFixed(2) + TEMP_S); + //*** humedad Externa + if (UltimoReg.humedad_externa != Ant_UltimoReg.humedad_externa){ if (UltimoReg.humedad_externa > Ant_UltimoReg.humedad_externa ) {tendenciaHE = Sube + Ant_UltimoReg.humedad_externa+"% || Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Sube+"'>";}else{tendenciaHE = Baja+Ant_UltimoReg.humedad_externa+"% || Fecha: "+ Ant_UltimoReg.fecha +"'>";result = Baja+"'>";}}else {result = Igual;} + $('#hum_ext').html(UltimoReg.humedad_externa + " % " + tendenciaHE);$('#hum_ext_img').html(result); + //*** Maximos y Minimos + $('#hum_ext_max').html(UltimoReg.humedad_externa_max_dia + " %" ); + $('#hum_ext_min').html(UltimoReg.humedad_externa_min_dia + " %" ); + //*** Intenciadad Luz + if(UltimoReg.luxer_intencidad != null) + { + if (UltimoReg.luxer_intencidad != Ant_UltimoReg.luxer_intencidad){ if (UltimoReg.luxer_intencidad > Ant_UltimoReg.luxer_intencidad ) {tendenciaLI = Sube + Ant_UltimoReg.luxer_intencidad + " Lux || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Sube;}else{tendenciaLI = Baja + Ant_UltimoReg.luxer_intencidad+" Lux || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Baja +"'>";}}else {result = Igual;} + $('#luxer_ext').html(UltimoReg.luxer_intencidad + " lux " + tendenciaLI);$('#luxer_ext_img').html(result); + //*** Maximos y Minimos + $('#luxer_ext_max').html((UltimoReg.luxer_intencidad_max_dia*0.001).toFixed(2) + " Klux" ); + $('#luxer_ext_min').html((UltimoReg.luxer_intencidad_min_dia*0.001).toFixed(2) + " Klux" ); + }else{ + $('#luxer_ext').html('S/D'); + $('#luxer_ext_min').html('S/D'); + $('#luxer_ext_max').html('S/D'); + } + //*** Rayos UV + if(UltimoReg.luxer_uv != null) + { + if (UltimoReg.luxer_uv != Ant_UltimoReg.luxer_uv){ if(UltimoReg.luxer_uv > Ant_UltimoReg.luxer_uv ) {tendenciaR = Sube + Ant_UltimoReg.luxer_uv +" UV || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Sube;}else{tendenciaR = Baja + Ant_UltimoReg.luxer_uv+" UV || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Baja +"'>";}}else {result = Igual;} + $('#rayos_ext').html(UltimoReg.luxer_uv + " uv / " +texto_uv + " " + tendenciaR);$('#rayos_img').html(result); + //*** Maximos y Minimos + $('#rayos_ext_max').html(UltimoReg.luxer_uv_max_dia + " uv" ); + $('#rayos_ext_min').html(UltimoReg.luxer_uv_min_dia + " uv" ); + }else{ + $('#rayos_ext').html('S/D'); + $('#rayos_ext_min').html('S/D'); + $('#rayos_ext_max').html('S/D'); + } + //*** Presion Absoluta + if (UltimoReg.presion_absoluta != Ant_UltimoReg.presion_absoluta){ if(UltimoReg.presion_absoluta > Ant_UltimoReg.presion_absoluta ) {tendenciaPA = Sube + Ant_UltimoReg.presion_absoluta +" hpa || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Sube;}else{tendenciaPA = Baja + Ant_UltimoReg.presion_absoluta+" hpa || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Baja +"'>";}}else {result = Igual;} + $('#presiona_ext').html(UltimoReg.presion_absoluta + " hpa " +tendenciaPA);$('#presiona_ext_img').html(result); + //*** Presion Relativa + if (UltimoReg.presion_relativa != Ant_UltimoReg.presion_relativa){ if(UltimoReg.presion_relativa > Ant_UltimoReg.presion_relativa ) {tendenciaPR = Sube + Ant_UltimoReg.presion_relativa +" hpa || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Sube;}else{tendenciaPR = Baja + Ant_UltimoReg.presion_relativa+" hpa || Fecha: "+ Ant_UltimoReg.fecha +"'>";result=Baja +"'>";}}else {result = Igual;} + $('#presionr_ext').html(UltimoReg.presion_relativa + " hpa " + tendenciaPR);$('#presionr_ext_img').html(result); + //*** Maximos y Minimos + $('#presionr_ext_max').html(UltimoReg.presion_relativa_max_dia + " hpa" ); + $('#presionr_ext_min').html(UltimoReg.presion_relativa_min_dia + " hpa" ); + //*** Acumulados Lluvia ----> No tiene tendencias. + $('#lloviendo_ext').html(UltimoReg.lloviendo + "mm"); + $('#totalacuhora_ext').html(UltimoReg.lluvia_acu_hora + "mm"); + $('#totalacudia_ext').html(UltimoReg.lluvia_acu_diaria + "mm"); + $('#totalL_ext').html(UltimoReg.lluvia_acumulado_total + "mm"); + } + // Se guarda el registro anterior + Ant_UltimoReg = UltimoReg; + // Se actualiza los ToolTips + //$(document).ready(function(){$('[data-toggle="tooltip"]').tooltip();}); + } + result=null;parpadeo=null;texto_uv=null;ST=null; + TEMP_S = null; TEMP_MULT = null;TEMP_POND = null; + }; + +async function RegistroPublicado() + { + var redesPub = EMA.UltimoPublicado(); + //Mostrar redes Publicadas + if(redesPub){ + var redespublicadashtml = ""; + for (var key in redesPub) + { + if(redesPub[key].estado === true){ + redespublicadashtml += ""+redesPub[key].red +": "+redesPub[key].fecha.substring(10,19)+"
"; + }else{ + if(redesPub[key].estado == 'No enviado'){ + redespublicadashtml += ""+redesPub[key].red +": "+redesPub[key].fecha.substring(10,19)+"
"; + }else{ + if(redesPub[key].estado == 'Esperar'){ + redespublicadashtml += ""+redesPub[key].red +" "+redesPub[key].fecha.substring(10,19)+"
"; + }else{ + if(redesPub[key].error == "Detenido") + {redespublicadashtml += ""+redesPub[key].red +": "+redesPub[key].fecha.substring(10,19)+"
"; + }else{redespublicadashtml += ""+redesPub[key].red +": "+redesPub[key].fecha.substring(10,19)+"
";} + } + } + } + } + document.getElementById("RedesMet").innerHTML = redespublicadashtml; + }else{ + document.getElementById("RedesMet").innerHTML = "Sin datos
"; + } + redesPub = null;redespublicadashtml = null;key = null; + }; + +async function ClimaActual() + { + // Se obtiene el estado actual del clima + var SALIDA_ENTRADA = "";var LLUEVE = 0; var NOCHE_DIA = 1; + if( UltimoReg.lloviendo > 0){LLUEVE = '1'; }else{LLUEVE = '0';} // LLUEVE? + if( UltimoReg.luxer_intencidad > 0){ NOCHE_DIA = '1'; }else{NOCHE_DIA = '0';} // DIA o NOCHE? + if( (UltimoReg.luxer_intencidad > UltimoReg.luxer_intencidad_1hs) && (UltimoReg.luxer_intencidad > 0 && UltimoReg.luxer_intencidad < 800)){ SALIDA_ENTRADA = '_1.gif';} // ALBA? + if( (UltimoReg.luxer_intencidad < UltimoReg.luxer_intencidad_1hs) && (UltimoReg.luxer_intencidad > 0 && UltimoReg.luxer_intencidad < 800)){ SALIDA_ENTRADA = '_0.gif';} // OCASO? + //Icono central + var image = document.createElement("IMG");image.alt = "Clima Actual";image.setAttribute("height", "96px");image.setAttribute("width", "96px");image.setAttribute('class', 'photo'); + if(SALIDA_ENTRADA != ""){image.src="../gui_common/img/clima/1_0_clima" + SALIDA_ENTRADA; //ver de agregar ALBA Y OCASO con lluvia + }else{image.src="../gui_common/img/clima/" + NOCHE_DIA +"_" + LLUEVE + "_clima" + SALIDA_ENTRADA +".webp";} + $('#clima').html(image); + //Fondo de la aplicacion + if( LLUEVE == 1){HABLA(0,"Se registra lluvia","info"); + if( NOCHE_DIA == 1){$("body").attr('class', 'dia_lluvia');}else{ $("body").attr('class', 'noche_lluvia');} + }else{if( NOCHE_DIA == 1){$("body").attr('class', 'dia');}else{ $("body").attr('class', 'noche');}} + // Hay cambios + if(UltimoReg.cambio === true && configGeneralEMA.ConfGeneral.notificar_cambios === true){ + var cambiosCarpincho = ''; + // Obteniendo todas las claves del JSON + for (var clave in UltimoReg.diferencia){ + // Controlando que json realmente tenga esa propiedad + if (UltimoReg.diferencia.hasOwnProperty(clave)) { + // Mostrando en pantalla la clave junto a su valor + cambiosCarpincho += ' ' + mapaDatos.get(clave) + '.'; //" (" + UltimoReg.diferencia[clave]+"), "; + } + } + if(cambiosCarpincho != '') HABLA(0, 'Hay cambios de ' + cambiosCarpincho ,"info"); + } + // Se borran las variables + SALIDA_ENTRADA=null;NOCHE_DIA=null;LLUEVE=null;image=null; + } + +async function Graficos(click) + { + //Graficos Interior (Temperatura y Humedad) + if(($('#interior').hasClass('active') && typeof click === "undefined" && $("#gtemp_int").length) || (click === 'interior')) + { + if(UltimoReg){var Tint = (UltimoReg.temperatura_interna || 0)}else{var Tint = 0;} + RGraph.ObjectRegistry.clear(gtemp_int); + gtempint = new RGraph.Thermometer({ + id: 'gtemp_int', + min: 0, + max: 100, + value: Tint, + options: { + labelsCount:10, + labelsValue:false, + valueLabelDecimals: 2, + textSize:6, + textColor: 'white', + scaleVisible: true, + textAccessible: false + } + }).grow(); + //color en gradiente + var grad = gtempint.context.createLinearGradient(0,50,0,350); + grad.addColorStop(0., 'Maroon'); + grad.addColorStop(0.85, 'red'); + grad.addColorStop(1, 'LightSalmon'); + gtempint.set({colors: [grad]}).draw(); + if(UltimoReg){var Hint = (UltimoReg.humedad_interna || 0);}else{var Hint=0;} + RGraph.ObjectRegistry.clear(ghum_int); + ghumint = new RGraph.Thermometer({ + id: 'ghum_int', + min: 0, + max: 100, + value: Hint, + options: { + textSize:6, + textColor: 'white', + labelsCount:10, + labelsValue:false, + scaleVisible: true, + colors: ['blue'], + textAccessible: false + } + }).grow(); + //color en gradiente + var grad2 = ghumint.context.createLinearGradient(0,50,0,350); + grad2.addColorStop(0, 'Navy'); + grad2.addColorStop(0.85, 'Blue'); + grad2.addColorStop(1, 'Aqua'); + ghumint.set({colors: [grad2]}).draw(); + grad2=null;Hint=null;Tint=null;grad=null; + }else{gtempint=null;ghumint=null;yaxis=null} + + //Graficos Exterior (Viento Direccion y Viento Velocidad/Rafagas) + if(($('#exterior').hasClass('active') && typeof click === "undefined" && $("#gviento_vel").length) || (click === 'exterior')) + { + //Viento Velocidad/Rafagas + if(configGeneralEMA.ConfGeneral.SistemaMetrico == "SI") + { + if(UltimoReg){var TvientoR = (UltimoReg.viento_rafagas || 0.0); + var Tviento = UltimoReg.viento_velocidad || 0.0; + var unidad = "Km"; + var ponderador = 1;}else{var TvientoR = 0; var Tviento = 0; var unidad = "Km";var ponderador = 1;} + }else{ + if(UltimoReg){var TvientoR = ((UltimoReg.viento_rafagas/3.6)*2.2369) || 0.0; + var Tviento = ((UltimoReg.viento_velocidad/3.6)*2.2369) || 0.0; + TvientoR = TvientoR.toFixed(2); + Tviento = Tviento.toFixed(2); + var ponderador = 0.6213712; + var unidad = "mp"; } + else{ var TvientoR = 0;var Tviento = 0;var unidad = "mp";var ponderador = 0.6213712;} + } + if(UltimoReg){var x = UltimoReg.viento_rafagas || 0.0;}else{var x = 0;} + switch (true) { + case x > -1 && x <= 1: viento_escala = "Calmo";break; + case x > 1 && x <= 5: viento_escala = "Aire Ligero (Ventolina)";break; + case x > 5 && x <= 11: viento_escala = "Brisa Muy Débil (Flojito)";break; + case x > 11 && x <= 19: viento_escala = "Brisa Ligera (Flojo)";break; + case x > 19 && x <= 28: viento_escala = "Brisa Moderada (Bonancible)";break; + case x > 28 && x <= 38: viento_escala = "Brisa Fresca (Fresquito)";break; + case x > 38 && x <= 49: viento_escala = "Brisa Fuerte (Fresco)";break; + case x > 49 && x <= 61: viento_escala = "Viento Fuerte (Frescachón)";break; + case x > 61 && x <= 74: viento_escala = "Viento Duro (Temporal)";break; + case x > 74 && x <= 88: viento_escala = "Viento Muy Duro (Temporal Fuerte)";break; + case x > 88 && x <= 102: viento_escala = "Temporal (Temporal Duro)";break; + case x > 102 && x <= 117: viento_escala = "Borrasca (Temporal Muy Duro)";break; + case x > 117: viento_escala = "Huracán (Temporal huracanado)";break; + } + $('#escala_vientos').html(viento_escala + "1"); + RGraph.ObjectRegistry.clear(gviento_vel); + gviento1 = new RGraph.Gauge({ + id: 'gviento_vel', + min: 0, + max: 140 * ponderador, + value: [Tviento,TvientoR], + options: { + scaleDecimals: 0, + tickmarksSmall: 50, + tickmarksBig: 5, + valuetext: true, + titleTop: 'Viento y Rafagas \n '+Tviento +' / '+TvientoR, + titleTopSize: 6, + textSize: 9, + margin: 0, + titleBottom: unidad, + colorsRanges:[[0, 28*ponderador, 'green'],[28*ponderador, 56*ponderador,'yellow'],[56*ponderador, 84*ponderador,'#FFBF00'],[84*ponderador, 112*ponderador, '#FA8258'],[112*ponderador, 140*ponderador, 'red']], + textAccessible: false + } + }).grow(); + + //Para el span de Vientos Exterior + if(UltimoReg){ + $('#viento_vel_max').html((((UltimoReg.viento_velocidad_max_dia||0))*ponderador).toFixed(2)); + $('#viento_rafag_max').html(((UltimoReg.viento_rafagas_max_dia||0)*ponderador).toFixed(2)); + $('#viento_vel').html(((UltimoReg.viento_velocidad||0)*ponderador).toFixed(2)+unidad); + $('#viento_vel_rafag').html(((UltimoReg.viento_rafagas||0)*ponderador).toFixed(2)+unidad);} + //Viento Direccion + + if(UltimoReg){ + var Tvientodir = UltimoReg.viento_direccion || 0; + var Tvientonombre = UltimoReg.viento_direccion_nombre || 'N/A'; + }else{var Tvientodir = 0; var Tvientonombre = 'N/A';} + x = Tvientodir; + viento_direccion = x; + $('#escala_direccion').html('Vientos del ' + Tvientonombre +' ('+Tvientodir +'º)'); + RGraph.ObjectRegistry.clear(gviento_dir); + //Imagen de Fondo + new RGraph.Drawing.Image({ + id: 'gviento_dir', + x: 15, + y: 15, + src: '../gui_common/img/brujula.webp', + options: { + width: 200, + height: 200 + } + }).draw(); + gviento = new RGraph.Odometer({ + id: 'gviento_dir', + min: 0, + max: 360, + value: Tvientodir, + options: { + border:false, + colorsGreenColor: 'rgba(0,0,0,0)', + colorsYellowColor: 'rgba(0,0,0,0)', + colorsRedColor: 'rgba(0,0,0,0)', + backgroundColor: 'rgba(0,0,0,0)', + backgroundBorder: 'rgba(0,0,0,0)', + backgroundLinesColor: 'rgba(0,0,0,0)', + tickmarksBigColor: 'rgba(0,0,0,0)', + textColor: 'rgba(0,0,0,0)', + needleColor: '#ddd', + tickmarks: false, + needleHead: true, + radius:99, + // needleTail: true, + needleType: 'pointer', + // needleWidth: 4, + needleThickness: 1 + } + }).grow(); + if(UltimoReg){var x = UltimoReg.viento_direccion_prom_dia || 0;}else{var x=0;} + var VientoDireccionProm = ''; + // direccion del viento por nombre promedio + switch (true) { + case x == 0: + VientoDireccionProm= 'Norte'; + break; + case x > 0 && x < 90: + VientoDireccionProm= 'Nordeste'; + break; + case x == 90: + VientoDireccionProm= 'Este'; + break; + case x > 90 && x < 180: + VientoDireccionProm= 'Sudeste'; + break; + case x == 180: + VientoDireccionProm= 'Sur'; + break; + case x > 180 && x < 270: + VientoDireccionProm= 'Sudoeste'; + break; + case x == 270: + VientoDireccionProm= 'Oeste'; + break; + case x > 270 && x < 360: + VientoDireccionProm= 'Noroeste'; + break; + default: + VientoDireccionProm= '-'; + } + //Para el span de Exterior + if(UltimoReg){ + $('#viento_dir').html(Tvientodir+'º'); + $('#viento_dir_nom').html(Tvientonombre||0); + $('#viento_dir_prom').html(UltimoReg.viento_direccion_prom_dia || 0 +'º'); + $('#viento_dir_nom_prom').html(VientoDireccionProm);} + delete(TvientoR);delete(Tviento);delete(x);delete(Tvientodir);delete(Tvientonombre);delete(Tvientonombre); + }else{ gviento1=undefined;gviento=undefined;} + click = null; + } + +function ListarRedes() + { + //Se listan la redes configuradas + var Publicar = configGeneralEMA.ConfPublicador; + var Cantidad = Publicar.length; + //Se arma la Tabla + var TablaHTML = ""; + TablaHTML += " "; + for (i = 0, t = Cantidad; i < t; ++i) + { + var publicar = ""+Publicar[i].Publicar +""; + if(Publicar[i].Publicar == false) {publicar = ""+Publicar[i].Publicar +"";} + if((Publicar[i].TipoRed != "emacenter") && (Publicar[i].TipoRed != "emacentergugler")) + { + TablaHTML += ""; + }else{ + if(Publicar[i].Llave_W != ''){var tienellave = "SI";}else{var tienellave ="NO";} + TablaHTML += ""; + } + } + TablaHTML += "
Nombre Local Tipo de RedClaveLLave_WPuertoPublicar
"+Publicar[i].Nombre+""+Publicar[i].TipoRed+"SINON/A"+publicar+"
"+Publicar[i].Nombre+""+Publicar[i].TipoRed+"N/A"+tienellave+""+(Publicar[i].Puerto || "N/A")+""+publicar+"
"; + //Se renderizan los botones + BotonHTML = ''; + $('#redesconfiguradas').html(TablaHTML); + $('#BotonRed').html(BotonHTML); + for (i = 0, t = Cantidad; i < t; ++i) + {$('#Red_activa_'+i).selectpicker('render');} + Publicar=null;Cantidad=null;TablaHTML=null;tieneusuario=null;tienellave=null; + } + +function MenuSelectRed() + { + if(($('#Tipo_Red').val() == "emacenter") || ($('#Tipo_Red').val() == "emacentergugler")) + { + $('#EmaConfAlta').attr("disabled",false);$('#EmaConfAlta').show(); + $('#EmaConfAlta2').hide();$('#EmaConfAlta2').attr("disabled",true); + $('#EmaConfAlta3').hide();$('#EmaConfAlta3').attr("disabled",true); + $('#EmaConfAlta4').attr("disabled",true);$('#EmaConfAlta4').hide(); + $('#EmaConfAlta5').attr("disabled",true);$('#EmaConfAlta5').hide(); + if($('#Tipo_Red').val() == "emacenter"){$('#EmaConfAlta4').attr("disabled",false);$('#EmaConfAlta4').show(); + $('#EmaConfAlta5').attr("disabled",false);$('#EmaConfAlta5').show(); + } + }else{ + if($('#Tipo_Red').val() == "openweathermap") {$('#EmaConfAlta6').attr("disabled",false);$('#EmaConfAlta6').show(); + $('#EmaConfAlta7').attr("disabled",false);$('#EmaConfAlta7').show(); + $('#EmaConfAlta8').attr("disabled",false);$('#EmaConfAlta8').show(); + $('#EmaConfAlta9').attr("disabled",false);$('#EmaConfAlta9').show(); + }else{ + $('#EmaConfAlta6').attr("disabled",true);$('#EmaConfAlta6').hide(); + $('#EmaConfAlta7').attr("disabled",true);$('#EmaConfAlta7').hide(); + $('#EmaConfAlta8').attr("disabled",true);$('#EmaConfAlta8').hide(); + $('#EmaConfAlta9').attr("disabled",true);$('#EmaConfAlta9').hide(); + } + $('#EmaConfAlta').attr("disabled",true); + $('#EmaConfAlta').hide(); + $('#EmaConfAlta2').attr("disabled",false);$('#EmaConfAlta2').show(); + $('#EmaConfAlta3').attr("disabled",false);$('#EmaConfAlta3').show(); + $('#EmaConfAlta4').attr("disabled",true);$('#EmaConfAlta4').hide(); + $('#EmaConfAlta5').attr("disabled",true);$('#EmaConfAlta5').hide(); + } + } + +function MenuRedes(red) + { + switch ($('#Red_activa_'+red).val()) { + case 'Eliminar': + // SE PREGUNTA SI ESTA SEGURO + $(document).off('click', '.notifyjs-foo-base .no'); // Se elimina el evento si existe + $(document).off('click', '.notifyjs-foo-base .yes'); // Se elimina el evento si existe + HABLA(0,'¿Esta seguro de eliminar
la red '+ configGeneralEMA.ConfPublicador[red].Nombre +'?',"success"); + $.notify.addStyle('foo', { + html: + "
" + + "
" + + "
" + + "" + + "
" + + "
" + }); + //PREGUNTA + $("#carpincho_img").notify({ + title: '¿Esta seguro de eliminar la red '+ configGeneralEMA.ConfPublicador[red].Nombre +'?', + button: 'SI' + }, { + position:"right middle", + style: 'foo', + autoHide: false, + clickToHide: false + }); + $(document).on('click', '.notifyjs-foo-base .no', function() { + //RESPONDE NO + ListarRedes(); + $(this).trigger('notify-hide'); + }); + $(document).on('click', '.notifyjs-foo-base .yes', function() { + //RESPONDE SI + configGeneralEMA.ConfPublicador.splice(red, 1); // elimina la red seleccionada + GuardarConf(); + ListarRedes(); + $(this).trigger('notify-hide'); + }); + break; + case 'Publicar': + HABLA(0,"Cambio de estado de la red '"+configGeneralEMA.ConfPublicador[red].Nombre + "', ahora se publica!!. ","success"); + configGeneralEMA.ConfPublicador[red].Publicar = true; // cambia el estado de la red + GuardarConf(); + ListarRedes(); + break; + case 'NoPublicar': + HABLA(0,"Cambio de estado de la red '"+configGeneralEMA.ConfPublicador[red].Nombre + "', ahora no se publica!!. ","warn"); + configGeneralEMA.ConfPublicador[red].Publicar = false; // cambia el estado de la red + GuardarConf(); + ListarRedes(); + break; + case 'Modificar': FormModificar(red); + break; + } + } + +function ModificarRedes(red) + { + HABLA(0,"Se modificó la red " + $('#Nombre').val(),"success"); + var TIPORED = $('#Tipo_Red').val(); + configGeneralEMA.ConfPublicador[red].Nombre = $('#Nombre').val(); + configGeneralEMA.ConfPublicador[red].TipoRed = TIPORED; + configGeneralEMA.ConfPublicador[red].Publicar = true; + configGeneralEMA.ConfPublicador[red].Usuario = $('#Usuario').val(); + configGeneralEMA.ConfPublicador[red].Password = $('#Password').val(); + delete configGeneralEMA.ConfPublicador[red].Llave_W; + delete configGeneralEMA.ConfPublicador[red].Server; + delete configGeneralEMA.ConfPublicador[red].Puerto; + if(TIPORED == 'emacentergugler') + { + delete configGeneralEMA.ConfPublicador[red].Usuario; + delete configGeneralEMA.ConfPublicador[red].Password; + configGeneralEMA.ConfPublicador[red].Llave_W = $('#LLaveW').val(); + } + if(TIPORED == 'emacenter') + { + delete configGeneralEMA.ConfPublicador[red].Usuario; + delete configGeneralEMA.ConfPublicador[red].Password; + configGeneralEMA.ConfPublicador[red].Server = $('#Servidor').val(); + configGeneralEMA.ConfPublicador[red].Puerto = $('#Puerto').val(); + configGeneralEMA.ConfPublicador[red].Llave_W = $('#LLaveW').val(); + } + GuardarConf(); + ListarRedes(); + } +function GuardarRed() + { + HABLA(0,"Se dío de alta una nueva red " + $('#Nombre').val(),"success"); + var TIPORED = $('#Tipo_Red').val(); + switch (TIPORED) { + case 'emacentergugler': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "emacentergugler", + Publicar: true, + Llave_W: $('#LLaveW').val() + }; + break; + case 'emacenter': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "emacenter", + Publicar: true, + Llave_W: $('#LLaveW').val(), + Server: $('#Servidor').val(), + Puerto: $('#Puerto').val() + }; + break; + case 'pws': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "pws", + Publicar: true, + Usuario: $('#Usuario').val(), + Password: $('#Password').val() + }; + break; + case 'wunderground': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "wunderground", + Publicar: true, + Usuario: $('#Usuario').val(), + Password: $('#Password').val() + }; + break; + case 'awekas': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "awekas", + Publicar: true, + Usuario: $('#Usuario').val(), + Password: $('#Password').val() + }; + break; + case 'windy': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "windy", + Publicar: true, + Usuario: $('#Usuario').val(), + Password: $('#Password').val() + }; + break; + case 'windguru': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "windguru", + Publicar: true, + Usuario: $('#Usuario').val(), + Password: $('#Password').val() + }; + break; + case 'wow': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "wow", + Publicar: true, + Usuario: $('#Usuario').val(), + Password: $('#Password').val() + }; + break; + case 'openweathermap': + var RegistroJSON = { + Nombre: $('#Nombre').val(), + TipoRed: "openweathermap", + Publicar: true, + keyapi: 'a2895a47d6297fa4a5a5684df1eb3400', + Usuario: $('#Usuario').val(), + Password: $('#Password').val() + }; + break; + default: + console.log('No Existe la red metorologica: ' + Parametros[0][0]); + } + configGeneralEMA.ConfPublicador.push(RegistroJSON); + delete(RegistroJSON);delete(TIPORED); + GuardarConf(); + MenuGUI('redes'); + } +function FormModificar(red) + { + $('#Tipo_Red').val(configGeneralEMA.ConfPublicador[red].TipoRed); + var TablaHTML = "

Modificación de Red

"; + TablaHTML += ""; + TablaHTML += ""; + TablaHTML += ""; + TablaHTML += ""; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += "
Tipo de Red
"; + TablaHTML += "
Configuracion de la Red

'; + TablaHTML += '
"; + BotonHTML = ''; + BotonHTML += '

'; + $('#redesconfiguradas').html(TablaHTML); + $('#BotonRed').html(BotonHTML); + $('#Tipo_Red').val(configGeneralEMA.ConfPublicador[red].TipoRed); + MenuSelectRed(); + $('#Tipo_Red').selectpicker('render'); + TablaHTML=null; + } + +function VerHistoricoT(lugar) + { + $('#exterior').html(""); + $('#interior').html(""); + var ubicacion = ""; + if(lugar == 0){ubicacion = 'exterior'}else{ubicacion='interior';} + var seleccion = document.getElementById(ubicacion); + $( seleccion ).load( "./view/modelo_historico.html", function(datosArchivo) + { + $("#botonhistorico").attr("onclick","MenuGUI('"+ubicacion+"');"); + $("#cantidadH").attr("onchange","VerHistorico("+lugar+");"); + VerHistorico(lugar); + lugar = null;ubicacion=null;seleccion=null; + }); + } + +// FUNCIONES DE ESCRITURA EN DISCO + +function GuardarConf(origen) + { + if (origen == 'conf'){ + //Se Setean los campos + HABLA(0,"Se almacenó correctamente la configuración", "success"); + configGeneralEMA.ConfGeneral.NombreEstacion = $('#NombreEstacion').val(); + configGeneralEMA.ConfEmail.Servicio = $('#Tipo_SMTP').val(); + if($('#Tipo_SMTP').val() == "Deshabilitado"){configGeneralEMA.ConfEmail.ActivarCorreos = false;}else{configGeneralEMA.ConfEmail.ActivarCorreos = true;} + configGeneralEMA.ConfEmail.Usuario = $('#Usuario_SMTP').val(); + configGeneralEMA.ConfEmail.Password = $('#Contrasenia_SMTP').val(); + configGeneralEMA.ConfEmail.Server = $('#Server_SMTP').val(); + configGeneralEMA.ConfEmail.Puerto = $('#Puerto_SMTP').val(); + configGeneralEMA.ConfEmail.ReceptorEmail = $('#Email_receptor').val(); + configGeneralEMA.ConfGeneral.Tiempo_de_Recoleccion = parseInt($('#Tiempo_de_Recoleccion').val()); + configGeneralEMA.ConfGeneral.debug = parseInt($('#Debug').val()); + configGeneralEMA.ConfGeneral.UTC = parseInt($('#utc').val()); + configGeneralEMA.ConfGeneral.SistemaMetrico = $('#SistemaMetrico').val(); + configGeneralEMA.ConfGeneral.Modo = $('#Modo').val(); + configGeneralEMA.ConfGeneral.Llave_R = $('#Llave_R').val(); + configGeneralEMA.ConfGeneral.debugTamanio = parseInt($('#debugMB').val()); + if($('#inicio_auto').val() == "Activado"){configGeneralEMA.ConfGeneral.inicio_automatico = true;}else{configGeneralEMA.ConfGeneral.inicio_automatico = false;} + if($('#notificar_cambios').val() == "Activado"){configGeneralEMA.ConfGeneral.notificar_cambios = true;}else{configGeneralEMA.ConfGeneral.notificar_cambios = false;} + if($('#audio').val() == "Activado"){configGeneralEMA.ConfGeneral.Audio = true;}else{configGeneralEMA.ConfGeneral.Audio = false;} + configGeneralEMA.ConfGeneral.audioVoces = $('#vocesAudio').val(); + } + //Se almacenan los campos + var configuracion_nueva = '// Configuraciones generales de EMA RECOLECTOR' + '\n\n'; + configuracion_nueva += 'module.exports = '; + configuracion_nueva += JSON.stringify(configGeneralEMA, null, ' '); + configuracion_nueva += ';'; + fsconf.writeFile('./conf/ConfiguracionGeneral.js', configuracion_nueva, function(err) { + if( err ){ + HABLA(0,"Upps, existió un problema intentando almacenar la configuración", "warn"); + EMA.RegistrarLog("0|CORE|Upps, existió un problema intentando almacenar la configuración."); + } + else{ + EMA.Reconfigurar(); + EMA.RegistrarLog("0|CORE|Se almaceno correctamente la configuración"); + } + }); + }; + +function PurgarP(origen) + { + fsconf.writeFile('./logs/TanquePendientes.log', JSON.stringify([], null, 4),{encoding: 'utf8', autoClose: true}, function(err) + { + EMA.RegistrarLog("1|PURGADO|Archivo de Pendientes"); + if (err) { EMA.RegistrarLog('0|ERROR|Depurando archivo registro de logs :' + err); } + }); + + HABLA(0,"Purgado - Se purgo correctamente el tanque de pendiente", "success"); + $('#tamanio_pendiente').html('0.00'); + $('#cantidad_pendiente').html('0'); + } + +function PurgarD(origen) + { + fsconf.writeFile('./logs/debug.log', '',{encoding: 'utf8', autoClose: true}, function(err) + { + EMA.RegistrarLog("1|PURGADO|Archivo de Debug"); + if (err) { EMA.RegistrarLog('0|ERROR|Depurando archivo registro de logs :' + err); } + }); + HABLA(0,"Purgado - Se purgo correctamente el archivo de debug", "success"); + $('#cantidad_debug').html('0'); + $('#tamanio_debug').html('0.00'); + } + +// FUNCIONES DE LECTURA EN DISCO + +function VerHistorico(lugar) + { + document.getElementById("mostrarregistrosH").style.display = "none"; + document.getElementById("actualizando").style.display = "block"; + $('#botonresfrescar').attr("disabled",true); + if(configGeneralEMA.ConfGeneral.Modo == 'Recolector') // se comprueba el modo se encuentra en Recolector + { + fsconf.readFile('./logs/registro_diario.log', {encoding: 'utf8', autoClose: true},function (err, data) + { if (err) throw err; + var TablaHTML = ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + if(lugar == 0) {TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += '';} + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + if(data.length < 100) + { + $('#mostrarregistros').html("| Info: Registro diario."); + } + else{ + var RegistroDiario = JSON.parse(data); + var CantRegistros = RegistroDiario.length; + $('#cantregH').html("Total Registros: " + CantRegistros); + var CantidadRegistrosInicio = CantRegistros - $('#cantidadH').val(); + if(CantidadRegistrosInicio < 0){CantidadRegistrosInicio=0;HABLA(0,"El filtro supera la cantidad de registros totales, por lo que se muestran todos", "info");} + for (j=CantidadRegistrosInicio; j < CantRegistros; ++j){ + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + if(lugar == 0) { + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + } + TablaHTML += ''; + } + + } + TablaHTML += ''; + TablaHTML += '
Fecha_RegistroTemp. Int.Hum. IntTemp. Ext.Hum. Ext.Punto. Roc.Luz int.Rayos UVViento Vel.Viento Raf.Viento Dir.Viento DirN.Presión Abs.Presión Rel.Luvia Act.Luvia HoraLuvia DiaLuvia Total
'+ j + ''+ RegistroDiario[j].fecha +''+ RegistroDiario[j].temperatura_interna +''+ RegistroDiario[j].humedad_interna +''+ RegistroDiario[j].temperatura_externa +''+ RegistroDiario[j].humedad_externa +''+ RegistroDiario[j].punto_de_rocio +''+ RegistroDiario[j].luxer_intencidad +''+ RegistroDiario[j].luxer_uv +''+ RegistroDiario[j].viento_velocidad +''+ RegistroDiario[j].viento_rafagas +''+ RegistroDiario[j].viento_direccion +''+ RegistroDiario[j].viento_direccion_nombre +''+ RegistroDiario[j].presion_absoluta +''+ RegistroDiario[j].presion_relativa +''+ RegistroDiario[j].lloviendo +''+ RegistroDiario[j].lluvia_acu_hora +''+ RegistroDiario[j].lluvia_acu_diaria +''+ RegistroDiario[j].lluvia_acumulado_total +'
'; + MostrarTabla(TablaHTML,'mostrarregistrosH','MiTablaH'); + RegistroDiario.length=0; + TablaHTML=null;RegistroDiario=null; + }); + }else{ //MODO Visor + var TablaHTML = ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + if(lugar == 0) {TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += '';} + else{ + TablaHTML += ''; + TablaHTML += ''; + } + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + $('#mostrarregistrosH').html(TablaHTML); + var cantreg=$('#cantidadH').val(); + if(cantreg > 7000){HABLA(0,"El modo visor el maximo de registro es 10000","info"); var cantreg = 10000;} + $(document).ready(function() + { + var i = 0; + $.ajax({ + url: 'https://emacenter.gugler.com.ar/api/get/'+configGeneralEMA.ConfGeneral.Llave_R+'/?cant='+cantreg, + method: 'get', + dataType: 'json', + success: function (data) + { + if(lugar == 0) { + $('#MiTablaH').DataTable( { + dom: 'Bfrtip', + buttons: ['copy','csv'], + pageLength: 5, + scrollX: true, + scrollCollapse: true, + lengthChange: false, + ordering: true, + destroy:true, + data: data.registros, + initComplete: function(settings, json) { + document.getElementById("mostrarregistrosH").style.display = "block"; + document.getElementById("actualizando").style.display = "none"; + $('#cantregH').html("Total Registros: " + cantreg); + }, + language: { + url: "../gui_common/css/Spanish.json" + }, + + columns: [ + + {"data": function (data) { + i++; + return i; + }}, + {"data": function (data) { + var db = new Date(data.fecha); + var minutos = db.getMinutes() ; if(minutos <= 9) {minutos = '0' + minutos}; + var hora = db.getHours(); if(hora <= 9) {hora = '0' + hora}; + var mes = db.getMonth() + 1; if(mes <= 9) {mes = '0'+ mes}; + var dia= db.getDate();if(dia <= 9) {dia = '0'+ dia}; + var segundo = db.getSeconds();if(segundo <= 9) {segundo = '0'+ segundo}; + var fecha = dia + "/" + mes + "/" + db.getFullYear() + " " + hora + ':'+minutos + ':' + segundo; + return fecha; + }}, + {"data": "temperatura_externa" }, + {"data": "humedad_externa" }, + {"data": "punto_de_rocio" }, + {"data": "luxer_intencidad" }, + {"data": "luxer_uv" }, + {"data": "viento_velocidad" }, + {"data": "viento_rafagas" }, + {"data": "viento_direccion" }, + {"data": "viento_direccion_nombre" }, + {"data": "presion_absoluta" }, + {"data": "presion_relativa" }, + {"data": "lluvia_actual" }, + {"data": "lluvia_acumulado_hora" }, + {"data": "lluvia_acumulado_diario" }, + {"data": "lluvia_acumulado_semanal" }, + {"data": "lluvia_acumulado_mensual" }, + {"data": "lluvia_acumulado_anual" }, + {"data": "lluvia_acumulado_total" } + ] + }); + }else{ + $('#MiTablaH').DataTable( { + dom: 'Bfrtip', + buttons: ['copy','csv'], + pageLength: 5, + scrollCollapse: true, + lengthChange: false, + ordering: true, + destroy:true, + data: data.registros, + initComplete: function(settings, json) { + document.getElementById("mostrarregistrosH").style.display = "block"; + document.getElementById("actualizando").style.display = "none"; + $('#cantregH').html("Total Registros: " + cantreg); + }, + language: { + url: "../gui_common/css/Spanish.json" + }, + + columns: [ + + {"data": function (data) { + i++; + return i; + }}, + {"data": function (data) { + var db = new Date(data.fecha); + var minutos = db.getMinutes() ; if(minutos <= 9) {minutos = '0' + minutos}; + var hora = db.getHours(); if(hora <= 9) {hora = '0' + hora}; + var mes = db.getMonth() + 1; if(mes <= 9) {mes = '0'+ mes}; + var dia= db.getDate();if(dia <= 9) {dia = '0'+ dia}; + var segundo = db.getSeconds();if(segundo <= 9) {segundo = '0'+ segundo}; + var fecha = dia + "/" + mes + "/" + db.getFullYear() + " " + hora + ':'+minutos + ':' + segundo; + return fecha; + }}, + {"data": function (data) { return data.temperatura_interna;}}, + {"data": function (data) { return data.humedad_interna;}} + ] + }); + } + }, + error: function () { + + document.getElementById("actualizandoH").style.display = "none"; + $('#botonresfrescar').attr("disabled",false); + $('#cantregH').html("Total Registros: 0"); + HABLA(0,"No se pudo obtener datos de EMA Center, verifique la llave de lectura o el servidor.", "error"); + }, + }); + }); + } + + } + +function VerRegistrosLog(select) + { + TablaHTML=null;registros=null; + document.getElementById("actualizando").style.display = "block"; + document.getElementById("mostrarregistrosLogs").style.display = "none"; + fsconf.readFile('./logs/debug.log', {encoding: 'utf8', autoClose: true}, function (err, data) + { if (err) throw err; + var TablaHTML = ''; + TablaHTML += '
Fecha_RegistroTemp. Ext.Hum. Ext.Punto. Roc.Luz int.Rayos UVViento Vel.Viento Raf.Viento Dir.Viento DirN.Presión Abs.Presión Rel.Luvia Act.Luvia HoraLuvia DiaLuvia SemanalLuvia MensualLuvia AnualLuvia TotalTemp. Int.Hum. Int
'; + TablaHTML += ''; + TablaHTML += ' '; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + if(data.length < 100) + {$('#mostrarregistrosLogs').html("");} + else{ + var registros = data.split('\n'); + if(select != false){ + $('#cantreg').html("Total Registros: " + registros.length); + if(registros.length<100){var totalselect = 1000;}else{var totalselect = registros.length;} + var HTML_SELECT = ''; + $('#select').html(HTML_SELECT); + HTML_SELECT = null; + } + var CantidadRegistrosInicio = registros.length - $('#cantidad').val(); + if(CantidadRegistrosInicio < 0){CantidadRegistrosInicio=0; HABLA(0,"El filtro supera la cantidad de registros totales, por lo que se muestran todos", "info");} + var Registro =''; + var Resultado =''; + for (var i=CantidadRegistrosInicio; i < registros.length - 1; ++i) + { + + Registro = registros[i].substring(24,999); + Resultado = Registro.split("|"); + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + TablaHTML += ''; + } + Resultado = null;Registro=null;registros=null; + } + TablaHTML += ''; + TablaHTML += '
Fecha_RegistroNivelTipoMensaje
000INFOTanque diario vacio
'+ i + ''+ registros[i].substring(0,19) +''+registros[i].substring(22,23) +''+Resultado[0] +''+Resultado[1] +'
'; + MostrarTabla(TablaHTML,'mostrarregistrosLogs','MiTabla'); + TablaHTML=null; + }); + } + +async function MostrarTabla(DATOS,DIV,TABLA) + { + $('#'+DIV).empty(); + $('#'+DIV).html(DATOS); + $('#'+TABLA).DataTable( + { + dom: 'Bfrtip', + buttons: ['copy','csv'], + pageLength: 8, + scrollX: true, + //scrollCollapse: true, + //lengthChange: false, + //ordering: true, + destroy:true, + //order: [[ 0, "desc" ]], + /*fixedHeader: { + header: true, + footer: true + },*/ + initComplete: function(settings, json) { + //console.log('Termino datatable'); + document.getElementById(DIV).style.display = "block"; + document.getElementById("actualizando").style.display = "none"; + }, + language: {url: "../gui_common/css/Spanish.json"} + }); + DATOS = null; + TABLA = null; + return true; + } + +async function graficoEstadisticas() + { + + // GRAFICO DEL TIEMPO CHARTJS + document.getElementById("grafico").style.display = "none"; + document.getElementById("actualizando").style.display = "block"; + //Se genera el grafico + if(configGeneralEMA.ConfGeneral.Modo == 'Recolector') // se comprueba el modo se encuentra en Recolector + { + + fsconf.readFile('./logs/registro_diario.log', { + encoding: 'utf8', + autoClose: true + }, (err, data) => { + if (err) { + EMA.RegistrarLog("1|ERROR|Error al intentar leer el registro diario para generar el grafico estadistico."); + } else { + var db = new Date(); + var mes = db.getMonth() + 1; if(mes <= 9) {mes = '0'+ mes}; + var dia= db.getDate();if(dia <= 9) {dia = '0'+ dia}; + var fecha = dia + "/" + mes + "/" + db.getFullYear(); + db = null;mes=null;dia=null; + var paraPendientes = fsconf.readFileSync('./logs/debug.log', 'utf8'); + var paraPendientes = paraPendientes.split('\n'); + var paraPendientesALM = paraPendientes.filter(function(datos) {var Resultado = datos.split("|"); return (Resultado[1] == 'PENDIENTE_ALM' && fecha == datos.substring(0,10)); }); + var paraPendientesPUB = paraPendientes.filter(function(datos) {var Resultado = datos.split("|"); return (Resultado[1] == 'PENDIENTE_PUB' && fecha == Resultado[2].substring(15,25)); }); + var CantiddPendientesAlmacenados = paraPendientesALM.length; + var CantiddPendientesPublicados = paraPendientesPUB.length; + paraPendientes = null;paraPendientesPUB = null; paraPendientesALM = null; fecha = null; + var RegistroDiarioTmp = JSON.parse(data); + var CantRegistros = RegistroDiarioTmp.length; + // console.log(CantRegistros); + if(CantRegistros > 1) + { + delete RegistroDiarioTmp['fechaISO']; + delete RegistroDiarioTmp['fechaUTC']; + delete RegistroDiarioTmp['luxer_intencidad_1hs']; + delete RegistroDiarioTmp['viento_direccion_nombre']; + delete RegistroDiarioTmp['lluvia_acu_diaria']; + delete RegistroDiarioTmp['temperatura_interna_max_dia']; + delete RegistroDiarioTmp['temperatura_interna_min_dia']; + delete RegistroDiarioTmp['humedad_interna_max_dia']; + delete RegistroDiarioTmp['humedad_interna_min_dia']; + delete RegistroDiarioTmp['temperatura_externa_max_dia']; + delete RegistroDiarioTmp['temperatura_externa_min_dia']; + delete RegistroDiarioTmp['humedad_externa_max_dia']; + delete RegistroDiarioTmp['humedad_externa_min_dia']; + delete RegistroDiarioTmp['punto_de_rocio_max_dia']; + delete RegistroDiarioTmp['punto_de_rocio_min_dia']; + delete RegistroDiarioTmp['luxer_intencidad_max_dia']; + delete RegistroDiarioTmp['luxer_intencidad_min_dia']; + delete RegistroDiarioTmp['luxer_uv_max_dia']; + delete RegistroDiarioTmp['luxer_uv_min_dia']; + delete RegistroDiarioTmp['presion_relativa_max_dia']; + delete RegistroDiarioTmp['presion_relativa_min_dia']; + delete RegistroDiarioTmp['viento_direccion_prom_dia']; + delete RegistroDiarioTmp['viento_velocidad_max_dia']; + delete RegistroDiarioTmp['viento_rafagas_max_dia']; + RegistroDiarioConCambios = []; + for (var j = 0; j < CantRegistros; j++) { + if ( RegistroDiarioTmp[j].cambio == true) RegistroDiarioConCambios.push(RegistroDiarioTmp[j]); + } + + delete RegistroDiarioConCambios['diferencia']; + // Se generan los datos para el grafico + var fecha_maxima = RegistroDiarioConCambios[RegistroDiarioConCambios.length-1].fecha; + var labels = RegistroDiarioConCambios.map(function(e) { return e.fecha.substring(11, 16) || 0;}); + var tmp_Ext = RegistroDiarioConCambios.map(function(e) { return e.temperatura_externa || 0;}); + var hum_Ext = RegistroDiarioConCambios.map(function(e) { return e.humedad_externa || 0;}); + var tmp_Int = RegistroDiarioConCambios.map(function(e) { return e.temperatura_interna || 0;}); + var hum_Int = RegistroDiarioConCambios.map(function(e) { return e.humedad_interna || 0;}); + var vientos = RegistroDiarioConCambios.map(function(e) { return e.viento_velocidad || 0;}); + var vinetosRaf = RegistroDiarioConCambios.map(function(e) { return e.viento_rafagas || 0;}); + var UV = RegistroDiarioConCambios.map(function(e) { return e.luxer_uv || 0;}); + var Luxer = RegistroDiarioConCambios.map(function(e) { return e.luxer_intencidad || 0;}); + var Lluvia = RegistroDiarioConCambios.map(function(e) { return e.lluvia_acu_hora || 0;}); + var presionRel = RegistroDiarioConCambios.map(function(e) { return e.presion_relativa || 0;}); + var validacion = RegistroDiarioConCambios.map(function(e) { return (e.estado_validacion_ant) || 0;}); + var puntorocio = RegistroDiarioConCambios.map(function(e) { return e.punto_de_rocio || 0;}); + + + //console.log(validacion); + var totalErrores = 0; + for(var i=0;i. + * + * @copyright Copyright (c) 2019 GUGLER (http://www.gugler.com.ar) + * @license https://www.gnu.org/licenses/gpl-3.0.html GPL License + * @version 3.0 + * @link http://www.gugler.com.ar + * @since File available since Release 3.0 + */ + +// Requiere el módulo NWJS +const gui = require('nw.gui'); + +// Obtener los parámetros pasados a la aplicación +const str = gui.App.argv; + +// Verificar si el parámetro 'update' está presente +const actualizar = str.includes('update'); + +// Limpiar caché para evitar problemas con versiones anteriores +gui.App.clearCache(); + +// Obtener las voces disponibles del sistema +const voices = window.speechSynthesis.getVoices(); + +// Verificar si hay voces disponibles +if (voices.length === 0) { + console.warn('No se han detectado voces en el sistema.'); +} + +if (actualizar) { + // Si el parámetro es 'update', abrir la ventana de actualización + gui.Window.open('./gui/index_actualizar.html', { + position: 'center', + width: 630, + height: 400 + }); +} else { + // Si no, abrir la ventana principal de la aplicación con un tamaño reducido + gui.Window.open('./gui/index.html', { + frame: false, + show: true, + position: 'center', + width: 450, + height: 200, + min_width: 450, + min_height: 200, + max_width: 450, + max_height: 200 + + }); +} \ No newline at end of file diff --git a/src/gui/index.html b/src/gui/index.html new file mode 100644 index 0000000..0cd35d6 --- /dev/null +++ b/src/gui/index.html @@ -0,0 +1,186 @@ + + + + + + + EMA Libre Cliente (Carpincho) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

EMA Libre Cliente
(Carpincho)
Licencia GPLv3

+
+
+
+ + +