Skip to content

Commit

Permalink
Merge branch 'release/1.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-Markus committed Aug 23, 2021
2 parents 55d05a2 + eab3755 commit 64676c6
Show file tree
Hide file tree
Showing 474 changed files with 6,402 additions and 6,399 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CD

on:
release:
types:
- edited
- released

jobs:
release:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.x

- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Test
run: dotnet test --no-build --configuration Release

- name: Create NuGet packages
run: |
VERSION=$(echo "${{ github.event.release.tag_name }}" | cut -c2-)
echo $VERSION
dotnet pack --no-build --configuration Release -p:Version=$VERSION
- name: Publish NuGet packages
run: dotnet nuget push "**/*.nupkg" --api-key $NUGET_AUTH_TOKEN --source https://api.nuget.org/v3/index.json --skip-duplicate
env:
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_API_KEY }}
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on:
push:
branches:
- '*'
pull_request:
branches:
- develop
- master

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.x

- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Test
run: dotnet test --no-build --configuration Release
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ It is fully implemented in Netstandard 2.0 and NET Core 3.0 so that it runs on m

| Name | Status |
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| master | [![Build status](https://ci.appveyor.com/api/projects/status/2c0c15ta3ow8pfib/branch/master?svg=true)](https://ci.appveyor.com/project/Mr-Markus/zigbeenet/branch/master) |
| develop | [![Build status](https://ci.appveyor.com/api/projects/status/2c0c15ta3ow8pfib/branch/develop?svg=true)](https://ci.appveyor.com/project/Mr-Markus/zigbeenet/branch/develop) |
| master | [![Build status](https://github.com/Mr-Markus/ZigbeeNet/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Mr-Markus/ZigbeeNet/actions/workflows/ci.yml) |
| develop | [![Build status](https://github.com/Mr-Markus/ZigbeeNet/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/Mr-Markus/ZigbeeNet/actions/workflows/ci.yml) |

## Packages ##

Expand Down
24 changes: 0 additions & 24 deletions appveyor.yml

This file was deleted.

20 changes: 10 additions & 10 deletions autocode/ZigBeeNet.CodeGenerator/ZigBeeBaseFieldGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ protected void GenerateFields(TextWriter @out, string parentClass, string classN
if (GetAutoSized(fields, StringToLowerCamelCase(field.Name)) != null)
{
ZigBeeXmlField sizedField = GetAutoSized(fields, StringToLowerCamelCase(field.Name));
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(sizedField.Name) + ".Count, ZclDataType.Get(DataType." + field.Type + "));");
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(sizedField.Name) + ".Count, DataType." + field.Type + ");");
continue;
}

if (field.Sizer != null)
{
@out.WriteLine(" for (int cnt = 0; cnt < " + StringToUpperCamelCase(field.Name) + ".Count; cnt++)");
@out.WriteLine(" {");
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(field.Name) + "[cnt], ZclDataType.Get(DataType." + field.Type + "));");
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(field.Name) + "[cnt], DataType." + field.Type + ");");
@out.WriteLine(" }");
}
else if (field.Condition != null)
Expand All @@ -75,7 +75,7 @@ protected void GenerateFields(TextWriter @out, string parentClass, string classN
// This checks for a single response
@out.WriteLine(" if (Status == ZclStatus.SUCCESS)");
@out.WriteLine(" {");
@out.WriteLine(" serializer.Serialize(Status, ZclDataType.Get(DataType.ZCL_STATUS));");
@out.WriteLine(" serializer.Serialize(Status, DataType.ZCL_STATUS);");
@out.WriteLine(" return;");
@out.WriteLine(" }");
continue;
Expand All @@ -90,14 +90,14 @@ protected void GenerateFields(TextWriter @out, string parentClass, string classN
@out.WriteLine(" if (" + UpperCaseFirstCharacter(field.Condition.Field) + " " + GetOperator(field.Condition.Operator) + " " + field.Condition.Value + ")");
@out.WriteLine(" {");
}
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(field.Name)+ ", ZclDataType.Get(DataType." + field.Type + "));");
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(field.Name)+ ", DataType." + field.Type + ");");
@out.WriteLine(" }");
}
else
{
if (field.Type != null && !string.IsNullOrEmpty(field.Type))
{
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(field.Name) + ", ZclDataType.Get(DataType." + field.Type + "));");
@out.WriteLine(" serializer.Serialize(" + StringToUpperCamelCase(field.Name) + ", DataType." + field.Type + ");");
}
else
{
Expand Down Expand Up @@ -155,7 +155,7 @@ protected void GenerateFields(TextWriter @out, string parentClass, string classN
}
if (GetAutoSized(fields, StringToLowerCamelCase(field.Name)) != null)
{
@out.WriteLine(" " + GetDataTypeClass(field) + "? " + StringToLowerCamelCase(field.Name) + " = (" + GetDataTypeClass(field) + "?) deserializer.Deserialize(ZclDataType.Get(DataType." + field.Type + "));");
@out.WriteLine(" " + GetDataTypeClass(field) + "? " + StringToLowerCamelCase(field.Name) + " = (" + GetDataTypeClass(field) + "?) deserializer.Deserialize(DataType." + field.Type + ");");
continue;
}

Expand All @@ -170,7 +170,7 @@ protected void GenerateFields(TextWriter @out, string parentClass, string classN
@out.WriteLine(" {");
@out.WriteLine(" for (int cnt = 0; cnt < " + field.Sizer + "; cnt++)");
@out.WriteLine(" {");
@out.WriteLine(" " + StringToUpperCamelCase(field.Name) + ".Add((" + dataType + ") deserializer.Deserialize(ZclDataType.Get(DataType." + field.Type + ")));");
@out.WriteLine(" " + StringToUpperCamelCase(field.Name) + ".Add((" + dataType + ") deserializer.Deserialize(DataType." + field.Type + "));");
@out.WriteLine(" }");
@out.WriteLine(" }");
}
Expand All @@ -182,7 +182,7 @@ protected void GenerateFields(TextWriter @out, string parentClass, string classN
// This checks for a single response
@out.WriteLine(" if (deserializer.RemainingLength == 1)");
@out.WriteLine(" {");
@out.WriteLine(" Status = deserializer.Deserialize<ZclStatus>(ZclDataType.Get(DataType.ZCL_STATUS));");
@out.WriteLine(" Status = deserializer.Deserialize<ZclStatus>(DataType.ZCL_STATUS);");
@out.WriteLine(" return;");
@out.WriteLine(" }");
continue;
Expand All @@ -197,14 +197,14 @@ protected void GenerateFields(TextWriter @out, string parentClass, string classN
@out.WriteLine(" if (" + UpperCaseFirstCharacter(field.Condition.Field) + " " + GetOperator(field.Condition.Operator) + " " + field.Condition.Value + ")");
@out.WriteLine(" {");
}
@out.WriteLine(" " + StringToUpperCamelCase(field.Name) + " = deserializer.Deserialize<" + GetDataTypeClass(field) + ">(ZclDataType.Get(DataType." + field.Type + "));");
@out.WriteLine(" " + StringToUpperCamelCase(field.Name) + " = deserializer.Deserialize<" + GetDataTypeClass(field) + ">(DataType." + field.Type + ");");
@out.WriteLine(" }");
}
else
{
if (!string.IsNullOrEmpty(field.Type))
{
@out.WriteLine(" " + StringToUpperCamelCase(field.Name) + " = deserializer.Deserialize<" + GetDataTypeClass(field) + ">(ZclDataType.Get(DataType." + field.Type + "));");
@out.WriteLine(" " + StringToUpperCamelCase(field.Name) + " = deserializer.Deserialize<" + GetDataTypeClass(field) + ">(DataType." + field.Type + ");");
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions autocode/ZigBeeNet.CodeGenerator/ZigBeeZclClusterGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ private void CreateInitializeAttributes(TextWriter @out, string clusterName, Lis

private string DefineAttribute(ZigBeeXmlAttribute attribute, string clusterName, string attributeName, int count)
{
return "new ZclAttribute(this, " + GetEnum(attributeName) + ", \"" + attributeName + "\", " + "ZclDataType.Get(DataType."
+ attribute.Type + "), " + (!attribute.Optional).ToString().ToLower() + ", " + true.ToString().ToLower()
return "new ZclAttribute(this, " + GetEnum(attributeName) + ", \"" + attributeName + "\", " + "DataType."
+ attribute.Type + ", " + (!attribute.Optional).ToString().ToLower() + ", " + true.ToString().ToLower()
+ ", " + attribute.Writable.ToString().ToLower() + ", " + attribute.Reportable.ToString().ToLower() + ")";
}

Expand Down
13 changes: 6 additions & 7 deletions autocode/ZigBeeNet.Digi.XBee.CodeGenerator/CommandGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ private void CreateEventFactory(string className, Protocol protocol)
IsClass = true,
TypeAttributes = System.Reflection.TypeAttributes.Public
};
codeNamespace.Imports.Add(new CodeNamespaceImport("Serilog"));
codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
codeNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Concurrent"));
codeNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
codeNamespace.Imports.Add(new CodeNamespaceImport("Microsoft.Extensions.Logging"));

codeNamespace.Types.Add(protocolClass);

Expand Down Expand Up @@ -291,13 +291,12 @@ private void CreateEventFactory(string className, Protocol protocol)

CodeConditionStatement apiCommandCorrelationCondition = new CodeConditionStatement(
new CodeSnippetExpression($"xbeeClass == null"),
new CodeStatement[] { new CodeSnippetStatement($" xbeeClass = _events[data[2]];") });
new CodeStatement[] { new CodeSnippetStatement($" _events.TryGetValue(data[2], out xbeeClass);") });
getXBeeFrameMethod.Statements.Add(apiCommandCorrelationCondition);
}
else
{
CodeAssignStatement codeAssignStatement = new CodeAssignStatement(new CodeSnippetExpression("Type xbeeClass"), new CodeSnippetExpression("_events[data[2]]"));
getXBeeFrameMethod.Statements.Add(codeAssignStatement);
getXBeeFrameMethod.Statements.Add(new CodeSnippetStatement($" _events.TryGetValue(data[2], out Type xbeeClass);"));
}

CodeConditionStatement noHandlerFoundCondition = new CodeConditionStatement(
Expand All @@ -311,7 +310,7 @@ private void CreateEventFactory(string className, Protocol protocol)
codeTryStatement.TryStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("xbeeFrame")));

CodeCatchClause catchClause = new CodeCatchClause("ex", new CodeTypeReference("Exception"));
catchClause.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression($"Log"), "Debug", new CodeVariableReferenceExpression($"\"Error creating instance of IXBeeResponse\", ex")));
catchClause.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression($"ZigBeeDongleXBee.Logger"), "LogDebug", new CodeVariableReferenceExpression($"\"Error creating instance of IXBeeResponse\", ex")));

