Compare commits
	
		
			1 commit
		
	
	
		
			
				main
			
			...
			
				hotfix/slo
			
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 92adc6ea9b | 
					 7 changed files with 42 additions and 102 deletions
				
			
		
							
								
								
									
										46
									
								
								animation.py
									
										
									
									
									
								
							
							
						
						
									
										46
									
								
								animation.py
									
										
									
									
									
								
							|  | @ -48,9 +48,9 @@ class RandomSingle(Animation): | ||||||
|         by Max & Lightmoll (https://lght.ml) |         by Max & Lightmoll (https://lght.ml) | ||||||
|         from 2022-06-08 |         from 2022-06-08 | ||||||
|     """ |     """ | ||||||
|     def __init__(self, color): |     def __init__(self, color, looptime=60): | ||||||
|         super().__init__() |         super().__init__() | ||||||
|         self.PERIOD = 4 * 30 #frames |         self.PERIOD = looptime * 30 #frames | ||||||
|         self.color = self._rand_color() |         self.color = self._rand_color() | ||||||
|         self.last_colors = [] |         self.last_colors = [] | ||||||
|         self.frame_counter = 0 |         self.frame_counter = 0 | ||||||
|  | @ -92,10 +92,10 @@ class TwoColor(Steady): | ||||||
|         by Max & Lightmoll (https://lght.ml) |         by Max & Lightmoll (https://lght.ml) | ||||||
|         from 2022-06-08 |         from 2022-06-08 | ||||||
|     """ |     """ | ||||||
|     def __init__(self, color):  |     def __init__(self, color, looptime=60): | ||||||
|         super().__init__(color)  |         super().__init__(color)  | ||||||
|         self.start_time = time() |         self.start_time = time() | ||||||
|         self.PERIOD = 0.5 #s |         self.PERIOD = looptime * 0.5 #s | ||||||
|         self.COL_1 = color #input color |         self.COL_1 = color #input color | ||||||
|          |          | ||||||
|         self.COL_2 = (255-self.r, 255-self.g, 255-self.b) #compl. color |         self.COL_2 = (255-self.r, 255-self.g, 255-self.b) #compl. color | ||||||
|  | @ -120,7 +120,6 @@ class TwoColor(Steady): | ||||||
|     def name(self): |     def name(self): | ||||||
|         return str(self) |         return str(self) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class Caramelldansen(Steady): | class Caramelldansen(Steady): | ||||||
|     """ |     """ | ||||||
|         by Max & Lightmoll (https://lght.ml) |         by Max & Lightmoll (https://lght.ml) | ||||||
|  | @ -175,7 +174,7 @@ class Caramelldansen(Steady): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class FadeTo(Steady): | class FadeTo(Steady): | ||||||
|     def __init__(self, color, t=2.0): |     def __init__(self, color, t=60.0): | ||||||
|         super(FadeTo, self).__init__(color) |         super(FadeTo, self).__init__(color) | ||||||
|         self.t = t |         self.t = t | ||||||
|         self.start = time() |         self.start = time() | ||||||
|  | @ -193,7 +192,7 @@ class FadeTo(Steady): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class RotatingRainbow(Animation): | class RotatingRainbow(Animation): | ||||||
|     def __init__(self, looptime=50.0): |     def __init__(self, looptime=60.0): | ||||||
|         super(RotatingRainbow, self).__init__() |         super(RotatingRainbow, self).__init__() | ||||||
|         self.looptime = looptime |         self.looptime = looptime | ||||||
|         pass |         pass | ||||||
|  | @ -217,7 +216,7 @@ class RotatingRainbow(Animation): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Chase(Steady): | class Chase(Steady): | ||||||
|     def __init__(self, color, looptime=1.0): |     def __init__(self, color, looptime=60.0): | ||||||
|         super(Chase, self).__init__(color) |         super(Chase, self).__init__(color) | ||||||
|         self.looptime = looptime |         self.looptime = looptime | ||||||
| 
 | 
 | ||||||
|  | @ -234,34 +233,9 @@ class Chase(Steady): | ||||||
|         return "chase" |         return "chase" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Hackertours(Steady): | class ChaseRandom(Animation): | ||||||
|     """ |     def __init__(self, color, looptime=60.0): | ||||||
|     Base color yellow, with green wandering back and forth |         super(Chase, self).__init__(color) | ||||||
|     """ |  | ||||||
|     def __init__(self, color, base=(255,223,0), looptime=4.0): |  | ||||||
|         super(Hackertours, self).__init__(color) |  | ||||||
|         self.looptime = looptime |  | ||||||
|         self.base = base |  | ||||||
| 
 |  | ||||||
|     def update(self, index, count): |  | ||||||
|         # angle is the position of the highlight on a circle, range [0, 1] |  | ||||||
|         angle = (time() / self.looptime + (index + 0.0) / count) % 1.0 |  | ||||||
|         l = 1 - min(abs(angle - 1 / count) * .9, 1.0 / count) * count |  | ||||||
|         return ( |  | ||||||
|             int(self.r * l + self.base[0] * (1-l)), |  | ||||||
|             int(self.g * l + self.base[1] * (1-l)), |  | ||||||
|             int(self.b * l + self.base[2] * (1-l))) |  | ||||||
| 
 |  | ||||||
|     def __str__(self): |  | ||||||
|         return f"{type(self).__name__}({self.r}, {self.g}, {self.b}, {self.looptime:.2f})" |  | ||||||
| 
 |  | ||||||
|     def name(self): |  | ||||||
|         return "hackertours" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class ChaseRandom(Steady): |  | ||||||
|     def __init__(self, color, looptime=1.0): |  | ||||||
|         super(ChaseRandom, self).__init__(color) |  | ||||||
|         self.looptime = looptime |         self.looptime = looptime | ||||||
| 
 | 
 | ||||||
|     def update(self, index, count): |     def update(self, index, count): | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								dmx.py
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								dmx.py
									
										
									
									
									
								
							|  | @ -5,8 +5,7 @@ from threading import Thread | ||||||
| from time import sleep | from time import sleep | ||||||
| from typing import Union | from typing import Union | ||||||
| 
 | 
 | ||||||
| from animation import Animation, Off, RandomSingle, Steady, FadeTo, RotatingRainbow, Chase, TwoColor, Caramelldansen, \ | from animation import Animation, Off, RandomSingle, Steady, FadeTo, RotatingRainbow, Chase, TwoColor, Caramelldansen | ||||||
|     Hackertours |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def ledlog(value): | def ledlog(value): | ||||||
|  | @ -21,13 +20,9 @@ class RGB: | ||||||
| 
 | 
 | ||||||
|     def rgb(self, color): |     def rgb(self, color): | ||||||
|         (r, g, b) = color |         (r, g, b) = color | ||||||
|         try: |         self.dmx.set(self.slot + self.offset + 0, ledlog(r)) | ||||||
|             self.dmx.set(self.slot + self.offset + 0, ledlog(r)) |         self.dmx.set(self.slot + self.offset + 1, ledlog(g)) | ||||||
|             self.dmx.set(self.slot + self.offset + 1, ledlog(g)) |         self.dmx.set(self.slot + self.offset + 2, ledlog(b)) | ||||||
|             self.dmx.set(self.slot + self.offset + 2, ledlog(b)) |  | ||||||
|         except Exception as e: |  | ||||||
|             print(f'slot={self.slot}, offset={self.offset}') |  | ||||||
|             raise(e) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Bar252(RGB): | class Bar252(RGB): | ||||||
|  | @ -52,20 +47,6 @@ class StairvilleLedPar56(RGB): | ||||||
|         dmx.set(self.slot + 6, 255) |         dmx.set(self.slot + 6, 255) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ZhennbyPar(RGB): |  | ||||||
|     def __init__(self, dmx, slot=1): |  | ||||||
|         super(ZhennbyPar, self).__init__(dmx, slot, 1) |  | ||||||
|         dmx.set(self.slot + 0, 255) |  | ||||||
|         dmx.set(self.slot + 4, 0) |  | ||||||
|         dmx.set(self.slot + 5, 0) |  | ||||||
|         dmx.set(self.slot + 6, 0) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Entec6RGBW(RGB): |  | ||||||
|     def __init__(self, dmx, slot=1): |  | ||||||
|         super(Entec6RGBW, self).__init__(dmx, slot) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DMX: | class DMX: | ||||||
|     def __init__(self, host, port=0x1936, universe=1, maxchan=512): |     def __init__(self, host, port=0x1936, universe=1, maxchan=512): | ||||||
|         self._host = host |         self._host = host | ||||||
|  | @ -150,8 +131,6 @@ class DMX: | ||||||
|                 animation = Caramelldansen(self._color) |                 animation = Caramelldansen(self._color) | ||||||
|             elif animation == "randomsingle": |             elif animation == "randomsingle": | ||||||
|                 animation = RandomSingle(self._color) |                 animation = RandomSingle(self._color) | ||||||
|             elif animation == "hackertours": |  | ||||||
|                 animation = Hackertours(self._color) |  | ||||||
|             else: |             else: | ||||||
|                 raise ValueError(f"No such animation {animation}") |                 raise ValueError(f"No such animation {animation}") | ||||||
|         self._animation = animation |         self._animation = animation | ||||||
|  | @ -174,5 +153,5 @@ class DMX: | ||||||
|     @color.setter |     @color.setter | ||||||
|     def color(self, color): |     def color(self, color): | ||||||
|         if self._color != color: |         if self._color != color: | ||||||
|             self._color = [int(c) for c in color] |             self._color = color | ||||||
|             self.animation = self.animation |             self.animation = self.animation | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								foobaz.py
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								foobaz.py
									
										
									
									
									
								
							|  | @ -7,7 +7,7 @@ from typing import Tuple | ||||||
| from bottle import post, request, route, run, static_file, view | from bottle import post, request, route, run, static_file, view | ||||||
| 
 | 
 | ||||||
| from animation import Off | from animation import Off | ||||||
| from dmx import DMX, Bar252, StairvilleLedPar56, REDSpot18RGB, ZhennbyPar, Entec6RGBW | from dmx import DMX, Bar252, StairvilleLedPar56, REDSpot18RGB | ||||||
| 
 | 
 | ||||||
| room = '' | room = '' | ||||||
| 
 | 
 | ||||||
|  | @ -51,12 +51,10 @@ def main(args): | ||||||
|     parser.add_argument('-l', '--listen', type=int, required=False, default=8080, help="TCP port to listen on for web") |     parser.add_argument('-l', '--listen', type=int, required=False, default=8080, help="TCP port to listen on for web") | ||||||
|     parser.add_argument('-r', '--room', type=str, required=True, help="light setup for room: shop or big") |     parser.add_argument('-r', '--room', type=str, required=True, help="light setup for room: shop or big") | ||||||
|     parser.add_argument('-u', '--universe', type=int, required=False, default=1, help="Universe to send to") |     parser.add_argument('-u', '--universe', type=int, required=False, default=1, help="Universe to send to") | ||||||
|     parser.add_argument('-A', '--animation', type=str, required=False, default="off", help="Initial animation") |  | ||||||
|     parser.add_argument('-C', '--color', type=str, required=False, default="255,255,0", help="Initial color") |  | ||||||
|     args = parser.parse_args(args) |     args = parser.parse_args(args) | ||||||
| 
 | 
 | ||||||
|     print(f"Starting DMX via Art-Net to {args.artnet}", file=sys.stderr) |     print(f"Starting DMX via Art-Net to {args.artnet}", file=sys.stderr) | ||||||
|     dmx = DMX(args.artnet, maxchan=512, universe=args.universe) |     dmx = DMX(args.artnet, maxchan=128, universe=args.universe) | ||||||
| 
 | 
 | ||||||
|     if args.room == "shop": |     if args.room == "shop": | ||||||
|         dmx._rgbs = [ |         dmx._rgbs = [ | ||||||
|  | @ -76,22 +74,13 @@ def main(args): | ||||||
|             Bar252(dmx, 51), |             Bar252(dmx, 51), | ||||||
|             Bar252(dmx, 62), |             Bar252(dmx, 62), | ||||||
|         ] |         ] | ||||||
|     elif args.room == "hackertours": |  | ||||||
|         dmx._rgbs = [ |  | ||||||
|             ZhennbyPar(dmx, 1), |  | ||||||
|             ZhennbyPar(dmx, 8), |  | ||||||
|             ZhennbyPar(dmx, 15), |  | ||||||
|             ZhennbyPar(dmx, 22), |  | ||||||
|         ] |  | ||||||
|     elif args.room == "defrag": |  | ||||||
|         dmx._rgbs = [Entec6RGBW(dmx, 300 + i*4) for i in range(19)] |  | ||||||
|     else: |     else: | ||||||
|         print(f"Unknown room {args.room}", file=sys.stderr) |         print(f"Unknown room {args.room}", file=sys.stderr) | ||||||
|         sys.exit(64) |         sys.exit(64) | ||||||
|     room = args.room |     room = args.room | ||||||
|     dmx.animation = Off() |     dmx.animation = Off() | ||||||
|     dmx.color = args.color.split(',') |     dmx.color = (0, 0, 0) | ||||||
|     dmx.animation = args.animation |     dmx.animation = "off" | ||||||
| 
 | 
 | ||||||
|     run(host='0.0.0.0', port=args.listen, reloader=False, debug=True) |     run(host='0.0.0.0', port=args.listen, reloader=False, debug=True) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,13 +0,0 @@ | ||||||
| [Unit] |  | ||||||
| Description=Run foobazdmx controller in Hackertours config |  | ||||||
| 
 |  | ||||||
| [Service] |  | ||||||
| Type=simple |  | ||||||
| ExecStart=poetry run python ./foobaz.py -a 127.0.0.1 -r hackertours -A hackertours -C 0,255,32 |  | ||||||
| WorkingDirectory=%h/working/foobazdmx |  | ||||||
| Restart=on-failure |  | ||||||
| 
 |  | ||||||
| [Install] |  | ||||||
| WantedBy=default.target |  | ||||||
| 
 |  | ||||||
| # link or copy me to ~/.config/systemd/user |  | ||||||
							
								
								
									
										17
									
								
								poetry.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										17
									
								
								poetry.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1,17 +1,18 @@ | ||||||
| # This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. |  | ||||||
| 
 |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "bottle" | name = "bottle" | ||||||
| version = "0.12.25" | version = "0.12.21" | ||||||
| description = "Fast and simple WSGI-framework for small web-applications." | description = "Fast and simple WSGI-framework for small web-applications." | ||||||
|  | category = "main" | ||||||
| optional = false | optional = false | ||||||
| python-versions = "*" | python-versions = "*" | ||||||
| files = [ |  | ||||||
|     {file = "bottle-0.12.25-py3-none-any.whl", hash = "sha256:d6f15f9d422670b7c073d63bd8d287b135388da187a0f3e3c19293626ce034ea"}, |  | ||||||
|     {file = "bottle-0.12.25.tar.gz", hash = "sha256:e1a9c94970ae6d710b3fb4526294dfeb86f2cb4a81eff3a4b98dc40fb0e5e021"}, |  | ||||||
| ] |  | ||||||
| 
 | 
 | ||||||
| [metadata] | [metadata] | ||||||
| lock-version = "2.0" | lock-version = "1.1" | ||||||
| python-versions = "^3.9" | python-versions = "^3.9" | ||||||
| content-hash = "861e3ad9d0b00deb876d2ca7797a608f215c7b91ec9b38f367b24bd096a28478" | content-hash = "861e3ad9d0b00deb876d2ca7797a608f215c7b91ec9b38f367b24bd096a28478" | ||||||
|  | 
 | ||||||
|  | [metadata.files] | ||||||
|  | bottle = [ | ||||||
|  |     {file = "bottle-0.12.21-py3-none-any.whl", hash = "sha256:6e1c9817019dae3a8c20adacaf09035251798d2ae2fcc8ce43157ee72965f257"}, | ||||||
|  |     {file = "bottle-0.12.21.tar.gz", hash = "sha256:787c61b6cc02b9c229bf2663011fac53dd8fc197f7f8ad2eeede29d888d7887e"}, | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | @ -3,7 +3,6 @@ name = "foobazdmx" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| description = "" | description = "" | ||||||
| authors = ["Stefan Bethke <stb@lassitu.de>"] | authors = ["Stefan Bethke <stb@lassitu.de>"] | ||||||
| #package-mode = false |  | ||||||
| 
 | 
 | ||||||
| [tool.poetry.dependencies] | [tool.poetry.dependencies] | ||||||
| python = "^3.9" | python = "^3.9" | ||||||
|  |  | ||||||
|  | @ -17,13 +17,24 @@ | ||||||
|             <input type="radio" class="js_animation" name="state" id="animation_white" value="steady"/> |             <input type="radio" class="js_animation" name="state" id="animation_white" value="steady"/> | ||||||
|             <label for="animation_white">Steady</label> |             <label for="animation_white">Steady</label> | ||||||
|         </div> |         </div> | ||||||
|  |         <div> | ||||||
|  |             <input type="radio" class="js_animation" name="state" id="animation_chase" value="chase"/> | ||||||
|  |             <label for="animation_chase">Chase</label> | ||||||
|  |         </div> | ||||||
|         <div> |         <div> | ||||||
|             <input type="radio" class="js_animation" name="state" id="animation_rainbow" value="rainbow"/> |             <input type="radio" class="js_animation" name="state" id="animation_rainbow" value="rainbow"/> | ||||||
|             <label for="animation_rainbow">Rainbow</label> |             <label for="animation_rainbow">Rainbow</label> | ||||||
|         </div> |         </div> | ||||||
|         <div> |         <div> | ||||||
|             <input type="radio" class="js_animation" name="state" id="animation_hackertours" value="hackertours"/> |             <input type="radio" class="js_animation" name="state" id="animation_randomsingle" value="randomsingle"/> | ||||||
|             <label for="animation_hackertours">Hackertours</label> |             <label for="animation_randomsingle">Random Single</label> | ||||||
|  |         <div> | ||||||
|  |             <input type="radio" class="js_animation" name="state" id="animation_twocolor" value="twocolor"/> | ||||||
|  |             <label for="animation_twocolor">Complementary</label> | ||||||
|  |         </div> | ||||||
|  |         <div> | ||||||
|  |             <input type="radio" class="js_animation" name="state" id="animation_caramelldansen" value="caramelldansen"/> | ||||||
|  |             <label for="animation_caramelldansen">Caramelldansen</label> | ||||||
|         </div> |         </div> | ||||||
|     </fieldset> |     </fieldset> | ||||||
|     <fieldset class="colors"> |     <fieldset class="colors"> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue