Skip to content

Commit

Permalink
Merge pull request #26 from Nasar165/start-transaction
Browse files Browse the repository at this point in the history
start charging implemented
  • Loading branch information
Nasar165 authored May 5, 2024
2 parents a7cab33 + bcbaf85 commit d3621e6
Show file tree
Hide file tree
Showing 14 changed files with 257 additions and 28 deletions.
12 changes: 6 additions & 6 deletions app/components/WebSocket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
OnMessageEvent,
} from '../service/websocket/websocket.model';
import WebSocketHook from '../hook/socketHook';
import Button from './button';

type Url = {
url: string;
Expand Down Expand Up @@ -35,12 +36,11 @@ export default function WebSocket({

return (
<div>
<button
className='border border-blue-600 rounded-md px-4 py-2 my-4'
onClick={() => start()}
>
{online ? 'Disconnect' : 'Connect'}
</button>
<Button
onClick={start}
text={online ? 'Disconnect' : 'Connect'}
disabled={false}
/>
</div>
);
}
18 changes: 18 additions & 0 deletions app/components/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
type button = {
text: string;
disabled: boolean;
onClick: () => void;
};

export default function Button({ text, disabled, onClick }: button) {
const disable = disabled ? 'bg-gray-400' : '';
return (
<button
className={`${disable} border border-blue-600 rounded-md px-4 py-2 my-4`}
onClick={() => onClick()}
disabled={disabled}
>
{text}
</button>
);
}
38 changes: 28 additions & 10 deletions app/components/evse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import { ConState, IWriter } from '../service/websocket/websocket.model';
import WebSocket from './WebSocket';
import { ChargingSocket, IChargingSocket } from '../service/ocpp/connector';
import { HandleOcpp } from '../service/ocpp/ocpp.handler';
import { SendBootNotification } from '../service/ocpp/command/boot-notification/bootnotification';
import { SendBootNotification } from '../service/ocpp/command/boot-notification/boot.notification';
import StatusNotificationUI from './status.notification';
import {
ChargePointErrorCodes,
StatusNotification,
} from '../service/ocpp/command/status-notification/status.notificiation';
} from '../service/ocpp/command/status-notification/status.notification';
import { SendStatusNotification } from '../service/ocpp/command/status-notification/statusnotification';
import Transaction from './transaction';

const defaultValue = 'ws://localhost:8080/ocpp/JwNpTpPxPm/CHR202305102';

Expand Down Expand Up @@ -55,14 +56,31 @@ export default function Evse() {

return (
<div className='w-screen mx-auto mt-8 md:w-2/3 xl:w-1/3'>
<Input name='url' value={url} onChange={onChange} disabled={online} />
<WebSocket
url={url}
state={onlineChange}
onMessage={onMessage}
online={online}
/>
<StatusNotificationUI state={socket.State} changeState={changeState} />
<div className='border border-black p-2 my-2 rounded-md'>
<Input
title='Websocket Url'
name='url'
placeholder='wss://'
value={url}
onChange={onChange}
disabled={online}
/>
<WebSocket
url={url}
state={onlineChange}
onMessage={onMessage}
online={online}
/>
<StatusNotificationUI state={socket.State} changeState={changeState} />
</div>

<div className={online ? '' : 'hidden'}>
<Transaction
writer={writer.current[0]}
connectorId={0}
state={socket.State}
/>
</div>
</div>
);
}
8 changes: 6 additions & 2 deletions app/components/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@ import { SyntheticEvent } from 'react';
type InputEvent = (event: SyntheticEvent<HTMLInputElement>) => void;

type input = {
title: string;
name: string;
value: string;
placeholder: string;
disabled: boolean;
onChange: InputEvent;
};

export default function Input({
title,
name,
value,
placeholder,
disabled,
onChange,
}: input): JSX.Element {
return (
<div className='px-4'>
<label className='block text-sm font-medium leading-6 text-gray-900'>
Websocket Url
{title}
</label>
<div className='relative mt-2 rounded-md shadow-sm'>
<input
Expand All @@ -27,7 +31,7 @@ export default function Input({
defaultValue={value}
onChange={onChange}
className='block w-full rounded-md border-0 py-1.5 pl-7 pr-20 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6'
placeholder='wss://'
placeholder={placeholder}
disabled={disabled}
/>
</div>
Expand Down
4 changes: 1 addition & 3 deletions app/components/status.notification.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { StatusNotification } from '../service/ocpp/command/status-notification/status.notificiation';
import { StatusNotification } from '../service/ocpp/command/status-notification/status.notification';
import { ChangeState } from '../service/ocpp/ocpp.handler';
import Select, { Item, ReturnValue } from './select';

Expand All @@ -20,8 +20,6 @@ export default function StatusNotificationUI({
const onChange = (value: ReturnValue) =>
changeState(value as StatusNotification);

console.log(state);

return (
<div>
state: {state}
Expand Down
81 changes: 81 additions & 0 deletions app/components/transaction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React, { SyntheticEvent, useState } from 'react';
import { SendStartTransaction } from '../service/ocpp/charging/start.transaction';
import Input from './input';
import Button from './button';
import { IWriter } from '../service/websocket/websocket.model';
import { StatusNotification } from '../service/ocpp/command/status-notification/status.notification';

type transaction = {
writer: IWriter;
connectorId: number;
state: StatusNotification;
};

export default function Transaction({
writer,
connectorId,
state,
}: transaction): React.JSX.Element {
const [idTag, setIdTag] = useState('cli013322');
const onChange = (ev: SyntheticEvent<HTMLInputElement>) => {
setIdTag(ev.currentTarget.value);
};

const notConnected = () => {
if (writer == null) {
alert('Please connect to CSMS');
}
};

const onStart = () => {
if (writer == null) {
notConnected();
return;
}

if (
state == StatusNotification.AVAILABLE ||
state == StatusNotification.PREPARING
) {
if (idTag.trim() == '') return;
SendStartTransaction(writer, connectorId, idTag);
return;
}

alert(
'Please make sure that the charger is in Available or preparing state'
);
};

const onStop = () => {
if (writer == null) {
notConnected();
return;
}
};

return (
<div className='border border-black p-2 my-2 rounded-md'>
<Input
title='Client id tag'
name='idTag'
placeholder='enter ID tag to submit with start transaction'
value={idTag}
onChange={onChange}
disabled={false}
/>
<div className='grid gap-2 grid-cols-2'>
<Button
onClick={onStart}
text='Start Transaction'
disabled={state == StatusNotification.CHARGING}
/>
<Button
onClick={onStop}
text='Stop Transaction'
disabled={state != StatusNotification.CHARGING}
/>
</div>
</div>
);
}
52 changes: 52 additions & 0 deletions app/service/ocpp/charging/start.transaction.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Min } from 'class-validator';

enum AuthorizationStatus {
ACCEPTED = 'Accepted',
BLOCKED = 'Blocked',
EXPIRED = 'Expired',
INVALID = 'Invalid',
CONCURRENT_TX = 'ConcurrentTx',
}

interface IIdTagInfo {
expiryDate: Date;
parentIdTag: string;
status: string;
}

interface IStartTransactionRes {
idTagInfo: IIdTagInfo;
transactionId: number;
}

interface IStartTransaction {
connectorId: number;
idTag: string;
meterStart: number;
timestamp: Date;
}

interface IChargingSession {
idTag: string;
transactionId: number;
connectorId: number;
}

class StartTransactionsRes implements IStartTransactionRes {
idTagInfo: IIdTagInfo = {
expiryDate: new Date(),
status: AuthorizationStatus.BLOCKED,
parentIdTag: '',
};

@Min(0)
transactionId: number = 0;
}

export type {
IIdTagInfo,
IStartTransaction,
IStartTransactionRes,
IChargingSession,
};
export { AuthorizationStatus, StartTransactionsRes };
60 changes: 60 additions & 0 deletions app/service/ocpp/charging/start.transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import Validate from '@/app/helper/validation.helper';
import { IWriter } from '../../websocket/websocket.model';
import { Action, CreateRequestFrame, GetRequestFrame } from '../ocpp.action';
import { CreateError, ErrorCode } from '../ocpp.error';
import { IResponse } from '../ocpp.frame';
import { ChangeState } from '../ocpp.handler';
import { CreateTransaction } from '../transaction/transaction.handler';
import {
AuthorizationStatus,
IChargingSession,
IStartTransaction,
StartTransactionsRes,
} from './start.transaction.model';
import { StatusNotification } from '../command/status-notification/status.notification';

let session: IChargingSession;

function SendStartTransaction(
w: IWriter,
connectorId: number,
idTag: string
): void {
const transaction: IStartTransaction = {
connectorId,
idTag,
meterStart: 0,
timestamp: new Date(),
};

const frame = CreateRequestFrame(Action.START_TRANSACTION, transaction);
w.Write(frame);
CreateTransaction(GetRequestFrame(frame), StartTransaction);
session = { connectorId, idTag, transactionId: -1 };
}

function StartTransaction(
w: IWriter,
frame: IResponse,
changeState: ChangeState
): IChargingSession | undefined {
const [result, validation] = Validate<StartTransactionsRes>(
StartTransactionsRes,
frame.payload
);

if (validation.length > 0) {
w.Write(CreateError(ErrorCode.PropertyConstraintViolation, validation));
return;
}

if (result.idTagInfo.status != AuthorizationStatus.ACCEPTED) {
return;
}

changeState(StatusNotification.CHARGING);
session.transactionId = result.transactionId;
return session;
}

export { SendStartTransaction, StartTransaction };
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import {
BootNotificationRes,
IBootNotification,
Status,
} from './bootnotification.model';
} from './boot.notification.model';
import { CreateError, ErrorCode } from '../../ocpp.error';
import Validate from '@/app/helper/validation.helper';
import { StatusNotification } from '../status-notification/status.notificiation';
import { StatusNotification } from '../status-notification/status.notification';
import { ChangeState } from '../../ocpp.handler';

const defaultValue: IBootNotification = {
Expand Down Expand Up @@ -60,8 +60,6 @@ function BootNotification(
frame.payload
);

console.log(validation);

if (validation.length > 0) {
w.Write(CreateError(ErrorCode.PropertyConstraintViolation, validation));
return retry(w);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ChargePointErrorCodes,
IStatusNotification,
StatusNotification,
} from './status.notificiation';
} from './status.notification';

function SendStatusNotification(
w: IWriter,
Expand Down
2 changes: 1 addition & 1 deletion app/service/ocpp/connector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { StatusNotification } from './command/status-notification/status.notificiation';
import { StatusNotification } from './command/status-notification/status.notification';

interface IChargingSocket {
State: StatusNotification;
Expand Down
2 changes: 1 addition & 1 deletion app/service/ocpp/ocpp.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import {
ChargePointErrorCodes,
StatusNotification,
} from './command/status-notification/status.notificiation';
} from './command/status-notification/status.notification';
import { FindTransaction } from './transaction/transaction.handler';

type OCPPData = IRequest | IResponse | IErrorFrame;
Expand Down

0 comments on commit d3621e6

Please sign in to comment.