initial
This commit is contained in:
20
Metro/LICENSE
Normal file
20
Metro/LICENSE
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 thomasfredericks
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
61
Metro/Metro.cpp
Normal file
61
Metro/Metro.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >= 100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#else
|
||||||
|
#include "WProgram.h"
|
||||||
|
#endif
|
||||||
|
#include "Metro.h"
|
||||||
|
|
||||||
|
Metro::Metro()
|
||||||
|
{
|
||||||
|
|
||||||
|
this->interval_millis = 1000;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Metro::Metro(unsigned long interval_millis)
|
||||||
|
{
|
||||||
|
|
||||||
|
this->interval_millis = interval_millis;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Metro::interval(unsigned long interval_millis)
|
||||||
|
{
|
||||||
|
this->interval_millis = interval_millis;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Metro::check()
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
|
if ( interval_millis == 0 ){
|
||||||
|
previous_millis = now;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (now - previous_millis) >= interval_millis) {
|
||||||
|
#ifdef NOCATCH-UP
|
||||||
|
previous_millis = now ;
|
||||||
|
#else
|
||||||
|
previous_millis += interval_millis ;
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Metro::reset()
|
||||||
|
{
|
||||||
|
|
||||||
|
this->previous_millis = millis();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
49
Metro/Metro.h
Normal file
49
Metro/Metro.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
Main code by Thomas O Fredericks (tof@t-o-f.info)
|
||||||
|
Contributions by Paul Bouchier and Benjamin.soelberg
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef Metro_h
|
||||||
|
#define Metro_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Metro
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Metro();
|
||||||
|
Metro(unsigned long interval_millis);
|
||||||
|
void interval(unsigned long interval_millis);
|
||||||
|
uint8_t check();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned long previous_millis, interval_millis;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
1
Metro/README.md
Normal file
1
Metro/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Please visit https://github.com/thomasfredericks/Metro-Arduino-Wiring for latest code and documentation.
|
||||||
30
Metro/examples/blinking/blinking.ino
Normal file
30
Metro/examples/blinking/blinking.ino
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
This code will blink an LED attached to pin 13 on and off.
|
||||||
|
It will stay on for 0.25 seconds.
|
||||||
|
It will stay off for 1 second.
|
||||||
|
*/
|
||||||
|
#include <Metro.h> //Include Metro library
|
||||||
|
#define LED 13 // Define the led's pin
|
||||||
|
|
||||||
|
//Create a variable to hold theled's current state
|
||||||
|
int state = HIGH;
|
||||||
|
|
||||||
|
// Instanciate a metro object and set the interval to 250 milliseconds (0.25 seconds).
|
||||||
|
Metro ledMetro = Metro(250);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
pinMode(LED,OUTPUT);
|
||||||
|
digitalWrite(LED,state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ledMetro.check() == 1) { // check if the metro has passed its interval .
|
||||||
|
if (state==HIGH) state=LOW;
|
||||||
|
else state=HIGH;
|
||||||
|
|
||||||
|
digitalWrite(LED,state);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
Metro/examples/blinking_2_instances/blinking_2_instances.ino
Normal file
51
Metro/examples/blinking_2_instances/blinking_2_instances.ino
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// This code will blink output 13 every 250 ms
|
||||||
|
// abd will blink output 9 every 125 ms
|
||||||
|
|
||||||
|
|
||||||
|
#include <Metro.h> // Include Metro library
|
||||||
|
#define LED0 13 // Define a LED pin
|
||||||
|
#define LED1 9 // Define another LED pin
|
||||||
|
|
||||||
|
// Create variables to hold the LED states
|
||||||
|
int state0 = HIGH;
|
||||||
|
int state1 = HIGH;
|
||||||
|
|
||||||
|
// Instantiate a metro object and set the interval to 250 milliseconds (0.25 seconds).
|
||||||
|
Metro metro0 = Metro(250);
|
||||||
|
|
||||||
|
// Instantiate another metro object and set the interval to 125 milliseconds (0.125 seconds).
|
||||||
|
Metro metro1 = Metro(125);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
pinMode(LED0,OUTPUT);
|
||||||
|
digitalWrite(LED0,state0);
|
||||||
|
|
||||||
|
pinMode(LED1,OUTPUT);
|
||||||
|
digitalWrite(LED1,state1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (metro0.check() == 1) { // check if the metro has passed its interval .
|
||||||
|
if (state0==HIGH) {
|
||||||
|
state0=LOW;
|
||||||
|
} else {
|
||||||
|
state0=HIGH;
|
||||||
|
}
|
||||||
|
digitalWrite(LED0,state0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metro1.check() == 1) { // check if the metro has passed its interval .
|
||||||
|
if (state1==HIGH) {
|
||||||
|
state1=LOW;
|
||||||
|
} else {
|
||||||
|
state1=HIGH;
|
||||||
|
}
|
||||||
|
digitalWrite(LED1,state1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
36
Metro/examples/blinking_2_intervals/blinking_2_intervals.ino
Normal file
36
Metro/examples/blinking_2_intervals/blinking_2_intervals.ino
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
This code will blink an LED attached to pin 13 on and off.
|
||||||
|
It will stay on for 0.25 seconds.
|
||||||
|
It will stay off for 1 second.
|
||||||
|
*/
|
||||||
|
#include <Metro.h> //Include Metro library
|
||||||
|
#define LED 13 // Define the led's pin
|
||||||
|
|
||||||
|
//Create a variable to hold theled's current state
|
||||||
|
int state = HIGH;
|
||||||
|
|
||||||
|
// Instanciate a metro object and set the interval to 250 milliseconds (0.25 seconds).
|
||||||
|
Metro ledMetro = Metro(250);
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
pinMode(LED,OUTPUT);
|
||||||
|
digitalWrite(LED,state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ledMetro.check() == 1) { // check if the metro has passed its interval .
|
||||||
|
if (state==HIGH) {
|
||||||
|
state=LOW;
|
||||||
|
ledMetro.interval(250); // if the pin is HIGH, set the interval to 0.25 seconds.
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ledMetro.interval(1000); // if the pin is LOW, set the interval to 1 second.
|
||||||
|
state=HIGH;
|
||||||
|
}
|
||||||
|
digitalWrite(LED,state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
24
Metro/examples/serialInterval/serialInterval.ino
Normal file
24
Metro/examples/serialInterval/serialInterval.ino
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// This example sends a Serial message every 250 milliseconds
|
||||||
|
|
||||||
|
#include <Metro.h> // Include the Metro library
|
||||||
|
|
||||||
|
Metro serialMetro = Metro(250); // Instantiate an instance
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200); // Start the Serial communication
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
if (serialMetro.check() == 1) { // check if the metro has passed it's interval .
|
||||||
|
// Output all the analog readings seperated by a space character
|
||||||
|
for (int i = 0; i < 6; i++ ) {
|
||||||
|
Serial.print (analogRead( i) );
|
||||||
|
Serial.print(32,BYTE);
|
||||||
|
}
|
||||||
|
// Terminate message with a linefeed and a carriage return
|
||||||
|
Serial.print(13,BYTE);
|
||||||
|
Serial.print(10,BYTE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
25
Metro/keywords.txt
Normal file
25
Metro/keywords.txt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map For Test
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
Metro KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
check KEYWORD2
|
||||||
|
interval KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Instances (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
BIN
ferrarismonitor.zip
Normal file
BIN
ferrarismonitor.zip
Normal file
Binary file not shown.
141
ferrarismonitor/FerrarisMonitor/FerrarisMonitor.ino
Normal file
141
ferrarismonitor/FerrarisMonitor/FerrarisMonitor.ino
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
int portLeft = 4;
|
||||||
|
int portRight = 3;
|
||||||
|
|
||||||
|
long sampleMetro = 10;
|
||||||
|
long printMetro = 100;
|
||||||
|
|
||||||
|
int16_t stateLeft = 0;
|
||||||
|
int16_t stateRight = 0;
|
||||||
|
|
||||||
|
int16_t minLeft = 1024;
|
||||||
|
int16_t maxLeft = 0;
|
||||||
|
int16_t nextMinLeft = 1024;
|
||||||
|
int16_t nextMaxLeft = 0;
|
||||||
|
int16_t minRight = 1024;
|
||||||
|
int16_t maxRight = 0;
|
||||||
|
int16_t nextMinRight = 1024;
|
||||||
|
int16_t nextMaxRight = 0;
|
||||||
|
|
||||||
|
int16_t margin = 5;
|
||||||
|
int16_t rotation = 1; // right = 1, normal, -1 is reverse
|
||||||
|
|
||||||
|
int16_t lightLeft = 0; // latest reading
|
||||||
|
int16_t lightRight = 0;
|
||||||
|
|
||||||
|
double prevMs = 0; // timestamp of last peak
|
||||||
|
long previousSample = 0;
|
||||||
|
long previousPrint = 0;
|
||||||
|
double len = 0; // delay between the last two peaks
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(57600);
|
||||||
|
Serial.println("\n[Monitoring a Ferraris Meter]");
|
||||||
|
|
||||||
|
//portLeft.mode(INPUT);
|
||||||
|
//portRight.mode(INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
// take a reading from both sensors
|
||||||
|
if(currentMillis - previousSample > sampleMetro) {
|
||||||
|
previousSample = currentMillis;
|
||||||
|
// read sensors
|
||||||
|
lightLeft = analogRead(portLeft);
|
||||||
|
lightRight = analogRead(portRight);
|
||||||
|
|
||||||
|
// to take into account changing peak sizes, we follow the peak size continuously
|
||||||
|
// the found peak size serves as the target (minus a small margin) for the next peak detection
|
||||||
|
// update minimum and maximum for the left sensor
|
||||||
|
if ( lightLeft > nextMaxLeft ) {
|
||||||
|
nextMaxLeft = lightLeft;
|
||||||
|
}
|
||||||
|
// we also do this for the valley
|
||||||
|
if ( lightLeft < nextMinLeft ) {
|
||||||
|
nextMinLeft = lightLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
// and the same for the right sensor
|
||||||
|
// update minimum and maximum for the right sensor
|
||||||
|
if ( lightRight > nextMaxRight ) {
|
||||||
|
nextMaxRight = lightRight;
|
||||||
|
}
|
||||||
|
if ( lightRight < nextMinRight ) {
|
||||||
|
nextMinRight = lightRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( stateLeft == 0 ) && (lightLeft > maxLeft - margin )) {
|
||||||
|
// make state = 1 when light above threshold and state == 0
|
||||||
|
stateLeft = 1;
|
||||||
|
|
||||||
|
// we are now going to a minimum, reset the minimum value of the left sensor
|
||||||
|
minLeft = nextMinLeft;
|
||||||
|
nextMinLeft = 1024;
|
||||||
|
|
||||||
|
// calculate rotation direction
|
||||||
|
if (( stateRight == 0 ) && (rotation < 1)) {
|
||||||
|
rotation++;
|
||||||
|
} else if ((stateRight == 1 ) && (rotation > -1)) {
|
||||||
|
rotation--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate delay between the last two peaks, now and prevMs
|
||||||
|
double ms = millis();
|
||||||
|
len = ms - prevMs;
|
||||||
|
prevMs = ms;
|
||||||
|
|
||||||
|
} else if ((stateLeft == 1 ) && (lightLeft < minLeft + margin)) {
|
||||||
|
// make state = 0 when light below threshold and state == 1
|
||||||
|
stateLeft = 0;
|
||||||
|
|
||||||
|
// we are now going to a maximum, reset the maximum value of the left sensor
|
||||||
|
maxLeft = nextMaxLeft;
|
||||||
|
nextMaxLeft = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( stateRight == 0 ) && (lightRight > maxRight - margin )) {
|
||||||
|
// make state = 1 when light above threshold and state == 0
|
||||||
|
stateRight = 1;
|
||||||
|
|
||||||
|
// we are now going to a minimum, reset the minimum value of the right sensor
|
||||||
|
minRight = nextMinRight;
|
||||||
|
nextMinRight = 1024;
|
||||||
|
|
||||||
|
} else if ((stateRight == 1 ) && (lightRight < minRight + margin)) {
|
||||||
|
// make state = 0 when light below threshold and state == 1
|
||||||
|
stateRight = 0;
|
||||||
|
|
||||||
|
// we are now going to a maximum, reset the maximum value of the right sensor
|
||||||
|
maxRight = nextMaxRight;
|
||||||
|
nextMaxRight = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// print current status
|
||||||
|
if(currentMillis - previousPrint > printMetro) {
|
||||||
|
previousPrint = currentMillis;
|
||||||
|
// calculate new delay between now and the previous peak (prevMs)
|
||||||
|
double ms = millis();
|
||||||
|
double tempDelay = ms - prevMs;
|
||||||
|
|
||||||
|
// if 'tempDelay' is larger than the delay between the last two peaks 'len' it means that the disc is spinning slower and power usage is decreasing
|
||||||
|
// so max power consumption at this moment is not len, but tempDelay.
|
||||||
|
if ( len > tempDelay ) {
|
||||||
|
tempDelay = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int watt = rotation * 4800000 / tempDelay; // my kwh meter says 600 rotations per kwh
|
||||||
|
|
||||||
|
Serial.print(watt);
|
||||||
|
Serial.print(" | ");
|
||||||
|
Serial.print(rotation);
|
||||||
|
Serial.print(" | ");
|
||||||
|
Serial.print(lightLeft);
|
||||||
|
Serial.print(" | ");
|
||||||
|
Serial.println(lightRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
38
kwhmeter.conf
Normal file
38
kwhmeter.conf
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
[kWh Settings]
|
||||||
|
leftchannelid = 0
|
||||||
|
rightchannelid = 2
|
||||||
|
|
||||||
|
[kWh]
|
||||||
|
importcounter = 1359430
|
||||||
|
exportcounter = 1190820
|
||||||
|
rotationsperkwh = 480
|
||||||
|
minleft = 76
|
||||||
|
maxleft = 722
|
||||||
|
minmarginleft = 396
|
||||||
|
maxmarginleft = 594
|
||||||
|
minright = 92
|
||||||
|
maxright = 807
|
||||||
|
minmarginright = 447
|
||||||
|
maxmarginright = 665
|
||||||
|
cumuliday = 20150331
|
||||||
|
importday = 2229
|
||||||
|
exportday = 3077
|
||||||
|
|
||||||
|
[MySQL]
|
||||||
|
host = localhost
|
||||||
|
user = root
|
||||||
|
passwd = root
|
||||||
|
db = kwhRijnsraat214
|
||||||
|
|
||||||
|
[pvout]
|
||||||
|
pvout_enabled = true
|
||||||
|
pvout_apikey = b8795509823e9439f9d107c8f608c0dd7a96239f
|
||||||
|
pvout_sysid = 28910
|
||||||
|
|
||||||
|
[EmonCMS]
|
||||||
|
emoncmspath = emoncms
|
||||||
|
domain = 192.168.2.2
|
||||||
|
apikey = 1e01f7ef0c6c83f4c2fe0bced49374ad
|
||||||
|
nodeid = 10
|
||||||
|
emon_enable = true
|
||||||
|
|
||||||
554
kwhmeter_20131014.py
Normal file
554
kwhmeter_20131014.py
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
# This Python script needs a SPI module.
|
||||||
|
# For more info, please see:
|
||||||
|
# http://www.100randomtasks.com/simple-spi-on-raspberry-pi
|
||||||
|
#
|
||||||
|
# This script also uses a "LoadAverage" module. This module can be downloaded from:
|
||||||
|
# http://patrick.i234.me/kwhmeter/LoadAverage.py
|
||||||
|
#
|
||||||
|
# This script is written for use on a Raspberri Pi, in combination with some
|
||||||
|
# custom-made hardware.
|
||||||
|
# The schematic of the hardware can be found here:
|
||||||
|
# https://www.circuitlab.com/circuit/eae95u/raspberry-pi-kwh-meter/
|
||||||
|
#
|
||||||
|
# or an PDF can be found on my own site:
|
||||||
|
# http://patrick.i234.me/kwhmeter/raspberry-pi-kwh-meter.pdf
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
# Unused modules, that I might incorporate later
|
||||||
|
#import rrdtool
|
||||||
|
#import os
|
||||||
|
|
||||||
|
import MySQLdb
|
||||||
|
|
||||||
|
|
||||||
|
import spidev
|
||||||
|
import time
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
import ConfigParser
|
||||||
|
# for the module LoadAverage, see: http://patrick.i234.me/kwhmeter/LoadAverage.py
|
||||||
|
import LoadAverage
|
||||||
|
import datetime
|
||||||
|
from datetime import date
|
||||||
|
# For PVoutput
|
||||||
|
import urllib, urllib2
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
# GPIO Pins for the different components:
|
||||||
|
switch = 23
|
||||||
|
redLED = 17
|
||||||
|
greenLED = 18
|
||||||
|
boardLED = 22
|
||||||
|
|
||||||
|
|
||||||
|
# Initialise SPI
|
||||||
|
spi = spidev.SpiDev()
|
||||||
|
spi.open(0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
|
||||||
|
def readadc(adcnum):
|
||||||
|
if ((adcnum > 7) or (adcnum < 0)):
|
||||||
|
return -1
|
||||||
|
r = spi.xfer2([1, (8 + adcnum) << 4, 0])
|
||||||
|
adcout = ((r[1] & 3) << 8) + r[2]
|
||||||
|
return adcout
|
||||||
|
|
||||||
|
|
||||||
|
def turnonLED(LED):
|
||||||
|
GPIO.output(LED, True)
|
||||||
|
|
||||||
|
|
||||||
|
def turnoffLED(LED):
|
||||||
|
GPIO.output(LED, False)
|
||||||
|
|
||||||
|
|
||||||
|
def toggleLED(LED):
|
||||||
|
GPIO.output(LED, GPIO.input(LED) ^ 1)
|
||||||
|
|
||||||
|
|
||||||
|
def writeLog(watt, total, importCount, exportCount, rotTime, loadaverage):
|
||||||
|
localtime = time.localtime(time.time())
|
||||||
|
filename = '%s_kWh-meter.log' % time.strftime("%Y-%m-%d", localtime)
|
||||||
|
line = "%s\t%s\t%s\t%s\t%.3f\t%.3f\t%.3f\t%.0f\t%.3f\t%.3f\t%.3f\n" % (
|
||||||
|
time.strftime("%Y-%m-%d %H:%M:00", localtime), time.strftime("%Y-%m-%d", localtime),
|
||||||
|
time.strftime("%H:%M:00", localtime), watt, total, importCount, exportCount, rotTime, loadaverage[0],
|
||||||
|
loadaverage[1], loadaverage[2])
|
||||||
|
|
||||||
|
logfile = open(filename, 'a')
|
||||||
|
try:
|
||||||
|
logfile.write(line)
|
||||||
|
finally:
|
||||||
|
logfile.close()
|
||||||
|
|
||||||
|
logfile.close()
|
||||||
|
|
||||||
|
|
||||||
|
def writesettings(config):
|
||||||
|
with open('kwhmeter.conf', 'wb') as configfile:
|
||||||
|
config.write(configfile)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def readsettings():
|
||||||
|
config = ConfigParser.SafeConfigParser()
|
||||||
|
config.read('kwhmeter.conf')
|
||||||
|
|
||||||
|
if not config.has_section('kWh Settings'):
|
||||||
|
config.add_section('kWh Settings')
|
||||||
|
if not config.has_option('kWh Settings', 'LeftChannelID'):
|
||||||
|
config.set('kWh Settings', 'LeftChannelID', '2')
|
||||||
|
if not config.has_option('kWh Settings', 'RightChannelID'):
|
||||||
|
config.set('kWh Settings', 'RightChannelID', '0')
|
||||||
|
|
||||||
|
|
||||||
|
# Section kWh data
|
||||||
|
if not config.has_section('kWh'):
|
||||||
|
config.add_section('kWh')
|
||||||
|
if not config.has_option('kWh', 'importCounter'):
|
||||||
|
config.set('kWh', 'importCounter', '0')
|
||||||
|
if not config.has_option('kWh', 'exportCounter'):
|
||||||
|
config.set('kWh', 'exportCounter', '0')
|
||||||
|
if not config.has_option('kWh', 'rotationsPerKWh'):
|
||||||
|
config.set('kWh', 'rotationsPerKWh', '600')
|
||||||
|
if not config.has_option('kWh', 'cumuliday'):
|
||||||
|
config.set('kWh', 'cumuliday', date.today().strftime("%Y%m%d"))
|
||||||
|
|
||||||
|
# Add Pvoutput stuff
|
||||||
|
if not config.has_section('pvout'):
|
||||||
|
config.add_section('pvout')
|
||||||
|
if not config.has_option('pvout','pvout_enabled'):
|
||||||
|
config.set('pvout','pvout_enabled','false')
|
||||||
|
if not config.has_option('pvout','pvout_apikey'):
|
||||||
|
config.set('pvout','pvout_apikey','0')
|
||||||
|
if not config.has_option('pvout','pvout_sysid'):
|
||||||
|
config.set('pvout','pvout_sysid','0')
|
||||||
|
|
||||||
|
# If you want to save in a MySQL DB, uncomment below:
|
||||||
|
# Section MySQL
|
||||||
|
#if not config.has_section('MySQL'):
|
||||||
|
# config.add_section('MySQL')
|
||||||
|
#if not config.has_option('MySQL', 'host'):
|
||||||
|
# config.set('MySQL', 'host', 'localhost')
|
||||||
|
#if not config.has_option('MySQL', 'user'):
|
||||||
|
# config.set('MySQL', 'user', 'root')
|
||||||
|
#if not config.has_option('MySQL', 'passwd'):
|
||||||
|
# config.set('MySQL', 'passwd', 'root')
|
||||||
|
#if not config.has_option('MySQL', 'db'):
|
||||||
|
# config.set('MySQL', 'db', 'kwhRijnsraat214')
|
||||||
|
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def savekwhdata(config, importCounter, exportCounter):
|
||||||
|
config.set('kWh', 'importCounter', "%.0f" % importCounter)
|
||||||
|
config.set('kWh', 'exportCounter', "%.0f" % exportCounter)
|
||||||
|
writesettings(config)
|
||||||
|
|
||||||
|
|
||||||
|
# If you want to save in a MySQL DB, uncomment below:
|
||||||
|
#def savetodb(config, watt, total, imported, exported):
|
||||||
|
# section = 'MySQL'
|
||||||
|
# localtime = time.localtime(time.time())
|
||||||
|
#
|
||||||
|
# conn = MySQLdb.connect(host = config.get(section, 'host'),
|
||||||
|
# user = config.get(section, 'user'),
|
||||||
|
# passwd = config.get(section, 'passwd'),
|
||||||
|
# db = config.get(section, 'db'))
|
||||||
|
# cursor = conn.cursor()
|
||||||
|
#
|
||||||
|
# try:
|
||||||
|
# cursor.execute(
|
||||||
|
# "INSERT INTO `DayDatakWh` (`DateTime`, `CurrentPower`, `ETotalToday`, `EImportToday`, `EExportToday`, `CurrentUsage`, `EUsageToday`, `PVOutput`, `CHANGETIME`) VALUES ('%s', %s, %.3f, %.3f, %.3f, NULL, NULL, NULL, '0000-00-00 00:00:00');" % (
|
||||||
|
# time.strftime("%Y-%m-%d %H:%M:00", localtime), watt, total, imported, exported))
|
||||||
|
# conn.commit()
|
||||||
|
# except:
|
||||||
|
# conn.rollback()
|
||||||
|
# conn.close()
|
||||||
|
#
|
||||||
|
# return True
|
||||||
|
|
||||||
|
def printinfo(line):
|
||||||
|
timeStr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||||
|
print "%s\t%s" % (timeStr, line)
|
||||||
|
#serialDev.writeLine("%s\t%s" % (timeStr, line))
|
||||||
|
|
||||||
|
def exportPvoutput(config, gentotal, genpower, contotal, conpower):
|
||||||
|
|
||||||
|
pvout_enabled = config.getboolean('pvout','pvout_enabled')
|
||||||
|
pvout_apikey = config.get('pvout','pvout_apikey')
|
||||||
|
pvout_sysid = config.get('pvout','pvout_sysid')
|
||||||
|
|
||||||
|
url = "http://pvoutput.org/service/r2/addstatus.jsp"
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
|
get_data = {
|
||||||
|
'key': pvout_apikey,
|
||||||
|
'sid': pvout_sysid,
|
||||||
|
'd': now.strftime('%Y%m%d'),
|
||||||
|
't': now.strftime('%H:%M'),
|
||||||
|
'v1': gentotal * 1000,
|
||||||
|
'v2': genpower,
|
||||||
|
'v3': contotal * 1000,
|
||||||
|
'v4': conpower,
|
||||||
|
'c1': "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get_data_encoded = urllib.urlencode(get_data) # UrlEncode the parameters
|
||||||
|
printinfo(get_data_encoded)
|
||||||
|
request_object = urllib2.Request(url + '?' + get_data_encoded) # Create request object
|
||||||
|
try:
|
||||||
|
response = urllib2.urlopen(request_object) #make the request and store the response
|
||||||
|
printinfo("Pvoutput Exported")
|
||||||
|
return True
|
||||||
|
except urllib.error.HTTPError, e:
|
||||||
|
printinfo('HTTPError = ' + str(e.code))
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
checksLogger.error('generic exception: ' + traceback.format_exc())
|
||||||
|
|
||||||
|
#http://pvoutput.org/service/r2/addstatus.jsp?
|
||||||
|
|
||||||
|
def calibratesensors(config):
|
||||||
|
printinfo("Do calibration of sensors . . .")
|
||||||
|
sensorleftLValue = 9999
|
||||||
|
sensorleftHValue = -1
|
||||||
|
sensorrightLValue = 9999
|
||||||
|
sensorrightHValue = -1
|
||||||
|
|
||||||
|
turnoffLED(boardLED)
|
||||||
|
turnoffLED(greenLED)
|
||||||
|
turnonLED(redLED)
|
||||||
|
|
||||||
|
startTime = millis()
|
||||||
|
elapsedTime = millis() - startTime
|
||||||
|
startBlink = millis()
|
||||||
|
startInfo = millis()
|
||||||
|
|
||||||
|
sensorleftDiff = 0
|
||||||
|
sensorrightDiff = 0
|
||||||
|
|
||||||
|
while (elapsedTime < 30000) or (sensorleftDiff < 40) or (sensorrightDiff < 40): #or not GPIO.input(switch):
|
||||||
|
# run calibration for min. 10 seconds,
|
||||||
|
# and distance between low and high value must be at least 40 ticks
|
||||||
|
# or while the switch on the board is hold down (pressing the switch = 0, not pressing the switch = 1)
|
||||||
|
|
||||||
|
sensordata = samplesensors(config)
|
||||||
|
sensorleftCurrent = sensordata['left']
|
||||||
|
sensorrightCurrent = sensordata['right']
|
||||||
|
|
||||||
|
if sensorleftLValue > sensorleftCurrent:
|
||||||
|
sensorleftLValue = sensorleftCurrent
|
||||||
|
if sensorleftHValue < sensorleftCurrent:
|
||||||
|
sensorleftHValue = sensorleftCurrent
|
||||||
|
|
||||||
|
if sensorrightLValue > sensorrightCurrent:
|
||||||
|
sensorrightLValue = sensorrightCurrent
|
||||||
|
if sensorrightHValue < sensorrightCurrent:
|
||||||
|
sensorrightHValue = sensorrightCurrent
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
printinfo("Sensor left: %s\tSensor right: %s" % (sensorleftCurrent, sensorrightCurrent))
|
||||||
|
|
||||||
|
if millis() - startBlink > 100:
|
||||||
|
toggleLED(boardLED)
|
||||||
|
toggleLED(greenLED)
|
||||||
|
toggleLED(redLED)
|
||||||
|
startBlink = millis()
|
||||||
|
|
||||||
|
|
||||||
|
sensorleftDiff = sensorleftHValue - sensorleftLValue
|
||||||
|
sensorrightDiff = sensorrightHValue - sensorrightLValue
|
||||||
|
|
||||||
|
if millis() - startInfo > 1000:
|
||||||
|
printinfo("Time %s: \tSL: %s (diff: %s) \t\tSR: %s (diff: %s)" % (elapsedTime, sensorleftCurrent, sensorleftDiff, sensorrightCurrent, sensorrightDiff))
|
||||||
|
startInfo = millis()
|
||||||
|
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
elapsedTime = millis() - startTime
|
||||||
|
|
||||||
|
|
||||||
|
sensorleftLTh = sensorleftLValue + ((sensorleftDiff / 10) * 5) # 50% above min
|
||||||
|
sensorleftHTh = sensorleftHValue - ((sensorleftDiff / 10) * 2) # 20% below max
|
||||||
|
sensorrightLTh = sensorrightLValue + ((sensorrightDiff / 10) * 5) # 50% above min
|
||||||
|
sensorrightHTh = sensorrightHValue - ((sensorrightDiff / 10) * 2) # 20% below max
|
||||||
|
|
||||||
|
turnoffLED(boardLED)
|
||||||
|
turnoffLED(greenLED)
|
||||||
|
turnoffLED(redLED)
|
||||||
|
|
||||||
|
printinfo("Calibration done!")
|
||||||
|
printinfo("Left low: %s" % sensorleftLValue)
|
||||||
|
printinfo(" high: %s" % sensorleftHValue)
|
||||||
|
printinfo(" diff: %s" % sensorleftDiff)
|
||||||
|
printinfo(" lthld.%s" % sensorleftLTh)
|
||||||
|
printinfo(" hthld.%s" % sensorleftHTh)
|
||||||
|
printinfo("Right low: %s" % sensorrightLValue)
|
||||||
|
printinfo(" high: %s" % sensorrightHValue)
|
||||||
|
printinfo(" diff: %s" % sensorrightDiff)
|
||||||
|
printinfo(" lthld.%s" % sensorrightLTh)
|
||||||
|
printinfo(" hthld.%s" % sensorrightHTh)
|
||||||
|
printinfo("")
|
||||||
|
|
||||||
|
config.set('kWh', 'minleft', "%.0f" % sensorleftLValue)
|
||||||
|
config.set('kWh', 'maxleft', "%.0f" % sensorleftHValue)
|
||||||
|
config.set('kWh', 'minmarginleft', "%.0f" % sensorleftLTh)
|
||||||
|
config.set('kWh', 'maxmarginleft', "%.0f" % sensorleftHTh)
|
||||||
|
|
||||||
|
config.set('kWh', 'minright', "%.0f" % sensorrightLValue)
|
||||||
|
config.set('kWh', 'maxright', "%.0f" % sensorrightHValue)
|
||||||
|
config.set('kWh', 'minmarginright', "%.0f" % sensorrightLTh)
|
||||||
|
config.set('kWh', 'maxmarginright', "%.0f" % sensorrightHTh)
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def millis():
|
||||||
|
return int(round(time.time() * 1000))
|
||||||
|
|
||||||
|
|
||||||
|
def samplesensors(config):
|
||||||
|
# Sample the left and right sensor for maxsamples times (in order to get an average value)
|
||||||
|
leftid = config.getint('kWh Settings', 'LeftChannelID')
|
||||||
|
rightid = config.getint('kWh Settings', 'RightChannelID')
|
||||||
|
maxsamples = 20
|
||||||
|
sensorleft = 0
|
||||||
|
sensorright = 0
|
||||||
|
|
||||||
|
for loopCount in range(0, maxsamples):
|
||||||
|
sensorleft += readadc(leftid)
|
||||||
|
sensorright += readadc(rightid)
|
||||||
|
#print "%s | %s" % (sensorleft, sensorright)
|
||||||
|
sensorleft /= maxsamples
|
||||||
|
sensorright /= maxsamples
|
||||||
|
|
||||||
|
return {'left': sensorleft, 'right': sensorright}
|
||||||
|
|
||||||
|
|
||||||
|
def dotFollower(config):
|
||||||
|
# This is the main part of the code, which will start to minitor the black dot on the disc
|
||||||
|
|
||||||
|
# Do some initialisations
|
||||||
|
rotationsperkwh = config.getfloat("kWh", "rotationsPerKWh") * 1.00
|
||||||
|
counterimport = config.getint("kWh", "importCounter")
|
||||||
|
counterexport = config.getint("kWh", "exportCounter")
|
||||||
|
countertotal = counterimport + counterexport
|
||||||
|
currentpower = 0
|
||||||
|
timeperrotation = 0
|
||||||
|
|
||||||
|
left = False
|
||||||
|
right = False
|
||||||
|
leftdetected = False
|
||||||
|
rightdetected = False
|
||||||
|
lefttimestamp = time.time()
|
||||||
|
leftprevtimestamp = time.time()
|
||||||
|
righttimestamp = time.time()
|
||||||
|
rightprevtimestamp = time.time()
|
||||||
|
sensorinnertimestamp = time.time()
|
||||||
|
sensorinnerlength = 0
|
||||||
|
sensoroutertimestamp = time.time()
|
||||||
|
sensoroutherlength = 0
|
||||||
|
exportpower = 0
|
||||||
|
importpower = 0
|
||||||
|
|
||||||
|
thisday = config.get("kWh", "cumuliday")
|
||||||
|
printinfo("Date: %s" % thisday)
|
||||||
|
|
||||||
|
|
||||||
|
leftmin = config.getint("kWh", "minmarginleft")
|
||||||
|
leftmax = config.getint("kWh", "maxmarginleft")
|
||||||
|
rightmin = config.getint("kWh", "minmarginright")
|
||||||
|
rightmax = config.getint("kWh", "maxmarginright")
|
||||||
|
|
||||||
|
logexported = False
|
||||||
|
loadaverage = LoadAverage.Loadaverage()
|
||||||
|
loadaverageadded = False
|
||||||
|
|
||||||
|
# Keep on running while the switch is NOT pressed
|
||||||
|
while 1: #GPIO.input(switch):
|
||||||
|
sensordata = samplesensors(config)
|
||||||
|
|
||||||
|
# left sensor
|
||||||
|
if sensordata['left'] >= leftmax and not left:
|
||||||
|
# turn left to False
|
||||||
|
left = True
|
||||||
|
turnonLED(greenLED)
|
||||||
|
leftdetected = True
|
||||||
|
leftprevtimestamp = lefttimestamp
|
||||||
|
lefttimestamp = time.time()
|
||||||
|
#printinfo("Left sensor: . %.5f secs" % (lefttimestamp - leftprevtimestamp))
|
||||||
|
if not rightdetected:
|
||||||
|
sensorinnertimestamp = time.time()
|
||||||
|
sensoroutherlength = time.time() - sensoroutertimestamp
|
||||||
|
else:
|
||||||
|
sensoroutertimestamp = time.time()
|
||||||
|
sensorinnerlength = time.time() - sensorinnertimestamp
|
||||||
|
|
||||||
|
if sensordata['left'] <= leftmin and left:
|
||||||
|
# turn left to False
|
||||||
|
left = False
|
||||||
|
turnoffLED(greenLED)
|
||||||
|
#printinfo("Left off")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# right sensor
|
||||||
|
if sensordata['right'] >= rightmax and not right:
|
||||||
|
# turn right to False
|
||||||
|
right = True
|
||||||
|
turnonLED(redLED)
|
||||||
|
rightdetected = True
|
||||||
|
rightprevtimestamp = righttimestamp
|
||||||
|
righttimestamp = time.time()
|
||||||
|
#printinfo("Right sensor:. %.5f secs" % (righttimestamp - rightprevtimestamp))
|
||||||
|
if not leftdetected:
|
||||||
|
sensorinnertimestamp = time.time()
|
||||||
|
sensoroutherlength = time.time() - sensoroutertimestamp
|
||||||
|
else:
|
||||||
|
sensoroutertimestamp = time.time()
|
||||||
|
sensorinnerlength = time.time() - sensorinnertimestamp
|
||||||
|
|
||||||
|
if sensordata['right'] <= rightmin and right:
|
||||||
|
# turn right to False
|
||||||
|
right = False
|
||||||
|
turnoffLED(redLED)
|
||||||
|
#printinfo("Right off")
|
||||||
|
|
||||||
|
if not left and not right and leftdetected and rightdetected:
|
||||||
|
#rotation detected!
|
||||||
|
leftdetected = False
|
||||||
|
rightdetected = False
|
||||||
|
if sensorinnerlength < sensoroutherlength: # detection of left and right was correct
|
||||||
|
turnonLED(boardLED)
|
||||||
|
# Determine direction
|
||||||
|
if lefttimestamp < righttimestamp:
|
||||||
|
# The left sensor was seen before the right
|
||||||
|
# S1 --> S2
|
||||||
|
# Rotation is "importing from the net"
|
||||||
|
rotation = 1
|
||||||
|
counterimport += 1
|
||||||
|
else:
|
||||||
|
# The right sensor was seen before the left
|
||||||
|
# S1 <-- S2
|
||||||
|
# Rotation is "exporting to the net"
|
||||||
|
rotation = -1
|
||||||
|
counterexport += 1
|
||||||
|
countertotal = counterimport - counterexport
|
||||||
|
|
||||||
|
# I'll average the left and right rotation time to get a "smoother" value (in principle I calculate the point between the 2 sensors)
|
||||||
|
timeperrotation = (((lefttimestamp - leftprevtimestamp) + (righttimestamp - rightprevtimestamp)) / 2)
|
||||||
|
currentpower = int(rotation * rotationsperkwh * 10 / (timeperrotation))
|
||||||
|
|
||||||
|
if rotation == 1:
|
||||||
|
printinfo("-> importing from net")
|
||||||
|
importpower = currentpower
|
||||||
|
exportpower = 0
|
||||||
|
else:
|
||||||
|
printinfo("<- exporting to net")
|
||||||
|
exportpower = currentpower * -1
|
||||||
|
importpower = 0
|
||||||
|
#printinfo("Rotation time: . %.5f secs" % timeperrotation)
|
||||||
|
#printinfo("-- -- -- -- -- -- -- -- -- -- --")
|
||||||
|
#printinfo("Inner gab: . . . %.5f secs" % sensorinnerlength)
|
||||||
|
#printinfo("Outer: . . . . . %.5f secs" % sensoroutherlength)
|
||||||
|
#printinfo("Total: . . . . . %.5f secs" % (sensoroutherlength + sensorinnerlength))
|
||||||
|
printinfo("Rotation time: . %.5f secs" % timeperrotation)
|
||||||
|
printinfo("Current power: . %.0f Watt" % currentpower)
|
||||||
|
#printinfo("ImportCount: . . %.0f" % counterimport)
|
||||||
|
#printinfo("ExportCount: . . %.0f" % counterexport)
|
||||||
|
printinfo("Import:. . . . . %.2f kWh" % (counterimport / rotationsperkwh))
|
||||||
|
printinfo("Export:. . . . . %.2f kWh" % (counterexport / rotationsperkwh))
|
||||||
|
printinfo("Total: . . . . . %.2f kWh" % (countertotal / rotationsperkwh))
|
||||||
|
printinfo("Load average:. . %.0f W, %.0f W, %.0f W" % loadaverage.loadaverage())
|
||||||
|
printinfo("--------------------------------------------------------------------------------")
|
||||||
|
|
||||||
|
# do a tiny nap
|
||||||
|
time.sleep(0.1)
|
||||||
|
turnoffLED(boardLED)
|
||||||
|
else:
|
||||||
|
# Ooops... inner gab is bigger then the outer route??? We are detecting the wrong way!
|
||||||
|
# sleep a bit and try again
|
||||||
|
printinfo("Skipping rotation . . .")
|
||||||
|
if (sensoroutherlength / 4) < 10:
|
||||||
|
time.sleep(sensoroutherlength / 4)
|
||||||
|
else:
|
||||||
|
time.sleep(10)
|
||||||
|
else:
|
||||||
|
time.sleep(0.001)
|
||||||
|
|
||||||
|
if time.gmtime()[5] % 10 == 0:
|
||||||
|
# Every 10 seconds print the current values
|
||||||
|
if not loadaverageadded:
|
||||||
|
loadaverage.addvalue(currentpower)
|
||||||
|
loadaverageadded = True
|
||||||
|
|
||||||
|
if time.gmtime()[4] % 5 == 0:
|
||||||
|
# Every 5 minutes, write a log entry & DB record
|
||||||
|
if not logexported:
|
||||||
|
writeLog(currentpower, (countertotal / rotationsperkwh), (counterimport / rotationsperkwh),
|
||||||
|
(counterexport / rotationsperkwh), (timeperrotation * 1000), loadaverage.loadaverage())
|
||||||
|
savekwhdata(config, counterimport, counterexport)
|
||||||
|
# If you want to save to pvoutput, uncomment the line below:
|
||||||
|
exportPvoutput(config, (counterexport / rotationsperkwh), exportpower, (counterimport / rotationsperkwh), importpower)
|
||||||
|
logexported = True
|
||||||
|
else:
|
||||||
|
logexported = False
|
||||||
|
else:
|
||||||
|
loadaverageadded = False
|
||||||
|
|
||||||
|
if thisday != date.today().strftime("%Y%m%d"):
|
||||||
|
if logexported == True:
|
||||||
|
exportpower = 0
|
||||||
|
importpower = 0
|
||||||
|
thisday = date.today().strftime("%Y%m%d")
|
||||||
|
config.set('kWh', 'cumuliday',thisday)
|
||||||
|
|
||||||
|
writesettings(config)
|
||||||
|
|
||||||
|
|
||||||
|
# Main program routine begins here:
|
||||||
|
#----------------------------------
|
||||||
|
|
||||||
|
config = readsettings()
|
||||||
|
writesettings(config)
|
||||||
|
|
||||||
|
#init raspberry pi gpio pins
|
||||||
|
GPIO.setwarnings(False)
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
|
||||||
|
GPIO.setup(switch, GPIO.IN)
|
||||||
|
GPIO.setup(boardLED, GPIO.OUT, initial = GPIO.LOW)
|
||||||
|
GPIO.setup(greenLED, GPIO.OUT, initial = GPIO.LOW)
|
||||||
|
GPIO.setup(redLED, GPIO.OUT, initial = GPIO.LOW)
|
||||||
|
|
||||||
|
#set LEDs default off
|
||||||
|
turnoffLED(boardLED)
|
||||||
|
turnoffLED(greenLED)
|
||||||
|
turnoffLED(redLED)
|
||||||
|
|
||||||
|
writesettings(config)
|
||||||
|
|
||||||
|
# Infinite loop
|
||||||
|
while True:
|
||||||
|
config = calibratesensors(config)
|
||||||
|
dotFollower(config)
|
||||||
|
|
||||||
|
# we will never get here...
|
||||||
|
GPIO.remove_event_detect(switch)
|
||||||
|
GPIO.cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user