Compare commits

...

5 Commits

Author SHA1 Message Date
a1dc088a23 Fix repeating notifications in Accident.js 2021-01-06 13:55:56 +05:30
d4a19060e8 Add notifications to pet mode 2021-01-06 13:55:22 +05:30
fe9f7e81e9 Add Smart Lights to SmartHome 2021-01-05 22:28:57 +05:30
6e07c2be85 Add marketplace 2021-01-04 23:53:59 +05:30
03db7575fd Changes in theming 2021-01-04 23:53:20 +05:30
9 changed files with 120 additions and 10 deletions

View File

@@ -42,6 +42,8 @@ function Core() {
label="Smart Home" margin="0 0 0 1em" />
<Button onClick={() => dispatch(setPlugin("maps"))} primary
label="Maps" margin="0 0 0 1em" />
<Button onClick={() => dispatch(setPlugin("marketplace"))} primary
label="Marketplace" margin="0 0 0 1em" />
</Box>
</Box>)
}

View File

@@ -2,7 +2,7 @@ import React from "react";
function VoiceBars() {
return (
<div className="waves" style={{transform: "rotate(180deg)", marginTop: "130px"}}>
<div className="waves" style={{transform: "rotate(180deg)", marginTop: "130px", transition: "1s"}}>
<svg width="100vw" fill="none" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">

View File

@@ -9,18 +9,18 @@ import { TG_API, TG_USERID } from "../config";
function sendNotification(close) {
if (window.sendingAccidentAlert)
return;
window.sending = true;
window.sendingAccidentAlert = true;
const bot = new Telegram(TG_API);
bot.sendMessage(TG_USERID, "User detected in an accident. Location has been attached below.");
navigator.geolocation.getCurrentPosition(
position => {
window.sendingAccidentAlert = false;
bot.sendLocation( TG_USERID,
position.coords.latitude, position.coords.longitude);
window.sendingAccidentAlert = false;
},
() => {
bot.sendMessage(TG_USERID, "Error retrieving location");
window.sendingAccidentAlert = false;
bot.sendMessage(TG_USERID, "Error retrieving location");
}
);
setTimeout(close, 2000);

View File

@@ -12,10 +12,13 @@ function GenericPageWithIcon(props) {
direction="column"
alignContent="center"
height="95vh"
style={{
padding: "0 3em",
}}
>
{props.icon}
<Heading>{props.title}</Heading>
<Text>{props.description}</Text>
<Text style={{ textAlign: "center" }}>{props.description}</Text>
<Button primary size="large" onClick={props.close}
label="Dismiss" margin="1.5em" />
</Box>

View File

@@ -0,0 +1,67 @@
import React from "react";
import PropTypes from "prop-types";
import { Box, Button, Card, CardBody, CardFooter, CardHeader, Heading } from "grommet";
import { InstallOption, Trash } from "grommet-icons";
function Marketplace(props) {
const plugins = [
{
name: "Maps",
description: "Google Maps is a mapping service. It offers satellite imagery, aerial photography, street maps, 360° interactive panoramic views of streets, real-time traffic conditions, and route planning for traveling.",
installed: true
},
{
name: "Smart Home",
description: "Smart Home Plugin lets you integrate with various well known smart devices allowing you to stream video from various devices.",
installed: true
},
{
name: "Spotify",
description: "With Spotify, you have access to a world of music. You can listen to artists and albums, or create your own playlist of your favourite songs.",
installed: false
},
];
return (
<Box
align="center"
background="light-1"
width="100vw"
justify="center"
direction="column"
alignContent="center"
height="95vh"
>
<Box wrap="wrap" direction="row">
{
plugins.map(i =>
<Card key={i.name} style={{margin: "1em", width: "30%"}}>
<CardHeader pad="medium"><Heading>{i.name}</Heading></CardHeader>
<CardBody pad="medium">{i.description}</CardBody>
<CardFooter pad="medium" justify="center">
<Button
label={i.installed ? "Uninstall": "Install"}
icon={i.installed ?
<Trash color="status-error" /> :
<InstallOption color="status-ok" />
}
/>
</CardFooter>
</Card>
)
}
</Box>
<Button primary size="large" onClick={props.close}
label="Dismiss" margin="1.5em" />
</Box>
);
}
Marketplace.propTypes = {
data: PropTypes.object,
close: PropTypes.func
};
Marketplace.pluginName = "Marketplace";
export default Marketplace;

View File

@@ -3,16 +3,38 @@ import PropTypes from "prop-types";
import GenericPageWithIcon from "./GenericPageWithIcon";
import { Sun } from "grommet-icons";
import axios from "axios";
import { CAR_API } from "../config";
import Telegram from "../utils/telegram";
import { CAR_API, TG_API, TG_USERID } from "../config";
function sendNotification(temp) {
if (window.sendingPetAlert)
return;
window.sendingPetAlert = true;
const bot = new Telegram(TG_API);
bot.sendMessage(TG_USERID, `The temperature in the car is ${temp}°C. Please check your child/pet.`);
window.sendingPetAlert = false;
}
function PetMode(props) {
const [ temp, setTemp ] = useState(null);
const [ , setNotified ] = useState(false);
useEffect(() => {
axios.get(`${CAR_API}data/InsideTemperature`)
.then(resp => setTemp(resp.data.value));
const id = setInterval(
() => axios.get(`${CAR_API}data/InsideTemperature`)
.then(resp => setTemp(resp.data.value)),
.then(resp => {
setTemp(resp.data.value);
if (resp.data.value > 35 || resp.data.value < 5) {
setNotified(notified => {
if (notified)
return true;
sendNotification(resp.data.value);
return true;
});
}
}),
1000
);
return () => clearInterval(id);

View File

@@ -1,8 +1,9 @@
import React, {useState, useEffect} from "react";
import PropTypes from "prop-types";
import { Box, Button } from "grommet";
import axios from "axios";
import { CAMERA_URL } from "../config";
import { CAMERA_URL, LIGHTS_URL } from "../config";
function SmartHome(props) {
const [ idx, setIdx ] = useState(0);
@@ -10,6 +11,12 @@ function SmartHome(props) {
const id = setInterval(() => setIdx(i => i + 1), 20);
return () => clearInterval(id);
}, []);
function turnOn() {
axios.get(`${LIGHTS_URL}/on`);
}
function turnOff() {
axios.get(`${LIGHTS_URL}/off`);
}
return (
<Box
align="center"
@@ -21,8 +28,14 @@ function SmartHome(props) {
height="95vh"
>
<img src={`${CAMERA_URL}?id=${idx}`} />
<Box direction="row" margin="1em 0">
<Button primary size="large" onClick={turnOn}
label="Turn On Lights" margin="0 0 0 0" />
<Button primary size="large" onClick={turnOff}
label="Turn Off Lights" margin="0 0 0 1em" />
</Box>
<Button primary size="large" onClick={props.close}
label="Dismiss" margin="1.5em" />
label="Dismiss" margin="0" />
</Box>
);
}

View File

@@ -5,6 +5,7 @@ import Accident from "./Accident";
import PetMode from "./PetMode";
import SmartHome from "./SmartHome";
import Maps from "./Maps";
import Marketplace from "./Marketplace";
export default {
warning: Warning,
@@ -14,4 +15,5 @@ export default {
petMode: PetMode,
smartHome: SmartHome,
maps: Maps,
marketplace: Marketplace,
};

View File

@@ -4,5 +4,6 @@ const TG_USERID = 123456789;
const CAR_API = "http://localhost:5000/";
const CAMERA_URL = "http://path.to/still/image.jpg";
const MAPS_API = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const LIGHTS_URL = "http://192.168.1.50:5000/";
export { WS_BASE, TG_API, TG_USERID, CAR_API, CAMERA_URL, MAPS_API };
export { WS_BASE, TG_API, TG_USERID, CAR_API, CAMERA_URL, MAPS_API, LIGHTS_URL };