Exemplo n.º 1
0
 def __init__(self, *args, **kwargs):
     """
     @TODO: perform LAN discovery, interrogate the resources, generate controls for all of them
     """
     self.led_strip = LEDStrip(RESOLVED_USER_SETTINGS)
     RaspberryPiWebResource.__init__(
         self, *args,
         **kwargs)  # Super, deals with generating the static directory etc
Exemplo n.º 2
0
 def __init__(self, *args, **kwargs):
     """
     @TODO: perform LAN discovery, interrogate the resources, generate controls for all of them
     """
     self.led_strip = LEDStrip(RESOLVED_USER_SETTINGS)
     Resource.__init__(self, *args, **kwargs) #Super
     # Add in the static folder.
     static_folder = os.path.join(RASPILED_DIR,"static")
     self.putChild("static", File(static_folder))  # Any requests to /static serve from the filesystem.
Exemplo n.º 3
0
 def render_css(self):
     """
     Generates a CSS gradient from the self.display_gradient list
     """
     if self.display_gradient:
         return "background: linear-gradient(-40deg, {colour_values}); color: white; text-shadow: 2px 2px 2px #000000".format(colour_values=self.colour)
     if self.display_colour:
         contrast_colour = LEDStrip.contrast_from_bg(col=self.colour, dark_default="202020")
         return "background: {display_colour}; color: {contrast_colour}".format(
             display_colour=self.colours_for_css_background(),
             contrast_colour=contrast_colour
         )
     return ""
Exemplo n.º 4
0
        print(content['colour'])
        strip.setcolourhex(content['colour'][1:])
        return 'Completed Successfully'
    elif 'period' in content.keys():
        period = float(content['period'])
        print("Period set")
        return 'Set period time to {}s'.format(period)
    else:
        cycler = False
        print(content)

        cycler = True
        print(gradient_cycler(content['gradient']))

        return 'Stopped gradient'


@app.route('/')
def main():
    return render_template('index.html')


if __name__ == "__main__":
    step_size = int(sys.argv[2])
    period = 0.05
    CLK = 18
    DAT = 17
    strip = LEDStrip(CLK, DAT)

    app.run(host=sys.argv[1], port=80)
Exemplo n.º 5
0
#!/usr/bin/python
from ledstrip import LEDStrip

strip = LEDStrip()
strip.off()
strip.update()
Exemplo n.º 6
0
#!/usr/bin/python

from time import sleep
from ledstrip import LEDStrip

strip = LEDStrip()

min = 36
max = 140
b = 40
speed = 1
dir = 1
while True:
    if   b <= min: dir =  1
    elif b >= max: dir = -1
    b += dir * speed

    if   b > 255: b = 255
    elif b < 0:   b = 0

    for i in xrange(105):
        strip.set(i, b, 0, 0)
    strip.update()
    sleep(0.08)
