Cynics at Large Plugin Formulas - A Gentle Tutorial

Plugin Formulas - A Gentle Tutorial

Not everyone aspires to be a Python programmer. If you don't know Python and have little interest in changing that, you're not completely out of luck. You just have accept that a certain amount of magic happens here, and your job is to come up with working incantations without getting burned. So to speak.

We will write examples like this:

What you put into the field
What value the plugin uses for the field

If you want to follow along, you can use any dynamic field of any Cynical Plugin. The Cynical Explorer plugin has a field and button right in its configuration dialog - just type something and press the button. Or you can use the Message field of its Write Log action.

You know what happens if you just type some text into a field - you get what you type:

Hello, there!
Hello, there!
and that works just fine with a dynamic field, the kind that can contain a formula. To make the field do something surprising, you need to start with an equal sign "=":
=12345
12345
The equal sign gets eaten, and the rest of the text gets taken to be the formula. Of course, 12345 is, well, 12345. Strings must be enclosed in single or double quotes:
='Just some text'
Just some text
which produces exactly the same result as just typing in the string. This is also how you deal with an actual string that begins with an equal sign:
="==> Great!"
==> Great!
Did you ever try to put a newline character into an Indigo field, though? With a dash of Python, it's easy:
='Here comes the end:\nVerily!
Here comes the end:
Verily!
This is called a string escape sequence, and it lets you put all kinds of funny characters into a string - even invisible binary ones.

Variables

Indigo has variables. Let's say you have a name variable containing your name, Joe. How do you get a variable into a string? Like this:

=name
Joe
Simple, no? If you change the value of name, the effective value of the field will magically change to match. Now this is useful.

Of course, we can also do calculations:

=6*12
72
Arithmetic is easy. So are string calculations:
="Hello, " + name + "!"
Hello, Joe!
The "+" operator concatenates string values. It also adds up numbers; that's just how it works. So you need to pay attention to what kinds of values you work with. Python is apt to surprise you at times:
=2*name
JoeJoe
Multiplying a string with a number repeats it. Just be prepared to be amazed at times.

There are many other operators for calculations. If Python has it, you can use it. One useful one is the string formatting operator "%":

="Hello, %s! You have %d bottles." % (name, bottle_count)
Hello, Joe! You have 7 bottles.
This is just a different way to put together string values. If you want to learn more about Python operators and how they work, check out the official Python tutorial.

Functions

Python has functions, and they work just fine in plugin formulas:

=len(name)
3
calculates the length (in characters) of Joe. It can tell you how many things are contained in just about anything. Other functions are attached to things (they're called methods when they do that), like
=name.upper()
JOE
which puts Joe in ALL CAPS. To use those, you'll have to find out what they're called and what you put between those parentheses though, so you'll either have to look that up or ask a friend who knows Python. You can get pretty complicated, like so:
="high!" if temperature > 72 else "normal (%d)" % temperature
normal (67)
and you can probably figure out what happens when it gets hot.

Objects

Don't get scared now. Objects don't bite. Much.

Playing with constants and variables is fun, but often you need the value of something inside Indigo itself:

=indigo.server.version
5.1.2
In Python, you dig inside things by writing their name, appending a dot and then saying what part of the object you mean. In this case, the name indigo contains stuff made by the Indigo programmers for us. Among that stuff is indigo.server, an object that represents Indigo itself to the plugin. And one of the attributes of indigo.server is its version. Check out the Indigo scripting tutorial for some ideas of what you can use.

And we're just barely getting started here. The name plugin refers to the plugin itself. It contains all kinds of useful things, like its version:

=plugin.version
1.1.0
In fact, plugin is the plugin object the Indigo documentation talks about. If the plugin has a preference field called main_calendar, then
=plugin.main_calendar
Personal
will get it for you.

Devices

Let's say the plugin has a device called countdown, and that device has a state called count. (The Cynical Explorer plugin has such devices.) Then you can say

=devices.countdown.count
56
and you'll get the value of the count of the countdown device. If the field you're typing into belongs to an action, and that action is for a particular device, then you can just say device for that, and you might fill in a set counter action's value field with
=device.count+1
57
to increment it by as much as you like.

The same approach also works if count is a configuration field. And if that field is itself dynamic, we'll evaluate it for you. Neat, huh?

That "dot" naming only works if the device's name is a regular Python name with no funny characters like spaces. There's a different way to name recaltricant devices with odd names:

=devices["My Counter!!"].count
56
Those square brackets let you use any value as the name. If you happen to know the id number for a device, you can use it instead of the name. In fact, you can even calculate the name:
=devices[location + " counter"].count
56
might get the count state or configuration field of the "Living Room counter" device - as long as it belongs to the plugin you're talking to. (Indigo won't let you mess with another plugin's devices without some special preparations.)

Modules

You can even talk directly to the operating system that Indigo is running on. Much of Python's power lies in its library of modules containing interesting things. In plugin formulas, you just start with the module name and keep going:

=time.asctime()
Sat Jun 16 00:36:35 2012
to get the current time as a string. Or perhaps
=os.getenv("HOME")
/Users/joe
to get the user's home directory. (That's the user running Indigo, not necessarily you.) Or even, somewhat precariously,
=open('/Users/joe/Desktop/testfile').read()
This is what I put into my test file.
which produces the (entire) content of a text file on disk. The possibilities are endless; the limit is your imagination. That, and your patience in figuring out that Python thing...

About This Area 29 Oct 2019 19:52