1
0
Форкнуть 0

Adding the API call for the temperature sensor. (#60)

PBI 30934

* added temperature value

* removed deead code

* removed dummy

* added type to the slider

* remove unit notions

* changes

* changes to the api

* created new variable

* added degree sign

* removed extra spaces

* more extra spaces removed

* using varaiable for the slider color

* added null check

* beautifying

* beuatifying

* solving issues

* Update src/view/components/toolbar/InputSlider.tsx

Co-Authored-By: Jonathan Wang <jonathanwangg@gmail.com>

* used prettier

* removed dummy

* prettier again

* following good unsollicited advices 1

* cleaning up

* adding support for stop button

* Update src/extension.ts

Co-Authored-By: Luke Slevinsky <lslevins@ualberta.ca>

* Update src/view/components/toolbar/TemperatureSensorBar.tsx

Co-Authored-By: Luke Slevinsky <lslevins@ualberta.ca>

* rework setmessage

* reformat

* let's follow best practices

* resolved issue with input
This commit is contained in:
FMounz 2019-07-21 12:37:23 -07:00 коммит произвёл GitHub
Родитель 59ce0a9a64
Коммит 28d0a68230
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 197 добавлений и 137 удалений

Просмотреть файл

@ -29,7 +29,8 @@ class Express:
(0, 0, 0)
],
'red_led': False,
'switch': False
'switch': False,
'temperature': 0
}
self.pixels = Pixel(self.__state)
@ -56,6 +57,10 @@ class Express:
def switch(self):
return self.__state['switch']
@property
def temperature(self):
return self.__state['temperature']
def __show(self):
utils.show(self.__state)

Просмотреть файл

