{"id":24508445,"url":"https://github.com/opendds/smartdevice2","last_synced_at":"2025-03-15T09:20:54.931Z","repository":{"id":40954911,"uuid":"131653518","full_name":"OpenDDS/smartdevice2","owner":"OpenDDS","description":null,"archived":false,"fork":false,"pushed_at":"2022-12-10T16:16:55.000Z","size":7496,"stargazers_count":0,"open_issues_count":15,"forks_count":3,"subscribers_count":13,"default_branch":"develop","last_synced_at":"2025-01-22T00:15:45.970Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenDDS.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-30T22:39:21.000Z","updated_at":"2022-10-27T20:42:11.000Z","dependencies_parsed_at":"2023-01-26T03:45:25.232Z","dependency_job_id":null,"html_url":"https://github.com/OpenDDS/smartdevice2","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDDS%2Fsmartdevice2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDDS%2Fsmartdevice2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDDS%2Fsmartdevice2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDDS%2Fsmartdevice2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenDDS","download_url":"https://codeload.github.com/OpenDDS/smartdevice2/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243707938,"owners_count":20334732,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-22T00:16:19.290Z","updated_at":"2025-03-15T09:20:54.914Z","avatar_url":"https://github.com/OpenDDS.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# smartdevice2\n[![Build Status](https://travis-ci.org/oci-labs/smartdevice2.svg?branch=develop)](https://travis-ci.org/oci-labs/smartdevice2)\n\nThis version of the SmartDevice web app provides flexibility\nin defining the organizational hierarchy and\ntypes of supported devices.\n\n## Installs\n\n### Install Node.js\n\nThis can be done by downloading and running an installer\nfrom https://nodejs.org.\nOn a Mac with Homebrew installed,\nthis can be done by running `brew install node`.\nOn a RaspberryPi,\n```\nsudo apt-get install git \u0026\u0026 \\\ngit clone https://github.com/audstanley/NodeJs-Raspberry-Pi-Arm7 \u0026\u0026 \\\ncd NodeJs-Raspberry-Pi-Arm7 \u0026\u0026 \\\nchmod +x Install-Node.sh \u0026\u0026 \\\nsudo ./Install-Node.sh\n```\n\n### Install MySQL\n\nFollow the instructions at https://dev.mysql.com/downloads/mysql/.\nOn a Mac with Homebrew installed,\nthis can be done by running `brew install mysql`.\nOn a RaspberryPi,\n```\nsudo apt-get install mysql-server\nsudo apt-get install mysql-client\n```\nThis installs the server and client.\n\n## MQTT Setup\n\nSee `MosquittoNotes.txt` in the top directory\nfor steps to start the MQTT server on a Mac.\nOn a RaspberryPi, `sudo apt-get install mosquitto`.\n\n## Local Train Software Setup\n* open a terminal window\n* `java -jar TheJoveExpress.jar`\n\n## Local Server Setup\n* open a terminal window\n* `cd server`\n* `npm install` (initially and for each new version)\n* `npm run dbstart` (only if MySQL server isn't running)\n  - may need to run `ps -ef | grep mysql`\n    and kill some processes in order for this to work\n* `npm run dbsetup` (initially and only after schema changes)\n  - This uses database/ddl.sql.\n  - WARNING: This will delete all data in the database.\n  - It can be restored by importing a .json file.\n* `npm run build` (initially and for each new version)\n* `npm run start-dev`\n\n## Local Client Setup\n* open a terminal window\n* `cd client`\n* `npm install` (initially and for each new version)\n* `npm run start`\n* a new tab will open in the default web browser\n* two options for data\n  - to manually add data\n    * add types in the hierarchy\n    * define properties to each type\n    * define alerts for each type\n    * create instances of each type\n  - to import from a .json file\n    * click gear icon in upper-right\n    * press \"Choose File\" button\n    * select the file \"devo.json\"\n    * press \"Open\" button\n    * press \"Import\" button\n\n## Building on Raspberry Pi\n\n* `ssh pi@trainstation.local`\n* `cd Mark/smartdevice2`\n\n* `git pull` (to get latest version of code)\n\n* `cd client`\n* `npm install`\n* `npm run deploy`\n  - copies client code to `server/public`\n\n* `cd ../server`\n* `npm install`\n* `npm run dbsetup-pi`\n* `npm run build`\n* `npm start`\n* from another machine on the same WiFi,\n  browse http://trainstation.local:3001\n  (may need to use IP address of the Pi\n   which can be obtained by running ifconfig\n   and noting the wlan0...inet value)\n\n* to interactively examime the database on Pi\n  - enter `npm run dbi-pi`\n  - enter `use smartdevice`\n  - enter any SQL queries\n\n* fix for \"Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not\n  support authentication protocol requested by server\"\n  - enter `npm run dbi-pi`\n  - enter `use mysql`\n  - enter `update user set authentication_string=password(''), plugin='mysql_native_password' where user='root';`\n  - enter `flush privileges`\n  - enter `exit`\n  - start server again\n\n## Running with Docker\n\n- images run in containers\n- to build an image, use the `docker build` command\n  * see examples below\n  * the instructions for how to build an image\n    are typically placed in a file named `Dockerfile`\n- to run an existing image in a new container,\n  use the `docker run` command\n  * see examples below\n- to verify that an image exists\n  * `docker images | grep {image-name}`\n- to verify that a container exists and get its id\n  * `docker ps | grep {container-name}`\n- to view logs of a container\n  * `docker logs {container-name}`\n- to get a shell in a container\n  * `docker exec -it {container-name} bash`\n    - if you get an error saying that `bash` isn't found,\n      try `sh` instead\n- to stop a container\n  * `docker stop {container-name}`\n- to remove a stopped container\n  * `docker rm {container-name}`\n- to remove an image\n  * `docker rmi -f {image-name}`\n\n### MySQL\n- build Docker image for MySQL\n  * cd database\n  * `docker build -t oci/devodb .`\n    - image name is oci/devodb\n- run image inside a new Docker container\n  * `docker run --name devodb \\\n    -e MYSQL_ROOT_PASSWORD={password} \\\n    -e MYSQL_DATABASE=smartdevice \\\n    -p 3306:3306 -d oci/devodb`\n    - container name is devodb\n    - outputs the container id\n    - creates the \"smartdevice\" database\n    - initializes database using ddl.sql\n      which is copied into the image in DockerFileDb\n- interactively examine the database\n  * `docker exec -it devodb mysql -uroot [-p{password}]`\n  * `show databases;`\n  * `use smartdevice`\n  * `show tables;`\n  * `describe {table-name};`\n  * `exit`\n\n### Client (web UI)\n- deploy client code to server\n  * cd to client directory\n  * `npm run deploy`\n    - creates optimized production build\n    - copies to `server/public` directory\n\n### REST/Web Server\n- build Docker image\n  * cd to top project directory\n  * `docker build -t oci/devo .`\n    - image name is oci/devo\n- run image inside a new Docker container\n  * `docker run --name devo --link devodb:mysql -p3001:3001 -d oci/devo`\n    - container name is devo\n    - outputs the container id\n    - to see the ip address and host name assigned to devodb,\n      * `docker exec -it devo sh`\n      * `cat /etc/hosts | grep mysql`\n      * example output: `172.17.0.2 mysql b11f93a270a6 devodb`\n        - first item is IP address\n        - third item is host name\n- run the web app\n  * browse http://localhost:3001\n\n### Docker Compose\n- manages multiple Docker-based services\n- described in a YAML file named `docker-compose.yml`\n- to build an image for each service,\n  `docker-compose build`\n- to run these services in a container,\n  `docker-compose up`\n  * before running this, stop any locally running servers\n    for this project\n  * when this completes, browse http://localhost:3001\n  * to stop all these containers, press ctrl-c\n- to do the same but in the background,\n  `docker-compose up -d`\n  * to stop all these containers,\n    `docker-compose stop`\n    - what does `docker-compose down` do?\n- to combine building and running in one command,\n  `docker-compose up --build`\n- creates a virtual network where the virtual host names match the service names\n\n## Kubernetes\n\n### Terminology\n\n* Image - a Docker image\n* Container - a Docker container\n* Pod - Is this the Kubernetes equivalent of a Docker image?\n* Replica Set - set of pod instances that can handle requests?\n* Deployment - Is this the Kubernetes equivalent of a Docker container?\n* Service - exposes a deployment on a port\n\n### Google Cloud Platform (GCP) Setup\n- these steps assumes Docker is installed\n- to go to GCP Console\n  * browse http://cloud.google.com\n  * sign in to your OCI Google account\n  * click \"CONSOLE\" in upper-right\n  * select an existing project from dropdown near upper-left\n- install \"Google Cloud SDK\"\n  * follow steps at https://cloud.google.com/sdk/\n  * if already installed, enter `gcloud components update`\n    to get the latest version\n- install kubectl\n  * open a terminal window\n  * `gcloud components install kubectl`\n- set gcloud defaults\n  * `export PROJECT_ID=ocismartdevice`\n    - in Fish shell, `set -x PROJECT_ID ocismartdevice`\n  * `gcloud config set project $PROJECT_ID`\n  * `gcloud config set compute/zone us-central1-b`\n- create a container cluster (one-time)\n  * `gcloud container clusters create {cluster-name} --num-nodes=3`\n    - I used \"ocismartdevice\" for the cluster name\n    - takes a few minutes to complete\n  * another way is to use the web console\n    - from the Console hamburger menu select\n      Kubernetes Engine ... Kubernetes clusters\n    - press \"Create cluster\" button\n    - enter a name (ex. ocismartdevice)\n    - can accept all the other defaults\n    - press \"Create\" button\n    - takes a few minutes to complete\n\n### Google Cloud Persistent Disk\n- one use is to enable using MySQL in a way that\n  data is not lost when the database service is restarted\n- to allocate persistent disk space\n  * `gcloud compute disks create --size 1GB smartdevice-disk`\n  * 1GB is the smallest size that can be requested\n- to delete a persistent disk space\n  * `gcloud compute disks delete smartdevice-disk`\n  * this must be done before one can be recreated\n\n### Kubernetes Secrets\n- to create a Kubernetes secret\n  * `./create-secret {secret-name} {data-name} {data-value}`\n  * these are typically referenced in a Kubernetes .yaml file\n  * ex.\n    ```\n    env:\n      - name: MYSQL_ROOT_PASSWORD\n        valueFrom:\n          secretKeyRef:\n            name: mysql-root-auth\n            key: root-password\n    ```\n- to delete a Kubernetes secret\n  * `kubectl delete secret {secret-name}`\n- to get a Kubernetes secret\n  * `./get-secret {secret-name} {data-name}`\n  * it may appear that the value ends with a newline, but it doesn't\n- to get the names defined in a Kubernetes secret\n  * `./get-secrets {secret-name}`\n\n### Deploying to Google Cloud Platform (GCP)\n- cd to top project directory\n- to build a Docker image for the web/REST server\n  and push it to the Google Cloud Container Registry\n  * `./image`\n  * this uses Dockerfile\n- to start everything in GCP\n  * `./gcpup`\n  * this uses server.yaml and database/database.yaml\n- to create/recreate the database in GCP\n  * `./dbsetup`\n  * this uses database/ddl.sql\n- to interactively query the database in GCP\n  * `./dbi`\n  * `show tables;`\n  * enter any SQL commands\n- to see a list of things managed by Kubernetes\n  * `kubectl get {kind}`\n    where kind can be many values including\n    all, services (or svc), deployments (or deploy),\n    pods (or po), replicasets (or rc), or secrets\n  * enter `kubectl get --help` to see more valid kinds\n- to see even more detail\n  * `kubectl describe {kind}`\n- to view the logs of the database deployment\n  * `./dblog`\n- to view the logs of the web/REST server deployment\n  * `./serverlog`\n- to get a shell into a Kubernetes pod for poking around\n  * `./kshell {pod-name}`\n  * ex. ./kshell devo-database or ./kshell devo-server\n- to open the web app running in Kubernetes\n  * `./openapp`\n- to stop everything in GCP\n  * `./gcpdown`\n- the web/REST server is ready to use when it has an EXTERNAL-IP\n  * enter `kubectl get services` repeatedly until they do\n\n### Miscellaneious Google Cloud Platform tips\n- to see content of GCP Container Registry\n  * browse https://cloud.google.com\n  * make sure the correct account is selected\n    from the account dropdown in upper-right\n  * click \"CONSOLE\" in upper-right\n  * select a project from the dropdown near upper-left\n  * select \"Container Registry\" from hamburger menu\n- to see list of running instances\n  * `gcloud compute instances list`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopendds%2Fsmartdevice2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopendds%2Fsmartdevice2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopendds%2Fsmartdevice2/lists"}