Mote Light LEDs - versatile, variable and discrete. Plus Home Assitant Switches, groups & API

Ok, now I get this error in the Hass log:

17-03-14 23:43:54 WARNING (MainThread) [homeassistant.core] Unable to find service input_select/turn_on

This is when I try to turn all the channels on

Edit:

The part you asked for now looks like this:

response = get('https://192.168.1.13:8123/api/states/input_select.mote_device_choice')
device = str(response.json()['state'])
if device == "Stereo":
    device = "http://192.168.1.58:5000/mote/api/v1.0"

Maybe there is an issue with using letsencrypt and duckdns?

I have to say I’ve never seen that message before. Not sure where it’s from.

Do all the curl calls work? Cylon, Rainbow, Bounce-wash etc. ?

Only tiedye and rainbow is working in the console. Nothing works in Hass.

curl -s http://192.168.1.58:5000/mote/api/v1.0/cyclon_rgb/1200/

results in “not found”

Hass is still reporting on/off state though.

In mote-hass-api-call.py I’ve appended hass-url with ?api_password=YOUR_PASSWORD

Okay that one should be handy enough - the curl is a bit longer. Could you try this one instead?

curl -s http://192.168.1.58:5000/mote/api/v1.0/cylon_rgb/1200/0/255/80/0/0.1/0/3

or in the code:

larson_rgb(ch_selection,direction,r,g,b,pause_time,persist,loop)

Running the curl command should have given you:

  • a Cylon effect,
  • on channels 1 and 2 (ignoring 3 and 4)
  • going to the USB ports,
  • in an amber yellow,
  • with a 0.1 second pause,
  • no light persistence,
  • repeating 3 times.

And we’ll be able to test this bit at the same time:

In mote-hass-api-call.py I’ve appended hass-url with ?api_password=YOUR_PASSWORD

curl -s http://192.168.1.58:5000/mote/api/v1.0/cylon_rgb/1200/0/255/80/0/0.1/0/3

Worked

1 Like

Yippee! All the other effects are variations on that really!

So bouncewash_rgb instead of cylon will get you the bounce version etc.

The switches in Hass are just those calls.

Turning off is sending 0/0/0/ or hex 000000 on all channels via some effect, e.g. the Larsonloop.

That makes the most likely place for a problem the mote-hass-api-call.py file again. Which in turn makes it seem like my code that’s the problem.

Can you try making a Hass switch using a curl command of your choice?

If that works, then it’s definitely my code and / or guide that’s the problem.

Sweeeet!

Made a test switch and that worked!

switch:
  - platform: command_line
    switches:
      wooden_stereo_lights:
        command_on: curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop/1200/0/ee7600/0.1/1/1
        command_off: curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop/1223/1/000000/0.11/1/1
        command_state: curl -s http://192.168.1.58:5000/mote/api/v1.0/led_lit | grep 'on'
        friendly_name: Stereo Cabinet
      test:
        command_off: curl -s http://192.168.1.58:5000/mote/api/v1.0/cylon_rgb/1234/0/0/0/0/0.1/0/3

Edit:

Seems like hex codes are throwing errors:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title>TypeError: 'float' object cannot be interpreted as an integer // Werkzeug Debugger</title>
    <link rel="stylesheet" href="?__debugger__=yes&amp;cmd=resource&amp;f=style.css" type="text/css">
    <!-- We need to make sure this has a favicon so that the debugger does not by
         accident trigger a request to /favicon.ico which might change the application
         state. -->
    <link rel="shortcut icon" href="?__debugger__=yes&amp;cmd=resource&amp;f=console.png">
    <script type="text/javascript" src="?__debugger__=yes&amp;cmd=resource&amp;f=jquery.js"></script>
    <script type="text/javascript" src="?__debugger__=yes&amp;cmd=resource&amp;f=debugger.js"></script>
    <script type="text/javascript">
      var TRACEBACK = 1965539120,
          CONSOLE_MODE = false,
          EVALEX = true,
          SECRET = "GpVoaB5yJZVpCXL2DAdK";
    </script>
  </head>
  <body>
    <div class="debugger">
<h1>builtins.TypeError</h1>
<div class="detail">
  <p class="errormsg">TypeError: 'float' object cannot be interpreted as an integer</p>
</div>
<h2 class="traceback">Traceback <em>(most recent call last)</em></h2>
<div class="traceback">

  <ul><li><div class="frame" id="frame-1965539056">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1836</em>,
      in <code class="function">__call__</code></h4>
  <pre>return self.wsgi_app(environ, start_response)</pre>
</div>

