Join us online for the "Hey Google" Smart Home Summit on July 8th! Register here to learn what's new, and what's coming up for Google Smart Home.

Smart Home FanSpeed Trait Schema

action.devices.traits.FanSpeed - This trait belongs to devices that support setting the speed of a fan (that is, blowing air from the device at various levels, which may be part of an air conditioning or heating unit, or in a car), with settings such as low, medium, and high.

Device ATTRIBUTES

Attribute Definition
availableFanSpeeds
  • speeds Array containing the name of each speed and a subarray for speed_values with language-specific synonyms. For example, the speed_name "S4" could correspond to the speed_synonym strings "highest" and "maximum" given the language code "en".
    • speed_name String. Internal name of the mode, which will be used in commands and states. This can be non-user-friendly, and will be shared across all languages.
    • speed_values Contains names and supported languages:
      • speed_synonym Strings. User-friendly names for the speed, in each language supported.
      • lang String. Supported language for the names (see Supported Languages/Language Codes).
  • ordered Boolean. If set to true, additional grammar for increase/decrease logic will apply, in the order (increasing) of the speeds array.
reversible Boolean. If set to true, this device supports blowing the fan in both directions and can accept the command to reverse fan direction.
supportsFanSpeedPercent Boolean. If set to true, this device will accept commands for adjusting the speed using a percentage from 0.0 to 100.0. Defaults to false.
commandOnlyFanSpeed Boolean. Optional. Defaults to false. Indicates if the device supports using one-way (true) or two-way (false) communication. Set this attribute to true if the device cannot respond to a QUERY intent or Report State for this trait.

Example:

{
  "availableFanSpeeds": {
    "speeds": [{
      "speed_name": "S1",
      "speed_values": [{
        "speed_synonym": ["low", "speed 1", ... ],
        "lang": "en" } , … ]
      },
      {
      "speed_name": "S2",
      "speed_values": [{
        "speed_synonym": ["high", "speed 2", ... ],
         "lang": "en" } , … ]
      }, ...
      ],
    "ordered": true
    },
  "supportsFanSpeedPercent": true,
  "reversible": true
}

Sample SYNC Request and Response

Request
{
    "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    "inputs": [{
      "intent": "action.devices.SYNC"
    }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onSync((body, headers) => {
  return {
    requestId: body.requestId,
    payload: {
      agentUserId: '1836.15267389',
      devices: [{
        id: '123',
        type: 'action.devices.types.FAN',
        traits: [
          'action.devices.traits.FanSpeed'
        ],
        name: {
          defaultNames: ['Sirius Cybernetics Corporation 33321'],
          name: 'Fan',
          nicknames: ['wall fan']
        },
        willReportState: true,
        attributes: {
          availableFanSpeeds: {
            speeds: [{
              speed_name: 'Low',
              speed_values: [{
                speed_synonym: ['low', 'slow'],
                lang: 'en'
              }, {
                speed_synonym: ['low', 'slow'],
                lang: 'de'
              }]
            }, {
              speed_name: 'High',
              speed_values: [{
                speed_synonym: ['high'],
                lang: 'en'
              }, {
                speed_synonym: ['high'],
                lang: 'de'
              }]
            }],
            ordered: true
          },
          reversible: true
        },
        deviceInfo: {
          manufacturer: 'Sirius Cybernetics Corporation',
          model: '233451',
          hwVersion: '3.2',
          swVersion: '11.4'
        },
        customData: {
          fooValue: 74,
          barValue: true,
          bazValue: 'lambtwirl'
        }
      }]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
public SyncResponse onSync(@NotNull SyncRequest syncRequest, @Nullable Map<?, ?> headers) {
  Payload payload = new Payload();
  payload.setAgentUserId("1836.15267389");
  payload.setDevices(
      new SyncResponse.Payload.Device[] {
        new SyncResponse.Payload.Device.Builder()
            .setId("123")
            .setType("action.devices.types.FAN")
            .addTrait("action.devices.traits.OnOff")
            .addTrait("action.devices.traits.FanSpeed")
            .setName(
                Collections.singletonList("Sirius Cybernetics Corporation 33321"),
                "Fan",
                Collections.singletonList("wall fan"))
            .setWillReportState(true)
            .setAttributes(
                new JSONObject()
                    .put(
                        "availableFanSpeeds",
                        new JSONObject()
                            .put(
                                "speeds",
                                new JSONObject[] {
                                  new JSONObject()
                                      .put("speed_name", "Low")
                                      .put(
                                          "speed_values",
                                          new JSONObject[] {
                                            new JSONObject()
                                                .put(
                                                    "speed_synonym", new String[] {"low", "slow"})
                                                .put("lang", "en"),
                                            new JSONObject()
                                                .put(
                                                    "speed_synonym",
                                                    new String[] {"niedrig", "schleppend"})
                                                .put("lang", "de")
                                          }),
                                  new JSONObject()
                                      .put("speed_name", "High")
                                      .put(
                                          "speed_values",
                                          new JSONObject[] {
                                            new JSONObject()
                                                .put("speed_synonym", new String[] {"high"})
                                                .put("lang", "en"),
                                            new JSONObject()
                                                .put("speed_synonym", new String[] {"hoch"})
                                                .put("lang", "de")
                                          })
                                })
                            .put("ordered", true))
                    .put("reversible", true))
            .setDeviceInfo("Sirius Cybernetics Corporation", "492134", "3.2", "11.4")
            .setCustomData(
                new JSONObject()
                    .put("fooValue", 74)
                    .put("barValue", true)
                    .put("bazValue", "lambtwirl")
                    .toString())
            .build()
      });
  return new SyncResponse(syncRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "agentUserId": "1836.15267389",
    "devices": [
      {
        "id": "123",
        "type": "action.devices.types.FAN",
        "traits": [
          "action.devices.traits.FanSpeed"
        ],
        "name": {
          "defaultNames": [
            "Sirius Cybernetics Corporation 33321"
          ],
          "name": "Fan",
          "nicknames": [
            "wall fan"
          ]
        },
        "willReportState": true,
        "attributes": {
          "availableFanSpeeds": {
            "speeds": [
              {
                "speed_name": "Low",
                "speed_values": [
                  {
                    "speed_synonym": [
                      "low",
                      "slow"
                    ],
                    "lang": "en"
                  },
                  {
                    "speed_synonym": [
                      "low",
                      "slow"
                    ],
                    "lang": "de"
                  }
                ]
              },
              {
                "speed_name": "High",
                "speed_values": [
                  {
                    "speed_synonym": [
                      "high"
                    ],
                    "lang": "en"
                  },
                  {
                    "speed_synonym": [
                      "high"
                    ],
                    "lang": "de"
                  }
                ]
              }
            ],
            "ordered": true
          },
          "reversible": true
        },
        "deviceInfo": {
          "manufacturer": "Sirius Cybernetics Corporation",
          "model": "233451",
          "hwVersion": "3.2",
          "swVersion": "11.4"
        },
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "lambtwirl"
        }
      }
    ]
  }
}
Validator

Device STATES

State Definition
currentFanSpeedSetting String. Required. This represents the name of the current speed setting of the device with the action.devices.traits.FanSpeed trait (for example, "S2").
currentFanSpeedPercent Float. Required. Required if the device supports commands for adjusting the fan speed using a percent. Valid values are from 0.0 to 100.0, and indicates the current fan speed by percentage.

Sample QUERY Request and Response

What speed are the fans in the living room?
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": 'action.devices.QUERY',
    "payload": {
      "devices": [{
        "id": "123",
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "foo"
        }
      }]
    }
  }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onQuery((body, headers) => {
  return {
    requestId: body.requestId,
    payload: {
      devices: {
        123: {
          on: true,
          online: true,
          currentFanSpeedSetting: 'S2',
          status: 'SUCCESS'
        },
        456: {
          on: true,
          online: true,
          currentFanSpeedSetting: 'S1',
          status: 'SUCCESS'
        }
      }
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
public QueryResponse onQuery(@NotNull QueryRequest queryRequest, @Nullable Map<?, ?> map) {
  QueryResponse.Payload payload = new QueryResponse.Payload();
  payload.setDevices(
      new HashMap<String, Map<String, Object>>() {
        {
          put(
              "123",
              new HashMap<String, Object>() {
                {
                  put("on", true);
                  put("online", true);
                  put("currentFanSpeedSetting", "S2");
                  put("status", "SUCCESS");
                }
              });
          put(
              "456",
              new HashMap<String, Object>() {
                {
                  put("on", true);
                  put("online", true);
                  put("currentFanSpeedSetting", "S1");
                  put("status", "SUCCESS");
                }
              });
        }
      });

  return new QueryResponse(queryRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "devices": {
      "123": {
        "on": true,
        "online": true,
        "currentFanSpeedSetting": "S2",
        "status": "SUCCESS"
      },
      "456": {
        "on": true,
        "online": true,
        "currentFanSpeedSetting": "S1",
        "status": "SUCCESS"
      }
    }
  }
}

Device COMMANDS

Command Parameters/Definition
action.devices.commands.SetFanSpeed Set the fan speed. Valid parameters include:
  • fanSpeed: String representing the name of the requested speed of the fan (for example, "S2").
  • fanSpeedPercent: Float value in the range of [0.0, 100.0] that represents the requested speed setting percentage.
action.devices.commands.SetFanSpeedRelativeSpeed Set the fan speed by a relative amount. This command is only available if the commandOnlyFanSpeed attribute is set to true. Valid parameters include:
  • fanSpeedRelativeWeight: Integer in the range of[-5,5]. This value indicates the relative amount of the speed change (for example: "lower a little", "raise a lot"). The absolute value 0 to 5 indicates the scaled amount (from small to large), while the numerical sign indicates the direction of the change.
  • fanSpeedRelativePercent: Float value in the range of [-100.0, 100.0]. This value represents the percentage of speed to change (for example: "increase speed by 20%").
action.devices.commands.Reverse Reverses the fan direction. This command is sent only if the reversible attribute is set to true.

Sample EXECUTE Request and Response

Set the fan to low.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "lambtwirl"
          }
        }],
        "execution": [{
          "command": "action.devices.commands.SetFanSpeed",
          "params": {
            "fanSpeed": "S1"
          }
        }]
      }]
    }
  }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onExecute((body, headers) => {
  return {
    requestId: body.requestId,
    payload: {
      commands: [{
        ids: ['123'],
        status: 'SUCCESS',
        states: {
          currentFanSpeedSetting: 'S1'
        }
      }]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
public ExecuteResponse onExecute(
    @NotNull ExecuteRequest executeRequest, @Nullable Map<?, ?> map) {
  ExecuteResponse.Payload payload = new ExecuteResponse.Payload();
payload.setCommands(
    new Commands[] {
      new Commands(
          new String[] {"123"},
          "SUCCESS",
          new HashMap<String, Object>() {
            {
              put("currentFanSpeedSetting", "S1");
            }
          },
          null,
          null)
    });
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "currentFanSpeedSetting": "S1"
        }
      }
    ]
  }
}
Turn the bedroom fan to maximum.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "lambtwirl"
          }
        }],
        "execution": [{
          "command": "action.devices.commands.SetFanSpeed",
          "params": {
            "fanSpeed": "S2"
          }
        }]
      }]
    }
  }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onExecute((body, headers) => {
  return {
    requestId: body.requestId,
    payload: {
      commands: [{
        ids: ['123'],
        status: 'SUCCESS',
        states: {
          currentFanSpeedSetting: 'S2'
        }
      }]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
public ExecuteResponse onExecute(
    @NotNull ExecuteRequest executeRequest, @Nullable Map<?, ?> map) {
  ExecuteResponse.Payload payload = new ExecuteResponse.Payload();
payload.setCommands(
    new Commands[] {
      new Commands(
          new String[] {"123"},
          "SUCCESS",
          new HashMap<String, Object>() {
            {
              put("currentFanSpeedSetting", "S2");
            }
          },
          null,
          null)
    });
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "currentFanSpeedSetting": "S2"
        }
      }
    ]
  }
}

Device ERRORS

See the full list of errors and exceptions.
  • maxSpeedReached: The device is already set to the maximum speed.
  • minSpeedReached: The device is already set to the minimum speed.