Coder Social home page Coder Social logo

sailthru / relay Goto Github PK

View Code? Open in Web Editor NEW
41.0 27.0 5.0 127 KB

A self-tuning thermostat for distributed systems that minimizes the error between some metric and a target

License: Apache License 2.0

Python 87.73% Shell 1.42% JavaScript 4.23% HTML 6.62%

relay's Introduction

Relay: A thermostat for distributed systems

Quickstart with a demo!

./bin/demo.sh  # You must have Docker installed

Navigate your browser to:

http://<dockerip>:8080  # <dockerip> is probably $DOCKER_HOST or "localhost"

What problem does it solve?

Imagine I wish to manually manage the temperature of a room. I have a thermostat at one corner and a heater and/or cooler at the other, and let's say I wish to maintain a target temperature of 68 degrees. I decide on a simple rule: add heat to the room until the thermometer reaches 68 degress. There is a problem, though. Heat takes some time to appear on the thermometer. If I wait until the thermometer reads my target temperature, I drastically overheat the room. So I decide on another rule: slowly add heat to the room until it reaches the target temperature. After trying this out, I realize that the temperature in the room doesn't get above 60 degrees because it is apparently so cold outside that I'm not adding enough heat to counter-balance those effects.

It looks like I need a more sophisticated temperature regulating algorithm. This type of problem is often quite complex, and there is a field called Control Theory dedicated to problems like the ones that a thermostat solves.

How does this apply to distributed systems?

Distributed systems need thermostats everywhere! Perhaps you have a need to add workers in proportion to a queue size. Or in another scenario, you may need to add more aws nodes when there's a lot of work to do. Perhaps your grid scheduler needs to maintain a constant number of jobs running at a time, once per node, but the number of nodes is dynamic. You could use Relay to tune hyper-parameters for online machine learning algorithms. Can you think of any applications? If you can't, look at a couple timeseries and you'll come up with good ideas, and there is a good chance that Relay makes solving those quite a bit easier.

In general, Relay is a good candidate for any scenario where you find yourself looking at some metric and then responding to that metric by running some code or tweaking your system.

Background: A lesson on PID controllers

A PID controller is a mechanism that implements a control loop. A control loop leverages feedback from its previous decisions to make new decisions about what to do next. According to Wikipedia, "In the absence of knowledge of the underlying process, a PID controller has historically been considered to be the best controller."

PID controllers look at a metric, like room temperature over time, and represent it as three components. "P," the "proportional" term, defines the amount of error between the current metric value and the target value. (How far off is the temperature from the target temperature?). "I" and "D" look at the integral and derivative of the metric. The amount of "heating" or "cooling" a PID controller decides to add depends on a weighted sum of those three terms.

MV = K_p * P + K_i * I + K_d * D

    where
    P = error between current value and target value
    I = integral of this error over time
    D = derivative of this error over time
    K_* - these are weights for the above

    MV = the amount of heat or cooling to add to the system

The challenge, in general, is to find the ideal weighting for the K_* terms.

Background: How does Relay solve this?

Relay is technically a modified PI controller. Specifically, K_p = 1, K_d * D = 0, and K_i is chosen according to a tuning algorithm. Given P, I, and an error history, the amount of heat or cooling to add (MV) is:

MV = P + K_i * I

    where
    P = PV - SP .... (metric value - target) value at timestep i
    I = sum(P_hist) / len(P_hist) .... average value of P over time.
    K_i is defined below as a weighted sum of component frequencies.

The challenge in this problem is to answer the question: "At the current moment in time, how important is the history of errors?" Here's how Relay does this:

If we can assume the signal is made up of various periodic (repeating) functions, we can evaluate, at any point in time, how far away from “zero error” each periodic function is. By joining all these errors as a weighted sum, we can estimate how important the error is by considering the relative presence of the signal's repeating components.

