Compare commits

..

No commits in common. 'master' and 'simu-visual-frontend' have entirely different histories.

@ -0,0 +1,17 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

99
.gitignore vendored

@ -1,53 +1,46 @@
# ---> Eagle
# Ignore list for Eagle, a PCB layout tool
# Backup files
*.s#?
*.b#?
*.l#?
*.b$?
*.s$?
*.l$?
# Eagle project file
# It contains a serial number and references to the file structure
# on your computer.
# comment the following line if you want to have your project file included.
eagle.epf
# Autorouter files
*.pro
*.job
# CAM files
*.$$$
*.cmp
*.ly2
*.l15
*.sol
*.plc
*.stc
*.sts
*.crc
*.crs
*.dri
*.drl
*.gpi
*.pls
*.ger
*.xln
*.drd
*.drd.*
*.s#*
*.b#*
*.info
*.eps
# file locks introduced since 7.x
*.lck
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
speed-measure-plugin*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

@ -1,208 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution
as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct
or indirect, to cause the direction or management of such entity, whether
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled object
code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that
is included in or attached to the work (an example is provided in the Appendix
below).
"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative
Works shall not include works that remain separable from, or merely link (or
bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative
Works thereof, that is intentionally submitted to Licensor for inclusion in
the Work by the copyright owner or by an individual or Legal Entity authorized
to submit on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication
sent to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor
for the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently incorporated
within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License,
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section) patent
license to make, have made, use, offer to sell, sell, import, and otherwise
transfer the Work, where such license applies only to those patent claims
licensable by such Contributor that are necessarily infringed by their Contribution(s)
alone or by combination of their Contribution(s) with the Work to which such
Contribution(s) was submitted. If You institute patent litigation against
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
that the Work or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses granted to You
under this License for that Work shall terminate as of the date such litigation
is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and
in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy
of this License; and
(b) You must cause any modified files to carry prominent notices stating that
You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source
form of the Work, excluding those notices that do not pertain to any part
of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable copy
of the attribution notices contained within such NOTICE file, excluding those
notices that do not pertain to any part of the Derivative Works, in at least
one of the following places: within a NOTICE text file distributed as part
of the Derivative Works; within the Source form or documentation, if provided
along with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works
that You distribute, alongside or as an addendum to the NOTICE text from the
Work, provided that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction,
or distribution of Your modifications, or for any such Derivative Works as
a whole, provided Your use, reproduction, and distribution of the Work otherwise
complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to the
Licensor shall be under the terms and conditions of this License, without
any additional terms or conditions. Notwithstanding the above, nothing herein
shall supersede or modify the terms of any separate license agreement you
may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names,
trademarks, service marks, or product names of the Licensor, except as required
for reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
in writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any warranties
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
of using or redistributing the Work and assume any risks associated with Your
exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether
in tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to
in writing, shall any Contributor be liable to You for damages, including
any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or inability
to use the Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all other commercial
damages or losses), even if such Contributor has been advised of the possibility
of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work
or Derivative Works thereof, You may choose to offer, and charge a fee for,
acceptance of support, warranty, indemnity, or other liability obligations
and/or rights consistent with this License. However, in accepting such obligations,
You may act only on Your own behalf and on Your sole responsibility, not on
behalf of any other Contributor, and only if You agree to indemnify, defend,
and hold each Contributor harmless for any liability incurred by, or claims
asserted against, such Contributor by reason of your accepting any such warranty
or additional liability. END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
information. (Don't include the brackets!) The text should be enclosed in
the appropriate comment syntax for the file format. We also recommend that
a file or class name and description of purpose be included on the same "printed
page" as the copyright notice for easier identification within third-party
archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -1,19 +1,27 @@
#### 从命令行创建一个新的仓库
# SimulationVisualization
```bash
touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://bdgit.educoder.net/pa4hzw8mg/MySmartHome.git
git push -u origin master
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 11.0.7.
```
## Development server
#### 从命令行推送已经创建的仓库
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
```bash
git remote add origin https://bdgit.educoder.net/pa4hzw8mg/MySmartHome.git
git push -u origin master
## Code scaffolding
```
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

@ -0,0 +1,125 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"simulation-visualization": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/simulation-visualization",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/@videogular/ngx-videogular/fonts/videogular.css",
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "simulation-visualization:build"
},
"configurations": {
"production": {
"browserTarget": "simulation-visualization:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "simulation-visualization:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "simulation-visualization:serve"
},
"configurations": {
"production": {
"devServerTarget": "simulation-visualization:serve:production"
}
}
}
}
}
},
"defaultProject": "simulation-visualization"
}

@ -0,0 +1,37 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome'
},
directConnect: true,
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: StacktraceOption.PRETTY
}
}));
}
};

@ -0,0 +1,23 @@
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', async () => {
await page.navigateTo();
expect(await page.getTitleText()).toEqual('simulation-visualization app is running!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

@ -0,0 +1,11 @@
import { browser, by, element } from 'protractor';
export class AppPage {
async navigateTo(): Promise<unknown> {
return browser.get(browser.baseUrl);
}
async getTitleText(): Promise<string> {
return element(by.css('app-root .content span')).getText();
}
}

@ -0,0 +1,13 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es2018",
"types": [
"jasmine",
"node"
]
}
}

@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/simulation-visualization'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

