\n \n );\n }\n}\n\n\nFTPServerFlow.propTypes = {\n classes: PropTypes.object.isRequired,\n}\n\nexport default withStyles(styles)(FTPServerFlow)\n","import React from 'react'\nimport {Link} from 'gatsby'\n\nimport Paper from '@material-ui/core/Paper'\nimport Typography from '@material-ui/core/Typography'\n\nimport { OutboundLink } from 'gatsby-plugin-google-analytics'\n\nimport SEOHelmet from '../../../../../components/Layout/SEOHelmet'\nimport Footer from \"../../../../../components/Layout/footer\"\nimport BreadCrumbs from '../../../../../components/Layout/breadcrumbs/breadcrumbs'\nimport LiveVideoFlow from '../../../../../components/Advanced_User/Node-RED_and_MQTT/Projects/Live_Video/live-video'\n\nimport UIOverview from '../../../../../assets/images/Advanced_User/Node-RED_OpenHAB_Projects_Live_Video_01.png'\nimport OpenHabSitemap from '../../../../../assets/images/Advanced_User/Node-RED_OpenHAB_Projects_Live_Video_03.png'\n\nconst seodata = {\n title: 'Home Automation :: Display your Camera\\'s Live Video Stream using Node-RED',\n description: 'We want to be able to display a JPG Stream of Images from the live video in the Node-RED dashboard.',\n image: '/images/Search/AU_SearchThumb_Node-RED.png'\n}\n\nconst imgStyle = {\n marginBottom: '-0.4rem',\n};\n\nexport default (props) => (\n \n \n \n Home Automation with Node-RED and OpenHAB\n \n \n\n\n \n \n
\n
Home Automation with Node-RED and OpenHAB
\n
\n
Live Video Stream
\n
Bonus :: OpenHAB Integration
\n
\n
\n \n \n \n Live Video Stream\n \n \n \n The screenshot below shows the final UI that we are going to build using Node-RED and the Node-RED Dashboard. We want to be able to display a JPG Stream of Images from the live video in the Node-RED dashboard.\n \n \n \n \n \n \n \n \n We are going to use the node-red-contrib-mjpgcamera plugin that can be installed from Manage Palette menu in our Node-RED dashboard. The plugin is grabbing single frames from one of the 3 MJPEG Streams that our camera offers and saves them to the public directory we created earlier. We then use a Watch Node to load the image every time it was updated, add a timestamp to its name - this is to trick your browser, that would refuse to reload the image, when the image name stays the same, thinking it was already loaded - and load it into our Node-RED dashboard.\n \n \n \n \n \n \n Bonus :: OpenHAB Integration\n \n \n \n Adding to the OpenHAB tutorial we are now going to consume the Node-RED flow in our OpenHAB 2 Basic UI.\n \n \n \n \n \n \n \n \n {`Image url=\"http://localhost:1880/352snap.jpg\" label=\"Camera Video Snapshot\" refresh=30000`}\n \n \n \n The refresh rate (in Milliseconds) can be adjusted to your needs. We have adjusted the MJEPG plugin in our Node-RED flow to grab a new frame from the 352p stream every 20s that will be displayed in the Node-RED Dashboard. The refresh value in the line above will update the image in the OpenHAB UI every 30s.\n \n \n \n \n \n);","module.exports = function () {\n var selection = document.getSelection();\n\n if (!selection.rangeCount) {\n return function () {};\n }\n\n var active = document.activeElement;\n var ranges = [];\n\n for (var i = 0; i < selection.rangeCount; i++) {\n ranges.push(selection.getRangeAt(i));\n }\n\n switch (active.tagName.toUpperCase()) {\n // .toUpperCase handles XHTML\n case 'INPUT':\n case 'TEXTAREA':\n active.blur();\n break;\n\n default:\n active = null;\n break;\n }\n\n selection.removeAllRanges();\n return function () {\n selection.type === 'Caret' && selection.removeAllRanges();\n\n if (!selection.rangeCount) {\n ranges.forEach(function (range) {\n selection.addRange(range);\n });\n }\n\n active && active.focus();\n };\n};","module.exports = __webpack_public_path__ + \"static/Node-RED_OpenHAB_Projects_Live_Video_01-00e664fcbf1ccf1e6f41aed82199d880.png\";","\"use strict\";\n\nvar _require = require('./Component'),\n CopyToClipboard = _require.CopyToClipboard;\n\nCopyToClipboard.CopyToClipboard = CopyToClipboard;\nmodule.exports = CopyToClipboard;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.CopyToClipboard = void 0;\n\nvar _react = _interopRequireDefault(require(\"react\"));\n\nvar _copyToClipboard = _interopRequireDefault(require(\"copy-to-clipboard\"));\n\nfunction _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n \"default\": obj\n };\n}\n\nfunction _typeof(obj) {\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function _typeof(obj) {\n return typeof obj;\n };\n } else {\n _typeof = function _typeof(obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n}\n\nfunction ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n if (enumerableOnly) symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n });\n keys.push.apply(keys, symbols);\n }\n\n return keys;\n}\n\nfunction _objectSpread(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i] != null ? arguments[i] : {};\n\n if (i % 2) {\n ownKeys(source, true).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n });\n } else if (Object.getOwnPropertyDescriptors) {\n Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n } else {\n ownKeys(source).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n }\n\n return target;\n}\n\nfunction _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n\n var target = _objectWithoutPropertiesLoose(source, excluded);\n\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n }\n\n return _assertThisInitialized(self);\n}\n\nfunction _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n\nfunction _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) _setPrototypeOf(subClass, superClass);\n}\n\nfunction _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nvar CopyToClipboard = /*#__PURE__*/function (_React$PureComponent) {\n _inherits(CopyToClipboard, _React$PureComponent);\n\n function CopyToClipboard() {\n var _getPrototypeOf2;\n\n var _this;\n\n _classCallCheck(this, CopyToClipboard);\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(CopyToClipboard)).call.apply(_getPrototypeOf2, [this].concat(args)));\n\n _defineProperty(_assertThisInitialized(_this), \"onClick\", function (event) {\n var _this$props = _this.props,\n text = _this$props.text,\n onCopy = _this$props.onCopy,\n children = _this$props.children,\n options = _this$props.options;\n\n var elem = _react[\"default\"].Children.only(children);\n\n var result = (0, _copyToClipboard[\"default\"])(text, options);\n\n if (onCopy) {\n onCopy(text, result);\n } // Bypass onClick if it was present\n\n\n if (elem && elem.props && typeof elem.props.onClick === 'function') {\n elem.props.onClick(event);\n }\n });\n\n return _this;\n }\n\n _createClass(CopyToClipboard, [{\n key: \"render\",\n value: function render() {\n var _this$props2 = this.props,\n _text = _this$props2.text,\n _onCopy = _this$props2.onCopy,\n _options = _this$props2.options,\n children = _this$props2.children,\n props = _objectWithoutProperties(_this$props2, [\"text\", \"onCopy\", \"options\", \"children\"]);\n\n var elem = _react[\"default\"].Children.only(children);\n\n return _react[\"default\"].cloneElement(elem, _objectSpread({}, props, {\n onClick: this.onClick\n }));\n }\n }]);\n\n return CopyToClipboard;\n}(_react[\"default\"].PureComponent);\n\nexports.CopyToClipboard = CopyToClipboard;\n\n_defineProperty(CopyToClipboard, \"defaultProps\", {\n onCopy: undefined,\n options: undefined\n});"],"sourceRoot":""}