Exemplo n.º 7
0
class RaspiledControlResource(RaspberryPiWebResource):
    """
    Our web page for controlling the LED strips
    """
    led_strip = None  # Populated at init

    # State what params should automatically trigger actions. If none supplied will show a default page. Specified in order of hierarchy
    PARAM_TO_ACTION_MAPPING = (
        # Stat actions
        ("off", "off"),
        ("stop", "stop"),
        ("set", "set"),
        ("fade", "fade"),
        ("color", "fade"),
        ("colour", "fade"),
        # Sequences
        ("sunrise", "sunrise"),
        ("morning", "sunrise"),
        ("dawn", "sunrise"),
        ("sunset", "sunset"),
        ("evening", "sunset"),
        ("dusk", "sunset"),
        ("night", "sunset"),
        ("jump", "jump"),
        ("rotate", "rotate"),
        ("rot", "rotate"),
        ("huerot", "rotate"),
        ("colors", "rotate"),
        ("colours", "rotate"),
        # Docs:
        ("capabilities", "capabilities"),
        ("capability", "capabilities"),
        ("status", "status"),
    )

    # State what presets to render:
    OFF_PRESET = Preset(label="""<img src="/static/figs/power-button-off.svg" class="icon_power_off"> Off""", display_colour="black", off="")
    PRESETS = {
        "Whites": (  # I've had to change the displayed colours from the strip colours for a closer apparent match
            Preset(label="Candle", display_colour="1500K", fade="1000K"),
            Preset(label="Tungsten", display_colour="3200K", fade="2000K"),
            Preset(label="Bulb match", display_colour="3900K", fade="ff821c"),
            Preset(label="Warm white", display_colour="4800K", fade="2600k"),  # Bulb match
            Preset(label="Strip white", display_colour="6000K", fade="3200K"),
            Preset(label="Daylight", display_colour="6900K", fade="5800K"),
            Preset(label="Cool white", display_colour="9500K", fade="10500K"),
        ),
        "Sunrise / Sunset": (
            Preset(label="&uarr; 2hr", display_gradient=("2000K", "5000K"), sunrise=60 * 60 * 2, is_sequence=True, is_sun=True),
            Preset(label="&uarr; 1hr", display_gradient=("2000K", "5000K"), sunrise=60 * 60 * 1, is_sequence=True, is_sun=True),
            Preset(label="&uarr; 30m", display_gradient=("2000K", "5000K"), sunrise=60 * 30, is_sequence=True, is_sun=True),
            Preset(label="&uarr; 1m", display_gradient=("2000K", "5000K"), sunrise=60 * 1, is_sequence=True, is_sun=True),
            PresetSpace(),
            Preset(label="&darr; 1m", display_gradient=("5000K", "2000K"), sunset=60 * 1, is_sequence=True, is_sun=True),
            Preset(label="&darr; 30m", display_gradient=("5000K", "2000K"), sunset=60 * 30, is_sequence=True, is_sun=True),
            Preset(label="&darr; 1hr", display_gradient=("5000K", "2000K"), sunset=60 * 60 * 1, is_sequence=True, is_sun=True),
            Preset(label="&darr; 2hr", display_gradient=("5000K", "2000K"), sunset=60 * 60 * 2, is_sequence=True, is_sun=True),
        ),
        "Colours": (
            Preset(label="Red", display_colour="#FF0000", fade="#FF0000"),
            Preset(label="Orange", display_colour="#FF8800", fade="#FF8800"),
            Preset(label="Yellow", display_colour="#FFFF00", fade="#FFFF00"),
            Preset(label="Lime", display_colour="#88FF00", fade="#88FF00"),
            Preset(label="Green", display_colour="#00BB00", fade="#00FF00"),
            Preset(label="Aqua", display_colour="#00FF88", fade="#00FF88"),
            Preset(label="Cyan", display_colour="#00FFFF", fade="#00FFFF"),
            Preset(label="Blue", display_colour="#0088FF", fade="#0088FF"),
            Preset(label="Indigo", display_colour="#0000FF", fade="#0000FF"),
            Preset(label="Purple", display_colour="#8800FF", fade="#7A00FF"),  # There's a difference!
            Preset(label="Magenta", display_colour="#FF00FF", fade="#FF00FF"),
            Preset(label="Crimson", display_colour="#FF0088", fade="#FF0088"),
            PresetRow(),
            Preset(label="Tasty Teal", display_colour="#009882", fade="#00FF3C"),
            Preset(label="Super Crimson", display_colour="#FF0077", fade="#FF0033"),
        ),
        "Sequences": (
            Preset(label="&#x1f525; Campfire", display_gradient=("600K", "400K", "1000K", "400K"), rotate="700K,500K,1100K,600K,800K,1000K,500K,1200K",
                   milliseconds="1800", is_sequence=True),
            Preset(label="&#x1f41f; Fish tank", display_gradient=("#00FF88", "#0088FF", "#007ACC", "#00FFFF"), rotate="00FF88,0088FF,007ACC,00FFFF",
                   milliseconds="2500", is_sequence=True),
            Preset(label="&#x1f389; Party", display_gradient=("cyan", "yellow", "magenta"), rotate="cyan,yellow,magenta", milliseconds="1250",
                   is_sequence=True),
            Preset(label="&#x1f33b; Flamboyant", display_gradient=("yellow", "magenta"), jump="yellow,magenta", milliseconds="150", is_sequence=True),
            Preset(label="&#x1F384; Christmas", display_gradient=("green", "red"), rotate="green,red", milliseconds="300", is_sequence=True),
            Preset(label="&#x1f6a8; NeeNaw", display_gradient=("cyan", "blue"), jump="cyan,blue", milliseconds="100", is_sequence=True),
            Preset(label="&#x1f6a8; NeeNaw USA", display_gradient=("red", "blue"), jump="red,blue", milliseconds="100", is_sequence=True),
            Preset(label="&#x1f308; Full circle", display_gradient=(
            "#FF0000", "#FF8800", "#FFFF00", "#88FF00", "#00FF00", "#00FF88", "#00FFFF", "#0088FF", "#0000FF", "#8800FF", "#FF00FF", "#FF0088"),
                   milliseconds=500, rotate="#FF0000,FF8800,FFFF00,88FF00,00FF00,00FF88,00FFFF,0088FF,0000FF,8800FF,FF00FF,FF0088", is_sequence=True),
        )
    }
    PRESETS_COPY = copy.deepcopy(PRESETS)  # Modifiable dictionary. Used in alarms and music.

    def __init__(self, *args, **kwargs):
        """
        @TODO: perform LAN discovery, interrogate the resources, generate controls for all of them
        """
        self.led_strip = LEDStrip(RESOLVED_USER_SETTINGS)
        RaspberryPiWebResource.__init__(self, *args, **kwargs)  # Super, deals with generating the static directory etc

    def render_controls(self, request):
        """
        Show the main controls screen
        """
        context = {
            "off_preset_html": self.OFF_PRESET.render(),
            "light_html": self.render_light_presets(request),
            "alarm_html": self.render_alarm_presets(request),
            "music_html": self.render_udevelop_presets(request),
            "controls_html": self.render_udevelop_presets(request),
        }
        return RaspberryPiWebResource.render_controls(self, request, context)

    #### Additional pages available via the menu ####

    def render_light_presets(self, request):
        """
        Renders the light presets as options

        @param request: The http request object

        """
        out_html_list = []
        for group_name, presets in self.PRESETS.items():
            preset_list = []
            # Inner for
            for preset in presets:
                preset_html = preset.render()
                preset_list.append(preset_html)
            group_html = """
                <div class="preset_group">
                    <h2>{group_name}</h2>
                    <div class="presets_row">
                        {preset_html}
                    </div>
                </div>
            """.format(
                group_name=group_name,
                preset_html="\n".join(preset_list)
            )
            out_html_list.append(group_html)
        out_html = "\n".join(out_html_list)
        return out_html

    def render_alarm_presets(self, request):
        """
        Renders the alarm presets as options. Same sunrise or sunset routine except for 100k.
        """
        out_html_list = []
        preset_list = []
        # Inner for
        group_name = "Sunrise / Sunset"
        presets = self.PRESETS_COPY[group_name]
        for preset in presets:
            try:
                if preset.display_gradient[0] == '5000K':
                    preset.display_gradient = ('5000K', '50K')
                else:
                    preset.display_gradient = ('50K', '5000K')
            except:
                pass
            preset_html = preset.render()
            preset_list.append(preset_html)
        group_html = """
                <p id="clock" class="current-colour"></p>
                <h2>{group_name}</h2>
                <div class="sun-alarm" data-latitude="{users_latitude}" data-longitude="{users_longitude}"></div>
                <div class="preset_group">
                    <div class="presets_row">
                        {preset_html}
                    </div>
                </div>
            """.format(
            group_name=group_name,
            preset_html="\n".join(preset_list),
            users_latitude=get_setting("latitude", 52.2053),
            users_longitude=get_setting("longitude", 0.1218)
        )
        out_html_list.append(group_html)
        out_html = "\n".join(out_html_list)
        return out_html

    def render_udevelop_presets(self, request):
        """
        Renders the Under Development text.
        """
        out_html = """
           <div class="underdevelop">
           <h1> Under Development, please refer to the Github repository.</h1>
           </div>
        """
        return out_html

    # Actions: These are the actions our web server can initiate. Triggered by hitting the url with ?action_name=value ####

    def before_action(self, *args, **kwargs):
        """
        Called just before an action takes place. We stop whatever current sequence is running
        """
        self.led_strip.stop_current_sequence()  # Stop current sequence

    def action__set(self, request):
        """
        Run when user wants to set a colour to a specified value
        """
        set_colour = request.get_param("set", force=unicode)
        D("Set to: %s" % set_colour)
        return self.led_strip.set(set_colour)

    action__set.capability = {
        "param": "set",
        "description": "Sets the RGB strip to a single colour.",
        "value": "<unicode> A named colour (e.g. 'pink') or colour hex value (e.g. '#19BECA').",
        "validity": "<unicode> A known named colour, or valid colour hex in the range #000000-#FFFFFF.",
        "widget": "colourpicker",
        "returns": "<unicode> The hex value of the colour the RGB strip has been set to."
    }

    def action__fade(self, request):
        """
        Run when user wants to set a colour to a specified value
        """
        fade_colour = request.get_param("fade", force=unicode)
        logging.info("Fade to: %s" % fade_colour)
        return self.led_strip.fade(fade_colour)

    action__fade.capability = {
        "param": "fade",
        "description": "Fades the RGB strip from its current colour to a specified colour.",
        "value": "<unicode> A named colour (e.g. 'pink') or colour hex value (e.g. '#19BECA').",
        "validity": "<unicode> A known named colour, or valid colour hex in the range #000000-#FFFFFF",
        "returns": "<unicode> The hex value of the colour the RGB strip has been set to."
    }

    def action__sunrise(self, request):
        """
        Performs a sunrise over the specified period of time
        """
        seconds = request.get_param(["seconds", "s", "sunrise"], default=10.0, force=float)
        milliseconds = request.get_param(["milliseconds", "ms"], default=0.0, force=float)
        temp_start = request.get_param(['temp_start', 'K'], default=None, force=unicode)
        temp_end = request.get_param('temp_end', default=None, force=unicode)
        logging.info("Sunrise: %s seconds" % (seconds + (milliseconds / 1000.0)))
        return self.led_strip.sunrise(seconds=seconds, milliseconds=milliseconds, temp_start=temp_start, temp_end=temp_end)

    action__sunrise.capability = {
        "param": "sunrise",
        "description": "Gently fades-in the RGB strip from deep red to daylight.",
        "value": "The number of seconds you would like the sunrise to take.",
        "validity": "<float> > 0",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the sunrise should take. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "1000",
            },
            {
                "param": "temp_start",
                "value": "The colour temperature you wish to start from (e.g. 500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "6500K"
            },
            {
                "param": "temp_end",
                "value": "The colour temperature you wish to finish at (e.g. 4500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "500K"
            }
        ],
        "returns": "<unicode> The hex value of the colour the RGB strip has been set to."
    }

    def action__sunset(self, request):
        """
        Performs a sunset over the specified period of time
        """
        seconds = request.get_param(["seconds", "s", "sunset"], default=10.0, force=float)
        milliseconds = request.get_param(["milliseconds", "ms"], default=0.0, force=float)
        temp_start = request.get_param(['temp_start', 'K'], default=None, force=unicode)
        temp_end = request.get_param('temp_end', default=None, force=unicode)
        logging.info("Sunset: %s seconds" % (seconds + (milliseconds / 1000.0)))
        return self.led_strip.sunset(seconds=seconds, milliseconds=milliseconds, temp_start=temp_start, temp_end=temp_end)

    action__sunset.capability = {
        "param": "sunset",
        "description": "Gently fades-out the RGB strip from daylight to deep-red.",
        "value": "The number of seconds you would like the sunrise to take.",
        "validity": "<float> > 0",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the sunset should take. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "1000",
            },
            {
                "param": "temp_start",
                "value": "The colour temperature you wish to start from (e.g. 500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "500K"
            },
            {
                "param": "temp_end",
                "value": "The colour temperature you wish to finish at (e.g. 4500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "6500K"
            }
        ],
        "returns": ""
    }

    def action__jump(self, request):
        """
        Jump from one specified colour to the next
        """
        jump_colours = request.get_param_values("jump")
        seconds = request.get_param(["seconds", "s"], default=0.0, force=float)
        milliseconds = request.get_param(["milliseconds", "ms"], default=0.0, force=float)
        self.led_strip.stop_current_sequence()  # Terminate any crap that's going on
        total_seconds = (seconds + (milliseconds / 1000.0))
        logging.info("Jump: %s, %s seconds" % (jump_colours, total_seconds))
        return self.led_strip.jump(jump_colours, seconds=seconds, milliseconds=milliseconds)  # Has its own colour sanitisation routine

    action__jump.capability = {
        "param": "jump",
        "description": "Hops from one colour to the next over an even period of time.",
        "value": "A comma delimited list of colours you wish to jump between.",
        "validity": "<unicode> valid colour names or hex values separated by commas (e.g. red,blue,green,cyan,#FF00FF)",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the each colour should be displayed for. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "200",
            },
            {
                "param": "seconds",
                "value": "The number of seconds each colour should be displayed for. Will be added to milliseconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "0",
            },
        ],
        "returns": "<unicode> The first hex value of sequence."
    }

    def action__rotate(self, request):
        """
        Rotates (fades) from one specified colour to the next
        """
        rotate_colours = request.get_param_values("rotate")
        seconds = request.get_param(["seconds", "s"], default=0.0, force=float)
        milliseconds = request.get_param(["milliseconds", "ms"], default=0.0, force=float)
        self.led_strip.stop_current_sequence()  # Terminate any crap that's going on
        total_seconds = (seconds + (milliseconds / 1000.0))
        logging.info("Rotate: %s, %s seconds" % (rotate_colours, total_seconds))
        return self.led_strip.rotate(rotate_colours, seconds=seconds, milliseconds=milliseconds)  # Has its own colour sanitisation routine

    action__rotate.capability = {
        "param": "rotate",
        "description": "Fades from one colour to the next over an even period of time.",
        "value": "A comma delimited list of colours you wish to cross-fade between.",
        "validity": "<unicode> valid colour names or hex values separated by commas (e.g. red,blue,green,cyan,#FF00FF)",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the each colour fade should take. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "200",
            },
            {
                "param": "seconds",
                "value": "The number of seconds each colour fade should take. Will be added to milliseconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "0",
            },
        ],
        "returns": "<unicode> The first hex value of sequence."
    }

    def action__stop(self, request):
        """
        Stops the current sequence
        """
        return self.led_strip.stop()

    action__stop.capability = {
        "param": "stop",
        "description": "Halts the current sequence or fade.",
        "value": "",
        "returns": "<unicode> The hex value of colour the RGB strip got halted on."
    }

    def action__off(self, request):
        """
        Turns the strip off
        """
        logging.info("Off!")
        return self.led_strip.off()

    action__off.capability = {
        "param": "off",
        "description": "Stops any fades or sequences. Quickly Fades the RGB strip to black (no light)",
        "value": "",
        "returns": "<unicode> The hex value of colour the RGB strip ends up at (#000000)."
    }

    def information__status(self, request, *args, **kwargs):
        """
        Reports the status of the RGB LED strip
        """
        current_rgb = "({})".format(self.led_strip)
        current_hex = self.led_strip.hex
        contrast_colour = self.led_strip.contrast_from_bg(current_hex, dark_default="202020")
        return {
            "sequence": self.led_strip.sequence_colours,
            "current_hex": current_hex,
            "current": current_rgb,
            "current_colour": current_rgb,
            "current_rgb": current_rgb,
            "contrast": contrast_colour,
            "contrast_colour": contrast_colour
        }

    def teardown(self):
        """
        Called automatically when exiting the parent reactor
        """
        self.led_strip.teardown()
Exemplo n.º 8
0
#!/usr/bin/python
from ledstrip import LEDStrip

strip = LEDStrip()

for i in xrange(105):
    strip.set(i, 255, 255, 255)

strip.update()
#!/usr/bin/python

import time
from flask import Flask, request
from ledstrip import LEDStrip

CLK = 17
DAT = 18

strip = LEDStrip(CLK, DAT)
app = Flask(__name__)

strip.setcolourred()
time.sleep(0.2)
strip.setcolourgreen()
time.sleep(0.2)
strip.setcolourblue()
time.sleep(0.2)
strip.setcolouroff()


@app.route("/")
def hello():
    strip.setcolouroff()
    return "Hello World!"


@app.route("/red")
def redled():
    strip.setcolourred()
    return "red"
Exemplo n.º 10
0
import time

from neopixel import *
from flask import Flask
from ledstrip import LEDStrip

from get_color import get_color

import argparse
import signal
import sys

app = Flask(__name__)

led_strip = LEDStrip(18, 60)


@app.route('/colorwipe/<string:color>')
def colorWipe(color):
    led_strip.colorWipe(get_color(color))
    return 'color wipe activated'


@app.route('/colorswipe/<string:color1>&<string:color2>')
def colorsWipe(color1, color2):
    led_strip.twoColorWipe(get_color(color1), get_color(color2))
    return 'color wipe activated'