<li><div class="frame" id="frame-1965539280">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1820</em>,
      in <code class="function">wsgi_app</code></h4>
  <pre>response = self.make_response(self.handle_exception(e))</pre>
</div>

<li><div class="frame" id="frame-1965539312">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1403</em>,
      in <code class="function">handle_exception</code></h4>
  <pre>reraise(exc_type, exc_value, tb)</pre>
</div>

<li><div class="frame" id="frame-1965539152">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/_compat.py"</cite>,
      line <em class="line">33</em>,
      in <code class="function">reraise</code></h4>
  <pre>raise value</pre>
</div>

<li><div class="frame" id="frame-1965539248">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1817</em>,
      in <code class="function">wsgi_app</code></h4>
  <pre>response = self.full_dispatch_request()</pre>
</div>

<li><div class="frame" id="frame-1965539184">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1477</em>,
      in <code class="function">full_dispatch_request</code></h4>
  <pre>rv = self.handle_user_exception(e)</pre>
</div>

<li><div class="frame" id="frame-1965539216">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1381</em>,
      in <code class="function">handle_user_exception</code></h4>
  <pre>reraise(exc_type, exc_value, tb)</pre>
</div>

<li><div class="frame" id="frame-1965281456">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/_compat.py"</cite>,
      line <em class="line">33</em>,
      in <code class="function">reraise</code></h4>
  <pre>raise value</pre>
</div>

<li><div class="frame" id="frame-1965281424">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1475</em>,
      in <code class="function">full_dispatch_request</code></h4>
  <pre>rv = self.dispatch_request()</pre>
</div>

<li><div class="frame" id="frame-1966869232">
  <h4>File <cite class="filename">"/usr/lib/python3/dist-packages/flask/app.py"</cite>,
      line <em class="line">1461</em>,
      in <code class="function">dispatch_request</code></h4>
  <pre>return self.view_functions[rule.endpoint](**req.view_args)</pre>
</div>

<li><div class="frame" id="frame-1966870352">
  <h4>File <cite class="filename">"/home/pi/Pimoroni/mote/mote-api-rc-for-github.py"</cite>,
      line <em class="line">180</em>,
      in <code class="function">larsonl</code></h4>
  <pre>r, g, b = hex_to_rgb(colour)</pre>
</div>

<li><div class="frame" id="frame-1966868912">
  <h4>File <cite class="filename">"/home/pi/Pimoroni/mote/mote-api-rc-for-github.py"</cite>,
      line <em class="line">50</em>,
      in <code class="function">hex_to_rgb</code></h4>
  <pre>return tuple(int(value[i:i + length / 3], 16) for i in range(0, length, length / 3))</pre>
</div>
</ul>
  <blockquote>TypeError: 'float' object cannot be interpreted as an integer</blockquote>
</div>

<div class="plain">
  <form action="/?__debugger__=yes&amp;cmd=paste" method="post">
    <p>
      <input type="hidden" name="language" value="pytb">
      This is the Copy/Paste friendly version of the traceback.  <span
      class="pastemessage">You can also paste this traceback into
      a <a href="https://gist.github.com/">gist</a>:
      <input type="submit" value="create paste"></span>
    </p>
    <textarea cols="50" rows="10" name="code" readonly>Traceback (most recent call last):
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File &quot;/usr/lib/python3/dist-packages/flask/_compat.py&quot;, line 33, in reraise
    raise value
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File &quot;/usr/lib/python3/dist-packages/flask/_compat.py&quot;, line 33, in reraise
    raise value
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File &quot;/usr/lib/python3/dist-packages/flask/app.py&quot;, line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File &quot;/home/pi/Pimoroni/mote/mote-api-rc-for-github.py&quot;, line 180, in larsonl
    r, g, b = hex_to_rgb(colour)
  File &quot;/home/pi/Pimoroni/mote/mote-api-rc-for-github.py&quot;, line 50, in hex_to_rgb
    return tuple(int(value[i:i + length / 3], 16) for i in range(0, length, length / 3))
TypeError: 'float' object cannot be interpreted as an integer</textarea>
  </form>
</div>
<div class="explanation">
  The debugger caught an exception in your WSGI application.  You can now
  look at the traceback which led to the error.  <span class="nojavascript">
  If you enable JavaScript you can also use additional features such as code
  execution (if the evalex feature is enabled), automatic pasting of the
  exceptions and much more.</span>
</div>
      <div class="footer">
        Brought to you by <strong class="arthur">DON'T PANIC</strong>, your
        friendly Werkzeug powered traceback interpreter.
      </div>
    </div>
  </body>
</html>

