diff --git a/.env b/.env
deleted file mode 100644
index a515357..0000000
--- a/.env
+++ /dev/null
@@ -1,19 +0,0 @@
-# Project name
-COMPOSE_PROJECT_NAME=fiware
-
-# Orion variables
-ORION_PORT=1026
-ORION_VERSION=3.11.0
-
-# MongoDB variables
-MONGO_DB_PORT=27017
-MONGO_DB_VERSION=6.0
-
-# IoT Agent JSON Variables
-JSON_VERSION=2.4.0-distroless
-IOTA_NORTH_PORT=4041
-IOTA_SOUTH_PORT=7896
-
-# Tutorial variables
-TUTORIAL_APP_PORT=3000
-TUTORIAL_DUMMY_DEVICE_PORT=3001
\ No newline at end of file
diff --git a/.gitpod.yml b/.gitpod.yml
deleted file mode 100644
index 6fb63c9..0000000
--- a/.gitpod.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-tasks:
- - name: Pull Images
- init: ./services create
-
-ports:
- - name: Orion
- description: Context Broker
- port: 1026
- onOpen: notify
- - name: Wilma
- description: PEP Proxy
- port: 1027
- onOpen: ignore
- - name: Tutorial App
- description: Web app displaying context data
- port: 3000
- onOpen: open-preview
- - name: Tutorial Devices
- description: Dummy IoT Sensors over HTTP
- port: 3001
- onOpen: ignore
- - name: Keyrock
- description: Identity Manager
- port: 3005
- onOpen: open-preview
- - name: MySQL
- description: Database for Keyrock
- port: 3306
- onOpen: ignore
- - name: IoT Agent (North Port)
- description: NGSI data and device provisioning
- port: 4041
- onOpen: ignore
- - name: IoT Agent (South Port)
- description: Ultralight HTTP measures
- port: 7896
- onOpen: ignore
- - name: MongoDB
- description: Database for Orion + IoT Agent
- port: 27017
- onOpen: ignore
\ No newline at end of file
diff --git a/README.es.md b/README.es.md
deleted file mode 100644
index b0164e6..0000000
--- a/README.es.md
+++ /dev/null
@@ -1,620 +0,0 @@
-[![FIWARE Banner](https://fiware.github.io/tutorials.Edge-Computing/img/fiware.png)](https://www.fiware.org/developers)
-[![NGSI v2](https://img.shields.io/badge/NGSI-v2-5dc0cf.svg)](https://fiware-ges.github.io/orion/api/v2/stable/)
-
-[![FIWARE Context processing, analysis and visualisation](https://nexus.lab.fiware.org/static/badges/chapters/processing.svg)](https://github.com/FIWARE/catalogue/blob/master/processing/README.md)
-
-
-Este es un tutorial introductorio para [FIWARE FogFlow](https://fogflow.readthedocs.io/en/latest/) que permite a sus
-usuarios para orquestar dinámicamente los flujos de procesamiento en los bordes. Explica cómo habilitar el FogFlow en
-una sistema de nodos, registrar los patrones de carga de trabajo definidos por el usuario y orquestarlos en los bordes
-en forma de tareas de ejecución. Para mejor comprensión, se han incluido ejemplos en el tutorial.
-
-## Contenido
-
-
-Detalles
-
-- [Arquitectura](#arquitectura)
- - [Arquitectura de capas](#arquitectura-de-capas)
-- [Start Up](#start-up)
- - [Nodo de nubes FogFlow](#nodo-de-nubes-fogflow)
- - [Nodo FogFlow Edge](#nodo-fogflow-edge)
-- [Conectar los dispositivos de IO a FogFlow](#conectar-los-dispositivos-de-io-a-fogflow)
-- [Orquestación dinámica en los bordes usando FogFlow](#orquestacion-dinamica-en-los-bordes-usando-fogflow)
- - [Definir y activar una función de niebla](#definir-y-activar-una-funcion-de-niebla)
- - [Registrar los operadores de la tarea](#registrar-los-operadores-de-la-tarea)
- - [Definir una función de niebla "dummy"](#definir-una-funcion-de-niebla-dummy)
- - [Desencadenar la función de niebla "dummy"](#desencadenar-la-funcion-de-niebla-dummy)
- - [Definir y activar una topología de servicio](#definir-y-activar-una-topologia-de-servicio)
- - [Implementar las funciones del operador](#implementar-las-funciones-del-operador)
- - [Especifique la topología del servicio](#especifique-la-topologia-del-servicio)
- - [Activar la topología de servicio mediante el envío de una intención](#activar-la-topologia-de-servicio-mediante-el-envio-de-una-intencion)
-
-
-
-# Computación en el borde de la nube
-
-La intención del tutorial es enseñar a sus usuarios cómo los dispositivos de sensores de IO envían datos de contexto a
-FogFlow, cuando y donde FogFlow inicia un flujo de procesamiento para alterar el ambiente a través de dispositivos
-actuadores. La siguiente figura muestra un visión general del escenario. Los sensores, los actuadores y los flujos de
-procesamiento dinámico se explican en las secciones de seguimiento en este tutorial, que se relacionan con la figura de
-abajo.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fogflow-overall-view.png)
-
-1. El usuario proporciona su escenario a FogFlow, que incluye qué hacer, cuándo hacer. FogFlow averiguará dónde hacer.
-2. Los sensores envían regularmente datos de contexto a FogFlow. Los datos pueden incluir datos ambientales como la
- temperatura, el video streaming, imágenes, etc.
-3. FogFlow orquesta los flujos de procesamiento en los bordes en poco tiempo. Estos flujos de procesamiento pueden
- cambiar el estado de un o publicar algunos datos en FogFlow, se trata de lo que el usuario quiere hacer.
-
-Material adicional para entender los conocimientos del desarrollador, visite
-[Tutorial de FogFlow](https://fogflow.readthedocs.io/en/latest/introduction.html). FogFlow también puede ser integrado
-con otros GEs de FIWARE.
-
-- [Integrar FogFlow con Scorpio Broker](https://fogflow.readthedocs.io/en/latest/scorpioIntegration.html)
-- [Integrar FogFlow con QuantumLeap](https://fogflow.readthedocs.io/en/latest/QuantumLeapIntegration.html)
-- [Integrar FogFlow con WireCloud](https://fogflow.readthedocs.io/en/latest/wirecloudIntegration.html)
-
-
-
-# Arquitectura
-
-El marco de FogFlow funciona con una infraestructura de TIC geo-distribuida, jerárquica y heterogénea que incluye nodos
-de nube, nodos de borde y dispositivos de IO. La siguiente figura ilustra la arquitectura del sistema de FogFlow y su
-componentes principales a través de tres capas lógicas.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/architecture.png)
-
-## Arquitectura de capas
-
-Lógicamente, FogFlow consiste en las siguientes tres capas:
-
-- **gestión de servicios:** convierte los requisitos de servicio en un plan de ejecución concreto y luego despliega el
- plan de ejecución sobre las nubes y los bordes. Los servicios de Diseñador de Tareas, Maestro de Topología y
- Registro de Dockers juntos componen la capa de gestión de servicios.
-- **gestión de contexto:** gestiona toda la información de contexto y la hace descubrible y accesible mediante una
- consulta flexible y suscribirse a las interfaces. Esta capa consiste en Corredores de Contexto y el Descubrimiento
- de IO.
-- **procesamiento de datos:** lanza tareas de procesamiento de datos y establece flujos de datos entre las tareas a
- través del pub/sub interfaces proporcionadas por la capa de gestión del contexto. Los trabajadores de borde (y por
- supuesto el trabajador de la nube) están bajo esta capa.
-
-# Start Up
-
-Antes de comenzar, debe asegurarse de que ha obtenido o construido las imágenes necesarias de Docker localmente. Por
-favor, clone el y crear las imágenes necesarias ejecutando los comandos como se muestra:
-
-```bash
-git clone https://github.com/FIWARE/tutorials.Edge-Computing.git
-cd tutorials.Edge-Computing
-git checkout NGSI-v2
-
-./services create
-```
-
-A partir de entonces, todos los servicios pueden ser inicializados desde la línea de comandos ejecutando el
-[servicios](https://github.com/FIWARE/tutorials.Edge-Computing/blob/NGSI-v2/services) El guión Bash proporcionado dentro
-de la repositorio:
-
-```bash
-./services start
-```
-
-## Nodo de nubes FogFlow
-
-**Los requisitos previos** para poner en marcha un nodo de nubes son los siguientes:
-
-- **Docker:** Por favor, refiérase...
- [esto](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-16-04) para
- instalación, versión requerida > 18.03.1-ce;
-- **Docker-Compose:** Por favor, refiérase...
- [esto](https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-16-04) para
- instalación, versión necesaria > 2.4.2;
-
-> **Importante:** Por favor, también permita a su usuario ejecutar los comandos del Docker sin sudo.
-
-**Para iniciar la instalación de los servicios de nubes de FogFlow, haga lo siguiente:**
-
-1. Cambie las siguientes direcciones IP en config.json de acuerdo con el entorno actual.
-
- - **coreservice_ip**: dirección IP pública del nodo de nubes FogFlow.
- - **external_hostip**: dirección IP pública del actual nodo de la nube/borde;
- - **internal_hostip**: La dirección IP de la interfaz de la red "docker0" en el nodo actual.
- - **site_id**: una identificación única basada en una cadena para identificar el nodo en el sistema FogFlow;
- - **physical_location**: la geo-localización del nodo;
-
-```json
-{
- "coreservice_ip": "10.156.0.9",
- "external_hostip": "10.156.0.9",
- "internal_hostip": "172.17.0.1",
- "physical_location": {
- "longitude": 139.709059,
- "latitude": 35.692221
- },
- "site_id": "001"
-}
-```
-
-2. Saque las imágenes de los componentes de FogFlow y póngalas en marcha.
-
-```console
- docker-compose pull
- docker-compose up -d
-```
-
-3. Validar la configuración del nodo de nubes de FogFlow a través de cualquiera de estas dos formas:
-
-- Comprobar si todos los contenedores están en funcionamiento usando `docker ps -a`.
-
-```console
- docker ps -a
-```
-
-```text
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 90868b310608 nginx:latest "nginx -g 'daemon of…" 5 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp fogflow_nginx_1
- d4fd1aee2655 fogflow/worker "/worker" 6 seconds ago Up 2 seconds fogflow_cloud_worker_1
- 428e69bf5998 fogflow/master "/master" 6 seconds ago Up 4 seconds 0.0.0.0:1060->1060/tcp fogflow_master_1
- 9da1124a43b4 fogflow/designer "node main.js" 7 seconds ago Up 5 seconds 0.0.0.0:1030->1030/tcp, 0.0.0.0:8080->8080/tcp fogflow_designer_1
- bb8e25e5a75d fogflow/broker "/broker" 9 seconds ago Up 7 seconds 0.0.0.0:8070->8070/tcp fogflow_cloud_broker_1
- 7f3ce330c204 rabbitmq:3 "docker-entrypoint.s…" 10 seconds ago Up 6 seconds 4369/tcp, 5671/tcp, 25672/tcp, 0.0.0.0:5672->5672/tcp fogflow_rabbitmq_1
- 9e95c55a1eb7 fogflow/discovery "/discovery" 10 seconds ago Up 8 seconds 0.0.0.0:8090->8090/tcp fogflow_discovery_1
-```
-
-- Comprueba el estado del sistema desde el FogFlow DashBoard en `http:///index.html`. La página web
- que se mostrará se muestra en la siguiente figura.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dashboard.png)
-
-## Nodo FogFlow Edge
-
-**Los requisitos previos** para poner en marcha un nodo de borde son los siguientes:
-
-- **Docker:** Por favor, refiérase a
- [Instalar Docker CE en Raspberry Pi](https://withblue.ink/2019/07/13/yes-you-can-run-docker-on-raspbian.html).
-
-**Para iniciar la instalación, haga lo siguiente:**
-
-1. Cambiar el archivo de configuración similar al nodo de la nube, pero ahora coreservice_ip se mantendrá uniforme
- porque es la dirección IP del nodo de la nube.
-
-```json
-{
- "coreservice_ip": "10.156.0.9",
- "external_hostip": "10.156.0.10",
- "internal_hostip": "172.17.0.1",
- "physical_location": {
- "longitude": 138.709059,
- "latitude": 36.692221
- },
- "site_id": "002",
-
- "worker": {
- "container_autoremove": false,
- "start_actual_task": true,
- "capacity": 4
- }
-}
-```
-
-2. Inicie el Edge IoT Broker y el FogFlow Worker. Si el nodo de borde está basado en ARM, entonces adjunte armar como
- el comando parámetro.
-
-```console
- ./start.sh
-```
-
-3. Detener tanto al corredor Edge IoT como al trabajador de FogFlow:
-
-```console
- ./stop.sh
-```
-
-# Conectar los dispositivos de IO a FogFlow
-
-Cuando los datos fluyen desde un dispositivo sensor hacia el corredor, se llama flujo hacia el norte, mientras que es
-flujo hacia el sur, cuando los datos fluyen desde el corredor hacia los dispositivos actuadores. FogFlow se basa en este
-flujo de datos bidireccional para realizar la la idea real detrás de esto.
-
-Para recibir datos de los dispositivos sensores, consulte
-[conectar a un dispositivo sensor](https://fogflow.readthedocs.io/en/latest/example3.html). El tutorial contiene
-ejemplos de tanto los dispositivos NGSI como los que no lo son.
-
-FogFlow puede cambiar el estado de los dispositivos actuadores conectados, como por ejemplo, cerrar una puerta, encender
-una lámpara, encender un el escudo se enciende o se apaga, etc. a través de sus flujos de procesamiento dinámico. Para
-**conectarse a un dispositivo actuador**, refiérase a
-[Integrar un dispositivo actuador con FogFlow](https://fogflow.readthedocs.io/en/latest/example5.html). Este tutorial
-también contiene ejemplos de dispositivos NGSI y no NGSI (especialmente, los UltraLight y MQTT).
-
-Para tener una idea básica de cómo funciona realmente Southbound en el contexto de FIWARE, véase
-[este](https://fiware-tutorials.readthedocs.io/en/latest/iot-agent/index.html#southbound-traffic-commands) tutorial.
-
-# Orquestación dinámica en los bordes usando FogFlow
-
-Antes de seguir adelante, los usuarios deben echar un vistazo a lo siguiente:
-
-- [Conceptos básicos](https://fogflow.readthedocs.io/en/latest/concept.html) de FogFlow y
-- [Modelo de programación basado en la intención](https://fogflow.readthedocs.io/en/latest/programming.html)
-
-## Definir y activar una función de niebla
-
-FogFlow permite la computación de borde sin servidor, es decir, los desarrolladores pueden definir y enviar una función
-de niebla junto con el lógica de procesamiento (u operador) y luego el resto será hecho por FogFlow automáticamente,
-incluyendo:
-
-- la activación de la función de niebla presentada cuando sus datos de entrada estén disponibles
-- decidir cuántas instancias se crearán de acuerdo con la granularidad definida
-- decidir dónde desplegar las instancias creadas o los flujos de procesamiento
-
-### Registrar los operadores de la tarea
-
-FogFlow permite a los desarrolladores especificar su propio código de función dentro de un operador registrado. Echa un
-vistazo a algunos [ejemplos](https://github.com/smartfog/fogflow/tree/master/application/operator) para saber cómo crear
-una operador.
-
-Se pueden encontrar plantillas en Python, Java y JavaScript para escribir un operador
-[aquí](https://github.com/FIWARE/tutorials.Edge-Computing/tree/master/templates).
-
-Para el tutorial actual, consulte el
-[código de operador dummy](https://github.com/FIWARE/tutorials.Edge-Computing/tree/master/dummy). Reemplaza lo siguiente
-contenido en el archivo `función.js` y construir la imagen del docker ejecutando el archivo de construcción. Esta imagen
-puede ser usada como operador.
-
-```javascript
-exports.handler = function(contextEntity, publish, query, subscribe) {
- console.log("enter into the user-defined fog function");
-
- var entityID = contextEntity.entityId.id;
-
- if (contextEntity == null) {
- return;
- }
- if (contextEntity.attributes == null) {
- return;
- }
-
- var updateEntity = {};
- updateEntity.entityId = {
- id: "Stream.result." + entityID,
- type: "result",
- isPattern: false
- };
- updateEntity.attributes = {};
- updateEntity.attributes.city = {
- type: "string",
- value: "Heidelberg"
- };
-
- updateEntity.metadata = {};
- updateEntity.metadata.location = {
- type: "point",
- value: {
- latitude: 33.0,
- longitude: -1.0
- }
- };
-
- console.log("publish: ", updateEntity);
- publish(updateEntity);
-};
-```
-
-Los siguientes pasos son necesarios para registrar un operador en Fogflow.
-
-1. **Registrar un Operador** para definir cuál sería el nombre del Operador y qué parámetros de entrada necesitaría. El
- En la siguiente imagen se muestra la lista de todos los operadores registrados.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/operator-list.png)
-
-Para registrar un nuevo operador, haga clic en el botón "registrar", cree un operador y añádale parámetros. Para definir
-el puerto para la aplicación del operador, utilice "service_port" y dé un número de puerto válido como su valor. La
-aplicación sería accesible al mundo exterior a través de este puerto.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/operator-registry.png)
-
-2. **Registra una imagen del muelle y elige Operador** para definir la imagen del muelle y asociar una ya registrada
- Operador con él. La siguiente imagen muestra la lista de imágenes de los estibadores registrados y la información
- clave de cada imagen.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dockerimage-registry-list.png)
-
-Haciendo clic en el botón de "registro", rellene la información requerida y haga clic en el botón de "registro" para
-terminar el registro.
-
-La forma se explica de la siguiente manera.
-
-- **Image:** el nombre de su imagen de operador de muelle, debe ser consistente con la que publica para
- [Docker Hub](https://hub.docker.com/)
-- **Tag:** la etiqueta que usaste para publicar la imagen de tu operador en el muelle; por defecto es "última"
-- **Hardware Type:** el tipo de hardware que la imagen de la plataforma soporta, incluyendo x86 o ARM (por ejemplo,
- Raspberry Pi)
-- **OS Type:** el tipo de sistema operativo que la imagen de tu docker soporta; actualmente esto sólo se limita a
- Linux
-- **Operator:** el nombre del operador, que debe ser único y se utilizará al definir una topología de servicio
-- **Prefetched:** si esto se comprueba, significa que todos los nodos del borde comenzarán a buscar esta imagen del
- muelle por adelantado; de lo contrario, la imagen de la rampa del operador se obtiene bajo demanda, sólo cuando los
- nodos de borde necesitan ejecutar una tarea programada. asociado con este operador.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dockerimage-registry.png)
-
-### Definir una función de niebla "dummy"
-
-Haga clic con el botón derecho del ratón dentro del tablero de diseño de tareas, se desplegará un menú que incluye:
-
-- **Tarea**: se utiliza para definir el nombre de la función de niebla y la lógica de procesamiento (u operador). Una
- tarea tiene entrada y corrientes de salida.
-- **EntityStream**: es el elemento de datos de entrada que se puede vincular con una función de niebla Task como su
- flujo de datos de entrada.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-1.png)
-
-Elija "Tarea", un elemento de la Tarea se colocará en el tablero de diseño, como se muestra a continuación.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-2.png)
-
-Haga clic en el botón de configuración en la esquina superior derecha del elemento de la tarea, como se ilustra en la
-siguiente figura. Especifique el nombre de la Tarea y elija un operador de una lista de algunos operadores registrados
-previamente.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-3.png)
-
-Añade un "EntityStream" del menú emergente al tablero de diseño.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-4.png)
-
-Contiene los siguientes campos:
-
-- **Tipo seleccionado:** se utiliza para definir el tipo de entidad del flujo de entrada cuya disponibilidad
- desencadenará la niebla función.
-- **Atributos seleccionados:** para el tipo de entidad seleccionado, qué atributos de la entidad son requeridos por su
- función de niebla; "todos" significa obtener todos los atributos de la entidad.
-- **Group By:** debe ser uno de los atributos de la entidad seleccionada, que define la granularidad de esta función
- de niebla, es decir, el número de instancias para esta función de niebla. En este ejemplo, la granularidad se define
- por "id", que significa que FogFlow creará una nueva instancia de tarea para cada ID de entidad individual.
-- **Scoped:** dice si los datos de la Entidad son específicos de la ubicación o no. True indica que los datos
- específicos de la ubicación son registrado en la Entidad y Falso se utiliza en el caso de los datos emitidos, por
- ejemplo, alguna regla o dato umbral que es válido para todos los lugares, no para un lugar específico.
-
-Configure el EntityStream haciendo clic en su botón de configuración como se muestra a continuación. "Temperatura" se
-muestra como ejemplo aquí, al igual que el tipo de entidad de datos de entrada para la función de niebla "dummy".
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-5.png)
-
-Puede haber múltiples EntityStreams para una Tarea y deben estar conectados a la Tarea como se muestra a continuación.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-6.png)
-
-Envíe la función de niebla.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-7.png)
-
-### Desencadenar la función de niebla "dummy"
-
-La función de niebla "Dummy" definida se activa sólo cuando se dispone de los datos de entrada necesarios.
-
-Una forma es registrar un dispositivo sensor de "Temperatura" como se muestra a continuación.
-
-Vaya al menú Dispositivo en la pestaña Estado del sistema. Proporcione la siguiente información.
-
-- **Device ID**: para especificar una identificación de entidad única
-- **Device Type**: utilizar "Temperature" como tipo de entidad
-- **Location**: para colocar una ubicación en el mapa
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/device-registration.png)
-
-Una vez registrado el perfil del dispositivo, se creará una nueva entidad de sensor de "Temperatura" y se activará el
-"maniquí" función de niebla automáticamente.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-triggering-device.png)
-
-La otra forma de activar la función de niebla es enviar una actualización de la entidad NGSI en forma de una solicitud
-POST al FogFlow para crear la entidad del sensor de "Temperatura".
-
-```console
-curl -iX POST \
- 'http://localhost:8080/ngsi10/updateContext' \
- -H 'Content-Type: application/json' \
- -d '{
- "contextElements": [
- {
- "entityId": {
- "id": "Device.temp001", "type": "Temperature", "isPattern": false
- },
- "attributes": [
- {
- "name": "temp", "type": "integer", "value": 10
- }
- ],
- "domainMetadata": [
- {
- "name": "location", "type": "point",
- "value": {
- "latitude": 49.406393,
- "longitude": 8.684208
- }
- }
- ]
- }
- ],
- "updateAction": "UPDATE"
-}'
-```
-
-Verifique si la función de niebla se activa o no de la siguiente manera.
-
-- compruebe la instancia de tarea de esta función de niebla, como se muestra en la siguiente imagen
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-task-running.png)
-
-- comprobar el resultado generado por su instancia de tarea en curso, como se muestra en la siguiente imagen
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-streams.png)
-
-## Definir y activar una topología de servicio
-
-La topología del servicio se define como un gráfico de varios operadores. Cada operador de la topología de servicio se
-anota con su entradas y salidas, que indican su dependencia de las otras tareas de la misma topología.
-
-**Diferente de las funciones de niebla, una topología de servicio es activada a pedido por un objeto "intencional"
-personalizado.**
-
-El estudio de un simple ejemplo de un caso de uso de **Detección de anomalías** puede ayudar a los desarrolladores a
-definir y probar una topología de servicio.
-
-Este estudio de caso de uso es para que las tiendas minoristas detecten el consumo anormal de energía en tiempo real.
-Como se ilustra en el En la siguiente imagen, una empresa de venta al por menor tiene un gran número de tiendas
-distribuidas en diferentes lugares. Para cada tienda, un El dispositivo Raspberry Pi (nodo de borde) se despliega para
-monitorear el consumo de energía de todos los paneles de poder en la tienda. En detección de uso anormal de energía en
-una tienda (o borde), el mecanismo de alarma de la tienda se activa para informar a la tienda propietario. Además, el
-suceso detectado se comunica a la nube para la agregación de información. La información agregada es y luego presentado
-al operador del sistema a través de un servicio de tablero de mandos. Además, el operador del sistema puede actualizar
-dinámicamente la regla para la detección de anomalías.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retails.png)
-
-### Implementar las funciones del operador
-
-Para este caso de uso específico se utilizan dos operadores, anomalía y contador, que ya están registrados en FogFlow.
-Véase a los ejemplos proporcionados en el depósito de códigos.
-
-- [Anomaly Detector](https://github.com/smartfog/fogflow/tree/master/application/operator/anomaly) operador es
- detectar eventos anómalos basados en los datos recogidos de los paneles de energía en una tienda minorista. Tiene
- dos tipos de entradas:
-
- - las reglas de detección son proporcionadas y actualizadas por el operador; El tipo de flujo de entrada de las
- reglas de detección está asociado con "transmisión", lo que significa que las reglas son necesarias para todas
- las instancias de tareas de este operador. La granularidad de este operador se basa en "shopID", lo que
- significa que se creará y configurará una instancia de tarea dedicada para cada tienda.
- - Los datos de los sensores son proporcionados por el panel de energía.
-
-- [Counter](https://github.com/smartfog/fogflow/tree/master/application/operator/counter) el operador debe contar el
- el número total de eventos de anomalías para todas las tiendas de cada ciudad. Por lo tanto, la granularidad de su
- tarea es por "ciudad". Su entrada El tipo de corriente es el tipo de corriente de salida del operador anterior
- (Detector de Anomalías).
-
-Hay dos tipos de consumidores de resultados:
-
-1. un servicio de tablero en la nube, que se suscribe a los resultados finales de agregación generados por el contador
- operador para el ámbito global;
-2. la alarma en cada tienda, que se suscribe a los eventos de anomalía generados por la tarea del Detector de Anomalías
- en el local nodo de borde en la tienda de venta al público.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retail-flow.png)
-
-### Especifique la topología del servicio
-
-Supongamos que las tareas que se utilizarán en la topología del servicio se han implementado y registrado, sólo hay que
-especificar el servicio de la siguiente manera usando el editor de topología de FogFlow.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retail-topology-1.png)
-
-Como se ve en la imagen, se debe proporcionar la siguiente información importante.
-
-1. definir el perfil de la topología, incluyendo
-
- - nombre de la topología: el nombre único de su topología
- - descripción del servicio: algún texto para describir de qué trata este servicio
-
-2. dibujar el gráfico de los flujos de procesamiento de datos dentro de la topología de servicio con un clic derecho en
- algún lugar del diseño tablero, elegir o tarea o flujos de entrada o barajar para definir sus flujos de
- procesamiento de datos de acuerdo con el diseño que tienes en mente.
-
-3. definir el perfil de cada elemento en el flujo de datos, incluyendo los siguientes, utilizando el botón de
- configuración de cada uno.
-
- - El perfil de la tarea puede definirse especificando el nombre, el operador y el tipo de entidad.
- - El perfil **EntityStream** se actualiza con los campos SelectedType, SelectedAttributes, Groupby, Scoped.
- - **El elemento Shuffle** sirve como conector entre dos tareas de tal manera que la salida de una tarea es la
- entrada para el elemento de barajado y el mismo es reenviado por barajado a otra tarea (o tareas) como entrada.
-
-### Activar la topología de servicio mediante el envío de una intención
-
-La topología de servicio puede ser activada en dos pasos:
-
-- Envío de un objeto de alto nivel de intención que divide la topología de servicio en tareas separadas
-- Proporcionando flujos de entrada a las tareas de esa topología de servicio.
-
-El objeto de intención se envía usando el tablero de FogFlow con las siguientes propiedades:
-
-- **Topología:** especifica para qué topología está destinado el objeto de intención.
-- **Prioridad:** define el nivel de prioridad de todas las tareas de su topología, que será utilizado por los nodos de
- borde para decidir cómo se deben asignar los recursos a las tareas.
-- **Uso de recursos:** define cómo una topología puede usar recursos en los nodos del borde. Compartir de forma
- exclusiva significa que el La topología no compartirá los recursos con ninguna tarea de otras topologías. La otra
- forma es inclusiva.
-- **Objetivo:** de máximo rendimiento, mínima latencia y mínimo coste se puede establecer para la asignación de tareas
- en los trabajadores. Sin embargo, esta característica no está totalmente soportada todavía, por lo que puede
- establecerse como "Ninguna" por ahora.
-- **Geoscopio:** es un área geográfica definida donde se deben seleccionar los flujos de entrada. Tanto global como
- personalizado los geóscopos pueden ser configurados.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/intent-registry.png)
-
-Tan pronto como se reciben los datos de contexto, que entran en el ámbito del objeto de la intención, se lanzan las
-tareas sobre el los trabajadores más cercanos.
-
-Aquí hay ejemplos de rizos para enviar corrientes de entrada para el caso de uso del Detector de Anomalías. Requiere
-PowerPanel así como datos de la regla.
-
-> **Nota:** Los usuarios también pueden usar
-> [Dispositivos de panel de potencia simulado](https://github.com/smartfog/fogflow/tree/544ebe782467dd81d5565e35e2827589b90e9601/application/device/powerpanel)
-> para enviar datos del panel de energía.
->
-> El caso Curl asume que el Broker de IO de la nube está funcionando en el host local en el puerto 8070.
-
-```console
-curl -iX POST \
- 'http://localhost:8070/ngsi10/updateContext' \
--H 'Content-Type: application/json' \
--d '
- {
- "contextElements": [
- {
- "entityId":{
- "id":"Device.PowerPanel.01", "type":"PowerPanel"
- },
- "attributes":[
- {
- "name":"usage", "type":"integer", "value":4
- },
- {
- "name":"shop", "type":"string", "value":"01"
- },
- {
- "name":"iconURL", "type":"string", "value":"/img/shop.png"
- }
- ],
- "domainMetadata":[
- {
- "name":"location", "type":"point",
- "value": {
- "latitude":35.7,
- "longitude":138
- }
- },
- {
- "name":"shop", "type":"string", "value":"01"
- }
- ]
- }
- ],
- "updateAction": "UPDATE"
-}'
-```
-
-Los resultados de la topología del servicio se publicarán al Corredor, cualquier solicitud que se suscriba a los datos
-recibirá la notificación. Un dispositivo actuador también puede recibir estos flujos como entradas del Corredor. Los
-flujos resultantes también se puede ver en el menú de Corrientes en el tablero de FogFlow.
-
-# Próximos pasos
-
-¿Quieres aprender a añadir más complejidad a tu aplicación añadiendo funciones avanzadas? Puedes averiguarlo leyendo los
-otros [tutoriales de esta serie](https://fiware-tutorials.rtfd.io)
-
----
-
-## License
-
-[MIT](LICENSE) © 2020 FIWARE Foundation e.V.
diff --git a/README.ja.md b/README.ja.md
deleted file mode 100644
index c665be8..0000000
--- a/README.ja.md
+++ /dev/null
@@ -1,614 +0,0 @@
-[![FIWARE Banner](https://fiware.github.io/tutorials.Edge-Computing/img/fiware.png)](https://www.fiware.org/developers)
-[![NGSI v2](https://img.shields.io/badge/NGSI-v2-5dc0cf.svg)](https://fiware-ges.github.io/orion/api/v2/stable/)
-
-[![FIWARE Context processing, analysis and visualisation](https://nexus.lab.fiware.org/static/badges/chapters/processing.svg)](https://github.com/FIWARE/catalogue/blob/master/processing/README.md)
-
-
-これは、[FIWARE FogFlow](https://fogflow.readthedocs.io/en/latest/) の入門チュートリアルであり、ユーザがエッジで処理
-フローを動的に調整できるようにします。分散または単一ノード・システムで FogFlow を有効にし、ユーザ定義のワークロード・
-パターンを登録し、実行中のタスクの形でエッジでそれらを調整する方法を説明します。理解を深めるために、チュートリアルに
-例が含まれています。
-
-## コンテンツ
-
-
-詳細
-
-- [アーキテクチャ](#architecture)
- - [レイヤード・アーキテクチャ](#layered-architecture)
-- [起動](#start-up)
- - [FogFlow クラウド・ノード](#fogflow-cloud-node)
- - [FogFlow エッジ・ノード](#fogflow-edge-node)
-- [IoT デバイスを FogFlow に接続](#connect-iot-devices-to-fogflow)
-- [FogFlow を使用したエッジでの動的オーケストレーション](#dynamic-orchestration-at-edges-using-fogflow)
- - [Fog ファンクションの定義とトリガー](#define-and-trigger-a-fog-function)
- - [タスク・オペレータの登録](#register-the-task-operators)
- - ["dummy" Fog ファンクションを定義](#define-a-dummy-fog-function)
- - ["dummy" Fog ファンクションをトリガー](#trigger-the-dummy-fog-function)
- - [サービス・トポロジの定義とトリガー](#define-and-trigger-a-service-topology)
- - [オペレータ・ファンクションの実装](#implement-the-operator-functions)
- - [サービス・トポロジの指定](#specify-the-service-topology)
- - [インテントを送信してサービス・トポロジをトリガー](#trigger-the-service-topology-by-sending-an-intent)
-
-
-
-# クラウド-エッジ・コンピューティング (Cloud-Edge Computing)
-
-チュートリアルの目的は、IoT センサ・デバイスがコンテキスト・データを FogFlow に送信する方法、FogFlow がアクチュエータ・
-デバイスを介して環境を変更する処理フローをいつ、どこで開始するかをユーザに教えることです。以下の図は、シナリオの概要を
-示しています。センサ、アクチュエータ、動的処理フローについては、このチュートリアルの後続のセクションで説明します。
-これらのセクションは、以下の図に関連しています。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fogflow-overall-view.png)
-
-1. ユーザがシナリオを FogFlow に提供します。これには、何をすべきか、いつすべきかが含まれます。FogFlow はどこを行うべき
- かを理解します
-2. センサは定期的にコンテキスト・データを FogFlow に送信します。データには、温度、ビデオ・ストリーミング、写真などの
- 環境データが含まれる場合があります
-3. FogFlow は、エッジでの処理フローをすぐに調整します。これらの処理フローは、アクチュエータの状態を変更したり、一部の
- データを FogFlow にパブリッシュしたりする可能性があります。それはすべて、ユーザが実行したいことに関するものです。
-
-
-
-
-
-# アーキテクチャ
-
-FogFlow フレームワークは、クラウド・ノード、エッジ・ノード、IoT デバイスを含む、地理的に分散した階層型の異種 ICT
-インフラストラクチャで動作します。次の図は、3つの論理層にわたる FogFlow とその主要コンポーネントのシステム・
-アーキテクチャを示しています。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/architecture.png)
-
-
-
-## レイヤード・アーキテクチャ (Layered Architecture)
-
-論理的には、FogFlow は次の3つのレイヤーで構成されています。
-
-- **サービス管理:** サービス要件を具体的な実行プランに変換し、生成された実行プランをクラウドとエッジに展開します。
- タスク・デザイナ、トポロジ・マスタ、および Docker レジストリ・サービスは、サービス管理レイヤーを構成します
-- **コンテキスト管理:** すべてのコンテキスト情報を管理し、柔軟なクエリおよびサブスクライブ・インターフェイスを介して
- それらを検出およびアクセス可能にします。このレイヤーは、Context Brokers と IoT Discovery で構成されています
-- **データ処理:** データ処理タスクを起動し、コンテキスト管理レイヤによって提供される pub/sub インターフェースを介して
- タスク間のデータ・フローを確立します。エッジ・ワーカ (そして、もちろんクラウド・ワーカ) はこのレイヤーの下にあります
-
-
-
-## FogFlow クラウド・ノード の起動
-
-クラウド・ノードを起動するための**前提条件**は次のとおりです :
-
-- **Docker:** インストールについては、
- [こちら](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-16-04)
- を参照してください。必要なバージョン > 18.03.1-ce;
-- **Docker-Compose:** インストールについては、
- [こちら](https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-16-04)
- を参照してください。必要なバージョン > 2.4.2;
-
-> **重要:** また、ユーザが sudo なしで Docker コマンドを実行できるようにしてください。
-
-**FogFlow クラウド・サービスのインストールを開始するには、次の操作を行います :**
-
-1. 現在の環境に応じて、config.json の次の IP アドレスを変更します
-
- - **my_hostip**: FogFlow クラウド・ノードのパブリック IP アドレス
- - **site_id**: FogFlow システムのノードを識別するための一意の文字列ベースの ID
- - **physical_location**: ノードの地理的位置
- - **worker.capacity**: これは、FogFlow ノードが呼び出すことができる Docker コンテナの最大数を意味します。
- デフォルトでは、その値は "8" です
-
-```json
-{
- "my_hostip": "10.156.0.9",
- "physical_location": {
- "longitude": 139.709059,
- "latitude": 35.692221
- },
- "site_id": "001",
- "worker": {
- "container_autoremove": false,
- "start_actual_task": true,
- "capacity": 8
- }
-}
-```
-> ## 重要 !
->
-> my_hostip の IP アドレスとして "127.0.0.1" を使用しないでください。これは、 Docker コンテナ内で実行中のタスクに
-> のみアクセスできるためです。
->
-> **ファイアウォール・ルール**: FogFlow Web ポータルにアクセスできるようにするには、TCP 経由でポート 80 および 5672
-> を開く必要があります。
->
-> **Mac ユーザ**: Macbook で FogFlow をテストする場合は、Docker デスクトップをインストールし、構成ファイルの my_hostip
- として "host.docker.internal" も使用してください。
->
-> ポート番号を変更する必要がある場合は、変更がこれら3つの構成ファイルすべてで一貫していることを確認してください。
-
-2. FogFlow コンポーネントの Docker イメージをプルして起動します
-
-```console
-git clone https://github.com/FIWARE/tutorials.Edge-Computing.git
-cd tutorials.Edge-Computing
-git checkout NGSI-v2
-
-docker-compose pull
-docker-compose up -d
-```
-
-3. 次の2つの方法のいずれかで FogFlow クラウド・ノードのセットアップを検証します
-
-- `docker ps -a` を使用して、すべてのコンテナが稼働していることを確認します
-
-```console
-docker ps -a
-```
-
-```text
-CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-e412877b4862 nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp tutorialsedgecomputing_nginx_1
-29ea8555685d fogflow/master:3.2 "/master" 2 minutes ago Up 2 minutes 0.0.0.0:1060->1060/tcp tutorialsedgecomputing_master_1
-aaa2f29959e7 fogflow/worker:3.2 "/worker" 2 minutes ago Up 2 minutes tutorialsedgecomputing_cloud_worker_1
-1298fe46bf1e fogflow/designer:3.2 "node main.js" 2 minutes ago Up 2 minutes 0.0.0.0:1030->1030/tcp, 0.0.0.0:8080->8080/tcp tutorialsedgecomputing_designer_1
-644333fa6215 fogflow/broker:3.2 "/broker" 2 minutes ago Up 2 minutes 0.0.0.0:8070->8070/tcp tutorialsedgecomputing_cloud_broker_1
-acd974d6c040 fogflow/discovery:3.2 "/discovery" 2 minutes ago Up 2 minutes 0.0.0.0:8090->8090/tcp tutorialsedgecomputing_discovery_1
-cce2c64503d9 dgraph/standalone "/run.sh" 2 minutes ago Up 2 minutes 0.0.0.0:6080->6080/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8082->8080/tcp, 0.0.0.0:9082->9080/tcp tutorialsedgecomputing_dgraph_1
-925d1deb343f rabbitmq:3 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 4369/tcp, 5671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:5672->5672/tcp tutorialsedgecomputing_rabbitmq_1
-```
-
-- `http:///index.html` にある FogFlow ダッシュボードからシステム・ステータスを確認します。表示される
- Web ページは下図のとおりです
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dashboard.png)
-
-
-
-## FogFlow エッジ・ノード の起動
-
-エッジ・ノードを起動するための**前提条件**は次のとおりです :
-
-- **Docker:** [Raspberry Piに Docker CE をインストールする方法](https://withblue.ink/2019/07/13/yes-you-can-run-docker-on-raspbian.html)
- を参照してください。
-
-**インストールを開始するには、次のようにします。**
-
-1. クラウド・ノードと同様に構成ファイルを変更しますが、**coreservice_ip** はクラウド・ノードの IP アドレスであるため、
- 統一されたままになります。**my_hostip** はエッジ・ノードのパブリック IP アドレスに変更されます。
-
-```json
-{
- "coreservice_ip": "10.156.0.9",
- "my_hostip": "172.17.0.1",
- "physical_location": {
- "longitude": 138.709059,
- "latitude": 36.692221
- },
- "site_id": "002",
-
- "worker": {
- "container_autoremove": false,
- "start_actual_task": true,
- "capacity": 4
- }
-}
-```
-
-2. Edge IoT Broker と FogFlow Worker の両方を起動します。エッジ・ノードが ARM ベースの場合は、コマンド・パラメータとして
- arm を追加します。
-
-```console
- ./start.sh
-```
-
-3. Edge IoT Broker と FogFlow Worker の両方を停止します :
-
-```console
- ./stop.sh
-```
-
-
-
-# IoT デバイスを FogFlow に接続
-
-センサ・デバイスからブローカーに向かうデータ・フローはノースバウンド・フローと呼ばれ、ブローカーからアクチュエータ・
-デバイスにデータ・フローが流れる場合はサウスバウンド・フローと呼ばれます。FogFlow は、この双方向のデータ・フローに依存
-して、その背後にある実際のアイデアを実現します。
-
-センサ・デバイスからデータを受信するには、
-[センサ・デバイスに接続する]((https://fogflow.readthedocs.io/en/latest/integration.html#northbound-integration)
-を参照してください。チュートリアルには、NGSI デバイスと非 NGSI デバイスの両方の例が含まれています。
-
-FogFlow は、動的な処理フローを通じて、ドアのロック、ランプのスイッチのオン、シールドのオン/オフなど、接続されている
-アクチュエータ・デバイスの状態を変更できます。**アクチュエータ・デバイスに接続する**には、
-[アクチュエータ・デバイスと FogFlow の統合](https://fogflow.readthedocs.io/en/latest/integration.html#southbound-integration)
-を参照してください。このチュートリアルには、NGSI デバイスと非 NGSI デバイス (特に、UltraLight デバイスと MQTT デバイス)
-の例も含まれています。
-
-サウスバウンドが実際に FIWARE のコンテキストでどのように機能するかについての基本的なアイデアを得るには、
-[この](https://fiware-tutorials.readthedocs.io/en/latest/iot-agent/index.html#southbound-traffic-commands)
-チュートリアルを参照してください。
-
-
-
-# FogFlow を使用したエッジでの動的オーケストレーション
-
-先に進む前に、ユーザは以下を確認する必要があります :
-
-- FogFlow の[コア・コンセプト](https://fogflow.readthedocs.io/en/latest/core_concept.html)
-- [インテント・ベースのプログラミング・モデル](https://fogflow.readthedocs.io/en/latest/intent_based_program.html)
-
-
-
-## Fog ファンクションを定義してトリガー
-
-FogFlow はサーバーレス・エッジ・コンピューティングを可能にします。つまり、開発者は処理ロジック (またはオペレータ)
-とともに Fog ファンクションを定義および送信でき、残りは FogFlow によって自動的に実行されます :
-
-- 入力データが利用可能になったときに送信された Fog ファンクションをトリガーします
-- 定義された粒度 (granularity) に従って作成されるインスタンスの数を決定します
-- 作成されたインスタンスまたは処理フローをデプロイする場所を決定します
-
-
-
-### タスク・オペレータを登録
-
-FogFlow を使用すると、開発者は登録済みオペレータ内で独自のファンクション・コードを指定できます。いくつかの
-[例](https://github.com/smartfog/fogflow/tree/master/application/operator) と
-[チュートリアル](https://fogflow.readthedocs.io/en/latest/intent_based_program.html#provide-the-code-of-your-own-function)
-をチェックして、カスタマイズされたオペレータの作成方法を確認してください。
-
-オペレータを作成するための Python, Java, JavaScript テンプレートは
-[こちら](https://github.com/FIWARE/tutorials.Edge-Computing/tree/master/templates)にあります。
-
-現在のチュートリアルについては、以下の手順を参照してください:
-
-FogFlow にオペレータを登録するには、次の手順が必要です。
-
-1. **オペレータの登録**とは、オペレータの名前と必要な入力パラメータを定義することを意味します。
-
-オペレータを登録するには、FogFlow ダッシュボードを開きます。水平バーから "Operator Registry" タブを選択し、左側の
-メニューから "Operator Registry" を選択して、"Register" ボタンをクリックします。ワークスペースを右クリックし、
-ドロップ・ダウン・リストからオペレータを選択して、詳細を入力し、最後に送信をクリックします。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/operator-registry.png)
-
-> **注:**
->
-> ユーザはオペレータにパラメータを追加できます。オペレータ・アプリケーションのポートを定義するには、"service_port"
-> を使用し、その値として有効なポート番号を指定します。アプリケーションは、このポートを介して外部からアクセスできます。
-
-2. **Docker イメージを登録し、オペレータを選択して**、Docker イメージを定義し、すでに登録されているオペレータを関連付け
- ます。次の図は、登録済みの Docker イメージのリストと各イメージの重要な情報を示しています。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dockerimage-registry-list.png)
-
-"register" ボタンをクリックして必要事項を入力し、"register" ボタンをクリックして登録を完了します。
-
-フォームは次のように説明されます。
-
-- **Image:** オペレータの Docker イメージの名前。[Docker Hub] に公開するものと一致している必要があります
-- **Tag:** オペレータの Docker イメージの公開に使用したタグ。デフォルトでは "latest" です
-- **Hardware Type:** x86 または ARM (Raspberry Pi など) を含む、Docker イメージがサポートするハードウェア・タイプ
-- **OS Type:** Docker イメージがサポートするオペレーティング・システム・タイプ。現在、これは Linux に限定されています
-- **Operator:** オペレータ名。一意である必要があり、サービス・トポロジを定義するときに使用されます
-- **Prefetched:** これがチェックされている場合、すべてのエッジ・ノードがこの Docker イメージを事前にフェッチし
- 始めます。それ以外の場合、エッジ・ノードがこのオペレータに関連付けられたスケジュールされたタスクを実行する必要が
- ある場合にのみ、オペレータの Docker イメージがオンデマンドでフェッチされます
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dockerimage-registry.png)
-
-
-
-### "dummy" Fog ファンクションを定義
-
-タスク・デザイン・ボード内を右クリックすると、次のようなメニューが表示されます :
-
-- **Task**: Fog ファンクション名と処理ロジック (またはオペレータ) を定義するために使用されます。タスクには入力
- ストリームと出力ストリームがあります
-- **EntityStream**: 入力データストリームとして Fog ファンクション・タスクとリンクできる入力データ要素です
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-1.png)
-
-"Task" を選択すると、以下に示すように、タスク・エレメントがデザイン・ボードに配置されます。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-2.png)
-
-次の図に示すように、タスク要素の右上隅にある設定ボタン (configuration button) をクリックします。タスクの名前を指定し、
-いくつかの事前登録されたオペレータのリストからオペレータを選択します。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-3.png)
-
-ポップアップ・メニューからデザイン・ボードに "EntityStream" を追加します。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-4.png)
-
-次のフィールドが含まれます :
-
-- **Selected Type:** は、その可用性が Fog ファンクションをトリガーする入力ストリームのエンティティ・タイプを定義する
- ために使用されます
-- **Selected Attributes:** は、選択されたエンティティ・タイプに対して、Fog ファンクションに必要なエンティティ属性。
- "all" は、すべてのエンティティ属性を取得することを意味します
-- **Group By:** は、選択されたエンティティ属性の1つである必要があります。これは、この Fog ファンクションの粒度、
- つまり、この Fog ファンクションのインスタンスの数を定義します。この例では、粒度は "id" で定義されています。つまり、
- FogFlow は個々のエンティティ ID ごとに新しいタスク・インスタンスを作成します
-- **Scoped:** は、エンティティ・データが場所固有 (location-specific) かどうかを示します。True は、場所固有のデータが
- エンティティに記録され、ブロードキャスト・データの場合は False が使用されることを示します。たとえば、特定の場所
- ではなく、すべての場所に true を保持するルールまたはしきい値データがあります。
-
-以下に示すように、設定ボタンをクリックして EntityStream を構成します。ここでは例として、"Temperature" を示していますが、
-"dummy" Fog ファンクションの入力データのエンティティ・タイプも同様です。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-5.png)
-
-タスクには複数の EntityStream が存在する可能性があり、それらは以下に示すようにタスクに接続されている必要があります。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-6.png)
-
-Fog ファンクションを送信します。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-7.png)
-
-
-
-### "dummy" Fog ファンクションをトリガー
-
-定義された "dummy" フォグ機能は、必要な入力データが利用可能な場合にのみトリガーされます。
-
-1つの方法は、以下に示すように "Temperature" センサ・デバイスを登録することです。
-
-System Status タブの Device メニューに移動します。以下の情報を提供します。
-
-- **Device ID**: 一意のエンティティ ID を指定します
-- **Device Type**: エンティティ・タイプとして "Temperature" を使用します
-- **Location**: 地図上に場所 (a location) を配置します
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/device-registration.png)
-
-デバイス・プロファイルが登録されると、新しい "Temperature" センサ・エンティティが作成され、"dummy" Fog ファンクションが
-自動的にトリガーされます。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-triggering-device.png)
-
-Fog ファンクションをトリガーするもう1つの方法は、POST リクエストの形式で NGSI エンティティの更新を FogFlow broker に
-送信して、"Temperature" センサ・エンティティを作成することです。
-
-#### 1️⃣ リクエスト:
-
-```console
-curl -iX POST \
- 'http://localhost:8080/ngsi10/updateContext' \
- -H 'Content-Type: application/json' \
- -d '{
- "contextElements": [
- {
- "entityId": {
- "id": "Device.temp001", "type": "Temperature", "isPattern": false
- },
- "attributes": [
- {
- "name": "temp", "type": "integer", "value": 10
- }
- ],
- "domainMetadata": [
- {
- "name": "location", "type": "point",
- "value": {
- "latitude": 49.406393,
- "longitude": 8.684208
- }
- }
- ]
- }
- ],
- "updateAction": "UPDATE"
-}'
-```
-
-次の方法で Fog ファンクションがトリガーされているかどうかを確認します。
-
-- 次の図に示すように、この Fog ファンクションのタスク・インスタンスを確認します
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-task-running.png)
-
-- 次の図に示すように、実行中のタスク・インスタンスによって生成された結果を確認します
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-streams.png)
-
-
-
-## サービス・トポロジを定義してトリガー
-
-サービス・トポロジは、いくつかのオペレータのグラフとして定義されます。サービス・トポロジの各オペレータには、
-入力と出力の注釈が付けられています。これは、同じトポロジの他のタスクへの依存関係を示しています。
-
-**Fog ファンクションとは異なり、サービス・トポロジはオンデマンドでカスタマイズされた "intent" オブジェクトによって
-トリガーされます。**
-
-簡単な**異常検出**の使用事例の調査は、開発者がサービス・トポロジを定義およびテストするのに役立ちます。
-
-この使用事例は、小売店が異常なエネルギー消費をリアルタイムで検出するためのものです。次の図に示すように、小売企業には
-さまざまな場所に多数のショップが分散しています。ショップごとに、Raspberry Pi デバイス (エッジ・ノード) が展開され、
-ショップ内のすべての電源パネルからの電力消費を監視します。店舗 (またはエッジ) での異常な電力使用を検出すると、
-店舗のアラーム・メカニズムがトリガーされ、店舗の所有者に通知します。さらに、検出されたイベントは情報集約のために
-クラウドに報告されます。集約された情報は、ダッシュボード・サービスを介してシステム・オペレータに提示されます。
-さらに、システム・オペレータは異常検出のルールを動的に更新できます。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retails.png)
-
-
-
-### オペレータ・ファンクションを実装
-
-この特定の使用例では、FogFlow にすでに登録されている anomaly と counter の2つのオペレータが使用されています。
-コード・リポジトリで提供されている例を参照してください。
-
-- [Anomaly Detector](https://github.com/smartfog/fogflow/tree/master/application/operator/anomaly) オペレータは、
- 小売店の電源パネルから収集されたデータに基づいて異常イベントを検出します。2つのタイプの入力があります
-
- - 検出ルールは、オペレータによって提供および更新されます。検出ルールの入力ストリーム・タイプは `broadcast`
- に関連付けられています。つまり、このオペレータのすべてのタスク・インスタンスでルールが必要です。このオペレータの
- 粒度は `shopID` に基づいています。つまり、専用のタスク・インスタンスが各ショップに対して作成および構成されます
- - センサ・データは電源パネルから提供されます
-
-- [Counter](https://github.com/smartfog/fogflow/tree/master/application/operator/counter) オペレータは、各都市のすべて
- の店舗の異常イベントの総数をカウントします。したがって、そのタスクの粒度は "都市" によるものです。その入力ストリーム
- ・タイプは、前のオペレータ (Anomaly Detector) の出力ストリームタイプです
-
-結果コンシューマ (result consumers) には2つのタイプがあります :
-
-1. クラウド内のダッシュボード・サービス。グローバル・スコープの Counter オペレータによって生成された最終的な集計結果に
- サブスクライブします
-2. 各店舗のアラーム。小売店のローカル・エッジ・ノードの Anomaly Detector タスクによって生成された異常イベントに
- サブスクライブします
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retail-flow.png)
-
-
-
-### サービス・トポロジを指定
-
-サービス・トポロジで使用されるタスクが実装および登録されていると仮定し、FogFlow トポロジ・エディタを使用して次の方法で
-サービス・トポロジを指定します。
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retail-topology-1.png)
-
-図のように、次の重要な情報を提供する必要があります。
-
-1. 以下を含むトポロジ・プロファイルを定義します。
-
- - topology name: トポロジの一意の名前
- - service description: このサービスについて説明するテキスト
-
-2. サービス・トポロジ内のデータ処理フローのグラフをデザイン・ボードのどこかで右クリックして描画し、タスクまたは
- 入力ストリームまたはシャッフルを選択して、考えている設計に従ってデータ処理フローを定義します
-
-3. それぞれの設定ボタンを使用して、以下を含むデータ・フローの各要素のプロファイルを定義します
-
- - **Task** プロファイルは、名前、オペレータ、エンティティ・タイプを指定して定義できます
- - **EntityStream** プロファイルは SelectedType, SelectedAttributes, Groupby, Scoped fields で更新されます
- - **Shuffle** 要素は2つのタスク間のコネクタとして機能し、タスクの出力は Shuffle 要素の入力であり、同じ要素は
- Shuffle によって別のタスク (複数可) に入力として転送されます
-
-
-
-### インテントを送信してサービス・トポロジをトリガー
-
-サービス・トポロジは、次の2つのステップでトリガーできます :
-
-- サービス・トポロジを個別のタスクに分割する高レベルのインテント・オブジェクトを送信します
-- そのサービス・トポロジのタスクに入力ストリームを提供します
-
-インテント・オブジェクトは、次のプロパティを持つ FogFlowダッシュボードを使用して送信されます。
-
-- **Topology:** インテント・オブジェクトが対象とするトポロジを指定します
-- **Priority:** トポロジ内のすべてのタスクの優先度レベルを定義します。これは、リソースをタスクに割り当てる方法を
- 決定するためにエッジ・ノードによって利用されます
-- **Resource Usage:** トポロジがエッジ・ノードのリソースを使用する方法を定義します。排他的な方法での共有は、
- トポロジが他のトポロジのタスクとリソースを共有しないことを意味します。もう1つは包括的な方法です
-- **Objective:** 最大スループット、最小待ち時間、および最小コストを、ワーカーでのタスク割り当てに設定できます。
- ただし、この機能はまだ完全にはサポートされていないため、現時点では "None" に設定できます
-- **Geoscope:** は、入力ストリームを選択する必要がある定義済みの地理的エリアです。グローバルおよびカスタムの
- ジオスコープを設定できます
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/intent-registry.png)
-
-インテント・オブジェクトのスコープ内にあるコンテキスト・データを受信するとすぐに、最も近いワーカーでタスクが
-起動されます。
-
-Anomaly-Detector の使用例の入力ストリームを送信するための Curl の例を次に示します。PowerPanel とルール・データが
-必要です。
-
-> **注:** ユーザは、
-> [シミュレートされた PowerPanel デバイス](https://github.com/smartfog/fogflow/tree/544ebe782467dd81d5565e35e2827589b90e9601/application/device/powerpanel)
-> を使用して、PowerPanel データを送信することもできます。
->
-> Curl のケースでは、クラウド IoT Broker がポート 8070 の localhost で実行されていると想定しています。
-
-#### 2️⃣ リクエスト:
-
-```console
-curl -iX POST \
- 'http://localhost:8070/ngsi10/updateContext' \
--H 'Content-Type: application/json' \
--d '
- {
- "contextElements": [
- {
- "entityId":{
- "id":"Device.PowerPanel.01", "type":"PowerPanel"
- },
- "attributes":[
- {
- "name":"usage", "type":"integer", "value":4
- },
- {
- "name":"shop", "type":"string", "value":"01"
- },
- {
- "name":"iconURL", "type":"string", "value":"/img/shop.png"
- }
- ],
- "domainMetadata":[ {
- "name":"location", "type":"point", "value": { "latitude":35.7,
- "longitude":138 }
- }, {
- "name":"shop", "type":"string", "value":"01"
- }
- ]
- }
- ],
- "updateAction": "UPDATE"
-}'
-```
-
-サービス・トポロジの出力はブローカーに公開され、データをサブスクライブするアプリケーションは通知を受け取ります。
-アクチュエータ・デバイスは、ブローカーからの入力としてこれらのストリームを受信することもできます。結果のストリームは、
-FogFlow ダッシュボードの Streams メニューにも表示されます。
-
-# 次のステップ
-
-FogFlow がどのように機能するかを理解するための追加資料については、
-[FogFlow チュートリアル](https://fogflow.readthedocs.io/en/latest/introduction.html)
-にアクセスしてください。 FogFlow は、他の FIWARE GEs と統合することもできます。
-
-- **FogFlow を NGSI-LD Broker と統合**: FogFlow は、クラウド・ノードとエッジ・ノードをサポートする堅牢なプラット
- フォームに進化しました。 エッジ・コンピューティングのためにエッジを分散させるという主な概念は、FogFlow と他の
- NGSI-LD Broker の相互作用によって進化しました。NGSI-LD テクノロジは、データ通信とデータ表現の新しい地平です。
- FogFlow は NGSI_LD 準拠のブローカーになりました。詳細については、
- この[チュートリアル](https://fogflow.readthedocs.io/en/latest/scorpioIntegration.html)を参照してください
-
-- **FogFlow を監視ツールと統合**: FogFlow は分散アーキテクチャを備えているため、プラットフォームから FogFlow
- の分散コンポーネントを監視する必要があります。このため、FogFlow は Grafana と Elastisearch を統合して、
- メモリ使用率、CPU 使用率、サービスの現在の状態などのさまざまなコンポーネントを監視しています。このトピックの
- 詳細については、この[チュートリアル](https://fogflow.readthedocs.io/en/latest/system_monitoring.html)
- を参照してください
-
-- **FogFlow をセキュリティコンポーネントと統合**: FogFlow は、セキュリティ機能をサポートすることにより、
- それ自体を強化しました。IoT デバイスとエッジ間の通信、およびクラウドとエッジ間の通信は、IDM (Identity Manager
- Keyrock) と Wilma (PEP Proxy) を使用して保護されています。FogFlow のセキュリティ設定の詳細については、この
- [チュートリアル](https://fogflow.readthedocs.io/en/latest/https.html#secure-fogflow-using-identity-management)
- を参照してください
-
-- **FogFlow を QuantumLeap と統合**: FogFlow は、NGSI v2 の時空間データを保存、クエリ、取得するための REST
- サービスである QuantumLeap と統合できます。QuantumLeap は、NGSI の半構造化データを表形式に変換し、
- 時系列データベースに保存します。これにより、さまざまなシナリオで FogFlow を利用するための新しい可能性が
- 開かれました。 詳細については、
- [チュートリアル](https://fogflow.readthedocs.io/en/latest/quantumleapIntegration.html)
- を参照してください
-
-- **FogFlow を WireCloud と統合**: FogFlow は、さまざまな用途の広いエッジ・プラットフォーム・テクノロジを
- 採用しています。WireCloud は、最先端のエンドユーザ開発、RIA、およびセマンティック・テクノロジに基づいて
- 構築されており、サービスのインターネットのロングテールを活用することを目的とした次世代のエンドユーザ中心の
- Web アプリケーション・マッシュアップ・プラットフォームを提供します。Fogflow と WireCloud の詳細については、
- [チュートリアル](https://fogflow.readthedocs.io/en/latest/wirecloudIntegration.html)
- を参照してください
-
-高度な機能を追加することで、アプリケーションに複雑さを加える方法を知りたいですか?このシリーズの
-[他のチュートリアル](https://www.letsfiware.jp/fiware-tutorials)を読むことで見つけることができます
-
----
-
-## License
-
-[MIT](LICENSE) © 2020-2024 FIWARE Foundation e.V.
diff --git a/README.md b/README.md
index 31ad6ae..3ffa9e0 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,4 @@
[![FIWARE Banner](https://fiware.github.io/tutorials.Edge-Computing/img/fiware.png)](https://www.fiware.org/developers)
-[![NGSI v2](https://img.shields.io/badge/NGSI-v2-5dc0cf.svg)](https://fiware-ges.github.io/orion/api/v2/stable/)
[![FIWARE Context processing, analysis and visualisation](https://nexus.lab.fiware.org/static/badges/chapters/processing.svg)](https://github.com/FIWARE/catalogue/blob/master/processing/README.md)
@@ -8,577 +7,40 @@ to dynamically orchestrate the processing flows on edges. It explains how to ena
node system, register user defined workload patterns and orchestrate them on the edges in the form of running tasks. For
better understanding, examples have been included in the tutorial.
-🇯🇵 このチュートリアルは[日本語](README.ja.md)でもご覧いただけます。
🇪🇸 Este tutorial también está disponible en
-[español](README.es.md)
+# Start-Up
-## Contents
+## NGSI-v2 Smart Supermarket
-
-Details
-
-- [Architecture](#architecture)
- - [Layered Architecture](#layered-architecture)
-- [Start Up](#start-up)
- - [FogFlow Cloud Node](#fogflow-cloud-node)
- - [FogFlow Edge Node](#fogflow-edge-node)
-- [Connect IoT Devices to FogFlow](#connect-iot-devices-to-fogflow)
-- [Dynamic Orchestration at Edges using FogFlow](#dynamic-orchestration-at-edges-using-fogflow)
- - [Define a Fog Function](#define-and-trigger-a-fog-function)
- - [Register the Task Operators](#register-the-task-operators)
- - [Define a "dummy" Fog Function](#define-a-dummy-fog-function)
- - [Trigger the "dummy" Fog Function](#trigger-the-dummy-fog-function)
- - [Define a Service Topology](#define-and-trigger-a-service-topology)
- - [Implement the Operator Functions](#implement-the-operator-functions)
- - [Specify the Service Topology](#specify-the-service-topology)
- - [Trigger the Service Topology by sending an Intent](#trigger-the-service-topology-by-sending-an-intent)
-
-
-
-# Cloud-Edge Computing
-
-The intention of the tutorial is to teach its users how the IoT sensor devices send context data to FogFlow, when and
-where FogFlow start a processing flow to alters the environment through actuator devices. The figure below gives an
-overview of the scenario. Sensors, actuators and the dynamic processing flows are explained in the trailing sections in
-this tutorial, which are relatable to the figure below.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fogflow-overall-view.png)
-
-1. User provides his scenario to FogFlow, which includes what to do, when to do. FogFlow will figure out where to do.
-2. Sensors regularly send context data to FogFlow. Data may include environmental data like temperature, video
- streaming, pictures, etc.
-3. FogFlow orchestrates processing flows at edges in no time. These processing flows may change the state of an
- actuator or publish some data back to FogFlow, it is all about what user wants to do.
-
-
-
-# Architecture
-
-The FogFlow framework operates on a geo-distributed, hierarchical, and heterogeneous ICT infrastructure that includes
-cloud nodes, edge nodes, and IoT devices. The following figure illustrates the system architecture of FogFlow and its
-major components across three logical layers.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/architecture.png)
-
-## Layered Architecture
-
-Logically, FogFlow consists of the following three layers:
-
-- **service management:** converts service requirements into concrete execution plan and then deploy the generated
- execution plan over cloud and edges. Task Designer, Topology Master and Docker Registry services together make up
- the service management layer.
-- **context management:** manages all context information and make them discoverable and accessible via flexible query
- and subscribe interfaces. This layer consists of Context Brokers and the IoT Discovery.
-- **data processing:** launches data processing tasks and establish data flows between tasks via the pub/sub
- interfaces provided by the context management layer. Edge workers (and of course the cloud worker) come under this
- layer.
-
-## Setup FogFlow Cloud Node
-
-**Prerequisites** for starting up a cloud node are as follows:
-
-- **Docker:** Please refer
- [this](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-16-04) for
- installation, required version > 18.03.1-ce;
-- **Docker-Compose:** Please refer
- [this](https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-16-04) for
- installation, required version > 2.4.2;
-
-> **Important:** Please also allow your user to execute the Docker commands without sudo.
-
-**To start the installation of FogFlow cloud services, do the following:**
-
-1. Change the following IP addresses in config.json according to the current environment.
-
- - **my_hostip**: Public IP address of the FogFlow cloud node.
- - **site_id**: Unique string-based ID to identify the node in FogFlow system.
- - **physical_location**: The geo-location of the node.
- - **worker.capacity**: It means the maximal number of docker containers that the FogFlow node can invoke. By
- default its value is "8"
-
-```json
-{
- "my_hostip": "10.156.0.9",
- "physical_location": {
- "longitude": 139.709059,
- "latitude": 35.692221
- },
- "site_id": "001",
- "worker": {
- "container_autoremove": false,
- "start_actual_task": true,
- "capacity": 8
- }
-}
-```
-
-> ## Important !
->
-> Please DO NOT use “127.0.0.1” as the IP address of my_hostip, because it is only accessible to a running task inside a
-> docker container.
->
-> **Firewall rules**: To make your FogFlow web portal accessible, the following ports 80 and 5672 over TCP must be open.
->
-> **Mac Users**: If you like to test FogFlow on your Macbook, please install Docker Desktop and also use
-> “host.docker.internal” as my_hostip in the configuration file.
->
-> If you need to change the port number(s), please make sure the change is consistence in all these three configuration
-> files.
-
-2. Pull the docker images of FogFlow components and start them.
-
-```console
- docker-compose pull
- docker-compose up -d
-```
-
-3. Validate the FogFlow cloud node setup through any of these two ways:
-
-- Check if all the containers are up and running using `docker ps -a`.
+**NGSI-v2** offers JSON based interoperability used in individual Smart Systems. To run this tutorial with **NGSI-v2**, use the `NGSI-v2` branch.
```console
- docker ps -a
-```
-
-```text
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- e412877b4862 nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp tutorialsedgecomputing_nginx_1
- 29ea8555685d fogflow/master:3.2 "/master" 2 minutes ago Up 2 minutes 0.0.0.0:1060->1060/tcp tutorialsedgecomputing_master_1
- aaa2f29959e7 fogflow/worker:3.2 "/worker" 2 minutes ago Up 2 minutes tutorialsedgecomputing_cloud_worker_1
- 1298fe46bf1e fogflow/designer:3.2 "node main.js" 2 minutes ago Up 2 minutes 0.0.0.0:1030->1030/tcp, 0.0.0.0:8080->8080/tcp tutorialsedgecomputing_designer_1
- 644333fa6215 fogflow/broker:3.2 "/broker" 2 minutes ago Up 2 minutes 0.0.0.0:8070->8070/tcp tutorialsedgecomputing_cloud_broker_1
- acd974d6c040 fogflow/discovery:3.2 "/discovery" 2 minutes ago Up 2 minutes 0.0.0.0:8090->8090/tcp tutorialsedgecomputing_discovery_1
- cce2c64503d9 dgraph/standalone "/run.sh" 2 minutes ago Up 2 minutes 0.0.0.0:6080->6080/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8082->8080/tcp, 0.0.0.0:9082->9080/tcp tutorialsedgecomputing_dgraph_1
- 925d1deb343f rabbitmq:3 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 4369/tcp, 5671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:5672->5672/tcp tutorialsedgecomputing_rabbitmq_1
+git clone https://github.com/FIWARE/tutorials.Edge-Computing.git
+cd tutorials.Edge-Computing
+git checkout NGSI-v2
+./services create
+./services start
```
-- Check the system status from the FogFlow DashBoard at `http:///index.html`. Web page to be displayed
- is shown in the figure below.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dashboard.png)
-
-## Setup FogFlow Edge Node
-
-**Prerequisites** for starting up an edge node are as follows:
-
-- **Docker:** Please refer to
- [Install Docker CE on Raspberry Pi](https://withblue.ink/2019/07/13/yes-you-can-run-docker-on-raspbian.html).
-
-**To start the installation, do the following:**
-
-1. Change the configuration file similar to the cloud node, but now **coreservice_ip** will remain uniform because it
- is the IP address of the cloud node. **my_hostip** will change to the public IP address of edge node.
-
-```json
-{
- "coreservice_ip": "10.156.0.9",
- "my_hostip": "172.17.0.1",
- "physical_location": {
- "longitude": 138.709059,
- "latitude": 36.692221
- },
- "site_id": "002",
-
- "worker": {
- "container_autoremove": false,
- "start_actual_task": true,
- "capacity": 4
- }
-}
-```
-
-2. Start both Edge IoT Broker and FogFlow Worker. If the edge node is ARM-based, then attach arm as the command
- parameter.
-
-```console
- ./start.sh
-```
-
-3. Stop both Edge IoT Broker and FogFlow Worker:
-
-```console
- ./stop.sh
-```
-
-# Connect IoT Devices to FogFlow
-
-When data flow from a sensor device towards broker, it is called Northbound Flow, whereas it is Southbound Flow, when
-data flow from broker towards the actuator devices. FogFlow relies on this bi-directional data flow to realize the
-actual idea behind it.
-
-To receive data from the sensor devices, refer
-[connect to a sensor device](https://fogflow.readthedocs.io/en/latest/integration.html#northbound-integration). The
-tutorial contains examples of both NGSI and Non-NGSI devices.
-
-FogFlow can change the state of connected actuator devices, such as, locking a door, switching on a lamp, turning a
-shield on or off, etc. through its dynamic processing flows. To **connect to an actuator device**, refer
-[Integrate an actuator device with FogFlow](https://fogflow.readthedocs.io/en/latest/integration.html#southbound-integration).
-This tutorial also contains examples of both NGSI and Non-NGSI devices (especially, the UltraLight and MQTT ones).
-
-To get a basic idea of how Southbound actually works in the context of FIWARE, refer
-[this](https://fiware-tutorials.readthedocs.io/en/latest/iot-agent/index.html#southbound-traffic-commands) tutorial.
-
-# Dynamic Orchestration at Edges using FogFlow
-
-Before moving further, users must have a look at the following:
-
-- [Core concepts](https://fogflow.readthedocs.io/en/latest/core_concept.html) of FogFlow and
-- [Intent-based programming model](https://fogflow.readthedocs.io/en/latest/intent_based_program.html)
-
-## Define and trigger a Fog Function
-
-FogFlow enables serverless edge computing, i.e., the developers can define and submit a fog function along with the
-processing logic (or operator) and then the rest will be done by FogFlow automatically, including:
-
-- triggering the submitted fog function when its input data are available
-- deciding how many instances are to be created according to the defined granularity
-- deciding where to deploy the created instances or processing flows
-
-### Register the Task Operators
-
-FogFlow allows the developers to specify their own function code inside a registered operator. Check out some
-[examples](https://github.com/smartfog/fogflow/tree/master/application/operator) and this
-[tutorial](https://fogflow.readthedocs.io/en/latest/intent_based_program.html#provide-the-code-of-your-own-function) to
-know how to create a customized operator.
-
-Python, Java and JavaScript templates to write an operator can be found
-[here](https://github.com/FIWARE/tutorials.Edge-Computing/tree/master/templates).
-
-For the current tutorial, refer the below mentioned steps.
-
-The following steps are required to register an operator in Fogflow.
-
-1. **Register an Operator** means to define what would be the name of Operator and what input parameters it would need.
-
-To register Operator, open fogflow dashboard. Select Operator Registry Tab from horizontal bar, select operator from
-menu on left and then click register button. Right click on workspace and select operator from drop down list and enter
-details as shown and at last click on submit.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/operator-registry.png)
-
-> [!NOTE]
-> User can add parameters to operator. To define the port for the operator application, use "service_port" and give a
-> valid port number as its value. The application would be accessible to the outer world through this port.
-
-2. **Register a Docker Image and choose Operator** means to define the docker image and associate an already registered
- Operator with it. The following picture shows the list of registered docker images and the key information of each
- image.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dockerimage-registry-list.png)
-
-Clicking on "register" button, fill out the required information and click on "register" button to finish the
-registration.
-
-The form is explained as the following.
-
-- **Image:** the name of your operator docker image, must be consistent with the one you publish to
- [Docker Hub](https://hub.docker.com/)
-- **Tag:** the tag you used to publish your operator docker image; by default it is "latest"
-- **Hardware Type:** the hardware type that your docker image supports, including x86 or ARM (e.g. Raspberry Pi)
-- **OS Type:** the operating system type that your docker image supports; currently this is only limited to Linux
-- **Operator:** the operator name, which must be unique and will be used when defining a service topology
-- **Prefetched:** if this is checked, that means all edge nodes will start to fetch this docker image in advance;
- otherwise, the operator docker image is fetched on demand, only when edge nodes need to run a scheduled task
- associated with this operator.
+| [![NGSI v2](https://img.shields.io/badge/NGSI-v2-5dc0cf.svg)](https://fiware-ges.github.io/orion/api/v2/stable/) | :books: [Documentation](https://github.com/FIWARE/tutorials.Edge-Computing/tree/NGSI-LD) | [Postman Collection](https://fiware.github.io/tutorials.Edge-Computing/) |
+| --- | --- | --- |
-![](https://fiware.github.io/tutorials.Edge-Computing/img/dockerimage-registry.png)
+## NGSI-LD Smart Farm
-### Define a "dummy" Fog Function
-
-Right click inside the task design board, a menu will be displayed that includes:
-
-- **Task**: is used to define the fog function name and the processing logic (or operator). A task has input and
- output streams.
-- **EntityStream**: is the input data element which can be linked with a fog function Task as its input data stream.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-1.png)
-
-Choose "Task", a Task element will be placed on the design board, as shown below.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-2.png)
-
-Click the configuration button on the top-right corner of the task element, as illustrated in the following figure.
-Specify the name of the Task and choose an operator out of a list of some pre-registered operators.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-3.png)
-
-Add an "EntityStream" from the pop-up menu to the design board.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-4.png)
-
-It contains the following fields:
-
-- **Selected Type:** is used to define the entity type of input stream whose availability will trigger the fog
- function.
-- **Selected Attributes:** for the selected entity type, which entity attributes are required by your fog function;
- "all" means to get all entity attributes.
-- **Group By:** should be one of the selected entity attributes, which defines the granularity of this fog function,
- i.e., the number of instances for this fog function. In this example, the granularity is defined by "id", meaning
- that FogFlow will create a new task instance for each individual entity ID.
-- **Scoped:** tells if the Entity data are location-specific or not. True indicates that location-specific data are
- recorded in the Entity and False is used in case of broadcasted data, for example, some rule or threshold data that
- holds true for all locations, not for a specific location.
-
-Configure the EntityStream by clicking on its configuration button as shown below. "Temperature" is shown as example
-here, as is the entity type of input data for the "dummy" fog function.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-5.png)
-
-There can be multiple EntityStreams for a Task and they must be connected to the Task as shown below.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-6.png)
-
-Submit the Fog Function.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-7.png)
-
-### Trigger the "dummy" Fog Function
-
-The defined "Dummy" fog function is triggered only when its required input data are available.
-
-One way is to register a "Temperature" sensor device as shown below.
-
-Go to Device menu in System Status tab. Provide the following information.
-
-- **Device ID**: to specify a unique entity ID
-- **Device Type**: use "Temperature" as the entity type
-- **Location**: to place a location on the map
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/device-registration.png)
-
-Once the device profile is registered, a new "Temperature" sensor entity will be created and it will trigger the "dummy"
-fog function automatically.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-triggering-device.png)
-
-The other way to trigger the fog function is to send an NGSI entity update in the form of a POST request to the FogFlow
-broker to create the "Temperature" sensor entity.
-
-#### 1️⃣ Request
+**NGSI-LD** offers JSON-LD based interoperability used for Federations and Data Spaces. To run this tutorial with **NGSI-LD**, use the `NGSI-LD` branch.
```console
-curl -iX POST \
- 'http://localhost:8080/ngsi10/updateContext' \
- -H 'Content-Type: application/json' \
- -d '{
- "contextElements": [
- {
- "entityId": {
- "id": "Device.temp001", "type": "Temperature", "isPattern": false
- },
- "attributes": [
- {
- "name": "temp", "type": "integer", "value": 10
- }
- ],
- "domainMetadata": [
- {
- "name": "location", "type": "point",
- "value": {
- "latitude": 49.406393,
- "longitude": 8.684208
- }
- }
- ]
- }
- ],
- "updateAction": "UPDATE"
-}'
-```
-
-Verify whether the fog function is triggered or not in the following way.
-
-- check the task instance of this fog function, as shown in the following picture
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-task-running.png)
-
-- check the result generated by its running task instance, as shown in the following picture
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/fog-function-streams.png)
-
-## Define and trigger a Service Topology
-
-Service topology is defined as a graph of several operators. Each operator in the service topology is annotated with its
-inputs and outputs, which indicate their dependency on the other tasks in the same topology.
-
-**Different from fog functions, a service topology is triggered on demand by a customized "intent" object.**
-
-Study of a simple **Anomaly Detection** use case example can help the developers to define and test a service topology.
+git clone https://github.com/FIWARE/tutorials.Edge-Computing.git
+cd tutorials.Edge-Computing
+git checkout NGSI-LD
-This use case study is for retail stores to detect abnormal energy consumption in real-time. As illustrated in the
-following picture, a retail company has a large number of shops distributed in different locations. For each shop, a
-Raspberry Pi device (edge node) is deployed to monitor the power consumption from all Power Panels in the shop. On
-detection of abnormal power usage in a shop (or edge), the alarm mechanism of shop is triggered to inform the shop
-owner. Moreover, the detected event is reported to the cloud for information aggregation. The aggregated information is
-then presented to the system operator via a dashboard service. In addition, the system operator can dynamically update
-the rule for anomaly detection.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retails.png)
-
-### Implement the Operator Functions
-
-For this specific use case, two operators, anomaly and counter are used, which are already registered in FogFlow. Refer
-to the examples provided in the code repository.
-
-- [Anomaly Detector](https://github.com/smartfog/fogflow/tree/master/application/operator/anomaly) operator is to
- detect anomaly events based on the collected data from power panels in a retail store. It has two types of inputs:
-
- - detection rules are provided and updated by the operator; The detection rules input stream type is associated
- with `broadcast`, meaning that the rules are needed by all task instances of this operator. The granularity of
- this operator is based on `shopID`, meaning that a dedicated task instance will be created and configured for
- each shop.
- - sensor data are provided by power panel.
-
-- [Counter](https://github.com/smartfog/fogflow/tree/master/application/operator/counter) operator is to count the
- total number of anomaly events for all shops in each city. Therefore, its task granularity is by `city`. Its input
- stream type is the output stream type of the previous operator (Anomaly Detector).
-
-There are two types of result consumers:
-
-1. a dashboard service in the cloud, which subscribes to the final aggregation results generated by the counter
- operator for the global scope;
-2. the alarm in each shop, which subscribes to the anomaly events generated by the Anomaly Detector task on the local
- edge node in the retail store.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retail-flow.png)
-
-### Specify the Service Topology
-
-Assume that the tasks to be used in the service topology have been implemented and registered, just specify the service
-topology in the following way using FogFlow Topology Editor.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/retail-topology-1.png)
-
-As seen in the picture, the following important information must be provided.
-
-1. define topology profile, including
-
- - topology name: the unique name of your topology
- - service description: some text to describe what this service is about
-
-2. draw the graph of data processing flows within the service topology with a right click at some place of the design
- board, choose either task or input streams or shuffle to define your data processing flows according to the design
- you have in mind.
-
-3. define the profile for each element in the data flow including the following using the configuration button of each.
-
- - **Task** profile can be defined by specifying name, operator and entity type.
- - **EntityStream** profile is updated with SelectedType, SelectedAttributes, Groupby, Scoped fields.
- - **Shuffle** element serves as a connector between two tasks such that output of a task is the input for the
- shuffle element and same is forwarded by Shuffle to another task (or tasks) as input.
-
-### Trigger the Service Topology by sending an Intent
-
-Service Topology can be triggered in two steps:
-
-- Sending a high level intent object which breaks the service topology into separate tasks
-- Providing Input Streams to the tasks of that service topology.
-
-The intent object is sent using the FogFlow dashboard with the following properties:
-
-- **Topology:** specifies which topology the intent object is meant for.
-- **Priority:** defines the priority level of all tasks in your topology, which will be utilized by edge nodes to
- decide how resources should be assigned to the tasks.
-- **Resource Usage:** defines how a topology can use resources on edge nodes. Sharing in an exclusive way means the
- topology will not share the resources with any task from other topologies. The other way is inclusive one.
-- **Objective:** of maximum throughput, minimum latency and minimum cost can be set for task assignment at workers.
- However, this feature is not fully supported yet, so it can be set as "None" for now.
-- **Geoscope:** is a defined geographical area where input streams should be selected. Global as well as custom
- geoscopes can be set.
-
-![](https://fiware.github.io/tutorials.Edge-Computing/img/intent-registry.png)
-
-As soon as context data are received, which fall within the scope of the intent object, tasks are launched on the
-nearest workers.
-
-Here are curl examples to send Input streams for Anomaly-Detector use case. It requires PowerPanel as well as Rule data.
-
-> [!NOTE]
-> Users can also use
-> [Simulated Powerpanel Devices](https://github.com/smartfog/fogflow/tree/544ebe782467dd81d5565e35e2827589b90e9601/application/device/powerpanel)
-> to send PowerPanel data.
->
-> The Curl case assumes that the cloud IoT Broker is running on localhost on port 8070.
-
-#### 2️⃣ Request
-
-```console
-curl -iX POST \
- 'http://localhost:8070/ngsi10/updateContext' \
--H 'Content-Type: application/json' \
--d '
- {
- "contextElements": [
- {
- "entityId":{
- "id":"Device.PowerPanel.01", "type":"PowerPanel"
- },
- "attributes":[
- {
- "name":"usage", "type":"integer", "value":4
- },
- {
- "name":"shop", "type":"string", "value":"01"
- },
- {
- "name":"iconURL", "type":"string", "value":"/img/shop.png"
- }
- ],
- "domainMetadata":[
- {
- "name":"location", "type":"point",
- "value": {
- "latitude":35.7,
- "longitude":138
- }
- },
- {
- "name":"shop", "type":"string", "value":"01"
- }
- ]
- }
- ],
- "updateAction": "UPDATE"
-}'
+./services create
+./services start
```
-Outputs of the Service Topology will be published to the Broker, any application subscribing to the data will receive
-the notification. An actuator device can also receive these streams as inputs from the Broker. Resulting streams will
-also be visible in the Streams menu on FogFlow dashboard.
-
-# Next Steps
-
-For additional material to understand how FogFlow works, visit
-[FogFlow tutorial](https://fogflow.readthedocs.io/en/latest/introduction.html). FogFlow can also be integrated with
-other FIWARE GEs.
-
-- **Integrate FogFlow with NGSI-LD Broker**: FogFlow has evolved into a robust platform that supports cloud and edge
- nodes. The main concept of having distributed edges for edge-computation has evolved with the interaction of Fogflow
- and other NGSI-LD brokers. NGSI-LD technology is the new horizon of data communication and data representation.
- Fogflow is now a NGSI_LD compliant broker. For detailed information, please refer this
- [tutorial](https://fogflow.readthedocs.io/en/latest/scorpioIntegration.html).
-
-- **Integrate FogFlow with Monitoring Tools**: FogFlow has a distributed architecture and therefore it generates a
- need to monitor the distributed components of Fogflow from a platform. For this cause Fogflow has integrated grafana
- and elastisearch, to monitor various components like memory utilisation, CPU utilisation and services current state
- etc.. To have more details over this topic, follow this
- [tutorial](https://fogflow.readthedocs.io/en/latest/system_monitoring.html).
-
-- **Integrate FogFlow with Security Components**: FogFlow has enhanced itself, by supporting security features. The
- communication between IoT devices and edges, and communication between cloud and edge has been secured using IDM
- (Identity Manager - Keyrock) and Wilma (PEP-Proxy). To know more about the security setup in FogFlow, follow this
- [tutorial](https://fogflow.readthedocs.io/en/latest/https.html#secure-fogflow-using-identity-management).
-
-- **Integrate FogFlow with QuantumLeap**: FogFlow can integrate with QuantumLeap, which is a REST service for storing,
- querying and retrieving NGSI-v2 spatial-temporal data. QuantumLeap converts NGSI semi-structured data into tabular
- format and stores it in a time-series database. This has opened up new possibilities for utilising FogFlow in
- different scenarios. For more on this, refer the
- [tutorial](https://fogflow.readthedocs.io/en/latest/quantumleapIntegration.html).
+| [![NGSI LD](https://img.shields.io/badge/NGSI-LD-d6604d.svg)](https://www.etsi.org/deliver/etsi_gs/CIM/001_099/009/01.08.01_60/gs_cim009v010801p.pdf) | :books: [Documentation](https://github.com/FIWARE/tutorials.Edge-Computing/tree/NGSI-LD) | [Postman Collection](https://fiware.github.io/tutorials.Edge-Computing/ngsi-ld.html) |
+| --- | --- | --- |
-- **Integrate FogFlow with WireCloud**: FogFlow has pitched in with different and versatile edge platform technology.
- WireCloud builds on cutting-edge end user development, RIA and semantic technologies to offer a next-generation end
- user centred web application mashup platform aimed at leveraging the long tail of the Internet of Services. For more
- on Fogflow and WireCloud, follow the [tutorial](https://fogflow.readthedocs.io/en/latest/wirecloudIntegration.html).
---
diff --git a/config.json b/config.json
deleted file mode 100644
index 5ab83ed..0000000
--- a/config.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "my_hostip": "172.30.48.46",
- "physical_location":{
- "longitude": 139.709059,
- "latitude": 35.692221
- },
- "site_id": "001",
- "logging":{
- "info":"stdout",
- "error":"stdout",
- "protocol": "stdout",
- "debug": "stdout"
- },
- "discovery": {
- "http_port": 8090
- },
- "broker": {
- "http_port": 8070
- },
- "master": {
- "ngsi_agent_port": 1060
- },
- "worker": {
- "container_autoremove": false,
- "start_actual_task": true,
- "capacity": 8
- },
- "designer": {
- "webSrvPort": 8080,
- "agentPort": 1030
- },
- "rabbitmq": {
- "port": 5672,
- "username": "admin",
- "password":"mypass"
- },
- "https": {
- "enabled" : false
- },
- "persistent_storage": {
- "port": 9082
- }
-}
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index a73aba9..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,108 +0,0 @@
-version: "3.8"
-services:
- designer:
- labels:
- org.fiware: 'tutorial'
- image: fogflow/designer:3.2
- volumes:
- - ./config.json:/app/config.json
- ports:
- - 8080:8080
- - 1030:1030
- depends_on:
- - discovery
- - cloud_broker
- - dgraph
- restart: always
-
- discovery:
- labels:
- org.fiware: 'tutorial'
- image: fogflow/discovery:3.2
- volumes:
- - ./config.json:/config.json
- ports:
- - 8090:8090
- depends_on:
- - dgraph
- restart: always
-
- master:
- labels:
- org.fiware: 'tutorial'
- image: fogflow/master:3.2
- volumes:
- - ./config.json:/config.json
- links:
- - rabbitmq
- ports:
- - 1060:1060
- depends_on:
- - rabbitmq
- - discovery
- - cloud_broker
- - dgraph
- restart: always
-
- cloud_broker:
- labels:
- org.fiware: 'tutorial'
- image: fogflow/broker:3.2
- volumes:
- - ./config.json:/config.json
- ports:
- - 8070:8070
- depends_on:
- - discovery
- - dgraph
- restart: always
-
- cloud_worker:
- labels:
- org.fiware: 'tutorial'
- image: fogflow/worker:3.2
- volumes:
- - /tmp:/tmp
- - ./config.json:/config.json
- - /var/run/docker.sock:/var/run/docker.sock
- depends_on:
- - cloud_broker
- - rabbitmq
- restart: always
-
- rabbitmq:
- labels:
- org.fiware: 'tutorial'
- image: rabbitmq:3
- ports:
- - 5672:5672
- environment:
- - RABBITMQ_DEFAULT_USER=admin
- - RABBITMQ_DEFAULT_PASS=mypass
- restart: always
-
- nginx:
- labels:
- org.fiware: 'tutorial'
- image: nginx:latest
- volumes:
- - ./nginx.conf:/etc/nginx/nginx.conf
- ports:
- - 80:80
- depends_on:
- - discovery
- - cloud_broker
- - designer
- restart: always
-
- dgraph:
- labels:
- org.fiware: 'tutorial'
- image: dgraph/standalone
- volumes:
- - ./dgraph:/dgraph
- ports:
- - 6080:6080
- - 8082:8080
- - 9082:9080
- - 8000:8000
diff --git a/dummy/build b/dummy/build
deleted file mode 100755
index 989d3bc..0000000
--- a/dummy/build
+++ /dev/null
@@ -1,2 +0,0 @@
-npm install
-docker build -t "fogflow/dummy" .
diff --git a/dummy/dockerfile b/dummy/dockerfile
deleted file mode 100644
index d7571f3..0000000
--- a/dummy/dockerfile
+++ /dev/null
@@ -1,5 +0,0 @@
-FROM node:alpine
-
-WORKDIR /app
-ADD . /app
-ENTRYPOINT [ "node", "main.js" ]
diff --git a/dummy/function.js b/dummy/function.js
deleted file mode 100644
index eccdab7..0000000
--- a/dummy/function.js
+++ /dev/null
@@ -1,36 +0,0 @@
-exports.handler = function (contextEntity, publish, query, subscribe) {
- console.log('enter into the user-defined fog function');
-
- var entityID = contextEntity.entityId.id;
-
- if (contextEntity == null) {
- return;
- }
- if (contextEntity.attributes == null) {
- return;
- }
-
- var updateEntity = {};
- updateEntity.entityId = {
- id: 'Stream.result.' + entityID,
- type: 'result',
- isPattern: false
- };
- updateEntity.attributes = {};
- updateEntity.attributes.city = {
- type: 'string',
- value: 'Heidelberg'
- };
-
- updateEntity.metadata = {};
- updateEntity.metadata.location = {
- type: 'point',
- value: {
- latitude: 33.0,
- longitude: -1.0
- }
- };
-
- console.log('publish: ', updateEntity);
- publish(updateEntity);
-};
diff --git a/dummy/main.js b/dummy/main.js
deleted file mode 100644
index 9045b8c..0000000
--- a/dummy/main.js
+++ /dev/null
@@ -1,216 +0,0 @@
-'use strict';
-
-const NGSIClient = require('./ngsi/ngsiclient.js');
-const NGSIAgent = require('./ngsi/ngsiagent.js');
-const fogfunction = require('./function.js');
-
-var ngsi10client = null;
-var brokerURL;
-var outputs = [];
-var threshold = 30;
-var myReferenceURL;
-var mySubscriptionId = null;
-var isConfigured = false;
-
-var buffer = [];
-
-function startApp() {
- console.log('start to receive input data streams via a listening port');
-}
-
-function stopApp() {
- console.log('clean up the app');
-}
-
-// handle the commands received from the engine
-function handleAdmin(req, commands, res) {
- console.log('=============configuration commands=============');
- console.log(commands);
-
- handleCmds(commands);
-
- isConfigured = true;
-
- res.status(200).json({});
-}
-
-function handleCmds(commands) {
- for (var i = 0; i < commands.length; i++) {
- var cmd = commands[i];
- console.log(cmd);
- handleCmd(cmd);
- console.log('handle next command');
- }
-
- // send the updates in the buffer
- sendUpdateWithinBuffer();
-}
-
-function handleCmd(commandObj) {
- if (commandObj.command == 'CONNECT_BROKER') {
- connectBroker(commandObj);
- } else if (commandObj.command == 'SET_OUTPUTS') {
- setOutputs(commandObj);
- } else if (commandObj.command == 'SET_REFERENCE') {
- setReferenceURL(commandObj);
- }
-}
-
-// connect to the IoT Broker
-function connectBroker(cmd) {
- brokerURL = cmd.brokerURL;
- ngsi10client = new NGSIClient.NGSI10Client(brokerURL);
- console.log('connected to broker', cmd.brokerURL);
-}
-
-function setReferenceURL(cmd) {
- myReferenceURL = cmd.url;
- console.log(
- 'your application can subscribe addtional inputs under the reference URL: ',
- myReferenceURL
- );
-}
-
-function setOutputs(cmd) {
- var outputStream = {};
- outputStream.id = cmd.id;
- outputStream.type = cmd.type;
-
- outputs.push(outputStream);
-
- console.log('output has been set: ', cmd);
-}
-
-function sendUpdateWithinBuffer() {
- for (var i = 0; i < buffer.length; i++) {
- var tmp = buffer[i];
-
- if (tmp.outputIdx > 0) {
- tmp.ctxObj.entityId.id = outputs[i].id;
- tmp.ctxObj.entityId.type = outputs[i].type;
- }
-
- ngsi10client
- .updateContext(tmp.ctxObj)
- .then(function (data) {
- console.log('======send update======');
- console.log(data);
- })
- .catch(function (error) {
- console.log(error);
- console.log('failed to update context');
- });
- }
-
- buffer = [];
-}
-
-//
-// query results from the assigned nearby IoT broker
-//
-function query(queryCtxReq, f) {
- if (ngsi10client == null) {
- console.log('=== broker is not configured for your query');
- return;
- }
-
- ngsi10client
- .queryContext(queryCtxReq)
- .then(f)
- .catch(function (error) {
- console.log('failed to subscribe context');
- });
-}
-
-//
-// send subscriptions to IoT broker
-//
-function subscribe(subscribeCtxReq) {
- if (ngsi10client == null) {
- console.log('=== broker is not configured for your subscription');
- return;
- }
-
- subscribeCtxReq.reference = myReferenceURL;
-
- console.log('================trigger my own subscription===================');
- console.log(subscribeCtxReq);
-
- ngsi10client
- .subscribeContext(subscribeCtxReq)
- .then(function (subscriptionId) {
- console.log('subscription id = ' + subscriptionId);
- mySubscriptionId = subscriptionId;
- })
- .catch(function (error) {
- console.log('failed to subscribe context');
- });
-}
-
-//
-// publish context entities:
-//
-function publish(ctxUpdate) {
- buffer.push(ctxUpdate);
-
- if (ngsi10client == null) {
- console.log('=== broker is not configured for your update');
- return;
- }
-
- for (var i = 0; i < buffer.length; i++) {
- var update = buffer[i];
-
- ngsi10client
- .updateContext(update)
- .then(function (data) {
- console.log('======send update======');
- console.log(data);
- })
- .catch(function (error) {
- console.log(error);
- console.log('failed to update context');
- });
- }
-
- buffer = [];
-}
-
-// handle the received results
-function handleNotify(req, ctxObjects, res) {
- console.log('============handle notify==========================');
- for (var i = 0; i < ctxObjects.length; i++) {
- console.log(ctxObjects[i]);
-
- try {
- fogfunction.handler(ctxObjects[i], publish, query, subscribe);
- } catch (error) {
- console.log(error);
- }
- }
-}
-
-// get the listening port number from the environment variables given by the FogFlow edge worker
-var myport = process.env.myport;
-
-var adminCfg = process.env.adminCfg;
-console.log('handle the initial admin configuration', adminCfg);
-try {
- const commands = JSON.parse(adminCfg);
- handleCmds(commands);
- isConfigured = true;
-} catch (err) {
- console.error(err);
-}
-
-// set up the NGSI agent to listen on
-NGSIAgent.setNotifyHandler(handleNotify);
-NGSIAgent.setAdminHandler(handleAdmin);
-NGSIAgent.start(myport, startApp);
-
-process.on('SIGINT', function () {
- NGSIAgent.stop();
- stopApp();
-
- process.exit(0);
-});
diff --git a/dummy/ngsi/ngsiagent.js b/dummy/ngsi/ngsiagent.js
deleted file mode 100644
index 0ac698e..0000000
--- a/dummy/ngsi/ngsiagent.js
+++ /dev/null
@@ -1,174 +0,0 @@
-'use strict';
-
-var http = require('http'),
- express = require('express'),
- logger = require('logops'),
- bodyParser = require('body-parser'),
- northboundServer,
- notifyHandler,
- adminHandler;
-
-
-function CtxElement2JSONObject(e) {
- var jsonObj = {};
- jsonObj.entityId = e.entityId;
-
- jsonObj.attributes = {}
- for(var i=0; e.attributes && i",
- "main": "main.js",
- "scripts": {
- "start": "node main.js"
- },
- "dependencies": {
- "express": "^4.13.3",
- "axios": "*",
- "logops": "*",
- "body-parser": "*"
- }
-}
diff --git a/nginx.conf b/nginx.conf
deleted file mode 100644
index b1d6c8a..0000000
--- a/nginx.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-events {
- worker_connections 4096;
-}
-
-http {
- server {
- listen 80;
- server_name www.fogflow.io;
-
- location / {
- proxy_pass http://designer:8080/;
- }
-
- location /ngsi9/ {
- proxy_pass http://discovery:8090/ngsi9/;
- }
-
- location /ngsi10/ {
- proxy_pass http://cloud_broker:8070/ngsi10/;
- }
-
- location /ngsi-ld/ {
- proxy_pass http://cloud_broker:8070/ngsi-ld/;
- }
- }
-}
-
-
-
-
diff --git a/services b/services
index 3de4b68..c744bc4 100755
--- a/services
+++ b/services
@@ -2,84 +2,8 @@
#
# Command Line Interface to start all services associated with the Tutorial
#
-# For this tutorial the commands are merely a convenience script to run docker or docker-compose
-#
-# Each services script can be run using either docker-compose (the external tool with the hyphen -)
-# or docker compose (the newer version directly bundled with Docker with a space )
-#
-# if you start up with the following command:
-#
-# ./services start legacy
-#
-# This will force the script to use docker-compose which may be more reliable in
-# some cases (or if an older version of Docker is being used)
set -e
-dockerCmd="docker compose"
-if (( $# == 2 )); then
- dockerCmd="docker-compose"
-fi
-
-if (( $# < 1 )); then
- echo "Illegal number of parameters"
- echo "usage: services [create|start|stop]"
- exit 1
-fi
-
-
-stoppingContainers () {
- CONTAINERS=$(docker ps --filter "label=org.fiware=tutorial" -aq)
- if [[ -n $CONTAINERS ]]; then
- echo "Stopping containers"
- docker rm -f $CONTAINERS || true
- fi
- VOLUMES=$(docker volume ls -qf dangling=true)
- if [[ -n $VOLUMES ]]; then
- echo "Removing old volumes"
- docker volume rm $VOLUMES || true
- fi
- NETWORKS=$(docker network ls --filter "label=org.fiware=tutorial" -q)
- if [[ -n $NETWORKS ]]; then
- echo "Removing tutorial networks"
- docker network rm $NETWORKS || true
- fi
-}
-
-displayServices () {
- echo ""
- docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" --filter name=fiware-*
- (gp ports list 2> /dev/null) || true
- echo ""
-}
-
-
-
-command="$1"
-case "${command}" in
- "help")
- echo "usage: services [create|start|stop]"
- ;;
- "start")
- stoppingContainers
- echo -e "Starting containers: including \033[1;35mFogFlow\033[0m, an \033[1mNGINX\033[0m instance, and \033[1mRabbitMQ\033[0m message broker."
- echo ""
- ${dockerCmd} up -d --remove-orphans
- displayServices
- ;;
- "stop")
- export $(cat .env | grep "#" -v)
- stoppingContainers
- ;;
- "create")
- export $(cat .env | grep "#" -v)
- echo "Pulling Docker images"
- docker pull -q quay.io/curl/curl
- ${dockerCmd} pull --ignore-pull-failures
- ;;
- *)
- echo "Command not Found."
- echo "usage: services [create|start|stop]"
- exit 127;
- ;;
-esac
+echo -e "Checkout the \033[1;36mNGSI-v2\033[0m branch of this repository to run the Smart Supermarket tutorial.\n"
+echo -e "Checkout the \033[1;31mNGSI-LD\033[0m branch of this repository to run the Smart Farm tutorial.\n"
diff --git a/start.sh b/start.sh
deleted file mode 100755
index 2d8cefd..0000000
--- a/start.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-if [ $# -eq 0 ]; then
- htype='3.2'
-else
- htype='arm'
-fi
-
-docker run -d --name=edgebroker -v $(pwd)/config.json:/config.json -p 8170:8170 fogflow/broker:$htype
-docker run -d --name=edgeworker -v $(pwd)/config.json:/config.json -v /tmp:/tmp -v /var/run/docker.sock:/var/run/docker.sock fogflow/worker:$htype
-
diff --git a/stop.sh b/stop.sh
deleted file mode 100755
index 17638b6..0000000
--- a/stop.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-docker stop edgebroker && docker rm $_
-docker stop edgeworker && docker rm $_
diff --git a/templates/java/build b/templates/java/build
deleted file mode 100755
index 7c52519..0000000
--- a/templates/java/build
+++ /dev/null
@@ -1,3 +0,0 @@
-mvn clean install
-
-docker build -t "javafogfunction" .
diff --git a/templates/java/dockerfile b/templates/java/dockerfile
deleted file mode 100644
index 2ae98a2..0000000
--- a/templates/java/dockerfile
+++ /dev/null
@@ -1,5 +0,0 @@
-FROM openjdk:12-jdk-alpine
-VOLUME /tmp
-COPY target/fogfunction.jar app.jar
-EXPOSE 8080
-ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
diff --git a/templates/java/pom.xml b/templates/java/pom.xml
deleted file mode 100644
index 8f2a942..0000000
--- a/templates/java/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
- 4.0.0
-
- com.fogflow.fogfunction
- fogfunction
- 0.0.1-SNAPSHOT
- jar
-
- fogfunction
- Fog Function Demo based on Spring Boot
-
-
- org.springframework.boot
- spring-boot-starter-parent
- 2.0.4.RELEASE
-
-
-
-
- UTF-8
- UTF-8
- 1.8
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
- org.hibernate
- hibernate-entitymanager
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
- fogfunction
-
-
-
-
diff --git a/templates/java/readme.MD b/templates/java/readme.MD
deleted file mode 100644
index 8f0c0d5..0000000
--- a/templates/java/readme.MD
+++ /dev/null
@@ -1,11 +0,0 @@
-
-How to use this template:
-1) overwrite the “ handleEntityObject" function to implement your own application logic in the file https://github.com/smartfog/fogflow/blob/master/application/template/java/src/main/java/com/fogflow/fogfunction/RestHandler.java
-
-2) use Eclipse to write your own code
-
-3) use the script “build” to build the docker image
-
-4) register this operator in FogFlow via FogFlow Task Designer
-
-5) specify a fog function to use this operator
diff --git a/templates/java/src/main/java/com/fogflow/fogfunction/MainApplication.java b/templates/java/src/main/java/com/fogflow/fogfunction/MainApplication.java
deleted file mode 100644
index 6cef371..0000000
--- a/templates/java/src/main/java/com/fogflow/fogfunction/MainApplication.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.fogflow.fogfunction;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class MainApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(MainApplication.class, args);
- }
-}
diff --git a/templates/java/src/main/java/com/fogflow/fogfunction/RestHandler.java b/templates/java/src/main/java/com/fogflow/fogfunction/RestHandler.java
deleted file mode 100644
index 440b521..0000000
--- a/templates/java/src/main/java/com/fogflow/fogfunction/RestHandler.java
+++ /dev/null
@@ -1,521 +0,0 @@
-package com.fogflow.fogfunction;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.util.Assert;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.client.RestTemplate;
-
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.core.JsonGenerationException;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-class Config {
- Map details = new LinkedHashMap<>();
-
- @JsonAnySetter
- void setDetail(String key, String value) {
- details.put(key, value);
- }
-}
-
-class StatusCode {
- public int code;
- public String reasonPhrase;
- public String details;
-
- public StatusCode() {
-
- }
-
- public int getCode() {
- return code;
- }
- public void setCode(int code) {
- this.code = code;
- }
-
- public String getReasonPhrase() {
- return reasonPhrase;
- }
- public void setReasonPhrase(String reasonPhrase) {
- this.reasonPhrase = reasonPhrase;
- }
-
- public String getDetails() {
- return details;
- }
- public void setDetailsn(String details) {
- this.details = details;
- }
-}
-
-class EntityId {
- public String id;
- public String type;
- public boolean isPattern;
-
- public EntityId() {
-
- }
-
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
-
- public String getType() {
- return type;
- }
- public void setType(String type) {
- this.type = type;
- }
-
- public boolean getIsPattern() {
- return isPattern;
- }
- public void setIsPattern(boolean isPattern) {
- this.isPattern = isPattern;
- }
-}
-
-class ContextMetadata {
- public String name;
- public String type;
- public Object value;
-
- public ContextMetadata() {
-
- }
-
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
-
- public String getType() {
- return type;
- }
- public void setType(String type) {
- this.type = type;
- }
-
- public Object getValue() {
- return value;
- }
- public void setValue(Object value) {
- this.value = value;
- }
-}
-
-class ContextAttribute {
- public String name;
- public String type;
- public Object value;
-
- @JsonProperty("metadata")
- public List metadata;
-
- public ContextAttribute() {
-
- }
-
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
-
- public String getType() {
- return type;
- }
- public void setType(String type) {
- this.type = type;
- }
-
- public Object getValue() {
- return value;
- }
- public void setValue(Object value) {
- this.value = value;
- }
-
- @JsonIgnore
- public List getMetadata() {
- if (metadata == null) {
- metadata = new ArrayList();
- }
-
- return metadata;
- }
-
- @JsonIgnore
- public void setMetadata(List metadata) {
- this.metadata = metadata;
- }
-}
-
-
-class ContextElement {
- public EntityId entityId;
-
- @JsonProperty("attributes")
- public List attributes;
-
- @JsonProperty("domainMetadata")
- public List domainMetadata;
-
- public ContextElement() {
- attributes = new ArrayList();
- domainMetadata = new ArrayList();
- }
-
- public ContextElement(ContextObject obj) {
- entityId = new EntityId();
-
- entityId.id = obj.id;
- entityId.type = obj.type;
- entityId.isPattern = false;
-
- for (Map.Entry entry : obj.attributes.entrySet()) {
- if (attributes == null) {
- attributes = new ArrayList();
- }
- attributes.add(entry.getValue());
- }
-
- for (Map.Entry entry : obj.domainMetadata.entrySet()) {
- if (domainMetadata == null) {
- domainMetadata = new ArrayList();
- }
- domainMetadata.add(entry.getValue());
- }
- }
-
- public EntityId getEntityId() {
- return entityId;
- }
-
- public void setEntityId(EntityId entityId) {
- this.entityId = entityId;
- }
-
- @JsonIgnore
- public List getAttributes() {
- return attributes;
- }
-
- @JsonIgnore
- public void setAttributes(List attributes) {
- this.attributes = attributes;
- }
-
- @JsonIgnore
- public List getDomainMetadata() {
- return domainMetadata;
- }
-
- @JsonIgnore
- public void setDomainMetadata(List domainMetadata) {
- this.domainMetadata = domainMetadata;
- }
-}
-
-class ContextElementResponse {
- public ContextElement contextElement;
- public StatusCode statusCode;
-
- public ContextElementResponse() {
-
- }
-
- public ContextElement getContextElement() {
- return contextElement;
- }
-
- public void setContextElement(ContextElement contextElement) {
- this.contextElement = contextElement;
- }
-
- public StatusCode getStatusCode() {
- return statusCode;
- }
-
- public void setStatusCode(StatusCode statusCode) {
- this.statusCode = statusCode;
- }
-}
-
-class Notification {
- public String subscriptionId;
- public String originator;
-
- @JsonProperty("contextResponses")
- public List contextResponses;
-
- public Notification() {
- contextResponses = new ArrayList();
- }
-
- public String getSubscriptionId() {
- return subscriptionId;
- }
-
- public void setSubscriptionId(String subscriptionId) {
- this.subscriptionId = subscriptionId;
- }
-
- public String getOriginator() {
- return originator;
- }
-
- public void setOriginator(String originator) {
- this.originator = originator;
- }
-
- @JsonIgnore
- public List getResponse() {
- return contextResponses;
- }
-
- @JsonIgnore
- public void setResponse(List contextResponses) {
- this.contextResponses = contextResponses;
- }
-}
-
-
-class ContextObject {
- public String id;
- public String type;
-
- public Map attributes = new LinkedHashMap<>();
-
- public Map domainMetadata = new LinkedHashMap<>();
-
- public ContextObject() {
-
- }
-
- public ContextObject(ContextElement element) {
- id = element.entityId.id;
- type = element.entityId.type;
-
- for(ContextAttribute attr : element.attributes) {
- attributes.put(attr.name, attr);
- }
-
- for(ContextMetadata meta : element.domainMetadata) {
- domainMetadata.put(meta.name, meta);
- }
- }
-}
-
-
-class UpdateContextRequest {
- public String updateAction;
-
- @JsonProperty("contextElements")
- public List contextElements;
-
- public UpdateContextRequest() {
- contextElements = new ArrayList();
- }
-
-
- @JsonIgnore
- public List getContextElements() {
- return contextElements;
- }
-
- @JsonIgnore
- public void setContextElements(List contextElements) {
- this.contextElements = contextElements;
- }
-
- public void addContextElement(ContextElement element) {
- this.contextElements.add(element);
- }
-
- public String getUpdateAction() {
- return updateAction;
- }
-
- public void setUpdateAction(String updateAction) {
- this.updateAction = updateAction;
- }
-}
-
-
-class UpdateContextResponse {
- List contextResponses;
- StatusCode errorCode;
-
- public UpdateContextResponse() {
- contextResponses = new ArrayList();
- }
-
-
- @JsonIgnore
- public List getContextResponses() {
- return contextResponses;
- }
-
- @JsonIgnore
- public void setContextResponses(List contextResponses) {
- this.contextResponses = contextResponses;
- }
-
-
- public StatusCode getStatusCode() {
- return errorCode;
- }
-
- public void setStatusCode(StatusCode errorCode) {
- this.errorCode = errorCode;
- }
-}
-
-@RestController
-public class RestHandler {
- private String BrokerURL;
-
- private String outputEntityId;
- private String outputEntityType;
-
- @PostConstruct
- private void setup() {
- System.out.print("=========test========");
- String jsonText = System.getenv("adminCfg");
- this.handleInitAdminCfg(jsonText);
- }
-
- @PostMapping("/admin")
- public ResponseEntity handleConfig(@RequestBody List configs) {
- for(Config cfg : configs) {
- System.out.println(cfg.details.get("command"));
- if (cfg.details.get("command").equalsIgnoreCase("CONNECT_BROKER") == true) {
- this.BrokerURL = cfg.details.get("brokerURL");
- } else if (cfg.details.get("command").equalsIgnoreCase("SET_OUTPUTS") == true) {
- this.outputEntityId = cfg.details.get("id");
- this.outputEntityType = cfg.details.get("type");
- }
- }
-
- System.out.println(this.BrokerURL.toString());
- System.out.println(this.outputEntityId.toString());
- System.out.println(this.outputEntityType.toString());
-
- return ResponseEntity.ok().build();
- }
-
-
- public void handleInitAdminCfg(String config) {
- ObjectMapper mapper = new ObjectMapper();
-
- try {
- List myAdminCfgs = mapper.readValue(config, new TypeReference>(){});
- this.handleConfig(myAdminCfgs);
- } catch (JsonGenerationException e) {
- e.printStackTrace();
- } catch (JsonMappingException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- @PostMapping("/notifyContext")
- public ResponseEntity handleNotify(@RequestBody Notification notify) {
- System.out.println(notify.subscriptionId);
-
- for(ContextElementResponse response : notify.contextResponses) {
- System.out.println(response.toString());
- if (response.statusCode.code == 200) {
- ContextObject contextObj = new ContextObject(response.contextElement);
- handleEntityObject(contextObj);
- }
- }
-
- return ResponseEntity.ok().build();
- }
-
- // to be overwritten according to your own data processing logic
- private void handleEntityObject(ContextObject entity) {
- System.out.println(entity.id);
- System.out.println(entity.type);
-
- ContextObject resultEntity = new ContextObject();
- resultEntity.id = "Test." + entity.id;
- resultEntity.type = "Result";
-
- ContextAttribute attr = new ContextAttribute();
- attr.name = "avg";
- attr.type = "integer";
- attr.value = 10;
-
- resultEntity.attributes.put("avg", attr);
-
- publishResult(resultEntity);
- }
-
-
- // to publish the generated result entity
- private void publishResult(ContextObject resultEntity) {
- if (resultEntity.id == "") {
- resultEntity.id = outputEntityId;
- }
-
- if (resultEntity.type == "") {
- resultEntity.type = outputEntityType;
- }
-
- // send it to the nearby broker, assigned by FogFlow Broker
- RestTemplate restTemplate = new RestTemplate();
-
- try {
- URI uri = new URI(BrokerURL + "/updateContext");
-
- ContextElement element = new ContextElement(resultEntity);
-
- UpdateContextRequest request = new UpdateContextRequest();
- request.addContextElement(element);
- request.setUpdateAction("UPDATE");
-
- ObjectMapper mapper = new ObjectMapper();
- try {
- String json = mapper.writeValueAsString(request);
- System.out.println("JSON = " + json);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
-
- ResponseEntity result = restTemplate.postForEntity(uri, request, UpdateContextResponse.class);
-
- System.out.println(result.getStatusCodeValue());
-
- }catch(Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/templates/java/src/main/resources/application.properties b/templates/java/src/main/resources/application.properties
deleted file mode 100644
index 1f146fa..0000000
--- a/templates/java/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-server.port=${myport}
\ No newline at end of file
diff --git a/templates/javascript/build b/templates/javascript/build
deleted file mode 100644
index 6ceeb6b..0000000
--- a/templates/javascript/build
+++ /dev/null
@@ -1,2 +0,0 @@
-npm install
-docker build -t "fogflow/connectedcar" .
diff --git a/templates/javascript/dockerfile b/templates/javascript/dockerfile
deleted file mode 100644
index 665b389..0000000
--- a/templates/javascript/dockerfile
+++ /dev/null
@@ -1,5 +0,0 @@
-FROM mhart/alpine-node
-
-WORKDIR /app
-ADD . /app
-ENTRYPOINT [ "node", "main.js" ]
diff --git a/templates/javascript/function.js b/templates/javascript/function.js
deleted file mode 100644
index 6828127..0000000
--- a/templates/javascript/function.js
+++ /dev/null
@@ -1,80 +0,0 @@
-// define global variables or include third-party libraries (notice that the library must be specified in the package.json file as well)
-var speakerID = null;
-
-//
-// contextEntity: the received entities
-// publish, query, and subscribe are the callback functions for your own function to interact with the assigned nearby broker
-// publish: publish the generated entity, which could be a new entity or the update of an existing entity
-// query: query addtional information from the assigned nearby broker
-// subscribe: subscribe addtional infromation from the assigned nearby broker
-//
-exports.handler = function(contextEntity, publish, query, subscribe)
-{
- console.log("enter into the user-defined fog function");
-
- if (contextEntity == null) {
- return;
- }
- if (contextEntity.attributes == null) {
- return;
- }
-
- // ============================== publish ======================================================
-
- // if you need to publish the generated result, please refer to the following example
-
- /*
- var updateEntity = {};
- updateEntity.entityId = {
- id: "Twin.Home.0001",
- type: 'Home',
- isPattern: false
- };
- updateEntity.attributes = {};
- updateEntity.attributes.city = {type: 'string', value: 'Heidelberg'};
-
- updateEntity.metadata = {};
- updateEntity.metadata.location = {
- type: 'point',
- value: {'latitude': 33.0, 'longitude': -1.0}
- };
-
- publish(updateEntity);
- console.log("publish: ", updateEntity);
- */
-
-
- // ============================== query ======================================================
-
- // if you want to query addtional information from the assigned nearby broker, please refer to the following example
-
- /*
- var queryReq = {}
- queryReq.entities = [{type:'PublicSite', isPattern: true}];
- var handleQueryResult = function(entityList) {
- for(var i=0; i 0) {
- tmp.ctxObj.entityId.id = outputs[i].id;
- tmp.ctxObj.entityId.type = outputs[i].type;
- }
-
- ngsi10client.updateContext(tmp.ctxObj).then( function(data) {
- console.log('======send update======');
- console.log(data);
- }).catch(function(error) {
- console.log(error);
- console.log('failed to update context');
- });
- }
-
- buffer= [];
-}
-
-//
-// query results from the assigned nearby IoT broker
-//
-function query(queryCtxReq, f)
-{
- if (ngsi10client == null) {
- console.log("=== broker is not configured for your query");
- return
- }
-
- ngsi10client.queryContext(queryCtxReq).then(f).catch( function(error) {
- console.log('failed to subscribe context');
- });
-}
-
-//
-// send subscriptions to IoT broker
-//
-function subscribe(subscribeCtxReq)
-{
- if (ngsi10client == null) {
- console.log("=== broker is not configured for your subscription");
- return
- }
-
- subscribeCtxReq.reference = myReferenceURL;
-
- console.log("================trigger my own subscription===================");
- console.log(subscribeCtxReq);
-
- ngsi10client.subscribeContext(subscribeCtxReq).then( function(subscriptionId) {
- console.log("subscription id = " + subscriptionId);
- mySubscriptionId = subscriptionId;
- }).catch(function(error) {
- console.log('failed to subscribe context');
- });
-}
-
-//
-// publish context entities:
-//
-function publish(ctxUpdate)
-{
- buffer.push(ctxUpdate)
-
- if (ngsi10client == null) {
- console.log("=== broker is not configured for your update");
- return
- }
-
- for(var i=0; i",
- "main": "main.js",
- "scripts": {
- "start": "node main.js"
- },
- "dependencies": {
- "express": "^4.13.3",
- "axios": "*",
- "logops": "*",
- "body-parser": "*"
- }
-}
diff --git a/templates/python/build b/templates/python/build
deleted file mode 100755
index 51529d6..0000000
--- a/templates/python/build
+++ /dev/null
@@ -1 +0,0 @@
-docker build -t "python-fog-function" .
diff --git a/templates/python/config.json b/templates/python/config.json
deleted file mode 100644
index c76e488..0000000
--- a/templates/python/config.json
+++ /dev/null
@@ -1,8 +0,0 @@
-[{
- "command": "CONNECT_BROKER",
- "brokerURL": "http://192.168.1.80:8091/ngsi10"
-}, {
- "command": "SET_OUTPUTS",
- "id": "Stream.ChildFound.01",
- "type": "ChildFound"
-}]
\ No newline at end of file
diff --git a/templates/python/dockerfile b/templates/python/dockerfile
deleted file mode 100644
index dc22687..0000000
--- a/templates/python/dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM python:2.7-alpine
-
-RUN mkdir /task
-ADD main.py /task
-ADD requirements.txt /task
-WORKDIR /task
-
-RUN pip install -r requirements.txt
-
-CMD ["python", "./main.py"]
diff --git a/templates/python/main.py b/templates/python/main.py
deleted file mode 100644
index 687bd84..0000000
--- a/templates/python/main.py
+++ /dev/null
@@ -1,185 +0,0 @@
-from flask import Flask, jsonify, abort, request, make_response
-import requests
-import json
-import time
-import datetime
-import threading
-import os
-
-
-app = Flask(__name__, static_url_path = "")
-
-# global variables
-brokerURL = ''
-outputs = []
-timer = None
-lock = threading.Lock()
-counter = 0
-
-@app.errorhandler(400)
-def not_found(error):
- return make_response(jsonify( { 'error': 'Bad request' } ), 400)
-
-@app.errorhandler(404)
-def not_found(error):
- return make_response(jsonify( { 'error': 'Not found' } ), 404)
-
-@app.route('/admin', methods=['POST'])
-def admin():
- if not request.json:
- abort(400)
-
- configObjs = request.json
- handleConfig(configObjs)
-
- return jsonify({ 'responseCode': 200 })
-
-
-@app.route('/notifyContext', methods = ['POST'])
-def notifyContext():
- print "=============notify============="
-
- if not request.json:
- abort(400)
-
- objs = readContextElements(request.json)
-
- global counter
- counter = counter + 1
-
- print(objs)
-
- handleNotify(objs)
-
- return jsonify({ 'responseCode': 200 })
-
-
-def element2Object(element):
- ctxObj = {}
-
- ctxObj['entityId'] = element['entityId'];
-
- ctxObj['attributes'] = {}
- if 'attributes' in element:
- for attr in element['attributes']:
- ctxObj['attributes'][attr['name']] = {'type': attr['type'], 'value': attr['value']}
-
- ctxObj['metadata'] = {}
- if 'domainMetadata' in element:
- for meta in element['domainMetadata']:
- ctxObj['metadata'][meta['name']] = {'type': meta['type'], 'value': meta['value']}
-
- return ctxObj
-
-def object2Element(ctxObj):
- ctxElement = {}
-
- ctxElement['entityId'] = ctxObj['entityId'];
-
- ctxElement['attributes'] = []
- if 'attributes' in ctxObj:
- for key in ctxObj['attributes']:
- attr = ctxObj['attributes'][key]
- ctxElement['attributes'].append({'name': key, 'type': attr['type'], 'value': attr['value']})
-
- ctxElement['domainMetadata'] = []
- if 'metadata' in ctxObj:
- for key in ctxObj['metadata']:
- meta = ctxObj['metadata'][key]
- ctxElement['domainMetadata'].append({'name': key, 'type': meta['type'], 'value': meta['value']})
-
- return ctxElement
-
-def readContextElements(data):
- print data
-
- ctxObjects = []
-
- for response in data['contextResponses']:
- if response['statusCode']['code'] == 200:
- ctxObj = element2Object(response['contextElement'])
- ctxObjects.append(ctxObj)
-
- return ctxObjects
-
-def handleNotify(contextObjs):
- for ctxObj in contextObjs:
- processInputStreamData(ctxObj)
-
-def processInputStreamData(obj):
- print '===============receive context entity===================='
- print obj
-
- global counter
- counter = counter + 1
-
-def handleConfig(configurations):
- global brokerURL
- global num_of_outputs
- for config in configurations:
- if config['command'] == 'CONNECT_BROKER':
- brokerURL = config['brokerURL']
- if config['command'] == 'SET_OUTPUTS':
- outputs.append({'id': config['id'], 'type': config['type']})
-
-def handleTimer():
- global timer
-
- # publish the counting result
- entity = {}
- entity['id'] = "result.01"
- entity['type'] = "Result"
- entity['counter'] = counter
-
- publishResult(entity)
-
- timer = threading.Timer(10, handleTimer)
- timer.start()
-
-
-def publishResult(result):
- resultCtxObj = {}
-
- resultCtxObj['entityId'] = {}
- resultCtxObj['entityId']['id'] = result['id']
- resultCtxObj['entityId']['type'] = result['type']
- resultCtxObj['entityId']['isPattern'] = False
-
- resultCtxObj['attributes'] = {}
- resultCtxObj['attributes']['counter'] = {'type': 'integer', 'value': result['counter']}
-
- # publish the real time results as context updates
- updateContext(resultCtxObj)
-
-def updateContext(ctxObj):
- global brokerURL
- if brokerURL == '':
- return
-
- ctxElement = object2Element(ctxObj)
-
- updateCtxReq = {}
- updateCtxReq['updateAction'] = 'UPDATE'
- updateCtxReq['contextElements'] = []
- updateCtxReq['contextElements'].append(ctxElement)
-
- headers = {'Accept' : 'application/json', 'Content-Type' : 'application/json'}
- response = requests.post(brokerURL + '/updateContext', data=json.dumps(updateCtxReq), headers=headers)
- if response.status_code != 200:
- print 'failed to update context'
- print response.text
-
-
-if __name__ == '__main__':
- handleTimer()
-
- myport = int(os.environ['myport'])
-
- myCfg = os.environ['adminCfg']
- adminCfg = json.loads(myCfg)
- handleConfig(adminCfg)
-
- app.run(host='0.0.0.0', port=myport)
-
- timer.cancel()
-
diff --git a/templates/python/requirements.txt b/templates/python/requirements.txt
deleted file mode 100644
index beb819f..0000000
--- a/templates/python/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Flask==1.0.2
-requests>=2.20.0
diff --git a/templates/python/subscription.json b/templates/python/subscription.json
deleted file mode 100644
index 203b88f..0000000
--- a/templates/python/subscription.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "entities": [
- {
- "type": "Camera",
- "isPattern": false,
- "id": "Stream.Camera.02"
- }
- ],
- "reference": "http://192.168.1.102:36772"
-}
diff --git a/templates/python/test.sh b/templates/python/test.sh
deleted file mode 100644
index 6d22024..0000000
--- a/templates/python/test.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#start a container for test
-#docker run -p 8009:8080 -t -i facefinder /bin/bash
-
-#configurate
-curl -X POST "http://192.168.1.80:8009/admin" -d @config.json --header "Content-Type:application/json" --header "Accept:application/json"
-
-#issue a subscription to get the input data
-curl -X POST "http://192.168.1.80:8091/ngsi10/subscribeContext" -d @subscriptionCamera.json --header "Content-Type:application/json" --header "Accept:application/json"
-curl -X POST "http://192.168.1.80:8091/ngsi10/subscribeContext" -d @subscriptionChildLost.json --header "Content-Type:application/json" --header "Accept:application/json"
-