codeTryStatement.CatchClauses.Add(catchClause);
getXBeeFrameMethod.Statements.Add(codeTryStatement);
Expand Down Expand Up @@ -1358,11 +1357,11 @@ private static void GenerateCode(CodeCompileUnit codeCompileUnit, string sourceF

if (provider.FileExtension[0] == '.')
{
sourceFile = $@"..\..\..\..\ZigBeeNet.Hardware.Digi.XBee\Internal\{protocolFolder}{sourceFile}{provider.FileExtension}";
sourceFile = $@"..\..\libraries\ZigBeeNet.Hardware.Digi.XBee\Internal\{protocolFolder}{sourceFile}{provider.FileExtension}";
}
else
{
sourceFile = $@"..\..\..\..\ZigBeeNet.Hardware.Digi.XBee\Internal\{protocolFolder}{sourceFile}.{provider.FileExtension}";
sourceFile = $@"..\..\libraries\ZigBeeNet.Hardware.Digi.XBee\Internal\{protocolFolder}{sourceFile}.{provider.FileExtension}";
}

var codeGeneratorOptions = new CodeGeneratorOptions
Expand Down
21 changes: 21 additions & 0 deletions docs/cicd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# CI & CD setup

Continuous Integration (CI) and Continuous Delivery (CD)
has been implemented using GitHub Actions.
Content on these files can be found in `.github/workflows/` folder.

CI uses `dotnet` command-line tooling in build steps.
Build is initiated by `push` to branch or `pull request`
to `develop` or `master` branches.

CD also uses `dotnet` tooling. It's initiated by
creating GitHub Release in the repository.

**Important**: CD uses `tag_name` from the release
as it's package version. Meaning if you tag your
release using `v1.5.0`, it will automatically version NuGet
packages as `1.5.0`.

**Important 2**: CD requires `NUGET_API_KEY` names [secret](https://docs.github.com/en/actions/reference/encrypted-secrets)
to be stored into the repository secrets.
It's used when publishing NuGet Packages to the nuget.org.
33 changes: 26 additions & 7 deletions libraries/ZigBeeNet.DataStore.Json/JsonNetworkDataStore.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Converters;
using ZigBeeNet.Database;

namespace ZigBeeNet.DataStore.Json
{
public class JsonNetworkDataStore : IZigBeeNetworkDataStore
{
private readonly string _dirname;
static private readonly JsonSerializerSettings _settings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new PrivateResolver(),
};

public JsonNetworkDataStore(string dirname)
{
Expand Down Expand Up @@ -65,7 +73,7 @@ public ZigBeeNodeDao ReadNode(IeeeAddress address)

if (File.Exists(filename))
{
node = JsonConvert.DeserializeObject<ZigBeeNodeDao>(File.ReadAllText(filename));
node = JsonConvert.DeserializeObject<ZigBeeNodeDao>(File.ReadAllText(filename),_settings);
}
}
catch (Exception ex)
Expand Down Expand Up @@ -98,12 +106,7 @@ public void WriteNode(ZigBeeNodeDao node)
{
string filename = GetFileName(node.IeeeAddress);

var settings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

string json = JsonConvert.SerializeObject(node, Formatting.Indented, settings);
string json = JsonConvert.SerializeObject(node, Formatting.Indented, _settings);

File.WriteAllText(filename, json);
}
Expand All @@ -112,5 +115,21 @@ public void WriteNode(ZigBeeNodeDao node)
Console.WriteLine(ex.ToString());
}
}

// Private resolver to configure Newtonsoft.Json to deserialize properties with private setter
// Credit : https://talkdotnet.wordpress.com/2019/03/15/newtonsoft-json-deserializing-objects-that-have-private-setters/
public class PrivateResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (!prop.Writable) {
PropertyInfo property = member as PropertyInfo;
bool hasPrivateSetter = property?.GetSetMethod(true) != null;
prop.Writable = hasPrivateSetter;
}
return prop;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.0.0</Version>
<Version>1.5.0</Version>
<Authors>Mr-Markus</Authors>
<Company>ZigBeeNet</Company>
<PackageLicenseExpression>EPL-1.0</PackageLicenseExpression>
Expand Down
Loading

0 comments on commit 64676c6

Please sign in to comment.