Command Template
CommandTemplate
CommandTemplate for implementing commands.
This is a base class that is used for all commands. Any command (pattern) inherits from this class. If you are creating a new command or pattern, create a new class using this as a base class:
from cmdtemplate import CommandTemplate
...
class MyCommand(CommandTemplate):
...
The new command class must implement one required method render()
. There is
an optional method, config()
which is only needed if the new command has
configuration attributes. Each of these is documented below.
The new class should also be added to cmdclasses.py
so that it will be made
available to the command processor code.
Source code in ledstrip/cmdtemplate.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
|
cfgstr = 'no configs'
class-attribute
instance-attribute
Brief help for configuration parameters.
This will be shown by the $help,config
command. It should be very short
list of the parameters and any description.
helpstr = 'n/a'
class-attribute
instance-attribute
Brief help string for the command.
This will be shown by the help command. It should be pretty short.
config(cfglist: list[str]) -> None
Optional method for configuring the command.
This method is used if the command has any configurable attributes. If the command has nothing to configure, then this does not need to be implemented by the subclass.
This method will be called when the config command is issued for a specific command. For example, if the command has three configurable attributes, the config command might look like:
$config,mycommand,parm1,parm2,parm3
The method is always passed the attributes as a list of strings. The first two items in the list are "config" command itself, and the name of the command being configured ("mycommand" in the above example).
The command class and the command name are related but separate. It is
possible to have two different named commands that have the same
underlying command class. In this case, the implementation of config
could have conditional behavior depending on the name of the command.
All the parameters are passed as strings, but they are almost certainly
integers, so they need to be converted when they are stored, using
int(v)
.
Example Implementation
def config(self, cfglist):
# cfglist[0] is "config"
# cfglist[1] is "mycommand" - the name of the command
self.attr1 = int(cfglist[2]) # first parameter
self.attr2 = int(cfglist[3])
self.attr3 = int(cfglist[4])
...
# possible other processing
Nothing is returned.
Source code in ledstrip/cmdtemplate.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
|
render(parmlist, framebuf)
Required method to carry out the command actions.
This method is called whenever the command is invoked. Any parameters are passed in as a list. For example:
$mycommand,parm1
The method is passed a list of strings. The first entry is the command name which could be used for conditional behavior depending on the command name. The first parameter from the command line is the second item in the list.
A pixel array named framebuf
is passed to the method. This is an
array of 32-bit integers that represents the color values of a pixel.
Assuming RGB, then the bits in the integer are arranged like this:
[31:24] - not used
[23:16] - red value
[15:8] - green value
[7:0] - blue value
The render
method should carry out any actions that are required to
execute the command. For example if it an LED pattern, then the method
should calculate how each LED should be lit and store the pixel values
in the framebuf
array. render
needs to calculate the pixel value
for any pixels it changes, and set the R, G, and B fields to the
calculated values.
The render
method is called using a simple scheduling process. This
allows for repeating or progressing patterns (a chase for example) to
be continually recalculated and redrawn.
render
can return three different ways:
- None - this is a one-shot command, does not need to run again
- 0 - call back immediately - for continuous updating at maximum rate
- N (where N is int>0) - N is a delay in microseconds, render will be called back after that amount of time
Upon return from render()
, the LED strip will be updated using the
pixel values in framebuf
.
Example One-Shot Command
# command named "ledset" to turn on a single pixel
# "$ledset,pixnum,r,g,b"
#
def render(self, parmlist, framebuf):
# parmlist[0] is "ledset"
# should probably check for valid pixnum (not shown)
pixnum = int(parmlist[1])
# get color parameters as integers
red = int(parmlist[2])
grn = int(parmlist[3])
blu = int(parmlist[4])
# calculate the pixel value for the given color parameters
color = (red << 16) + (grn << 8) + blu
# set the specified pixel in the frame buffer
framebuf[pixnum] = color
# this one does not need to be repeated, so return None
return None
Example Periodic Command
# the class needs its own variables to track state
def __init__():
super().__init__() # get the superclass
self._delay = 10000 # 10 ms, overrides default of None
self._pixnum = 0
self._pixmax = 100 # could be configurable
# command named "ledrun" to cause a single pixel to "run" down the strip
# the lit LED will run from pixel 0 to some limit and then repeat
# in this example the limit is hard coded, but it could be a
# configurable attribute
# "$ledrun,r,g,b"
#
def render(self, parmlist, framebuf):
# parmlist[0] is "ledrun"
# get color parameters as integers
red = int(parmlist[1])
grn = int(parmlist[2])
blu = int(parmlist[3])
# calculate the pixel value for the given color parameters
color = (red << 16) + (grn << 8) + blu
# clear the last pixel that was lit
framebuf[self._pixnum] = 0
# advance the pixel, and set the color
self._pixnum += 1
if self._pixnum > self._pixmax:
self._pixnum = 0 # reset to beginning
framebuf[self._pixnum] = color # turn on new pixel
# repeat after a fixed delay (run periodically)
return self._delay
Source code in ledstrip/cmdtemplate.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
|