@app.route('/rainbow')
def rainbow():
Exemplo n.º 11
0
class RaspiledControlResource(Resource):
    """
    Our web page for controlling the LED strips
    """
    isLeaf = False  # Allows us to go into dirs
    led_strip = None  # Populated at init
    _path = None  # If a user wants to hit a dynamic subpage, the path appears here
    
    PARAM_TO_AUTHENTICATE = (
        ("user","newclient"),
        ("ukey","authenticate"),
        )
    #State what params should automatically trigger actions. If none supplied will show a default page. Specified in order of hierarchy
    # State what params should automatically trigger actions. If none supplied will show a default page. Specified in order of hierarchy
    PARAM_TO_ACTION_MAPPING = (
        # Stat actions
        ("off", "off"),
        ("stop", "stop"),
        ("set", "set"),
        ("fade", "fade"),
        ("color", "fade"),
        ("colour", "fade"),
        # Sequences
        ("sunrise", "sunrise"),
        ("morning", "alarm"),
        ("dawn", "alarm"),
        ("sunset", "sunset"),
        ("evening", "sunset"),
        ("dusk", "sunset"),
        ("night", "sunset"),
        ("jump", "jump"),
        ("rotate", "rotate"),
        ("rot", "rotate"),
        ("huerot", "rotate"),
        ("colors", "rotate"),
        ("colours", "rotate"),
        # Docs:
        ("capabilities", "capabilities"),
        ("capability", "capabilities"),
        ("status", "status"),
    )
    
    # State what presets to render:
    OFF_PRESET = Preset(label="""<img src="/static/figs/power-button-off.svg" class="icon_power_off"> Off""", display_colour="black", off="")
    PRESETS = {
        "Whites":( #I've had to change the displayed colours from the strip colours for a closer apparent match
                Preset(label="Candle", display_colour="1500K", fade="1000K"),
                Preset(label="Tungsten", display_colour="3200K", fade="2000K"),
                Preset(label="Bulb match", display_colour="3900K", fade="ff821c"), 
                Preset(label="Warm white", display_colour="4800K", fade="2600k"), #Bulb match
                Preset(label="Strip white", display_colour="6000K", fade="3200K"),
                Preset(label="Daylight", display_colour="6900K", fade="5800K"),
                Preset(label="Cool white", display_colour="9500K", fade="10500K"),
            ),
        "Sunrise / Sunset":(
                Preset(label="&uarr; 2hr", display_gradient=("2000K","5000K"), sunrise=60*60*2, is_sequence=True, is_sun=True),
                Preset(label="&uarr; 1hr", display_gradient=("2000K","5000K"), sunrise=60*60*1, is_sequence=True, is_sun=True),
                Preset(label="&uarr; 30m", display_gradient=("2000K","5000K"), sunrise=60*30, is_sequence=True, is_sun=True),
                Preset(label="&uarr; 1m", display_gradient=("2000K","5000K"), sunrise=60*1, is_sequence=True, is_sun=True),
                PresetSpace(),
                Preset(label="&darr; 1m", display_gradient=("5000K","2000K"), sunset=60*1, is_sequence=True, is_sun=True),
                Preset(label="&darr; 30m", display_gradient=("5000K","2000K"), sunset=60*30, is_sequence=True, is_sun=True),
                Preset(label="&darr; 1hr", display_gradient=("5000K","2000K"), sunset=60*60*1, is_sequence=True, is_sun=True),
                Preset(label="&darr; 2hr", display_gradient=("5000K","2000K"), sunset=60*60*2, is_sequence=True, is_sun=True),
            ),
        "Colours":(
                Preset(label="Red", display_colour="#FF0000", fade="#FF0000"),
                Preset(label="Orange", display_colour="#FF8800", fade="#FF8800"),
                Preset(label="Yellow", display_colour="#FFFF00", fade="#FFFF00"),
                Preset(label="Lime", display_colour="#88FF00", fade="#88FF00"),
                Preset(label="Green", display_colour="#00BB00", fade="#00FF00"),
                Preset(label="Aqua", display_colour="#00FF88", fade="#00FF88"),
                Preset(label="Cyan", display_colour="#00FFFF", fade="#00FFFF"),
                Preset(label="Blue", display_colour="#0088FF", fade="#0088FF"),
                Preset(label="Indigo", display_colour="#0000FF", fade="#0000FF"),
                Preset(label="Purple", display_colour="#8800FF", fade="#7A00FF"),  # There's a difference!
                Preset(label="Magenta", display_colour="#FF00FF", fade="#FF00FF"),
                Preset(label="Crimson", display_colour="#FF0088", fade="#FF0088"),
            ),
        "Sequences":(
                Preset(label="&#x1f525; Campfire", display_gradient=("600K","400K","1000K","400K"), rotate="1100K,800K,1100K,1300K,1300K,900K,1500K,800K,900K,800K,1300K,600K,600K,600K,900K,600K,900K,1100K,1400K,1400K,900K,800K,600K,700K,700K,900K,1000K,1000K,800K,900K,1000K,700K,900K,1000K,600K,700K,1000K,800K,800K,1400K,900K,1100K,1000K,1500K,1000K,1000K,900K,700K", milliseconds="80", is_sequence=True),
                Preset(label="&#x1f41f; Fish tank", display_gradient=("#00FF88","#0088FF","#007ACC","#00FFFF"), rotate="00FF88,0088FF,007ACC,00FFFF", milliseconds="2500", is_sequence=True),
                Preset(label="&#x1f389; Party", display_gradient=("cyan","yellow","magenta"), rotate="cyan,yellow,magenta", milliseconds="1250", is_sequence=True),
                Preset(label="&#x1f33b; Flamboyant", display_gradient=("yellow","magenta"), jump="yellow,magenta", milliseconds="150", is_sequence=True),
                Preset(label="&#x1f6a8; NeeNaw", display_gradient=("cyan","blue"), jump="cyan,blue", milliseconds="100", is_sequence=True),
                Preset(label="&#x1f6a8; NeeNaw USA", display_gradient=("red","blue"), jump="red,blue", milliseconds="100", is_sequence=True),
                Preset(label="&#x1f308; Full circle", display_gradient=("#FF0000","#FF8800","#FFFF00","#88FF00","#00FF00","#00FF88","#00FFFF","#0088FF","#0000FF","#8800FF","#FF00FF","#FF0088"), milliseconds=500, rotate="#FF0000,FF8800,FFFF00,88FF00,00FF00,00FF88,00FFFF,0088FF,0000FF,8800FF,FF00FF,FF0088", is_sequence=True),
            )
    }

    ALARM_PRESETS = {
        "Morning":(
                Preset(label="&uarr; 2hr", display_gradient=("0K","5000K"), morning=60*60*2, is_sequence=True, is_sun=True),
                Preset(label="&uarr; 1hr", display_gradient=("0K","5000K"), morning=60*60*1, is_sequence=True, is_sun=True),
                Preset(label="&uarr; 30m", display_gradient=("0K","5000K"), morning=60*30, is_sequence=True, is_sun=True),
                Preset(label="&uarr; 1m", display_gradient=("0K","5000K"), morning=60*1, is_sequence=True, is_sun=True),
            ),
        "Dawn":(
                Preset(label="&darr; 2hr", display_gradient=("5000K","0K"), dawn=60*60*2, is_sequence=True, is_sun=True),
                Preset(label="&darr; 1hr", display_gradient=("5000K","0K"), dawn=60*60*1, is_sequence=True, is_sun=True),
                Preset(label="&darr; 30m", display_gradient=("5000K","0K"), dawn=60*30, is_sequence=True, is_sun=True),
                Preset(label="&darr; 1m", display_gradient=("5000K","0K"), dawn=60*1, is_sequence=True, is_sun=True),
            )
    }

    PRESETS_COPY = copy.deepcopy(PRESETS)  # Modifiable dictionary. Used in alarms and music.

    def __init__(self, *args, **kwargs):
        """
        @TODO: perform LAN discovery, interrogate the resources, generate controls for all of them
        """
        self.led_strip = LEDStrip(RESOLVED_USER_SETTINGS)
        Resource.__init__(self, *args, **kwargs) #Super
        # Add in the static folder.
        static_folder = os.path.join(RASPILED_DIR,"static")
        self.putChild("static", File(static_folder))  # Any requests to /static serve from the filesystem.
    
    def getChild(self, path, request, *args, **kwargs):
        """
        Entry point for dynamic pages 
        """
        self._path = path
        return self
    
    def getChildWithDefault(self, path, request):
        """
        Retrieve a static or dynamically generated child resource from me.

        First checks if a resource was added manually by putChild, and then
        call getChild to check for dynamic resources. Only override if you want
        to affect behaviour of all child lookups, rather than just dynamic
        ones.

        This will check to see if I have a pre-registered child resource of the
        given name, and call getChild if I do not.

        @see: L{IResource.getChildWithDefault}
        """
        if path in self.children:
            return self.children[path]
        return self.getChild(path, request)

    def client_LOGIN(self, request):
        accepted_connection=False
        self.ip=request.getClientIP()
        self.session_data = {
              '0':{
                   'user'  :  'pi',
                   'psw'   :  '',
                   'ip'    :  ['127.0.0.1'],
                   'key'   :  '',
                   'last_c':  '',
                   'u_key' :  '',
                  }
              }
        if os.path.exists(wlist_path):
            with open(wlist_path) as json_data:
                self.session_data = json.load(json_data)
        else:
             self.whitelistjson2file()
        for key, value in self.session_data.items():
            if accepted_connection==True:
                break
            for ip in value['ip']:
                if self.ip==ip:
                    accepted_connection=True
                    break
        return accepted_connection
   
    def render_GET(self, request):
        """
        MAIN WEB PAGE ENTRY POINT
            Responds to GET requests

            If a valid action in the GET querystring is present, that action will get performed and
            the web server will return a JSON response. The assumption is that a javascript function is calling
            this web server to act as an API

            If a human being arrives at the web server without providing a valid action in the GET querystring,
            they'll just be given the main html page which shows all the buttons.

        @param request: The http request, passed in from Twisted, which will be an instance of <SmartRequest>

        @return: HTML or JSON depending on if there is no action or an action.
        """
        accepted_client = self.client_LOGIN(request)
        if accepted_client:
            _colour_result = None
            #Look through the actions if the request key exists, perform that action
            for key_name, action_name in self.PARAM_TO_ACTION_MAPPING:
                if request.has_param(key_name):
                    self.led_strip.stop_current_sequence() #Stop current sequence
                    action_func_name = "action__%s" % action_name
                    _colour_result = getattr(self, action_func_name)(request) #Execute that function
                    break
        
            # Look through the actions if the request key exists, perform that action
            clean_path = unicode(self._path or u"").rstrip("/")
            for key_name, action_name in self.PARAM_TO_ACTION_MAPPING:
                if request.has_param(key_name) or clean_path == key_name:
                    action_func_name = "action__%s" % action_name
                    if action_name in ("capabilities", "status"):  # Something is asking for our capabilities or status
                        output = getattr(self, action_func_name)(request)  # Execute that function
                        request.setHeader("Content-Type", "application/json; charset=utf-8")
                        return json.dumps(output)
                    else:
                        self.led_strip.stop_current_sequence() #Stop current sequence
                        _colour_result = getattr(self, action_func_name)(request) #Execute that function
                    break
        
            # Now deduce our colour:
            current_colour = "({})".format(self.led_strip)
            current_hex = self.led_strip.hex
            contrast_colour = self.led_strip.contrast_from_bg(current_hex, dark_default="202020")
            # Return a JSON object if an action has been performed (i.e. _colour_result is set):
            if _colour_result is not None:
                json_data = {
                    "current" : current_hex,
                    "contrast" : contrast_colour,
                    "current_rgb": current_colour
                }
                try:
                    request.setHeader("Content-Type", "application/json; charset=utf-8")
                    return json.dumps(json_data)
                except (TypeError, ValueError):
                    return b"Raspiled generated invalid JSON data!"
        
            # Otherwise, we've not had an action, so return normal page
            request.setHeader("Content-Type", "text/html; charset=utf-8")
            htmlstr = ''
            with open(RASPILED_DIR+'/static/index.html') as index_html_template:
                htmlstr = index_html_template.read()  # 2018-09-08 It's more efficient to pull the whole file in
            return htmlstr.format(
                   current_colour=current_colour,
                   current_hex=current_hex,
                   contrast_colour=contrast_colour,
                   off_preset_html=self.OFF_PRESET.render(),
                   light_html=self.light_presets(request),
                   alarm_html=self.alarm_presets(request),
                   music_html=self.music_presets(request),
                   controls_html=self.udevelop_presets(request),
                   addition_js=self.js_interactions(request)
                   ).encode('utf-8')
        else:
            # Authenticatiom
            _connection_result=None
            for key_name, action_name in self.PARAM_TO_AUTHENTICATE:
                if request.has_param(key_name):
                    action_func_name = "action__%s" % action_name
                    _connection_result = getattr(self, action_func_name)(request)
                    break
            if _connection_result is not None:
                  try:
                      return json.dumps(_connection_result)
                  except:
                      return b"Json fkucked up"
            request.setHeader("Content-Type", "text/html; charset=utf-8")
            htmlstr=''
            with open(RASPILED_DIR+'/static/singin.html') as file:
                for line in file:
                     htmlstr+=line
            return htmlstr.encode('utf-8')
            
    def action__newclient(self,request):
        """
        Push a new client to the autentication or appends the new ip to the dictionary of sessions.
        """
        self.user = request.get_param("user", force=unicode)
        self.pswd = request.get_param("pswd", force=unicode)
        if (self.user==None or self.pswd == None ):
            pass
        elif (self.user=='' or self.pswd == '' ):
            return {'error':True,'message':'Empty user or password','accepted':False,'authentication':False}
        else:
            csession = request.getSession()
            self.key = csession.uid
            for key, value in self.session_data.items():
                if value['user'] == self.user and value['psw'] == self.pswd:
                    value['ip'].append(self.ip)
                    self.whitelistjson2file()
                    return {'error':False,'message':'Success','accepted':True,'authentication':False}        
            self.ukey = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(10))
            logging.info("Attempt from user: %s with IP: %s to access the server. Unique key: %s" % (self.user,self.ip,self.ukey))
            return {'error':False,'message':'Authenticate','accepted':False,'authentication':True}
    
    def action__authenticate(self,request):
        """
        Client authenticate with random string generated in the server
        """
        user_ukey = request.get_param("ukey", force=unicode)
        if self.ukey == user_ukey:
            self.session_data[str(len(self.session_data.keys()))]={
                                                                   'user'  :  self.user,
                                                                   'psw'   :  self.pswd,
                                                                   'ip'    :  [self.ip],
                                                                   'key'   :  self.key,
                                                                   'last_c':  str(datetime.datetime.now()),
                                                                   'u_key' :  self.ukey,
                                                                  }
            self.whitelistjson2file()
            return {'error':False,'message':'Success','accepted':True,'authentication':False}
           
        else:
            self.ukey=''.join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(10))
            logging.info("New unique key: %s" % self.ukey)
            return {'error':True,'message':'New authenticate code','accepted':False,'authentication':True}

    def whitelistjson2file(self):
        with open(wlist_path, 'w') as write_file:
            json.dump(self.session_data, write_file)
    
    #### Additional pages available via the menu ####

    def light_presets(self, request):
        """
        Renders the light presets as options

        @param request: The http request object

        """
        out_html_list = []
        for group_name, presets in self.PRESETS.items():
            preset_list = []
            #Inner for
            for preset in presets:
                preset_html = preset.render()
                preset_list.append(preset_html)
            group_html = """
                <div class="preset_group">
                    <h2>{group_name}</h2>
                    <div class="presets_row">
                        {preset_html}
                    </div>
                </div>
            """.format(
                group_name = group_name,
                preset_html = "\n".join(preset_list)
            )
            out_html_list.append(group_html)
        out_html = "\n".join(out_html_list)
        return out_html

    def alarm_presets(self,request):
       """
       Renders the alarm presets as options. Same sunrise or sunset routine except for 100k.
       """
       out_html_list = []
       for group_name, presets in self.ALARM_PRESETS.items():
           preset_list = []
           for preset in presets:
                preset_html = preset.render_select()
                preset_list.append(preset_html)
           group_html = """
                <p> {group_name} time </p>
                <div class="{group_name}"></div>
                <div class="preset_group">
                    <select class="presets_select {group_name}_select">
                        {preset_html}
                    </select>
                </div>
                """.format(
                    group_name = group_name,
                    preset_html = "\n".join(preset_list),
                )
           out_html_list.append(group_html)
       out_html = "\n".join(out_html_list)
       return out_html

    def music_presets(self,request):
       """
       Renders the Modipy music front page.
       """
       #out_html="""
       #    <iframe src="http://192.168.182.190:{mopify}/mopify/" style="width:100vw;height:100vh">
       #    </iframe>
       #""".format(mopify=params['mopidy_port'])
       #return out_html
       pass

    def udevelop_presets(self,request):
       """
       Renders the Under Development text.
       """
       out_html="""
           <div class="underdevelop">
           <h1> Under Development, please refer to the Github repository.</h1>
           </div>
       """
       return out_html
    
    def js_interactions(self,request):
        request.setHeader("Content-Type", "text/html; charset=utf-8")
        if params['latitude'] == '' or params['longitude'] == '':
            lat,lon=pi_gps_location()
        else:
            lat=params['latitude']
            lon=params['longitude']
        jsstr=''
        with open(RASPILED_DIR+'/static/js/raspiled_interaction.js') as file:
            for line in file:
                 jsstr+=line
        return jsstr.format(latcoord=str(lat),loncoord=str(lon)).encode('utf-8')

    #### Actions: These are the actions our web server can initiate. Triggered by hitting the url with ?action_name=value ####

    def action__set(self, request):
        """
        Run when user wants to set a colour to a specified value
        """
        set_colour = request.get_param("set", force=unicode)
        D("Set to: %s" % set_colour)
        return self.led_strip.set(set_colour)
    action__set.capability = {
        "param": "set",
        "description": "Sets the RGB strip to a single colour.",
        "value": "<unicode> A named colour (e.g. 'pink') or colour hex value (e.g. '#19BECA').",
        "validity": "<unicode> A known named colour, or valid colour hex in the range #000000-#FFFFFF.",
        "widget": "colourpicker",
        "returns": "<unicode> The hex value of the colour the RGB strip has been set to."
    }
    
    def action__fade(self, request):
        """
        Run when user wants to set a colour to a specified value
        """
        fade_colour = request.get_param("fade", force=unicode)
        logging.info("Fade to: %s" % fade_colour)
        return self.led_strip.fade(fade_colour)
    action__fade.capability = {
        "param": "fade",
        "description": "Fades the RGB strip from its current colour to a specified colour.",
        "value": "<unicode> A named colour (e.g. 'pink') or colour hex value (e.g. '#19BECA').",
        "validity": "<unicode> A known named colour, or valid colour hex in the range #000000-#FFFFFF",
        "returns": "<unicode> The hex value of the colour the RGB strip has been set to."
    }
    
    def action__sunrise(self, request):
        """
        Performs a sunrise over the specified period of time
        """
        seconds = request.get_param(["seconds","s","sunrise"], default=10.0, force=float)
        milliseconds = request.get_param(["milliseconds","ms"], default=0.0, force=float)
        temp_start = request.get_param(['temp_start','K'], default=None, force=unicode)
        temp_end = request.get_param('temp_end', default=None, force=unicode)
        logging.info("Sunrise: %s seconds" % (seconds + (milliseconds/1000.0)))
        return self.led_strip.sunrise(seconds=seconds, milliseconds=milliseconds, temp_start=temp_start, temp_end=temp_end)
    action__sunrise.capability = {
        "param": "sunrise",
        "description": "Gently fades-in the RGB strip from deep red to daylight.",
        "value": "The number of seconds you would like the sunrise to take.",
        "validity": "<float> > 0",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the sunrise should take. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "1000",
            },
            {
                "param": "temp_start",
                "value": "The colour temperature you wish to start from (e.g. 500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "6500K"
            },
            {
                "param": "temp_end",
                "value": "The colour temperature you wish to finish at (e.g. 4500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "500K"
            }
        ],
        "returns": "<unicode> The hex value of the colour the RGB strip has been set to."
    }
    
    def action__sunset(self, request):
        """
        Performs a sunset over the specified period of time
        """
        seconds = request.get_param(["seconds","s","sunset"], default=10.0, force=float)
        milliseconds = request.get_param(["milliseconds","ms"], default=0.0, force=float)
        temp_start = request.get_param(['temp_start', 'K'], default=None, force=unicode)
        temp_end = request.get_param('temp_end', default=None, force=unicode)
        logging.info("Sunset: %s seconds" % (seconds + (milliseconds/1000.0)))
        return self.led_strip.sunset(seconds=seconds, milliseconds=milliseconds, temp_start=temp_start, temp_end=temp_end)
    action__sunset.capability = {
        "param": "sunset",
        "description": "Gently fades-out the RGB strip from daylight to deep-red.",
        "value": "The number of seconds you would like the sunrise to take.",
        "validity": "<float> > 0",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the sunset should take. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "1000",
            },
            {
                "param": "temp_start",
                "value": "The colour temperature you wish to start from (e.g. 500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "500K"
            },
            {
                "param": "temp_end",
                "value": "The colour temperature you wish to finish at (e.g. 4500K).",
                "validity": "<unicode> Matches a named colour temperature (50K - 15000K in 100 Kelvin steps)",
                "default": "6500K"
            }
        ],
        "returns": ""
    }
    
    def action__alarm(self, request):
        """
        Performs a sunrise over the specified period of time
        """
        m_seconds = request.get_param(["seconds","s","morning"], default=10.0, force=float)
        d_seconds = request.get_param(["seconds","s","dawn"], default=10.0, force=float)
        hour = request.get_param(["time","hr","hour"], default='12:00', force=unicode)
        freq = request.get_param(["freq"], default='daily', force=float)
        milliseconds = request.get_param(["milliseconds","ms"], default=0.0, force=float)
        temp_start = request.get_param(['temp_start', 'K'], default=None, force=unicode)
        temp_end = request.get_param('temp_end', default=None, force=unicode)
        logging.info("Morning Alarm : %s seconds at %s" % (m_seconds + (milliseconds/1000.0), hour[0]))
        logging.info("Dawn Alarm    : %s seconds at %s" % (d_seconds + (milliseconds/1000.0), hour[1]))
        return self.led_strip.alarm(seconds=[d_seconds,m_seconds], milliseconds=milliseconds, hour=hour, freq=freq, temp_start=temp_start, temp_end=temp_end)

    def action__jump(self, request):
        """
        Jump from one specified colour to the next
        """
        jump_colours = request.get_param_values("jump")
        seconds = request.get_param(["seconds","s"], default=0.0, force=float)
        milliseconds = request.get_param(["milliseconds","ms"], default=0.0, force=float)
        self.led_strip.stop_current_sequence() #Terminate any crap that's going on
        total_seconds = (seconds + (milliseconds/1000.0))
        logging.info("Jump: %s, %s seconds" % (jump_colours, total_seconds))
        return self.led_strip.jump(jump_colours, seconds=seconds, milliseconds=milliseconds) #Has its own colour sanitisation routine
    action__jump.capability = {
        "param": "jump",
        "description": "Hops from one colour to the next over an even period of time.",
        "value": "A comma delimited list of colours you wish to jump between.",
        "validity": "<unicode> valid colour names or hex values separated by commas (e.g. red,blue,green,cyan,#FF00FF)",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the each colour should be displayed for. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "200",
            },
            {
                "param": "seconds",
                "value": "The number of seconds each colour should be displayed for. Will be added to milliseconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "0",
            },
        ],
        "returns": "<unicode> The first hex value of sequence."
    }

    def action__rotate(self, request):
        """
        Rotates (fades) from one specified colour to the next
        """
        rotate_colours = request.get_param_values("rotate")
        seconds = request.get_param(["seconds","s"], default=0.0, force=float)
        milliseconds = request.get_param(["milliseconds","ms"], default=0.0, force=float)
        self.led_strip.stop_current_sequence() #Terminate any crap that's going on
        total_seconds = (seconds + (milliseconds/1000.0))
        logging.info("Rotate: %s, %s seconds" % (rotate_colours, total_seconds))
        return self.led_strip.rotate(rotate_colours, seconds=seconds, milliseconds=milliseconds) #Has its own colour sanitisation routine
    action__rotate.capability = {
        "param": "rotate",
        "description": "Fades from one colour to the next over an even period of time.",
        "value": "A comma delimited list of colours you wish to cross-fade between.",
        "validity": "<unicode> valid colour names or hex values separated by commas (e.g. red,blue,green,cyan,#FF00FF)",
        "optional_concurrent_parameters": [
            {
                "param": "milliseconds",
                "value": "The number of milliseconds the each colour fade should take. Will be added to seconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "200",
            },
            {
                "param": "seconds",
                "value": "The number of seconds each colour fade should take. Will be added to milliseconds (if specified) to give a total time.",
                "validity": "<int> > 0",
                "default": "0",
            },
        ],
        "returns": "<unicode> The first hex value of sequence."
    }

    def action__stop(self, request):
        """
        Stops the current sequence
        """
        return self.led_strip.stop()
    action__stop.capability = {
        "param": "stop",
        "description": "Halts the current sequence or fade.",
        "value": "",
        "returns": "<unicode> The hex value of colour the RGB strip got halted on."
    }
    
    def action__off(self, request):
        """
        Turns the strip off
        """
        logging.info("Off!")
        return self.led_strip.off()
    action__off.capability = {
        "param": "off",
        "description": "Stops any fades or sequences. Quickly Fades the RGB strip to black (no light)",
        "value": "",
        "returns": "<unicode> The hex value of colour the RGB strip ends up at (#000000)."
    }

    def action__capabilities(self, request, *args, **kwargs):
        """
        Reports this listener's capabilities
        """
        output_capabilities = []
        for function_name in dir(self):
            if function_name.startswith("action__"):
                try:
                    capability_details = getattr(self,function_name).capability
                    output_capabilities.append(capability_details)
                except AttributeError:
                    pass
        return output_capabilities

    def action__status(self, request, *args, **kwargs):
        """
        Reports the status of the RGB LED strip
        """
        return {
            "current": self.led_strip.hex,
            "contrast": self.led_strip.contrast_from_bg(self.led_strip.hex, dark_default="202020"),
            "current_rgb": "({})".format(self.led_strip)
        }
    
    def teardown(self):
        """
        Called automatically when exiting the parent reactor
        """
        self.led_strip.teardown()
