Mercurial > code > home > repos > homeauto
changeset 492:139eee3a17c0
rm old arduino code for a few boards. includes driver for IR sensor taped to power meter; virtualwire communications from garage to bathroom.
Ignore-this: de7e267e47243e122d0d8cc111d4497a
author | drewp@bigasterisk.com |
---|---|
date | Sun, 21 Apr 2019 01:34:24 -0700 |
parents | 92d01aba812a |
children | f5664bea7cfe |
files | service/garageArduino/bathroom_recv/bathroom_recv.ino service/garageArduino/bathroom_satt/bathroom_satt.ino service/garageArduino/garage/garage.ino service/garageArduino/garageArduino.py service/garageArduino/index.html service/garageArduino/powermeter/analog-samples.png service/garageArduino/powermeter/end-of-day.png service/garageArduino/powermeter/sensor.sch service/garageArduino/pydeps |
diffstat | 9 files changed, 0 insertions(+), 834 deletions(-) [+] |
line wrap: on
line diff
--- a/service/garageArduino/bathroom_recv/bathroom_recv.ino Sun Apr 21 01:33:13 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - board: 'Digispark (Tiny Core)' - programmer: 'Digispark' - - pin 0 DI from radio - pin 1 DO to radio (and green status led) - pin 2 SCK to radio - pin 3 output to LED string - pin 4 input from garage arduino - pin 5 output to garage arduino - - (attiny85 pin 5 is MOSI, pin 6 is MISO, 7 might be clock) - -*/ -#include <VirtualWire.h> - -#include <Adafruit_NeoPixel.h> - -// Parameter 1 = number of pixels in strip -// Parameter 2 = pin number (most are valid) -// Parameter 3 = pixel type flags, add together as needed: -// NEO_RGB Pixels are wired for RGB bitstream -// NEO_GRB Pixels are wired for GRB bitstream -// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels) -// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip) -Adafruit_NeoPixel strip = Adafruit_NeoPixel(4, 3, NEO_GRB + NEO_KHZ800); - -#define SET(i, r, g, b) strip.setPixelColor(i, strip.Color(r, g, b)); strip.show(); - -int numLeds = 4; - -void wakeUpPattern() { - for (int t = 0; t < 255; t += 2) { - for (int i = 0; i < numLeds; i++) { - //SET(i, 255 - t, max(0, 255 - t * 2), max(0, 255 - t * 3)); - SET(i, - (i % 2) ? (255 - t) : 0, - (i % 2) ? 0 : (255 - t), - (i % 2) ? (255 - t) : 0); - } - delay(10); - } - SET(0, 0, 0, 0); - SET(1, 0, 0, 0); - SET(2, 0, 0, 0); - SET(3, 0, 0, 0); -} - -void blinkFailedMessageError() { - digitalWrite(1, 1); - delay(100); - digitalWrite(1, 0); -} - -void blinkShortBufferError() { - digitalWrite(1, 1); - delay(100); - digitalWrite(1, 0); - delay(50); - digitalWrite(1, 1); - delay(100); - digitalWrite(1, 0); -} - -void setup() { - pinMode(1, OUTPUT); // for errors - - vw_set_rx_pin(4); - vw_setup(2000); // Bits per sec - - vw_rx_start(); // Start the receiver PLL running - - strip.begin(); - strip.show(); - - wakeUpPattern(); -} - -void loop() { - uint8_t buf[VW_MAX_MESSAGE_LEN]; - uint8_t buflen = VW_MAX_MESSAGE_LEN; - - vw_wait_rx(); - int success = vw_get_message(buf, &buflen); - if (!success) { - blinkFailedMessageError(); - return; - } - if (buflen < numLeds * 3) { - blinkShortBufferError(); - return; - } - - for (int i=0; i < numLeds; i++) { - strip.setPixelColor(i, strip.Color( - buf[i * 3 + 0], - buf[i * 3 + 1], - buf[i * 3 + 2])); - } - strip.show(); -} -
--- a/service/garageArduino/bathroom_satt/bathroom_satt.ino Sun Apr 21 01:33:13 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -/* - - DI from radio - - DO to radio - - SCK to radio - - output to the LED string - - PIR in - - room light analog in - - temp/humid https://github.com/adafruit/DHT-sensor-library -*/ -
--- a/service/garageArduino/garage/garage.ino Sun Apr 21 01:33:13 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,188 +0,0 @@ -#include <VirtualWire.h> - -/* -board is Arduino UNO with '328 - */ - -int datapin = 7; // DI -int latchpin = 9; // LI -int clockpin = 8; // CI - -unsigned long SB_CommandPacket; -int SB_CommandMode; -int SB_BlueCommand; -int SB_RedCommand; -int SB_GreenCommand; - -#define SHIFT(val) shiftOut(datapin, clockpin, MSBFIRST, val) - -void SB_SendPacket() { - /* high bits are 00 for color, 01 for current */ - SB_CommandPacket = SB_CommandMode & B11; - SB_CommandPacket = (SB_CommandPacket << 10) | (SB_BlueCommand & 1023); - SB_CommandPacket = (SB_CommandPacket << 10) | (SB_RedCommand & 1023); - SB_CommandPacket = (SB_CommandPacket << 10) | (SB_GreenCommand & 1023); - - SHIFT(SB_CommandPacket >> 24); - SHIFT(SB_CommandPacket >> 16); - SHIFT(SB_CommandPacket >> 8); - SHIFT(SB_CommandPacket); -} - -void latch() { - delayMicroseconds(100); - digitalWrite(latchpin,HIGH); // latch data into registers - delayMicroseconds(100); - digitalWrite(latchpin,LOW); -} - -void setCurrent(byte r, byte g, byte b) { - /* 127 = max */ - SB_CommandMode = B01; // Write to current control registers - SB_RedCommand = r; - SB_GreenCommand = g; - SB_BlueCommand = b; - SB_SendPacket(); - latch(); -} - - -void setup() { - - pinMode(2, INPUT); - digitalWrite(2, LOW); -// PIR sensor on here is a -// http://octopart.com/555-28027-parallax-708653 in a -// http://octopart.com/1551ggy-hammond-15686 box - - // the phototransistor on analog2 is jameco 2006414 - - pinMode(3, OUTPUT); - digitalWrite(3, LOW); - // this drives a relay for the garage door. There is a - // LP filter on it so the garage doesn't open if there's - // an arduino power-on glitch. It may be that atmel has - // circuitry to prevent such glitches, so a pull-down - // resistor may be enough. I haven't checked carefully. - - pinMode(4, OUTPUT); - pinMode(5, OUTPUT); - // video input selector. picks which video input will be multiplexed - // into the bt848 capture card - - pinMode(6, OUTPUT); // front yard light - - pinMode(7, OUTPUT); // bathroom shiftbrite data - pinMode(8, OUTPUT); // bathroom shiftbrite clk - pinMode(9, OUTPUT); // bathroom shiftbrite latch - - vw_set_ptt_pin(11); // waste, but VW will be writing to this - vw_set_tx_pin(10); // bathroom new virtualwire out - - // Bits per sec. Match this in bathroom_recv. - // The reason to have this anywhere high is to - // make a color change block the sending arduino - // for less time. - // 2000bps -> 120ms PUT requests - // 8000bps -> 30ms PUT requests, but lots of message errors - vw_setup(2000); - - for (int i=0; i < 1; i++) { - setCurrent(127, 127, 127); - } - - Serial.begin(115200); -} - -int newBlinks = 0; -int lastLevel = 0; -int threshold = 750; -int hold = 3; // pulse must last this many loops. Guessing-- I don't know the loop rate or the pulse width -int seenFor = 0; - -void loop() -{ - unsigned char head, cmd, arg; - int level = analogRead(3) < threshold; - - if (level) { - seenFor++; - if (seenFor == hold) { - newBlinks++; - } - } else { - seenFor = 0; - } - - if (Serial.available() >= 3) { - head = Serial.read(); - if (head != 0x60) { - Serial.flush(); - return; - } - cmd = Serial.read(); - arg = Serial.read(); - Serial.flush(); - if (cmd == 0x00) { - Serial.print("{\"ok\":true}\n"); - } else if (cmd == 0x01) { // poll - Serial.print("{\"newBlinks\":"); - Serial.print(newBlinks); - Serial.print(", \"motion\":"); - Serial.print(digitalRead(2) ? "true" : "false"); - Serial.print("}\n"); - newBlinks = 0; - } else if (cmd == 0x02) { - // current level - Serial.print("{\"z\":"); - Serial.print(analogRead(3)); - Serial.print("}\n"); - } else if (cmd == 0x03) { - if (arg != 0) { - threshold = arg << 2; - } - Serial.print("{\"threshold\":"); - Serial.print(threshold); - Serial.print("}\n"); - } else if (cmd == 0x04) { - digitalWrite(3, arg); - Serial.print("{\"garage\":"); - Serial.print(arg ? "true" : "false"); - Serial.print("}\n"); - } else if (cmd == 0x05) { // set video - digitalWrite(4, arg & 1); - digitalWrite(5, arg & 2); - Serial.print("{\"videoSelect\":"); - Serial.print(arg); - Serial.print("}\n"); - } else if (cmd == 0x06) { // talk to shiftbrite - /* - one byte for the string length, then a buffer to be shifted - out to all the shiftbrites - */ - for (int i=0; i<arg; i++) { - while (Serial.available() == 0) NULL; - SHIFT(Serial.read()); - } - latch(); - Serial.print("{\"ok\":1}\n"); - } else if (cmd == 0x07) { // send virtualwire - // arg is the number of bytes in the message to send - uint8_t msg[99]; - for (int i=0; i<arg; i++) { - while (Serial.available() == 0) NULL; - msg[i] = Serial.read(); - } - if (!vw_send(msg, arg)) { - Serial.print("{\"err\":\"message too long for virtualwire\"}"); - return; - } - vw_wait_tx(); - Serial.print("{\"sent\":"); - Serial.print(arg); - Serial.print("}\n"); - } - } -} - -
--- a/service/garageArduino/garageArduino.py Sun Apr 21 01:33:13 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,319 +0,0 @@ -#!bin/python -""" -talks to frontdoordriver.pde on an arduino -""" - -from __future__ import division - -import cyclone.web, json, traceback, os, sys, time, logging, bitstring -from twisted.internet import reactor, task, defer -from twisted.web.client import getPage -sys.path.append("/my/proj/house/frontdoor") -from loggingserial import LoggingSerial -sys.path.append("/my/proj/homeauto/lib") -from cycloneerr import PrettyErrorHandler -from logsetup import log -sys.path.append("../../../room") -from carbondata import CarbonClient -sys.path.append("/my/site/magma") -from stategraph import StateGraph -from rdflib import Namespace, RDF, Literal -from webcolors import hex_to_rgb, rgb_to_hex - -def rgbFromHex(h): - """returns tuple of 0..1023""" - norm = hex_to_rgb(h) - return tuple([x * 4 for x in norm]) - -def hexFromRgb(rgb): - return rgb_to_hex(tuple([x // 4 for x in rgb])) - - -ROOM = Namespace("http://projects.bigasterisk.com/room/") -DEV = Namespace("http://projects.bigasterisk.com/device/") - -class ArduinoGarage(object): - def __init__(self, port='/dev/ttyACM0'): - self.ser = LoggingSerial(port=port, baudrate=115200, timeout=1) - time.sleep(2) # wait for a arduino reset to pass - self.ser.flush() - self.ping() - - def ping(self): - self.ser.write("\x60\x00\x00") - msg = self.ser.readJson() - assert msg == {"ok":True}, msg - - def poll(self): - self.ser.write("\x60\x01\x00") - ret = self.ser.readJson() - return ret - - def lastLevel(self): - self.ser.write("\x60\x02\x00") - return self.ser.readJson()['z'] - - def setThreshold(self, t): - """set 10-bit threshold""" - self.ser.write("\x60\x03"+chr(max(1 << 2, t) >> 2)) - return self.ser.readJson()['threshold'] - - def setGarage(self, level): - """set garage door opener pin""" - self.ser.write("\x60\x04"+chr(int(bool(level)))) - return self.ser.readJson()['garage'] - - def setVideoSelect(self, chan): - """set video select bits from 0..3""" - self.ser.write("\x60\x05"+chr(chan)) - - return self.ser.readJson()['videoSelect'] - - def shiftbrite(self, colors): - """ - shift out this sequence of (r,g,b) triples of 10-bit ints - """ - resetCurrent = "".join(bitstring.pack("0b01, uint:10, uint:10, uint:10", - 127, 127, 127).bytes - for loop in range(len(colors))) - out = "".join(bitstring.pack("0b00, uint:10, uint:10, uint:10", - b, r, g).bytes - for r,g,b in colors) - out = resetCurrent + out - self.ser.write("\x60\x06" + chr(len(out)) + out) - msg = self.ser.readJson() - assert msg == {"ok":1}, msg - - def virtualwire(self, colors): - """ - send this sequence of (r,g,b) 8-bit triples - """ - numLeds = 4 - # vw receiver wants data for all leds every time - colors = (list(colors) + [(0,0,0)] * numLeds)[:numLeds] - msg = "".join("%s%s%s" % (chr(r), chr(g), chr(b)) for r,g,b in colors) - self.ser.write("\x60\x07" + chr(len(msg)) + msg) - msg = self.ser.readJson() - assert msg == {"sent": 12}, msg - - -class Index(PrettyErrorHandler, cyclone.web.RequestHandler): - def get(self): - """ - this is an acceptable status check since it makes a round-trip - to the arduino before returning success - """ - self.settings.arduino.ping() - - self.set_header("Content-Type", "application/xhtml+xml") - self.write(open("index.html").read()) - -class GraphPage(PrettyErrorHandler, cyclone.web.RequestHandler): - def get(self): - self.set_header("Content-Type", "application/x-trig") - g = StateGraph(ROOM['garageArduino']) - self.settings.poller.assertIsCurrent() - g.add((DEV['frontDoorMotion'], ROOM['state'], - ROOM['motion'] if self.settings.poller.lastValues['motion'] else - ROOM['noMotion'])) - g.add((ROOM['house'], ROOM['usingPower'], - Literal(self.settings.poller.lastWatts, datatype=ROOM["#watts"]))) - self.write(g.asTrig()) - -class FrontDoorMotion(PrettyErrorHandler, cyclone.web.RequestHandler): - def get(self): - self.set_header("Content-Type", "application/javascript") - self.settings.poller.assertIsCurrent() - self.write(json.dumps({"frontDoorMotion" : - self.settings.poller.lastValues['motion']})) - -class HousePower(PrettyErrorHandler, cyclone.web.RequestHandler): - def get(self): - self.set_header("Content-Type", "application/javascript") - self.settings.poller.assertIsCurrent() - w = self.settings.poller - self.write(json.dumps({ - "currentWatts" : round(w.lastWatts, 2) if isinstance(w.lastWatts, float) else w.lastWatts, - "lastPulseAgo" : "%.1f sec ago" % (time.time() - w.lastBlinkTime) if w.lastBlinkTime is not None else "unknown", - "kwhPerBlink" : w.kwhPerBlink})) - -class HousePowerRaw(PrettyErrorHandler, cyclone.web.RequestHandler): - """ - raw data from the analog sensor, for plotting or picking a noise threshold - """ - def get(self): - self.set_header("Content-Type", "application/javascript") - pts = [] - for i in range(60): - level = self.settings.arduino.lastLevel() - pts.append((round(time.time(), 3), level)) - - self.write(json.dumps({"irLevels" : pts})) - -class HousePowerThreshold(PrettyErrorHandler, cyclone.web.RequestHandler): - """ - the level that's between between an IR pulse and the noise - """ - def get(self): - self.set_header("Content-Type", "application/javascript") - self.settings.poller.assertIsCurrent() - self.write(json.dumps({"threshold" : thr})) - - def put(self): - pass - -class GarageDoorOpen(PrettyErrorHandler, cyclone.web.RequestHandler): - def post(self): - self.set_header("Content-Type", "text/plain") - self.settings.arduino.setGarage(True) - self.write("pin high, waiting..\n") - self.flush() - d = defer.Deferred() - def finish(): - self.settings.arduino.setGarage(False) - self.write("pin low. Done") - d.callback(None) - reactor.callLater(1.5, finish) # this time depends on the LP circuit - return d - -class VideoSelect(PrettyErrorHandler, cyclone.web.RequestHandler): - def post(self): - self.set_header("Content-Type", "application/javascript") - v = self.settings.arduino.setVideoSelect(int(self.request.body)) - self.write(json.dumps({"videoSelect" : v})) - -class Brite(PrettyErrorHandler, cyclone.web.RequestHandler): - def get(self, chan): - self.set_header("Content-Type", "text/plain") - self.write(hexFromRgb(self.settings.colors[int(chan)])) - - def put(self, chan): - s = self.settings - s.colors[int(chan)] = rgbFromHex(self.request.body) - #s.arduino.shiftbrite(s.colors) - s.arduino.virtualwire([(r//4, g//4, b//4) for r,g,b in s.colors]) - post = put - -class Application(cyclone.web.Application): - def __init__(self, ard, poller): - handlers = [ - (r"/", Index), - (r"/graph", GraphPage), - (r"/frontDoorMotion", FrontDoorMotion), - (r'/housePower', HousePower), - (r'/housePower/raw', HousePowerRaw), - (r'/housePower/threshold', HousePowerThreshold), - (r'/garageDoorOpen', GarageDoorOpen), - (r'/videoSelect', VideoSelect), - (r"/brite/(\d+)", Brite), - ] - colors = [(0,0,0)] * 4 # stored 10-bit for legacy (or future!) reasons - settings = {"arduino" : ard, "poller" : poller, "colors" : colors} - cyclone.web.Application.__init__(self, handlers, **settings) - -class Poller(object): - """ - times the blinks to estimate power usage. Captures the other - returned sensor values too in self.lastValues - """ - def __init__(self, ard, period): - self.ard = ard - self.period = period - self.carbon = CarbonClient(serverHost='bang') - self.lastBlinkTime = None - self.lastValues = None - self.lastPollTime = 0 - self.lastWatts = "(just restarted; wait no data yet)" - self.kwhPerBlink = 1.0 # unsure - self.lastMotion = False - - def assertIsCurrent(self): - """raise an error if the poll data is not fresh""" - dt = time.time() - self.lastPollTime - if dt > period * 2: - raise ValueError("last poll time was too old: %.1f sec ago" % dt) - - def poll(self): - now = time.time() - try: - try: - newData = ard.poll() - except ValueError, e: - print e - os.abort() - else: - self.lastPollTime = now - self.lastValues = newData # for other data besides the blinks - self.processBlinks(now, newData['newBlinks']) - self.processMotion(newData['motion']) - - except (IOError, OSError): - os.abort() - except Exception, e: - print "poll error", e - traceback.print_exc() - - def processBlinks(self, now, b): - if b > 0: - if b > 1: - # todo: if it's like 1,1,2,2,2,2,1,1 then we - # need to subdivide those inner sample periods - # since there might really be two blinks. But - # if it's like 0,0,0,2,0,0, that should be - # treated like b=1 since it's probably noise - pass - - if self.lastBlinkTime is not None: - dt = now - self.lastBlinkTime - dth = dt / 3600. - watts = self.kwhPerBlink / dth - - if watts > 20000: - # this pulse (or the previous one) is - # likely noise. Too late for the previous - # one, but we're going to skip this one - return - else: - self.lastWatts = watts - - # todo: remove this; a separate logger shall do it - self.carbon.send('system.house.powerMeter_w', watts, now) - - self.lastBlinkTime = now - - def processMotion(self, state): - if state == self.lastMotion: - return - self.lastMotion = state - msg = json.dumps(dict(board='garage', - name="frontDoorMotion", state=state)) - getPage('http://bang.bigasterisk.com:9069/inputChange', - method="POST", - postdata=msg, - headers={'Content-Type' : 'application/json'} - ).addErrback(self.reportError, msg) - - def reportError(self, msg, *args): - print "post error", msg, args - -if __name__ == '__main__': - - config = { # to be read from a file - 'arduinoPort': '/dev/serial/by-id/usb-Arduino__www.arduino.cc__Arduino_Uno_6493534323335161A2F1-if00', - 'servePort' : 9050, - 'pollFrequency' : 5, - 'boardName' : 'garage', # gets sent with updates - } - - #from twisted.python import log as twlog - #twlog.startLogging(sys.stdout) - - log.setLevel(logging.DEBUG) - - ard = ArduinoGarage(port=config['arduinoPort']) - - period = 1/config['pollFrequency'] - p = Poller(ard, period) - task.LoopingCall(p.poll).start(period) - reactor.listenTCP(config['servePort'], Application(ard, p)) - reactor.run()
--- a/service/garageArduino/index.html Sun Apr 21 01:33:13 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" -"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>garageArduino</title> - <link rel="alternate" type="application/x-trig" title="RDF graph" href="graph" /> - <style type="text/css" media="all"> - /* <![CDATA[ */ -.val { -font-weight: bold; -} -.colorpicker { - display: inline-block; -} -/* ]]> */ - </style> - </head> - <body> - - <h1>garageArduino service</h1> - - <p>Talking to an arduino uno on host <tt>slash</tt></p> - - <p>Pulse pin 3 to trigger garage door opener <form method="post" action="garageDoorOpen"><input type="submit" value="Garage door opener"/></form></p> - - <p><a href="http://octopart.com/555-28027-parallax-708653">PIR sensor</a> (in <a href="http://octopart.com/1551ggy-hammond-15686">a box</a>) measuring front door motion: <span class="val" id="frontDoorMotion"/></p> - - <p><a href="http://www.jameco.com/webapp/wcs/stores/servlet/ProductDisplay?langId=-1&productId=2006414&catalogId=10001&freeText=2006414&app.products.maxperpage=15&storeId=10001&search_type=jamecoall&ddkey=http:StoreCatalogDrillDownView">phototransistor</a> watching IR pulses on the power meter: last pulse was <span class="val" id="lastPulseAgo"/>; current power usage is <span class="val"><span id="currentWatts"/> watts</span> (assuming <span class="val" id="kwhPerBlink"/> kwh/blink)</p> - - <p>Recent raw IR sensor data: <div><img src="" id="raw"/></div></p> - - <p><button type="submit" id="refresh">refresh</button></p> - - <p>Bathroom LEDs</p> - <div><input id="lockColor" type="checkbox"/> Send first color to all LEDs</div> - <div class="colorpicker" id="p0"></div> - <div class="colorpicker" id="p1"></div> - <div class="colorpicker" id="p2"></div> - <div class="colorpicker" id="p3"></div> - - <script type="text/javascript" src="//bigasterisk.com/lib/jquery-2.0.3.min.js"/> - <script type="text/javascript" src="//bigasterisk.com/lib/farbtastic-1.2/farbtastic.js"></script> - <link rel="stylesheet" href="//bigasterisk.com/lib/farbtastic-1.2/farbtastic.css" type="text/css" /> - - <script type="text/javascript"> - // <![CDATA[ - $(function () { - function setTexts(data) { - $.each(data, function (k,v) { $("#"+k).text(v); }) - } - function refresh() { - $.getJSON("frontDoorMotion", setTexts); - $.getJSON("housePower", setTexts); - - $.getJSON("housePower/raw", function (data) { - var xp=[], yp=[]; - var start = data.irLevels[0][0]; - var maxTime = 0; - $.each(data.irLevels, function (i, xy) { - maxTime = xy[0] - start; - xp.push(maxTime.toPrecision(3)); - yp.push(xy[1]); - }); - // edit with http://imagecharteditor.appspot.com/ - $("#raw").attr("src", - "http://chart.apis.google.com/chart"+ - "?chxr=0,0,"+maxTime+"|1,0,1024"+ - "&chds=0,"+maxTime+",0,1024"+ - "&chxl=2:|seconds"+ - "&chxs=0,676767,11.5,0,lt,676767|1,676767,11.5,-0.5,l,676767"+ - "&chxt=x,y,x"+ - "&chs=600x200"+ - "&cht=lxy"+ - "&chco=76A4FB"+ - "&chd=t:"+xp.join(",")+"|"+yp.join(",")+ - "&chg=10,20"+ - "&chls=2"+ - "&chma=40,20,20,30"+ - "&chm=h,FF0000,0,0.7:50:2,1"); - }); - } - refresh(); - $("#refresh").click(refresh); - - var inProgress = false; - var pending = {}; // url : data - function sendColor(url, newColor) { - inProgress = 1; - $.ajax({ - type: "put", url: url, - contentType: "text/plain", data: newColor, - success: function () { - inProgress = false; - $.each(pending, function (u, n) { - delete pending[u]; - sendColor(u, n); - }); - } - }); - } - function copyColor(newColor) { - $.farbtastic("#p1").setColor(newColor); - $.farbtastic("#p2").setColor(newColor); - $.farbtastic("#p3").setColor(newColor); - } - $("#lockColor").click(function () { copyColor($.farbtastic("#p0").color); }); - $.each([ - ["#p0", "brite/0"], - ["#p1", "brite/1"], - ["#p2", "brite/2"], - ["#p3", "brite/3"], - ], function (i, row) { - var picker = $.farbtastic(row[0], function (newColor) { - if (row[1] == "brite/0" && $("#lockColor")[0].checked) { - copyColor(newColor); - } - if (inProgress) { - pending[row[1]] = newColor; - return; - } - sendColor(row[1], newColor); - }); - $.get(row[1], picker.setColor); - }); - - }); - // ]]> - </script> - </body> -</html>
--- a/service/garageArduino/powermeter/sensor.sch Sun Apr 21 01:33:13 2019 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -v 20100214 2 -C 40000 40000 0 0 0 title-B.sym -C 44400 47000 1 0 0 photo-transistor-1.sym -{ -T 44200 47500 5 6 0 1 0 0 1 -device=PS2501-1 -T 44660 47100 5 10 1 1 0 0 1 -refdes=Q? -T 44360 47000 5 10 0 1 0 0 1 -device=photo-transistor -} -C 48000 48000 1 180 0 connector5-1.sym -{ -T 46200 46500 5 10 0 0 180 0 1 -device=CONNECTOR_5 -T 47900 46300 5 10 1 1 180 0 1 -refdes=ARDUINO -} -N 44600 47000 44900 46900 4 -N 44900 46900 45900 46900 4 -N 44600 47400 46000 47400 4 -N 46000 47400 46300 47200 4 -C 46200 45600 1 0 0 ground.sym -N 46400 45900 45900 46900 4 -C 50100 47300 1 180 0 terminal-1.sym -{ -T 49790 46550 5 10 0 0 180 0 1 -device=terminal -T 49790 46700 5 10 0 0 180 0 1 -footprint=CONNECTOR 1 1 -T 49850 47250 5 10 1 1 180 6 1 -refdes=~INPUT -} -N 49200 47200 47500 47200 4 -C 48800 47200 1 90 0 resistor-1.sym -{ -T 48400 47500 5 10 0 0 90 0 1 -device=RESISTOR -T 48500 47400 5 10 1 1 90 0 1 -refdes=20K -} -C 48500 48100 1 0 0 vcc-1.sym -C 44400 49500 1 270 0 led-1.sym -{ -T 45000 48700 5 10 0 0 270 0 1 -device=LED -T 44800 48700 5 10 1 1 270 0 1 -refdes=LED? -T 45200 48700 5 10 0 0 270 0 1 -symversion=0.1 -} -N 44100 49500 48300 49500 4 -N 48300 48100 48300 49500 4 -N 48300 48100 48700 48100 4 -C 44500 48300 1 270 0 resistor-1.sym -{ -T 44900 48000 5 10 0 0 270 0 1 -device=RESISTOR -T 44800 48100 5 10 1 1 270 0 1 -refdes=150 -} -N 44600 48600 44600 48300 4 -C 48700 45900 1 180 0 connector4-1.sym -{ -T 46900 45000 5 10 0 0 180 0 1 -device=CONNECTOR_4 -T 48700 44500 5 10 1 1 180 0 1 -refdes=RJ11 -} -N 47000 44800 44100 44800 4 -N 44100 44800 44100 49500 4 -N 47000 45100 45200 45100 4 -N 45200 45100 45200 47400 4 -N 46400 45900 47000 45900 4 -N 47000 45900 47000 45700 4