mirror of
https://github.com/koush/scrypted.git
synced 2026-02-10 09:12:03 +00:00
remove sprinkler
This commit is contained in:
4
plugins/koush-sprinkler/.gitignore
vendored
4
plugins/koush-sprinkler/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
dist/
|
||||
@@ -1,8 +0,0 @@
|
||||
.DS_Store
|
||||
out/
|
||||
node_modules/
|
||||
*.map
|
||||
fs
|
||||
src
|
||||
.vscode
|
||||
dist/*.js
|
||||
22
plugins/koush-sprinkler/.vscode/launch.json
vendored
22
plugins/koush-sprinkler/.vscode/launch.json
vendored
@@ -1,22 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Scrypted Debugger",
|
||||
"address": "${config:scrypted.debugHost}",
|
||||
"port": 10081,
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"preLaunchTask": "scrypted: deploy+debug",
|
||||
"sourceMaps": true,
|
||||
"localRoot": "${workspaceFolder}/out",
|
||||
"remoteRoot": "/plugin/",
|
||||
"type": "pwa-node"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
{
|
||||
"scrypted.debugHost": "127.0.0.1",
|
||||
}
|
||||
20
plugins/koush-sprinkler/.vscode/tasks.json
vendored
20
plugins/koush-sprinkler/.vscode/tasks.json
vendored
@@ -1,20 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "scrypted: deploy+debug",
|
||||
"type": "shell",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "silent",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"command": "npm run scrypted-vscode-launch ${config:scrypted.debugHost}",
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# @scrypted/koush-sprinkler
|
||||
|
||||
## npm commands
|
||||
* npm run scrypted-webpack
|
||||
* npm run scrypted-deploy <ipaddress>
|
||||
* npm run scrypted-debug <ipaddress>
|
||||
|
||||
## scrypted distribution via npm
|
||||
1. Ensure package.json is set up properly for publishing on npm.
|
||||
2. npm publish
|
||||
|
||||
## Visual Studio Code configuration
|
||||
|
||||
* If using a remote server, edit [.vscode/settings.json](blob/master/.vscode/settings.json) to specify the IP Address of the Scrypted server.
|
||||
* Launch Scrypted Debugger from the launch menu.
|
||||
@@ -1,291 +0,0 @@
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiMulti.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <arduino-timer.h>
|
||||
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEUtils.h>
|
||||
#include <BLEServer.h>
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <esp32-hal.h>
|
||||
|
||||
const char *wsUrl = "/endpoint/@scrypted/koush-sprinkler/public/";
|
||||
const int chipid = ESP.getEfuseMac();
|
||||
const uint16_t chip = (uint16_t)(chipid >> 32);
|
||||
|
||||
|
||||
const int ssidOffset = 0;
|
||||
const int ssidLength = 32;
|
||||
const int passOffset = ssidLength;
|
||||
const int passLength = 32;
|
||||
const int hostOffset = passOffset + passLength;
|
||||
const int hostLength = 32;
|
||||
|
||||
char ssid[ssidLength];
|
||||
char pass[passLength];
|
||||
char host[hostLength];
|
||||
|
||||
#define WIFI_SETUP_UUID "d900a203-a982-4a49-85b8-1b5ff00cd6ea"
|
||||
#define WIFI_SSID_UUID "24edce76-d542-4b9f-b201-e76e220396df"
|
||||
#define WIFI_PASS_UUID "0b7beaf6-5a90-4209-8df0-ecc2b7bf0054"
|
||||
#define SCRYPTED_HOST_UUID "7dbd9d28-9ec8-428f-8724-a6107b132131"
|
||||
int advertising = 0;
|
||||
|
||||
int open_pin = 32;
|
||||
int close_pin = 33;
|
||||
int button_pin = 0;
|
||||
int led_pin = 2;
|
||||
int WAIT_TIME = 1000;
|
||||
int OPEN_TIME = 5000;
|
||||
int state = 0;
|
||||
int stateChanged = 0;
|
||||
auto timer = timer_create_default();
|
||||
|
||||
WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
bool clearValvePins(void *argument) {
|
||||
digitalWrite(open_pin, HIGH);
|
||||
digitalWrite(close_pin, HIGH);
|
||||
Serial.println("command ended");
|
||||
sendState();
|
||||
}
|
||||
|
||||
void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
|
||||
const uint8_t* src = (const uint8_t*) mem;
|
||||
Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
if (i % cols == 0) {
|
||||
Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
|
||||
}
|
||||
Serial.printf("%02X ", *src);
|
||||
src++;
|
||||
}
|
||||
Serial.printf("\n");
|
||||
}
|
||||
|
||||
void sendState() {
|
||||
char json[64];
|
||||
sprintf(json, "{\"type\":\"state\",\"state\":\"%s\"}", state ? "open" : "close");
|
||||
webSocket.sendTXT(json);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void handleJson(uint8_t *payload) {
|
||||
Serial.printf("webSocket data %s\n", payload);
|
||||
|
||||
StaticJsonDocument<512> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
if (error) {
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const char *type = doc["type"];
|
||||
if (!type) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(type, "open") == 0) {
|
||||
state = 1;
|
||||
sendState();
|
||||
digitalWrite(close_pin, LOW);
|
||||
digitalWrite(open_pin, HIGH);
|
||||
timer.in(10000, clearValvePins);
|
||||
}
|
||||
else if (strcmp(type, "close") == 0) {
|
||||
state = 0;
|
||||
sendState();
|
||||
digitalWrite(open_pin, LOW);
|
||||
digitalWrite(close_pin, HIGH);
|
||||
timer.in(10000, clearValvePins);
|
||||
}
|
||||
else if (strcmp(type, "state") == 0) {
|
||||
sendState();
|
||||
}
|
||||
}
|
||||
|
||||
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
||||
Serial.printf("webSocket event %d\n", type);
|
||||
switch (type) {
|
||||
case WStype_DISCONNECTED:
|
||||
Serial.printf("[WSc] Disconnected!\n");
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
Serial.printf("[WSc] Connected to url: %s\n", payload);
|
||||
char json[64];
|
||||
|
||||
char ssid[23];
|
||||
|
||||
snprintf(ssid, 23, "MCUDEVICE-%04X%08X", chip, (uint32_t)chipid);
|
||||
|
||||
sprintf(json, "{\"type\":\"id\",\"id\":\"%s\"}", ssid);
|
||||
webSocket.sendTXT(json);
|
||||
sendState();
|
||||
// // send message to server when Connected
|
||||
// webSocket.sendTXT("Connected");
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
// Serial.printf("[WSc] get text: %s\n", payload);
|
||||
handleJson(payload);
|
||||
|
||||
// send message to server
|
||||
// webSocket.sendTXT("message here");
|
||||
break;
|
||||
case WStype_BIN:
|
||||
// Serial.printf("[WSc] get binary length: %u\n", length);
|
||||
// hexdump(payload, length);
|
||||
|
||||
// send data to server
|
||||
// webSocket.sendBIN(payload, length);
|
||||
break;
|
||||
case WStype_ERROR:
|
||||
case WStype_FRAGMENT_TEXT_START:
|
||||
case WStype_FRAGMENT_BIN_START:
|
||||
case WStype_FRAGMENT:
|
||||
case WStype_FRAGMENT_FIN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void readEEPROMString(char *dest, int offset, int length) {
|
||||
for (int i = 0; i < length - 1; i++) {
|
||||
dest[i] = EEPROM.read(offset + i);
|
||||
}
|
||||
dest[length - 1] = '\0';
|
||||
}
|
||||
|
||||
void connectWebSocket() {
|
||||
//webSocket.disconnect();
|
||||
webSocket.begin(host, 10080, wsUrl);
|
||||
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
webSocket.setReconnectInterval(5000);
|
||||
}
|
||||
|
||||
|
||||
void readEEPROM() {
|
||||
readEEPROMString(ssid, ssidOffset, sizeof(ssid));
|
||||
readEEPROMString(pass, passOffset, sizeof(pass));
|
||||
readEEPROMString(host, hostOffset, sizeof(host));
|
||||
WiFiMulti.addAP(ssid, pass);
|
||||
|
||||
connectWebSocket();
|
||||
}
|
||||
|
||||
class EEPROMCallbacks : public BLECharacteristicCallbacks {
|
||||
public:
|
||||
int offset;
|
||||
int size;
|
||||
EEPROMCallbacks(int offset, int size) {
|
||||
this->offset = offset;
|
||||
this->size = size;
|
||||
}
|
||||
void onWrite(BLECharacteristic* pCharacteristic) override {
|
||||
auto value = pCharacteristic->getValue();
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
EEPROM.write(offset + i, value[i]);
|
||||
}
|
||||
EEPROM.write(offset + value.length(), '\0');
|
||||
EEPROM.commit();
|
||||
|
||||
readEEPROM();
|
||||
}
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin (115200);
|
||||
pinMode (open_pin, OUTPUT);
|
||||
pinMode (close_pin, OUTPUT);
|
||||
pinMode(led_pin, OUTPUT);
|
||||
|
||||
digitalWrite(open_pin, HIGH);
|
||||
digitalWrite(close_pin, HIGH);
|
||||
digitalWrite(led_pin, LOW);
|
||||
|
||||
EEPROM.begin(512);
|
||||
|
||||
readEEPROM();
|
||||
|
||||
BLEDevice::init("Sprinkler Setup");
|
||||
BLEServer *pServer = BLEDevice::createServer();
|
||||
BLEService *pService = pServer->createService(WIFI_SETUP_UUID);
|
||||
BLECharacteristic *ssidChar = pService->createCharacteristic(
|
||||
WIFI_SSID_UUID,
|
||||
BLECharacteristic::PROPERTY_READ |
|
||||
BLECharacteristic::PROPERTY_WRITE
|
||||
);
|
||||
BLEDescriptor *ssidLabel = new BLEDescriptor("2901");
|
||||
ssidLabel->setValue("SSID");
|
||||
ssidChar->addDescriptor(ssidLabel);
|
||||
|
||||
ssidChar->setValue(ssid);
|
||||
ssidChar->setCallbacks(new EEPROMCallbacks(ssidOffset, ssidLength));
|
||||
|
||||
BLECharacteristic *passChar = pService->createCharacteristic(
|
||||
WIFI_PASS_UUID,
|
||||
BLECharacteristic::PROPERTY_READ |
|
||||
BLECharacteristic::PROPERTY_WRITE
|
||||
);
|
||||
BLEDescriptor *passLabel = new BLEDescriptor("2901");
|
||||
passLabel->setValue("Password");
|
||||
passChar->addDescriptor(passLabel);
|
||||
passChar->setValue(pass);
|
||||
passChar->setCallbacks(new EEPROMCallbacks(passOffset, passLength));
|
||||
|
||||
|
||||
BLECharacteristic *hostChar = pService->createCharacteristic(
|
||||
SCRYPTED_HOST_UUID,
|
||||
BLECharacteristic::PROPERTY_READ |
|
||||
BLECharacteristic::PROPERTY_WRITE
|
||||
);
|
||||
BLEDescriptor *hostLabel = new BLEDescriptor("2901");
|
||||
hostLabel->setValue("Host");
|
||||
hostChar->addDescriptor(hostLabel);
|
||||
hostChar->setValue(host);
|
||||
hostChar->setCallbacks(new EEPROMCallbacks(hostOffset, hostLength));
|
||||
|
||||
pService->start();
|
||||
|
||||
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
|
||||
pAdvertising->addServiceUUID(WIFI_SETUP_UUID);
|
||||
pAdvertising->setScanResponse(true);
|
||||
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
|
||||
pAdvertising->setMinPreferred(0x12);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
int needAdvertising = 0;
|
||||
if (WiFiMulti.run(5000) != WL_CONNECTED) {
|
||||
Serial.printf("connecting to wifi %s %s %s\n", ssid, pass, host);
|
||||
needAdvertising = 1;
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
webSocket.loop();
|
||||
if (!webSocket.isConnected()) {
|
||||
needAdvertising = 1;
|
||||
}
|
||||
|
||||
if (!advertising && needAdvertising) {
|
||||
advertising = 1;
|
||||
BLEDevice::startAdvertising();
|
||||
Serial.println("Start Advertising");
|
||||
}
|
||||
else if (advertising && !needAdvertising) {
|
||||
advertising = 0;
|
||||
BLEDevice::stopAdvertising();
|
||||
Serial.println("Stop Advertising");
|
||||
|
||||
digitalWrite(led_pin, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(led_pin, LOW);
|
||||
}
|
||||
|
||||
timer.tick();
|
||||
}
|
||||
220
plugins/koush-sprinkler/package-lock.json
generated
220
plugins/koush-sprinkler/package-lock.json
generated
@@ -1,220 +0,0 @@
|
||||
{
|
||||
"name": "@scrypted/koush-sprinkler",
|
||||
"version": "0.0.10",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/koush-sprinkler",
|
||||
"version": "0.0.10",
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"ws": "^6.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/ws": "^7.4.7"
|
||||
}
|
||||
},
|
||||
"../../sdk": {
|
||||
"name": "@scrypted/sdk",
|
||||
"version": "0.0.134",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.14.5",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.14.5",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.15.4",
|
||||
"@babel/plugin-transform-typescript": "^7.15.8",
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.13.8",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.2.6",
|
||||
"webpack": "^5.59.0"
|
||||
},
|
||||
"bin": {
|
||||
"scrypted-debug": "bin/scrypted-debug.js",
|
||||
"scrypted-deploy": "bin/scrypted-deploy.js",
|
||||
"scrypted-deploy-debug": "bin/scrypted-deploy-debug.js",
|
||||
"scrypted-package-json": "bin/scrypted-package-json.js",
|
||||
"scrypted-readme": "bin/scrypted-readme.js",
|
||||
"scrypted-webpack": "bin/scrypted-webpack.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1"
|
||||
}
|
||||
},
|
||||
"../sdk": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@scrypted/sdk": {
|
||||
"resolved": "../../sdk",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "14.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
|
||||
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "7.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz",
|
||||
"integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410",
|
||||
"dependencies": {
|
||||
"follow-redirects": "1.5.10"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"dependencies": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects/node_modules/debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
|
||||
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
|
||||
"dependencies": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": {
|
||||
"version": "file:../../sdk",
|
||||
"requires": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
|
||||
"@babel/plugin-proposal-numeric-separator": "^7.14.5",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.14.5",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.15.4",
|
||||
"@babel/plugin-transform-typescript": "^7.15.8",
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/stringify-object": "^4.0.0",
|
||||
"adm-zip": "^0.4.13",
|
||||
"axios": "^0.21.4",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-const-enum": "^1.1.0",
|
||||
"esbuild": "^0.13.8",
|
||||
"ncp": "^2.0.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tmp": "^0.2.1",
|
||||
"ts-loader": "^9.2.6",
|
||||
"ts-node": "^10.4.0",
|
||||
"typedoc": "^0.22.8",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"webpack": "^5.59.0"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
|
||||
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/ws": {
|
||||
"version": "7.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz",
|
||||
"integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
|
||||
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"name": "@scrypted/koush-sprinkler",
|
||||
"scripts": {
|
||||
"prepublishOnly": "NODE_ENV=production scrypted-webpack",
|
||||
"prescrypted-vscode-launch": "scrypted-webpack",
|
||||
"scrypted-vscode-launch": "scrypted-deploy-debug",
|
||||
"scrypted-deploy-debug": "scrypted-deploy-debug",
|
||||
"scrypted-debug": "scrypted-debug",
|
||||
"scrypted-deploy": "scrypted-deploy",
|
||||
"scrypted-readme": "scrypted-readme",
|
||||
"scrypted-package-json": "scrypted-package-json",
|
||||
"scrypted-webpack": "scrypted-webpack"
|
||||
},
|
||||
"scrypted": {
|
||||
"name": "Sprinkler System",
|
||||
"type": "DeviceProvider",
|
||||
"interfaces": [
|
||||
"DeviceProvider",
|
||||
"EngineIOHandler"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"ws": "^6.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"@types/ws": "^7.4.7"
|
||||
},
|
||||
"version": "0.0.10"
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
import { DeviceProvider, EngineIOHandler, HttpRequest, HttpRequestHandler, OnOff, Refresh, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, StartStop } from '@scrypted/sdk';
|
||||
import sdk from '@scrypted/sdk';
|
||||
import { Server } from "ws";
|
||||
import { EventEmitter } from 'events';
|
||||
const { log, deviceManager } = sdk;
|
||||
|
||||
class Valve extends ScryptedDeviceBase implements StartStop, Refresh {
|
||||
system: SprinklerSystem;
|
||||
wsEvents = new EventEmitter();
|
||||
ws: WebSocket;
|
||||
|
||||
constructor(system: SprinklerSystem, nativeId: string) {
|
||||
super(nativeId);
|
||||
this.system = system;
|
||||
|
||||
this.wsEvents.on('state', e => {
|
||||
this.running = e.state !== 'close';
|
||||
});
|
||||
}
|
||||
attachWebSocket(ws: WebSocket) {
|
||||
this.ws = ws;
|
||||
ws.onmessage = async (message) => {
|
||||
this.log.i(message.data);
|
||||
const e = JSON.parse(message.data);
|
||||
this.wsEvents.emit(e.type, e);
|
||||
};
|
||||
}
|
||||
async getRefreshFrequency(): Promise<number> {
|
||||
return 1800;
|
||||
}
|
||||
async refresh(refreshInterface: string, userInitiated: boolean) {
|
||||
if (!this.ws)
|
||||
return;
|
||||
this.ws.send(JSON.stringify({
|
||||
type: 'state',
|
||||
}));
|
||||
}
|
||||
async stop() {
|
||||
log.i('turnOff');
|
||||
|
||||
this.ws.send(JSON.stringify({
|
||||
type: 'close',
|
||||
}));
|
||||
}
|
||||
async start() {
|
||||
// set a breakpoint here.
|
||||
log.i('turnOn');
|
||||
|
||||
this.ws.send(JSON.stringify({
|
||||
type: 'open',
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SprinklerSystem extends ScryptedDeviceBase implements EngineIOHandler, DeviceProvider {
|
||||
wss = new Server({ port: 8080 });
|
||||
devices = new Map<string, Valve>();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.running = this.running || false;
|
||||
|
||||
sdk.endpointManager.getInsecurePublicLocalEndpoint()
|
||||
.then(endpoint => log.i(endpoint));
|
||||
}
|
||||
|
||||
async discoverDevices(duration: number) {
|
||||
}
|
||||
getDevice(nativeId: string) {
|
||||
return this.devices.get(nativeId);
|
||||
}
|
||||
|
||||
async onConnection(request: HttpRequest, webSocketUrl: string) {
|
||||
log.i("connection");
|
||||
const ws = new WebSocket(webSocketUrl);
|
||||
ws.onmessage = async (message) => {
|
||||
const e = JSON.parse(message.data);
|
||||
if (e.type === 'id') {
|
||||
log.i(`client connected ${message.data}`);
|
||||
const {id} = e;
|
||||
let d = this.devices.get(id);
|
||||
if (!d) {
|
||||
d = new Valve(this, id);
|
||||
this.devices.set(id, d);
|
||||
}
|
||||
else {
|
||||
d.ws.close();
|
||||
}
|
||||
d.attachWebSocket(ws);
|
||||
|
||||
await deviceManager.onDeviceDiscovered({
|
||||
nativeId: id,
|
||||
type: ScryptedDeviceType.Irrigation,
|
||||
interfaces: [ScryptedInterface.StartStop, ScryptedInterface.Refresh],
|
||||
});
|
||||
d.log.i(`client connected ${message.data}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new SprinklerSystem();
|
||||
Reference in New Issue
Block a user