Lights can be modified by a guest

This commit is contained in:
Claudio Maggioni (maggicl) 2020-05-04 11:13:19 +02:00
parent 770469ade3
commit c145be02b4
10 changed files with 56 additions and 14 deletions

View file

@ -101,6 +101,7 @@ class Curtain extends Component {
{Math.round(this.props.stateOrDevice.intensity)}% {Math.round(this.props.stateOrDevice.intensity)}%
</span> </span>
<input <input
disabled={this.props.disabled}
onChange={this.handleChange} onChange={this.handleChange}
value={this.props.stateOrDevice.intensity} value={this.props.stateOrDevice.intensity}
className="slider" className="slider"

View file

@ -105,7 +105,7 @@ export class KnobDimmerComponent extends Component {
<CircularInput <CircularInput
style={KnobDimmerStyle} style={KnobDimmerStyle}
value={+(Math.round(this.state.intensity / 100 + "e+2") + "e-2")} value={+(Math.round(this.state.intensity / 100 + "e+2") + "e-2")}
onChange={this.setIntensity} onChange={this.props.disabled ? null : this.setIntensity}
> >
<text <text
style={textStyle} style={textStyle}

View file

@ -68,9 +68,12 @@ class Light extends Component {
onClickDevice = () => { onClickDevice = () => {
const on = !this.turnedOn; const on = !this.turnedOn;
if (this.props.tab === "Devices") { if (this.props.tab !== "Scenes") {
this.props this.props
.saveDevice({ ...this.props.stateOrDevice, on }) .saveDevice(
{ ...this.props.stateOrDevice, on },
this.props.tab === "Hosts" ? this.props.activeHost : null
)
.catch((err) => console.error("regular light update error", err)); .catch((err) => console.error("regular light update error", err));
} else { } else {
if (this.props.device.kind === "regularLight") { if (this.props.device.kind === "regularLight") {
@ -115,10 +118,13 @@ class Light extends Component {
saveIntensity = () => { saveIntensity = () => {
const intensity = Math.round(this.state.intensity); const intensity = Math.round(this.state.intensity);
if (this.props.tab === "Devices") { if (this.props.tab !== "Scenes") {
this.props this.props
.saveDevice({ ...this.props.stateOrDevice, intensity }) .saveDevice(
.catch((err) => console.error("regular light update error", err)); { ...this.props.stateOrDevice, intensity },
this.props.tab === "Hosts" ? this.props.activeHost : null
)
.catch((err) => console.error("dimmable light update error", err));
} else { } else {
this.props this.props
.updateState( .updateState(
@ -137,8 +143,8 @@ class Light extends Component {
<CircularInput <CircularInput
style={LightDimmerStyle} style={LightDimmerStyle}
value={+(Math.round(this.intensity / 100 + "e+2") + "e-2")} value={+(Math.round(this.intensity / 100 + "e+2") + "e-2")}
onChange={this.setIntensity} onChange={this.props.disabled ? null : this.setIntensity}
onMouseUp={this.saveIntensity} onMouseUp={this.props.disabled ? null : this.saveIntensity}
> >
<text <text
style={textStyle} style={textStyle}

View file

@ -52,7 +52,7 @@ class SmartPlug extends Component {
render() { render() {
return ( return (
<StyledDiv onClick={this.onClickDevice}> <StyledDiv onClick={this.props.disabled ? () => {} : this.onClickDevice}>
<Image src={this.getIcon()} style={imageStyle} /> <Image src={this.getIcon()} style={imageStyle} />
<span style={nameStyle}>Smart Plug</span> <span style={nameStyle}>Smart Plug</span>

View file

@ -38,7 +38,7 @@ class Switch extends Component {
render() { render() {
return ( return (
<StyledDiv onClick={this.onClickDevice}> <StyledDiv onClick={this.props.disabled ? () => {} : this.onClickDevice}>
<Image src={this.getIcon()} style={imageStyle} /> <Image src={this.getIcon()} style={imageStyle} />
<span style={nameStyle}>Switch</span> <span style={nameStyle}>Switch</span>

View file

@ -99,6 +99,7 @@ class Thermostats extends Component {
<h3 style={deviceName}> <h3 style={deviceName}>
Thermostat Thermostat
<Checkbox <Checkbox
disabled={this.props.disabled}
checked={ checked={
this.props.tab === "Devices" this.props.tab === "Devices"
? this.props.device.mode !== "OFF" ? this.props.device.mode !== "OFF"
@ -118,6 +119,7 @@ class Thermostats extends Component {
</div> </div>
{this.props.tab === "Devices" ? ( {this.props.tab === "Devices" ? (
<Slider <Slider
disabled={this.props.disabled}
min={10} min={10}
max={30} max={30}
step={0.1} step={0.1}

View file

@ -45,6 +45,7 @@ function getRoomName(state, ownProps) {
export default function mapStateToProps(state, ownProps) { export default function mapStateToProps(state, ownProps) {
return { return {
activeHost: state.active.activeHost,
get stateOrDevice() { get stateOrDevice() {
return getStateOrDevice(state, ownProps); return getStateOrDevice(state, ownProps);
}, },
@ -57,5 +58,12 @@ export default function mapStateToProps(state, ownProps) {
get type() { get type() {
return getDevice(state, ownProps).kind; return getDevice(state, ownProps).kind;
}, },
get disabled() {
return (
ownProps.tab === "Hosts" &&
["dimmableLight", "light"].indexOf(getDevice(state, ownProps).kind) ===
-1
);
},
}; };
} }

View file

@ -529,16 +529,24 @@ export const RemoteService = {
* @returns {Promise<Device, RemoteError>} promise that resolves to the saved device and rejects * @returns {Promise<Device, RemoteError>} promise that resolves to the saved device and rejects
* with user-fiendly errors as a RemoteError * with user-fiendly errors as a RemoteError
*/ */
saveDevice: (data) => { saveDevice: (data, hostId = null) => {
return (dispatch) => { return (dispatch) => {
let url = "/device"; let url = "/device";
if ((data.id && data.flowType === "OUTPUT") || !data.id) { if ((data.id && data.flowType === "OUTPUT") || !data.id) {
url = "/" + data.kind; url = "/" + data.kind;
} }
return Endpoint[data.id ? "put" : "post"](url, {}, data) return Endpoint[data.id ? "put" : "post"](
url,
hostId ? { hostId } : {},
data
)
.then((res) => { .then((res) => {
dispatch(actions.deviceSave(res.data)); dispatch(
hostId
? actions.hostDeviceSave(hostId, res.data)
: actions.deviceSave(res.data)
);
return res.data; return res.data;
}) })
.catch((err) => { .catch((err) => {

View file

@ -3,6 +3,7 @@ import thunk from "redux-thunk";
import update from "immutability-helper"; import update from "immutability-helper";
import reduxWebSocket, { connect } from "@giantmachines/redux-websocket"; import reduxWebSocket, { connect } from "@giantmachines/redux-websocket";
import { socketURL } from "./endpoint"; import { socketURL } from "./endpoint";
import actions from "./storeActions";
function reducer(previousState, action) { function reducer(previousState, action) {
let newState, change; let newState, change;
@ -333,6 +334,18 @@ function reducer(previousState, action) {
} }
newState = update(previousState, change); newState = update(previousState, change);
break; break;
case "HOST_DEVICE_SAVE":
change = {
hostDevices: {
[action.hostId]: {
[action.device.id]: {
$set: action.device,
},
},
},
};
newState = update(previousState, change);
break;
case "AUTOMATION_SAVE": case "AUTOMATION_SAVE":
change = { change = {
@ -491,7 +504,6 @@ function reducer(previousState, action) {
a[hostId].push(e); a[hostId].push(e);
return a; return a;
}, {}); }, {});
newState = reducer(previousState, { newState = reducer(previousState, {
type: "DEVICES_UPDATE", type: "DEVICES_UPDATE",
partial: true, partial: true,

View file

@ -25,6 +25,11 @@ const actions = {
type: "DEVICE_SAVE", type: "DEVICE_SAVE",
device, device,
}), }),
hostDeviceSave: (hostId, device) => ({
type: "HOST_DEVICE_SAVE",
hostId,
device,
}),
triggerSave: (automation) => ({ triggerSave: (automation) => ({
type: "TRIGGER_SAVE", type: "TRIGGER_SAVE",
automation, automation,