xPL Schema for the sprinklr schema Updated June 8, 2006 NOTE: The schema class for the sprinklers is "sprinklr" -- note the missing "e" near the ane of the name. xPL allows 8 characters maximum in a schema class, so the "e" was dropped to conform. NOTE: This document, as written today, is in an early format. As such, it's addressing both the end user audience that wants to learn how to use this schema to control a sprinkler controller and the controller xPL gateway author who is interfacing a new sprinkler controller to xPL via this schema. Minimum function a controller must implement for this schema: At a minimum, it must be able to enumerate it's valves, enumerate it's queue(s) and accept a command to queue a request for opening a specified valve for a specified number of minutes. Valves: Also known as Zones in some circles. This really is a controllable load and that is all it is. Given the nature of this schema, that probably means Time Increment: Minutes are specified starting with 1 and going to the controllers maximum. If the controller does not have a continuous range of minutes, but only offers predefined blocks (like 5, 10, 15, 20 or 5, 15, 30, 60), then the gateway should still accept any number of minutes, but *ROUND DOWN* to the next lowest valid minute increment (unless the request exactly matches a valid minute increment). This prevents potentially watering/opening a valve for far longer than a user expects. It's always better to round down (convervative) in these cases. Queues: For controllers that support them, a queue is an independent list of valve/time requests that are processed one after the order, in a first in, first out manner. Queues have no interdependcy -- each is equal to any other. Since they are independent, each queue can have a valve open meaning that for a controller that supports 4 queues, you could potentially have 4 valves open at the same time (assuming all queues have requests in them). If the controller has just one queue (even if not described as such), the gateway should advertise the controller as supporting a single queue. If the controller hardware doesn't have any queues -- just opens or closes a valve in response to a command, the gateway author should create at least one software queue in the gateway to hold requests and feed them to the hardware as time dictates. Commands: sprinklr.basic [queue-id=] [valve-id=] command=QUEUE-REQUEST|CLEAR-QUEUE|DELETE-REQUEST|CHANGE-REQUEST|MOVE-REQUEST|HOLD-QUEUE|RELEASE-QUEUE [run-minutes=] [request-index=] [new-request-index=] Send basic commands to control the sprinkler. Not all parameters are appropriate to all commands. command=QUEUE-REQUEST allows queue-id (optional), valve-id (required), run-minutes (required) and request-index (optional). This will add a request to a given queue on the specified controller to open the specified valve for the specified number of minutes. If request-index is not provided (or if it is provided but not supported according to sprinklr.gateinfo's can-insert-into-queue), the request is expected to be added to the end of the queue. If there is a request-index included but it specifies an invalid position, the gateway should discard the position and simply add the request to the end of the queue. Unless the specified queue is on hold, as soon as the first requests is queued, it's expected the valve will open (pending any delays for pump short cycle control, inter-valve delays, etc). command=CLEAR-QUEUE allows queue-id (optional). If supported, all requests in the specified queue are deleted/cleared and any valve open as a result of entries in that queue are closed. Command=HOLD-QUEUE allows queue-id (optional). If supported, the queue is put on hold. Any valve currently open as a result in the queue is closed and that valves "minutes left" timer stopped. You can still queue requests into the queue, but none will start until the queue is released. Pausing an already "on hold" queue is harmless and should be ignored. command=RELEASE-QUEUE allows queue-id (optional). If supported and if the queue was previously on hold, the queue is released. If there are entries in it, the "head of of the queue" valve is re-opened and it's "minutes left" timer resumes running. Releasing an already running queue is harmless and should be ignored. command=DELETE-REQUEST allows queue-id (optional) and request-index (required). The request at the passed position in the queue will be deleted. If the position is invalid (too low/too high), the command is ignored. command=CHANGE-REQUEST allows queue-id (optional), request-index (required) and run-minutes (required). This allows you to change the number of minutes a request can run for. If the position is invalid (too high/low) or the minutes are invalid (too low or above the maximum), the command is ignored. NOTE: Changing the minutes reset the controllers idea of time remaining. So if you are altering the request at request-index 0 (head of the queue) from 5 minutes to 10 minutes after the requests valve has already been oepn 3 minutes, the total valve open time will be 13 minutes (3 minutes before the CHANGE-REQUEST, then 10 minutes from that point on). command=MOVE-REQUEST allows queue-id (optional), request-index (required) and new-request-index (required). Moves the request at request-index in the queue to the new position. If the new position is beyond the end of the requests currently in the queue, then the request is moved to the end of the queue. If either position is otherwise invalid, the command is ignored. sprinklr.request request=[gateinfo|pumpinfo|queinfo|valvinfo|rqstinfo] [queue-id=] (for queue/request) [valve-id=] (for valve) [request-index=] (for request) requests info to be returned (via status messages) for the gateway, pump, queue (requires queue-id), valve (requires valve-id) or request (requires queue-id and request-index). Status Messages: sprinklr.gateinfo [controller-name=] Optional. Name, if any, of the controller [controller-version=] Optional. Version of the controller. This can be a device version, firmware version, etc. [controller-uptime=] Optional. Time controller has been up, formatted as DDDDHHMMSS (4 days, 2 hours, 2 minutes, 2 secounds, in decimal, zero filled, right justified). valve-id-list= List of valve identifiers. Each identifier is unique to a particular valve and will be the only thing valid for valve= tags in messages. Each identifier is seperated by a comma, no space. queue-id-list= List of queue identifiers. Each identifier is unique to a particular queue and will be the only thing valid for queue= tags in messages. Each identifier is seperated by a command, no space. If the device only has a single queue, you still need to provide an identifier (anything will work -- "default", "0", etc). default-queue-id= For messages that do not include a queue-id= in them, this is the queue to apply them toward. It is generally always best to include a queue-id= in a message, but for single queue controllers, it is overkill. Note: Messages sent from the gateway will *always* have a queue-id= in them. max-valve-open-time= Maximum amount of time in minutes the controller can open a valve for. Some controllers may not have any hard limit -- in those cases, picking 1440 (one day is 24 hours * 60 minutes == 1,440 minutes) is as good a value as any. max-requests-per-queue= Set the maximum number of requests that a queue can accept. It's presumed the gateway or the controller will reject attempts to add more entries than a queue can accept, though a user shouldn't try to overload this. If there is no limit per-se, 999 is a good default. max-total-requests= Set the maximum number of requests that a controller/gateway can accept. For a single queue controller/gateway, this should be the same as max-request-per-queue. For multiple queue controllers/gateways, this is the total the controller/gateway can support across all queues. For controllers that apply request limits only to queues (there is no controller limit), this value should be max-request-per-queue * # of queues on the controller/gateway (or a sufficiantly large number to never be exceeded, like 999999). For controllers that do not have a per-queue limit, but do have an overall request limit, the max-requests-per-queue and max-total-requests should have the same value. For controllers that have per-queue limits and total controller limits, the values here should be clearly dictated already by those parameters. has-pump=[yes|no] If the controller/gateway has a pump that is activated when any valve is open and shutdown after the last valve is closed, this should be YES. If there is no pump control, this should be NO. sends-time-updates=[yes|no] If the controller/gateway will send out periodic (once a minute) updates on the remaining time a queued requests valve is open, set to YES. If there is no such report, NO. sends-valve-updates=[yes|no] If the controller/gateway will send out an update whenever a valve opens or closes, set to YES. If there is no such report, NO. sends-pump-updates=[yes|no] If the controller/gateway can or does manage an irrigation pump and sends an update when the pump is started and when it is stopped, set to YES. If there is no pump or there are no updates sent, set to NO. sends-queue-updates=[yes|no] If the controller/gateway will send out an update whenever a request is added to, removed from altered or reordered in a queue, set to YES. If there is no such report, NO. can-queues-be-held=[yes|no] If the controller/gateway can be commanded to put a queue "on hold" (which would cause the valve of the current request, if any, to close and the "minutes open" timer to be halted and no new requests to be started) and release it (re-open the valve in the current request and resume the "minutes open" timer), set to YES. If the queue cannot be held, NO. can-insert-into-queue=[yes|no] If the controller/gateway allows a request to be inserted into any arbitrary place into the specified queue (i.e. add entry at position #3, vs end of the queu), set to YES. If all requests are appened to the queue, NO. can-delete-from-queue=[yes|no] If the controller/gateway allows a request to be deleted from a queue (any request in the queue, by request #/index), set to YES. If requests cannot be deleted, NO. can-reorder-queue=[yes|no] If the controller/gateway allows requests in a queue to be reordered (i.e. move request at #3 up to #1), set to YES. If requests cannot be reorderred, NO. can-change-request-time=[yes|no] If the controller/gateway allows the time for a request that is already in a queue to be altered, set to YES. If request time cannot be changed once queued, NO. can-clear-queue=[yes|no] If the controller/gateway allows the ability to clear all requests from a queue, set to YES. If requests cannot be cleared, NO. sprinklr.pumpinfo state=[running|stopped] sprinklr.valvinfo valve-id= valve-name= state=[open|closed] sprinklr.queinfo queue-id= queue-name= state=[on-hold|running] request-count= sprinklr.rqstinfo queue-id= request-index= valve-id= run-minutes= remaining-minutes= Triggers: sprinklr.gateway action=reboot|uptime [controller-uptime=] sprinklr.pump state=[running|stopped] sprinklr.valve valve-id= action=[opened|closed] sprinklr.queue queue-id= action=[running|on-hold|requests-reordered] request-count= action=running Indicates the queue has transitioned from "on hold" to running. action=on-hold Indicates the queue has transitioned from running to being "on hold". action=request-reordered Indicates one or more requests in the queue were re-ordered. Clients should purge their idea of the queue reqests and reload them. sprinklr.vrequest queue-id= request-index= action=[added|changed|removed|time-update] [valve-id=] [run-minutes=] [remaining-minutes=] action=added Indicates the passed valve-id/run-minutes was added to the queue at the passed request-index position. action=changed Indicates the passed valve-id had it's run-minutes changed to the value included in run-minutes= action=removed Indicates the passed request-index was removed from the queue. action=time-uodate Indicates the remaining time for a request has changed. Includes the valve-id/run-minutes and remaining-minutes