Exemplo n.º 12
0
        print('exiting')
        self.kill_now = True


def set_color(strip):
    now = datetime.datetime.now()
    if now.time() < datetime.time(12):
        strip.set_morning_color()
    else:
        strip.set_evening_color()


def run(strip):
    print('running')


if __name__ == '__main__':
    killer = GracefulKiller()
    strip = LEDStrip()

    try:
        set_color(strip)
        while not killer.kill_now:
            run(strip)
            time.sleep(10)

    except Exception as ex:
        print(ex)
        strip.switch_off()

    strip.switch_off()
Exemplo n.º 13
0
from helpers import *
import pycom
from network import WLAN
from machine import Pin, Timer
from _thread import start_new_thread
import utime
from ledstrip import LEDStrip

pycom.heartbeat(False)

import usocket as socket

ledstrip = LEDStrip(Pin('P22'), Pin('P21'), Pin('P23'))
pir = Pin('P18', mode=Pin.IN, pull=None)
fadeout_timer = None

# Commands:
#
# WAT - get color + fader status
# DIS - set color
# FAD - enable/disable Fader


def leds(port, ledstrip):
    s = socket.socket()
    ip_addr = WLAN().ifconfig()[0]
    s.bind((ip_addr, port))
    s.listen()

    while True:
        machine.idle()