<!--

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3/dist-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python3/dist-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/pi/Pimoroni/mote/mote-api-rc-for-github.py", line 180, in larsonl
    r, g, b = hex_to_rgb(colour)
  File "/home/pi/Pimoroni/mote/mote-api-rc-for-github.py", line 50, in hex_to_rgb
    return tuple(int(value[i:i + length / 3], 16) for i in range(0, length, length / 3))
TypeError: 'float' object cannot be interpreted as an integer

-->

Thrilled the curl calls and switches are working for you :slight_smile:

So definitely my code then!

Well, I’ll be off to fix those problems, and be back to you as soon as I’ve checked it all!

Thanks so much for trying out my code, sorry didn’t work ‘right out of the box’!

WIll have a fresh version ready tomorrow!

Happy Lighting!

Thanks for your help! No worries about the errors. It gives me the opportunity to learn something :slight_smile:

Time for bed for me. We’ll pick it up later!

1 Like

Hey, I’ve tried to send curl commands to just turn the lights on with a color, brightness and channel but I can’t find the right ones. Are you able to provide me with a couple of examples?

I’ve been out of the loop for a bit. Haven’t gotten around to checking my code for problems. That’s this evening :slight_smile:

So a quick guide to how the curl commands work, and can be put together, here’s a working one using your IP address.

curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop/1234/1/ee7600/0.1/1/1

and I’ve a bunch for you at the end.

This part curl -s http://192.168.1.58:5000/mote/api/v1.0/ always stays the same, you decide what comes after.

larsonloop/1234/1/ee7600/0.1/1/1

which describes:

effect type / channels / dir / colour / pause time / persist / loop

A “larsonloop” is the standard light-by-light change, you can also choose from:

  • larsonloop, larsonloop_rgb

  • larsonswipe, larsonswipe_rgb

  • cylon (essentially a larsonloop twice), cylon_rgb

  • bouncewash, bouncewash_rgb (another larsonloop sequence)

  • rainbow

  • tiedye


Next up are the channel selections - the “1234” part.

If you had only two mote sticks on port 1 & 2, you’d type “1200”. If you have 3 mote sticks on ports 1,2 & 4 - you’d type “1204”.

You can also use this to pick one stick, apply an effect then pick another stick apply a different effect:

So

curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop/1000/1/ee7600/0.1/1/1

Make only channel one, an “ee7600” colour (ambery yellow)

curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop/0200/1/ff0000/0.1/1/1

Make only channel two, an “ff0000” colour (max red)

You can check the codes here: http://www.december.com/html/spec/colorhex.html

curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop/0034/1/ff00ff/0.1/1/1

Make channels three & four purple.

You don’t have to use Hex colour codes, if you find RGB easier the just call larsonloop_rgb instead, and here’s a list for them:

http://www.rapidtables.com/web/color/RGB_Color.htm#rgb-format


Right after the channels is the light direction setting:

0 = Travels from the USB port to the End.

1 = Travels from the End to the USB port.


Next is the colour selection, which we’ve looked at above.


After that is the pause time, in seconds:

So for one tenth of a second, put in 0.1 - for two seconds 2.0


Next is persist,:

0 = Light does not remain, clears as it goes.

1 = Light remains lit.

This value may not always matter, e.g. the Cylon and Bouncewash animations will ignore this value as they have their own pattern.


Last is loop (how many repeats you want):

0 = Nothing will happen

1 = Effect happens once

2 = Total of two loops, and so on …


Anyway, assuming your IP address hasn’t changed here’s a bunch:

  • curl -s http://192.168.1.58:5000/mote/api/v1.0/rainbow/1200

Make channels 1 and 2 cycle through rainbow colours.

  • curl -s http://192.168.1.58:5000/mote/api/v1.0/tiedye/0034

Make channels 3 and 4 cycle through tiedye colours.


Next one is different, a larsonswipe. This time the channel selection is instead a channel sequence:

  • curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonswipe_rgb/1432/0/255/80/0/0.5/0/2

So it’s stick #1, in a yellow red, then #4, #3 and finally #2 - travelling to the USB port with a pause of 0.5 seconds, no persistence, performed a total of two times.


All channels orangey-red:

  • curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop_rgb/1234/1/255/60/0/0.1/1/1

All channels orangey-red, with a little travelling motion before all leds go a solid colour:

  • curl -s http://192.168.1.58:5000/mote/api/v1.0/bouncewash_rgb/1234/1/255/60/0/0.1/1/1

Of course if you have a sequence of these you like to run, you can put them in a script and call the script as part of a Hass Switch.

(Ahh, have to pop out again - I’ll finish this up as soon as I’m back with scripts & switches for you)

Thanks! I’ll check those out :slight_smile:

Rather than edit the above, I’ll carry on here.

