How to create a custom mobile app with Habit Analytics
Before starting any coding, please access to our Selfcare to setup your project and get all the needed information to setup on your Custom mobile app.
Authentication
In order to interact with our API, clients must authenticate using the OAuth 2.0 protocol, in particular the Resource Owner Password Credentials flow.
Account creation with mail (without mail validation)
A POST call must be made using the /v3/legacy/account endpoint, providing the following parameters:
appId, corresponding to the pre-generated client_id that you should get from your previously created project on Selfcare
device, indicating if is and 'android' or 'ios'
email, indicating your user's mail
name, indicating your user's name
password, indicating your user's password
type, should always be 'account'
The response will be populated with several attributes, mainly authToken and id (that corresponds to the user-id).
Call POST /v3/legacy/account
Request (application/json)
{
"appId":"{application-namespace}",
"device":"{android|ios}",
"email":"{user-mail}",
"name":"{user-name}",
"password":"{password}",
"type":"account"
}
Response 200 (application/json)
{
"message":"user created and signed in",
"success":true,
"user":{
"authToken":"{token}",
"clientId":"{mobile-application-client-id}",
"email":"{user-mail}",
"id":"{user-id}",
"name":"{user-name}",
"newUser":true,
"photoUrl":"https:\/\/cdn.muzzley.com\/users\/default.png",
"token":"{access-token}"
}
}
A GET call to /v3/auth/authorize should be immediately done to obtain all the other needed authentication information.
The response will be populated with, at least, 4 main attributes:
access_token, the actual token to be used in subsequent calls
expires, the validity of the returned tokens
refresh_token, for refreshing this information, before expires is reached
endpoints, an object containing the HTTP and MQTT base URLs assigned to the requesting client
Call GET /v3/auth/authorize
Request parameters:
response_type **should be password (required, string)
scope should be application,user (required, string)
client_id is your application client-id generated by Selfcare (required, string)
username (required, string)
password (required, string)
Response 200 (application/json)
{
"_id":"\/v3\/tokens\/{token}",
"access_token":"{token}",
"client_id":"{client-id}",
"code":"{code}",
"created":"2020-03-17T15:52:52.484+0000",
"endpoints":
{
"http":"https:\/\/api.platform.muzzley.com",
"mqtt":"mqtts:\/\/api.platform.muzzley.com:8881",
"uploader":"https:\/\/assets.ci.habit.io"
},
"expires":"2020-06-15T15:52:51.618+0000",
"grant_type":"password",
"href":"\/v3\/tokens\/{token}",
"id":"{id}",
"owner_id":"{user-id}",
"refresh_token":"{refresh-token}",
"scope":["application","user"],
"updated":"2020-03-17T15:52:52.484+0000"
}
For this first 2 calls the host to be used should be https://api.platform.muzzley.com/ but all subsequent calls must be directed to the base URL provided in endpoints.http and an Authorization header must be added to every API call, in the form:
Authorization: Bearer {access_token}
Account Sign in with the mail
The response will be populated with, at least, 4 main attributes:
access_token, the actual token to be used in subsequent calls
expires, the validity of the returned tokens
refresh_token, for refreshing this information, before expires is reached
endpoints, an object containing the HTTP and MQTT base URLs assigned to the requesting client
Call GET /v3/auth/authorize
Request parameters:
client_id (required, string)
refresh_token (required, string)
grant_type (required, string)
redirect_uri (optional, string)
Response 200 (application/json)
{
"_id":"\/v3\/users\/{user-id}",
"_rev":"3-94c1450541b80ec43c7503d7b2ec8e6c",
"active_ts":"2019-05-24T09:58:16.824+0000",
"cdata":null,
"confirmation_hash":"qweqweqwe",
"created":"2019-05-24T09:58:15.841+0000",
"email":"{user-mail}",
"href":"\/v3\/users\/{user-id}",
"id":"{user-id}",
"inactive_ts":"1970-01-01T00:00:00.000+0000",
"name":"{user-name}",
"namespace":"qweqweqwe",
"secret":"qweqweqwe",
"state":"active",
"target_id":"{applciation-client-id}",
"type":"users",
"updated":"2019-05-24T09:58:16.825+0000"
}
API Usage
For this first call the host to be used should be https://api.platform.muzzley.com/ but all subsequent calls must be directed to the base URL provided in endpoints.http and an Authorization header must be added to every API call, in the form:
Authorization: Bearer {access_token}
Retrieve User
The response will be populated with, at least, 4 main attributes:
id, the user ID
name, the user full name
namespace, unique user namespace
state, state of the user in the platform
target_id, application ID that the user belongs
Call GET /v3/users/[me|:user-id]
Response 200 (application/json)
{
"_id":"\/v3\/users\/{user-id}",
"_rev":"3-94c1450541b80ec43c7503d7b2ec8e6c",
"active_ts":"2019-05-24T09:58:16.824+0000",
"cdata":null,
"confirmation_hash":"qweqweqwe",
"created":"2019-05-24T09:58:15.841+0000",
"email":"{user-mail}",
"href":"\/v3\/users\/{user-id}",
"id":"{user-id}",
"inactive_ts":"1970-01-01T00:00:00.000+0000",
"name":"{user-name}",
"namespace":"qweqweqwe",
"secret":"qweqweqwe",
"state":"active",
"target_id":"{application-id}",
"type":"users",
"updated":"2019-05-24T09:58:16.825+0000"
}
List User Channels
Channel Instance Ontology:
profileId : Profile id of the database document.
channelId : Channel instance id.
component : An array of the parts that make up the actual channel instance.
id : Component id such as "bulb-3"
type : Component type (described in the channel spec).
label : Channel component label such as "Nightstand Left".
property : An array of properties listed in the channel spec.
Call GET /v3/legacy/users/{user-id}/channels
Request parameters:
include (optional, string) # ex: channelProperties,context,capabilities
Response 200 (application/json)
{
"_id":"\/v3\/legacy\/users\/{user-id}\/channels",
"_rev":"9-3d8b450212eafb9a9e02e192349b6a8b",
"channels":[
{
"_rev":"3-66beebb3261617dee4d80a789563bbd2",
"categories":[
"5478934836f3f24465ca061d"
],
"components":[
{
"classes":[
"com.muzzley.components.sensor.smoke"
],
"id":"smoke_sensor",
"label":"Smoke Detector",
"type":"smoke_sensor"
}
],
"content":"Device",
"id":"9fc96b08-c654-11e8-8567-000d3a38a46d",
"interface":{
"etag":"0",
"native":[
],
"src":"",
"url":"",
"uuid":"bf76f033-d36a-4ce2-af5e-9208ddd3b7e0"
},
"isActionable":false,
"isStateful":false,
"isTriggerable":true,
"photoUrl":"https:\/\/cdn.muzzley.com\/things\/profiles\/nest-v3\/allianz\/allianz-nest-protect-centered.jpg",
"profileId":"3a200576-04e1-11e8-9059-6e8e8fac3ec8",
"properties":[
{
"actions":[
],
"agentLabel":"",
"classes":[
"com.muzzley.properties.level.power.battery"
],
"components":[
"smoke_sensor"
],
"controlInterfaces":[
{
"config":{
"options":[
{
"label":"OK",
"value":"ok"
},
{
"label":"Replace",
"value":"replace"
},
{
"label":"Low",
"value":"low"
},
{
"label":"Full",
"value":"full"
}
]
},
"controlInterface":"text-picker",
"id":"ci1"
}
],
"id":"battery_health",
"io":"rs",
"isActionable":false,
"isStateful":false,
"isTriggerable":true,
"label":"Batterie",
"mainActionPriority":0,
"mainInformationPriority":0,
"onChange":false,
"rateLimit":0,
"requiredCapabilities":[
],
"schema":"https:\/\/ontology.muzzley.com\/schemas\/v1\/battery-status-string",
"schemaExtension":{
},
"states":[
],
"triggers":[
{
"condition":"equals",
"id":"3054a645-3ddf-48e5-9cf3-6956ea68264e",
"inputs":[
{
"controlInterfaceId":"ci1",
"id":"value",
"path":[
{
"source":"selection.value",
"target":"data.value"
}
]
}
],
"inputsLabel":"{{value}}",
"label":"",
"predicateLabel":"is equal to"
}
],
"unitsOptions":{
"muzzleyUnit":"",
"targetImperial":"",
"targetMetric":""
}
},
{
"actions":[
],
"agentLabel":"",
"classes":[
"com.muzzley.properties.status.co",
"com.muzzley.properties.status.co"
],
"components":[
"smoke_sensor"
],
"controlInterfaces":[
{
"config":{
"options":[
{
"label":"OK",
"value":"ok"
},
{
"label":"Warning",
"value":"warning"
},
{
"label":"Emergency",
"value":"emergency"
}
]
},
"controlInterface":"text-picker",
"id":"ci1"
}
],
"id":"co_status",
"io":"rs",
"isActionable":false,
"isStateful":false,
"isTriggerable":true,
"label":"Statut CO",
"mainActionPriority":0,
"mainInformationPriority":0,
"onChange":false,
"rateLimit":0,
"requiredCapabilities":[
],
"schema":"https:\/\/ontology.muzzley.com\/schemas\/v1\/alarm-status",
"schemaExtension":{
},
"states":[
],
"triggers":[
{
"condition":"equals",
"id":"170547a5-9dc1-4f10-9328-5ba034d5e02a",
"inputs":[
{
"controlInterfaceId":"ci1",
"id":"value",
"path":[
{
"source":"selection.value",
"target":"data.value"
}
]
}
],
"inputsLabel":"{{value}}",
"label":"",
"predicateLabel":"is equal to"
}
],
"unitsOptions":{
"muzzleyUnit":"",
"targetImperial":"",
"targetMetric":""
}
},
{
"actions":[
],
"agentLabel":"",
"classes":[
"com.muzzley.properties.status.smoke"
],
"components":[
"smoke_sensor"
],
"controlInterfaces":[
{
"config":{
"options":[
{
"label":"OK",
"value":"ok"
},
{
"label":"Warning",
"value":"warning"
},
{
"label":"Emergency",
"value":"emergency"
}
]
},
"controlInterface":"text-picker",
"id":"ci1"
}
],
"id":"smoke_status",
"io":"rs",
"isActionable":false,
"isStateful":false,
"isTriggerable":true,
"label":"Statut Fum\u00e9e",
"mainActionPriority":0,
"mainInformationPriority":0,
"onChange":false,
"rateLimit":0,
"requiredCapabilities":[
],
"schema":"https:\/\/ontology.muzzley.com\/schemas\/v1\/alarm-status",
"schemaExtension":{
},
"states":[
],
"triggers":[
{
"condition":"equals",
"id":"51ed5e32-633a-49b6-9f84-8d6d358812cc",
"inputs":[
{
"controlInterfaceId":"ci1",
"id":"value",
"path":[
{
"source":"selection.value",
"target":"data.value"
}
]
}
],
"inputsLabel":"{{value}}",
"label":"",
"predicateLabel":"is equal to"
}
],
"unitsOptions":{
"muzzleyUnit":"",
"targetImperial":"",
"targetMetric":""
}
},
{
"actions":[
],
"agentLabel":"",
"classes":[
"com.muzzley.properties.status.color"
],
"components":[
"smoke_sensor"
],
"controlInterfaces":[
],
"id":"color_status",
"io":"rs",
"isActionable":false,
"isStateful":false,
"isTriggerable":false,
"label":"Statut de Couleur",
"mainActionPriority":0,
"mainInformationPriority":0,
"onChange":false,
"rateLimit":0,
"requiredCapabilities":[
],
"schema":"https:\/\/ontology.muzzley.com\/schemas\/v1\/color-name",
"schemaExtension":{
},
"states":[
],
"triggers":[
],
"unitsOptions":{
"muzzleyUnit":"",
"targetImperial":"",
"targetMetric":""
}
}
],
"remoteId":"9fc96b08-c654-11e8-8567-000d3a38a46d",
"tilePhotoUrl":"https:\/\/cdn.muzzley.com\/things\/profiles\/nest-v3\/nest-smoke_center.jpg",
"user":"{user-id}"
}
],
"href":"\/v3\/legacy\/users\/{user-id}\/channels",
"id":"channels"
}
List User Tiles
Tiles are meant to represent a visual rendering of the most important properties and actions that physical devices can have, like a temperature reading, or an on/off switch.
Call GET /v3/legacy/users/{user-id}/tiles
Request parameters:
include (optional, string) # ex: specs
Response 200 (application/json)
{
"tiles":[
{
"_rev":"2-2cb3794172f6a8acd45607d176292c0e",
"actions":[
],
"channel":"{channel-id}",
"channelInfo":{
"backgroundPhotoUrl":"https:\/\/cdn.nest-protect-tiles.jpg",
"id":"{id}",
"photoUrl":"https:\/\/cdn.nest-protect-tiles.jpg",
"profileId":"{channeltemplate-id}",
"remoteId":"{remote-id}"
},
"components":[
{
"id":"smoke_sensor",
"type":"smoke_sensor"
}
],
"groups":[
"{group-id}"
],
"href":"\/v3\/legacy\/tiles\/{tile-id}",
"id":"{tile-id}",
"information":[
{
"componentType":"smoke_sensor",
"options":{
"inputPath":"data.value",
"mathExpression":"x * 100",
"prefix":"",
"suffix":"%"
},
"property":"battery_health",
"type":"text-expression"
}
],
"isGroupable":false,
"kind":"device",
"label":"Device",
"overlayUrl":"",
"photoUrl":"https:\/\/cdn.nest-protect-tiles.jpg",
"photoUrlAlt":"https:\/\/cdn.nest-protect-tiles.jpg",
"profile":"{channeltemplate-id}",
"user":"{user-id}"
},
{
"_rev":"2-7d3cbf7f7647b28ccb9a95c4366d530a",
"actions":[
],
"channel":"{channel-id}",
"channelInfo":{
"backgroundPhotoUrl":"https:\/\/cdn.nest_thermostat_left.jpg",
"id":"{id}",
"photoUrl":"https:\/\/cdn.nest_thermostat_left.jpg",
"profileId":"{channeltemplate-id}",
"remoteId":"{remote-id}"
},
"components":[
{
"id":"thermostat",
"type":"thermostat"
}
],
"groups":[
"{group-id}"
],
"href":"\/v3\/legacy\/tiles\/{tile-id}",
"id":"{tile-id}",
"information":[
{
"componentType":"thermostat",
"options":{
"inputPath":"data.value",
"mathExpression":"x * 100",
"prefix":"",
"suffix":"%"
},
"property":"humidity",
"type":"text-expression"
},
{
"componentType":"thermostat",
"options":{
"inputPath":"data.value",
"inputUnit":"C"
},
"property":"environment_temperature",
"type":"text-unit"
}
],
"isGroupable":false,
"kind":"device",
"label":"Device",
"overlayUrl":"",
"photoUrl":"https:\/\/cdn/nest_thermostat_left.jpg",
"photoUrlAlt":"https:\/\/cdn/nest_thermostat_left.jpg",
"profile":"{channeltemplate-id}",
"user":"{user-id}"
},
{
"_id":"\/v3\/legacy\/tiles\/{tile-id}",
"_rev":"1-d1780bc8367d83cd4dbea3c97a1bfe13",
"actions":[
{
"componentType":"light-bulb",
"options":{
"icon":"on_off",
"mappings":{
"off":false,
"on":true
},
"outputPath":"data.value"
},
"property":"status",
"type":"tri-state"
}
],
"channel":"{channel-id}",
"channelInfo":{
"backgroundPhotoUrl":"https:\/\/cdn\/allianz-hue-left.jpg",
"id":"{id}",
"photoUrl":"https:\/\/cdn\/allianz-hue-left.jpg",
"profileId":"{channeltemplate-id}",
"remoteId":"{remote-id}"
},
"components":[
{
"id":"light-bulb",
"type":"light-bulb"
}
],
"groups":[
"{group-id}"
],
"href":"\/v3\/legacy\/tiles\/{tile-id}",
"id":"{tile-id}",
"information":[
{
"componentType":"light-bulb",
"options":{
"char":"\ue600",
"format":"hsv"
},
"property":"color",
"type":"icon-color"
},
{
"componentType":"light-bulb",
"options":{
"inputPath":"data.value",
"mathExpression":"x * 100",
"prefix":"",
"suffix":"%"
},
"property":"brightness",
"type":"text-expression"
}
],
"isGroupable":true,
"kind":"device",
"label":"office light",
"overlayUrl":"https:\/\/cdn.\/muzzley_label_fr.png",
"photoUrl":"https:\/\/cdn\/allianz-hue-left.jpg",
"photoUrlAlt":"https:\/\/cdn\/allianz-hue-left.jpg",
"profile":"{channeltemplate-id}",
"user":"{user-id}"
}
]
}
Units Table
The Units table is needed to determine which conversions between metric and imperial systems are needed. Some devices output their measurements in either metric or imperial system, and conversion is done on-device, according to user preferences.
Response 200 (application/json)
{
"version":"1",
"unitSpec":{
"celsius":{
"name":{
"singular":"celsius",
"plural":"celsius"
},
"prefix":"",
"suffix":" °C",
"decimalPlaces":1,
"unitSystem":"metric",
"public":true
},
"millimeter":{
"name":{
"singular":"millimeter",
"plural":"millimeters"
},
"prefix":"",
"suffix":" mm",
"decimalPlaces":2,
"unitSystem":"metric"
},
"centimeter":{
"name":{
"singular":"centimeter",
"plural":"centimeters"
},
"prefix":"",
"suffix":" cm",
"decimalPlaces":2,
"unitSystem":"metric"
},
"meter":{
"name":{
"singular":"meter",
"plural":"meters"
},
"prefix":"",
"suffix":" m",
"decimalPlaces":1,
"unitSystem":"metric",
"public":true
},
"kilometer":{
"name":{
"singular":"kilometer",
"plural":"kilometers"
},
"prefix":"",
"suffix":" km",
"decimalPlaces":1,
"unitSystem":"metric"
},
"milligram":{
"name":{
"singular":"milligram",
"plural":"milligrams"
},
"prefix":"",
"suffix":" mg",
"decimalPlaces":2,
"unitSystem":"metric"
},
"gram":{
"name":{
"singular":"gram",
"plural":"grams"
},
"prefix":"",
"suffix":" gr",
"decimalPlaces":1,
"unitSystem":"metric",
"public":true
},
"kilogram":{
"name":{
"singular":"kilogram",
"plural":"kilograms"
},
"prefix":"",
"suffix":" kg",
"decimalPlaces":1,
"unitSystem":"metric"
},
"milliliter":{
"name":{
"singular":"milliliter",
"plural":"milliliters"
},
"prefix":"",
"suffix":" ml",
"decimalPlaces":2,
"unitSystem":"metric"
},
"liter":{
"name":{
"singular":"liter",
"plural":"liters"
},
"prefix":"",
"suffix":" l",
"decimalPlaces":1,
"unitSystem":"metric",
"public":true
},
"lp100km":{
"name":{
"singular":"liters per 100 kilometers",
"plural":""
},
"prefix":"",
"suffix":" l/100km",
"decimalPlaces":1,
"unitSystem":"metric"
},
"kmpl":{
"name":{
"singular":"kilometers per liter",
"plural":""
},
"prefix":"",
"suffix":" km/L",
"decimalPlaces":1,
"unitSystem":"metric",
"public":true
},
"mps":{
"name":{
"singular":"meters per second",
"plural":""
},
"prefix":"",
"suffix":" m/s",
"decimalPlaces":1,
"unitSystem":"metric",
"public":true
},
"kmph":{
"name":{
"singular":"kilometers per hour",
"plural":""
},
"prefix":"",
"suffix":" km/h",
"decimalPlaces":0,
"unitSystem":"metric"
},
"watt":{
"name":{
"singular":"watt",
"plural":"watts"
},
"prefix":"",
"suffix":" W",
"decimalPlaces":4,
"unitSystem":"metric",
"public":true
},
"kilowatt":{
"name":{
"singular":"kilowatt",
"plural":"kilowatts"
},
"prefix":"",
"suffix":" kW",
"decimalPlaces":2,
"unitSystem":"metric"
},
"mbar":{
"name":{
"singular":"millibar",
"plural":"millibars"
},
"prefix":"",
"suffix":" mbar",
"decimalPlaces":1,
"unitSystem":"metric",
"public":true
},
"bar":{
"name":{
"singular":"bar",
"plural":"bars"
},
"prefix":"",
"suffix":" bar",
"decimalPlaces":0,
"unitSystem":"metric"
},
"pascal":{
"name":{
"singular":"pascal",
"plural":"pascals"
},
"prefix":"",
"suffix":" Pa",
"decimalPlaces":0,
"unitSystem":"metric"
},
"volt":{
"name":{
"singular":"volt",
"plural":"volts"
},
"prefix":"",
"suffix":" V",
"decimalPlaces":0,
"unitSystem":"metric"
},
"ampere":{
"name":{
"singular":"ampere",
"plural":"amperes"
},
"prefix":"",
"suffix":" A",
"decimalPlaces":3,
"unitSystem":"metric"
},
"hertz":{
"name":{
"singular":"hertz",
"plural":"hertz"
},
"prefix":"",
"suffix":" Hz",
"decimalPlaces":0,
"unitSystem":"metric"
},
"kph":{
"name":{
"singular":"kilowatt hour",
"plural":"kilowatts hour"
},
"prefix":"",
"suffix":" kWh",
"decimalPlaces":0,
"unitSystem":"metric"
},
"fahrenheit":{
"name":{
"singular":"fahrenheit",
"plural":"fahrenheit"
},
"prefix":"",
"suffix":" °F",
"decimalPlaces":1,
"unitSystem":"imperial"
},
"inch":{
"name":{
"singular":"inch",
"plural":"inches"
},
"prefix":"",
"suffix":" in",
"decimalPlaces":2,
"unitSystem":"imperial"
},
"foot":{
"name":{
"singular":"foot",
"plural":"feet"
},
"prefix":"",
"suffix":" ft",
"decimalPlaces":2,
"unitSystem":"imperial"
},
"yard":{
"name":{
"singular":"yard",
"plural":"yards"
},
"prefix":"",
"suffix":" yd",
"decimalPlaces":2,
"unitSystem":"imperial"
},
"mile":{
"name":{
"singular":"mile",
"plural":"miles"
},
"prefix":"",
"suffix":" mi",
"decimalPlaces":2,
"unitSystem":"imperial"
},
"grain":{
"name":{
"singular":"grain",
"plural":"grains"
},
"prefix":"",
"suffix":" gr",
"decimalPlaces":2,
"unitSystem":"imperial"
},
"ounce":{
"name":{
"singular":"ounce",
"plural":"ounces"
},
"prefix":"",
"suffix":" oz",
"decimalPlaces":2,
"unitSystem":"imperial"
},
"pound":{
"name":{
"singular":"pound",
"plural":"pounds"
},
"prefix":"",
"suffix":" lb",
"decimalPlaces":1,
"unitSystem":"imperial"
},
"gallon":{
"name":{
"singular":"gallon",
"plural":"gallons"
},
"prefix":"",
"suffix":" gal",
"decimalPlaces":2,
"unitSystem":"imperial"
},
"mpg":{
"name":{
"singular":"miles per gallon",
"plural":""
},
"prefix":"",
"suffix":" mpg",
"decimalPlaces":0,
"unitSystem":"imperial"
},
"mpgus":{
"name":{
"singular":"miles per gallon (US)",
"plural":""
},
"prefix":"",
"suffix":" mpg (US)",
"decimalPlaces":0,
"unitSystem":"imperial"
},
"fps":{
"name":{
"singular":"feet per second",
"plural":""
},
"prefix":"",
"suffix":" fps",
"decimalPlaces":0,
"unitSystem":"imperial"
},
"mph":{
"name":{
"singular":"miles per hour",
"plural":""
},
"prefix":"",
"suffix":" mph",
"decimalPlaces":1,
"unitSystem":"imperial"
},
"horsepower":{
"name":{
"singular":"horsepower",
"plural":"horsepowers"
},
"prefix":"",
"suffix":" hp",
"decimalPlaces":4,
"unitSystem":"imperial"
},
"psi":{
"name":{
"singular":"pounds per square inch",
"plural":""
},
"prefix":"",
"suffix":" psi",
"decimalPlaces":1,
"unitSystem":"imperial"
},
"inhg":{
"name":{
"singular":"inches of mercury",
"plural":""
},
"prefix":"",
"suffix":" inHg",
"decimalPlaces":1,
"unitSystem":"imperial"
},
"mmhg":{
"name":{
"singular":"blood pressure",
"plural":""
},
"prefix":"",
"suffix":" mmHg",
"decimalPlaces":0
},
"kelvin":{
"name":{
"singular":"kelvin",
"plural":"kelvins"
},
"prefix":"",
"suffix":" °K",
"decimalPlaces":0
},
"lux":{
"name":{
"singular":"lux",
"plural":"lux"
},
"prefix":"",
"suffix":" lx",
"decimalPlaces":0
},
"millisecond":{
"name":{
"singular":"millisecond",
"plural":"milliseconds"
},
"prefix":"",
"suffix":" ms",
"decimalPlaces":0
},
"second":{
"name":{
"singular":"second",
"plural":"seconds"
},
"prefix":"",
"suffix":" s",
"decimalPlaces":0
},
"hour":{
"name":{
"singular":"hour",
"plural":"hours"
},
"prefix":"",
"suffix":" h",
"decimalPlaces":0
},
"minute":{
"name":{
"singular":"minute",
"plural":"minutes"
},
"prefix":"",
"suffix":" min",
"decimalPlaces":0
},
"lumen":{
"name":{
"singular":"lumen",
"plural":"lumens"
},
"prefix":"",
"suffix":" lm",
"decimalPlaces":0
},
"rpm":{
"name":{
"singular":" revolutions per minute",
"plural":""
},
"prefix":"",
"suffix":" r/min",
"decimalPlaces":0
},
"bpm":{
"name":{
"singular":"beats per minute",
"plural":"beats per minute"
},
"prefix":"",
"suffix":" bpm",
"decimalPlaces":0
},
"spo2":{
"name":{
"singular":"pulse oximetry",
"plural":""
},
"prefix":"",
"suffix":" SpO2",
"decimalPlaces":0
},
"ppm":{
"name":{
"singular":"parts per million",
"plural":"parts per millions"
},
"prefix":"",
"suffix":" ppm",
"decimalPlaces":0
},
"decibel":{
"name":{
"singular":"decibel",
"plural":"decibels"
},
"prefix":"",
"suffix":" dB",
"decimalPlaces":0
},
"mgdl":{
"name":{
"singular":"milligrams per deciliter",
"plural":"milligrams per deciliters"
},
"prefix":"",
"suffix":" mg/dL",
"decimalPlaces":0
},
"calorie":{
"name":{
"singular":"calorie",
"plural":"calories"
},
"prefix":"",
"suffix":" cal",
"decimalPlaces":0
}
},
"unitCalc":{
"from":{
"to":"expression"
},
"fahrenheit":{
"celsius":"(x - 32) / 1.8"
},
"inch":{
"millimeter":"x / 0.03937",
"centimeter":"x / 0.3937"
},
"feet":{
"centimeter":"x / 30.5"
},
"yard":{
"meter":"x * 0.9144",
"kilometer":"x * 0.0009144",
"mile":"x / 1760"
},
"mile":{
"kilometer":"x / 0.6214",
"meter":"x * 1609.34",
"yard":"x * 1760"
},
"meter":{
"kilometer":"x * 0.001",
"yard":"x / 0.9144",
"mile":"x / 1609.34"
},
"kilometer":{
"meter":"x * 1000",
"yard":"x * 1093.61",
"mile":"x * 0.621371"
},
"grain":{
"milligram":"x * 0.015432358"
},
"ounce":{
"gram":"x / 0.03527"
},
"pound":{
"kilogram":"x / 2.2046"
},
"gallon":{
"liter":"x * 4.5"
},
"mpg":{
"kmpl":"x * 0.354006"
},
"mpgus":{
"kmpl":"x * 0.4251"
},
"fps":{
"mps":"x * 0.3048"
},
"mph":{
"kmph":"x * 1.609344",
"mps":"x * 0.44704"
},
"horsepower":{
"watt":"x * 745.7",
"kilowatt":"x * 0.7457"
},
"kilowatt":{
"watt":"x * 1000",
"horsepower":"x / 0.7457"
},
"watt":{
"kilowatt":"x / 1000",
"horsepower":"x / 745.7"
},
"psi":{
"bar":"x * 0.0689476",
"mbar":"x * 68.9476"
},
"inhg":{
"mbar":"x * 33.8639"
},
"celsius":{
"fahrenheit":"(x * 1.8) + 32"
},
"millimeter":{
"inch":"x * 0.03937"
},
"centimeter":{
"inch":"x * 0.3937",
"foot":"x / 30.5"
},
"milligram":{
"grain":"x * 0.015432358"
},
"gram":{
"ounce":"x * 0.03527"
},
"kilogram":{
"pound":"x * 2.2046"
},
"liter":{
"gallon":"x / 4.5"
},
"kmpl":{
"mpgus":"x / 0.4251",
"mpg":"x / 0.354006"
},
"mps":{
"fps":"x / 0.3048",
"mph":"x / 0.44704"
},
"kmph":{
"mph":"x / 1.609344"
},
"bar":{
"psi":"x / 0.0689476"
},
"mbar":{
"psi":"x / 68.9476",
"inhg":"x / 33.8639"
},
"second":{
"hour":"x/3600"
}
}
}
Last updated