Skip to content

Commit

Permalink
Improve SiriusLed
Browse files Browse the repository at this point in the history
  • Loading branch information
RafaelLyra8 committed Oct 27, 2023
1 parent 666e9b2 commit 304f2bc
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 121 deletions.
4 changes: 2 additions & 2 deletions example/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ const ChartDoc: React.FC = () => {
ADD PVs
</button>
<SiriusChart
pv_name={["RAD:Berthold:TotalDoseRate:Dose",
"RAD:ELSE:TotalDoseRate:Dose", "RAD:Berthold:TotalDoseRate:Dose",
pv_name={["RAD:Thermo1:TotalDoseRate:Dose",
"RAD:ELSE:TotalDoseRate:Dose", "RAD:Thermo1:TotalDoseRate:Dose",
"RAD:ELSE:TotalDoseRate:Dose"]}
label={[['SI','MI'], 'SO', 'RAD', 'SWC']}
color_label={pvs}
Expand Down
4 changes: 0 additions & 4 deletions src/assets/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
type RefChart = React.RefObject<HTMLCanvasElement>

interface State<T> {
value: T
}

interface Dict<T> {
[key: string]: T
}
Expand Down
172 changes: 58 additions & 114 deletions src/components/SiriusLed/index.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,35 @@
import React from "react";
import React, { useState, useEffect } from "react";
import EpicsBase from "../../controllers/epics_base";
import SiriusTooltip from "../SiriusTooltip";
import { State, LedPv, EpicsData, Dict } from "../../assets/interfaces";
import { LedPv, EpicsData, Dict } from "../../assets/interfaces";
import { default_colors, led_shape } from "../../assets/themes";
import * as S from './styled';

/**
* Default Led component for monitoring a PV from the EPICS control system.
*/
class SiriusLed extends React.Component<LedPv, State<string>>{
private epics: EpicsBase<string>;
private color_list: Dict<string>;
private hasMounted: boolean;
private fist_update: Date;

constructor(props: LedPv) {
super(props);
this.updateLed = this.updateLed.bind(this);

this.state = {
value: 'nc'
};
this.fist_update = new Date(0);
this.hasMounted = false;
this.color_list = this.initialize_led_style(props.color);
this.epics = this.initialize_epics_base(props);
this.updateLed();
}

componentDidMount(): void {
this.hasMounted = true;
}

/**
* Save PV name with update
*/
componentDidUpdate(): void {
const { pv_name } = this.props;
this.epics.set_pvname(pv_name);
}

componentWillUnmount(): void {
this.epics.destroy();
}

initialize_epics_base(props: LedPv): EpicsBase<string> {
const SiriusLed: React.FC<LedPv> = (props) => {
const epics: EpicsBase<string> = new EpicsBase<string>(props.pv_name);
const [colorList, setColorList] = useState<Dict<string>>({});
const [state, setState] = useState<string>('nc');

useEffect(() => {
initialize_epics_base();
setColorList(initialize_led_style());
epics?.set_pvname(props.pv_name);
}, [props.pv_name]);

const initialize_epics_base = (): void => {
const { pv_name, threshold, update_interval } = props;

this.epics = new EpicsBase(pv_name);
this.epics.initialize(pv_name, threshold, update_interval);
this.epics.start_timer(this.updateLed);
return this.epics;
}

initialize_led_style(color: Dict<string>|undefined) {
if(color !== undefined) {
color = this.handle_default_color(color);
return color;
}
return default_colors.led;
epics.initialize(pv_name, threshold, update_interval);
epics.start_timer(updateLed);
}

/**
* Add normal and nc (Not connected) colors to the color dictionary
* if they are not declared.
*/
handle_default_color(color: Dict<string>): Dict<string> {
const handle_default_color = (color: Dict<string>): Dict<string> => {
if(!('nc' in color)){
color["nc"] = default_colors.led["nc"];
}
Expand All @@ -75,86 +39,66 @@ class SiriusLed extends React.Component<LedPv, State<string>>{
return color;
}

const initialize_led_style = (): Dict<string> => {
const { color } = props;
if(color !== undefined)
return handle_default_color(color);
return default_colors.led;
}

/**
* Check if the time since the last PV update is greater than
* the disconnect time parameter value.
*/
check_disconnected(disc_time: number, pvInfo: EpicsData<number>, led_value: string): string {
if(pvInfo.date != null){
const update_time: number = pvInfo.date.getTime();
const start_date: number = update_time - this.fist_update.getTime();
let time_since_update: number = (new Date()).getTime() - update_time;
if(start_date < 1000){
time_since_update += disc_time;
}
const check_disconnected = (disc_time: number, pvInfo: EpicsData<number>, led_value: string): string => {
if(pvInfo.date === null)
return "nc";

if(time_since_update >= disc_time){
led_value = "nc";
}
}else{
led_value = "nc";
}
return led_value
}
const update_time: number = pvInfo.date.getTime();
const now_ms: number = (new Date()).getTime();
let time_since_update: number = now_ms - update_time;

/**
* Register first update
*/
register_first_update(): void {
const date_0: Date = new Date(0);
if(date_0.getTime() == this.fist_update.getTime()){
this.fist_update = new Date();
}
if(time_since_update >= disc_time)
return "nc";

return led_value
}

/**
* Update led color with measured EPICS value
*/
updateLed(): void {
const { disc_time, pv_name, modifyValue } = this.props;
const updateLed = (): void => {
const { disc_time, pv_name, modifyValue } = props;
let led_value: string = "nc";
let pvData: Dict<EpicsData<number>> = this.epics.get_pv_data<number>();
const pvInfo: EpicsData<number> = pvData[pv_name];
this.register_first_update();

if(pvInfo != undefined){
const validValue: boolean = this.state!=null && pvInfo.value != null;
if(validValue){
led_value = this.epics.get_threshold(Number(pvInfo.value));
if(modifyValue!=undefined){
led_value = modifyValue<string>(
led_value, pv_name);
if(epics){
let pvData: Dict<EpicsData<number>> = epics.get_pv_data<number>();
const pvInfo: EpicsData<number> = pvData[pv_name];

if(pvInfo != undefined){
const validValue: boolean = state!=null && pvInfo.value != null;
if(validValue){
console.info("OK"+pvInfo.value)
led_value = epics.get_threshold(Number(pvInfo.value));
if(modifyValue!=undefined)
led_value = modifyValue<string>(led_value, pv_name);
if(disc_time)
led_value = check_disconnected(disc_time, pvInfo, led_value);
setState(led_value);
}
if(disc_time){
led_value = this.check_disconnected(
disc_time, pvInfo, led_value)
}
}else{
this.fist_update = new Date(0);
}
}else{
this.fist_update = new Date(0);
}

if(this.hasMounted){
this.setState({
value: led_value
});
}
}

render(): React.ReactNode {
const {shape, pv_name} = this.props;

return(
<SiriusTooltip text={pv_name}>
<S.LedWrapper
shape={led_shape[shape]}
color={this.color_list[this.state.value]}
data-testid="sirius-led"/>
</SiriusTooltip>
);
}
return (
<SiriusTooltip text={props.pv_name}>
<S.LedWrapper
shape={led_shape[props.shape]}
color={colorList[state]}
data-testid="sirius-led"/>
</SiriusTooltip>
);
}

export default SiriusLed;
2 changes: 1 addition & 1 deletion src/controllers/epics_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class EpicsBase<T extends string|string[]> {
private timer: any;

constructor(pvname: T){
this.update_interval = 100;
this.update_interval = 300;
this.pv_name = pvname;
this._subscribe2epics_con();
this.timer = null;
Expand Down

0 comments on commit 304f2bc

Please sign in to comment.