13697
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,53 @@
{
"name": "simulation-visualization",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~11.0.9",
"@angular/common": "~11.0.9",
"@angular/compiler": "~11.0.9",
"@angular/core": "~11.0.9",
"@angular/forms": "~11.0.9",
"@angular/platform-browser": "~11.0.9",
"@angular/platform-browser-dynamic": "~11.0.9",
"@angular/router": "~11.0.9",
"@types/dom-mediacapture-record": "^1.0.10",
"@videogular/ngx-videogular": "^4.0.0",
"jquery": "^3.6.0",
"js-audio-recorder": "^1.0.7",
"ng2-file-upload": "^1.4.0",
"recorder-core": "^1.1.21080800",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1100.7",
"@angular/cli": "~11.0.7",
"@angular/compiler-cli": "~11.0.9",
"@types/core-js": "^2.5.4",
"@types/jasmine": "~3.6.0",
"@types/jquery": "^3.5.6",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.7.1",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.1.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.6.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.0.2"
}
}

@ -0,0 +1,27 @@
.whole{
margin-top: 0;
margin-bottom: 0;
width: 100%;
height: 800px;
}
.input_class{
height: 90%;
width: 100%;
border: black,solid,1px;
position: relative;
}
#requirementsPanel #input_textarea {
position: relative;
margin-left: 20px;
height: 480px;
resize: none;
display: block;
border: 2px solid #000;
border-radius: 5px;
}

@ -0,0 +1,7 @@
<div class="whole">
<app-topbar></app-topbar>
<app-main></app-main>
</div>

@ -0,0 +1,31 @@
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'simulation-visualization'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('simulation-visualization');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('simulation-visualization app is running!');
});
});

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'simulation-visualization';
}