So let’s say you want a script to do a few light effects, and then be able to turn this on and off in Hass.

First up a script with light effects, for let’s say - two shelves with two mote sticks under each.

#!/bin/sh

# Turn all sticks lights yellow slowly with a little light travelling, then a solid wash of colour
curl -s http://192.168.1.58:5000/mote/api/v1.0/bouncewash_rgb/1234/1/255/60/0/0.5/1/1

# Now Turn them all more red, no little light, at a slower pace
curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop_rgb/1234/1/255/30/0/1/1/1

# Finally Turn the top shelf (in this case say that's #1 & #3) - slower again
curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop_rgb/1030/1/0/0/0/1.5/1/1

So if you copy and paste that into a file and we’ll save it as: first-effect.sh on the same machine that Hass runs on.

Also, don’t forget to do a chmod u+x first-effect.sh, so you can run the file.

Now over to switches.yaml file, and add this:

- platform: command_line
  switches:
    first_effect_shelf:
      command_on: /path/to/first-effect.sh
      command_off: curl -s http://192.168.1.58:5000/mote/api/v1.0/larsonloop/1234/1/000000/1.5/1/1
      command_state: curl -s http://192.168.1.58:5000/pi/api/v1.0/led_state | grep 'on'

And in your groups.yaml add in something like:

Mote Cabinet Lights:
  view: yes
  entities:
    - switches.first_effect_shelf

To set the light effect to illuminate at Sunset, and set a time off - you can add this into your automations.yaml file:

- alias: "Sunset-Lights-On"
  trigger:
    - platform: sun
      event: sunset
      offset: "-00:00:17"
  action:
    - service: homeassistant.turn_on
      switch.first_effect_shelf

- alias: "Sleep-Time-Lights-Off"
  trigger:
    - platform: time
      after: '00:30:00'
  action:
    - service: homeassistant.turn_off
      entity_id: switch.first_effect_shelf

And you can build effect combinations up like that, make switches of the them, automate them to when you come home etc. - all while I’m getting to the bottom of why my code isn’t working for you.

Also, could you post a snippet of the mote-hass-api-call.py you’re using:

Your version of this bit from the top of the file,

response = get('http://192.168.178.40:8123/api/states/input_slider.mote_value_red')
r = int(float(response.json()['state']))

and further down:

response = get('http://192.168.178.40:8123/api/states/input_select.mote_device_choice')
device = str(response.json()['state'])
if device == "Stereo":
    device = "http://192.168.178.95:5000/mote/api/v1.0"

would be great!

Thanks again. I have to do a reinstall of my Pi and am working on getting WiFi to work (which is a pain in the ass).

Could take a while but I’ll get back to you.

Oh definitely, best of luck.

And if they’re suitable, there’s always powerline plugs (I’ve 7)!

OK, I’m up and running again.

my mote-hass-api-call.py:

response = get(''myurl:8123/api/states/input_slider.mote_value_red?api_password=mypass')
r = int(float(response.json()['state']))


response = get('https://myurl:8123/api/states/input_select.mote_device_choice?api_password=mypass')
device = str(response.json()['state'])
if device == "Stereo":
    device = "http://192.168.1.58:5000/mote/api/v1.0"
elif device == "Square Circle":
    device = "http://192.168.1.58:5000/mote/api/v1.0"
elif device == "Ceramic Oval":
    device = "http://192.168.1.58:5000/mote/api/v1.0"

I see that the first one start with ‘’ and ends with ’ - is this correct?

BTW I did some testing in Postman and got responses from every call in mote-hass-api-call.py

I love this setup. Can it be controlled by voice with Alexa?

I see that the first one start with ‘’ and ends with ’ - is this correct?

I’d say not, better to make it a single ’ , happy to see the api-call part is playing well with others.

Still not sure why it’s not working fully for you yet!

Apologies for the delay in reply (St. Patrick’s Day, Rugby, catch-up etc.)

1 Like

Can it be controlled by voice with Alexa?

I’ve no working knowledge of Alexa, but I imagine it can’t be too hard.

So if the word ‘Cylon’ is to trigger a cylon light effect - this is the curl command to create a Cylon effect, and match to Alexa’s recognition of the word:

  • ‘Cylon Yellow’
    curl -s http://[your mote IP]:5000/mote/api/v1.0/cylon_rgb/1200/0/255/80/0/0.1/0/3

  • ‘Cylon Red’
    curl -s http://[your mote IP]:5000/mote/api/v1.0/cylon_rgb/1200/0/255/0/0/0.1/0/3

So if you can marry Alexa word recognition to trigger curl command-line statements, you’re set :slight_smile: