{"id":13585858,"url":"https://github.com/edfungus/Crouton","last_synced_at":"2025-04-07T10:32:09.801Z","repository":{"id":49985897,"uuid":"48307720","full_name":"edfungus/Crouton","owner":"edfungus","description":"Crouton MQTT IOT Dashboard","archived":false,"fork":false,"pushed_at":"2021-06-07T02:49:54.000Z","size":19523,"stargazers_count":291,"open_issues_count":17,"forks_count":69,"subscribers_count":30,"default_branch":"master","last_synced_at":"2024-11-06T03:43:57.127Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://crouton.mybluemix.net/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edfungus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-20T04:53:16.000Z","updated_at":"2024-08-09T07:46:55.000Z","dependencies_parsed_at":"2022-09-06T01:11:09.920Z","dependency_job_id":null,"html_url":"https://github.com/edfungus/Crouton","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edfungus%2FCrouton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edfungus%2FCrouton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edfungus%2FCrouton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edfungus%2FCrouton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edfungus","download_url":"https://codeload.github.com/edfungus/Crouton/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247636961,"owners_count":20971036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T15:05:11.292Z","updated_at":"2025-04-07T10:32:07.856Z","avatar_url":"https://github.com/edfungus.png","language":"Python","funding_links":[],"categories":["Visualization, Dashboards","Python","Data Visualization"],"sub_categories":["Misc","Android Things"],"readme":"[Crouton](http://crouton.mybluemix.net/)\n================\n\n[![Join the chat at https://gitter.im/edfungus/Crouton](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/edfungus/Crouton?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nhttp://crouton.mybluemix.net/\n\nCrouton is a dashboard that lets you visualize and control your IOT devices with minimal setup. Essentially, it is the easiest dashboard to setup for any IOT hardware enthusiast using only MQTT and JSON.\n\n* Makes IOT devices easy to use\n* No frontend knowledge needed\n* Flexible for wide variety of devices\n* Compatible with devices that use MQTT\n* Easy to use interface\n* It is FREE!\n\n\nRunning the Project\n--------------\n\n```\n  $ git clone https://github.com/edfungus/Crouton.git\n  $ npm install\n  $ grunt\n```\n\n\nGetting Started\n--------------\n\nTo start, we will need a **device** and a **MQTT Broker**. Don't have either? No worries, because we have several demo options for you!\n\n### The Device\n\nThe device can be anything from hardware (ESP8266) to a Python script. As long as the device can use the MQTT protocol and encode/decode JSON, then it will work as a device. While this guide is not about setting up specific devices, we do have reference links for the ESP8266 and Python MQTT libraries.\n\n##### ESP8266\n\nIf you are using LUA scripting, then the Nodemcu Firmware has MQTT and JSON capabilities already built.\n\n\u003eESP8266 Lua [Nodemcu documentation on Github](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en)\n\nSample code for the ESP8266 which included a togglable and dimmable light. Refer to the [*/client/* directory](https://github.com/edfungus/Crouton/tree/master/clients) page for more details.\n\n##### Python\n\nThe package we suggest to use for Python client is [paho-mqtt](http://www.eclipse.org/paho/). It has the necessary MQTT libraries to get up and running.\n\n\u003ePython MQTT library: [Paho-mqtt](http://www.eclipse.org/paho/)\n\nSample code for Python dummy client which includes most of the dashboard elements. Refer to the [*/client/* directory](https://github.com/edfungus/Crouton/tree/master/clients) page for more details.\n\n##### Test Clients\n\nIn addition to the sample code above, we have a always running (we try!) test client under the name \"crouton-demo\" on the \"test.mosquitto.org\" public broker. The status of the device can be checked [here](http://crouton-demo-client.mybluemix.net/). And of course, check out the [getting started](/crouton/gettingStarted) for more details.\n\n\u003eDemo page detailing [Crouton test clients](http://crouton.mybluemix.net/crouton/gettingStarted)\n\n### MQTT Broker\n\nMQTT Broker takes care of delivering messages to its clients via a publish and subscribe model. The MQTT Broker required for Crouton *must support web sockets*. Web sockets allow Crouton to connect to it. While there are free options to download and run your own MQTT Broker, there are also free to use public MQTT Brokers that are already set up. We default to Mosquitto's publicly hosted broker.\n\n\u003eFree downloadable brokers:\n\u003e[Mosquitto](http://mosquitto.org/),\n\u003e[Emqttd](http://emqtt.io/)\n\u003e\n\u003eFree publicly hosted brokers:\n\u003e[Mosquitto](http://test.mosquitto.org/),\n\u003e[HiveMQ](http://www.hivemq.com/try-out/)\n\n\nRemember, Crouton must connect to the web socket port of the MQTT Broker, while devices will usually connect to the regular port.\n\nIn the future, we plan to have Crouton's own MQTT Broker which will have better up time and security in comparison to public brokers.\n\nHow it Works\n==============\n\nAfter getting a device and a broker, we simply need to hook everything up. The beauty of Crouton is that, like the device, *Crouton is also a client to the same MQTT Broker.* As a result, Crouton does not rely on any additional centralized server than does your MQTT device. In fact, Crouton is purely a frontend application with no backend services.\n\n![MQTT diagram with Crouton and devices](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/mqtt.png)\n\nBeing a distributed system, like the one shown above, connection between the device and Crouton is only via the MQTT Broker. The communication between Crouton and the device is defined by a protocol that utilizes addresses and MQTT's last will and testament (LWT) feature.\n\nOnce Crouton and and the device are connected to the same MQTT Broker, we can use Crouton to initiate the connection to the device. The device will in turn send a JSON describing itself known as the deviceInfo to Crouton.\n\n\nConnecting to Crouton\n--------------\n\nFirst, have Crouton and the device connected to the same MQTT Broker. The connection between the device and Crouton will be initiated from Crouton, therefore the device needs to subscribe to its own inbox.\n\n```\nDevice should subscribe to the following:\n/inbox/[the device name]/deviceInfo\n```\n\nEvery time the device successfully connects to the MQTT Broker, it should publish its *deviceInfo*. This is needed for auto-reconnection. If Crouton is waiting for the device to connect, it will listen for the *deviceInfo* when the device comes back online.\n\n```\nDevice should publish deviceInfo JSON once connected\n/outbox/[the device name]/deviceInfo\n```\n\n### DeviceInfo\n\nThe deviceInfo is the primary method for Crouton to understand the device. It is the first message the device will send to Crouton to establish connection and also the message that describes the device and values to Crouton. The primary object is *deviceInfo*. Within *deviceInfo* there are several keys as follows:\n\n```json\n{\n  \"deviceInfo\": {\n    \"name\": \"Kroobar\",\n    \"endPoints\": {\n      \"barDoor\": {\n        \"title\": \"Bar Main Door\",\n        \"card-type\": \"crouton-simple-text\",\n        \"units\": \"people entered\",\n        \"values\": {\n            \"value\": 34\n        }\n      }\n    },\n    \"description\": \"Kroobar's IOT devices\",\n    \"status\": \"good\"\n  }\n}\n```\n\n* \\*name: A string that is the name for the device. This is same name you would use to add the device\n* \\**endPoints*: An object that configures each dashboard element Crouton will show. There can be more than one endPoint which would be key/object pairs within *endPoints*\n* *description*: A string that describes the device (for display to user only)\n* *status*: A string that describes the status of the device (for display to user only)\n\n**Note**: Both *name* and *endPoints* are required and must be unique to other *names* or *endPoints* respectively\n\n### Addresses\n\nAddresses are what Crouton and the device will publish and subscribe to. They are also critical in making the communication between Crouton and the devices accurate therefore there is a structure they should follow.\n\nAn address can be broken up into 3 sections.\n\n```\n/[inbox or outbox]/[device name]/[endPoint name]\n```\n\n* *inbox or outbox*: The box is relative to the device. Inbox is for messages going *to* the device and outbox is for messages *from* the device\n* *device name*: The name of the device the are targeting; from *name* key/value pair of *deviceInfo*\n* *endPoint name*: The name of the endPoint the are targeting; from the key used in the key/object pair in *endPoints*\n\n**Note**: All addresses must be unique to one MQTT Broker. Therefore issues could be encounter when using public brokers where there are naming conflicts.\n\n### Updating device values\n\nUpdating device values can come from Crouton or the device. The message payload will be a JSON that updates the value. This JSON will be equivalent to the object of the key *values* within each endPoint. However, only values that are being updated needs to be updated. All other values must be updated by the deviceInfo JSON.\n\n```json\nPayload: {\"value\": 35}\n\nAn entry in endPoints:\n\"barDoor\": {\n  \"title\": \"Bar Main Door\",\n  \"card-type\": \"crouton-simple-text\",\n  \"units\": \"people entered\",\n  \"values\": {\n      \"value\": 34\n  }\n}\n```\n\n##### From Crouton\n\nCrouton has the ability to update the value of the device's endPoints via certain dashboard cards. Therefore the device needs to be subscribe to certain addresses detailed in the Endpoints section below. The payload from Crouton is in the same format as the one coming from the device.\n\n```\nAddress: /inbox/Kroobar/barDoor\nPayload: {\"value\": 35}\n```\n\n##### From Device\n\nTo update values on Crouton from the device, simply publish messages to the outbox of the endPoint which Crouton is already subscribed to. The payload is just the same as the one coming from Crouton.\n\n```\nAddress: /outbox/Kroobar/barDoor\nPayload: {\"value\": 35}\n```\n\n### Last will and testament (LWT)\n\nIn order for Crouton to know when the device has unexpectedly disconnected, the device must create a LWT with the MQTT Broker. This a predefined broadcast that the broker will publish on the device's behalf when the device disconnects. The payload in this case can be anything as long as the address is correct.\n\n```\nAddress: /outbox/Kroobar/lwt\nPayload: anything\n```\n\n**Note**: No endPoints can be named lwt; they will conflict in the name space.\n\n### Endpoints\n\nA device can have multiple endPoints. Each endPoint represents a dashboard card that will be displayed on the dashboard.\n\nThe device must subscribe to the inbox of each endPoint which may receive values from Crouton. For example, a toggle switch on Crouton may change a value on the device therefore a subscription is necessary; however, an alert button which sends only messages from device to Crouton may not need a subscription because the device does not expect any values from Crouton.\n\n```\nSubscription address for endPoints on device:\n/inbox/[device name]/[endpoint name]\n```\n\nUpon receiving a new value from Crouton, the device **must** send back the new value or the appropriate value back to Crouton. This is because Crouton will not reflect the new value change *unless* it is coming from the device.\n\nTherefore the value shown on Crouton more accurately reflects the value on the device.\n\n```\nAddress: /outbox/[device name]/[endpoint name]\nPayload: {\"value\": \"some new value here\"}\n```\n\nDashboard Cards\n==============\n\nDashboard cards are visual and control elements which allow interaction with connected devices. By simply adding a new endPoint in the deviceInfo JSON, a new dashboard card will be automatically generated upon connection. They strive to do several things:\n\n* Provide a visual experience for IOT devices\n* Modularity allows different combinations of different devices\n* Simplicity of define functionality for each type of card\n* Reflect the latest real value of the device\n\nThe type of dashboard card for each endPoint is specified in the object of the endPoint under the key *card-type*. The *values* object is the object that is sent between Crouton and the device to keep values up-to-date. Both of these fields are required for each endPoint.\n\n```json\n\"barDoor\": {\n  ...\n  \"card-type\": \"crouton-simple-text\",\n  \"values\": {\n    ...\n  }\n  ...\n}\n```\n\nAny icons used come from [Font Awesome](https://fortawesome.github.io/Font-Awesome/icons/) and utilizes the same name for the icons.\n\nAlso, new cards are always coming so keep the suggestions coming!\n\n## Simple cards\n\nSimple cards are basic cards that have only one value. Therefore if they are buttons, inputs, etc, there will only be one button, inputs, etc per card. Their functionality are fairly limited but by using multiple cards together, they can still be powerful. All simple card have the same prefix.\n\n```\nSimple card prefix:\ncrouton-simple-[card type]\n```\n\n### Simple Text\n\n![Crouton-simple-text](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-simple-text.png) \u003c/br\u003e Simple text is used to display a value (text or number) on the dashboard from the device to Crouton.\n\n```json\nDevice -\u003e Crouton\nName: crouton-simple-text\n\nExample:\n\"barDoor\": {\n  \"units\": \"people entered\", [optional]\n  \"values\": {\n    \"value\": 34 [required]\n  },\n  \"card-type\": \"crouton-simple-text\", [required]\n  \"title\": \"Bar Main Door\" [optional]\n}\n```\n\n### Simple Input\n\n![Crouton-simple-input](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-simple-input.png) \u003c/br\u003e Simple input is similar to simple text except the user can update the value on the device from Crouton. There is no length restriction of the value by Crouton.\n\n```json\nDevice \u003c-\u003e Crouton\nName: crouton-simple-input\n\nExample:\n\"customMessage\": {\n  \"values\": {\n    \"value\": \"Happy Hour is NOW!\" [required]\n  },\n  \"card-type\": \"crouton-simple-input\", [required]\n  \"title\": \"Billboard Message\" [optional]\n}\n```\n\n### Simple Slider\n\n![Crouton-simple-slider](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-simple-slider.png) \u003c/br\u003e Simple slider allows the user to select continuous values within a given range. Both the large number and the slider will attempt the give the real device value at all times except when the user is sliding.\n\n```json\nDevice \u003c-\u003e Crouton\nName: crouton-simple-slider\n\nExample:\n\"barLightLevel\": {\n  \"values\": {\n    \"value\": 30 [required]\n  },\n  \"min\": 0, [required]\n  \"max\": 100, [required]\n  \"units\": \"percent\", [optional]\n  \"card-type\": \"crouton-simple-slider\", [required]\n  \"title\": \"Bar Light Brightness\" [optional]\n}\n```\n\n### Simple Button\n\n![Crouton-simple-button](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-simple-button.png) \u003c/br\u003e Simple button is one directional, sending a signal (with no meaningful value) from Crouton to the device. However, this is still a bi-directional card because the button is only enable if value is *true*. If the device updates the value of the card to *false*, the button will be disabled.\n\n```json\nDevice \u003c-\u003e Crouton\nName: crouton-simple-button\n\nExample:\n\"lastCall\": {\n  \"values\": {\n    \"value\": true [required]\n  },\n  \"icons\": {\n    \"icon\": \"bell\" [required]\n  },\n  \"card-type\": \"crouton-simple-button\", [required]\n  \"title\": \"Last Call Bell\" [optional]\n}\n```\n\n### Simple Toggle\n\n![Crouton-simple-toggle](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-simple-toggle.png) \u003c/br\u003e Simple toggle allows a boolean value to be changed by both Crouton and the device. In the larger value display, priority for display is icon, labels, boolean text. If no labels or icons are given, the words true and false will be used. The labels around the toggle is only defined by *labels* object.\n\n```json\nDevice \u003c-\u003e Crouton\nName: crouton-simple-toggle\n\nExample:\n\"backDoorLock\": {\n  \"values\": {\n    \"value\": false [required]\n  },\n  \"labels\":{ [optional]\n    \"true\": \"Locked\",\n    \"false\": \"Unlocked\"\n  },\n  \"icons\": { [optional]\n    \"true\": \"lock\",\n    \"false\": \"lock\"\n  },\n  \"card-type\": \"crouton-simple-toggle\", [required]\n  \"title\": \"Employee Door\" [optional]\n}\n```\n\n\n## Chart cards\n\nThese cards are for charts!\n\n### Donut Chart\n\n![Crouton-chart-donut-1](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-chart-donut-1.png)\n\n![Crouton-chart-donut-1](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-chart-donut-2.png)\n\n\u003c/br\u003e A fairly flexible pie chart. The *labels* and *series* (values) are in arrays. The labels are optional (must have at least an empty array) and will not show if empty. *message* is displayed in the center of the donut. *centerSum* (defualt is false) sums up all of the values and replaces *message*. *total* is the value that will fill up the complete circle. If sum of *series* is beyond *total*, the extra parts will be truncated.\n\n```json\nDevice -\u003e Crouton\nName: crouton-chart-donut\n\nExample:\n\"drinksOrdered\": {\n  \"values\": {\n    \"labels\": [\"Scotch\",\"Rum \u0026 Coke\",\"Shiner\",\"Margarita\", \"Other\"], [required]\n    \"series\": [10,20,30,10,30], [required]\n    \"message\": \"\" [optional]\n  },\n  \"total\": 100, [required]\n  \"card-type\": \"crouton-chart-donut\",\n  \"title\": \"Drinks Ordered\" [optional]\n},\n\"occupancy\": {\n  \"values\": {\n    \"labels\": [], [required]\n    \"series\": [76] [required]\n  },\n  \"total\": 100, [required]\n  \"centerSum\": true, [optional]\n  \"units\": \"%\", [optional]\n  \"card-type\": \"crouton-chart-donut\", [required]\n  \"title\": \"Occupancy\" [optional]\n}\n```\n\n### Line Chart\n\n![Crouton-chart-line](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-chart-line.png)\n\n\u003c/br\u003e A simple line chart with multiple lines available. The *labels* corresponds to the x axis values and the *series* corresponds to the y axis values. Multiple sets of (x,y) values can be passed at once as long as the array length of labels and series are matched. The reason why series is multidimensional is so that multiple lines can be drawn where each array in series corresponds to a line. The *update* parameter is expected on update and holds a copy of *values* with the new *labels* and *series* within. *Max* refers to the maximum number of data points based on the x axis is shown. *low* and *high* refers to the maximum y values expected.\n\n*It is suggested that labels and series be prepopulated with one set of (x,y) value for each line*\n\n```json\nDevice -\u003e Crouton\nName: crouton-chart-line\n\nExample:\n\"temperature\": {\n    \"values\": {\n        \"labels\": [1],  [required]\n        \"series\": [[60]],  [required]\n        \"update\": null  [required]  \n    },\n    \"max\": 11, [required]\n    \"low\": 58,  [required]\n    \"high\": 73,  [required]\n    \"card-type\": \"crouton-chart-line\",  [required]\n    \"title\": \"Temperature (F)\" [optional]\n}\n\n3 lines and 1 value:\n\"values\": {\n    \"labels\": [1],\n    \"series\": [[60],[2],[543]],\n    \"update\": null  \n}\n\n3 lines and 2 values:\n\"values\": {\n    \"labels\": [1,2],\n    \"series\": [[60,62],[2,4],[543,545]],\n    \"update\": null  \n}\n\nTo update temperature:\n\"values\": {\n    \"labels\": null,\n    \"series\": null,\n    \"update\": {\n      \"labels\" : [2],\n      \"series\": [[62]]\n    }\n}\n```\n\n\n## Advanced cards\n\nThese cards are a little bit more specific to certain applications.\n\n### RGB Slider\n\n![Crouton-rgb-slider](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-rgb-slider.png) \u003c/br\u003e RGB slider is three combined slider for the specific application of controlling a RGB led. Prepopulate the values for red, green and blue by setting in values.\n\n```json\nDevice \u003c-\u003e Crouton\nName: crouton-rgb-slider\n\nExample:\n\"discoLights\": {\n  \"values\": {\n    \"red\": 0, [required]\n    \"green\": 0, [required]\n    \"blue\": 0 [required]\n  },\n  \"min\": 0, [required]\n  \"max\": 255, [required]\n  \"card-type\": \"crouton-rgb-slider\", [required]\n  \"title\": \"RGB Lights\" [optional]\n}\n```\n\n### Youtube Stream\n\n![crouton-video-youtube](https://raw.githubusercontent.com/edfungus/Crouton/master/public/common/images/crouton-video-youtube.png) \u003c/br\u003e (Thank you [wickwire](https://github.com/wickwire) for this addition) \u003c/br\u003e Add a Youtube video or livestream to your dashboard. This is great for having a dashboard of various security cameras.\n\n```json\nDevice - Crouton\nName: crouton-video-youtube\n\nExample:\n\"youTubeStream\": {\n  \"values\": {\n      \"youtubeID\": \"GZnb3jQ2YZo\" [required]\n  },\n  \"card-type\": \"crouton-video-youtube\", [required]\n  \"title\": \"YouTube Stream\" [optional]\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedfungus%2FCrouton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedfungus%2FCrouton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedfungus%2FCrouton/lists"}