@ -125,6 +125,7 @@ export enum TelemetryEventName {
export enum WebviewMessages {
BUTTON_PRESS = "button-press",
PLAY_SIMULATOR = "play-simulator",
SENSOR_CHANGED = "sensor-changed",
REFRESH_SIMULATOR = "refresh-simulator"
}

Просмотреть файл

@ -77,25 +77,33 @@ export function activate(context: vscode.ExtensionContext) {
// Handle messages from webview
messageListener = currentPanel.webview.onDidReceiveMessage(
message => {
const messageJson = JSON.stringify(message.text);
switch (message.command) {
case WebviewMessages.BUTTON_PRESS:
// Send input to the Python process
handleButtonPressTelemetry(message.text);
console.log("About to write");
console.log(JSON.stringify(message.text) + "\n");
console.log(messageJson + "\n");
if (childProcess) {
childProcess.stdin.write(JSON.stringify(message.text) + "\n");
childProcess.stdin.write(messageJson + "\n");
}
break;
case WebviewMessages.PLAY_SIMULATOR:
console.log("Play button");
console.log(JSON.stringify(message.text) + "\n");
console.log(messageJson + "\n");
if (message.text as boolean) {
runSimulatorCommand();
} else {
killProcessIfRunning();
}
break;
case WebviewMessages.SENSOR_CHANGED:
console.log("sensor changed");
console.log(messageJson + "\n");
if (childProcess) {
childProcess.stdin.write(messageJson + "\n");
}
break;
case WebviewMessages.REFRESH_SIMULATOR:
console.log("Refresh button");
runSimulatorCommand();
@ -150,11 +158,9 @@ export function activate(context: vscode.ExtensionContext) {
vscode.window
.showInformationMessage(
CONSTANTS.INFO.NEW_PROJECT,
...[
DialogResponses.DONT_SHOW,
DialogResponses.EXAMPLE_CODE,
DialogResponses.TUTORIALS
]
)
.then((selection: vscode.MessageItem | undefined) => {
if (selection === DialogResponses.DONT_SHOW) {
@ -357,7 +363,7 @@ export function activate(context: vscode.ExtensionContext) {
vscode.window
.showErrorMessage(
CONSTANTS.ERROR.NO_DEVICE,
...[DialogResponses.HELP]
DialogResponses.HELP
)
.then((selection: vscode.MessageItem | undefined) => {
if (selection === DialogResponses.HELP) {
@ -382,17 +388,17 @@ export function activate(context: vscode.ExtensionContext) {
}
});
// Std error output
deviceProcess.stderr.on("data", data => {
telemetryAI.trackFeatureUsage(
TelemetryEventName.ERROR_PYTHON_DEVICE_PROCESS,
{ error: `${data}` }
);
console.error(
`Error from the Python device process through stderr: ${data}`
);
logToOutputChannel(outChannel, `[ERROR] ${data} \n`, true);
});
// Std error output
deviceProcess.stderr.on("data", data => {
telemetryAI.trackFeatureUsage(
TelemetryEventName.ERROR_PYTHON_DEVICE_PROCESS,
{ error: `${data}` }
);
console.error(
`Error from the Python device process through stderr: ${data}`
);
logToOutputChannel(outChannel, `[ERROR] ${data} \n`, true);
});
// When the process is done
deviceProcess.on("end", (code: number) => {
@ -431,33 +437,38 @@ export function activate(context: vscode.ExtensionContext) {
const getActivePythonFile = () => {
const editors: vscode.TextEditor[] = vscode.window.visibleTextEditors;
const activeEditor = editors.find((editor) => editor.document.languageId === "python");
const activeEditor = editors.find(
editor => editor.document.languageId === "python"
);
return activeEditor ? activeEditor.document.fileName : "";
}
};
const getFileFromFilePicker = () => {
const options: vscode.OpenDialogOptions = {
canSelectMany: false,
filters: {
'All files': ['*'],
'Python files': ['py']
"All files": ["*"],
"Python files": ["py"]
},
openLabel: 'Run File'
openLabel: "Run File"
};
return vscode.window.showOpenDialog(options).then(fileUri => {
if (fileUri && fileUri[0]) {
console.log('Selected file: ' + fileUri[0].fsPath);
console.log(`Selected file: ${fileUri[0].fsPath}`);
return fileUri[0].fsPath;
}
});
}
};
const updateCurrentFileIfPython = async (activeTextEditor: vscode.TextEditor | undefined) => {
const updateCurrentFileIfPython = async (
activeTextEditor: vscode.TextEditor | undefined
) => {
if (activeTextEditor && activeTextEditor.document.languageId === "python") {
currentFileAbsPath = activeTextEditor.document.fileName;
} else if (currentFileAbsPath === "") {
currentFileAbsPath = getActivePythonFile() || await getFileFromFilePicker() || "";
currentFileAbsPath =
getActivePythonFile() || (await getFileFromFilePicker()) || "";
}
};
@ -496,7 +507,9 @@ const logToOutputChannel = (
show: boolean = false
) => {
if (outChannel) {
if (show) { outChannel.show(true); }
if (show) {
outChannel.show(true);
}
outChannel.append(message);
}
};
@ -522,4 +535,4 @@ function getWebviewContent(context: vscode.ExtensionContext) {
}
// this method is called when your extension is deactivated
export function deactivate() { }
export function deactivate() {}

Просмотреть файл

@ -30,6 +30,8 @@ class UserInput(threading.Thread):
'button_b', cpx._Express__state['button_b'])
cpx._Express__state['switch'] = new_state.get(
'switch', cpx._Express__state['switch'])
cpx._Express__state['temperature'] = new_state.get(
'temperature', cpx._Express__state['temperature'])
except Exception as e:
print("Error trying to send event to the process : ",
e, file=sys.stderr, flush=True)

Просмотреть файл

@ -55,7 +55,6 @@ interface vscode {
declare const vscode: vscode;
const sendMessage = (type: string, state: any) => {
console.log("sendmessage");
vscode.postMessage({ command: type, text: state });
};

Просмотреть файл

@ -2,88 +2,131 @@
// Licensed under the MIT license.
import * as React from "react";
import "./InputSlider.css"
import "./InputSlider.css";
interface ISliderProps{
min:number;
max: number;
min_label: string;
max_label: string;
step:number;
type: string;
interface vscode {
postMessage(message: any): void;
}
declare const vscode: vscode;
const sendMessage = (state: any) => {
vscode.postMessage({ command: "sensor-changed", text: state });
};
class InputSlider extends React.Component<ISliderProps,any,any>{
interface ISliderProps {
min: number;
max: number;
min_label: string;
max_label: string;
step: number;
type: string;
}
constructor(props: ISliderProps){
super(props);
this.state = {
value: 0
};
class InputSlider extends React.Component<ISliderProps, any, any> {
constructor(props: ISliderProps) {
super(props);
this.state = {
value: 0
};
this.handleOnChange = this.handleOnChange.bind(this);
this.validateRange = this.validateRange.bind(this);
this.handleOnChange = this.handleOnChange.bind(this);
this.validateRange = this.validateRange.bind(this);
}
handleMessage = (event: any): void => {
const message = event.data; // The JSON data our extension sent
switch (message.command) {
case "reset-state":
this.setState({ value: 0 });
break;
case "set-state":
console.log("Setting the state: " + JSON.stringify(message.state));
break;
default:
console.log("Invalid message received from the extension.");
this.setState({ value: 0 });
break;
}
};
render(){
return (
<div className="inputSlider">
<input type="text" className="sliderValue" value={this.state.value}
onInput={this.handleOnChange} defaultValue={this.props.min.toLocaleString()} pattern="^-?[0-9]*$" onKeyUp={this.validateRange}/>
<div className="sliderArea">
<div className="upLabelArea">
<div className='minLabel'>
{this.props.min_label}
</div>
<div className='maxLabel'>
{this.props.max_label}
</div>
</div>
<input type="range" className="slider" min={this.props.min} max={this.props.max}
step={this.props.step} onChange={this.handleOnChange} value={this.state.value} defaultValue={this.props.min.toLocaleString()}/>
<div className="downLabelArea">
<div className='minLabel'>
{this.props.min}
</div>
<div className='maxLabel'>
{this.props.max}
</div>
</div>
</div>
componentDidMount() {
console.log("Mounted");
window.addEventListener("message", this.handleMessage);
}
componentWillUnmount() {
// Make sure to remove the DOM listener when the component is unmounted.
window.removeEventListener("message", this.handleMessage);
}
render() {
return (
<div className="inputSlider">
<input
type="text"
className="sliderValue"
value={this.state.value}
onInput={this.handleOnChange}
defaultValue={this.props.min.toLocaleString()}
pattern="^-?[0-9]*$"
onKeyUp={this.validateRange}
/>
<div className="sliderArea">
<div className="upLabelArea">
<div className="minLabel">{this.props.min_label}</div>
<div className="maxLabel">{this.props.max_label}</div>
</div>
<input
type="range"
className="slider"
min={this.props.min}
max={this.props.max}
step={this.props.step}
onChange={this.handleOnChange}
value={this.state.value}
defaultValue={this.props.min.toLocaleString()}
/>
<div className="downLabelArea">
<div className="minLabel">{this.props.min}</div>
<div className="maxLabel">{this.props.max}</div>
</div>
</div>
</div>
);
}
)
private handleOnChange(event: React.ChangeEvent<HTMLInputElement>) {
this.updateValue(event);
this.validateRange();
const newSensorState = this.writeMessage(event);
if (newSensorState) {
sendMessage(newSensorState);
}
}
private handleOnChange(event: React.ChangeEvent<HTMLInputElement>){
this.updateValue(event);
this.validateRange();
private writeMessage(event: React.ChangeEvent<HTMLInputElement>) {
parseInt(event.target.value, 10);
return this.props.type && this.state.value && event.target.value
? { temperature: parseInt(event.target.value, 10) }
: undefined;
}
private updateValue(event: React.ChangeEvent<HTMLInputElement>) {
const newValue = event.target.validity.valid
? event.target.value
: this.state.value;
console.log(`set state to ${this.state.value}`);
this.setState({ value: newValue });
}
private validateRange() {
if (this.state.value < this.props.min) {
this.setState({ value: this.props.min });
}
private updateValue(event: React.ChangeEvent<HTMLInputElement>){
const newValue = (event.target.validity.valid) ? event.target.value : this.state.value;
this.setState({value:newValue});
if (this.state.value > this.props.max) {
this.setState({ value: this.props.max });
}
private validateRange(){
if(this.state.value<this.props.min){
this.setState({value:this.props.min,dummy:2});
}
if(this.state.value>this.props.max){
this.setState({value:this.props.max,dummy:1});
}
}
}
}
export default InputSlider;

Просмотреть файл

@ -3,55 +3,52 @@
import * as React from "react";
import InputSlider from "./InputSlider";
import "./TemperatureSensorBar.css"
import "./TemperatureSensorBar.css";
const TEMPERATURE_SENSOR_PROPERTIES = {
MIN_LABEL: "Cold",
MAX_LABEL: "Hot",
LABEL: "Temperature sensor",
TYPE: "temperature",
}
LABEL: "Temperature sensor",
MAX_LABEL: "Hot",
MIN_LABEL: "Cold",
TYPE: "temperature"
};
interface ITemperatureUnit {
name: string,
minValue: number,
maxValue: number
unitLabel: string;
minValue: number;
maxValue: number;
}
const CELSIUS_STATE: ITemperatureUnit ={
name: "°C",
minValue: -40,
maxValue: 40
}
const CELSIUS_STATE: ITemperatureUnit = {
maxValue: 40,
minValue: -40,
unitLabel: "°C"
};
class TemperatureSensorBar extends React.Component<any, ITemperatureUnit, any> {
constructor(props: any) {
super(props);
this.state = CELSIUS_STATE;
}
class TemperatureSensorBar extends React.Component<any,ITemperatureUnit,any>{
constructor(props: any){
super(props);
this.state = CELSIUS_STATE
}
render(){
return (
<div className="temperatureSensorBar">
<div className="header">
<div className="title">{TEMPERATURE_SENSOR_PROPERTIES.LABEL+" "+CELSIUS_STATE.name}</div>
</div>
<InputSlider min={this.state.minValue} max={this.state.maxValue} type={TEMPERATURE_SENSOR_PROPERTIES.TYPE}
min_label={TEMPERATURE_SENSOR_PROPERTIES.MIN_LABEL} max_label={TEMPERATURE_SENSOR_PROPERTIES.MAX_LABEL}
step={1} />
render() {
return (
<div className="temperatureSensorBar">
<div className="header">
<div className="title">
{`${TEMPERATURE_SENSOR_PROPERTIES.LABEL} ${CELSIUS_STATE.unitLabel}`}
</div>
</div>
)
}
<InputSlider
min={this.state.minValue}
max={this.state.maxValue}
type={TEMPERATURE_SENSOR_PROPERTIES.TYPE}
min_label={TEMPERATURE_SENSOR_PROPERTIES.MIN_LABEL}
max_label={TEMPERATURE_SENSOR_PROPERTIES.MAX_LABEL}
step={1}
/>
</div>
);
}
}
export default TemperatureSensorBar;