A Fast Fourier Transform (we use FFT) breaks down a signal (ie Relay's error history) into a number of repeating sine waves of different frequencies. For any given component frequency, f_j we can look at the current phase, ø_i, of the wave we happen to be in. Since we sample the signal (and therefore each component frequency) at a known rate, we can also calculate the number of samples, n, in this particular frequency that we consider. In one period, large frequency components will have less samples than small frequency components. Given a component frequency, f_j, the current phase, ø, and the number of samples in one wavelength, n, we can then look back we can find how much of n - 1 most recent samples the the current phase is worth, or h_j = abs(sin(ø_i)) / Σ_k [ abs(sin(ø_(i-k))) ] where k = [0:n).

If we calculate h_j for each frequency, j, and than take a weighted sum of frequencies, we define a tuning parameter, K_i, that responds quite well to periodicity of the signal!

At the current timestep: For each f_j: n=num samples in f_j h_j = abs(sin(ø_i)) / Σ_k [ abs(sin(ø_(i-k))) ] where k = [0:n)

K_i = Σ_j [ f_j * h_j ]


And finally:
MV = P + K_i * I

Quick Start!

Install relay

pip install relay.runner

  OR for this demo:

pip install "relay.runner[webui]"  # webui needs ZeroMQ installed

Look at the usage

relay -h

Try a demo. This demo runs monitors the number of a certain kind of bash echo command running every .1 seconds, and if there aren't enough of them running, will add more.

relay --metric bash_echo_metric --warmer bash_echo_warmer --delay .1 --sendstats webui --target 20

# navigate to localhost:8080 in a web browser

# demos 2 and 3: changing target values over time
relay --metric bash_echo_metric --warmer bash_echo_warmer --delay .1 --sendstats webui --target oscillating_setpoint
relay --metric bash_echo_metric --warmer bash_echo_warmer --delay .1 --sendstats webui --target squarewave_setpoint

# demo 4: running a heater and cooler at the same time
relay --metric bash_echo_metric --warmer bash_echo_warmer --delay .1 --sendstats webui --target squarewave_setpoint --cooler bash_echo_cooler

Detailed Usage:

Relay has 4 main components:

metric - a timeseries of numbers that you wish to monitor (ie temperature)
target - a numerical value (or timeseries) that you'd like the
    metric to be at (ie same units as the metric)

warmer - a function that Relay assumes will increase the metric
cooler - a function that Relay assumes will decrease the metric

In certain cases it can be more efficient to run a heater and air conditioner at the same time, but generally it's not. It's usually safe to apply this reasoning to Relay. You generaly should define only a warmer or a cooler, but sometimes it is better to define both.

Relay makes some assumptions:

  • The metric you monitoring is eventually consistent. This means that if it takes a little while for effects to become apparent, Relay will figure this out as soon as it acquires enough error history to do so.

  • The signal you're monitoring is continuous, integrable, and otherwise valid input to a Fourier Transforms.

  • Warmer functions increase metric values and Cooler functions decrease metric values.

  • If Relay accrues a large history of error, it will remember that error for n samples, where n is the size of Relay's lookback window. If a warmer or cooler function suddenly stops working or something changes how it affects themetric, Relay's decisions may become less predictable until it stabilizes.

  • You can run multiple redundant Relays! If you add multiple Relay processes, they will each account for a part of the signal. If you stop multiple Relays, the remaining ones will figure this out and re-adjust themselves over the next few samples.

relay's People

Contributors

adgaudio avatar

Stargazers

 avatar Bennett Kanuka avatar Ilias Ktn avatar malraharsh avatar Muhammad Alan Nur avatar Ted Drain avatar Yevgeny avatar Prasanna Swaminathan avatar Michal Valoušek avatar Dalton Barreto avatar ajish avatar Luke Alex Reeve avatar Torsten Egenolf avatar Jason Hines avatar  avatar Matthias Bach avatar  avatar Fairiz 'Fi' Azizi avatar Zoltan Nagy avatar Krisztián Szűcs avatar BenWhitehead avatar Michael Hausenblas avatar Vivek Juneja avatar Olaf avatar Craig Wickesser avatar Xavier Barbosa avatar Keith Chambers avatar Eli Lindsey avatar Francois Dang Ngoc avatar Mike Hamrah avatar Stephan Erb avatar Mathieu Velten avatar Zagig Yragerne avatar Benjamin Staffin avatar Subramanyam Chitti avatar Petter Wigle avatar James Scott avatar Kamil Chmielewski avatar David Höppner avatar Shingo Omura avatar  avatar

Watchers

Neil Capel avatar Ian White avatar Nick Berard avatar Chris Chapman avatar Stephan Erb avatar Daniel Hjelseth Høyer avatar James Cloos avatar  avatar Katrin avatar José Coelho avatar  avatar Jeremy Stanley avatar  avatar Johnson Wang avatar Andras Kerekes avatar Taras avatar Kyle Hamlin avatar  avatar  avatar Isaac (.ike) Levy avatar Divyanshu Vats avatar Avi Chad-Friedman avatar  avatar  avatar  avatar Tej avatar  avatar

relay's Issues

some numpy something?

seen this with python2 or 3.

 relay --metric bash_echo_metric --warmer bash_echo_warmer --delay 2 --targe
t 200
INFO     Starting relay!    lookback=1000 warmer=<function bash_echo_warmer at 0x7f44c85ae730> target=<function targettype.<locals>.infinite_iterator at 0x7f44c85a5ea0> ramp=1 delay=2.0 cooler=None stop_condition=None metric=<function bash_echo_metric at 0x7f44c85ae6a8> sendstats=None
DEBUG    got metric value    PV=1 SP=200
DEBUG    adding heat    MV=199 err=199
DEBUG    got metric value    PV=200 SP=200
WARNING  no variation in the signal.  fft cannot continue
INFO     data    data=[0, 1, 0.0]
DEBUG    stabilized PV at setpoint    PV=200 SP=200 MV=0
DEBUG    got metric value    PV=200 SP=200
WARNING  no variation in the signal.  fft cannot continue
INFO     data    data=[0, 1, 0.0]
DEBUG    stabilized PV at setpoint    PV=200 SP=200 MV=0
DEBUG    got metric value    PV=181 SP=200
INFO     data    data=[19, 0.3333333333333333, 4.75]
DEBUG    adding heat    MV=17 err=19
DEBUG    got metric value    PV=94 SP=200
INFO     data    data=[106, 0.2360679774997897, 25.0]
DEBUG    adding heat    MV=100 err=106
DEBUG    got metric value    PV=118 SP=200
Traceback (most recent call last):
  File "/home/automaticgiant/.local/share/virtualenvs/work-tJEz75H6/bin/relay", line 11, in <module>
    sys.exit(go())
  File "/home/automaticgiant/.local/share/virtualenvs/work-tJEz75H6/lib/python3.6/site-packages/relay/__main__.py", line 9, in go
    main(NS)
  File "/home/automaticgiant/.local/share/virtualenvs/work-tJEz75H6/lib/python3.6/site-packages/relay/runner.py", line 161, in main
    weight = calc_weight(errdata)
  File "/home/automaticgiant/.local/share/virtualenvs/work-tJEz75H6/lib/python3.6/site-packages/relay/runner.py", line 57, in calc_weight
    p_k[not_idxs] = 0
IndexError: boolean index did not match indexed array along dimension 0; dimension is 2 but corresponding boolean dimension is 1

.relay.conf

Hi there,

Nice looking project, maybe this is what i have been waiting a long time ago...
Please tell me if i'm wrong, i want to create a setup using 1 on/off relay for the heater (Natural Gas - Methane - 24kw ) and DHT22 or DS18B20 as sensor.
And if it's working i want to integrate in pimatic home automation framework, already running.

I have installed relay, but i run:

relay --metric bash_echo_metric --warmer bash_echo_warmer --delay .1 --sendstats webui --target 20

i get :

Relay config file does not exist at /home/pi/.relay.conf!

I created the file, but he want's to read something from this file...
Please help me with a sample file.

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.