{"id":15043680,"url":"https://github.com/klemenjak/yomopie","last_synced_at":"2025-04-15T00:31:39.817Z","repository":{"id":62590665,"uuid":"111898872","full_name":"klemenjak/YoMoPie","owner":"klemenjak","description":"A User-Oriented Energy Monitor to Enhance Energy Efficiency in Households","archived":false,"fork":false,"pushed_at":"2018-08-31T14:12:24.000Z","size":5322,"stargazers_count":12,"open_issues_count":1,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-29T05:02:50.040Z","etag":null,"topics":["energy-disaggregation","energy-efficiency","energy-monitor","home-automation","open-hardware-electronics","open-source","raspberrypi","smarthome","smartmeter","smartmetering"],"latest_commit_sha":null,"homepage":"https://klemenjak.github.io/YoMoPie","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/klemenjak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-24T09:14:41.000Z","updated_at":"2024-03-26T22:07:24.000Z","dependencies_parsed_at":"2022-11-03T22:44:31.720Z","dependency_job_id":null,"html_url":"https://github.com/klemenjak/YoMoPie","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemenjak%2FYoMoPie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemenjak%2FYoMoPie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemenjak%2FYoMoPie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemenjak%2FYoMoPie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/klemenjak","download_url":"https://codeload.github.com/klemenjak/YoMoPie/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248984292,"owners_count":21193719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["energy-disaggregation","energy-efficiency","energy-monitor","home-automation","open-hardware-electronics","open-source","raspberrypi","smarthome","smartmeter","smartmetering"],"created_at":"2024-09-24T20:49:25.605Z","updated_at":"2025-04-15T00:31:34.795Z","avatar_url":"https://github.com/klemenjak.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Servus!\n\nComputational methods for the enhancement of energy efficiency rely on a measurement process with sufficient accuracy and number of measurements. Networked energy meters, energy monitors, serve as a vital link between the energy consumption of households and key insights that reveal strategies to achieve significant energy savings.\nWith YoMoPie, we propose a user-oriented energy monitor for the Raspberry Pi platform that aims to enable intelligent energy services in households. YoMoPie measures active as well as apparent power, stores data locally, and integrates a user-friendly Python library. Furthermore, the presented energy monitor allows users to run self-designed services in their home to enhance energy efficiency. Potential services are (but not limited to) residential demand response, immediate user feedback, smart meter data analytics, or energy disaggregation.\n\n\u003c!--- YoMoPie builds on [the work published in [1]](https://link.springer.com/article/10.1007%2Fs00450-014-0290-8#/page-1).\nYoMoPie provides the following advancements:\n\n* It doesn't suffer from a data update rate of 1 second\n* It stores data locally\n* It integrates a new measurement IC that allows poly-phase metering\n* It builds on the Raspberry platform\n* The YoMoPie Python package enables easy handling --\u003e\n\n\n## Research Paper on YomoPie\n\nAll design files and pieces of software are available free of charge. However, in case you use the PCB design, code, or other material for research purposes, we kindly ask you to cite our peer-reviewed research paper:\n\n* *Title*: YoMoPie: A User-Oriented Energy Monitor to Enhance Energy Efficiency in Households\n* *Authors*: Mr. Christoph Klemenjak, Mr. Stefan Jost and Dr. Wilfried Elmenreich\n* *Conference*: 2018 IEEE Conference on Technologies for Sustainability (SusTech)\n\nRecommended Citation:\n```\n@INPROCEEDINGS{klemenjak2018yomopie,\nauthor={C. Klemenjak and S. Jost and W. Elmenreich},\nbooktitle={2018 IEEE Conference on Technologies for Sustainability (SusTech)},\ntitle={Yo{M}o{P}ie: {A} User-Oriented Energy Monitor to Enhance Energy Efficiency in Households},\nyear={2018},\nvolume={},\nnumber={},\npages={},\nkeywords={},\ndoi={},\nISSN={},\nmonth={Nov}}\n```\n\n![](/Images/ypi_blos.JPG)\n\n\n|                 | YoMoPie  |\n| ------------- | -----:|\n|Communication|  WiFi, Ethernet, RF |\n|Measurement|  P, Q, S, I, U |\n|Number of connections| 1 or 3 |\n|Integrated relay |  yes |\n|Sampling frequency|  tba. |\n|Data update rate |  tba. |\n|Power calculation|  Hardware |\n|Open-Source|  yes |\n|RaspberryPi-compatible|  yes  |\n|Costs| approx. 50€  |\n\nBeside a current and a voltage sensor, the board integrates an energy metering chip, the ADE7754. Our library is designed in a way to offer single-phase as well as multi-phase metering.\n\n## Installation\n\nThe YoMoPie Python package is available on Python Package Index (PyPI), a repository of software for the Python programming language, and can be installed by issuing one command:\n\n```python\npip3 install YoMoPie\n```\nAdditionally, the entire source code and a manual can be obtained from our YoMoPie Github repository.\n\n## Examples of use\n\nAfter a successful installation process, the YoMoPie package is available system-wide and can be accessed by a simple import command:\n```python\nimport YoMoPie as yomopie\nyp = yomopie.YoMoPie()\n```\n\nDuring initialisation, the number of line conductors has to be set (single or polyphase metering):\n```python\nyomo.set_lines(1)\n```\n\nTo test the operation, we recommend to call the function *do_n_measurements*. Based on the number of samples and the sampling period, the function will return first measurement values and saves it into the target file:\n```python\nyomo.do_n_measurements(number of samples, sampling period, target file)\n```\n\nActive power, apparent power, current, and voltage samples can be read with commands such as:\n```python\n[t, I] = yp.get_irms()\n[t, U] = yp.get_vrms()\n[t, P] = yp.get_active_energy()\n[t, S] = yp.get_apparent_energy()\n```\nIn the same vein, users can activate continuous data logging or perform a fixed amount of subsequent measurements:\n```python\nyp.do_metering()\nyp.do_n_measurements(quantity, rate, file)\n```\n\nThe operational mode (OPMODE) register defines the general configuration of the integrated measurement chip ADE7754. By writing to this register, A/D converters can be turned on/off, sleep mode can be activated, or a software chip reset can be triggered. For further information, we refer to the datasheet of the measurement chip.\n\n```python\nyp.set_operational_mode(OPMODE)\n```\n\n\n\n# YoMoPie Python package documentation\n**[Imports](#imports)**\u003cbr\u003e\n**[Classvariables](#classvariables)**\u003cbr\u003e\n**[Methods](#methods)**\u003cbr\u003e\n*[-init](#init)*\u003cbr\u003e\n*[-init_yomopie](#init_yomopie)*\u003cbr\u003e\n*[-set_lines](#set_lines)*\u003cbr\u003e\n*[-enable_board](#enable_board)*\u003cbr\u003e\n*[-disable_board](#disable_board)*\u003cbr\u003e\n*[-chip_reset](#chip_reset)*\u003cbr\u003e\n*[-write_8bit](#write_8bit)*\u003cbr\u003e\n*[-read_8bit](#read_8bit)*\u003cbr\u003e\n*[-write_16bit](#write_16bit)*\u003cbr\u003e\n*[-read_16bit](#read_16bit)*\u003cbr\u003e\n*[-read_24bit](#read_24bit)*\u003cbr\u003e\n*[-get_temp](#get_temp)*\u003cbr\u003e\n*[-get_laenergy](#get_laenergy)*\u003cbr\u003e\n*[-get_lappenergy](#get_lappenergy)*\u003cbr\u003e\n*[-get_period](#get_period)*\u003cbr\u003e\n*[-set_operational_mode](#set_operational_mode)*\u003cbr\u003e\n*[-set_measurement_mode](#set_measurement_mode)*\u003cbr\u003e\n*[-close_SPI_connection](#close_SPI_connection)*\u003cbr\u003e\n*[-get_aenergy](#get_aenergy)*\u003cbr\u003e\n*[-get_active_energy](#get_active_energy)*\u003cbr\u003e\n*[-get_apparent_energy](#get_apparent_energy)*\u003cbr\u003e\n*[-get_sample](#get_sample)*\u003cbr\u003e\n*[-get_sampleperperiod](#get_sampleperperiod)*\u003cbr\u003e\n*[-get_vrms](#get_vrms)*\u003cbr\u003e\n*[-get_irms](#get_irms)*\u003cbr\u003e\n*[-do_n_measurements](#do_n_measurements)*\u003cbr\u003e\n*[-do_metering](#do_metering)*\u003cbr\u003e\n*[-change_factors](#change_factors)*\u003cbr\u003e\n*[-reset_factors](#reset_factors)*\u003cbr\u003e\n*[-init_nrf24](#init_nrf24)*\u003cbr\u003e\n*[-write_nrf24](#write_nrf24)*\u003cbr\u003e\n*[-read_nrf24](#read_nrf24)*\u003cbr\u003e\n**[OPMODE](#opmode)**\u003cbr\u003e\n**[MMODE](#mmode)**\u003cbr\u003e\n\n## Imports\nYomoPie requires some additional libraries:\n\n**time**: The time package is required to obtain timestamps.\n\n**math**: YoMoPie requires the math lib for calculations such as reactive energy.\n\n**spidev**: The YoMoPie integrates an energy monitor IC, which communicates via SPI to the RPi. To enable this communication, YoMoPie exploits the spidev lib.\n\n**sys**: This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter.\n\n**RPi.GPIO**: In order to allow further extensions of the YoMoPie eco-system, our package integrates the RPi.GPIO. Also, the reset pin is controlled via GPIO.\n\n**NRF24**: This package allows to utilize the RF module for 2.4 GHz communication.\n\n```python\nimport time\nimport math\nimport spidev\nimport sys\nimport RPi.GPIO as GPIO\nfrom lib_nrf24 import NRF24\n```\n## Class variables\n\nTo correctly access the internal registers of the energy monitor IC, several custom variables are required to adjust the register values.\n\n* **read** and **write**: These variables hold the mask that defines the operational mode. Therefore, for reading a register the given address and the **read** variable are the inputs of a bitwise AND operation. On the other hand, for writing to a register the register address and the **write** variable are the inputs of a bitwise OR operation.\n\n* **spi**, **active_lines** and **debug**: These variables hold the SPI object, save the number of active lines, and enable/disable the debug mode.\n\n* **radio**: This object will be used for the RF communication and its functions.\n* **sample interval** and **max_f_sample**: defines the time between two samples (with respect to the start_sampling method) in seconds and the maximum sampling frequency (with respect to the sampling error).\n* **active_power_LSB**, **apparent_power_LSB**, **vrms_factor** and **irms_factor**: Convert register values to physical quantities and represent permanent conversion factors.\n\n```python\nread = 0b00111111\nwrite = 0b10000000\nspi=0\nradio=0\nactive_lines = 1\ndebug = 1\n\nsample_intervall = 1\nmax_f_sample = 10\n\nactive_power_LSB= 0.000013292\napparent_power_LSB= 0.00001024\nvrms_factor = 0.000047159\nirms_factor = 0.000010807\n```\n\n## Methods\n\nIn this Section, we describe every method of our  package. A description of function parameters and return values is given.\n\n### __init__\n\n**Description**: This method represents  the constructor and creates a new YoMoPie object.\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef __init__(self):\n\tself.spi=spidev.SpiDev()\n\tself.init_yomopie()\n\treturn\n```\n\n### init_yomopie\n\n**Description**: Initialises the YoMoPie object. Sets the GPIO mode, disables GPIO warnings and defines pin 19 as output. Also opens a new SPI connection via the SPI device (0,0), sets the SPI speed to 62500 Hz and sets the SPI mode to 1. Finally, the function set_lines is called to set the MMODE, WATMODE and VAMODE.\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef init_yomopie(self):\n\tGPIO.setmode(GPIO.BCM)\n\tGPIO.setwarnings(False)\n\tGPIO.setup(19,GPIO.OUT)\n\tself.spi.open(0,0)\n\tself.spi.max_speed_hz = 62500\n\tself.spi.mode = 0b01\n\tself.set_lines(self.active_lines)\n\tself.sampleintervall = 1\n\treturn\n```\n\n### set_lines\n\n**Description**: This function sets the number of active phases that will be measured.\n\n**Parameters**:\n* lines - Number of phases\n\n**Returns**: Nothing.\n\n```python\ndef set_lines(self, lines):\n\tif (lines != 1) and (lines != 3):\n\t\tprint(\"Incompatible number of power lines\")\n\t\treturn\n\telse:\n\t\tself.active_lines = lines\n\t\tif self.active_lines == 3:\n\t\t\tself.write_8bit(0x0D, 0x3F)\n\t\t\tself.write_8bit(0x0E, 0x3F)\n\t\t\tself.set_measurement_mode(0x70)\n\t\telif self.active_lines == 1:\n\t\t\tself.write_8bit(0x0E, 0x24)\n\t\t\tself.set_measurement_mode(0x10)\n\t\t\tself.write_8bit(0x0D, 0x24)\n\t\treturn\n```\n\n### enable_board\n\n**Description**: Enables the board by pulling pin 19 to HIGH.\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef enable_board(self):\n\tGPIO.output(19, GPIO.HIGH)\n\treturn\n```\n\n### disable_board\n\n**Description**: Disables the board by pulling pin 19 to LOW.\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef disable_board(self):\n\tGPIO.output(19, GPIO.LOW)\n\treturn\n```\n\n### chip_reset\n\n**Description**: Resets the chip to the manufacturer settings\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef chip_reset(self):\n\tself.write_8bit(0x0A, 0x40)\n\ttime.sleep(1);\n\treturn\n```\t\t\n### write_8bit    \n\n**Description**: Writes 8 bit to the given address.\n\n**Parameters**:\n\n* register - 8 bit address of the register (see ADE7754 register table)\n\n* value - 8 bit of value that will be written into the register\n\n**Returns**: Nothing.\n\n```python\ndef write_8bit(self, register, value):\n\tself.enable_board()\n\tregister = register | self.write\n\tself.spi.xfer2([register, value])\n\treturn\n```\n\n### read_8bit\n\n**Description**: Reads 8 bit of data from the given address.\n\n**Parameters**:\n* register - 8 bit address of the register (see ADE7754 register table)\n\n**Returns**: the 8 bit of data in the register as decimal\n\n```python\ndef read_8bit(self, register):\n\tself.enable_board()\n\tregister = register \u0026 self.read\n\tresult = self.spi.xfer2([register, 0x00])[1:]        \n\treturn result[0]\n```\n\n### write_16bit\n\n**Description**: Writes 16 bit to the given address.\n\n**Parameters**:\n\n* register - 8 bit address of the register (see ADE7754 register table)\n\n* value - 16 bit of value that will be written into the register\n\n**Returns**: Nothing.\n\n```python\ndef write_16bit(self, register, value):\n\tself.enable_board()\n\tregister = register | self.write\n\tself.spi.xfer2([register, value[0], value[1]])\n\treturn\n```\t\t\n\n### read_16bit  \n\n**Description**: Reads 16 bit of data from the given address.\n\n**Parameters**:\n* register - 8 bit address of the register (see ADE7754 register table)\n\n**Returns**: the 16 bit of data in the register as decimal\n\n```python\ndef read_16bit(self, register):\n\tself.enable_board()\n\tregister = register \u0026 self.read\n\tresult = self.spi.xfer2([register, 0x00, 0x00])[1:]\n\tdec_result = (result[0]\u003c\u003c8)+result[1]\n\treturn dec_result\n```\n\n### read_24bit        \n\n**Description**: Reads 24 bit of data from the given address.\n\n**Parameters**:\n* register - 8 bit address of the register (see ADE7754 register table)\n\n**Returns**: the 24 bit of data in the register as decimal\n\n```python\ndef read_24bit(self, register):\n\tself.enable_board()\n\tregister = register \u0026 self.read\n\tresult = self.spi.xfer2([register, 0x00, 0x00, 0x00])[1:]\n\tdec_result = (result[0]\u003c\u003c16)+(result[1]\u003c\u003c8)+(result[2])\n\treturn dec_result\n```\n\n### get_temp\n\n**Description**: Reads the temperature register (0x08).\n\n**Parameters**: None.\n\n**Returns**: A list [timestamp, temperature in °C]\n\n```python\ndef get_temp(self):\n\treg = self.read_8bit(0x08)\n\ttemp = [time.time(),(reg-129)/4]\n\treturn temp\n```\n\n### get_laenergy\n\n**Description**: Reads the active energy register (0x03).\n\n**Parameters**: None.\n\n**Returns**: A list [timestamp, value of the register]\n\n```python\ndef get_laenergy(self):\n\tlaenergy = [time.time(), self.read_24bit(0x03)]\n\treturn laenergy\n```\n\n### get_lappenergy\n\n**Description**: Reads the apparent energy register (0x06).\n\n**Parameters**: None.\n\n**Returns**: A list [timestamp, value of the register]\n\n```python\ndef get_lappenergy(self):\n\tlappenergy = [time.time(), self.read_24bit(0x06)]\n\treturn lappenergy\n```\n\n### get_period   \n\n**Description**: Reads the period register (0x07).\n\n**Parameters**: None.\n\n**Returns**: A list [timestamp, value of the register]\n\n```python\ndef get_period(self):\n       period = [time.time(), self.read_16bit(0x07)]\n       return period\n```\n\n### set_operational_mode\n\n**Description**: Sets the OPMODE. For more information see section OPMODE.\n\n**Parameters**:\n* value - 8 bit of data representing the OPMODE\n\n**Returns**: Nothing.\n\n```python\ndef set_operational_mode(self, value):\n\tself.write_8bit(0x0A, value)\n\treturn\n```\n\n### set_measurement_mode\n\n**Description**: Sets the MMODE. For more information see section MMODE.\n\n**Parameters**:\n* value - 8 bit of data representing the MMODE\n\n**Returns**: Nothing.\n\n```python\ndef set_measurement_mode(self, value):\n\tself.write_8bit(0x0B, value)\n\treturn\n```\n\n### close_SPI_connection\n\n**Description**: Closes the SPI connection.\n\n**Parameters**: None.\n\nReturns**: 0 if connection is closed.\n\n```python\ndef close_SPI_connection(self):\n\tself.spi.close()\n\treturn 0\n```\n### get_aenergy\n\n**Description**: Reads the active energy register (0x01).\n\n**Parameters**: None.\n\n**Returns**: A list [timestamp, value of register converted to real value]\n\n```python\ndef get_aenergy(self):\n\taenergy = [time.time(), self.active_power_LSB * self.read_24bit(0x01) *  3600/self.sample_intervall]\n\treturn aenergy\n```\n### get_active_energy\n\n**Description**: Reads the active energy register (0x02) and resets the register value.\n\n**Parameters**: None.\n\n**Returns**: A list [timestamp, value of register converted to real value]\n\n```python\ndef get_active_energy(self):\n\taenergy =  [time.time(), self.active_power_LSB * self.read_24bit(0x02) *  3600/self.sample_intervall]\n\treturn aenergy\n```\n### get_apparent_energy\n\n**Description**: Reads the apparent energy register (0x05) and resets the register vlaue.\n\n**Parameters**: None.\n\n**Returns**: A list [timestamp, value of register converted to real value]\n\n```python\ndef get_apparent_energy(self):\n\tappenergy = [time.time(), self.apparent_power_LSB * self.read_24bit(0x05)*  3600/self.sample_intervall]\n\treturn appenergy\n```\n### get_sample\n\n**Description**: Takes one sample and calculates the active energy, apparent energy, reactive energy, VRMS and IRMS.\n\n**Parameters**: None.\n\n**Returns**: A list of 7 elements [timestamp, active energy, apparent energy, reactive energy, period, VRMS, IRMS]\n\n```python\ndef get_sample(self):\n\taenergy = self.get_aenergy()[1] *self.active_factor\n\tappenergy = self.get_appenergy()[1] *self.apparent_factor\n\trenergy = math.sqrt(appenergy*appenergy - aenergy*aenergy)\n\tif self.debug:\n\t\tprint\"Active energy: %f W, Apparent energy: %f VA, Reactive Energy: %f var\" %(aenergy, appenergy, renergy)\n\t\tprint\"VRMS: %f IRMS: %f\" %(self.get_vrms()[1]*self.vrms_factor,self.get_irms()[1]*self.irms_factor)\n\tsample = []\n\tsample.append(time.time())\n\tsample.append(aenergy)\n\tsample.append(appenergy)\n\tsample.append(renergy)\n\tsample.append(self.get_period()[1])\n\tsample.append(self.get_vrms()[1]*self.vrms_factor)\n\tsample.append(self.get_irms()[1]*self.irms_factor)\n\treturn sample\n```\n\n### get_vrms\n\n**Description**: Reads the VRMS register depending.\n\n**Parameters**: None.\n\n**Returns**: A list of 2 elements [timestamp, Phase A VRMS] or 4 elements [timestamp, Phase A VRMS, Phase B VRMS, Phase C VRMS]\n\n```python\ndef get_vrms(self):\n\tif self.active_lines == 1:\n\t\tavrms = [time.time(), self.read_24bit(0x2C)]\n\t\treturn avrms\n\telif self.active_lines == 3:\n\t\tvrms = []\n\t\tvrms.append(time.time())\n\t\tvrms.append(self.read_24bit(0x2C))\n\t\tvrms.append(self.read_24bit(0x2D))\n\t\tvrms.append(self.read_24bit(0x2E))\n\t\treturn vrms\n\treturn 0\n```\n\n### get_irms\n\n**Description**: Reads the IRMS register.\n\n**Parameters**: None.\n\n**Returns**: A list of 2 elements [timestamp, Phase A IRMS] or 4 elements [timestamp, Phase A IRMS, Phase B IRMS, Phase C IRMS]\n\n```python\ndef get_irms(self):\n\tif self.active_lines == 1:\n\t\tairms = [time.time(), self.read_24bit(0x29)]\n\t\treturn airms\n\telif self.active_lines == 3:\n\t\tirms = []\n\t\tirms.append(time.time())\n\t\tirms.append(self.read_24bit(0x29))\n\t\tirms.append(self.read_24bit(0x2A))\n\t\tirms.append(self.read_24bit(0x2B))\n\t\treturn vrms\n\treturn 0\n```\n\n### get_sampleperperiod\n\n**Description**: Reads multiple register and returns the values adjusted to the sampling frequency. This function will be used in the do_n_measurements\n function.\n\n**Parameters**:\n* samplerate - the actual samplerate\n\n**Returns**: A list of 7 elements [timestamp, active energy, apparent energy, reactive energy, period, VRMS, IRMS]\n\n```python\ndef get_sampleperperiod(self, samplerate):\n\taenergy = self.get_aenergy()[1] *self.active_factor * 3600/samplerate\n\tappenergy = self.get_appenergy()[1] *self.apparent_factor * 3600/samplerate\n\trenergy = math.sqrt(abs(appenergy*appenergy - aenergy*aenergy))\n\tvrms = self.get_vrms()[1]*self.vrms_factor\n\tirms = self.get_irms()[1]*self.irms_factor\n\tif self.debug:\n\t\tprint(\"Active energy: %f W, Apparent energy: %f VA, Reactive Energy: %f var\" % (aenergy, appenergy, renergy))\n\t\tprint(\"VRMS: %f IRMS: %f\" %(vrms,irms))\n\tsample = []\n\tsample.append(time.time())\n\tsample.append(aenergy)\n\tsample.append(appenergy)\n\tsample.append(renergy)\n\tsample.append(self.get_period()[1])\n\tsample.append(vrms)\n\tsample.append(irms)\n\treturn sample\n```\n\n### do_n_measurements\n\n**Description**: Takes *nr_samples* with sampling period *samplerate* and saves the measurements into the give file.\n\n**Parameters**:\n\n* nr_samples - this are the number of samples that will be taken, integer greater then 0\n* samplerate - this is the time between each sample, integer greater then 0\n* file - this will be the path and name of the file, where the date will be stored\n\n**Returns**: A list of samples (each sample is a list of 7 elements)\n\n```python\ndef do_n_measurements(self, nr_samples, samplerate, file):\n\tif (samplerate\u003c1) or (nr_samples\u003c1):\n\t\treturn 0\n\tself.sample_intervall = samplerate\n\tsamples = []\n\tfor i in range(0, nr_samples):\n\t\tfor j in range(0, samplerate):\n\t\t\ttime.sleep(1)\n\tsample = self.get_sampleperperiod(samplerate)\n\tsamples.append(sample)\n\tlogfile = open(file, \"a\")\n\tfor value in sample:\n\t\tlogfile.write(\"%s; \" % value)\n\tlogfile.write(\"\\n\")\n\tlogfile.close()\n\treturn samples\n```\n\n### do_metering\n\n**Description**: Starts a sampling process and saves the data into a file.\n\n**Parameters**:\n\n* f_sample - the sampling frequency (\u003c= 10, but if max_f_sample is changed, this value can be up to 100 with a higher error)\n* file - this will be the path and name of the file, where the date will be stored. If this parameter is empty the data will be stored in \"smart_meter_output.csv\".\n\n**Returns**: Nothing.\n\n```python\ndef do_metering(self, f_sample, file):\n\tif (f_sample \u003e max_f_sample):\n\t\tprint('Incompatible sampling frequency!')\n\t\treturn 1\n\tif (file == ''):\n\t\tfile = 'smart_meter_output.csv'\n\tfor i in range(0,86400):\n\t\tsample = []\n\t\tsample.append(time.time())\n\t\tsample.append(i)\n\t\tsample.append(self.get_active_energy())\n\t\tsample.append(self.get_apparent_energy())\n\t\tdata_file = open(file,'a')\n\t\tfor value in sample:\n\t\t\tlogfile.write(\"%s; \" % value)\n\t\tlogfile.write(\"\\n\")\n\t\t##print(sample)\n\t\ttime.sleep(1/f_sample);\n\treturn 0\n```\n\n### change_factors\n\n**Description**: Changes the multiplication factors for the register values.\n\n**Parameters**:\n\n* active_f - this is the factor for the active energy calculation\n* apparent_f - this is the factor for the apparent energy calculation\n* vrms_f - this is the factor for the vrms calculation\n* irms_f  this is the factor for the irms calculation\n\n**Returns**: Nothing.\n\n```python\ndef change_factors(self, active_f, apparent_f, vrms_f, irms_f):\n\tself.active_power_LSB = active_f\n\tself.apparent_power_LSB = apparent_f\n\tself.vrms_factor = vrms_f\n\tself.irms_factor = irms_f\n\treturn\n```\n\n### reset_factors\n\n**Description**: Resets the multiplication factors to the default values. The default values are calculated by our measurements with calibrated equipment.\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef reset_factors(self):\n\tself.active_power_LSB= 0.000013292\n\tself.apparent_power_LSB= 0.00001024\n\tself.vrms_factor = 0.000047159\n\tself.irms_factor = 0.000010807\n\treturn\n```\n\n### init_nrf24\n\n**Description**: Initializes the RF communication via the NRF24 chip.\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef init_nrf24(self):\n\tpipes = [[0xe7, 0xe7, 0xe7, 0xe7, 0xe7], [0xc2, 0xc2, 0xc2, 0xc2, 0xc2]]\n\n\tself.radio = NRF24(GPIO, self.spi)\n\tself.radio.begin(1, 13)\n\tself.radio.setPayloadSize(32)\n\tself.radio.setChannel(0x60)\n\n\tself.radio.setDataRate(NRF24.BR_2MBPS)\n\tself.radio.setPALevel(NRF24.PA_MIN)\n\tself.radio.setAutoAck(True)\n\tself.radio.enableDynamicPayloads()\n\tself.radio.enableAckPayload()\n\tself.radio.openWritingPipe(pipes[1])\n\tself.radio.openReadingPipe(1, pipes[0])\n\tself.radio.printDetails()\n\treturn\n```\n\n### write_nrf24\n\n**Description**: Sends a message via the RF communication.\n\n**Parameters**:\n* command - the message that will be written via RF\n\n**Returns**: Nothing.\n\n```python\ndef write_nrf24(self, command):\n\tmessage = []\n\tmessage = list(command)\n\tself.radio.write(message)\n\tprint(\"Send: {}\".format(message))\n\n\tif self.radio.isAckPayloadAvailable():\n\t\tpl_buffer = []\n\t\tself.radio.read(pl_buffer, self.radio.getDynamicPayloadSize())\n\t\tprint(pl_buffer)\n\t\tprint(\"Translating the acknowledgment to unicode chars...\")\n\t\tstring = \"\"\n\t\tfor n in pl_buffer:\n\t\t\tif(n \u003e= 32 and n \u003c= 126):\n\t\t\tstring += chr(n)\n\t\tprint(string)\n\treturn\n```\n\n### read_nrf24\n\n**Description**: Reads a message via the RF communication.\n\n**Parameters**: None.\n\n**Returns**: Nothing.\n\n```python\ndef read_nrf24(self):\n\tprint(\"Ready to receive data...\")\n\tself.radio.startListening()\n\tpipe = [0]\n\twhile not self.radio.available(pipe):\n\t\ttime.sleep(1/100)\n\treceivedMessage = []\n\tself.radio.read(receivedMessage, self.radio.getDynamicPayloadSize())\n\n\tprint(\"Translating the receivedMessage to unicode chars...\")\n\tstring = \"\"\n\tfor n in receivedMessage:\n\t\tif (n \u003e= 32 and n \u003c= 126):\n\t\t\tstring += chr(n)\n\t\tprint(\"Our sensor sent us: {}\".format(string))\n\tself.radio.stopListening()\n\treturn\n```\n## OPMODE\nThe operational mode (OPMODE) register defines the general configuration of the ADE7754 chip. For detailed information about the individual bits of this register we refer to [Table IX](https://github.com/klemenjak/YoMoPie/blob/master/Datasheets/ADE7754.pdf).\n\n\n## MMODE\nThe configuration of period and peak measurements are defined by writing to the MMODE register (0x0B). For more information about the register we refer to [Table XII](https://github.com/klemenjak/YoMoPie/blob/master/Datasheets/ADE7754.pdf).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklemenjak%2Fyomopie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fklemenjak%2Fyomopie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklemenjak%2Fyomopie/lists"}