@ -0,0 +1,35 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { TopbarComponent } from './topbar/topbar.component';
import { MainComponent } from './main/main.component';
import { FormsModule } from '@angular/forms';
import { FileUploadModule } from 'ng2-file-upload';
import { HttpClientModule } from '@angular/common/http';
import {VgCoreModule} from '@videogular/ngx-videogular/core';
import {VgControlsModule} from '@videogular/ngx-videogular/controls';
import {VgOverlayPlayModule} from '@videogular/ngx-videogular/overlay-play';
import {VgBufferingModule} from '@videogular/ngx-videogular/buffering';
@NgModule({
declarations: [
AppComponent,
TopbarComponent,
MainComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
FileUploadModule,
VgCoreModule,
VgControlsModule,
VgOverlayPlayModule,
VgBufferingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

@ -0,0 +1,555 @@
import { StringMap } from "@angular/compiler/src/compiler_facade_interface";
import { ITS_JUST_ANGULAR } from "@angular/core/src/r3_symbols";
// export interface Scene{
// sceneName:string;
// datasTimeValue:Array<DataTimeValue>;
// nameDataFunctions:Array<NameDataFunction>;
// devicesAnalysResults:Array<DeviceAnalysResult>;
// triggeredRulesName:Array<DataTimeValue>;
// cannotTriggeredRulesName:Array<string>;
// }
export interface DataTimeValue{
name:string;
timeValues:Array<number[]>;
}
export interface NameDataFunction{
name:string;
dataFunctions:Array<DataFunction>;
}
export interface DataFunction{
downTime:number;
upTime:number;
downValue:number;
upValue:number;
function:Function;
}
export interface Function{
a:number;
b:number;
}
export interface DeviceAnalysResult{
deviceName:string;
statesConflict:DeviceConflict;
statesChange:StatesChange;
deviceStateLastTime:DeviceStateTime;
deviceCannotOff:DeviceCannotOff;
deviceStateName:DeviceStateName;
}
export interface DeviceConflict{
name:string;
hasConflict:boolean;
conflictTimes:Array<ConflictTime>;
}
export interface ConflictTime{
conflictStates:Array<string[]>;
conflictTime:string;
}
export interface StatesChange{
statesChangeCount:number;
statesChangeFrequence:number;
stateChangeFasts:Array<StateChangeFast>;
}
export interface StateChangeFast{
startTimeValue:number[];
middleTimeValue:number[];
endTimeValue:number[];
}
export interface DeviceStateTime{
name:string;
statesTime:Array<StateLastTime>;
}
export interface StateLastTime{
state:string;
stateName:string;
lastTime:number;
}
export interface DeviceCannotOff{
cannotOff:boolean;
cannotOffReason:CannotOffReason;
}
export interface CannotOffReason{
reason:string;
cannotTriggeredRules:Array<Rule>;
}
export interface DeviceStateName{
deviceName:string;
stateNames:Array<StateNameRelativeRule>;
}
export interface StateNameRelativeRule{
stateValue:string;
stateName:string;
relativeRules:Array<Rule>;
}
export interface Rule{
ruleName:string;
ruleContent:string;
trigger:Array<string>;
action:Array<string>;
}
export interface Action{
action:string;
device:string;
toState:string;
value:string;
attrVal:Array<string>;
rules:Array<Rule>
}
export interface RuleText{
rules:Array<string>
}
export interface RulesSceneSimulationTime{
rules:Array<Rule>;
scene:Scene;
simulationTime:string
}
export interface RulesAllScenesSimulationTime{
rules:Array<Rule>;
scenes:Array<Scene>;
simulationTime:string
}
/////////////////////////////states conflict//////////////
export interface StateAndRuleAndCauseRule{
stateValue:string;
stateName:string;
rulesAndCauseRules:Array<RuleAndCause>;
}
export interface RuleAndCause{
selfRule:Rule;
causeRules:Array<RuleAndCause>;
}
export interface CauseRuleInput{
conflictStateTime:ConflictTime;
triggeredRulesName:Array<DataTimeValue>;
deviceStateName:DeviceStateName;
rules:Array<Rule>;
}
export interface AllCauseRuleInput{
conflictStateTimes:Array<ConflictTime>;
triggeredRulesName:Array<DataTimeValue>;
deviceStateName:DeviceStateName;
rules:Array<Rule>;
}
///////////////conflict 总的分析/////////////////
export interface ConflictStateAndRules{
conflictStateCauseRules:Array<StateAndRuleAndCauseRule>;
count:number;
}
export interface DeviceConflictCauseRule{
deviceName:string;
conflictStatisticCauseRuleList:Array<ConflictStateAndRules>;
}
/////////////////////////state changes////////////////////////
export interface WholeAndCurrentChangeCauseRule{
wholeStateChangesCauseRules:Array<StateChangeCauseRules>;
currentStateChangeCauseRules:StateChangeCauseRules;
}
export interface StateChangeCauseRules{
start: TimeStateRelativeRules;
middle: TimeStateRelativeRules;
end: TimeStateRelativeRules;
}
export interface TimeStateRelativeRules{
time:number;
stateName:string;
relativeRules:Array<Rule>;
}
export interface StateChangeCauseRuleInput{
triggeredRulesName:Array<DataTimeValue>;
deviceStateName:DeviceStateName;
stateChangeFasts:Array<StateChangeFast>;
stateChangeFast:StateChangeFast;
}
export interface StateRules{
stateName:string;
causeRules:Array<Rule>;
count:number;
}
export interface DeviceFastChangeCause{
deviceName:string;
fastChangeCauseRuleList:Array<Array<StateRules>>;
}
export interface DeviceStateReachable{
deviceName:string;
stateReachable:Array<StateReachable>;
}
export interface StateReachable{
stateName:string;
stateValue:string;
reachable:boolean;
rules:Array<Rule>;
}
export interface DeviceNotOff{
deviceName:string;
rules:Array<Rule>;
}
export interface AllScenesAnalysisInput{
scenes:Array<Scene>;
rules:Array<Rule>;
properties:Array<string>;
}
export interface RuleAnalysis{
rule:Rule;
canTriggered:boolean;
canCauseStateConflict:CanCauseStateConflict;
canCauseFastChange:CanCauseFastChange;
}
export interface CanCauseStateConflict{
canCauseStateConflict:boolean;
devicesStateCounterRules:Array<DeviceStateCounterRules>
}
export interface CanCauseFastChange{
canCause:boolean;
devicesStateCouterRules:Array<DeviceStateCounterRules>
}
export interface DeviceStateCounterRules{
deviceName:string;
deviceState:string;
counterRules:Array<CounterRule>;
}
export interface CounterRule{
rule:Rule;
deviceState:string;
occurScenes:Array<Scene>
}
export interface DeviceSceneConflictCauseRule{
deviceName:string;
scenesConflcitStateCasueRule:Array<SceneConflictStateCauseRule>;
}
export interface SceneConflictStateCauseRule{
sceneName:String;
conflictCauseRuleStatistic:Array<CountStatesCauseRule>;
}
export interface CountStatesCauseRule{
count:number;
statesCauseRule:Array<StateCauseRule>;
}
export interface StateCauseRule{
stateValue:string;
stateName:string;
causeRules:Array<RuleAndCause>;
}
export interface DeviceSceneFastChangeCauseRule{
deviceName:string;
scenesFastChangeCauseRule:Array<SceneFastChangeCauseRule>;//每个场景frequent change的情况
}
export interface SceneFastChangeCauseRule{
sceneName:string;
fastChangeStateCauseRuleCountList:Array<StateCauseRuleCount>;
}
export interface DeviceScenesFastChangeCauseRule{
deviceName:string;
scenesFastChangeCauseRules:Array<ScenesFastChangeCauseRule>;
}
export interface ScenesFastChangeCauseRule{
sceneNames:Array<string>;
fastChangeStateCauseRuleCountList:Array<StateCauseRuleCount>;//////////某段frenquent change 的states及相应rules
}
export interface StateCauseRuleCount{
stateName:string;
rulesCount:Array<RuleCount>; ////////////在这一段引起frequent change中的某一状态发生的规则及其发生次数
}
export interface RuleCount{
causeRule:RuleAndCause;
count:number;
}
export interface DeviceAllSceneConflictRule{
deviceName:string;
allCountStateCauseRuleSceneName:Array<CountStatesCauseRuleSceneName>;
}
export interface CountStatesCauseRuleSceneName{
sceneNames:Array<string>;
countStatesCauseRule:CountStatesCauseRule;
}
export interface DeviceAllSceneFastChangeRule{
deviceName:string;
allFastChangeStateCauseRuleCountSceneName:Array<StateCauseRuleCountSceneName>;
}
export interface StateCauseRuleCountSceneName{
stateName:string;
rulesCountSceneName:Array<RuleCountSceneName>;
}
export interface RuleCountSceneName{
sceneNames:Array<string>;
ruleCount:RuleCount;
}
export interface AllRuleAnalysisResult{
scenes:Array<Scene>;
rulesNeverTriggered:Array<RuleAndCause>;
devicesAllSceneConflictRule:Array<DeviceAllSceneConflictRule>;
devicesAllSceneFastChangeRule:Array<DeviceAllSceneFastChangeRule>;
devicesSceneConflictCauseRule:Array<DeviceSceneConflictCauseRule>;
devicesSceneFastChangeCauseRule:Array<DeviceSceneFastChangeCauseRule>;
propertyAnalysis:Array<PropertyAnalysis>;
}
export interface RuleCauseRuleInput{
causeRules:Array<Rule>,
rules:Array<Rule>
}
export interface DeviceStatesCauseRules{
deviceName:string;
statesRules:Array<StateCauseRules>
}
export interface StateCauseRules{
stateName:string;
causeRules:Array<RuleAndCause>
}
export interface PropertyAnalysis{
property:string;
reachable:boolean;
reachableScenes:Array<string>
}
/////静态分析结构
export interface StaticAnalysisResult{
incorrectRules:Array<ErrorReason>;
unusedRules:Array<ErrorReason>;
redundantRules:Array<Array<Rule>>;
incompleteness:Array<string>;
usableRules:Array<Rule>;
totalRules:Array<Rule>
}
export interface ErrorReason{
rule:Rule;
reason:string;
}
/////环境模型
export interface EnvironmentModel{
devices:Array<DeviceDetail>;
sensors:Array<SensorType>;
biddables:Array<BiddableType>;
deviceTypes:Array<DeviceType>;
attributes:Array<Attribute>
}
export interface DeviceDetail{
deviceName:string;
location:string;
deviceType:DeviceType;
constructionNum:Number;
}
export interface Entity{
name:string;
}
export interface DeviceType extends Entity{
stateActionValues:Array<string[]>;
stateEffects:Array<StateEffect>;
deviceNumber:Number;
}
export interface StateEffect{
state:string;
effects:Array<string[]>
}
export interface BiddableType extends Entity{
stateAttributeValues:Array<string[]>;
}
export interface SensorType extends Entity{
attribute:string;
style:string
}
/////静态分析结果输出结构
export interface EnvironmentStatic{
environmentModel:EnvironmentModel;
staticAnalysisResult:StaticAnalysisResult
}
/////生成仿真模型输入结构
export interface EnvironmentRule{
environmentModel:EnvironmentModel;
rules:Array<Rule>
}
export interface Scene{
scenarioName:string;
dataTimeValues:Array<DataTimeValue>;
triggeredRulesName:Array<DataTimeValue>;
cannotTriggeredRulesName:Array<string>;
deviceAnalysisResults:Array<DeviceAnalysisResult>
}
export interface SceneEnvironmentProperty{
scenes:Array<Scene>;
properties:Array<string>;
rules:Array<Rule>;
environmentModel:EnvironmentModel;
}
export interface DeviceAnalysisResult{
deviceStateName: any;
deviceName:string;
conflictReasons:Array<ConflictReason>;
jitterReasons:Array<JitterReason>
}
export interface ConflictReason{
conflict:Conflict;
causingRules:Array<CauseRule>
}
export interface JitterReason{
jitter:Array<Number[]>;
causingRules:Array<CauseRule>
}
export interface Conflict{
time:Number;
conflictValues:Array<Number>
}
export interface CauseRule{
state:string;
value:Number;
stateCausingRules:Array<RuleNode>
}
export interface RuleNode{
rule:Rule;
preRules:Array<RuleNode>
}
export interface SceneEnvironmentRule{
scene:Scene;
environmentModel:EnvironmentModel;
rules:Array<Rule>
}
/////综合原因,并计数
export interface CauseRulesCount{
count:number;
causingRules:Array<CauseRule>
////表示有哪些场景有这种情况
exsitScenes:Array<string>
}
export interface DeviceAnalysisSyntheticResult{
deviceName:string;
jitterCauseRulesCounts:Array<CauseRulesCount>;
conflictCauseRulesCounts:Array<CauseRulesCount>;
}
export interface DeviceCauseRuleConclusion{
deviceName:string;
causingRules:Array<CauseRule>
}
export interface ScenePropertyResult{
scenes:Array<Scene>;
propertyVerifyResults:Array<PropertyVerifyResult>;
}
export interface PropertyVerifyResult{
property:string;
reachable:boolean;
reachableReasons:Array<ReachableReason>;
hasCorrespondRule:boolean;
correspondingRules:Array<Rule>
}
export interface ReachableReason{
satisfyIntervalTime:Number[];
scenarioName:string;
causingRules:Array<CauseRule>;
}
export interface PropertyReachableSyntheticResult{
property:string
reachableCauseRulesCounts:Array<CauseRulesCount>
reachable:boolean
hasCorrespondRule:boolean;
correspondingRules:Array<Rule>
}
export interface Attribute{
content:string;
attribute:string;
delta:string
}

@ -0,0 +1,263 @@
.main{
width: 100%;
height: 800px;
}
.left{
width: 40%;
position: relative;
display: flex;
flex-direction: column;
}
.rule_ontology{
width: 100%;
position: relative;
display: flex;
flex-direction: column;
height: 100%;
}
.right{
width: 60%;
position: relative;
}
.button{
margin-left: 20px;
width:140px;
height: 50px;
border: solid #000 1px;
border-radius: 5px;
}
/* rules-ontology */
.textarea{
margin-left: 10px;
margin-right: 10px;
margin-bottom: 10px;
width:95%;
height: 670px;
border: #36648B 2px solid;
border-radius: 10px;
padding: 10px;
font-size: 1em;
}
.chooseFile{
margin-left: 10px;
margin-top: 5px;
padding: 2px;
width: 200px;
border: solid,1px, #36648B;
background-color: #5fa3df;
}
.chooseFile_c{
background-color: #8bb7df;
margin-left: 10px;
margin-top: 0px;
padding: 1px;
width: 200px;
}
.submit_button{
margin-left: 40px;
margin-top: 10px;
width:100px;
height: 40px;
border: solid #000 1px;
border-radius: 5px;
}
label{
margin-left: 10px;
color: #36648B;
}
.my-code-editor .editor-container {
height: calc(100vh - 100px);
}
#input_textarea {
position: relative;
margin-left: 10px;
height: 690px;
resize: none;
display: block;
border: 2px solid #36648B;
border-radius: 5px;
}
/* rule-ontology */
.ifd_style{
width: 100%;
height: 700px;
}
.main_ontology_rules{
position: relative;
width: 100%;
display: flex;
flex-direction: row;
}
h2{
margin-top: 10px;
margin-left: 10px;
margin-bottom: 10px;
}
.random-range{
margin-left: 10px;
margin-right: 10px;
margin-bottom: 10px;
border: #36648B 2px solid;
border-radius: 10px;
padding: 10px;
width:95%;
height: 670px;
position: relative;
}
img{
width: 100%;
height: 100%;
}
.button-group{
height: 50px;
display: flex;
}
.scenes-scope{
position: relative;
height: 100%;
width: 100%;
}
.scrollbar{
background-color:transparent;
position: relative;
height: 100%;
width: 100%;
overflow-y: auto;
overflow-x: auto;
scrollbar-face-color: #889B9F;
scrollbar-shadow-color: #3D5054;
scrollbar-highlight-color: #C3D6DA;
scrollbar-3dlight-color: #3D5054;
scrollbar-darkshadow-color: #85989C;
scrollbar-track-color: #95A6AA;
scrollbar-arrow-color: #FFD6DA;
}
.echarts_scale{
position: relative;
height:200%;
width: 200%;
}
.scenes_tree_scale{
position: relative;
height: 100%;
width: 100%;
}
.scenes_rules_scale{
position: relative;
height: 98%;
width: 100%;
}
.rules_scenes_scale{
position: relative;
height: 98%;
width: 100%;
}
.upload {
position: relative;
}
.change {
position: absolute;
overflow: hidden;
right: 0;
top: 0;
opacity: 0;
cursor: pointer;
width:140px;
height: 50px;
}
.upload_button {
margin-left: 20px;
margin-top: 30px;
padding: 1px 6px;
color: rgb(12, 11, 11);
background: #e0e2e4;
border: 1px solid #ddd;
cursor: pointer;
float: left;
font-size: 20px;
z-index: 5;
}
.analys_button{
border-right: 20px;
width:80px;
height: 50px;
border: solid #000 1px;
border-radius: 5px;
}
.auth-btn{
margin-left: 20px;
margin-right: 20px;
width:80px;
height: 50px;
border: solid #000 1px;
border-radius: 5px;
}
.record-btn{
margin-left: 20px;
margin-right: 10px;
width:50px;
height: 40px;
border: solid #000 1px;
border-radius: 5px;
}
.simulation_time_input{
margin-top: 10px;
margin-left: 10px;
width: 100px;
}
.simulation_time{
margin-left: 20px;
width: 150px;
}

@ -0,0 +1,107 @@
<div class="main">
<div id="ontology_rules" class="main_ontology_rules">
<div class="left">
<div class="rule_ontology">
<div>
<h2><b>Please Enter Trigger Action Programs:</b></h2>
<textarea class="textarea"
placeholder="Please enter 'IF...THEN...', such as 'IF temperature>30 THEN AirConditioner_0.turn_ac_cool '"
[(ngModel)]="ruleText">
</textarea>
<div class="button-group">
<!-- 上传环境本体 -->
<!-- <button class="upload button">Upload Ontology
<input class="change" type="file" ng2FileSelect [uploader]="modelUploader"
(change)="uploadModelFile($event)" />
</button> -->
<!-- 上传location和deviceInformation的property文件 -->
<!-- <button class="upload button">Upload Device Information
<input class="change" type="file" ng2FileSelect [uploader]="propertyUploader"
(change)="uploadPropertyFile($event)" />
</button> -->
<button class="auth-btn" id="auth" (click)="authorize()">record</button>
<!-- <button class="record-btn" id="record_btn" (click)="recordAudio()">record</button> -->
<!-- <audio controls class="audio-player" id="play_btn" src="{{audioURL}}"></audio> -->
<button class="analys_button" (click)="getBestScenarioAnalysis()">Simulation</button>
<!-- <button class="analys_button" (click)="getStaticAnalysisResult()">Static Analysis</button>
<button class="analys_button" (click)="generateAllSystemModels()">Generate Models</button>
<button class="analys_button" (click)="scenariosSimulation()">Simulate</button> -->
</div>
</div>
</div>
<!-- <app-rules-ontology class="rule_ontology"></app-rules-ontology> -->
</div>
<div class="right">
<div id="simulation">
<h2><b>Simulation Visualization:</b></h2>
<div class="random-range" >
<vg-player id="visualizationResult" >
<vg-overlay-play></vg-overlay-play>
<vg-buffering></vg-buffering>
<vg-scrub-bar>
<vg-scrub-bar-current-time></vg-scrub-bar-current-time>
<vg-scrub-bar-buffering-time></vg-scrub-bar-buffering-time>
</vg-scrub-bar>
<vg-controls>
<vg-play-pause></vg-play-pause>
<vg-playback-button></vg-playback-button>
<vg-time-display vgProperty="current" vgFormat="mm:ss"></vg-time-display>
<vg-scrub-bar style="pointer-events: none;"></vg-scrub-bar>
<vg-time-display vgProperty="left" vgFormat="mm:ss"></vg-time-display>
<vg-time-display vgProperty="total" vgFormat="mm:ss"></vg-time-display>
<!-- <vg-track-selector></vg-track-selector> -->
<vg-mute></vg-mute>
<vg-volume></vg-volume>
<vg-fullscreen></vg-fullscreen>
</vg-controls>
<video [vgMedia]="media" #media id="singleVideo" preload="auto" crossorigin >
<source src="{{videoURL}}" type="video/mp4" *ngIf="videoURL.length>0">
<!-- <source src="http://static.videogular.com/assets/videos/videogular.ogg" type="video/ogg">
<source src="http://static.videogular.com/assets/videos/videogular.webm" type="video/webm"> -->
<!-- <track kind="subtitles" label="English" src="http://static.videogular.com/assets/subs/pale-blue-dot.vtt" srclang="en" default>
<track kind="subtitles" label="Español" src="http://static.videogular.com/assets/subs/pale-blue-dot-es.vtt" srclang="es"> -->
</video>
</vg-player>
</div>
<div class="button-group">
<button class="button" (click)="visualize()">Visualization</button>
<div ng-view></div>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MainComponent } from './main.component';
describe('MainComponent', () => {
let component: MainComponent;
let fixture: ComponentFixture<MainComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MainComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MainComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,351 @@
import { Component, OnInit } from '@angular/core';
import { FileUploader } from 'ng2-file-upload';
import { EnvironmentModel, StaticAnalysisResult } from '../class/scene';
import { BestScenarioService } from '../service/best-scenario.service';
import { DomSanitizer } from '@angular/platform-browser';
import * as $ from "jquery";
/********加载RecordApp需要用到的支持文件*********/
//必须引入的app核心文件换成require也是一样的。注意app.js会自动往window下挂载名称为RecordApp对象全局可调用window.RecordApp也许可自行调整相关源码清除全局污染
import RecordApp from 'recorder-core/src/app-support/app'
//可选开启Native支持需要引入此文件
import 'recorder-core/src/app-support/app-native-support'
//可选开启IOS上微信录音支持需要引入此文件
import 'recorder-core/src/app-support/app-ios-weixin-support'
/*********加载Recorder需要的文件***********/
//必须引入的核心,所有需要的文件都应当引入,引入后会检测到组件已自动加载
//不引入也可以app.js会去用script动态加载应确保app.js内BaseFolder目录的正确性(参阅RecordAppBaseFolder)否则会导致404 js加载失败
import 'recorder-core'
//需要使用到的音频格式编码引擎的js文件统统加载进来
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
//由于大部分情况下ios-weixin的支持需要用到amr解码器应当把amr引擎也加载进来
import 'recorder-core/src/engine/beta-amr'
import 'recorder-core/src/engine/beta-amr-engine'
import 'recorder-core/src/engine/wav' //amr依赖了wav引擎
//可选的扩展支持项
import 'recorder-core/src/extensions/waveview'
@Component({
selector: 'app-main',
templateUrl: './main.component.html',
styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit {
initModelFileName:string=""
propertyFileName:string=""
ruleTextLine:Array<string>=[]
ruleText: string = "";
ruleTextFinal: string = "";
fileUploaded: boolean = false;
simulationTime: string = "300";
simulationTimeFinal: string = "";
videoURL:string="";
audioURL:string
recordState:string="inactive"
authorized:boolean=false;
environmentModel:EnvironmentModel|null=null;
staticAnalysisResult:StaticAnalysisResult|null=null;
address:string='http://localhost:8085/';
modelUploader: FileUploader = new FileUploader({
url: this.address+'visual/upload',
method: 'POST',
itemAlias: 'file'
});
propertyUploader: FileUploader = new FileUploader({
url: this.address+'visual/upload',
method: 'POST',
itemAlias: 'file'
});
audioUploader: FileUploader=new FileUploader({
url: this.address+'visual/upload',
method: 'POST',
itemAlias: 'file'
})
// recordApp:RecordApp
constructor(private bestScenarioService:BestScenarioService,private sanitizer:DomSanitizer) { }
ngOnInit(): void {
document.getElementById("visualizationResult").style.display="none";
}
//////////////////////////////上传文件/////////////////////////////////
////上传环境本体文件
uploadModelFile(event:any){
this.initModelFileName=event.target.files[0].name;
console.log(event);
////上传
this.upload(this.modelUploader,this.initModelFileName);
}
/////上传设备位置信息表文件
uploadPropertyFile(event:any){
this.propertyFileName=event.target.files[0].name;
console.log(event);
//////上传
this.upload(this.propertyUploader,this.propertyFileName);
}
upload(fileUploader:FileUploader,fileName:string){
console.log(fileName + '执行上传文件');
fileUploader.queue[0].onSuccess= function (response, status, headers){
if (status == 200) {
// 上传文件后获取服务器返回的数据
const tempRes = response;
console.log(response);
} else {
// 上传文件后获取服务器返回的数据错误
alert(fileName + '上传失败');
}
}
fileUploader.queue[0].upload();//开始上传
console.log(fileName + '上传之后');
}
////////////////////////////////////////////////////////////////////////
// authorize(){
// const recordBtn = document.getElementById("record_btn");
// const playBtn = document.querySelector(".play-btn");
// var chunks = [];
// if (navigator.mediaDevices.getUserMedia) {
// const constraints = { audio: true };
// navigator.mediaDevices.getUserMedia(constraints).then(
// stream => {
// this.mediaRecorder = new MediaRecorder(stream);
// recordBtn.onclick = () => {
// if (this.mediaRecorder.state === "recording") {
// this.mediaRecorder.stop();
// recordBtn.textContent = "record";
// console.log("录音结束");
// } else {
// this.mediaRecorder.start();
// console.log("录音中...");
// recordBtn.textContent = "stop";
// }
// console.log("录音器状态:", this.mediaRecorder.state);
// };
// this.mediaRecorder.ondataavailable = e => {
// chunks.push(e.data);
// };
// this.mediaRecorder.onstop = e => {
// var blob = new Blob(chunks, { type: "audio/ogg; codecs=opus" });
// console.log(blob)
// console.log(chunks)
// chunks = [];
// var audioURL = window.URL.createObjectURL(blob);
// this.audioURL = audioURL;
// };
// },
// () => {
// console.error("授权失败!");
// }
// );
// } else {
// console.error("浏览器不支持 getUserMedia");
// }
// }
authorize(){
if(this.recordState==="inactive"){
RecordApp.RequestPermission(() => {
//dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
this.authorized=true
console.log(this.authorized)
this.recordAudio()
},function(msg,isUserNotAllow){//用户拒绝未授权或不支持
//dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
console.log((isUserNotAllow?"UserNotAllow":"")+"无法录音:"+msg);
});
}else if(this.recordState==="recording"){
this.recordAudio()
}
}
recordAudio(){
const recordBtn = document.getElementById("auth");
const playBtn = document.getElementById("play_btn");
console.log(this.recordState)
if(this.authorized){
if(this.recordState=="inactive"){
RecordApp.Start({//如果需要的组件还在延迟加载Start调用会等待这些组件加载完成后才会调起底层平台的Start方法可通绑定RecordApp.Current.OnLazyReady事件来确定是否已完成组件的加载或者设置RecordApp.UseLazyLoad=false来关闭延迟加载会阻塞Install导致RequestPermission变慢
type:"wav",sampleRate:16000,bitRate:16 //mp3格式指定采样率hz、比特率kbps其他参数使用默认配置注意是数字的参数必须提供数字不要用字符串需要使用的type类型需提前把支持文件到Platforms.Default内注册
,onProcess:function(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd){
//如果当前环境支持实时回调RecordApp.Current.CanProcess()),收到录音数据时就会实时调用本回调方法
//可利用extensions/waveview.js扩展实时绘制波形
//可利用extensions/sonic.js扩展实时变速变调此扩展计算量巨大onProcess需要返回true开启异步模式
}
},()=>{
this.recordState="recording"
recordBtn.textContent = "stop";
console.log("start")
},function(msg){
console.log("开始录音失败:"+msg);
}
)
}else if(this.recordState=="recording"){
RecordApp.Stop((blob,duration)=>{//到达指定条件停止录音和清理资源
console.log(blob,(window.URL||webkitURL).createObjectURL(blob),"时长:"+duration+"ms");
this.recordState="inactive"
recordBtn.textContent = "record";
this.authorized=false;
let file = new window.File([blob],"audio.wav", {type: "wav"})
// console.log(file)
// this.audioURL=window.URL.createObjectURL(blob)
//已经拿到blob文件对象想干嘛就干嘛立即播放、上传
// var link = document.createElement('a')
// link.href=window.URL.createObjectURL(blob)
// link.setAttribute('download','audio.wav');
// link.click();
// URL.revokeObjectURL(link.href) // 释放url
// document.body.removeChild(link) // 释放标签
// this.upload(this.audioUploader,files.name)
var fd = new FormData();
fd.append('fname', 'audio.wav');
fd.append('file', file);
console.log(fd.get('fname'))
console.log(fd.get('file'))
$.ajax({
type: 'POST',
url: 'http://localhost:8085/visual/upload',
data: fd,
processData: false,
contentType: false
}).done((rule) =>{
if(rule!="[None]"){
this.ruleTextLine.push(rule)
this.ruleText=this.ruleText+rule
}
console.log(this.ruleTextLine);
console.log(this.ruleText)
});
// $.ajax({
// url: '/visual/upload',
// type: 'POST',
// processData: false,
// contentType: false,
// cache: false,
// data: formData,
// success(res) {
// console.log("上传完成!")
// }
// })
},function(msg){
console.log("录音失败:"+msg);
});
}
}
}
// //////静态分析
// getStaticAnalysisResult(){
// document.getElementById("static")!.style.display="block";
// document.getElementById("simulation")!.style.display="none";
// this.ruleText=this.ruleText.trim();
// this.staticAnalysisService.getStaticAnalysisResult(this.ruleText,this.initModelFileName,this.propertyFileName).subscribe(environmentStatic=>{
// console.log(environmentStatic)
// this.staticAnalysisResult=environmentStatic.staticAnalysisResult
// this.environmentModel=environmentStatic.environmentModel;
// })
// }
/////获得最佳场景分析结果
getBestScenarioAnalysis(){
// console.log(this.environmentModel)
// console.log(this.staticAnalysisResult)
// if(this.staticAnalysisResult!=null&&this.environmentModel!=null){
// console.log("???")
// this.bestScenarioService.generateBestScenarioModelAndSimulate(this.ruleText,this.initModelFileName,this.propertyFileName,"300").subscribe(scene=>{
// console.log(scene)
// })
// }
this.bestScenarioService.generateBestScenarioModelAndSimulate(this.ruleText,this.initModelFileName,this.propertyFileName,"300").subscribe(scene=>{
console.log(scene)
alert("finished")
})
}
simulate(){
}
//可视化
visualize(){
this.bestScenarioService.getVisualization(this.initModelFileName).subscribe(videoURL=>{
this.videoURL="assets/"+videoURL[0];
console.log(this.videoURL)
document.getElementById("visualizationResult").style.display="block";
})
// this.bestScenarioService.getVisualizationResult(this.initModelFileName).subscribe(videoURL=>{
// // this.videoURL=this.sanitizer.bypassSecurityTrustResourceUrl(videoURL[0]);
// this.videoURL="assets/"+videoURL[0];
// console.log(this.videoURL)
// document.getElementById("visualizationResult").style.display="block";
// })
}
}

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { BestScenarioService } from './best-scenario.service';
describe('BestScenarioService', () => {
let service: BestScenarioService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(BestScenarioService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

@ -0,0 +1,49 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { observable, Observable, of } from 'rxjs';
import { Scene } from '../class/scene';
@Injectable({
providedIn: 'root'
})
export class BestScenarioService {
constructor(private http:HttpClient) { }
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
address:string="http://localhost:8085/";
generateBestScenarioModelAndSimulate(ruleText:string,initModelFileName:string,propertyFileName:string,simulationTime:String):Observable<Scene>{
console.log(ruleText)
console.log(initModelFileName)
console.log(propertyFileName)
console.log(simulationTime)
var ruleTextLines:Array<string>;
if(ruleText.indexOf("\r\n")>0){
ruleTextLines=ruleText.split("\r\n");
}else if(ruleText.indexOf("\n")>0){
ruleTextLines=ruleText.split("\n");
}else {
ruleTextLines=ruleText.split("\n");
}
var url=this.address+`visual/generateBestScenarioModelAndSimulate?`;
return this.http.post<Scene>(url,ruleTextLines,this.httpOptions);
}
getVisualization(initModelFileName:string){
var url="http://localhost:8081/jsonfile?";
return this.http.get(url);
}
getVisualizationResult(initModelFileName:string):Observable<string[]>{
var url=this.address+`visual/getVisualizationResult?initModelFileName=${initModelFileName}`;
return this.http.get<string[]>(url);
}
}

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { DynamicAnalysisService } from './dynamic-analysis.service';
describe('DynamicAnalysisService', () => {
let service: DynamicAnalysisService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DynamicAnalysisService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { EnvironmentModel, Rule ,EnvironmentRule, DeviceDetail, Scene, SceneEnvironmentProperty, SceneEnvironmentRule, ScenePropertyResult} from '../class/scene';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { observable, Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DynamicAnalysisService {
constructor(private http:HttpClient) { }
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
address:string="http://localhost:8083/";
generateBestScenarioModelAndSimulate(environmentModel:EnvironmentModel,rules:Array<Rule>,initModelFileName:string,simulationTime:string):Observable<Scene>{
var environmentRule:EnvironmentRule={
environmentModel:environmentModel,
rules:rules
}
var url=this.address+`analysis/generateBestScenarioModelAndSimulate?initModelFileName=${initModelFileName}&simulationTime=${simulationTime}`;
return this.http.post<Scene>(url,environmentRule,this.httpOptions);
}
}

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { StaticAnalysisService } from './static-analysis.service';
describe('StaticAnalysisService', () => {
let service: StaticAnalysisService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(StaticAnalysisService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

@ -0,0 +1,37 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { observable, Observable, of } from 'rxjs';
import { EnvironmentStatic } from '../class/scene';
@Injectable({
providedIn: 'root'
})
export class StaticAnalysisService {
constructor(private http:HttpClient) { }
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
address:string="http://localhost:8083/";
getStaticAnalysisResult(ruleText:string,initModelFileName:string,propertyFileName:string):Observable<EnvironmentStatic>{
var ruleTextLines:Array<string>;
if(ruleText.indexOf("\r\n")>0){
ruleTextLines=ruleText.split("\r\n");
}else if(ruleText.indexOf("\n")>0){
ruleTextLines=ruleText.split("\n");
}else {
ruleTextLines=ruleText.split("\n");
}
var url=this.address+`analysis/getStaticAnalysisResult?initModelFileName=${initModelFileName}&propertyFileName=${propertyFileName}`;
return this.http.post<EnvironmentStatic>(url,ruleTextLines,this.httpOptions);
}
}

@ -0,0 +1,24 @@
.topbar{
height: 5rem;
background-color: #1874cd;
margin-left: 10px;
margin-top: 2px;
margin-right: 10px;
display: flex;
flex-direction: row;
border-radius: 0;
align-items: stretch;
}
.topbar-font{
color: white;
font-size: 3rem;
margin-top: 11px;
margin-left: 20px;
}

@ -0,0 +1,3 @@
<div class="topbar">
<p class="topbar-font">TAPs Visualization</p>
</div>

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TopbarComponent } from './topbar.component';
describe('TopbarComponent', () => {
let component: TopbarComponent;
let fixture: ComponentFixture<TopbarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TopbarComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TopbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-topbar',
templateUrl: './topbar.component.html',
styleUrls: ['./topbar.component.css']
})
export class TopbarComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

@ -0,0 +1,3 @@
export const environment = {
production: true
};

@ -0,0 +1,16 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 B

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SimulationVisualization</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

@ -0,0 +1,63 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

@ -0,0 +1,25 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {
keys(): string[];
<T>(id: string): T;
};
};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

@ -0,0 +1,15 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"files": [
"src/main.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
}

@ -0,0 +1,21 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports":true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": [
"es2018",
"dom"
]
}
}

@ -0,0 +1,18 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]
},
"files": [
"src/test.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}

@ -0,0 +1,152 @@
{
"extends": "tslint:recommended",
"rulesDirectory": [
"codelyzer"
],
"rules": {
"align": {
"options": [
"parameters",
"statements"
]
},
"array-type": false,
"arrow-return-shorthand": true,
"curly": true,
"deprecation": {
"severity": "warning"
},
"eofline": true,
"import-blacklist": [
true,
"rxjs/Rx"
],
"import-spacing": true,
"indent": {
"options": [
"spaces"
]
},
"max-classes-per-file": false,
"max-line-length": [
true,
140
],
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-empty": false,
"no-inferrable-types": [
true,
"ignore-params"
],
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-switch-case-fall-through": true,
"no-var-requires": false,
"object-literal-key-quotes": [
true,
"as-needed"
],
"quotemark": [
true,
"single"
],
"semicolon": {
"options": [
"always"
]
},
"space-before-function-paren": {
"options": {
"anonymous": "never",
"asyncArrow": "always",
"constructor": "never",
"method": "never",
"named": "never"
}
},
"typedef": [
true,
"call-signature"
],
"typedef-whitespace": {
"options": [
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
]
},
"variable-name": {
"options": [
"ban-keywords",
"check-format",
"allow-pascal-case"
]
},
"whitespace": {
"options": [
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
},
"component-class-suffix": true,
"contextual-lifecycle": true,
"directive-class-suffix": true,
"no-conflicting-lifecycle": true,
"no-host-metadata-property": true,
"no-input-rename": true,
"no-inputs-metadata-property": true,
"no-output-native": true,
"no-output-on-prefix": true,
"no-output-rename": true,
"no-outputs-metadata-property": true,
"template-banana-in-box": true,
"template-no-negated-async": true,
"use-lifecycle-interface": true,
"use-pipe-transform-interface": true,
"directive-selector": [
true,
"attribute",
"app",
"camelCase"
],
"component-selector": [
true,
"element",
"app",
"kebab-case"
]
}
}
Loading…
Cancel
Save