Exemplo n.º 14
0
#!/usr/bin/python
import time

from ledstrip import LEDStrip

CLK = 17
DAT = 18

strip = LEDStrip(CLK, DAT)

print("Off")
strip.setcolouroff()
time.sleep(1)

print("White")
strip.setcolourwhite()
time.sleep(1)

print("Red")
strip.setcolourred()
time.sleep(1)

print("Green")
strip.setcolourgreen()
time.sleep(1)

print("Blue")
strip.setcolourblue()
time.sleep(1)

print("RGB 128,128,0")
Exemplo n.º 15
0
from ledstrip import LEDStrip
import time
import random

CLK = 3
DAT = 2

strip = LEDStrip(CLK, DAT)

print("Set Color to Red")
for r in range(50, 100):
    strip.setcolourrgb(r, 0, 0)
    time.sleep(0.05)

print("Set Color to Blue")
for b in range(50, 100):
    strip.setcolourrgb(0, 0, b)
    time.sleep(0.05)

print("Set Color to Green")
for g in range(50, 100):
    strip.setcolourrgb(0, g, 0)
    time.sleep(0.05)

for ra in range(50, 200):
    r = random.randint(0, 255)
    b = random.randint(0, 255)
    g = random.randint(0, 255)
    strip.setcolourrgb(r, g, b)
    time.sleep(0.50)