Dev prototype #1

Merged
david merged 7 commits from dev into main 2025-04-24 11:34:49 -07:00
6 changed files with 94 additions and 57 deletions
Showing only changes of commit e10a492910 - Show all commits

View File

@ -1,9 +1,12 @@
{
"dependencies": {
"@roamhq/wrtc": "0.8.0",
"node-dht-sensor": "^0.4.5",
"node-pre-gyp": "^0.17.0",
"ws": "^8.18.0",
"sass": "1.86.3"
"pigpio": "^3.3.1",
"sass": "1.86.3",
"serialport": "^13.0.0",
"ws": "^8.18.0"
},
"scripts": {
"build:scss": "npx sass src/static/css:dist/static/css",
@ -16,6 +19,7 @@
},
"devDependencies": {
"@types/node": "^22.10.2",
"@types/node-dht-sensor": "^0.4.2",
"@types/ws": "^8.5.13",
"ts-node": "^10.9.2",
"typescript": "^5.8.2"

View File

@ -1,5 +1,6 @@
import Serial from "./serial";
import * as pigpio from 'pigpio';
import * as dht from 'node-dht-sensor';
type ONOFF = 0 | 1;
const ON: ONOFF = 0
@ -9,61 +10,69 @@ const OFF: ONOFF = 1
export interface ISensors {
temperature: number;
power: boolean;
moisture: number;
lights: boolean;
heat: boolean
moisture0: number;
moisture1: number;
humidity: number;
}
export default class IO implements ISensors {
temperature: number;
moisture: number;
humidity: number;
gpio: pigpio.Gpio
export default class IO {
gpioLights: pigpio.Gpio
gpioHeat: pigpio.Gpio
serial: Serial;
power: boolean;
getMoisture : ()=>number;
lights: boolean;
heat: boolean;
getMoisture: () => ({ moisture0: number, moisture1: number });
public constructor(POWER_GPIO = 17) {
public constructor(LIGHTS_GPIO = 17, HEAT_GPIO=22, DHT_GPIO = 27, DHT_MODEL = 22) {
const serial = new Serial()
this.getMoisture = serial.getMoisture.bind(serial);
this.serial = serial;
// Initialize pigpio and the GPIO pin
const read = new pigpio.Gpio(POWER_GPIO, {mode: pigpio.Gpio.INPUT});
this.power = read.digitalRead() == ON ? true : false
this.gpio = new pigpio.Gpio(POWER_GPIO, { mode: pigpio.Gpio.OUTPUT });
this.humidity = 0
this.temperature = 0;
// this.serial.getMoisture.bind(this)
const readLights = new pigpio.Gpio(LIGHTS_GPIO, { mode: pigpio.Gpio.INPUT });
this.lights = readLights.digitalRead() == ON ? true : false
this.gpioLights = new pigpio.Gpio(LIGHTS_GPIO, { mode: pigpio.Gpio.OUTPUT });
const readHeat = new pigpio.Gpio(HEAT_GPIO, { mode: pigpio.Gpio.INPUT });
this.lights = readHeat.digitalRead() == ON ? true : false
this.gpioHeat = new pigpio.Gpio(HEAT_GPIO, { mode: pigpio.Gpio.OUTPUT });
dht.initialize(22, DHT_GPIO);
dht.setMaxRetries(10);
}
public setPower(state: boolean, GPIO= 17) {
if(GPIO == 17){
this.lights = state;
this.gpioLights.digitalWrite(this.lights ? ON : OFF);
}
else if(GPIO == 22){
this.heat = state;
this.gpioHeat.digitalWrite(this.heat ? ON : OFF);
}
// getPower() {
// // Read the current state of the GPIO pin
// return this.gpio.digitalRead() === ON;
}
// public togglePower() {
// this.power = !this.power;
// this.gpio.digitalWrite(this.power ? ON : OFF);
// }
public setPower(power: boolean) {
// Set the GPIO pin to high (1) or low (0)
this.power = power;
this.gpio.digitalWrite(this.power ? ON : OFF);
}
public togglePower() {
// Toggle the power state (turn the pin on or off)
this.power = !this.power;
this.gpio.digitalWrite(this.power ? ON : OFF);
}
private round = (n) =>
(n * 100) / 100
public getSensors(): ISensors {
// console.log("serial ", )
const { temperature, humidity } = dht.read(22, 27)
const { moisture0, moisture1 } = this.getMoisture()
return {
power: this.power,
moisture: this.getMoisture(),
temperature: this.temperature,
humidity: this.humidity
lights: this.lights,
heat: this.heat,
moisture0: moisture0,
moisture1: moisture1,
temperature: this.round(temperature),
humidity: this.round(humidity)
}
}
}

View File

@ -14,25 +14,29 @@ export default class Serial {
const readline = new serialport.ReadlineParser({ delimiter });
const parser = port.pipe(readline);
parser.on('data', line => {
// console.log("data line ", line)
const data = JSON.parse(line)
const moisture0 = parseInt(data['A0'], 10);
const moisture1 = parseInt(data['A1'], 10);
if (!isNaN(moisture0) && !isNaN(moisture1)) {
// console.log("m ", this.moisture)
this.moisture0 = moisture0;
this.moisture1 = moisture1;
}
else {
console.log("data ",data)
console.error("Error reading analog data")
}
});
port.on('error', err => {
console.error('Serial Error:', err.message);
});
}
private scale = (value: number) => {
const percent = (value / 1024) * 100;
return Math.min(Math.max(percent, 0), 100); // Clamp to 0-100 just in case
}
public getMoisture() {
return this.moisture0;
return { moisture0: this.scale(this.moisture0), moisture1: this.scale(this.moisture1) };
}

View File

@ -42,7 +42,7 @@ httpServer.start();
process.stdin.setEncoding("utf8");
process.stdin.resume();
console.log("Menu:\n1) Power off\n2)Power on\n3) Power flop\n4)Read Sensors");
console.log("Menu:\n1)Lights Power off\n2) Lights Power on\n3)Heat Power Off\n4) Heat power on\n5)Read Sensors");
process.stdin.on("data", async (data: string) => {
const input = data.trim();
@ -53,16 +53,20 @@ process.stdin.on("data", async (data: string) => {
break;
case 1:
io.setPower(false);
io.setPower(false,17);
break;
case 2:
io.setPower(true);
io.setPower(true,17);
break;
case 3:
io.togglePower();
io.setPower(false,22);
break;
case 4:
io.setPower(true,22);
break;
case 5:
console.log("a ", getSensors())
break;
default:

View File

@ -18,8 +18,12 @@
<video id="video0" autoplay playsinline controls></video>
<div id="channel-container-0" class="channel-group"></div>
</div>
<p id="sensors"></p>
<button onclick="poll()">Poll</button>
<div id="data-container">
<!-- <p id="power"></p>
<p id="moisture"></p>
<p id="temperature"></p>
<p id="humidity"></p> -->
</div>
</main>
</div>

View File

@ -2,6 +2,14 @@ const isSecure = window.location.protocol === 'https:';
const host = window.location.hostname;
const ws0builder = isSecure ? `wss://${host}/ws3` : `ws://${host}:3003`;
const ws0 = new WebSocket(ws0builder);
interface IData {
power: boolean,
moisture: number,
temperature: number,
humidity: number
}
const dataContainer = document.getElementById('data-container') as HTMLDivElement
const config = {
iceServers: [
{
@ -36,7 +44,11 @@ dataChannel.onopen = () => {
};
dataChannel.onmessage = (event) => {
console.log("📦 Client received message:", event.data);
// console.log("📦 Client received message:", event.data);
const json = JSON.parse(event.data) ;
dataContainer.innerHTML = Object.entries(json).map(([k,v])=>`<p>${k}:${v}</p>`).join('')
};
dataChannel.onclose = () => {